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