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