• 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(std::shared_ptr<ConnectionRecord> connectionRecord)95 void ConnectionStateManager::AddConnection(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(std::shared_ptr<ConnectionRecord> connectionRecord,bool isCallerDied)115 void ConnectionStateManager::RemoveConnection(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 
GetConnectionData(std::vector<AbilityRuntime::ConnectionData> & connectionData)307 void ConnectionStateManager::GetConnectionData(std::vector<AbilityRuntime::ConnectionData> &connectionData)
308 {
309     std::lock_guard guard(stateLock_);
310     for (const auto &stateItem : connectionStates_) {
311         if (!stateItem.second) {
312             HILOG_WARN("Unexpected null");
313             continue;
314         }
315 
316         std::vector<AbilityRuntime::ConnectionData> allConnectionData;
317         stateItem.second->GenerateAllConnectionData(allConnectionData);
318         connectionData.insert(connectionData.end(), allConnectionData.begin(), allConnectionData.end());
319     }
320     HILOG_DEBUG("GetConnectionData: %{public}zu", connectionData.size());
321 }
322 
AddConnectionInner(std::shared_ptr<ConnectionRecord> connectionRecord,AbilityRuntime::ConnectionData & data)323 bool ConnectionStateManager::AddConnectionInner(std::shared_ptr<ConnectionRecord> connectionRecord,
324     AbilityRuntime::ConnectionData &data)
325 {
326     std::shared_ptr<ConnectionStateItem> targetItem = nullptr;
327     auto callerPid = connectionRecord->GetCallerPid();
328     std::lock_guard<ffrt::mutex> guard(stateLock_);
329     auto it = connectionStates_.find(callerPid);
330     if (it == connectionStates_.end()) {
331         targetItem = ConnectionStateItem::CreateConnectionStateItem(connectionRecord);
332         if (targetItem) {
333             connectionStates_[callerPid] = targetItem;
334         }
335     } else {
336         targetItem = it->second;
337     }
338 
339     if (!targetItem) {
340         HILOG_ERROR("failed to find target connection state item.");
341         return false;
342     }
343 
344     return targetItem->AddConnection(connectionRecord, data);
345 }
346 
RemoveConnectionInner(std::shared_ptr<ConnectionRecord> connectionRecord,AbilityRuntime::ConnectionData & data)347 bool ConnectionStateManager::RemoveConnectionInner(std::shared_ptr<ConnectionRecord> connectionRecord,
348     AbilityRuntime::ConnectionData &data)
349 {
350     auto callerPid = connectionRecord->GetCallerPid();
351     std::lock_guard<ffrt::mutex> guard(stateLock_);
352     auto it = connectionStates_.find(callerPid);
353     if (it == connectionStates_.end()) {
354         HILOG_WARN("can not find target item, connection caller pid:%{public}d.", callerPid);
355         return false;
356     }
357 
358     auto targetItem = it->second;
359     if (!targetItem) {
360         HILOG_ERROR("failed to find target connection state item.");
361         return false;
362     }
363 
364     bool result = targetItem->RemoveConnection(connectionRecord, data);
365     if (result && targetItem->IsEmpty()) {
366         connectionStates_.erase(it);
367     }
368     return result;
369 }
370 
HandleCallerDied(int32_t callerPid)371 void ConnectionStateManager::HandleCallerDied(int32_t callerPid)
372 {
373     auto connectionStateItem = RemoveDiedCaller(callerPid);
374     if (!connectionStateItem) {
375         HILOG_DEBUG("no connectionStateItem, may already handled.");
376         return;
377     }
378 
379     std::vector<AbilityRuntime::ConnectionData> allConnectionData;
380     connectionStateItem->GenerateAllConnectionData(allConnectionData);
381     if (allConnectionData.empty()) {
382         HILOG_WARN("allConnectionData is empty.");
383         return;
384     }
385 
386     std::shared_ptr<ConnectionObserverController> controller = observerController_;
387     if (!controller) {
388         return;
389     }
390 
391     for (auto& connectionData : allConnectionData) {
392         controller->NotifyExtensionDisconnected(connectionData);
393     }
394 }
395 
RemoveDiedCaller(int32_t callerPid)396 std::shared_ptr<ConnectionStateItem> ConnectionStateManager::RemoveDiedCaller(int32_t callerPid)
397 {
398     std::lock_guard<ffrt::mutex> guard(stateLock_);
399     auto it = connectionStates_.find(callerPid);
400     if (it == connectionStates_.end()) {
401         HILOG_WARN("connection caller pid:%{public}d.", callerPid);
402         return nullptr;
403     }
404     auto stateItem = it->second;
405     (void)connectionStates_.erase(it);
406 
407     return stateItem;
408 }
409 
AddDataAbilityConnectionInner(const DataAbilityCaller & caller,const std::shared_ptr<DataAbilityRecord> & record,ConnectionData & data)410 bool ConnectionStateManager::AddDataAbilityConnectionInner(const DataAbilityCaller &caller,
411     const std::shared_ptr<DataAbilityRecord> &record, ConnectionData &data)
412 {
413     std::shared_ptr<ConnectionStateItem> targetItem = nullptr;
414     std::lock_guard<ffrt::mutex> guard(stateLock_);
415     auto it = connectionStates_.find(caller.callerPid);
416     if (it == connectionStates_.end()) {
417         targetItem = ConnectionStateItem::CreateConnectionStateItem(caller);
418         if (targetItem) {
419             connectionStates_[caller.callerPid] = targetItem;
420         }
421     } else {
422         targetItem = it->second;
423     }
424 
425     if (!targetItem) {
426         HILOG_ERROR("failed to find target connection state item.");
427         return false;
428     }
429 
430     return targetItem->AddDataAbilityConnection(caller, record, data);
431 }
432 
RemoveDataAbilityConnectionInner(const DataAbilityCaller & caller,const std::shared_ptr<DataAbilityRecord> & record,AbilityRuntime::ConnectionData & data)433 bool ConnectionStateManager::RemoveDataAbilityConnectionInner(const DataAbilityCaller &caller,
434     const std::shared_ptr<DataAbilityRecord> &record, AbilityRuntime::ConnectionData &data)
435 {
436     std::lock_guard<ffrt::mutex> guard(stateLock_);
437     auto it = connectionStates_.find(caller.callerPid);
438     if (it == connectionStates_.end()) {
439         HILOG_WARN("can not find target item, connection caller pid:%{public}d.", caller.callerPid);
440         return false;
441     }
442 
443     auto targetItem = it->second;
444     if (!targetItem) {
445         HILOG_ERROR("failed to find target data ability state item.");
446         return false;
447     }
448 
449     bool result = targetItem->RemoveDataAbilityConnection(caller, record, data);
450     if (result && targetItem->IsEmpty()) {
451         connectionStates_.erase(it);
452     }
453     return result;
454 }
455 
HandleDataAbilityDiedInner(const sptr<IRemoteObject> & abilityToken,std::vector<AbilityRuntime::ConnectionData> & allData)456 void ConnectionStateManager::HandleDataAbilityDiedInner(const sptr<IRemoteObject> &abilityToken,
457     std::vector<AbilityRuntime::ConnectionData> &allData)
458 {
459     std::lock_guard<ffrt::mutex> guard(stateLock_);
460     for (auto it = connectionStates_.begin(); it != connectionStates_.end();) {
461         auto item = it->second;
462         if (!item) {
463             connectionStates_.erase(it++);
464             continue;
465         }
466 
467         AbilityRuntime::ConnectionData data;
468         if (item->HandleDataAbilityDied(abilityToken, data)) {
469             allData.emplace_back(data);
470         }
471 
472         if (item->IsEmpty()) {
473             connectionStates_.erase(it++);
474         } else {
475             it++;
476         }
477     }
478 }
479 
HandleDlpAbilityInner(const std::shared_ptr<AbilityRecord> & dlpAbility,bool isAdd,AbilityRuntime::DlpStateData & dlpData)480 bool ConnectionStateManager::HandleDlpAbilityInner(const std::shared_ptr<AbilityRecord> &dlpAbility,
481     bool isAdd, AbilityRuntime::DlpStateData &dlpData)
482 {
483     if (!dlpAbility) {
484         HILOG_DEBUG("invalid dlp ability.");
485         return false;
486     }
487 
488     if (dlpAbility->GetAppIndex() == 0) {
489         HILOG_DEBUG("this is not dlp ability, do not report connection stat.");
490         return false;
491     }
492 
493     std::lock_guard<ffrt::mutex> guard(dlpLock_);
494     auto it = dlpItems_.find(dlpAbility->GetOwnerMissionUserId());
495     if (it == dlpItems_.end()) {
496         HILOG_WARN("no dlp manager, invalid state.");
497         return false;
498     }
499 
500     auto dlpItem = it->second;
501     if (!dlpItem) {
502         HILOG_WARN("invalid dlpItem.");
503         return false;
504     }
505 
506     if (isAdd) {
507         return dlpItem->AddDlpConnectionState(dlpAbility, dlpData);
508     }
509 
510     return dlpItem->RemoveDlpConnectionState(dlpAbility, dlpData);
511 }
512 
InitAppStateObserver()513 void ConnectionStateManager::InitAppStateObserver()
514 {
515     if (appStateObserver_) {
516         return;
517     }
518 
519     sptr<OHOS::AppExecFwk::IAppMgr> appManager = GetAppMgr();
520     if (!appManager) {
521         HILOG_WARN("%{public}s app manager nullptr! retry:%{public}d", __func__, retry_);
522         if (retry_ < MAX_RETRY && handler_) {
523             auto initConnectionStateManagerTask = [weak = weak_from_this()]() {
524                 auto self = weak.lock();
525                 if (!self) {
526                     HILOG_WARN("invalid self pointer");
527                     return;
528                 }
529                 self->InitAppStateObserver();
530             };
531             handler_->SubmitTask(initConnectionStateManagerTask, "InitConnectionStateManager", DELAY_TIME);
532             retry_++;
533         }
534         return;
535     }
536 
537     appStateObserver_ = new (std::nothrow)InnerAppStateObserver([](int32_t pid) {
538         DelayedSingleton<ConnectionStateManager>::GetInstance()->HandleAppDied(pid);
539     });
540     int32_t err = appManager->RegisterApplicationStateObserver(appStateObserver_);
541     if (err != 0) {
542         HILOG_ERROR("%{public}s register to appmanager failed. err:%{public}d", __func__, err);
543         appStateObserver_ = nullptr;
544         return;
545     }
546 }
547 } // namespace AAFwk
548 } // namespace OHOS
549