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