• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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