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