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