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