1/*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "connection_observer_controller.h"
17
18#include "connection_observer_errors.h"
19#include "hilog_tag_wrapper.h"
20
21namespace OHOS {
22namespace AAFwk {
23using namespace OHOS::AbilityRuntime;
24int ConnectionObserverController::AddObserver(const sptr<AbilityRuntime::IConnectionObserver> &observer)
25{
26    if (!observer) {
27        TAG_LOGE(AAFwkTag::CONNECTION, "invalid observer");
28        return AbilityRuntime::ERR_INVALID_OBSERVER;
29    }
30
31    std::lock_guard<ffrt::mutex> guard(observerLock_);
32    auto it = std::find_if(observers_.begin(), observers_.end(), [&observer](const sptr<IConnectionObserver> &item) {
33        return (item && item->AsObject() == observer->AsObject());
34    });
35    if (it != observers_.end()) {
36        TAG_LOGW(AAFwkTag::CONNECTION, "observer already added");
37        return 0;
38    }
39
40    if (!observerDeathRecipient_) {
41        std::weak_ptr<ConnectionObserverController> thisWeakPtr(shared_from_this());
42        observerDeathRecipient_ =
43            new ObserverDeathRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
44                auto controller = thisWeakPtr.lock();
45                if (controller) {
46                    controller->HandleRemoteDied(remote);
47                }
48            });
49    }
50    auto observerObj = observer->AsObject();
51    if (!observerObj || !observerObj->AddDeathRecipient(observerDeathRecipient_)) {
52        TAG_LOGE(AAFwkTag::CONNECTION, "AddDeathRecipient failed");
53    }
54    observers_.emplace_back(observer);
55
56    return 0;
57}
58
59void ConnectionObserverController::RemoveObserver(const sptr<AbilityRuntime::IConnectionObserver> &observer)
60{
61    if (!observer) {
62        TAG_LOGE(AAFwkTag::CONNECTION, "observer invalid");
63        return;
64    }
65
66    std::lock_guard<ffrt::mutex> guard(observerLock_);
67    auto it = std::find_if(observers_.begin(), observers_.end(), [&observer](const sptr<IConnectionObserver> item) {
68        return (item && item->AsObject() == observer->AsObject());
69    });
70    if (it != observers_.end()) {
71        observers_.erase(it);
72    }
73}
74
75void ConnectionObserverController::NotifyExtensionConnected(const AbilityRuntime::ConnectionData& data)
76{
77    CallObservers(&AbilityRuntime::IConnectionObserver::OnExtensionConnected, data);
78}
79
80void ConnectionObserverController::NotifyExtensionDisconnected(const AbilityRuntime::ConnectionData& data)
81{
82    CallObservers(&AbilityRuntime::IConnectionObserver::OnExtensionDisconnected, data);
83}
84
85#ifdef WITH_DLP
86void ConnectionObserverController::NotifyDlpAbilityOpened(const AbilityRuntime::DlpStateData& data)
87{
88    CallObservers(&AbilityRuntime::IConnectionObserver::OnDlpAbilityOpened, data);
89}
90
91void ConnectionObserverController::NotifyDlpAbilityClosed(const AbilityRuntime::DlpStateData& data)
92{
93    CallObservers(&AbilityRuntime::IConnectionObserver::OnDlpAbilityClosed, data);
94}
95#endif // WITH_DLP
96
97std::vector<sptr<AbilityRuntime::IConnectionObserver>> ConnectionObserverController::GetObservers()
98{
99    std::lock_guard<ffrt::mutex> guard(observerLock_);
100    return observers_;
101}
102
103void ConnectionObserverController::HandleRemoteDied(const wptr<IRemoteObject> &remote)
104{
105    TAG_LOGD(AAFwkTag::CONNECTION, "remote connection oberver died");
106    auto remoteObj = remote.promote();
107    if (!remoteObj) {
108        TAG_LOGD(AAFwkTag::CONNECTION, "invalid remoteObj");
109        return;
110    }
111    remoteObj->RemoveDeathRecipient(observerDeathRecipient_);
112
113    std::lock_guard<ffrt::mutex> guard(observerLock_);
114    auto it = std::find_if(observers_.begin(), observers_.end(), [&remoteObj](const sptr<IConnectionObserver> item) {
115        return (item && item->AsObject() == remoteObj);
116    });
117    if (it != observers_.end()) {
118        observers_.erase(it);
119    }
120}
121
122ConnectionObserverController::ObserverDeathRecipient::ObserverDeathRecipient(ObserverDeathHandler handler)
123    : deathHandler_(handler)
124{}
125
126void ConnectionObserverController::ObserverDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
127{
128    if (deathHandler_) {
129        deathHandler_(remote);
130    }
131}
132} // namespace AAFwk
133} // namespace OHOS
134