• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "ability_connect_manager.h"
17 
18 #include <algorithm>
19 
20 #include "ability_connect_callback_stub.h"
21 #include "ability_manager_errors.h"
22 #include "ability_manager_service.h"
23 #include "ability_util.h"
24 #include "hitrace_meter.h"
25 #include "hilog_wrapper.h"
26 #include "in_process_call_wrapper.h"
27 #include "parameter.h"
28 
29 namespace OHOS {
30 namespace AAFwk {
AbilityConnectManager(int userId)31 AbilityConnectManager::AbilityConnectManager(int userId) : userId_(userId)
32 {}
33 
~AbilityConnectManager()34 AbilityConnectManager::~AbilityConnectManager()
35 {}
36 
StartAbility(const AbilityRequest & abilityRequest)37 int AbilityConnectManager::StartAbility(const AbilityRequest &abilityRequest)
38 {
39     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
40     std::lock_guard<std::recursive_mutex> guard(Lock_);
41     return StartAbilityLocked(abilityRequest);
42 }
43 
TerminateAbility(const sptr<IRemoteObject> & token)44 int AbilityConnectManager::TerminateAbility(const sptr<IRemoteObject> &token)
45 {
46     std::lock_guard<std::recursive_mutex> guard(Lock_);
47     auto abilityRecord = GetExtensionByTokenFromSeriveMap(token);
48     MoveToTerminatingMap(abilityRecord);
49     return TerminateAbilityLocked(token);
50 }
51 
TerminateAbility(const std::shared_ptr<AbilityRecord> & caller,int requestCode)52 int AbilityConnectManager::TerminateAbility(const std::shared_ptr<AbilityRecord> &caller, int requestCode)
53 {
54     HILOG_INFO("Terminate ability.");
55     std::lock_guard<std::recursive_mutex> guard(Lock_);
56 
57     std::shared_ptr<AbilityRecord> targetAbility = nullptr;
58     int result = static_cast<int>(ABILITY_VISIBLE_FALSE_DENY_REQUEST);
59     std::for_each(serviceMap_.begin(),
60         serviceMap_.end(),
61         [&targetAbility, &caller, requestCode, &result](ServiceMapType::reference service) {
62             auto callerList = service.second->GetCallerRecordList();
63             for (auto &it : callerList) {
64                 if (it->GetCaller() == caller && it->GetRequestCode() == requestCode) {
65                     targetAbility = service.second;
66                     if (targetAbility) {
67                         auto abilityMs = DelayedSingleton<AbilityManagerService>::GetInstance();
68                         CHECK_POINTER(abilityMs);
69                         result = abilityMs->JudgeAbilityVisibleControl(targetAbility->GetAbilityInfo());
70                     }
71                     break;
72                 }
73             }
74         });
75 
76     if (!targetAbility) {
77         HILOG_ERROR("targetAbility error.");
78         return NO_FOUND_ABILITY_BY_CALLER;
79     }
80     if (result != ERR_OK) {
81         HILOG_ERROR("%{public}s JudgeAbilityVisibleControl error.", __func__);
82         return result;
83     }
84 
85     MoveToTerminatingMap(targetAbility);
86     return TerminateAbilityLocked(targetAbility->GetToken());
87 }
88 
StopServiceAbility(const AbilityRequest & abilityRequest)89 int AbilityConnectManager::StopServiceAbility(const AbilityRequest &abilityRequest)
90 {
91     HILOG_INFO("Stop Service ability.");
92     std::lock_guard<std::recursive_mutex> guard(Lock_);
93     return StopServiceAbilityLocked(abilityRequest);
94 }
95 
TerminateAbilityResult(const sptr<IRemoteObject> & token,int startId)96 int AbilityConnectManager::TerminateAbilityResult(const sptr<IRemoteObject> &token, int startId)
97 {
98     HILOG_INFO("Terminate ability result.");
99     std::lock_guard<std::recursive_mutex> guard(Lock_);
100     return TerminateAbilityResultLocked(token, startId);
101 }
102 
StartAbilityLocked(const AbilityRequest & abilityRequest)103 int AbilityConnectManager::StartAbilityLocked(const AbilityRequest &abilityRequest)
104 {
105     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
106     HILOG_INFO("Start ability locked, ability_name: %{public}s",
107         abilityRequest.want.GetElement().GetURI().c_str());
108 
109     std::shared_ptr<AbilityRecord> targetService;
110     bool isLoadedAbility = false;
111     GetOrCreateServiceRecord(abilityRequest, false, targetService, isLoadedAbility);
112     CHECK_POINTER_AND_RETURN(targetService, ERR_INVALID_VALUE);
113 
114     targetService->AddCallerRecord(abilityRequest.callerToken, abilityRequest.requestCode);
115 
116     if (!isLoadedAbility) {
117         LoadAbility(targetService);
118     } else if (targetService->IsAbilityState(AbilityState::ACTIVE)) {
119         // It may have been started through connect
120         CommandAbility(targetService);
121     } else {
122         HILOG_ERROR("Target service is already activating.");
123         return START_SERVICE_ABILITY_ACTIVATING;
124     }
125 
126     sptr<Token> token = targetService->GetToken();
127     sptr<Token> preToken = nullptr;
128     if (targetService->GetPreAbilityRecord()) {
129         preToken = targetService->GetPreAbilityRecord()->GetToken();
130     }
131     DelayedSingleton<AppScheduler>::GetInstance()->AbilityBehaviorAnalysis(token, preToken, 0, 1, 1);
132     return ERR_OK;
133 }
134 
TerminateAbilityLocked(const sptr<IRemoteObject> & token)135 int AbilityConnectManager::TerminateAbilityLocked(const sptr<IRemoteObject> &token)
136 {
137     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
138     HILOG_INFO("Terminate ability locked.");
139     auto abilityRecord = GetExtensionByTokenFromTerminatingMap(token);
140     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
141 
142     if (abilityRecord->IsTerminating()) {
143         HILOG_INFO("Ability is on terminating.");
144         return ERR_OK;
145     }
146 
147     if (!abilityRecord->GetConnectRecordList().empty()) {
148         HILOG_INFO("Target service has been connected. Post disconnect task.");
149         auto connectRecordList = abilityRecord->GetConnectRecordList();
150         HandleTerminateDisconnectTask(connectRecordList);
151     }
152 
153     auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
154         HILOG_WARN("Disconnect ability terminate timeout.");
155         connectManager->HandleStopTimeoutTask(abilityRecord);
156     };
157     abilityRecord->Terminate(timeoutTask);
158 
159     return ERR_OK;
160 }
161 
TerminateAbilityResultLocked(const sptr<IRemoteObject> & token,int startId)162 int AbilityConnectManager::TerminateAbilityResultLocked(const sptr<IRemoteObject> &token, int startId)
163 {
164     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
165     HILOG_INFO("Terminate ability result locked, startId: %{public}d", startId);
166     CHECK_POINTER_AND_RETURN(token, ERR_INVALID_VALUE);
167 
168     auto abilityRecord = GetExtensionByTokenFromSeriveMap(token);
169     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
170 
171     if (abilityRecord->GetStartId() != startId) {
172         HILOG_ERROR("Start id not equal.");
173         return TERMINATE_ABILITY_RESULT_FAILED;
174     }
175 
176     MoveToTerminatingMap(abilityRecord);
177     return TerminateAbilityLocked(token);
178 }
179 
StopServiceAbilityLocked(const AbilityRequest & abilityRequest)180 int AbilityConnectManager::StopServiceAbilityLocked(const AbilityRequest &abilityRequest)
181 {
182     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
183     HILOG_INFO("Stop service ability locked.");
184     AppExecFwk::ElementName element(abilityRequest.abilityInfo.deviceId, abilityRequest.abilityInfo.bundleName,
185         abilityRequest.abilityInfo.name, abilityRequest.abilityInfo.moduleName);
186     auto abilityRecord = GetServiceRecordByElementName(element.GetURI());
187     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
188 
189     if (abilityRecord->IsTerminating()) {
190         HILOG_INFO("Ability is on terminating.");
191         return ERR_OK;
192     }
193 
194     if (!abilityRecord->GetConnectRecordList().empty()) {
195         HILOG_INFO("Target service has been connected. Post disconnect task.");
196         auto connectRecordList = abilityRecord->GetConnectRecordList();
197         HandleTerminateDisconnectTask(connectRecordList);
198     }
199 
200     auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
201         HILOG_WARN("Disconnect ability terminate timeout.");
202         connectManager->HandleStopTimeoutTask(abilityRecord);
203     };
204 
205     MoveToTerminatingMap(abilityRecord);
206     abilityRecord->Terminate(timeoutTask);
207 
208     return ERR_OK;
209 }
210 
GetOrCreateServiceRecord(const AbilityRequest & abilityRequest,const bool isCreatedByConnect,std::shared_ptr<AbilityRecord> & targetService,bool & isLoadedAbility)211 void AbilityConnectManager::GetOrCreateServiceRecord(const AbilityRequest &abilityRequest,
212     const bool isCreatedByConnect, std::shared_ptr<AbilityRecord> &targetService, bool &isLoadedAbility)
213 {
214     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
215     AppExecFwk::ElementName element(abilityRequest.abilityInfo.deviceId, abilityRequest.abilityInfo.bundleName,
216         abilityRequest.abilityInfo.name, abilityRequest.abilityInfo.moduleName);
217     auto serviceMapIter = serviceMap_.find(element.GetURI());
218     if (serviceMapIter == serviceMap_.end()) {
219         targetService = AbilityRecord::CreateAbilityRecord(abilityRequest);
220         if (targetService) {
221             targetService->SetOwnerMissionUserId(userId_);
222         }
223 
224         if (isCreatedByConnect && targetService != nullptr) {
225             targetService->SetCreateByConnectMode();
226         }
227         if (targetService && abilityRequest.abilityInfo.name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
228             targetService->SetLauncherRoot();
229             targetService->SetKeepAlive();
230             targetService->SetRestartTime(abilityRequest.restartTime);
231             targetService->SetRestartCount(abilityRequest.restartCount);
232         } else if (IsAbilityNeedKeepAlive(targetService)) {
233             targetService->SetKeepAlive();
234             targetService->SetRestartTime(abilityRequest.restartTime);
235             targetService->SetRestartCount(abilityRequest.restartCount);
236         }
237         serviceMap_.emplace(element.GetURI(), targetService);
238         isLoadedAbility = false;
239     } else {
240         targetService = serviceMapIter->second;
241         if (targetService != nullptr) {
242             // want may be changed for the same ability.
243             targetService->SetWant(abilityRequest.want);
244         }
245         isLoadedAbility = true;
246     }
247 }
248 
GetConnectRecordListFromMap(const sptr<IAbilityConnection> & connect,std::list<std::shared_ptr<ConnectionRecord>> & connectRecordList)249 void AbilityConnectManager::GetConnectRecordListFromMap(
250     const sptr<IAbilityConnection> &connect, std::list<std::shared_ptr<ConnectionRecord>> &connectRecordList)
251 {
252     auto connectMapIter = connectMap_.find(connect->AsObject());
253     if (connectMapIter != connectMap_.end()) {
254         connectRecordList = connectMapIter->second;
255     }
256 }
257 
ConnectAbilityLocked(const AbilityRequest & abilityRequest,const sptr<IAbilityConnection> & connect,const sptr<IRemoteObject> & callerToken)258 int AbilityConnectManager::ConnectAbilityLocked(const AbilityRequest &abilityRequest,
259     const sptr<IAbilityConnection> &connect, const sptr<IRemoteObject> &callerToken)
260 {
261     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
262     HILOG_DEBUG("Connect ability called, callee:%{public}s.", abilityRequest.want.GetElement().GetURI().c_str());
263     std::lock_guard<std::recursive_mutex> guard(Lock_);
264 
265     // 1. get target service ability record, and check whether it has been loaded.
266     std::shared_ptr<AbilityRecord> targetService;
267     bool isLoadedAbility = false;
268     GetOrCreateServiceRecord(abilityRequest, true, targetService, isLoadedAbility);
269     CHECK_POINTER_AND_RETURN(targetService, ERR_INVALID_VALUE);
270     // 2. get target connectRecordList, and check whether this callback has been connected.
271     ConnectListType connectRecordList;
272     GetConnectRecordListFromMap(connect, connectRecordList);
273     bool isCallbackConnected = !connectRecordList.empty();
274     // 3. If this service ability and callback has been connected, There is no need to connect repeatedly
275     if (isLoadedAbility && (isCallbackConnected) && IsAbilityConnected(targetService, connectRecordList)) {
276         HILOG_INFO("Service and callback was connected.");
277         return ERR_OK;
278     }
279 
280     // 4. Other cases , need to connect the service ability
281     auto connectRecord = ConnectionRecord::CreateConnectionRecord(callerToken, targetService, connect);
282     CHECK_POINTER_AND_RETURN(connectRecord, ERR_INVALID_VALUE);
283     connectRecord->AttachCallerInfo();
284     connectRecord->SetConnectState(ConnectionState::CONNECTING);
285     targetService->AddConnectRecordToList(connectRecord);
286     connectRecordList.push_back(connectRecord);
287     if (isCallbackConnected) {
288         RemoveConnectDeathRecipient(connect);
289         connectMap_.erase(connectMap_.find(connect->AsObject()));
290     }
291     AddConnectDeathRecipient(connect);
292     connectMap_.emplace(connect->AsObject(), connectRecordList);
293 
294     // 5. load or connect ability
295     int ret = ERR_OK;
296     if (!isLoadedAbility) {
297         LoadAbility(targetService);
298     } else if (targetService->IsAbilityState(AbilityState::ACTIVE)) {
299         // this service ability has not first connect
300         if (targetService->GetConnectRecordList().size() > 1) {
301             if (eventHandler_ != nullptr) {
302                 auto task = [connectRecord]() { connectRecord->CompleteConnect(ERR_OK); };
303                 eventHandler_->PostTask(task);
304             }
305         } else {
306             ConnectAbility(targetService);
307         }
308     } else {
309         HILOG_INFO("Target service ability is activating, just wait for callback");
310     }
311 
312     auto token = targetService->GetToken();
313     auto preToken = iface_cast<Token>(connectRecord->GetToken());
314     DelayedSingleton<AppScheduler>::GetInstance()->AbilityBehaviorAnalysis(token, preToken, 0, 1, 1);
315     return ret;
316 }
317 
DisconnectAbilityLocked(const sptr<IAbilityConnection> & connect)318 int AbilityConnectManager::DisconnectAbilityLocked(const sptr<IAbilityConnection> &connect)
319 {
320     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
321     HILOG_INFO("Disconnect ability begin.");
322     std::lock_guard<std::recursive_mutex> guard(Lock_);
323 
324     // 1. check whether callback was connected.
325     ConnectListType connectRecordList;
326     GetConnectRecordListFromMap(connect, connectRecordList);
327     if (connectRecordList.empty()) {
328         HILOG_ERROR("Can't find the connect list from connect map by callback.");
329         return CONNECTION_NOT_EXIST;
330     }
331 
332     // 2. schedule disconnect to target service
333     for (auto &connectRecord : connectRecordList) {
334         if (connectRecord) {
335             auto abilityRecord = connectRecord->GetAbilityRecord();
336             CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
337             HILOG_INFO("Disconnect ability, caller:%{public}s.", abilityRecord->GetAbilityInfo().name.c_str());
338             auto abilityMs = DelayedSingleton<AbilityManagerService>::GetInstance();
339             CHECK_POINTER_AND_RETURN(abilityMs, GET_ABILITY_SERVICE_FAILED);
340             int result = abilityMs->JudgeAbilityVisibleControl(abilityRecord->GetAbilityInfo());
341             if (result != ERR_OK) {
342                 HILOG_ERROR("Judge ability visible error.");
343                 return result;
344             }
345             int ret = connectRecord->DisconnectAbility();
346             if (ret != ERR_OK) {
347                 HILOG_ERROR("Disconnect ability fail , ret = %{public}d.", ret);
348                 return ret;
349             }
350 
351             if (connectRecord->GetConnectState() == ConnectionState::DISCONNECTED) {
352                 HILOG_WARN("This record: %{public}d complete disconnect directly.", connectRecord->GetRecordId());
353                 connectRecord->CompleteDisconnect(ERR_OK, false);
354                 RemoveConnectionRecordFromMap(connectRecord);
355             }
356         }
357     }
358 
359     return ERR_OK;
360 }
361 
AttachAbilityThreadLocked(const sptr<IAbilityScheduler> & scheduler,const sptr<IRemoteObject> & token)362 int AbilityConnectManager::AttachAbilityThreadLocked(
363     const sptr<IAbilityScheduler> &scheduler, const sptr<IRemoteObject> &token)
364 {
365     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
366     std::lock_guard<std::recursive_mutex> guard(Lock_);
367     auto abilityRecord = GetExtensionByTokenFromSeriveMap(token);
368     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
369     if (eventHandler_ != nullptr) {
370         int recordId = abilityRecord->GetRecordId();
371         std::string taskName = std::string("LoadTimeout_") + std::to_string(recordId);
372         eventHandler_->RemoveTask(taskName);
373         eventHandler_->RemoveEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, abilityRecord->GetEventId());
374     }
375     std::string element = abilityRecord->GetWant().GetElement().GetURI();
376     HILOG_DEBUG("Ability: %{public}s", element.c_str());
377     abilityRecord->SetScheduler(scheduler);
378     abilityRecord->Inactivate();
379 
380     return ERR_OK;
381 }
382 
OnAppStateChanged(const AppInfo & info)383 void AbilityConnectManager::OnAppStateChanged(const AppInfo &info)
384 {
385     std::lock_guard<std::recursive_mutex> guard(Lock_);
386     std::for_each(serviceMap_.begin(), serviceMap_.end(), [&info](ServiceMapType::reference service) {
387         if (service.second && (info.processName == service.second->GetAbilityInfo().process ||
388                                   info.processName == service.second->GetApplicationInfo().bundleName)) {
389             auto appName = service.second->GetApplicationInfo().name;
390             auto uid = service.second->GetAbilityInfo().applicationInfo.uid;
391             auto isExist = [&appName, &uid](
392                                const AppData &appData) { return appData.appName == appName && appData.uid == uid; };
393             auto iter = std::find_if(info.appData.begin(), info.appData.end(), isExist);
394             if (iter != info.appData.end()) {
395                 service.second->SetAppState(info.state);
396             }
397         }
398     });
399 }
400 
AbilityTransitionDone(const sptr<IRemoteObject> & token,int state)401 int AbilityConnectManager::AbilityTransitionDone(const sptr<IRemoteObject> &token, int state)
402 {
403     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
404     std::lock_guard<std::recursive_mutex> guard(Lock_);
405     int targetState = AbilityRecord::ConvertLifeCycleToAbilityState(static_cast<AbilityLifeCycleState>(state));
406     std::string abilityState = AbilityRecord::ConvertAbilityState(static_cast<AbilityState>(targetState));
407     std::shared_ptr<AbilityRecord> abilityRecord;
408     if (static_cast<AbilityState>(targetState) == AbilityState::INACTIVE) {
409         abilityRecord = GetExtensionByTokenFromSeriveMap(token);
410     } else if (static_cast<AbilityState>(targetState) == AbilityState::INITIAL) {
411         abilityRecord = GetExtensionByTokenFromTerminatingMap(token);
412     } else {
413         abilityRecord = nullptr;
414     }
415     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
416     std::string element = abilityRecord->GetWant().GetElement().GetURI();
417     HILOG_DEBUG("Ability: %{public}s, state: %{public}s", element.c_str(), abilityState.c_str());
418 
419     switch (state) {
420         case AbilityState::INACTIVE: {
421             if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
422                 DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
423                     token, AppExecFwk::AbilityState::ABILITY_STATE_CREATE);
424             } else {
425                 DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
426                     token, AppExecFwk::ExtensionState::EXTENSION_STATE_CREATE);
427                 auto preloadTask = [owner = weak_from_this(), abilityRecord] {
428                     auto acm = owner.lock();
429                     if (acm == nullptr) {
430                         HILOG_ERROR("AbilityConnectManager is nullptr.");
431                         return;
432                     }
433                     acm->ProcessPreload(abilityRecord);
434                 };
435                 if (eventHandler_ != nullptr) {
436                     eventHandler_->PostTask(preloadTask);
437                 }
438             }
439             return DispatchInactive(abilityRecord, state);
440         }
441         case AbilityState::INITIAL: {
442             if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
443                 DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
444                     token, AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED);
445             } else {
446                 DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
447                     token, AppExecFwk::ExtensionState::EXTENSION_STATE_TERMINATED);
448             }
449             return DispatchTerminate(abilityRecord);
450         }
451         default: {
452             HILOG_WARN("Don't support transiting state: %{public}d", state);
453             return ERR_INVALID_VALUE;
454         }
455     }
456 }
457 
ProcessPreload(const std::shared_ptr<AbilityRecord> & record) const458 void AbilityConnectManager::ProcessPreload(const std::shared_ptr<AbilityRecord> &record) const
459 {
460     auto bms = AbilityUtil::GetBundleManager();
461     CHECK_POINTER(bms);
462     auto abilityInfo = record->GetAbilityInfo();
463     Want want;
464     want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
465     auto uid = record->GetUid();
466     want.SetParam("uid", uid);
467     bms->ProcessPreload(want);
468 }
469 
ScheduleConnectAbilityDoneLocked(const sptr<IRemoteObject> & token,const sptr<IRemoteObject> & remoteObject)470 int AbilityConnectManager::ScheduleConnectAbilityDoneLocked(
471     const sptr<IRemoteObject> &token, const sptr<IRemoteObject> &remoteObject)
472 {
473     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
474     std::lock_guard<std::recursive_mutex> guard(Lock_);
475     CHECK_POINTER_AND_RETURN(token, ERR_INVALID_VALUE);
476 
477     auto abilityRecord = Token::GetAbilityRecordByToken(token);
478     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
479 
480     std::string element = abilityRecord->GetWant().GetElement().GetURI();
481     HILOG_DEBUG("Connect ability done, ability: %{public}s.", element.c_str());
482 
483     if ((!abilityRecord->IsAbilityState(AbilityState::INACTIVE)) &&
484         (!abilityRecord->IsAbilityState(AbilityState::ACTIVE))) {
485         HILOG_ERROR("Ability record state is not inactive ,state: %{public}d", abilityRecord->GetAbilityState());
486         return INVALID_CONNECTION_STATE;
487     }
488 
489     if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
490         DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
491             token, AppExecFwk::AbilityState::ABILITY_STATE_CONNECTED);
492     } else {
493         DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
494             token, AppExecFwk::ExtensionState::EXTENSION_STATE_CONNECTED);
495     }
496 
497     abilityRecord->SetConnRemoteObject(remoteObject);
498     // There may be multiple callers waiting for the connection result
499     auto connectRecordList = abilityRecord->GetConnectRecordList();
500     for (auto &connectRecord : connectRecordList) {
501         connectRecord->ScheduleConnectAbilityDone();
502     }
503 
504     return ERR_OK;
505 }
506 
ScheduleDisconnectAbilityDoneLocked(const sptr<IRemoteObject> & token)507 int AbilityConnectManager::ScheduleDisconnectAbilityDoneLocked(const sptr<IRemoteObject> &token)
508 {
509     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
510     std::lock_guard<std::recursive_mutex> guard(Lock_);
511     auto abilityRecord = GetExtensionByTokenFromSeriveMap(token);
512     CHECK_POINTER_AND_RETURN(abilityRecord, CONNECTION_NOT_EXIST);
513 
514     auto connect = abilityRecord->GetDisconnectingRecord();
515     CHECK_POINTER_AND_RETURN(connect, CONNECTION_NOT_EXIST);
516 
517     if (!abilityRecord->IsAbilityState(AbilityState::ACTIVE)) {
518         HILOG_ERROR("The service ability state is not active ,state: %{public}d", abilityRecord->GetAbilityState());
519         return INVALID_CONNECTION_STATE;
520     }
521 
522     if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
523         DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
524             token, AppExecFwk::AbilityState::ABILITY_STATE_DISCONNECTED);
525     } else {
526         DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
527             token, AppExecFwk::ExtensionState::EXTENSION_STATE_DISCONNECTED);
528     }
529 
530     std::string element = abilityRecord->GetWant().GetElement().GetURI();
531     HILOG_DEBUG("Disconnect ability done, service:%{public}s.", element.c_str());
532 
533     // complete disconnect and remove record from conn map
534     connect->ScheduleDisconnectAbilityDone();
535     abilityRecord->RemoveConnectRecordFromList(connect);
536     if (abilityRecord->IsConnectListEmpty() && abilityRecord->GetStartId() == 0) {
537         HILOG_INFO("Service ability has no any connection, and not started , need terminate.");
538         auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
539             HILOG_WARN("Disconnect ability terminate timeout.");
540             connectManager->HandleStopTimeoutTask(abilityRecord);
541         };
542         MoveToTerminatingMap(abilityRecord);
543         abilityRecord->Terminate(timeoutTask);
544     }
545     RemoveConnectionRecordFromMap(connect);
546 
547     return ERR_OK;
548 }
549 
ScheduleCommandAbilityDoneLocked(const sptr<IRemoteObject> & token)550 int AbilityConnectManager::ScheduleCommandAbilityDoneLocked(const sptr<IRemoteObject> &token)
551 {
552     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
553     std::lock_guard<std::recursive_mutex> guard(Lock_);
554     CHECK_POINTER_AND_RETURN(token, ERR_INVALID_VALUE);
555     auto abilityRecord = Token::GetAbilityRecordByToken(token);
556     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
557     std::string element = abilityRecord->GetWant().GetElement().GetURI();
558     HILOG_DEBUG("Ability: %{public}s", element.c_str());
559 
560     if ((!abilityRecord->IsAbilityState(AbilityState::INACTIVE)) &&
561         (!abilityRecord->IsAbilityState(AbilityState::ACTIVE))) {
562         HILOG_ERROR("Ability record state is not inactive ,state: %{public}d", abilityRecord->GetAbilityState());
563         return INVALID_CONNECTION_STATE;
564     }
565     // complete command and pop waiting start ability from queue.
566     CompleteCommandAbility(abilityRecord);
567 
568     return ERR_OK;
569 }
570 
CompleteCommandAbility(std::shared_ptr<AbilityRecord> abilityRecord)571 void AbilityConnectManager::CompleteCommandAbility(std::shared_ptr<AbilityRecord> abilityRecord)
572 {
573     CHECK_POINTER(abilityRecord);
574 
575     if (eventHandler_) {
576         int recordId = abilityRecord->GetRecordId();
577         std::string taskName = std::string("CommandTimeout_") + std::to_string(recordId) + std::string("_") +
578                                std::to_string(abilityRecord->GetStartId());
579         eventHandler_->RemoveTask(taskName);
580     }
581 
582     abilityRecord->SetAbilityState(AbilityState::ACTIVE);
583 }
584 
GetServiceRecordByElementName(const std::string & element)585 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetServiceRecordByElementName(const std::string &element)
586 {
587     std::lock_guard<std::recursive_mutex> guard(Lock_);
588     auto mapIter = serviceMap_.find(element);
589     if (mapIter != serviceMap_.end()) {
590         return mapIter->second;
591     }
592     return nullptr;
593 }
594 
GetExtensionByTokenFromSeriveMap(const sptr<IRemoteObject> & token)595 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetExtensionByTokenFromSeriveMap(const sptr<IRemoteObject> &token)
596 {
597     std::lock_guard<std::recursive_mutex> guard(Lock_);
598     auto IsMatch = [token](auto service) {
599         if (!service.second) {
600             return false;
601         }
602         sptr<IRemoteObject> srcToken = service.second->GetToken();
603         return srcToken == token;
604     };
605     auto serviceRecord = std::find_if(serviceMap_.begin(), serviceMap_.end(), IsMatch);
606     if (serviceRecord != serviceMap_.end()) {
607         return serviceRecord->second;
608     }
609     return nullptr;
610 }
611 
GetExtensionByTokenFromTerminatingMap(const sptr<IRemoteObject> & token)612 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetExtensionByTokenFromTerminatingMap(
613     const sptr<IRemoteObject> &token)
614 {
615     std::lock_guard<std::recursive_mutex> guard(Lock_);
616     auto IsMatch = [token](auto& extension) {
617         if (extension.second == nullptr) {
618             return false;
619         }
620         auto&& terminatingToken = extension.second->GetToken();
621         if (terminatingToken != nullptr) {
622             return terminatingToken->AsObject() == token;
623         }
624         return false;
625     };
626 
627     auto terminatingExtensionRecord =
628         std::find_if(terminatingExtensionMap_.begin(), terminatingExtensionMap_.end(), IsMatch);
629     if (terminatingExtensionRecord != terminatingExtensionMap_.end()) {
630         return terminatingExtensionRecord->second;
631     }
632     return nullptr;
633 }
634 
GetConnectRecordListByCallback(sptr<IAbilityConnection> callback)635 std::list<std::shared_ptr<ConnectionRecord>> AbilityConnectManager::GetConnectRecordListByCallback(
636     sptr<IAbilityConnection> callback)
637 {
638     std::lock_guard<std::recursive_mutex> guard(Lock_);
639     std::list<std::shared_ptr<ConnectionRecord>> connectList;
640     auto connectMapIter = connectMap_.find(callback->AsObject());
641     if (connectMapIter != connectMap_.end()) {
642         connectList = connectMapIter->second;
643     }
644     return connectList;
645 }
646 
GetAbilityRecordByEventId(int64_t eventId)647 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetAbilityRecordByEventId(int64_t eventId)
648 {
649     std::lock_guard<std::recursive_mutex> guard(Lock_);
650     auto IsMatch = [eventId](auto service) {
651         if (!service.second) {
652             return false;
653         }
654         return eventId == service.second->GetEventId();
655     };
656     auto serviceRecord = std::find_if(serviceMap_.begin(), serviceMap_.end(), IsMatch);
657     if (serviceRecord != serviceMap_.end()) {
658         return serviceRecord->second;
659     }
660     return nullptr;
661 }
662 
LoadAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)663 void AbilityConnectManager::LoadAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
664 {
665     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
666     CHECK_POINTER(abilityRecord);
667     abilityRecord->SetStartTime();
668 
669     if (!abilityRecord->CanRestartRootLauncher()) {
670         HILOG_ERROR("Root launcher restart is out of max count.");
671         RemoveServiceAbility(abilityRecord);
672         return;
673     }
674 
675     PostTimeOutTask(abilityRecord, AbilityManagerService::LOAD_TIMEOUT_MSG);
676 
677     sptr<Token> token = abilityRecord->GetToken();
678     sptr<Token> perToken = nullptr;
679     if (abilityRecord->IsCreateByConnect()) {
680         perToken = iface_cast<Token>(abilityRecord->GetConnectingRecord()->GetToken());
681     } else {
682         auto callerList = abilityRecord->GetCallerRecordList();
683         if (!callerList.empty() && callerList.back()) {
684             auto caller = callerList.back()->GetCaller();
685             if (caller) {
686                 perToken = caller->GetToken();
687             }
688         }
689     }
690     DelayedSingleton<AppScheduler>::GetInstance()->LoadAbility(
691         token, perToken, abilityRecord->GetAbilityInfo(), abilityRecord->GetApplicationInfo(),
692         abilityRecord->GetWant());
693 }
694 
PostRestartResidentTask(const AbilityRequest & abilityRequest)695 void AbilityConnectManager::PostRestartResidentTask(const AbilityRequest &abilityRequest)
696 {
697     HILOG_INFO("PostRestartResidentTask start.");
698     CHECK_POINTER(eventHandler_);
699     std::string taskName = std::string("RestartResident_") + std::string(abilityRequest.abilityInfo.name);
700     auto task = [abilityRequest, connectManager = shared_from_this()]() {
701         CHECK_POINTER(connectManager);
702         connectManager->HandleRestartResidentTask(abilityRequest);
703     };
704     int restartIntervalTime = 0;
705     auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
706     if (abilityMgr) {
707         abilityMgr->GetRestartIntervalTime(restartIntervalTime);
708     }
709     HILOG_DEBUG("PostRestartResidentTask, time:%{public}d", restartIntervalTime);
710     eventHandler_->PostTask(task, taskName, restartIntervalTime);
711     HILOG_INFO("PostRestartResidentTask end.");
712 }
713 
HandleRestartResidentTask(const AbilityRequest & abilityRequest)714 void AbilityConnectManager::HandleRestartResidentTask(const AbilityRequest &abilityRequest)
715 {
716     HILOG_INFO("HandleRestartResidentTask start.");
717     auto findRestartResidentTask = [abilityRequest](const AbilityRequest &requestInfo) {
718         return (requestInfo.want.GetElement().GetBundleName() == abilityRequest.want.GetElement().GetBundleName() &&
719             requestInfo.want.GetElement().GetModuleName() == abilityRequest.want.GetElement().GetModuleName() &&
720             requestInfo.want.GetElement().GetAbilityName() == abilityRequest.want.GetElement().GetAbilityName());
721     };
722     auto findIter = find_if(restartResidentTaskList_.begin(), restartResidentTaskList_.end(), findRestartResidentTask);
723     if (findIter != restartResidentTaskList_.end()) {
724         restartResidentTaskList_.erase(findIter);
725     }
726     StartAbilityLocked(abilityRequest);
727 }
728 
PostTimeOutTask(const std::shared_ptr<AbilityRecord> & abilityRecord,uint32_t messageId)729 void AbilityConnectManager::PostTimeOutTask(const std::shared_ptr<AbilityRecord> &abilityRecord, uint32_t messageId)
730 {
731     CHECK_POINTER(abilityRecord);
732     CHECK_POINTER(eventHandler_);
733     if (messageId != AbilityConnectManager::LOAD_TIMEOUT_MSG &&
734         messageId != AbilityConnectManager::CONNECT_TIMEOUT_MSG) {
735         HILOG_ERROR("Timeout task messageId is error.");
736         return;
737     }
738 
739     int recordId;
740     std::string taskName;
741     int resultCode;
742     uint32_t delayTime;
743     if (abilityRecord->GetApplicationInfo().asanEnabled) {
744         recordId = abilityRecord->GetRecordId();
745         taskName = std::string("LoadTimeout_") + std::to_string(recordId);
746         resultCode = LOAD_ABILITY_TIMEOUT;
747         delayTime = AbilityManagerService::LOAD_TIMEOUT_ASANENABLED;
748     } else if (messageId == AbilityManagerService::LOAD_TIMEOUT_MSG) {
749         // first load ability, There is at most one connect record.
750         recordId = abilityRecord->GetRecordId();
751         taskName = std::string("LoadTimeout_") + std::to_string(recordId);
752         resultCode = LOAD_ABILITY_TIMEOUT;
753         delayTime = AbilityManagerService::LOAD_TIMEOUT;
754     } else {
755         auto connectRecord = abilityRecord->GetConnectingRecord();
756         CHECK_POINTER(connectRecord);
757         recordId = connectRecord->GetRecordId();
758         taskName = std::string("ConnectTimeout_") + std::to_string(recordId);
759         resultCode = CONNECTION_TIMEOUT;
760         delayTime = AbilityManagerService::CONNECT_TIMEOUT;
761     }
762 
763     // check libc.hook_mode
764     const int bufferLen = 128;
765     char paramOutBuf[bufferLen] = {0};
766     const char *hook_mode = "startup:";
767     int ret = GetParameter("libc.hook_mode", "", paramOutBuf, bufferLen - 1);
768     if (ret > 0 && strncmp(paramOutBuf, hook_mode, strlen(hook_mode)) == 0) {
769         HILOG_DEBUG("Hook_mode: no timeoutTask");
770         return;
771     }
772 
773     auto timeoutTask = [abilityRecord, connectManager = shared_from_this(), resultCode]() {
774         HILOG_WARN("Connect or load ability timeout.");
775         connectManager->HandleStartTimeoutTask(abilityRecord, resultCode);
776     };
777 
778     eventHandler_->PostTask(timeoutTask, taskName, delayTime);
779 }
780 
HandleStartTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord,int resultCode)781 void AbilityConnectManager::HandleStartTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord, int resultCode)
782 {
783     HILOG_DEBUG("Complete connect or load ability timeout.");
784     std::lock_guard<std::recursive_mutex> guard(Lock_);
785     CHECK_POINTER(abilityRecord);
786     auto connectingList = abilityRecord->GetConnectingRecordList();
787     for (auto &connectRecord : connectingList) {
788         if (connectRecord == nullptr) {
789             HILOG_WARN("ConnectRecord is nullptr.");
790             continue;
791         }
792         connectRecord->CompleteDisconnect(ERR_OK, true);
793         abilityRecord->RemoveConnectRecordFromList(connectRecord);
794         RemoveConnectionRecordFromMap(connectRecord);
795     }
796 
797     if (GetExtensionByTokenFromSeriveMap(abilityRecord->GetToken()) == nullptr) {
798         HILOG_ERROR("Timeojut ability record is not exist in service map.");
799         return;
800     }
801     MoveToTerminatingMap(abilityRecord);
802 
803     if (resultCode == LOAD_ABILITY_TIMEOUT) {
804         HILOG_WARN("Load time out , remove target service record from services map.");
805         RemoveServiceAbility(abilityRecord);
806         if (abilityRecord->GetAbilityInfo().name != AbilityConfig::LAUNCHER_ABILITY_NAME) {
807             DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
808             if (IsAbilityNeedKeepAlive(abilityRecord)) {
809                 HILOG_WARN("Load time out , try to restart.");
810                 RestartAbility(abilityRecord, userId_);
811             }
812         }
813     }
814 
815     if (abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
816         // terminate the timeout root launcher.
817         DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
818         if (resultCode == LOAD_ABILITY_TIMEOUT) {
819             StartRootLauncher(abilityRecord);
820         }
821     }
822 }
823 
HandleCommandTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord)824 void AbilityConnectManager::HandleCommandTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord)
825 {
826     HILOG_DEBUG("HandleCommandTimeoutTask start");
827     std::lock_guard<std::recursive_mutex> guard(Lock_);
828     CHECK_POINTER(abilityRecord);
829     if (abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
830         HILOG_DEBUG("Handle root launcher command timeout.");
831         // terminate the timeout root launcher.
832         DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
833     }
834     HILOG_DEBUG("HandleCommandTimeoutTask end");
835 }
836 
StartRootLauncher(const std::shared_ptr<AbilityRecord> & abilityRecord)837 void AbilityConnectManager::StartRootLauncher(const std::shared_ptr<AbilityRecord> &abilityRecord)
838 {
839     CHECK_POINTER(abilityRecord);
840     AbilityRequest requestInfo;
841     requestInfo.want = abilityRecord->GetWant();
842     requestInfo.abilityInfo = abilityRecord->GetAbilityInfo();
843     requestInfo.appInfo = abilityRecord->GetApplicationInfo();
844     requestInfo.restartTime = abilityRecord->GetRestartTime();
845     requestInfo.restart = true;
846     requestInfo.restartCount = abilityRecord->GetRestartCount() - 1;
847 
848     HILOG_DEBUG("restart root launcher, number:%{public}d", requestInfo.restartCount);
849     StartAbilityLocked(requestInfo);
850 }
851 
HandleStopTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord)852 void AbilityConnectManager::HandleStopTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord)
853 {
854     HILOG_DEBUG("Complete stop ability timeout start.");
855     std::lock_guard<std::recursive_mutex> guard(Lock_);
856     CHECK_POINTER(abilityRecord);
857     TerminateDone(abilityRecord);
858 }
859 
HandleTerminateDisconnectTask(const ConnectListType & connectlist)860 void AbilityConnectManager::HandleTerminateDisconnectTask(const ConnectListType& connectlist)
861 {
862     HILOG_DEBUG("Disconnect ability when terminate.");
863     std::lock_guard<std::recursive_mutex> guard(Lock_);
864     for (auto& connectRecord : connectlist) {
865         if (!connectRecord) {
866             continue;
867         }
868         auto targetService = connectRecord->GetAbilityRecord();
869         if (targetService) {
870             HILOG_WARN("This record complete disconnect directly. recordId:%{public}d", connectRecord->GetRecordId());
871             connectRecord->CompleteDisconnect(ERR_OK, true);
872             targetService->RemoveConnectRecordFromList(connectRecord);
873             RemoveConnectionRecordFromMap(connectRecord);
874         };
875     }
876 }
877 
DispatchInactive(const std::shared_ptr<AbilityRecord> & abilityRecord,int state)878 int AbilityConnectManager::DispatchInactive(const std::shared_ptr<AbilityRecord> &abilityRecord, int state)
879 {
880     CHECK_POINTER_AND_RETURN(eventHandler_, ERR_INVALID_VALUE);
881     if (!abilityRecord->IsAbilityState(AbilityState::INACTIVATING)) {
882         HILOG_ERROR("Ability transition life state error. expect %{public}d, actual %{public}d callback %{public}d",
883             AbilityState::INACTIVATING,
884             abilityRecord->GetAbilityState(),
885             state);
886         return ERR_INVALID_VALUE;
887     }
888     eventHandler_->RemoveEvent(AbilityManagerService::INACTIVE_TIMEOUT_MSG, abilityRecord->GetEventId());
889 
890     // complete inactive
891     abilityRecord->SetAbilityState(AbilityState::INACTIVE);
892     if (abilityRecord->IsCreateByConnect()) {
893         ConnectAbility(abilityRecord);
894     } else {
895         CommandAbility(abilityRecord);
896     }
897 
898     return ERR_OK;
899 }
900 
DispatchTerminate(const std::shared_ptr<AbilityRecord> & abilityRecord)901 int AbilityConnectManager::DispatchTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord)
902 {
903     // remove terminate timeout task
904     if (eventHandler_ != nullptr) {
905         eventHandler_->RemoveTask(std::to_string(abilityRecord->GetEventId()));
906     }
907     // complete terminate
908     TerminateDone(abilityRecord);
909     return ERR_OK;
910 }
911 
ConnectAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)912 void AbilityConnectManager::ConnectAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
913 {
914     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
915     CHECK_POINTER(abilityRecord);
916     PostTimeOutTask(abilityRecord, AbilityConnectManager::CONNECT_TIMEOUT_MSG);
917     abilityRecord->ConnectAbility();
918 }
919 
CommandAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)920 void AbilityConnectManager::CommandAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
921 {
922     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
923     if (eventHandler_ != nullptr) {
924         // first connect ability, There is at most one connect record.
925         int recordId = abilityRecord->GetRecordId();
926         abilityRecord->AddStartId();
927         std::string taskName = std::string("CommandTimeout_") + std::to_string(recordId) + std::string("_") +
928                                std::to_string(abilityRecord->GetStartId());
929         auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
930             HILOG_ERROR("Command ability timeout. %{public}s", abilityRecord->GetAbilityInfo().name.c_str());
931             connectManager->HandleCommandTimeoutTask(abilityRecord);
932         };
933         eventHandler_->PostTask(timeoutTask, taskName, AbilityManagerService::COMMAND_TIMEOUT);
934         // scheduling command ability
935         abilityRecord->CommandAbility();
936     }
937 }
938 
TerminateDone(const std::shared_ptr<AbilityRecord> & abilityRecord)939 void AbilityConnectManager::TerminateDone(const std::shared_ptr<AbilityRecord> &abilityRecord)
940 {
941     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
942     if (!abilityRecord->IsAbilityState(AbilityState::TERMINATING)) {
943         std::string expect = AbilityRecord::ConvertAbilityState(AbilityState::TERMINATING);
944         std::string actual = AbilityRecord::ConvertAbilityState(abilityRecord->GetAbilityState());
945         HILOG_ERROR(
946             "Transition life state error. expect %{public}s, actual %{public}s", expect.c_str(), actual.c_str());
947         return;
948     }
949     DelayedSingleton<AppScheduler>::GetInstance()->TerminateAbility(abilityRecord->GetToken(), false);
950     RemoveServiceAbility(abilityRecord);
951 }
952 
IsAbilityConnected(const std::shared_ptr<AbilityRecord> & abilityRecord,const std::list<std::shared_ptr<ConnectionRecord>> & connectRecordList)953 bool AbilityConnectManager::IsAbilityConnected(const std::shared_ptr<AbilityRecord> &abilityRecord,
954     const std::list<std::shared_ptr<ConnectionRecord>> &connectRecordList)
955 {
956     auto isMatch = [abilityRecord](auto connectRecord) -> bool {
957         if (abilityRecord == nullptr || connectRecord == nullptr) {
958             return false;
959         }
960         if (abilityRecord != connectRecord->GetAbilityRecord()) {
961             return false;
962         }
963         return true;
964     };
965     return std::any_of(connectRecordList.begin(), connectRecordList.end(), isMatch);
966 }
967 
RemoveConnectionRecordFromMap(const std::shared_ptr<ConnectionRecord> & connection)968 void AbilityConnectManager::RemoveConnectionRecordFromMap(const std::shared_ptr<ConnectionRecord> &connection)
969 {
970     for (auto &connectCallback : connectMap_) {
971         auto &connectList = connectCallback.second;
972         auto connectRecord = std::find(connectList.begin(), connectList.end(), connection);
973         if (connectRecord != connectList.end()) {
974             HILOG_INFO("Remove connrecord(%{public}d) from maplist.", (*connectRecord)->GetRecordId());
975             connectList.remove(connection);
976             if (connectList.empty()) {
977                 HILOG_INFO("Remove connlist from map.");
978                 sptr<IAbilityConnection> connect = iface_cast<IAbilityConnection>(connectCallback.first);
979                 RemoveConnectDeathRecipient(connect);
980                 connectMap_.erase(connectCallback.first);
981             }
982             return;
983         }
984     }
985 }
986 
RemoveServiceAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)987 void AbilityConnectManager::RemoveServiceAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
988 {
989     CHECK_POINTER(abilityRecord);
990     auto& abilityInfo = abilityRecord->GetAbilityInfo();
991     AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name,
992         abilityInfo.moduleName);
993     HILOG_DEBUG("Remove service(%{public}s) from terminating map.", element.GetURI().c_str());
994     terminatingExtensionMap_.erase(element.GetURI());
995 }
996 
AddConnectDeathRecipient(const sptr<IAbilityConnection> & connect)997 void AbilityConnectManager::AddConnectDeathRecipient(const sptr<IAbilityConnection> &connect)
998 {
999     CHECK_POINTER(connect);
1000     CHECK_POINTER(connect->AsObject());
1001     auto it = recipientMap_.find(connect->AsObject());
1002     if (it != recipientMap_.end()) {
1003         HILOG_ERROR("This death recipient has been added.");
1004         return;
1005     } else {
1006         std::weak_ptr<AbilityConnectManager> thisWeakPtr(shared_from_this());
1007         sptr<IRemoteObject::DeathRecipient> deathRecipient =
1008             new AbilityConnectCallbackRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
1009                 auto abilityConnectManager = thisWeakPtr.lock();
1010                 if (abilityConnectManager) {
1011                     abilityConnectManager->OnCallBackDied(remote);
1012                 }
1013             });
1014         connect->AsObject()->AddDeathRecipient(deathRecipient);
1015         recipientMap_.emplace(connect->AsObject(), deathRecipient);
1016     }
1017 }
1018 
RemoveConnectDeathRecipient(const sptr<IAbilityConnection> & connect)1019 void AbilityConnectManager::RemoveConnectDeathRecipient(const sptr<IAbilityConnection> &connect)
1020 {
1021     CHECK_POINTER(connect);
1022     CHECK_POINTER(connect->AsObject());
1023     auto it = recipientMap_.find(connect->AsObject());
1024     if (it != recipientMap_.end()) {
1025         it->first->RemoveDeathRecipient(it->second);
1026         recipientMap_.erase(it);
1027         return;
1028     }
1029 }
1030 
OnCallBackDied(const wptr<IRemoteObject> & remote)1031 void AbilityConnectManager::OnCallBackDied(const wptr<IRemoteObject> &remote)
1032 {
1033     auto object = remote.promote();
1034     CHECK_POINTER(object);
1035     if (eventHandler_) {
1036         auto task = [object, connectManager = shared_from_this()]() { connectManager->HandleCallBackDiedTask(object); };
1037         eventHandler_->PostTask(task, TASK_ON_CALLBACK_DIED);
1038     }
1039 }
1040 
HandleCallBackDiedTask(const sptr<IRemoteObject> & connect)1041 void AbilityConnectManager::HandleCallBackDiedTask(const sptr<IRemoteObject> &connect)
1042 {
1043     HILOG_INFO("Handle call back died task.");
1044     std::lock_guard<std::recursive_mutex> guard(Lock_);
1045     CHECK_POINTER(connect);
1046     auto it = connectMap_.find(connect);
1047     if (it != connectMap_.end()) {
1048         ConnectListType connectRecordList = it->second;
1049         for (auto &connRecord : connectRecordList) {
1050             connRecord->ClearConnCallBack();
1051         }
1052     } else {
1053         HILOG_INFO("Died object can't find from conn map.");
1054         return;
1055     }
1056     sptr<IAbilityConnection> object = iface_cast<IAbilityConnection>(connect);
1057     DisconnectAbilityLocked(object);
1058 }
1059 
OnAbilityDied(const std::shared_ptr<AbilityRecord> & abilityRecord,int32_t currentUserId)1060 void AbilityConnectManager::OnAbilityDied(const std::shared_ptr<AbilityRecord> &abilityRecord, int32_t currentUserId)
1061 {
1062     HILOG_INFO("On ability died.");
1063     CHECK_POINTER(abilityRecord);
1064     if (abilityRecord->GetAbilityInfo().type != AbilityType::SERVICE &&
1065         abilityRecord->GetAbilityInfo().type != AbilityType::EXTENSION) {
1066         HILOG_DEBUG("Ability type is not service.");
1067         return;
1068     }
1069     if (eventHandler_) {
1070         auto task = [abilityRecord, connectManager = shared_from_this(), currentUserId]() {
1071             connectManager->HandleAbilityDiedTask(abilityRecord, currentUserId);
1072         };
1073         eventHandler_->PostTask(task, TASK_ON_ABILITY_DIED);
1074     }
1075 }
1076 
OnTimeOut(uint32_t msgId,int64_t eventId)1077 void AbilityConnectManager::OnTimeOut(uint32_t msgId, int64_t eventId)
1078 {
1079     HILOG_DEBUG("On timeout, msgId is %{public}d", msgId);
1080     std::lock_guard<std::recursive_mutex> guard(Lock_);
1081     auto abilityRecord = GetAbilityRecordByEventId(eventId);
1082     if (abilityRecord == nullptr) {
1083         HILOG_ERROR("AbilityConnectManager on time out event: ability record is nullptr.");
1084         return;
1085     }
1086     HILOG_DEBUG("Ability timeout ,msg:%{public}d,name:%{public}s", msgId, abilityRecord->GetAbilityInfo().name.c_str());
1087 
1088     switch (msgId) {
1089         case AbilityManagerService::INACTIVE_TIMEOUT_MSG:
1090             HandleInactiveTimeout(abilityRecord);
1091             break;
1092         default:
1093             break;
1094     }
1095 }
1096 
HandleInactiveTimeout(const std::shared_ptr<AbilityRecord> & ability)1097 void AbilityConnectManager::HandleInactiveTimeout(const std::shared_ptr<AbilityRecord> &ability)
1098 {
1099     HILOG_DEBUG("HandleInactiveTimeout start");
1100     std::lock_guard<std::recursive_mutex> guard(Lock_);
1101     CHECK_POINTER(ability);
1102     if (ability->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
1103         HILOG_DEBUG("Handle root launcher inactive timeout.");
1104         // terminate the timeout root launcher.
1105         DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(ability->GetToken());
1106     }
1107 
1108     HILOG_DEBUG("HandleInactiveTimeout end");
1109 }
1110 
IsAbilityNeedKeepAlive(const std::shared_ptr<AbilityRecord> & abilityRecord)1111 bool AbilityConnectManager::IsAbilityNeedKeepAlive(const std::shared_ptr<AbilityRecord> &abilityRecord)
1112 {
1113     auto bms = AbilityUtil::GetBundleManager();
1114     CHECK_POINTER_AND_RETURN(bms, false);
1115     std::vector<AppExecFwk::BundleInfo> bundleInfos;
1116     bool getBundleInfos = bms->GetBundleInfos(OHOS::AppExecFwk::GET_BUNDLE_DEFAULT, bundleInfos, USER_ID_NO_HEAD);
1117     if (!getBundleInfos) {
1118         HILOG_ERROR("Handle ability died task, get bundle infos failed");
1119         return false;
1120     }
1121 
1122     auto CheckIsAbilityNeedKeepAlive = [](const AppExecFwk::HapModuleInfo &hapModuleInfo,
1123         const std::string processName, std::string &mainElement) {
1124         if (!hapModuleInfo.isModuleJson) {
1125             // old application model
1126             mainElement = hapModuleInfo.mainAbility;
1127             for (auto abilityInfo : hapModuleInfo.abilityInfos) {
1128                 if (abilityInfo.process == processName && abilityInfo.name == mainElement) {
1129                     return true;
1130                 }
1131             }
1132             return false;
1133         }
1134 
1135         // new application model
1136         if (hapModuleInfo.process == processName) {
1137             mainElement = hapModuleInfo.mainElementName;
1138             return true;
1139         }
1140         return false;
1141     };
1142 
1143     auto GetKeepAliveAbilities = [&](std::vector<std::pair<std::string, std::string>> &keepAliveAbilities) {
1144         for (size_t i = 0; i < bundleInfos.size(); i++) {
1145             std::string processName = bundleInfos[i].applicationInfo.process;
1146             if (!bundleInfos[i].isKeepAlive || processName.empty()) {
1147                 continue;
1148             }
1149             std::string bundleName = bundleInfos[i].name;
1150             for (auto hapModuleInfo : bundleInfos[i].hapModuleInfos) {
1151                 std::string mainElement;
1152                 if (CheckIsAbilityNeedKeepAlive(hapModuleInfo, processName, mainElement) && !mainElement.empty()) {
1153                     keepAliveAbilities.push_back(std::make_pair(bundleName, mainElement));
1154                 }
1155             }
1156         }
1157     };
1158 
1159     auto findKeepAliveAbility = [abilityRecord](const std::pair<std::string, std::string> &keepAlivePair) {
1160         return ((abilityRecord->GetAbilityInfo().bundleName == keepAlivePair.first &&
1161                 abilityRecord->GetAbilityInfo().name == keepAlivePair.second) ||
1162                 abilityRecord->GetAbilityInfo().name == AbilityConfig::SYSTEM_UI_ABILITY_NAME ||
1163                 abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME);
1164     };
1165 
1166     std::vector<std::pair<std::string, std::string>> keepAliveAbilities;
1167     GetKeepAliveAbilities(keepAliveAbilities);
1168     auto findIter = find_if(keepAliveAbilities.begin(), keepAliveAbilities.end(), findKeepAliveAbility);
1169     if (findIter != keepAliveAbilities.end()) {
1170         abilityRecord->SetKeepAlive();
1171         return true;
1172     }
1173     return false;
1174 }
1175 
HandleAbilityDiedTask(const std::shared_ptr<AbilityRecord> & abilityRecord,int32_t currentUserId)1176 void AbilityConnectManager::HandleAbilityDiedTask(
1177     const std::shared_ptr<AbilityRecord> &abilityRecord, int32_t currentUserId)
1178 {
1179     HILOG_INFO("Handle ability died task.");
1180     std::lock_guard<std::recursive_mutex> guard(Lock_);
1181     CHECK_POINTER(abilityRecord);
1182     ConnectListType connlist = abilityRecord->GetConnectRecordList();
1183     for (auto &connectRecord : connlist) {
1184         HILOG_WARN("This record complete disconnect directly. recordId:%{public}d", connectRecord->GetRecordId());
1185         connectRecord->CompleteDisconnect(ERR_OK, true);
1186         abilityRecord->RemoveConnectRecordFromList(connectRecord);
1187         RemoveConnectionRecordFromMap(connectRecord);
1188     }
1189 
1190     if (abilityRecord->IsTerminating()) {
1191         HILOG_INFO("Handle extension DiedByTerminating.");
1192         RemoveServiceAbility(abilityRecord);
1193         if (IsAbilityNeedKeepAlive(abilityRecord)) {
1194             HILOG_INFO("restart ability: %{public}s", abilityRecord->GetAbilityInfo().name.c_str());
1195             RestartAbility(abilityRecord, currentUserId);
1196         }
1197         return;
1198     }
1199 
1200     if (GetExtensionByTokenFromSeriveMap(abilityRecord->GetToken()) == nullptr) {
1201         HILOG_ERROR("Died ability record is not exist in service map.");
1202         return;
1203     }
1204 
1205     MoveToTerminatingMap(abilityRecord);
1206     RemoveServiceAbility(abilityRecord);
1207     if (IsAbilityNeedKeepAlive(abilityRecord)) {
1208         HILOG_INFO("restart ability: %{public}s", abilityRecord->GetAbilityInfo().name.c_str());
1209         RestartAbility(abilityRecord, currentUserId);
1210     }
1211 }
1212 
RestartAbility(const std::shared_ptr<AbilityRecord> & abilityRecord,int32_t currentUserId)1213 void AbilityConnectManager::RestartAbility(const std::shared_ptr<AbilityRecord> &abilityRecord, int32_t currentUserId)
1214 {
1215     HILOG_INFO("Restart ability");
1216     AbilityRequest requestInfo;
1217     requestInfo.want = abilityRecord->GetWant();
1218     requestInfo.abilityInfo = abilityRecord->GetAbilityInfo();
1219     requestInfo.appInfo = abilityRecord->GetApplicationInfo();
1220     requestInfo.restartTime = abilityRecord->GetRestartTime();
1221     requestInfo.restart = true;
1222     abilityRecord->SetRestarting(true);
1223 
1224     if (currentUserId != userId_ &&
1225         abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
1226         HILOG_WARN("delay restart root launcher until switch user.");
1227         return;
1228     }
1229 
1230     if (abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
1231         requestInfo.restartCount = abilityRecord->GetRestartCount();
1232         HILOG_DEBUG("restart root launcher, number:%{public}d", requestInfo.restartCount);
1233         StartAbilityLocked(requestInfo);
1234         return;
1235     }
1236 
1237     // restart other resident ability
1238     if (abilityRecord->CanRestartResident()) {
1239         requestInfo.restartCount = abilityRecord->GetRestartCount();
1240         requestInfo.restartTime = AbilityUtil::SystemTimeMillis();
1241         StartAbilityLocked(requestInfo);
1242     } else {
1243         auto findRestartResidentTask = [requestInfo](const AbilityRequest &abilityRequest) {
1244             return (requestInfo.want.GetElement().GetBundleName() == abilityRequest.want.GetElement().GetBundleName() &&
1245                 requestInfo.want.GetElement().GetModuleName() == abilityRequest.want.GetElement().GetModuleName() &&
1246                 requestInfo.want.GetElement().GetAbilityName() == abilityRequest.want.GetElement().GetAbilityName());
1247         };
1248         auto findIter = find_if(restartResidentTaskList_.begin(), restartResidentTaskList_.end(),
1249             findRestartResidentTask);
1250         if (findIter != restartResidentTaskList_.end()) {
1251             HILOG_WARN("The restart task has been registered.");
1252             return;
1253         }
1254         restartResidentTaskList_.emplace_back(requestInfo);
1255         PostRestartResidentTask(requestInfo);
1256     }
1257 }
1258 
DumpState(std::vector<std::string> & info,bool isClient,const std::string & args) const1259 void AbilityConnectManager::DumpState(std::vector<std::string> &info, bool isClient, const std::string &args) const
1260 {
1261     HILOG_INFO("DumpState args:%{public}s.", args.c_str());
1262     if (!args.empty()) {
1263         auto it = std::find_if(serviceMap_.begin(), serviceMap_.end(), [&args](const auto &service) {
1264             return service.first.compare(args) == 0;
1265         });
1266         if (it != serviceMap_.end()) {
1267             info.emplace_back("uri [ " + it->first + " ]");
1268             it->second->DumpService(info, isClient);
1269         } else {
1270             info.emplace_back(args + ": Nothing to dump.");
1271         }
1272     } else {
1273         auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
1274         info.emplace_back("  ExtensionRecords:");
1275         for (auto &&service : serviceMap_) {
1276             info.emplace_back("    uri [" + service.first + "]");
1277             service.second->DumpService(info, isClient);
1278         }
1279     }
1280 }
1281 
DumpStateByUri(std::vector<std::string> & info,bool isClient,const std::string & args,std::vector<std::string> & params) const1282 void AbilityConnectManager::DumpStateByUri(std::vector<std::string> &info, bool isClient, const std::string &args,
1283     std::vector<std::string> &params) const
1284 {
1285     HILOG_INFO("DumpState args:%{public}s, params size: %{public}zu", args.c_str(), params.size());
1286     auto it = std::find_if(serviceMap_.begin(), serviceMap_.end(), [&args](const auto &service) {
1287         return service.first.compare(args) == 0;
1288     });
1289     if (it != serviceMap_.end()) {
1290         info.emplace_back("uri [ " + it->first + " ]");
1291         it->second->DumpService(info, params, isClient);
1292     } else {
1293         info.emplace_back(args + ": Nothing to dump.");
1294     }
1295 }
1296 
GetExtensionRunningInfos(int upperLimit,std::vector<ExtensionRunningInfo> & info,const int32_t userId,bool isPerm)1297 void AbilityConnectManager::GetExtensionRunningInfos(int upperLimit, std::vector<ExtensionRunningInfo> &info,
1298     const int32_t userId, bool isPerm)
1299 {
1300     HILOG_INFO("Get extension running info.");
1301     std::lock_guard<std::recursive_mutex> guard(Lock_);
1302     auto mgr = shared_from_this();
1303     auto queryInfo = [&info, upperLimit, userId, isPerm, mgr](ServiceMapType::reference service) {
1304         if (static_cast<int>(info.size()) >= upperLimit) {
1305             return;
1306         }
1307         auto abilityRecord = service.second;
1308         CHECK_POINTER(abilityRecord);
1309 
1310         if (isPerm) {
1311             mgr->GetExtensionRunningInfo(abilityRecord, userId, info);
1312         } else {
1313             auto callingTokenId = IPCSkeleton::GetCallingTokenID();
1314             auto tokenID = abilityRecord->GetApplicationInfo().accessTokenId;
1315             if (callingTokenId == tokenID) {
1316                 mgr->GetExtensionRunningInfo(abilityRecord, userId, info);
1317             }
1318         }
1319     };
1320     std::for_each(serviceMap_.begin(), serviceMap_.end(), queryInfo);
1321 }
1322 
GetAbilityRunningInfos(std::vector<AbilityRunningInfo> & info,bool isPerm)1323 void AbilityConnectManager::GetAbilityRunningInfos(std::vector<AbilityRunningInfo> &info, bool isPerm)
1324 {
1325     HILOG_INFO("Query running ability infos.");
1326     std::lock_guard<std::recursive_mutex> guard(Lock_);
1327 
1328     auto queryInfo = [&info, isPerm](ServiceMapType::reference service) {
1329         auto abilityRecord = service.second;
1330         CHECK_POINTER(abilityRecord);
1331 
1332         if (isPerm) {
1333             DelayedSingleton<AbilityManagerService>::GetInstance()->GetAbilityRunningInfo(info, abilityRecord);
1334         } else {
1335             auto callingTokenId = IPCSkeleton::GetCallingTokenID();
1336             auto tokenID = abilityRecord->GetApplicationInfo().accessTokenId;
1337             if (callingTokenId == tokenID) {
1338                 DelayedSingleton<AbilityManagerService>::GetInstance()->GetAbilityRunningInfo(info, abilityRecord);
1339             }
1340         }
1341     };
1342 
1343     std::for_each(serviceMap_.begin(), serviceMap_.end(), queryInfo);
1344 }
1345 
GetExtensionRunningInfo(std::shared_ptr<AbilityRecord> & abilityRecord,const int32_t userId,std::vector<ExtensionRunningInfo> & info)1346 void AbilityConnectManager::GetExtensionRunningInfo(std::shared_ptr<AbilityRecord> &abilityRecord, const int32_t userId,
1347     std::vector<ExtensionRunningInfo> &info)
1348 {
1349     ExtensionRunningInfo extensionInfo;
1350     AppExecFwk::RunningProcessInfo processInfo;
1351     extensionInfo.extension = abilityRecord->GetWant().GetElement();
1352     auto bms = AbilityUtil::GetBundleManager();
1353     CHECK_POINTER(bms);
1354     std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
1355     bool queryResult = IN_PROCESS_CALL(bms->QueryExtensionAbilityInfos(abilityRecord->GetWant(),
1356         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, extensionInfos));
1357     if (queryResult) {
1358         HILOG_INFO("Query Extension Ability Infos Success.");
1359         auto abilityInfo = abilityRecord->GetAbilityInfo();
1360         auto isExist = [&abilityInfo](const AppExecFwk::ExtensionAbilityInfo &extensionInfo) {
1361             HILOG_INFO("%{public}s, %{public}s", extensionInfo.bundleName.c_str(), extensionInfo.name.c_str());
1362             return extensionInfo.bundleName == abilityInfo.bundleName && extensionInfo.name == abilityInfo.name
1363                 && extensionInfo.applicationInfo.uid == abilityInfo.applicationInfo.uid;
1364         };
1365         auto infoIter = std::find_if(extensionInfos.begin(), extensionInfos.end(), isExist);
1366         if (infoIter != extensionInfos.end()) {
1367             HILOG_INFO("Get target success.");
1368             extensionInfo.type = (*infoIter).type;
1369         }
1370     }
1371     DelayedSingleton<AppScheduler>::GetInstance()->
1372         GetRunningProcessInfoByToken(abilityRecord->GetToken(), processInfo);
1373     extensionInfo.pid = processInfo.pid_;
1374     extensionInfo.uid = processInfo.uid_;
1375     extensionInfo.processName = processInfo.processName_;
1376     extensionInfo.startTime = abilityRecord->GetStartTime();
1377     ConnectListType connectRecordList = abilityRecord->GetConnectRecordList();
1378     for (auto &connectRecord : connectRecordList) {
1379         if (connectRecord == nullptr) {
1380             HILOG_DEBUG("connectRecord is nullptr.");
1381             continue;
1382         }
1383         auto callerAbilityRecord = Token::GetAbilityRecordByToken(connectRecord->GetToken());
1384         if (callerAbilityRecord == nullptr) {
1385             HILOG_DEBUG("callerAbilityRecord is nullptr.");
1386             continue;
1387         }
1388         std::string package = callerAbilityRecord->GetAbilityInfo().bundleName;
1389         extensionInfo.clientPackage.emplace_back(package);
1390     }
1391     info.emplace_back(extensionInfo);
1392 }
1393 
StopAllExtensions()1394 void AbilityConnectManager::StopAllExtensions()
1395 {
1396     HILOG_INFO("StopAllExtensions begin.");
1397     std::lock_guard<std::recursive_mutex> guard(Lock_);
1398     for (auto it = serviceMap_.begin(); it != serviceMap_.end();) {
1399         auto targetExtension = it->second;
1400         if (targetExtension != nullptr && targetExtension->GetAbilityInfo().type == AbilityType::EXTENSION) {
1401             terminatingExtensionMap_.emplace(it->first, it->second);
1402             serviceMap_.erase(it++);
1403             TerminateAbilityLocked(targetExtension->GetToken());
1404         } else {
1405             it++;
1406         }
1407     }
1408     HILOG_INFO("StopAllExtensions end.");
1409 }
1410 
MoveToTerminatingMap(const std::shared_ptr<AbilityRecord> & abilityRecord)1411 void AbilityConnectManager::MoveToTerminatingMap(const std::shared_ptr<AbilityRecord>& abilityRecord)
1412 {
1413     CHECK_POINTER(abilityRecord);
1414     auto& abilityInfo = abilityRecord->GetAbilityInfo();
1415     AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name,
1416         abilityInfo.moduleName);
1417     terminatingExtensionMap_.emplace(element.GetURI(), abilityRecord);
1418     serviceMap_.erase(element.GetURI());
1419 }
1420 }  // namespace AAFwk
1421 }  // namespace OHOS
1422