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