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_client_impl.h"
17
18 #include "connection_observer_errors.h"
19 #include "connection_observer_stub_impl.h"
20 #include "hilog_tag_wrapper.h"
21 #include "iservice_registry.h"
22 #include "system_ability_definition.h"
23
24 namespace OHOS {
25 namespace AbilityRuntime {
RegisterObserver(const std::shared_ptr<ConnectionObserver> & observer)26 int32_t ConnectionObserverClientImpl::RegisterObserver(const std::shared_ptr<ConnectionObserver> &observer)
27 {
28 if (!observer) {
29 TAG_LOGE(AAFwkTag::CONNECTION, "invalid observer");
30 return ERR_INVALID_OBSERVER;
31 }
32
33 auto proxy = GetServiceProxy();
34
35 std::lock_guard<std::mutex> guard(observerLock_);
36 if (!RegisterObserverToServiceLocked(proxy)) {
37 TAG_LOGE(AAFwkTag::CONNECTION, "register failed");
38 return ERR_REGISTER_FAILED;
39 }
40
41 return AddObserversLocked(observer);
42 }
43
UnregisterObserver(const std::shared_ptr<ConnectionObserver> & observer)44 int32_t ConnectionObserverClientImpl::UnregisterObserver(const std::shared_ptr<ConnectionObserver> &observer)
45 {
46 if (!observer) {
47 TAG_LOGE(AAFwkTag::CONNECTION, "invalid observer");
48 return ERR_INVALID_OBSERVER;
49 }
50
51 auto proxy = GetServiceProxy();
52
53 std::lock_guard<std::mutex> guard(observerLock_);
54 auto ret = RemoveObserversLocked(observer);
55 if (userObservers_.empty()) {
56 UnregisterFromServiceLocked(proxy);
57 }
58
59 return ret;
60 }
61
62 #ifdef WITH_DLP
GetDlpConnectionInfos(std::vector<DlpConnectionInfo> & infos)63 int32_t ConnectionObserverClientImpl::GetDlpConnectionInfos(std::vector<DlpConnectionInfo> &infos)
64 {
65 auto proxy = GetServiceProxy();
66 if (!proxy) {
67 TAG_LOGE(AAFwkTag::CONNECTION, "invalid observer");
68 return ERR_NO_PROXY;
69 }
70
71 return proxy->GetDlpConnectionInfos(infos);
72 }
73 #endif // WITH_DLP
74
GetConnectionData(std::vector<ConnectionData> & connectionData)75 int32_t ConnectionObserverClientImpl::GetConnectionData(std::vector<ConnectionData> &connectionData)
76 {
77 auto proxy = GetServiceProxy();
78 if (!proxy) {
79 TAG_LOGE(AAFwkTag::CONNECTION, "invalid observer");
80 return ERR_NO_PROXY;
81 }
82
83 return proxy->GetConnectionData(connectionData);
84 }
85
HandleExtensionConnected(const ConnectionData & data)86 void ConnectionObserverClientImpl::HandleExtensionConnected(const ConnectionData &data)
87 {
88 auto observers = GetObservers();
89 for (auto it = observers.begin(); it != observers.end(); ++it) {
90 auto observer = *it;
91 if (observer) {
92 observer->OnExtensionConnected(data);
93 }
94 }
95 }
96
HandleExtensionDisconnected(const ConnectionData & data)97 void ConnectionObserverClientImpl::HandleExtensionDisconnected(const ConnectionData &data)
98 {
99 auto observers = GetObservers();
100 for (auto it = observers.begin(); it != observers.end(); ++it) {
101 auto observer = *it;
102 if (observer) {
103 observer->OnExtensionDisconnected(data);
104 }
105 }
106 }
107
108 #ifdef WITH_DLP
HandleDlpAbilityOpened(const DlpStateData & data)109 void ConnectionObserverClientImpl::HandleDlpAbilityOpened(const DlpStateData &data)
110 {
111 auto observers = GetObservers();
112 for (auto it = observers.begin(); it != observers.end(); ++it) {
113 auto observer = *it;
114 if (observer) {
115 observer->OnDlpAbilityOpened(data);
116 }
117 }
118 }
119
HandleDlpAbilityClosed(const DlpStateData & data)120 void ConnectionObserverClientImpl::HandleDlpAbilityClosed(const DlpStateData &data)
121 {
122 auto observers = GetObservers();
123 for (auto it = observers.begin(); it != observers.end(); ++it) {
124 auto observer = *it;
125 if (observer) {
126 observer->OnDlpAbilityClosed(data);
127 }
128 }
129 }
130 #endif // WITH_DLP
131
RegisterObserverToServiceLocked(const std::shared_ptr<ServiceProxyAdapter> & proxy)132 bool ConnectionObserverClientImpl::RegisterObserverToServiceLocked(const std::shared_ptr<ServiceProxyAdapter> &proxy)
133 {
134 if (isRegistered_) {
135 return true;
136 }
137
138 if (!proxy) {
139 TAG_LOGE(AAFwkTag::CONNECTION, "fail to get service");
140 return false;
141 }
142
143 if (!observer_) {
144 observer_ = sptr<IConnectionObserver>(new (std::nothrow) ConnectionObserverStubImpl(shared_from_this()));
145 }
146
147 if (proxy->RegisterObserver(observer_) != ERR_OK) {
148 TAG_LOGE(AAFwkTag::CONNECTION, "register observer failed");
149 return false;
150 }
151 isRegistered_ = true;
152 return true;
153 }
154
UnregisterFromServiceLocked(const std::shared_ptr<ServiceProxyAdapter> & proxy)155 void ConnectionObserverClientImpl::UnregisterFromServiceLocked(const std::shared_ptr<ServiceProxyAdapter> &proxy)
156 {
157 if (!isRegistered_ || !observer_) {
158 return;
159 }
160
161 if (!proxy) {
162 return;
163 }
164
165 if (proxy->UnregisterObserver(observer_) != ERR_OK) {
166 TAG_LOGE(AAFwkTag::CONNECTION, "unregister observer failed");
167 return;
168 }
169 isRegistered_ = false;
170 }
171
AddObserversLocked(const std::shared_ptr<ConnectionObserver> & observer)172 int32_t ConnectionObserverClientImpl::AddObserversLocked(const std::shared_ptr<ConnectionObserver> &observer)
173 {
174 if (userObservers_.find(observer) != userObservers_.end()) {
175 TAG_LOGE(AAFwkTag::CONNECTION, "observer already registered");
176 return ERR_OBSERVER_ALREADY_REGISTERED;
177 }
178 userObservers_.emplace(observer);
179 return ERR_OK;
180 }
181
RemoveObserversLocked(const std::shared_ptr<ConnectionObserver> & observer)182 int32_t ConnectionObserverClientImpl::RemoveObserversLocked(const std::shared_ptr<ConnectionObserver> &observer)
183 {
184 if (userObservers_.find(observer) == userObservers_.end()) {
185 TAG_LOGE(AAFwkTag::CONNECTION, "no such observer");
186 return ERR_OBSERVER_NOT_REGISTERED;
187 }
188 userObservers_.erase(observer);
189 return ERR_OK;
190 }
191
GetServiceProxy()192 std::shared_ptr<ServiceProxyAdapter> ConnectionObserverClientImpl::GetServiceProxy()
193 {
194 std::lock_guard<std::mutex> guard(proxyLock_);
195 if (!serviceAdapter_) {
196 ConnectLocked();
197 }
198 return serviceAdapter_;
199 }
200
ConnectLocked()201 void ConnectionObserverClientImpl::ConnectLocked()
202 {
203 if (serviceAdapter_ != nullptr) {
204 return;
205 }
206 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
207 if (systemManager == nullptr) {
208 TAG_LOGE(AAFwkTag::CONNECTION, "get system ability registry failed");
209 return;
210 }
211 sptr<IRemoteObject> remoteObj = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
212 if (remoteObj == nullptr) {
213 TAG_LOGE(AAFwkTag::CONNECTION, "connect AMS failed");
214 return;
215 }
216
217 deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(
218 new (std::nothrow) ServiceDeathRecipient(shared_from_this()));
219 if (deathRecipient_ == nullptr) {
220 TAG_LOGE(AAFwkTag::CONNECTION, "create AbilityMgrDeathRecipient failed");
221 return;
222 }
223 if ((remoteObj->IsProxyObject()) && (!remoteObj->AddDeathRecipient(deathRecipient_))) {
224 TAG_LOGE(AAFwkTag::CONNECTION, "Add death recipient failed");
225 return;
226 }
227
228 serviceAdapter_ = std::make_shared<ServiceProxyAdapter>(remoteObj);
229 TAG_LOGI(AAFwkTag::CONNECTION, "Connect AMS success");
230 }
231
HandleRemoteDied(const wptr<IRemoteObject> & remote)232 void ConnectionObserverClientImpl::HandleRemoteDied(const wptr<IRemoteObject> &remote)
233 {
234 if (!ResetProxy(remote)) {
235 return;
236 }
237 NotifyServiceDiedToObservers();
238 }
239
ResetProxy(const wptr<IRemoteObject> & remote)240 bool ConnectionObserverClientImpl::ResetProxy(const wptr<IRemoteObject> &remote)
241 {
242 std::lock_guard<std::mutex> guard(proxyLock_);
243 if (serviceAdapter_ == nullptr) {
244 return false;
245 }
246
247 auto proxyObject = serviceAdapter_->GetProxyObject();
248 if ((proxyObject != nullptr) && (proxyObject == remote.promote())) {
249 proxyObject->RemoveDeathRecipient(deathRecipient_);
250 serviceAdapter_ = nullptr;
251 return true;
252 }
253
254 return false;
255 }
256
ResetStatus()257 void ConnectionObserverClientImpl::ResetStatus()
258 {
259 std::lock_guard<std::mutex> guard(observerLock_);
260 isRegistered_ = false;
261 userObservers_.clear();
262 }
263
NotifyServiceDiedToObservers()264 void ConnectionObserverClientImpl::NotifyServiceDiedToObservers()
265 {
266 auto observers = GetObservers();
267 ResetStatus();
268 for (auto it = observers.begin(); it != observers.end(); ++it) {
269 auto observer = *it;
270 if (observer) {
271 observer->OnServiceDied();
272 }
273 }
274 }
275
GetObservers()276 std::unordered_set<std::shared_ptr<ConnectionObserver>> ConnectionObserverClientImpl::GetObservers()
277 {
278 std::lock_guard<std::mutex> guard(observerLock_);
279 return userObservers_;
280 }
281
OnRemoteDied(const wptr<IRemoteObject> & remote)282 void ConnectionObserverClientImpl::ServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
283 {
284 TAG_LOGI(AAFwkTag::CONNECTION, "called");
285 auto owner = owner_.lock();
286 if (!owner) {
287 TAG_LOGE(AAFwkTag::CONNECTION, "OnRemoteDied");
288 return;
289 }
290 owner->HandleRemoteDied(remote);
291 }
292 } // namespace AbilityRuntime
293 } // namespace OHOS
294