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 
21 namespace OHOS {
22 namespace AAFwk {
23 using namespace OHOS::AbilityRuntime;
AddObserver(const sptr<AbilityRuntime::IConnectionObserver> & observer)24 int 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 
RemoveObserver(const sptr<AbilityRuntime::IConnectionObserver> & observer)59 void 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 
NotifyExtensionConnected(const AbilityRuntime::ConnectionData & data)75 void ConnectionObserverController::NotifyExtensionConnected(const AbilityRuntime::ConnectionData& data)
76 {
77     CallObservers(&AbilityRuntime::IConnectionObserver::OnExtensionConnected, data);
78 }
79 
NotifyExtensionDisconnected(const AbilityRuntime::ConnectionData & data)80 void ConnectionObserverController::NotifyExtensionDisconnected(const AbilityRuntime::ConnectionData& data)
81 {
82     CallObservers(&AbilityRuntime::IConnectionObserver::OnExtensionDisconnected, data);
83 }
84 
85 #ifdef WITH_DLP
NotifyDlpAbilityOpened(const AbilityRuntime::DlpStateData & data)86 void ConnectionObserverController::NotifyDlpAbilityOpened(const AbilityRuntime::DlpStateData& data)
87 {
88     CallObservers(&AbilityRuntime::IConnectionObserver::OnDlpAbilityOpened, data);
89 }
90 
NotifyDlpAbilityClosed(const AbilityRuntime::DlpStateData & data)91 void ConnectionObserverController::NotifyDlpAbilityClosed(const AbilityRuntime::DlpStateData& data)
92 {
93     CallObservers(&AbilityRuntime::IConnectionObserver::OnDlpAbilityClosed, data);
94 }
95 #endif // WITH_DLP
96 
GetObservers()97 std::vector<sptr<AbilityRuntime::IConnectionObserver>> ConnectionObserverController::GetObservers()
98 {
99     std::lock_guard<ffrt::mutex> guard(observerLock_);
100     return observers_;
101 }
102 
HandleRemoteDied(const wptr<IRemoteObject> & remote)103 void 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 
ObserverDeathRecipient(ObserverDeathHandler handler)122 ConnectionObserverController::ObserverDeathRecipient::ObserverDeathRecipient(ObserverDeathHandler handler)
123     : deathHandler_(handler)
124 {}
125 
OnRemoteDied(const wptr<IRemoteObject> & remote)126 void ConnectionObserverController::ObserverDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
127 {
128     if (deathHandler_) {
129         deathHandler_(remote);
130     }
131 }
132 } // namespace AAFwk
133 } // namespace OHOS
134