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_state_manager.h"
17
18 #include "connection_observer_errors.h"
19 #include "global_constant.h"
20 #include "hilog_tag_wrapper.h"
21 #include "iservice_registry.h"
22 #include "system_ability_definition.h"
23
24 namespace OHOS {
25 namespace AAFwk {
26 namespace {
27 static const int MAX_RETRY = 10;
28 static const int DELAY_TIME = 1000;
GetAppMgr()29 OHOS::sptr<OHOS::AppExecFwk::IAppMgr> GetAppMgr()
30 {
31 OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
32 OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
33 if (!systemAbilityManager) {
34 return nullptr;
35 }
36 OHOS::sptr<OHOS::IRemoteObject> object = systemAbilityManager->GetSystemAbility(OHOS::APP_MGR_SERVICE_ID);
37 return OHOS::iface_cast<OHOS::AppExecFwk::IAppMgr>(object);
38 }
39 }
40 using namespace OHOS::AbilityRuntime;
41
ConnectionStateManager()42 ConnectionStateManager::ConnectionStateManager() {}
43
~ConnectionStateManager()44 ConnectionStateManager::~ConnectionStateManager() {}
45
GetProcessNameByPid(int32_t pid)46 std::string ConnectionStateManager::GetProcessNameByPid(int32_t pid)
47 {
48 return std::to_string(pid);
49 }
50
Init(const std::shared_ptr<TaskHandlerWrap> & handler)51 void ConnectionStateManager::Init(const std::shared_ptr<TaskHandlerWrap> &handler)
52 {
53 if (!observerController_) {
54 observerController_ = std::make_shared<ConnectionObserverController>();
55 }
56 handler_ = handler;
57 if (!handler) {
58 TAG_LOGW(AAFwkTag::CONNECTION, "invalid eventhandler");
59 InitAppStateObserver();
60 return;
61 }
62 auto initConnectionStateManagerTask = [weak = weak_from_this()]() {
63 auto self = weak.lock();
64 if (!self) {
65 TAG_LOGW(AAFwkTag::CONNECTION, "invalid self pointer");
66 return;
67 }
68 self->InitAppStateObserver();
69 };
70 handler->SubmitTask(initConnectionStateManagerTask, "InitConnectionStateManager");
71 }
72
RegisterObserver(const sptr<AbilityRuntime::IConnectionObserver> & observer)73 int ConnectionStateManager::RegisterObserver(const sptr<AbilityRuntime::IConnectionObserver> &observer)
74 {
75 if (!observerController_) {
76 return ERR_SERVICE_NOT_INIT;
77 }
78
79 return observerController_->AddObserver(observer);
80 }
81
UnregisterObserver(const sptr<AbilityRuntime::IConnectionObserver> & observer)82 int ConnectionStateManager::UnregisterObserver(const sptr<AbilityRuntime::IConnectionObserver> &observer)
83 {
84 if (!observerController_) {
85 return ERR_SERVICE_NOT_INIT;
86 }
87 observerController_->RemoveObserver(observer);
88
89 return 0;
90 }
91
AddConnection(std::shared_ptr<ConnectionRecord> connectionRecord)92 void ConnectionStateManager::AddConnection(std::shared_ptr<ConnectionRecord> connectionRecord)
93 {
94 std::shared_ptr<ConnectionObserverController> controller = observerController_;
95 if (!controller) {
96 return;
97 }
98
99 if (!connectionRecord) {
100 TAG_LOGE(AAFwkTag::CONNECTION, "invalid connection record");
101 return;
102 }
103
104 ConnectionData connectionData;
105 if (!AddConnectionInner(connectionRecord, connectionData)) {
106 TAG_LOGD(AAFwkTag::CONNECTION, "no need notify observers");
107 return;
108 }
109 controller->NotifyExtensionConnected(connectionData);
110 }
111
RemoveConnection(std::shared_ptr<ConnectionRecord> connectionRecord,bool isCallerDied)112 void ConnectionStateManager::RemoveConnection(std::shared_ptr<ConnectionRecord> connectionRecord,
113 bool isCallerDied)
114 {
115 std::shared_ptr<ConnectionObserverController> controller = observerController_;
116 if (!controller) {
117 return;
118 }
119
120 if (!connectionRecord) {
121 TAG_LOGE(AAFwkTag::CONNECTION, "invalid connection record");
122 return;
123 }
124
125 // if caller died, notify at once.
126 if (isCallerDied) {
127 HandleCallerDied(connectionRecord->GetCallerPid());
128 return;
129 }
130
131 ConnectionData connectionData;
132 if (!RemoveConnectionInner(connectionRecord, connectionData)) {
133 TAG_LOGD(AAFwkTag::CONNECTION, "no need notify observers");
134 return;
135 }
136 controller->NotifyExtensionDisconnected(connectionData);
137 }
138
AddDataAbilityConnection(const DataAbilityCaller & caller,const std::shared_ptr<DataAbilityRecord> & record)139 void ConnectionStateManager::AddDataAbilityConnection(const DataAbilityCaller &caller,
140 const std::shared_ptr<DataAbilityRecord> &record)
141 {
142 if (!CheckDataAbilityConnectionParams(caller, record)) {
143 return;
144 }
145
146 ConnectionData connectionData;
147 if (!AddDataAbilityConnectionInner(caller, record, connectionData)) {
148 TAG_LOGW(AAFwkTag::CONNECTION, "no need notify observers");
149 return;
150 }
151 observerController_->NotifyExtensionConnected(connectionData);
152 }
153
RemoveDataAbilityConnection(const DataAbilityCaller & caller,const std::shared_ptr<DataAbilityRecord> & record)154 void ConnectionStateManager::RemoveDataAbilityConnection(const DataAbilityCaller &caller,
155 const std::shared_ptr<DataAbilityRecord> &record)
156 {
157 if (!CheckDataAbilityConnectionParams(caller, record)) {
158 return;
159 }
160
161 ConnectionData connectionData;
162 if (!RemoveDataAbilityConnectionInner(caller, record, connectionData)) {
163 TAG_LOGW(AAFwkTag::CONNECTION, "no need notify observers");
164 return;
165 }
166 observerController_->NotifyExtensionDisconnected(connectionData);
167 }
168
CheckDataAbilityConnectionParams(const DataAbilityCaller & caller,const std::shared_ptr<DataAbilityRecord> & record) const169 bool ConnectionStateManager::CheckDataAbilityConnectionParams(const DataAbilityCaller &caller,
170 const std::shared_ptr<DataAbilityRecord> &record) const
171 {
172 if (!observerController_) {
173 return false;
174 }
175
176 if (!record) {
177 TAG_LOGE(AAFwkTag::CONNECTION, "invalid data ability record");
178 return false;
179 }
180
181 if (caller.callerPid == 0) {
182 TAG_LOGE(AAFwkTag::CONNECTION, "invalid callerPid");
183 return false;
184 }
185
186 return true;
187 }
188
HandleDataAbilityDied(const std::shared_ptr<DataAbilityRecord> & record)189 void ConnectionStateManager::HandleDataAbilityDied(const std::shared_ptr<DataAbilityRecord> &record)
190 {
191 if (!record) {
192 TAG_LOGE(AAFwkTag::CONNECTION, "invalid data ability");
193 return;
194 }
195
196 auto token = record->GetToken();
197 if (!token) {
198 TAG_LOGE(AAFwkTag::CONNECTION, "invalid token");
199 return;
200 }
201
202 std::vector<AbilityRuntime::ConnectionData> allData;
203 HandleDataAbilityDiedInner(token, allData);
204 if (allData.empty()) {
205 TAG_LOGW(AAFwkTag::CONNECTION, "empty allData");
206 return;
207 }
208
209 std::shared_ptr<ConnectionObserverController> controller = observerController_;
210 if (!controller) {
211 return;
212 }
213
214 for (auto& item : allData) {
215 controller->NotifyExtensionDisconnected(item);
216 }
217 }
218
HandleDataAbilityCallerDied(int32_t callerPid)219 void ConnectionStateManager::HandleDataAbilityCallerDied(int32_t callerPid)
220 {
221 if (callerPid <= 0) {
222 TAG_LOGW(AAFwkTag::CONNECTION, "invalid callerPid");
223 return;
224 }
225
226 HandleCallerDied(callerPid);
227 }
228
229 #ifdef WITH_DLP
AddDlpManager(const std::shared_ptr<AbilityRecord> & dlpManger)230 void ConnectionStateManager::AddDlpManager(const std::shared_ptr<AbilityRecord> &dlpManger)
231 {
232 if (!dlpManger) {
233 return;
234 }
235
236 auto userId = dlpManger->GetOwnerMissionUserId();
237 std::lock_guard<ffrt::mutex> guard(dlpLock_);
238 auto it = dlpItems_.find(userId);
239 if (it == dlpItems_.end()) {
240 dlpItems_[userId] = std::make_shared<DlpStateItem>(dlpManger->GetUid(), dlpManger->GetPid());
241 }
242 }
243
RemoveDlpManager(const std::shared_ptr<AbilityRecord> & dlpManger)244 void ConnectionStateManager::RemoveDlpManager(const std::shared_ptr<AbilityRecord> &dlpManger)
245 {
246 if (!dlpManger) {
247 return;
248 }
249
250 std::lock_guard<ffrt::mutex> guard(dlpLock_);
251 dlpItems_.erase(dlpManger->GetOwnerMissionUserId());
252 }
253
AddDlpAbility(const std::shared_ptr<AbilityRecord> & dlpAbility)254 void ConnectionStateManager::AddDlpAbility(const std::shared_ptr<AbilityRecord> &dlpAbility)
255 {
256 std::shared_ptr<ConnectionObserverController> controller = observerController_;
257 if (!controller) {
258 return;
259 }
260
261 DlpStateData dlpData;
262 if (!HandleDlpAbilityInner(dlpAbility, true, dlpData)) {
263 TAG_LOGD(AAFwkTag::CONNECTION, "no need report dlp opened conn state");
264 return;
265 }
266 controller->NotifyDlpAbilityOpened(dlpData);
267 }
268
RemoveDlpAbility(const std::shared_ptr<AbilityRecord> & dlpAbility)269 void ConnectionStateManager::RemoveDlpAbility(const std::shared_ptr<AbilityRecord> &dlpAbility)
270 {
271 std::shared_ptr<ConnectionObserverController> controller = observerController_;
272 if (!controller) {
273 return;
274 }
275
276 DlpStateData dlpData;
277 if (!HandleDlpAbilityInner(dlpAbility, false, dlpData)) {
278 TAG_LOGD(AAFwkTag::CONNECTION, "no need report dlp closed conn state");
279 return;
280 }
281 controller->NotifyDlpAbilityClosed(dlpData);
282 }
283 #endif // WITH_DLP
284
HandleAppDied(int32_t pid)285 void ConnectionStateManager::HandleAppDied(int32_t pid)
286 {
287 HandleCallerDied(pid);
288 }
289
290 #ifdef WITH_DLP
GetDlpConnectionInfos(std::vector<AbilityRuntime::DlpConnectionInfo> & infos)291 void ConnectionStateManager::GetDlpConnectionInfos(std::vector<AbilityRuntime::DlpConnectionInfo> &infos)
292 {
293 std::lock_guard<ffrt::mutex> guard(dlpLock_);
294 for (auto it = dlpItems_.begin(); it != dlpItems_.end(); it++) {
295 auto item = it->second;
296 if (!item) {
297 continue;
298 }
299
300 AbilityRuntime::DlpConnectionInfo info;
301 info.dlpUid = item->GetDlpUid();
302 info.openedAbilityCount = item->GetOpenedAbilitySize();
303 infos.emplace_back(info);
304 }
305 }
306 #endif // WITH_DLP
307
GetConnectionData(std::vector<AbilityRuntime::ConnectionData> & connectionData)308 void ConnectionStateManager::GetConnectionData(std::vector<AbilityRuntime::ConnectionData> &connectionData)
309 {
310 std::lock_guard guard(stateLock_);
311 for (const auto &stateItem : connectionStates_) {
312 if (!stateItem.second) {
313 TAG_LOGW(AAFwkTag::CONNECTION, "Unexpected null");
314 continue;
315 }
316
317 std::vector<AbilityRuntime::ConnectionData> allConnectionData;
318 stateItem.second->GenerateAllConnectionData(allConnectionData);
319 connectionData.insert(connectionData.end(), allConnectionData.begin(), allConnectionData.end());
320 }
321 TAG_LOGD(AAFwkTag::CONNECTION, "GetConnectionData: %{public}zu", connectionData.size());
322 }
323
AddConnectionInner(std::shared_ptr<ConnectionRecord> connectionRecord,AbilityRuntime::ConnectionData & data)324 bool ConnectionStateManager::AddConnectionInner(std::shared_ptr<ConnectionRecord> connectionRecord,
325 AbilityRuntime::ConnectionData &data)
326 {
327 std::shared_ptr<ConnectionStateItem> targetItem = nullptr;
328 auto callerPid = connectionRecord->GetCallerPid();
329 std::lock_guard<ffrt::mutex> guard(stateLock_);
330 auto it = connectionStates_.find(callerPid);
331 if (it == connectionStates_.end()) {
332 targetItem = ConnectionStateItem::CreateConnectionStateItem(connectionRecord);
333 if (targetItem) {
334 connectionStates_[callerPid] = targetItem;
335 }
336 } else {
337 targetItem = it->second;
338 }
339
340 if (!targetItem) {
341 TAG_LOGE(AAFwkTag::CONNECTION, "find targetItem failed");
342 return false;
343 }
344
345 return targetItem->AddConnection(connectionRecord, data);
346 }
347
RemoveConnectionInner(std::shared_ptr<ConnectionRecord> connectionRecord,AbilityRuntime::ConnectionData & data)348 bool ConnectionStateManager::RemoveConnectionInner(std::shared_ptr<ConnectionRecord> connectionRecord,
349 AbilityRuntime::ConnectionData &data)
350 {
351 auto callerPid = connectionRecord->GetCallerPid();
352 std::lock_guard<ffrt::mutex> guard(stateLock_);
353 auto it = connectionStates_.find(callerPid);
354 if (it == connectionStates_.end()) {
355 TAG_LOGW(AAFwkTag::CONNECTION, "find target failed, callerPid:%{public}d", callerPid);
356 return false;
357 }
358
359 auto targetItem = it->second;
360 if (!targetItem) {
361 TAG_LOGE(AAFwkTag::CONNECTION, "find targetItem failed");
362 return false;
363 }
364
365 bool result = targetItem->RemoveConnection(connectionRecord, data);
366 if (result && targetItem->IsEmpty()) {
367 connectionStates_.erase(it);
368 }
369 return result;
370 }
371
HandleCallerDied(int32_t callerPid)372 void ConnectionStateManager::HandleCallerDied(int32_t callerPid)
373 {
374 auto connectionStateItem = RemoveDiedCaller(callerPid);
375 if (!connectionStateItem) {
376 TAG_LOGD(AAFwkTag::CONNECTION, "no connectionStateItem");
377 return;
378 }
379
380 std::vector<AbilityRuntime::ConnectionData> allConnectionData;
381 connectionStateItem->GenerateAllConnectionData(allConnectionData);
382 if (allConnectionData.empty()) {
383 TAG_LOGW(AAFwkTag::CONNECTION, "empty allConnectionData");
384 return;
385 }
386
387 std::shared_ptr<ConnectionObserverController> controller = observerController_;
388 if (!controller) {
389 return;
390 }
391
392 for (auto& connectionData : allConnectionData) {
393 controller->NotifyExtensionDisconnected(connectionData);
394 }
395 }
396
RemoveDiedCaller(int32_t callerPid)397 std::shared_ptr<ConnectionStateItem> ConnectionStateManager::RemoveDiedCaller(int32_t callerPid)
398 {
399 std::lock_guard<ffrt::mutex> guard(stateLock_);
400 auto it = connectionStates_.find(callerPid);
401 if (it == connectionStates_.end()) {
402 TAG_LOGW(AAFwkTag::CONNECTION, "callerPid:%{public}d.", callerPid);
403 return nullptr;
404 }
405 auto stateItem = it->second;
406 (void)connectionStates_.erase(it);
407
408 return stateItem;
409 }
410
AddDataAbilityConnectionInner(const DataAbilityCaller & caller,const std::shared_ptr<DataAbilityRecord> & record,ConnectionData & data)411 bool ConnectionStateManager::AddDataAbilityConnectionInner(const DataAbilityCaller &caller,
412 const std::shared_ptr<DataAbilityRecord> &record, ConnectionData &data)
413 {
414 std::shared_ptr<ConnectionStateItem> targetItem = nullptr;
415 std::lock_guard<ffrt::mutex> guard(stateLock_);
416 auto it = connectionStates_.find(caller.callerPid);
417 if (it == connectionStates_.end()) {
418 targetItem = ConnectionStateItem::CreateConnectionStateItem(caller);
419 if (targetItem) {
420 connectionStates_[caller.callerPid] = targetItem;
421 }
422 } else {
423 targetItem = it->second;
424 }
425
426 if (!targetItem) {
427 TAG_LOGE(AAFwkTag::CONNECTION, "find targetItem failed");
428 return false;
429 }
430
431 return targetItem->AddDataAbilityConnection(caller, record, data);
432 }
433
RemoveDataAbilityConnectionInner(const DataAbilityCaller & caller,const std::shared_ptr<DataAbilityRecord> & record,AbilityRuntime::ConnectionData & data)434 bool ConnectionStateManager::RemoveDataAbilityConnectionInner(const DataAbilityCaller &caller,
435 const std::shared_ptr<DataAbilityRecord> &record, AbilityRuntime::ConnectionData &data)
436 {
437 std::lock_guard<ffrt::mutex> guard(stateLock_);
438 auto it = connectionStates_.find(caller.callerPid);
439 if (it == connectionStates_.end()) {
440 TAG_LOGW(AAFwkTag::CONNECTION, "find target item failed, callerPid:%{public}d", caller.callerPid);
441 return false;
442 }
443
444 auto targetItem = it->second;
445 if (!targetItem) {
446 TAG_LOGE(AAFwkTag::CONNECTION, "find targetItem failed");
447 return false;
448 }
449
450 bool result = targetItem->RemoveDataAbilityConnection(caller, record, data);
451 if (result && targetItem->IsEmpty()) {
452 connectionStates_.erase(it);
453 }
454 return result;
455 }
456
HandleDataAbilityDiedInner(const sptr<IRemoteObject> & abilityToken,std::vector<AbilityRuntime::ConnectionData> & allData)457 void ConnectionStateManager::HandleDataAbilityDiedInner(const sptr<IRemoteObject> &abilityToken,
458 std::vector<AbilityRuntime::ConnectionData> &allData)
459 {
460 std::lock_guard<ffrt::mutex> guard(stateLock_);
461 for (auto it = connectionStates_.begin(); it != connectionStates_.end();) {
462 auto item = it->second;
463 if (!item) {
464 connectionStates_.erase(it++);
465 continue;
466 }
467
468 AbilityRuntime::ConnectionData data;
469 if (item->HandleDataAbilityDied(abilityToken, data)) {
470 allData.emplace_back(data);
471 }
472
473 if (item->IsEmpty()) {
474 connectionStates_.erase(it++);
475 } else {
476 it++;
477 }
478 }
479 }
480
481 #ifdef WITH_DLP
HandleDlpAbilityInner(const std::shared_ptr<AbilityRecord> & dlpAbility,bool isAdd,AbilityRuntime::DlpStateData & dlpData)482 bool ConnectionStateManager::HandleDlpAbilityInner(const std::shared_ptr<AbilityRecord> &dlpAbility,
483 bool isAdd, AbilityRuntime::DlpStateData &dlpData)
484 {
485 if (!dlpAbility) {
486 TAG_LOGD(AAFwkTag::CONNECTION, "invalid dlp ability");
487 return false;
488 }
489
490 if (dlpAbility->GetAppIndex() <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
491 TAG_LOGD(AAFwkTag::CONNECTION, " not dlp ability, do not report connection stat");
492 return false;
493 }
494
495 std::lock_guard<ffrt::mutex> guard(dlpLock_);
496 auto it = dlpItems_.find(dlpAbility->GetOwnerMissionUserId());
497 if (it == dlpItems_.end()) {
498 TAG_LOGW(AAFwkTag::CONNECTION, "invalid state");
499 return false;
500 }
501
502 auto dlpItem = it->second;
503 if (!dlpItem) {
504 TAG_LOGW(AAFwkTag::CONNECTION, "invalid dlpItem");
505 return false;
506 }
507
508 if (isAdd) {
509 return dlpItem->AddDlpConnectionState(dlpAbility, dlpData);
510 }
511
512 return dlpItem->RemoveDlpConnectionState(dlpAbility, dlpData);
513 }
514 #endif // WITH_DLP
515
InitAppStateObserver()516 void ConnectionStateManager::InitAppStateObserver()
517 {
518 if (appStateObserver_) {
519 return;
520 }
521
522 sptr<OHOS::AppExecFwk::IAppMgr> appManager = GetAppMgr();
523 if (!appManager) {
524 TAG_LOGW(AAFwkTag::CONNECTION, "null appManager, retry:%{public}d", retry_);
525 if (retry_ < MAX_RETRY && handler_) {
526 auto initConnectionStateManagerTask = [weak = weak_from_this()]() {
527 auto self = weak.lock();
528 if (!self) {
529 TAG_LOGW(AAFwkTag::CONNECTION, "invalid self pointer");
530 return;
531 }
532 self->InitAppStateObserver();
533 };
534 handler_->SubmitTask(initConnectionStateManagerTask, "InitConnectionStateManager", DELAY_TIME);
535 retry_++;
536 }
537 return;
538 }
539
540 appStateObserver_ = new (std::nothrow)InnerAppStateObserver([](int32_t pid) {
541 DelayedSingleton<ConnectionStateManager>::GetInstance()->HandleAppDied(pid);
542 });
543 int32_t err = appManager->RegisterApplicationStateObserver(appStateObserver_);
544 if (err != 0) {
545 TAG_LOGE(AAFwkTag::CONNECTION, "register to appmanager err:%{public}d", err);
546 appStateObserver_ = nullptr;
547 return;
548 }
549 }
550 } // namespace AAFwk
551 } // namespace OHOS
552