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
HandleExtensionSuspended(const ConnectionData & data)108 void ConnectionObserverClientImpl::HandleExtensionSuspended(const ConnectionData &data)
109 {
110 auto observers = GetObservers();
111 for (auto it = observers.begin(); it != observers.end(); ++it) {
112 auto observer = *it;
113 if (observer) {
114 observer->OnExtensionSuspended(data);
115 }
116 }
117 }
118
HandleExtensionResumed(const ConnectionData & data)119 void ConnectionObserverClientImpl::HandleExtensionResumed(const ConnectionData &data)
120 {
121 auto observers = GetObservers();
122 for (auto it = observers.begin(); it != observers.end(); ++it) {
123 auto observer = *it;
124 if (observer) {
125 observer->OnExtensionResumed(data);
126 }
127 }
128 }
129
130 #ifdef WITH_DLP
HandleDlpAbilityOpened(const DlpStateData & data)131 void ConnectionObserverClientImpl::HandleDlpAbilityOpened(const DlpStateData &data)
132 {
133 auto observers = GetObservers();
134 for (auto it = observers.begin(); it != observers.end(); ++it) {
135 auto observer = *it;
136 if (observer) {
137 observer->OnDlpAbilityOpened(data);
138 }
139 }
140 }
141
HandleDlpAbilityClosed(const DlpStateData & data)142 void ConnectionObserverClientImpl::HandleDlpAbilityClosed(const DlpStateData &data)
143 {
144 auto observers = GetObservers();
145 for (auto it = observers.begin(); it != observers.end(); ++it) {
146 auto observer = *it;
147 if (observer) {
148 observer->OnDlpAbilityClosed(data);
149 }
150 }
151 }
152 #endif // WITH_DLP
153
RegisterObserverToServiceLocked(const std::shared_ptr<ServiceProxyAdapter> & proxy)154 bool ConnectionObserverClientImpl::RegisterObserverToServiceLocked(const std::shared_ptr<ServiceProxyAdapter> &proxy)
155 {
156 if (isRegistered_) {
157 return true;
158 }
159
160 if (!proxy) {
161 TAG_LOGE(AAFwkTag::CONNECTION, "fail to get service");
162 return false;
163 }
164
165 if (!observer_) {
166 observer_ = sptr<IConnectionObserver>(new (std::nothrow) ConnectionObserverStubImpl(shared_from_this()));
167 }
168
169 if (proxy->RegisterObserver(observer_) != ERR_OK) {
170 TAG_LOGE(AAFwkTag::CONNECTION, "register observer failed");
171 return false;
172 }
173 isRegistered_ = true;
174 return true;
175 }
176
UnregisterFromServiceLocked(const std::shared_ptr<ServiceProxyAdapter> & proxy)177 void ConnectionObserverClientImpl::UnregisterFromServiceLocked(const std::shared_ptr<ServiceProxyAdapter> &proxy)
178 {
179 if (!isRegistered_ || !observer_) {
180 return;
181 }
182
183 if (!proxy) {
184 return;
185 }
186
187 if (proxy->UnregisterObserver(observer_) != ERR_OK) {
188 TAG_LOGE(AAFwkTag::CONNECTION, "unregister observer failed");
189 return;
190 }
191 isRegistered_ = false;
192 }
193
AddObserversLocked(const std::shared_ptr<ConnectionObserver> & observer)194 int32_t ConnectionObserverClientImpl::AddObserversLocked(const std::shared_ptr<ConnectionObserver> &observer)
195 {
196 if (userObservers_.find(observer) != userObservers_.end()) {
197 TAG_LOGE(AAFwkTag::CONNECTION, "observer already registered");
198 return ERR_OBSERVER_ALREADY_REGISTERED;
199 }
200 userObservers_.emplace(observer);
201 return ERR_OK;
202 }
203
RemoveObserversLocked(const std::shared_ptr<ConnectionObserver> & observer)204 int32_t ConnectionObserverClientImpl::RemoveObserversLocked(const std::shared_ptr<ConnectionObserver> &observer)
205 {
206 if (userObservers_.find(observer) == userObservers_.end()) {
207 TAG_LOGE(AAFwkTag::CONNECTION, "no such observer");
208 return ERR_OBSERVER_NOT_REGISTERED;
209 }
210 userObservers_.erase(observer);
211 return ERR_OK;
212 }
213
GetServiceProxy()214 std::shared_ptr<ServiceProxyAdapter> ConnectionObserverClientImpl::GetServiceProxy()
215 {
216 std::lock_guard<std::mutex> guard(proxyLock_);
217 if (!serviceAdapter_) {
218 ConnectLocked();
219 }
220 return serviceAdapter_;
221 }
222
ConnectLocked()223 void ConnectionObserverClientImpl::ConnectLocked()
224 {
225 if (serviceAdapter_ != nullptr) {
226 return;
227 }
228 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
229 if (systemManager == nullptr) {
230 TAG_LOGE(AAFwkTag::CONNECTION, "get system ability registry failed");
231 return;
232 }
233 sptr<IRemoteObject> remoteObj = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
234 if (remoteObj == nullptr) {
235 TAG_LOGE(AAFwkTag::CONNECTION, "connect AMS failed");
236 return;
237 }
238
239 deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(
240 new (std::nothrow) ServiceDeathRecipient(shared_from_this()));
241 if (deathRecipient_ == nullptr) {
242 TAG_LOGE(AAFwkTag::CONNECTION, "create AbilityMgrDeathRecipient failed");
243 return;
244 }
245 if ((remoteObj->IsProxyObject()) && (!remoteObj->AddDeathRecipient(deathRecipient_))) {
246 TAG_LOGE(AAFwkTag::CONNECTION, "Add death recipient failed");
247 return;
248 }
249
250 serviceAdapter_ = std::make_shared<ServiceProxyAdapter>(remoteObj);
251 TAG_LOGI(AAFwkTag::CONNECTION, "Connect AMS success");
252 }
253
HandleRemoteDied(const wptr<IRemoteObject> & remote)254 void ConnectionObserverClientImpl::HandleRemoteDied(const wptr<IRemoteObject> &remote)
255 {
256 if (!ResetProxy(remote)) {
257 return;
258 }
259 NotifyServiceDiedToObservers();
260 }
261
ResetProxy(const wptr<IRemoteObject> & remote)262 bool ConnectionObserverClientImpl::ResetProxy(const wptr<IRemoteObject> &remote)
263 {
264 std::lock_guard<std::mutex> guard(proxyLock_);
265 if (serviceAdapter_ == nullptr) {
266 return false;
267 }
268
269 auto proxyObject = serviceAdapter_->GetProxyObject();
270 if ((proxyObject != nullptr) && (proxyObject == remote.promote())) {
271 proxyObject->RemoveDeathRecipient(deathRecipient_);
272 serviceAdapter_ = nullptr;
273 return true;
274 }
275
276 return false;
277 }
278
ResetStatus()279 void ConnectionObserverClientImpl::ResetStatus()
280 {
281 std::lock_guard<std::mutex> guard(observerLock_);
282 isRegistered_ = false;
283 userObservers_.clear();
284 }
285
NotifyServiceDiedToObservers()286 void ConnectionObserverClientImpl::NotifyServiceDiedToObservers()
287 {
288 auto observers = GetObservers();
289 ResetStatus();
290 for (auto it = observers.begin(); it != observers.end(); ++it) {
291 auto observer = *it;
292 if (observer) {
293 observer->OnServiceDied();
294 }
295 }
296 }
297
GetObservers()298 std::unordered_set<std::shared_ptr<ConnectionObserver>> ConnectionObserverClientImpl::GetObservers()
299 {
300 std::lock_guard<std::mutex> guard(observerLock_);
301 return userObservers_;
302 }
303
OnRemoteDied(const wptr<IRemoteObject> & remote)304 void ConnectionObserverClientImpl::ServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
305 {
306 TAG_LOGI(AAFwkTag::CONNECTION, "called");
307 auto owner = owner_.lock();
308 if (!owner) {
309 TAG_LOGE(AAFwkTag::CONNECTION, "OnRemoteDied");
310 return;
311 }
312 owner->HandleRemoteDied(remote);
313 }
314 } // namespace AbilityRuntime
315 } // namespace OHOS
316