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