1 /*
2 * Copyright (c) 2021-2023 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 #include <mutex>
20
21 #include "ability_connect_callback_stub.h"
22 #include "ability_manager_errors.h"
23 #include "ability_manager_service.h"
24 #include "ability_util.h"
25 #include "appfreeze_manager.h"
26 #include "app_utils.h"
27 #include "extension_config.h"
28 #include "hitrace_meter.h"
29 #include "hilog_wrapper.h"
30 #include "in_process_call_wrapper.h"
31 #include "parameter.h"
32 #include "session/host/include/zidl/session_interface.h"
33 #include "extension_record.h"
34 #include "ui_extension_utils.h"
35
36 namespace OHOS {
37 namespace AAFwk {
38 namespace {
39 constexpr char EVENT_KEY_UID[] = "UID";
40 constexpr char EVENT_KEY_PID[] = "PID";
41 constexpr char EVENT_KEY_MESSAGE[] = "MSG";
42 constexpr char EVENT_KEY_PACKAGE_NAME[] = "PACKAGE_NAME";
43 constexpr char EVENT_KEY_PROCESS_NAME[] = "PROCESS_NAME";
44 const std::string DEBUG_APP = "debugApp";
45 const std::string FRS_APP_INDEX = "ohos.extra.param.key.frs_index";
46 const std::string FRS_BUNDLE_NAME = "com.ohos.formrenderservice";
47 const std::string UIEXTENSION_ABILITY_ID = "ability.want.params.uiExtensionAbilityId";
48 #ifdef SUPPORT_ASAN
49 const int LOAD_TIMEOUT_MULTIPLE = 150;
50 const int CONNECT_TIMEOUT_MULTIPLE = 45;
51 const int COMMAND_TIMEOUT_MULTIPLE = 75;
52 const int COMMAND_WINDOW_TIMEOUT_MULTIPLE = 75;
53 const int UI_EXTENSION_CONSUME_SESSION_TIMEOUT_MULTIPLE = 150;
54 #else
55 const int LOAD_TIMEOUT_MULTIPLE = 10;
56 const int CONNECT_TIMEOUT_MULTIPLE = 3;
57 const int COMMAND_TIMEOUT_MULTIPLE = 5;
58 const int COMMAND_WINDOW_TIMEOUT_MULTIPLE = 5;
59 const int UI_EXTENSION_CONSUME_SESSION_TIMEOUT_MULTIPLE = 10;
60 #endif
61 const int32_t AUTO_DISCONNECT_INFINITY = -1;
62 const std::unordered_map<std::string, std::string> trustMap = {
63 { AbilityConfig::SCENEBOARD_BUNDLE_NAME, AbilityConfig::SCENEBOARD_ABILITY_NAME },
64 { AbilityConfig::SYSTEM_UI_BUNDLE_NAME, AbilityConfig::SYSTEM_UI_ABILITY_NAME },
65 { AbilityConfig::LAUNCHER_BUNDLE_NAME, AbilityConfig::LAUNCHER_ABILITY_NAME }
66 };
67 const std::unordered_set<std::string> FROZEN_WHITE_LIST {
68 "com.huawei.hmos.huaweicast"
69 };
70
IsSpecialAbility(const AppExecFwk::AbilityInfo & abilityInfo)71 bool IsSpecialAbility(const AppExecFwk::AbilityInfo &abilityInfo)
72 {
73 auto it = trustMap.find(abilityInfo.bundleName);
74 return (it != trustMap.end() && it->second == abilityInfo.name);
75 }
76 }
77
AbilityConnectManager(int userId)78 AbilityConnectManager::AbilityConnectManager(int userId) : userId_(userId)
79 {
80 uiExtensionAbilityRecordMgr_ = std::make_unique<AbilityRuntime::ExtensionRecordManager>(userId);
81 }
82
~AbilityConnectManager()83 AbilityConnectManager::~AbilityConnectManager()
84 {}
85
StartAbility(const AbilityRequest & abilityRequest)86 int AbilityConnectManager::StartAbility(const AbilityRequest &abilityRequest)
87 {
88 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
89 std::lock_guard guard(Lock_);
90 return StartAbilityLocked(abilityRequest);
91 }
92
TerminateAbility(const sptr<IRemoteObject> & token)93 int AbilityConnectManager::TerminateAbility(const sptr<IRemoteObject> &token)
94 {
95 std::lock_guard guard(Lock_);
96 return TerminateAbilityInner(token);
97 }
98
TerminateAbilityInner(const sptr<IRemoteObject> & token)99 int AbilityConnectManager::TerminateAbilityInner(const sptr<IRemoteObject> &token)
100 {
101 auto abilityRecord = GetExtensionFromServiceMapInner(token);
102 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
103 std::string element = abilityRecord->GetURI();
104 HILOG_DEBUG("Terminate ability, ability is %{public}s.", element.c_str());
105 if (IsUIExtensionAbility(abilityRecord) && !abilityRecord->IsConnectListEmpty()) {
106 HILOG_INFO("There exist connection, don't terminate.");
107 return ERR_OK;
108 }
109 MoveToTerminatingMap(abilityRecord);
110 return TerminateAbilityLocked(token);
111 }
112
StopServiceAbility(const AbilityRequest & abilityRequest)113 int AbilityConnectManager::StopServiceAbility(const AbilityRequest &abilityRequest)
114 {
115 HILOG_INFO("call");
116 std::lock_guard guard(Lock_);
117 return StopServiceAbilityLocked(abilityRequest);
118 }
119
StartAbilityLocked(const AbilityRequest & abilityRequest)120 int AbilityConnectManager::StartAbilityLocked(const AbilityRequest &abilityRequest)
121 {
122 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
123 HILOG_DEBUG("ability_name:%{public}s", abilityRequest.want.GetElement().GetURI().c_str());
124
125 std::vector<AppExecFwk::Metadata> metaData = abilityRequest.abilityInfo.metadata;
126 bool isSingleton = std::any_of(metaData.begin(), metaData.end(), [](const auto &metaDataItem) {
127 return metaDataItem.name == "UIExtensionAbilityLaunchTypeTemp" && metaDataItem.value == "singleton";
128 });
129 HILOG_DEBUG("State isSingleton: %{public}d.", isSingleton);
130
131 std::shared_ptr<AbilityRecord> targetService;
132 bool isLoadedAbility = false;
133 if (UIExtensionUtils::IsUIExtension(abilityRequest.abilityInfo.extensionAbilityType) && !isSingleton) {
134 auto callerAbilityRecord = AAFwk::Token::GetAbilityRecordByToken(abilityRequest.callerToken);
135 if (callerAbilityRecord == nullptr) {
136 HILOG_ERROR("Failed to get callerAbilityRecord.");
137 return ERR_NULL_OBJECT;
138 }
139 std::string hostBundleName = callerAbilityRecord->GetAbilityInfo().bundleName;
140 int32_t ret = GetOrCreateExtensionRecord(abilityRequest, false, hostBundleName, targetService, isLoadedAbility);
141 if (ret != ERR_OK) {
142 HILOG_ERROR("Failed to get or create extension record, ret: %{public}d", ret);
143 return ret;
144 }
145 } else {
146 GetOrCreateServiceRecord(abilityRequest, false, targetService, isLoadedAbility);
147 }
148 CHECK_POINTER_AND_RETURN(targetService, ERR_INVALID_VALUE);
149 HILOG_INFO("Start ability: %{public}s", targetService->GetURI().c_str());
150
151 targetService->AddCallerRecord(abilityRequest.callerToken, abilityRequest.requestCode);
152
153 targetService->SetLaunchReason(LaunchReason::LAUNCHREASON_START_EXTENSION);
154
155 targetService->DoBackgroundAbilityWindowDelayed(false);
156
157 if (IsUIExtensionAbility(targetService) && abilityRequest.sessionInfo && abilityRequest.sessionInfo->sessionToken) {
158 auto &remoteObj = abilityRequest.sessionInfo->sessionToken;
159 uiExtensionMap_[remoteObj] = UIExtWindowMapValType(targetService, abilityRequest.sessionInfo);
160 AddUIExtWindowDeathRecipient(remoteObj);
161 if (!isLoadedAbility) {
162 SaveUIExtRequestSessionInfo(targetService, abilityRequest.sessionInfo);
163 }
164 }
165
166 if (!isLoadedAbility) {
167 HILOG_DEBUG("Target service has not been loaded.");
168 LoadAbility(targetService);
169 if (UIExtensionUtils::IsUIExtension(abilityRequest.abilityInfo.extensionAbilityType) && isSingleton) {
170 HILOG_DEBUG("Start uiextension in singleton mode.");
171 auto callerAbilityRecord = AAFwk::Token::GetAbilityRecordByToken(abilityRequest.callerToken);
172 if (callerAbilityRecord == nullptr) {
173 HILOG_ERROR("Failed to get callerAbilityRecord.");
174 return ERR_NULL_OBJECT;
175 }
176 std::string hostBundleName = callerAbilityRecord->GetAbilityInfo().bundleName;
177 int32_t inputId = abilityRequest.sessionInfo->want.GetIntParam(UIEXTENSION_ABILITY_ID,
178 INVALID_EXTENSION_RECORD_ID);
179 std::shared_ptr<ExtensionRecord> extensionRecord = nullptr;
180 CHECK_POINTER_AND_RETURN(uiExtensionAbilityRecordMgr_, ERR_NULL_OBJECT);
181 uiExtensionAbilityRecordMgr_->CreateExtensionRecord(
182 targetService, hostBundleName, extensionRecord, inputId);
183 HILOG_DEBUG("UIExtensionAbility id %{public}d.", inputId);
184 }
185 } else if (targetService->IsAbilityState(AbilityState::ACTIVE) && !IsUIExtensionAbility(targetService)) {
186 // It may have been started through connect
187 targetService->SetWant(abilityRequest.want);
188 CommandAbility(targetService);
189 } else if (IsUIExtensionAbility(targetService)) {
190 DoForegroundUIExtension(targetService, abilityRequest);
191 } else {
192 HILOG_INFO("Target service is already activating.");
193 EnqueueStartServiceReq(abilityRequest);
194 return ERR_OK;
195 }
196
197 sptr<Token> token = targetService->GetToken();
198 sptr<Token> preToken = nullptr;
199 if (targetService->GetPreAbilityRecord()) {
200 preToken = targetService->GetPreAbilityRecord()->GetToken();
201 }
202 DelayedSingleton<AppScheduler>::GetInstance()->AbilityBehaviorAnalysis(token, preToken, 0, 1, 1);
203 return ERR_OK;
204 }
205
DoForegroundUIExtension(std::shared_ptr<AbilityRecord> abilityRecord,const AbilityRequest & abilityRequest)206 void AbilityConnectManager::DoForegroundUIExtension(std::shared_ptr<AbilityRecord> abilityRecord,
207 const AbilityRequest &abilityRequest)
208 {
209 CHECK_POINTER(abilityRecord);
210 CHECK_POINTER(abilityRequest.sessionInfo);
211 HILOG_INFO("Foreground ability: %{public}s, persistentId: %{public}d", abilityRecord->GetURI().c_str(),
212 abilityRequest.sessionInfo->persistentId);
213 if (abilityRecord->IsReady() && !abilityRecord->IsAbilityState(AbilityState::INACTIVATING) &&
214 !abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING) &&
215 !abilityRecord->IsAbilityState(AbilityState::BACKGROUNDING) &&
216 abilityRecord->IsAbilityWindowReady()) {
217 if (abilityRecord->IsAbilityState(AbilityState::FOREGROUND)) {
218 abilityRecord->SetWant(abilityRequest.want);
219 CommandAbilityWindow(abilityRecord, abilityRequest.sessionInfo, WIN_CMD_FOREGROUND);
220 return;
221 } else {
222 if (abilityRecord->GetUIExtRequestSessionInfo() == nullptr) {
223 abilityRecord->SetWant(abilityRequest.want);
224 SaveUIExtRequestSessionInfo(abilityRecord, abilityRequest.sessionInfo);
225 DelayedSingleton<AppScheduler>::GetInstance()->MoveToForeground(abilityRecord->GetToken());
226 return;
227 }
228 }
229 }
230 EnqueueStartServiceReq(abilityRequest, abilityRecord->GetURI());
231 }
232
SaveUIExtRequestSessionInfo(std::shared_ptr<AbilityRecord> abilityRecord,sptr<SessionInfo> sessionInfo)233 void AbilityConnectManager::SaveUIExtRequestSessionInfo(std::shared_ptr<AbilityRecord> abilityRecord,
234 sptr<SessionInfo> sessionInfo)
235 {
236 CHECK_POINTER(abilityRecord);
237 CHECK_POINTER(taskHandler_);
238 abilityRecord->SetUIExtRequestSessionInfo(sessionInfo);
239 auto callback = [abilityRecord, connectManager = shared_from_this()]() {
240 std::lock_guard guard{connectManager->Lock_};
241 HILOG_ERROR("consume session timeout, abilityUri: %{public}s", abilityRecord->GetURI().c_str());
242 abilityRecord->SetUIExtRequestSessionInfo(nullptr);
243 };
244
245 int consumeSessionTimeout = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() *
246 UI_EXTENSION_CONSUME_SESSION_TIMEOUT_MULTIPLE;
247 std::string taskName = std::string("ConsumeSessionTimeout_") + std::to_string(abilityRecord->GetRecordId());
248 taskHandler_->SubmitTask(callback, taskName, consumeSessionTimeout);
249 }
250
EnqueueStartServiceReq(const AbilityRequest & abilityRequest,const std::string & serviceUri)251 void AbilityConnectManager::EnqueueStartServiceReq(const AbilityRequest &abilityRequest, const std::string &serviceUri)
252 {
253 std::lock_guard guard(startServiceReqListLock_);
254 auto abilityUri = abilityRequest.want.GetElement().GetURI();
255 if (!serviceUri.empty()) {
256 abilityUri = serviceUri;
257 }
258 HILOG_INFO("abilityUri is %{public}s", abilityUri.c_str());
259 auto reqListIt = startServiceReqList_.find(abilityUri);
260 if (reqListIt != startServiceReqList_.end()) {
261 reqListIt->second->push_back(abilityRequest);
262 } else {
263 auto reqList = std::make_shared<std::list<AbilityRequest>>();
264 reqList->push_back(abilityRequest);
265 startServiceReqList_.emplace(abilityUri, reqList);
266
267 CHECK_POINTER(taskHandler_);
268 auto callback = [abilityUri, connectManager = shared_from_this()]() {
269 std::lock_guard guard{connectManager->startServiceReqListLock_};
270 auto exist = connectManager->startServiceReqList_.erase(abilityUri);
271 if (exist) {
272 HILOG_ERROR("Target service %{public}s start timeout", abilityUri.c_str());
273 }
274 };
275
276 int connectTimeout =
277 AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * CONNECT_TIMEOUT_MULTIPLE;
278 taskHandler_->SubmitTask(callback, std::string("start_service_timeout:") + abilityUri,
279 connectTimeout);
280 }
281 }
282
TerminateAbilityLocked(const sptr<IRemoteObject> & token)283 int AbilityConnectManager::TerminateAbilityLocked(const sptr<IRemoteObject> &token)
284 {
285 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
286 HILOG_DEBUG("called");
287 auto abilityRecord = GetExtensionFromTerminatingMapInner(token);
288 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
289
290 if (abilityRecord->IsTerminating()) {
291 HILOG_DEBUG("Ability is on terminating.");
292 return ERR_OK;
293 }
294
295 if (!abilityRecord->GetConnectRecordList().empty()) {
296 HILOG_INFO("Target service has been connected. Post disconnect task.");
297 auto connectRecordList = abilityRecord->GetConnectRecordList();
298 HandleTerminateDisconnectTask(connectRecordList);
299 }
300
301 auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
302 HILOG_WARN("Disconnect ability terminate timeout.");
303 connectManager->HandleStopTimeoutTask(abilityRecord);
304 };
305 abilityRecord->Terminate(timeoutTask);
306 RemoveUIExtensionAbilityRecord(abilityRecord);
307
308 return ERR_OK;
309 }
310
StopServiceAbilityLocked(const AbilityRequest & abilityRequest)311 int AbilityConnectManager::StopServiceAbilityLocked(const AbilityRequest &abilityRequest)
312 {
313 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
314 HILOG_INFO("call");
315 AppExecFwk::ElementName element(abilityRequest.abilityInfo.deviceId, abilityRequest.abilityInfo.bundleName,
316 abilityRequest.abilityInfo.name, abilityRequest.abilityInfo.moduleName);
317 auto abilityRecord = GetServiceRecordByElementNameInner(element.GetURI());
318 if (FRS_BUNDLE_NAME == abilityRequest.abilityInfo.bundleName) {
319 abilityRecord = GetServiceRecordByElementNameInner(
320 element.GetURI() + std::to_string(abilityRequest.want.GetIntParam(FRS_APP_INDEX, 0)));
321 }
322 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
323
324 if (abilityRecord->IsTerminating()) {
325 HILOG_INFO("Ability is on terminating.");
326 return ERR_OK;
327 }
328
329 if (!abilityRecord->GetConnectRecordList().empty()) {
330 HILOG_INFO("Post disconnect task.");
331 auto connectRecordList = abilityRecord->GetConnectRecordList();
332 HandleTerminateDisconnectTask(connectRecordList);
333 }
334
335 TerminateRecord(abilityRecord);
336 return ERR_OK;
337 }
338
GetOrCreateExtensionRecord(const AbilityRequest & abilityRequest,bool isCreatedByConnect,const std::string & hostBundleName,std::shared_ptr<AbilityRecord> & extensionRecord,bool & isLoaded)339 int32_t AbilityConnectManager::GetOrCreateExtensionRecord(const AbilityRequest &abilityRequest, bool isCreatedByConnect,
340 const std::string &hostBundleName, std::shared_ptr<AbilityRecord> &extensionRecord, bool &isLoaded)
341 {
342 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
343 AppExecFwk::ElementName element(abilityRequest.abilityInfo.deviceId, abilityRequest.abilityInfo.bundleName,
344 abilityRequest.abilityInfo.name, abilityRequest.abilityInfo.moduleName);
345 CHECK_POINTER_AND_RETURN(uiExtensionAbilityRecordMgr_, ERR_NULL_OBJECT);
346 if (uiExtensionAbilityRecordMgr_->IsBelongToManager(abilityRequest.abilityInfo)) {
347 int32_t ret = uiExtensionAbilityRecordMgr_->GetOrCreateExtensionRecord(
348 abilityRequest, hostBundleName, extensionRecord, isLoaded);
349 if (ret != ERR_OK) {
350 return ret;
351 }
352 extensionRecord->SetCreateByConnectMode(isCreatedByConnect);
353 std::string extensionRecordKey = element.GetURI() + std::to_string(extensionRecord->GetUIExtensionAbilityId());
354 extensionRecord->SetURI(extensionRecordKey);
355 HILOG_DEBUG("Service map add, hostBundleName:%{public}s, key: %{public}s", hostBundleName.c_str(),
356 extensionRecordKey.c_str());
357 serviceMap_.emplace(extensionRecordKey, extensionRecord);
358 if (IsAbilityNeedKeepAlive(extensionRecord)) {
359 extensionRecord->SetKeepAlive();
360 extensionRecord->SetRestartTime(abilityRequest.restartTime);
361 extensionRecord->SetRestartCount(abilityRequest.restartCount);
362 }
363 return ERR_OK;
364 }
365 return ERR_INVALID_VALUE;
366 }
367
GetOrCreateServiceRecord(const AbilityRequest & abilityRequest,const bool isCreatedByConnect,std::shared_ptr<AbilityRecord> & targetService,bool & isLoadedAbility)368 void AbilityConnectManager::GetOrCreateServiceRecord(const AbilityRequest &abilityRequest,
369 const bool isCreatedByConnect, std::shared_ptr<AbilityRecord> &targetService, bool &isLoadedAbility)
370 {
371 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
372 // lifecycle is not complete when window extension is reused
373 bool noReuse = UIExtensionUtils::IsWindowExtension(abilityRequest.abilityInfo.extensionAbilityType);
374 AppExecFwk::ElementName element(abilityRequest.abilityInfo.deviceId, abilityRequest.abilityInfo.bundleName,
375 abilityRequest.abilityInfo.name, abilityRequest.abilityInfo.moduleName);
376 auto serviceMapIter = serviceMap_.find(element.GetURI());
377 std::string frsKey = "";
378 if (FRS_BUNDLE_NAME == abilityRequest.abilityInfo.bundleName) {
379 frsKey = element.GetURI() + std::to_string(abilityRequest.want.GetIntParam(FRS_APP_INDEX, 0));
380 serviceMapIter = serviceMap_.find(frsKey);
381 }
382 if (noReuse && serviceMapIter != serviceMap_.end()) {
383 if (FRS_BUNDLE_NAME == abilityRequest.abilityInfo.bundleName) {
384 serviceMap_.erase(frsKey);
385 } else {
386 serviceMap_.erase(element.GetURI());
387 }
388 if (IsSpecialAbility(abilityRequest.abilityInfo)) {
389 HILOG_INFO("Removing ability: %{public}s", element.GetURI().c_str());
390 }
391 }
392 if (noReuse || serviceMapIter == serviceMap_.end()) {
393 targetService = AbilityRecord::CreateAbilityRecord(abilityRequest);
394 if (targetService) {
395 targetService->SetOwnerMissionUserId(userId_);
396 }
397
398 if (isCreatedByConnect && targetService != nullptr) {
399 targetService->SetCreateByConnectMode();
400 }
401 if (targetService && abilityRequest.abilityInfo.name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
402 targetService->SetLauncherRoot();
403 targetService->SetKeepAlive();
404 targetService->SetRestartTime(abilityRequest.restartTime);
405 targetService->SetRestartCount(abilityRequest.restartCount);
406 } else if (IsAbilityNeedKeepAlive(targetService)) {
407 targetService->SetKeepAlive();
408 targetService->SetRestartTime(abilityRequest.restartTime);
409 targetService->SetRestartCount(abilityRequest.restartCount);
410 }
411 if (FRS_BUNDLE_NAME == abilityRequest.abilityInfo.bundleName) {
412 serviceMap_.emplace(frsKey, targetService);
413 } else {
414 serviceMap_.emplace(element.GetURI(), targetService);
415 }
416 isLoadedAbility = false;
417 } else {
418 targetService = serviceMapIter->second;
419 isLoadedAbility = true;
420 }
421 }
422
GetConnectRecordListFromMap(const sptr<IAbilityConnection> & connect,std::list<std::shared_ptr<ConnectionRecord>> & connectRecordList)423 void AbilityConnectManager::GetConnectRecordListFromMap(
424 const sptr<IAbilityConnection> &connect, std::list<std::shared_ptr<ConnectionRecord>> &connectRecordList)
425 {
426 auto connectMapIter = connectMap_.find(connect->AsObject());
427 if (connectMapIter != connectMap_.end()) {
428 connectRecordList = connectMapIter->second;
429 }
430 }
431
GetOrCreateTargetServiceRecord(const AbilityRequest & abilityRequest,const sptr<UIExtensionAbilityConnectInfo> & connectInfo,std::shared_ptr<AbilityRecord> & targetService,bool & isLoadedAbility)432 int32_t AbilityConnectManager::GetOrCreateTargetServiceRecord(
433 const AbilityRequest &abilityRequest, const sptr<UIExtensionAbilityConnectInfo> &connectInfo,
434 std::shared_ptr<AbilityRecord> &targetService, bool &isLoadedAbility)
435 {
436 if (UIExtensionUtils::IsUIExtension(abilityRequest.abilityInfo.extensionAbilityType) && connectInfo != nullptr) {
437 int32_t ret = GetOrCreateExtensionRecord(
438 abilityRequest, true, connectInfo->hostBundleName, targetService, isLoadedAbility);
439 if (ret != ERR_OK || targetService == nullptr) {
440 HILOG_ERROR("Failed to get or create extension record.");
441 return ERR_NULL_OBJECT;
442 }
443 connectInfo->uiExtensionAbilityId = targetService->GetUIExtensionAbilityId();
444 HILOG_DEBUG("UIExtensionAbility id %{public}d.", connectInfo->uiExtensionAbilityId);
445 } else {
446 GetOrCreateServiceRecord(abilityRequest, true, targetService, isLoadedAbility);
447 }
448 CHECK_POINTER_AND_RETURN(targetService, ERR_INVALID_VALUE);
449 return ERR_OK;
450 }
451
ConnectAbilityLocked(const AbilityRequest & abilityRequest,const sptr<IAbilityConnection> & connect,const sptr<IRemoteObject> & callerToken,sptr<SessionInfo> sessionInfo,sptr<UIExtensionAbilityConnectInfo> connectInfo)452 int AbilityConnectManager::ConnectAbilityLocked(const AbilityRequest &abilityRequest,
453 const sptr<IAbilityConnection> &connect, const sptr<IRemoteObject> &callerToken, sptr<SessionInfo> sessionInfo,
454 sptr<UIExtensionAbilityConnectInfo> connectInfo)
455 {
456 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
457 HILOG_DEBUG("callee:%{public}s.", abilityRequest.want.GetElement().GetURI().c_str());
458 std::lock_guard guard(Lock_);
459
460 // 1. get target service ability record, and check whether it has been loaded.
461 std::shared_ptr<AbilityRecord> targetService;
462 bool isLoadedAbility = false;
463 int32_t ret = GetOrCreateTargetServiceRecord(abilityRequest, connectInfo, targetService, isLoadedAbility);
464 if (ret != ERR_OK) {
465 return ret;
466 }
467 // 2. get target connectRecordList, and check whether this callback has been connected.
468 ConnectListType connectRecordList;
469 GetConnectRecordListFromMap(connect, connectRecordList);
470 bool isCallbackConnected = !connectRecordList.empty();
471 // 3. If this service ability and callback has been connected, There is no need to connect repeatedly
472 if (isLoadedAbility && (isCallbackConnected) && IsAbilityConnected(targetService, connectRecordList)) {
473 HILOG_INFO("Service and callback was connected.");
474 return ERR_OK;
475 }
476
477 // 4. Other cases , need to connect the service ability
478 auto connectRecord = ConnectionRecord::CreateConnectionRecord(callerToken, targetService, connect);
479 CHECK_POINTER_AND_RETURN(connectRecord, ERR_INVALID_VALUE);
480 connectRecord->AttachCallerInfo();
481 connectRecord->SetConnectState(ConnectionState::CONNECTING);
482 targetService->AddConnectRecordToList(connectRecord);
483 targetService->SetSessionInfo(sessionInfo);
484 connectRecordList.push_back(connectRecord);
485 if (isCallbackConnected) {
486 RemoveConnectDeathRecipient(connect);
487 connectMap_.erase(connectMap_.find(connect->AsObject()));
488 }
489 AddConnectDeathRecipient(connect);
490 connectMap_.emplace(connect->AsObject(), connectRecordList);
491 targetService->SetLaunchReason(LaunchReason::LAUNCHREASON_CONNECT_EXTENSION);
492
493 if (UIExtensionUtils::IsWindowExtension(targetService->GetAbilityInfo().extensionAbilityType)
494 && abilityRequest.sessionInfo) {
495 windowExtensionMap_.emplace(connect->AsObject(),
496 WindowExtMapValType(targetService->GetApplicationInfo().accessTokenId, abilityRequest.sessionInfo));
497 }
498
499 if (!isLoadedAbility) {
500 LoadAbility(targetService);
501 } else if (targetService->IsAbilityState(AbilityState::ACTIVE)) {
502 targetService->SetWant(abilityRequest.want);
503 HandleActiveAbility(targetService, connectRecord);
504 } else {
505 HILOG_DEBUG("Target service is activating, wait for callback");
506 }
507
508 auto token = targetService->GetToken();
509 auto preToken = iface_cast<Token>(connectRecord->GetToken());
510 DelayedSingleton<AppScheduler>::GetInstance()->AbilityBehaviorAnalysis(token, preToken, 0, 1, 1);
511 return ret;
512 }
513
HandleActiveAbility(std::shared_ptr<AbilityRecord> & targetService,std::shared_ptr<ConnectionRecord> & connectRecord)514 void AbilityConnectManager::HandleActiveAbility(std::shared_ptr<AbilityRecord> &targetService,
515 std::shared_ptr<ConnectionRecord> &connectRecord)
516 {
517 if (targetService == nullptr) {
518 HILOG_WARN("null target service.");
519 return;
520 }
521 if (targetService->GetConnectRecordList().size() > 1) {
522 if (taskHandler_ != nullptr && targetService->GetConnRemoteObject()) {
523 auto task = [connectRecord]() { connectRecord->CompleteConnect(ERR_OK); };
524 taskHandler_->SubmitTask(task, TaskQoS::USER_INTERACTIVE);
525 } else {
526 HILOG_INFO("Target service is connecting, wait for callback");
527 }
528 } else {
529 ConnectAbility(targetService);
530 }
531 }
532
DisconnectAbilityLocked(const sptr<IAbilityConnection> & connect)533 int AbilityConnectManager::DisconnectAbilityLocked(const sptr<IAbilityConnection> &connect)
534 {
535 std::lock_guard guard(Lock_);
536 return DisconnectAbilityLocked(connect, false);
537 }
538
DisconnectAbilityLocked(const sptr<IAbilityConnection> & connect,bool force)539 int AbilityConnectManager::DisconnectAbilityLocked(const sptr<IAbilityConnection> &connect, bool force)
540 {
541 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
542 HILOG_DEBUG("call");
543
544 // 1. check whether callback was connected.
545 ConnectListType connectRecordList;
546 GetConnectRecordListFromMap(connect, connectRecordList);
547 if (connectRecordList.empty()) {
548 HILOG_ERROR("Can't find the connect list from connect map by callback.");
549 return CONNECTION_NOT_EXIST;
550 }
551
552 // 2. schedule disconnect to target service
553 int result = ERR_OK;
554 ConnectListType list;
555 for (auto &connectRecord : connectRecordList) {
556 if (connectRecord) {
557 auto abilityRecord = connectRecord->GetAbilityRecord();
558 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
559 HILOG_DEBUG("abilityName: %{public}s, bundleName: %{public}s",
560 abilityRecord->GetAbilityInfo().name.c_str(), abilityRecord->GetAbilityInfo().bundleName.c_str());
561 if (abilityRecord->GetAbilityInfo().type == AbilityType::EXTENSION) {
562 RemoveExtensionDelayDisconnectTask(connectRecord);
563 }
564 if (connectRecord->GetCallerTokenId() != IPCSkeleton::GetCallingTokenID() &&
565 static_cast<uint32_t>(IPCSkeleton::GetSelfTokenID() != IPCSkeleton::GetCallingTokenID())) {
566 HILOG_WARN("The caller is inconsistent with the caller stored in the connectRecord.");
567 continue;
568 }
569
570 if (force) {
571 DisconnectRecordForce(list, connectRecord);
572 } else {
573 result = DisconnectRecordNormal(list, connectRecord);
574 }
575
576 if (result != ERR_OK) {
577 HILOG_ERROR("Disconnect ability fail , ret = %{public}d.", result);
578 break;
579 }
580 }
581 }
582 for (auto&& connectRecord : list) {
583 RemoveConnectionRecordFromMap(connectRecord);
584 }
585
586 return result;
587 }
588
TerminateRecord(std::shared_ptr<AbilityRecord> abilityRecord)589 void AbilityConnectManager::TerminateRecord(std::shared_ptr<AbilityRecord> abilityRecord)
590 {
591 auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
592 HILOG_WARN("Disconnect ability terminate timeout.");
593 connectManager->HandleStopTimeoutTask(abilityRecord);
594 };
595
596 MoveToTerminatingMap(abilityRecord);
597 abilityRecord->Terminate(timeoutTask);
598 }
599
DisconnectRecordNormal(ConnectListType & list,std::shared_ptr<ConnectionRecord> connectRecord) const600 int AbilityConnectManager::DisconnectRecordNormal(ConnectListType &list,
601 std::shared_ptr<ConnectionRecord> connectRecord) const
602 {
603 auto result = connectRecord->DisconnectAbility();
604 if (result != ERR_OK) {
605 HILOG_ERROR("Disconnect ability fail , ret = %{public}d.", result);
606 return result;
607 }
608
609 if (connectRecord->GetConnectState() == ConnectionState::DISCONNECTED) {
610 HILOG_WARN("This record: %{public}d complete disconnect directly.", connectRecord->GetRecordId());
611 connectRecord->CompleteDisconnect(ERR_OK, false);
612 list.emplace_back(connectRecord);
613 }
614 return ERR_OK;
615 }
616
DisconnectRecordForce(ConnectListType & list,std::shared_ptr<ConnectionRecord> connectRecord)617 void AbilityConnectManager::DisconnectRecordForce(ConnectListType &list,
618 std::shared_ptr<ConnectionRecord> connectRecord)
619 {
620 auto abilityRecord = connectRecord->GetAbilityRecord();
621 if (abilityRecord == nullptr) {
622 HILOG_ERROR("Disconnect force abilityRecord null");
623 return;
624 }
625 abilityRecord->RemoveConnectRecordFromList(connectRecord);
626 connectRecord->CompleteDisconnect(ERR_OK, true);
627 list.emplace_back(connectRecord);
628 if (abilityRecord->IsConnectListEmpty() && abilityRecord->GetStartId() == 0) {
629 HILOG_WARN("Force terminate ability record state: %{public}d.", abilityRecord->GetAbilityState());
630 TerminateRecord(abilityRecord);
631 }
632 }
633
AttachAbilityThreadLocked(const sptr<IAbilityScheduler> & scheduler,const sptr<IRemoteObject> & token)634 int AbilityConnectManager::AttachAbilityThreadLocked(
635 const sptr<IAbilityScheduler> &scheduler, const sptr<IRemoteObject> &token)
636 {
637 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
638 std::lock_guard guard(Lock_);
639 auto abilityRecord = GetExtensionFromServiceMapInner(token);
640 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
641 if (taskHandler_ != nullptr) {
642 int recordId = abilityRecord->GetRecordId();
643 std::string taskName = std::string("LoadTimeout_") + std::to_string(recordId);
644 taskHandler_->CancelTask(taskName);
645 }
646 if (eventHandler_) {
647 eventHandler_->RemoveEvent(AbilityManagerService::LOAD_TIMEOUT_MSG,
648 abilityRecord->GetAbilityRecordId());
649 }
650 std::string element = abilityRecord->GetURI();
651 HILOG_DEBUG("Ability: %{public}s", element.c_str());
652 if (abilityRecord->IsSceneBoard()) {
653 HILOG_INFO("Attach Ability: %{public}s", element.c_str());
654 }
655 abilityRecord->SetScheduler(scheduler);
656 if (IsUIExtensionAbility(abilityRecord) && !abilityRecord->IsCreateByConnect()) {
657 DelayedSingleton<AppScheduler>::GetInstance()->MoveToForeground(token);
658 } else {
659 abilityRecord->Inactivate();
660 }
661
662 return ERR_OK;
663 }
664
OnAbilityRequestDone(const sptr<IRemoteObject> & token,const int32_t state)665 void AbilityConnectManager::OnAbilityRequestDone(const sptr<IRemoteObject> &token, const int32_t state)
666 {
667 HILOG_DEBUG("state: %{public}d", state);
668 std::lock_guard guard(Lock_);
669 AppAbilityState abilityState = DelayedSingleton<AppScheduler>::GetInstance()->ConvertToAppAbilityState(state);
670 if (abilityState == AppAbilityState::ABILITY_STATE_FOREGROUND) {
671 auto abilityRecord = GetExtensionFromServiceMapInner(token);
672 CHECK_POINTER(abilityRecord);
673 if (!IsUIExtensionAbility(abilityRecord)) {
674 HILOG_ERROR("Not ui extension.");
675 return;
676 }
677 if (abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING)) {
678 HILOG_WARN("abilityRecord is foregrounding.");
679 return;
680 }
681 std::string element = abilityRecord->GetURI();
682 HILOG_DEBUG("Ability is %{public}s, start to foreground.", element.c_str());
683 MoveToForeground(abilityRecord);
684 }
685 }
686
OnAppStateChanged(const AppInfo & info)687 void AbilityConnectManager::OnAppStateChanged(const AppInfo &info)
688 {
689 std::lock_guard guard(Lock_);
690 std::for_each(serviceMap_.begin(), serviceMap_.end(), [&info](ServiceMapType::reference service) {
691 if (service.second && (info.processName == service.second->GetAbilityInfo().process ||
692 info.processName == service.second->GetApplicationInfo().bundleName)) {
693 auto appName = service.second->GetApplicationInfo().name;
694 auto uid = service.second->GetAbilityInfo().applicationInfo.uid;
695 auto isExist = [&appName, &uid](
696 const AppData &appData) { return appData.appName == appName && appData.uid == uid; };
697 auto iter = std::find_if(info.appData.begin(), info.appData.end(), isExist);
698 if (iter != info.appData.end()) {
699 service.second->SetAppState(info.state);
700 }
701 }
702 });
703 }
704
AbilityTransitionDone(const sptr<IRemoteObject> & token,int state)705 int AbilityConnectManager::AbilityTransitionDone(const sptr<IRemoteObject> &token, int state)
706 {
707 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
708 std::lock_guard guard(Lock_);
709 int targetState = AbilityRecord::ConvertLifeCycleToAbilityState(static_cast<AbilityLifeCycleState>(state));
710 std::string abilityState = AbilityRecord::ConvertAbilityState(static_cast<AbilityState>(targetState));
711 std::shared_ptr<AbilityRecord> abilityRecord;
712 if (targetState == AbilityState::INACTIVE
713 || targetState == AbilityState::FOREGROUND
714 || targetState == AbilityState::BACKGROUND) {
715 abilityRecord = GetExtensionFromServiceMapInner(token);
716 } else if (targetState == AbilityState::INITIAL) {
717 abilityRecord = GetExtensionFromTerminatingMapInner(token);
718 } else {
719 abilityRecord = nullptr;
720 }
721 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
722 std::string element = abilityRecord->GetURI();
723 HILOG_DEBUG("Ability: %{public}s, state: %{public}s", element.c_str(), abilityState.c_str());
724
725 switch (targetState) {
726 case AbilityState::INACTIVE: {
727 if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
728 DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
729 token, AppExecFwk::AbilityState::ABILITY_STATE_CREATE);
730 } else {
731 DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
732 token, AppExecFwk::ExtensionState::EXTENSION_STATE_CREATE);
733 auto preloadTask = [owner = weak_from_this(), abilityRecord] {
734 auto acm = owner.lock();
735 if (acm == nullptr) {
736 HILOG_ERROR("AbilityConnectManager is nullptr.");
737 return;
738 }
739 acm->ProcessPreload(abilityRecord);
740 };
741 if (taskHandler_ != nullptr) {
742 taskHandler_->SubmitTask(preloadTask);
743 }
744 }
745 return DispatchInactive(abilityRecord, state);
746 }
747 case AbilityState::FOREGROUND: {
748 return DispatchForeground(abilityRecord);
749 }
750 case AbilityState::BACKGROUND: {
751 return DispatchBackground(abilityRecord);
752 }
753 case AbilityState::INITIAL: {
754 if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
755 DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
756 token, AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED);
757 } else {
758 DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
759 token, AppExecFwk::ExtensionState::EXTENSION_STATE_TERMINATED);
760 }
761 return DispatchTerminate(abilityRecord);
762 }
763 default: {
764 HILOG_WARN("Don't support transiting state: %{public}d", state);
765 return ERR_INVALID_VALUE;
766 }
767 }
768 }
769
ProcessPreload(const std::shared_ptr<AbilityRecord> & record) const770 void AbilityConnectManager::ProcessPreload(const std::shared_ptr<AbilityRecord> &record) const
771 {
772 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
773 CHECK_POINTER(bundleMgrHelper);
774 auto abilityInfo = record->GetAbilityInfo();
775 Want want;
776 want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
777 auto uid = record->GetUid();
778 want.SetParam("uid", uid);
779 bundleMgrHelper->ProcessPreload(want);
780 }
781
ScheduleConnectAbilityDoneLocked(const sptr<IRemoteObject> & token,const sptr<IRemoteObject> & remoteObject)782 int AbilityConnectManager::ScheduleConnectAbilityDoneLocked(
783 const sptr<IRemoteObject> &token, const sptr<IRemoteObject> &remoteObject)
784 {
785 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
786 std::lock_guard guard(Lock_);
787 CHECK_POINTER_AND_RETURN(token, ERR_INVALID_VALUE);
788
789 auto abilityRecord = Token::GetAbilityRecordByToken(token);
790 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
791
792 std::string element = abilityRecord->GetURI();
793 HILOG_DEBUG("Connect ability done, ability: %{public}s.", element.c_str());
794
795 if ((!abilityRecord->IsAbilityState(AbilityState::INACTIVE)) &&
796 (!abilityRecord->IsAbilityState(AbilityState::ACTIVE))) {
797 HILOG_ERROR("Ability record state is not inactive ,state: %{public}d", abilityRecord->GetAbilityState());
798 return INVALID_CONNECTION_STATE;
799 }
800
801 if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
802 DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
803 token, AppExecFwk::AbilityState::ABILITY_STATE_CONNECTED);
804 } else {
805 DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
806 token, AppExecFwk::ExtensionState::EXTENSION_STATE_CONNECTED);
807 }
808
809 abilityRecord->SetConnRemoteObject(remoteObject);
810 // There may be multiple callers waiting for the connection result
811 auto connectRecordList = abilityRecord->GetConnectRecordList();
812 for (auto &connectRecord : connectRecordList) {
813 connectRecord->ScheduleConnectAbilityDone();
814 if (abilityRecord->GetAbilityInfo().type == AbilityType::EXTENSION &&
815 abilityRecord->GetAbilityInfo().extensionAbilityType != AppExecFwk::ExtensionAbilityType::SERVICE) {
816 PostExtensionDelayDisconnectTask(connectRecord);
817 }
818 }
819
820 return ERR_OK;
821 }
822
ScheduleDisconnectAbilityDoneLocked(const sptr<IRemoteObject> & token)823 int AbilityConnectManager::ScheduleDisconnectAbilityDoneLocked(const sptr<IRemoteObject> &token)
824 {
825 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
826 std::lock_guard guard(Lock_);
827 auto abilityRecord = GetExtensionFromServiceMapInner(token);
828 CHECK_POINTER_AND_RETURN(abilityRecord, CONNECTION_NOT_EXIST);
829
830 auto connect = abilityRecord->GetDisconnectingRecord();
831 CHECK_POINTER_AND_RETURN(connect, CONNECTION_NOT_EXIST);
832
833 if (!abilityRecord->IsAbilityState(AbilityState::ACTIVE)) {
834 if (IsUIExtensionAbility(abilityRecord) && (abilityRecord->IsForeground() ||
835 abilityRecord->IsAbilityState(AbilityState::BACKGROUND) ||
836 abilityRecord->IsAbilityState(AbilityState::BACKGROUNDING))) {
837 // uiextension ability support connect and start, so the ability state maybe others
838 HILOG_INFO("Disconnect when ability state is %{public}d", abilityRecord->GetAbilityState());
839 } else {
840 HILOG_ERROR("The service ability state is not active ,state: %{public}d", abilityRecord->GetAbilityState());
841 return INVALID_CONNECTION_STATE;
842 }
843 }
844
845 if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
846 DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
847 token, AppExecFwk::AbilityState::ABILITY_STATE_DISCONNECTED);
848 } else {
849 DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
850 token, AppExecFwk::ExtensionState::EXTENSION_STATE_DISCONNECTED);
851 }
852
853 std::string element = abilityRecord->GetURI();
854 HILOG_DEBUG("Disconnect ability done, service:%{public}s.", element.c_str());
855
856 // complete disconnect and remove record from conn map
857 connect->ScheduleDisconnectAbilityDone();
858 abilityRecord->RemoveConnectRecordFromList(connect);
859 if (abilityRecord->IsConnectListEmpty() && abilityRecord->GetStartId() == 0) {
860 if (IsUIExtensionAbility(abilityRecord) && CheckUIExtensionAbilitySessionExistLocked(abilityRecord)) {
861 HILOG_INFO("There exist ui extension component, don't terminate when disconnect.");
862 } else {
863 HILOG_DEBUG("Service ability has no any connection, and not started, need terminate.");
864 RemoveUIExtensionAbilityRecord(abilityRecord);
865 if (!IsSceneBoard(abilityRecord)) {
866 TerminateRecord(abilityRecord);
867 }
868 }
869 }
870 RemoveConnectionRecordFromMap(connect);
871
872 return ERR_OK;
873 }
874
ScheduleCommandAbilityDoneLocked(const sptr<IRemoteObject> & token)875 int AbilityConnectManager::ScheduleCommandAbilityDoneLocked(const sptr<IRemoteObject> &token)
876 {
877 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
878 std::lock_guard guard(Lock_);
879 CHECK_POINTER_AND_RETURN(token, ERR_INVALID_VALUE);
880 auto abilityRecord = Token::GetAbilityRecordByToken(token);
881 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
882 std::string element = abilityRecord->GetURI();
883 HILOG_DEBUG("Ability: %{public}s", element.c_str());
884
885 if ((!abilityRecord->IsAbilityState(AbilityState::INACTIVE)) &&
886 (!abilityRecord->IsAbilityState(AbilityState::ACTIVE))) {
887 HILOG_ERROR("Ability record state is not inactive ,state: %{public}d", abilityRecord->GetAbilityState());
888 return INVALID_CONNECTION_STATE;
889 }
890 // complete command and pop waiting start ability from queue.
891 CompleteCommandAbility(abilityRecord);
892
893 return ERR_OK;
894 }
895
ScheduleCommandAbilityWindowDone(const sptr<IRemoteObject> & token,const sptr<SessionInfo> & sessionInfo,WindowCommand winCmd,AbilityCommand abilityCmd)896 int AbilityConnectManager::ScheduleCommandAbilityWindowDone(
897 const sptr<IRemoteObject> &token,
898 const sptr<SessionInfo> &sessionInfo,
899 WindowCommand winCmd,
900 AbilityCommand abilityCmd)
901 {
902 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
903 std::lock_guard guard(Lock_);
904 CHECK_POINTER_AND_RETURN(token, ERR_INVALID_VALUE);
905 CHECK_POINTER_AND_RETURN(sessionInfo, ERR_INVALID_VALUE);
906 auto abilityRecord = Token::GetAbilityRecordByToken(token);
907 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
908 std::string element = abilityRecord->GetURI();
909 HILOG_DEBUG("Ability: %{public}s, persistentId: %{private}d, winCmd: %{public}d, abilityCmd: %{public}d",
910 element.c_str(), sessionInfo->persistentId, winCmd, abilityCmd);
911
912 // Only foreground mode need cancel, cause only foreground CommandAbilityWindow post timeout task.
913 if (taskHandler_ && winCmd == WIN_CMD_FOREGROUND) {
914 int recordId = abilityRecord->GetRecordId();
915 std::string taskName = std::string("CommandWindowTimeout_") + std::to_string(recordId) + std::string("_") +
916 std::to_string(sessionInfo->persistentId) + std::string("_") + std::to_string(winCmd);
917 taskHandler_->CancelTask(taskName);
918 }
919
920 if (winCmd == WIN_CMD_DESTROY) {
921 HandleCommandDestroy(sessionInfo);
922 }
923
924 abilityRecord->SetAbilityWindowState(sessionInfo, winCmd, true);
925
926 CompleteStartServiceReq(element);
927 return ERR_OK;
928 }
929
HandleCommandDestroy(const sptr<SessionInfo> & sessionInfo)930 void AbilityConnectManager::HandleCommandDestroy(const sptr<SessionInfo> &sessionInfo)
931 {
932 if (sessionInfo == nullptr) {
933 HILOG_WARN("null session info.");
934 return;
935 }
936 if (sessionInfo->sessionToken) {
937 RemoveUIExtWindowDeathRecipient(sessionInfo->sessionToken);
938 size_t ret = uiExtensionMap_.erase(sessionInfo->sessionToken);
939 if (ret > 0) {
940 return;
941 }
942
943 for (auto& item : windowExtensionMap_) {
944 auto sessionInfoVal = item.second.second;
945 if (sessionInfoVal && sessionInfoVal->callerToken == sessionInfo->sessionToken) {
946 windowExtensionMap_.erase(item.first);
947 break;
948 }
949 }
950 }
951 }
952
CompleteCommandAbility(std::shared_ptr<AbilityRecord> abilityRecord)953 void AbilityConnectManager::CompleteCommandAbility(std::shared_ptr<AbilityRecord> abilityRecord)
954 {
955 CHECK_POINTER(abilityRecord);
956 if (taskHandler_) {
957 int recordId = abilityRecord->GetRecordId();
958 std::string taskName = std::string("CommandTimeout_") + std::to_string(recordId) + std::string("_") +
959 std::to_string(abilityRecord->GetStartId());
960 taskHandler_->CancelTask(taskName);
961 }
962
963 abilityRecord->SetAbilityState(AbilityState::ACTIVE);
964
965 // manage queued request
966 CompleteStartServiceReq(abilityRecord->GetURI());
967 if (abilityRecord->NeedConnectAfterCommand()) {
968 ConnectAbility(abilityRecord);
969 }
970 }
971
CompleteStartServiceReq(const std::string & serviceUri)972 void AbilityConnectManager::CompleteStartServiceReq(const std::string &serviceUri)
973 {
974 std::shared_ptr<std::list<OHOS::AAFwk::AbilityRequest>> reqList;
975 {
976 std::lock_guard guard(startServiceReqListLock_);
977 auto it = startServiceReqList_.find(serviceUri);
978 if (it != startServiceReqList_.end()) {
979 reqList = it->second;
980 startServiceReqList_.erase(it);
981 if (taskHandler_) {
982 taskHandler_->CancelTask(std::string("start_service_timeout:") + serviceUri);
983 }
984 }
985 }
986
987 if (reqList) {
988 HILOG_INFO("Target service is activating : %{public}zu, uri: %{public}s", reqList->size(), serviceUri.c_str());
989 for (const auto &req: *reqList) {
990 StartAbilityLocked(req);
991 }
992 }
993 }
994
GetServiceRecordByElementName(const std::string & element)995 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetServiceRecordByElementName(const std::string &element)
996 {
997 std::lock_guard guard(Lock_);
998 return GetServiceRecordByElementNameInner(element);
999 }
1000
GetServiceRecordByElementNameInner(const std::string & element)1001 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetServiceRecordByElementNameInner(const std::string &element)
1002 {
1003 auto mapIter = serviceMap_.find(element);
1004 if (mapIter != serviceMap_.end()) {
1005 return mapIter->second;
1006 }
1007 return nullptr;
1008 }
1009
GetExtensionByTokenFromServiceMap(const sptr<IRemoteObject> & token)1010 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetExtensionByTokenFromServiceMap(
1011 const sptr<IRemoteObject> &token)
1012 {
1013 std::lock_guard guard(Lock_);
1014 return GetExtensionFromServiceMapInner(token);
1015 }
1016
GetExtensionFromServiceMapInner(const sptr<IRemoteObject> & token)1017 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetExtensionFromServiceMapInner(
1018 const sptr<IRemoteObject> &token)
1019 {
1020 auto IsMatch = [token](auto service) {
1021 if (!service.second) {
1022 return false;
1023 }
1024 sptr<IRemoteObject> srcToken = service.second->GetToken();
1025 return srcToken == token;
1026 };
1027 auto serviceRecord = std::find_if(serviceMap_.begin(), serviceMap_.end(), IsMatch);
1028 if (serviceRecord != serviceMap_.end()) {
1029 return serviceRecord->second;
1030 }
1031 return nullptr;
1032 }
1033
GetExtensionFromServiceMapInner(int32_t abilityRecordId)1034 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetExtensionFromServiceMapInner(
1035 int32_t abilityRecordId)
1036 {
1037 for (const auto &[key, value] : serviceMap_) {
1038 if (value && value->GetAbilityRecordId() == abilityRecordId) {
1039 return value;
1040 }
1041 }
1042 return nullptr;
1043 }
1044
GetUIExtensioBySessionInfo(const sptr<SessionInfo> & sessionInfo)1045 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetUIExtensioBySessionInfo(
1046 const sptr<SessionInfo> &sessionInfo)
1047 {
1048 std::lock_guard guard(Lock_);
1049 CHECK_POINTER_AND_RETURN(sessionInfo, nullptr);
1050 auto sessionToken = iface_cast<Rosen::ISession>(sessionInfo->sessionToken);
1051 CHECK_POINTER_AND_RETURN(sessionToken, nullptr);
1052 std::string descriptor = Str16ToStr8(sessionToken->GetDescriptor());
1053 if (descriptor != "OHOS.ISession") {
1054 HILOG_ERROR("Input token is not a sessionToken, token->GetDescriptor(): %{public}s",
1055 descriptor.c_str());
1056 return nullptr;
1057 }
1058
1059 auto it = uiExtensionMap_.find(sessionToken->AsObject());
1060 if (it != uiExtensionMap_.end()) {
1061 auto abilityRecord = it->second.first.lock();
1062 if (abilityRecord == nullptr) {
1063 HILOG_WARN("abilityRecord is nullptr.");
1064 RemoveUIExtWindowDeathRecipient(sessionToken->AsObject());
1065 uiExtensionMap_.erase(it);
1066 return nullptr;
1067 }
1068 auto savedSessionInfo = it->second.second;
1069 if (!savedSessionInfo || savedSessionInfo->sessionToken != sessionInfo->sessionToken
1070 || savedSessionInfo->callerToken != sessionInfo->callerToken) {
1071 HILOG_WARN("Inconsistent sessionInfo.");
1072 return nullptr;
1073 }
1074 return abilityRecord;
1075 } else {
1076 HILOG_ERROR("UIExtension not found.");
1077 }
1078 return nullptr;
1079 }
1080
GetExtensionByTokenFromTerminatingMap(const sptr<IRemoteObject> & token)1081 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetExtensionByTokenFromTerminatingMap(
1082 const sptr<IRemoteObject> &token)
1083 {
1084 std::lock_guard guard(Lock_);
1085 return GetExtensionFromTerminatingMapInner(token);
1086 }
1087
GetExtensionFromTerminatingMapInner(const sptr<IRemoteObject> & token)1088 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetExtensionFromTerminatingMapInner(
1089 const sptr<IRemoteObject> &token)
1090 {
1091 auto IsMatch = [token](auto& extension) {
1092 if (extension.second == nullptr) {
1093 return false;
1094 }
1095 auto&& terminatingToken = extension.second->GetToken();
1096 if (terminatingToken != nullptr) {
1097 return terminatingToken->AsObject() == token;
1098 }
1099 return false;
1100 };
1101
1102 auto terminatingExtensionRecord =
1103 std::find_if(terminatingExtensionMap_.begin(), terminatingExtensionMap_.end(), IsMatch);
1104 if (terminatingExtensionRecord != terminatingExtensionMap_.end()) {
1105 return terminatingExtensionRecord->second;
1106 }
1107 return nullptr;
1108 }
1109
GetConnectRecordListByCallback(sptr<IAbilityConnection> callback)1110 std::list<std::shared_ptr<ConnectionRecord>> AbilityConnectManager::GetConnectRecordListByCallback(
1111 sptr<IAbilityConnection> callback)
1112 {
1113 std::lock_guard guard(Lock_);
1114 std::list<std::shared_ptr<ConnectionRecord>> connectList;
1115 auto connectMapIter = connectMap_.find(callback->AsObject());
1116 if (connectMapIter != connectMap_.end()) {
1117 connectList = connectMapIter->second;
1118 }
1119 return connectList;
1120 }
1121
GetAbilityRecordById(int64_t abilityRecordId)1122 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetAbilityRecordById(int64_t abilityRecordId)
1123 {
1124 auto IsMatch = [abilityRecordId](auto service) {
1125 if (!service.second) {
1126 return false;
1127 }
1128 return abilityRecordId == service.second->GetAbilityRecordId();
1129 };
1130 auto serviceRecord = std::find_if(serviceMap_.begin(), serviceMap_.end(), IsMatch);
1131 if (serviceRecord != serviceMap_.end()) {
1132 return serviceRecord->second;
1133 }
1134 return nullptr;
1135 }
1136
LoadAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)1137 void AbilityConnectManager::LoadAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
1138 {
1139 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1140 CHECK_POINTER(abilityRecord);
1141 abilityRecord->SetStartTime();
1142
1143 if (!abilityRecord->CanRestartRootLauncher()) {
1144 HILOG_ERROR("Root launcher restart is out of max count.");
1145 RemoveServiceAbility(abilityRecord);
1146 return;
1147 }
1148 if (!abilityRecord->IsDebugApp()) {
1149 HILOG_DEBUG("IsDebug is false, here is not debug app");
1150 PostTimeOutTask(abilityRecord, AbilityManagerService::LOAD_TIMEOUT_MSG);
1151 }
1152 sptr<Token> token = abilityRecord->GetToken();
1153 sptr<Token> perToken = nullptr;
1154 if (abilityRecord->IsCreateByConnect()) {
1155 perToken = iface_cast<Token>(abilityRecord->GetConnectingRecord()->GetToken());
1156 } else {
1157 auto callerList = abilityRecord->GetCallerRecordList();
1158 if (!callerList.empty() && callerList.back()) {
1159 auto caller = callerList.back()->GetCaller();
1160 if (caller) {
1161 perToken = caller->GetToken();
1162 }
1163 }
1164 }
1165 DelayedSingleton<AppScheduler>::GetInstance()->LoadAbility(
1166 token, perToken, abilityRecord->GetAbilityInfo(), abilityRecord->GetApplicationInfo(),
1167 abilityRecord->GetWant());
1168 }
1169
PostRestartResidentTask(const AbilityRequest & abilityRequest)1170 void AbilityConnectManager::PostRestartResidentTask(const AbilityRequest &abilityRequest)
1171 {
1172 HILOG_INFO("PostRestartResidentTask start.");
1173 CHECK_POINTER(taskHandler_);
1174 std::string taskName = std::string("RestartResident_") + std::string(abilityRequest.abilityInfo.name);
1175 auto task = [abilityRequest, connectManager = shared_from_this()]() {
1176 CHECK_POINTER(connectManager);
1177 connectManager->HandleRestartResidentTask(abilityRequest);
1178 };
1179 int restartIntervalTime = 0;
1180 auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
1181 if (abilityMgr) {
1182 restartIntervalTime = AmsConfigurationParameter::GetInstance().GetRestartIntervalTime();
1183 }
1184 HILOG_DEBUG("PostRestartResidentTask, time:%{public}d", restartIntervalTime);
1185 taskHandler_->SubmitTask(task, taskName, restartIntervalTime);
1186 HILOG_INFO("PostRestartResidentTask end.");
1187 }
1188
HandleRestartResidentTask(const AbilityRequest & abilityRequest)1189 void AbilityConnectManager::HandleRestartResidentTask(const AbilityRequest &abilityRequest)
1190 {
1191 HILOG_INFO("HandleRestartResidentTask start.");
1192 std::lock_guard guard(Lock_);
1193 auto findRestartResidentTask = [abilityRequest](const AbilityRequest &requestInfo) {
1194 return (requestInfo.want.GetElement().GetBundleName() == abilityRequest.want.GetElement().GetBundleName() &&
1195 requestInfo.want.GetElement().GetModuleName() == abilityRequest.want.GetElement().GetModuleName() &&
1196 requestInfo.want.GetElement().GetAbilityName() == abilityRequest.want.GetElement().GetAbilityName());
1197 };
1198 auto findIter = find_if(restartResidentTaskList_.begin(), restartResidentTaskList_.end(), findRestartResidentTask);
1199 if (findIter != restartResidentTaskList_.end()) {
1200 restartResidentTaskList_.erase(findIter);
1201 }
1202 StartAbilityLocked(abilityRequest);
1203 }
1204
PostTimeOutTask(const std::shared_ptr<AbilityRecord> & abilityRecord,uint32_t messageId)1205 void AbilityConnectManager::PostTimeOutTask(const std::shared_ptr<AbilityRecord> &abilityRecord, uint32_t messageId)
1206 {
1207 CHECK_POINTER(abilityRecord);
1208 CHECK_POINTER(taskHandler_);
1209 if (messageId != AbilityConnectManager::LOAD_TIMEOUT_MSG &&
1210 messageId != AbilityConnectManager::CONNECT_TIMEOUT_MSG) {
1211 HILOG_ERROR("Timeout task messageId is error.");
1212 return;
1213 }
1214
1215 int recordId;
1216 std::string taskName;
1217 int resultCode;
1218 uint32_t delayTime;
1219 if (messageId == AbilityManagerService::LOAD_TIMEOUT_MSG) {
1220 // first load ability, There is at most one connect record.
1221 recordId = abilityRecord->GetRecordId();
1222 taskName = std::string("LoadTimeout_") + std::to_string(recordId);
1223 resultCode = LOAD_ABILITY_TIMEOUT;
1224 delayTime = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * LOAD_TIMEOUT_MULTIPLE;
1225 } else {
1226 auto connectRecord = abilityRecord->GetConnectingRecord();
1227 CHECK_POINTER(connectRecord);
1228 recordId = connectRecord->GetRecordId();
1229 taskName = std::string("ConnectTimeout_") + std::to_string(recordId);
1230 resultCode = CONNECTION_TIMEOUT;
1231 delayTime = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * CONNECT_TIMEOUT_MULTIPLE;
1232 }
1233
1234 // check libc.hook_mode
1235 const int bufferLen = 128;
1236 char paramOutBuf[bufferLen] = {0};
1237 const char *hook_mode = "startup:";
1238 int ret = GetParameter("libc.hook_mode", "", paramOutBuf, bufferLen - 1);
1239 if (ret > 0 && strncmp(paramOutBuf, hook_mode, strlen(hook_mode)) == 0) {
1240 HILOG_DEBUG("Hook_mode: no timeoutTask");
1241 return;
1242 }
1243
1244 auto timeoutTask = [abilityRecord, connectManager = shared_from_this(), resultCode]() {
1245 HILOG_WARN("Connect or load ability timeout.");
1246 connectManager->HandleStartTimeoutTask(abilityRecord, resultCode);
1247 };
1248 taskHandler_->SubmitTask(timeoutTask, taskName, delayTime);
1249 }
1250
HandleStartTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord,int resultCode)1251 void AbilityConnectManager::HandleStartTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord, int resultCode)
1252 {
1253 HILOG_DEBUG("Complete connect or load ability timeout.");
1254 std::lock_guard guard(Lock_);
1255 CHECK_POINTER(abilityRecord);
1256 auto connectingList = abilityRecord->GetConnectingRecordList();
1257 for (auto &connectRecord : connectingList) {
1258 if (connectRecord == nullptr) {
1259 HILOG_WARN("ConnectRecord is nullptr.");
1260 continue;
1261 }
1262 connectRecord->CompleteDisconnect(ERR_OK, true);
1263 abilityRecord->RemoveConnectRecordFromList(connectRecord);
1264 RemoveConnectionRecordFromMap(connectRecord);
1265 }
1266
1267 if (GetExtensionFromServiceMapInner(abilityRecord->GetToken()) == nullptr) {
1268 HILOG_ERROR("Timeout ability record is not exist in service map.");
1269 return;
1270 }
1271 MoveToTerminatingMap(abilityRecord);
1272
1273 if (resultCode == LOAD_ABILITY_TIMEOUT) {
1274 HILOG_WARN("Load time out , remove target service record from services map.");
1275 RemoveServiceAbility(abilityRecord);
1276 if (abilityRecord->GetAbilityInfo().name != AbilityConfig::LAUNCHER_ABILITY_NAME) {
1277 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
1278 if (IsAbilityNeedKeepAlive(abilityRecord)) {
1279 HILOG_WARN("Load time out , try to restart.");
1280 RestartAbility(abilityRecord, userId_);
1281 }
1282 }
1283 }
1284
1285 if (abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
1286 // terminate the timeout root launcher.
1287 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
1288 if (resultCode == LOAD_ABILITY_TIMEOUT) {
1289 StartRootLauncher(abilityRecord);
1290 }
1291 }
1292 }
1293
HandleCommandTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord)1294 void AbilityConnectManager::HandleCommandTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord)
1295 {
1296 HILOG_DEBUG("HandleCommandTimeoutTask start");
1297 std::lock_guard guard(Lock_);
1298 CHECK_POINTER(abilityRecord);
1299 if (abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
1300 HILOG_DEBUG("Handle root launcher command timeout.");
1301 // terminate the timeout root launcher.
1302 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
1303 }
1304 HILOG_DEBUG("HandleCommandTimeoutTask end");
1305 }
1306
HandleCommandWindowTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord,const sptr<SessionInfo> & sessionInfo,WindowCommand winCmd)1307 void AbilityConnectManager::HandleCommandWindowTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord,
1308 const sptr<SessionInfo> &sessionInfo, WindowCommand winCmd)
1309 {
1310 HILOG_DEBUG("start");
1311 std::lock_guard guard(Lock_);
1312 CHECK_POINTER(abilityRecord);
1313 abilityRecord->SetAbilityWindowState(sessionInfo, winCmd, true);
1314 // manage queued request
1315 CompleteStartServiceReq(abilityRecord->GetURI());
1316 HILOG_DEBUG("end");
1317 }
1318
StartRootLauncher(const std::shared_ptr<AbilityRecord> & abilityRecord)1319 void AbilityConnectManager::StartRootLauncher(const std::shared_ptr<AbilityRecord> &abilityRecord)
1320 {
1321 CHECK_POINTER(abilityRecord);
1322 AbilityRequest requestInfo;
1323 requestInfo.want = abilityRecord->GetWant();
1324 requestInfo.abilityInfo = abilityRecord->GetAbilityInfo();
1325 requestInfo.appInfo = abilityRecord->GetApplicationInfo();
1326 requestInfo.restartTime = abilityRecord->GetRestartTime();
1327 requestInfo.restart = true;
1328 requestInfo.restartCount = abilityRecord->GetRestartCount() - 1;
1329
1330 HILOG_DEBUG("restart root launcher, number:%{public}d", requestInfo.restartCount);
1331 StartAbilityLocked(requestInfo);
1332 }
1333
HandleStopTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord)1334 void AbilityConnectManager::HandleStopTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord)
1335 {
1336 HILOG_DEBUG("Complete stop ability timeout start.");
1337 std::lock_guard guard(Lock_);
1338 CHECK_POINTER(abilityRecord);
1339 TerminateDone(abilityRecord);
1340 }
1341
HandleTerminateDisconnectTask(const ConnectListType & connectlist)1342 void AbilityConnectManager::HandleTerminateDisconnectTask(const ConnectListType& connectlist)
1343 {
1344 HILOG_DEBUG("Disconnect ability when terminate.");
1345 for (auto& connectRecord : connectlist) {
1346 if (!connectRecord) {
1347 continue;
1348 }
1349 auto targetService = connectRecord->GetAbilityRecord();
1350 if (targetService) {
1351 HILOG_WARN("This record complete disconnect directly. recordId:%{public}d", connectRecord->GetRecordId());
1352 connectRecord->CompleteDisconnect(ERR_OK, true);
1353 targetService->RemoveConnectRecordFromList(connectRecord);
1354 RemoveConnectionRecordFromMap(connectRecord);
1355 };
1356 }
1357 }
1358
DispatchInactive(const std::shared_ptr<AbilityRecord> & abilityRecord,int state)1359 int AbilityConnectManager::DispatchInactive(const std::shared_ptr<AbilityRecord> &abilityRecord, int state)
1360 {
1361 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
1362 CHECK_POINTER_AND_RETURN(eventHandler_, ERR_INVALID_VALUE);
1363 if (!abilityRecord->IsAbilityState(AbilityState::INACTIVATING)) {
1364 HILOG_ERROR("Ability transition life state error. expect %{public}d, actual %{public}d callback %{public}d",
1365 AbilityState::INACTIVATING,
1366 abilityRecord->GetAbilityState(),
1367 state);
1368 return ERR_INVALID_VALUE;
1369 }
1370 eventHandler_->RemoveEvent(AbilityManagerService::INACTIVE_TIMEOUT_MSG, abilityRecord->GetAbilityRecordId());
1371
1372 // complete inactive
1373 abilityRecord->SetAbilityState(AbilityState::INACTIVE);
1374 if (abilityRecord->IsCreateByConnect()) {
1375 ConnectAbility(abilityRecord);
1376 } else {
1377 CommandAbility(abilityRecord);
1378 if (abilityRecord->GetConnectRecordList().size() > 0) {
1379 // It means someone called connectAbility when service was loading
1380 ConnectAbility(abilityRecord);
1381 }
1382 }
1383
1384 return ERR_OK;
1385 }
1386
DispatchForeground(const std::shared_ptr<AbilityRecord> & abilityRecord)1387 int AbilityConnectManager::DispatchForeground(const std::shared_ptr<AbilityRecord> &abilityRecord)
1388 {
1389 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
1390 CHECK_POINTER_AND_RETURN(taskHandler_, ERR_INVALID_VALUE);
1391 // remove foreground timeout task.
1392 taskHandler_->CancelTask("foreground_" + std::to_string(abilityRecord->GetAbilityRecordId()));
1393
1394 auto self(shared_from_this());
1395 auto task = [self, abilityRecord]() { self->CompleteForeground(abilityRecord); };
1396 taskHandler_->SubmitTask(task, TaskQoS::USER_INTERACTIVE);
1397
1398 return ERR_OK;
1399 }
1400
DispatchBackground(const std::shared_ptr<AbilityRecord> & abilityRecord)1401 int AbilityConnectManager::DispatchBackground(const std::shared_ptr<AbilityRecord> &abilityRecord)
1402 {
1403 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
1404 CHECK_POINTER_AND_RETURN(taskHandler_, ERR_INVALID_VALUE);
1405 // remove background timeout task.
1406 taskHandler_->CancelTask("background_" + std::to_string(abilityRecord->GetAbilityRecordId()));
1407
1408 auto self(shared_from_this());
1409 auto task = [self, abilityRecord]() { self->CompleteBackground(abilityRecord); };
1410 taskHandler_->SubmitTask(task, TaskQoS::USER_INTERACTIVE);
1411
1412 return ERR_OK;
1413 }
1414
DispatchTerminate(const std::shared_ptr<AbilityRecord> & abilityRecord)1415 int AbilityConnectManager::DispatchTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord)
1416 {
1417 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
1418 // remove terminate timeout task
1419 if (taskHandler_ != nullptr) {
1420 taskHandler_->CancelTask("terminate_" + std::to_string(abilityRecord->GetAbilityRecordId()));
1421 }
1422 // complete terminate
1423 TerminateDone(abilityRecord);
1424 return ERR_OK;
1425 }
1426
ConnectAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)1427 void AbilityConnectManager::ConnectAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
1428 {
1429 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1430 CHECK_POINTER(abilityRecord);
1431 PostTimeOutTask(abilityRecord, AbilityConnectManager::CONNECT_TIMEOUT_MSG);
1432 abilityRecord->ConnectAbility();
1433 }
1434
CommandAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)1435 void AbilityConnectManager::CommandAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
1436 {
1437 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1438 if (taskHandler_ != nullptr) {
1439 // first connect ability, There is at most one connect record.
1440 int recordId = abilityRecord->GetRecordId();
1441 abilityRecord->AddStartId();
1442 std::string taskName = std::string("CommandTimeout_") + std::to_string(recordId) + std::string("_") +
1443 std::to_string(abilityRecord->GetStartId());
1444 auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
1445 HILOG_ERROR("Command ability timeout. %{public}s", abilityRecord->GetAbilityInfo().name.c_str());
1446 connectManager->HandleCommandTimeoutTask(abilityRecord);
1447 };
1448 int commandTimeout =
1449 AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * COMMAND_TIMEOUT_MULTIPLE;
1450 taskHandler_->SubmitTask(timeoutTask, taskName, commandTimeout);
1451 // scheduling command ability
1452 abilityRecord->CommandAbility();
1453 }
1454 }
1455
CommandAbilityWindow(const std::shared_ptr<AbilityRecord> & abilityRecord,const sptr<SessionInfo> & sessionInfo,WindowCommand winCmd)1456 void AbilityConnectManager::CommandAbilityWindow(const std::shared_ptr<AbilityRecord> &abilityRecord,
1457 const sptr<SessionInfo> &sessionInfo, WindowCommand winCmd)
1458 {
1459 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1460 CHECK_POINTER(abilityRecord);
1461 CHECK_POINTER(sessionInfo);
1462 HILOG_DEBUG("ability: %{public}s, persistentId: %{private}d, wincmd: %{public}d",
1463 abilityRecord->GetURI().c_str(), sessionInfo->persistentId, winCmd);
1464 abilityRecord->SetAbilityWindowState(sessionInfo, winCmd, false);
1465 if (taskHandler_ != nullptr) {
1466 int recordId = abilityRecord->GetRecordId();
1467 std::string taskName = std::string("CommandWindowTimeout_") + std::to_string(recordId) + std::string("_") +
1468 std::to_string(sessionInfo->persistentId) + std::string("_") + std::to_string(winCmd);
1469 auto timeoutTask = [abilityRecord, sessionInfo, winCmd, connectManager = shared_from_this()]() {
1470 HILOG_ERROR("Command window timeout. %{public}s", abilityRecord->GetAbilityInfo().name.c_str());
1471 connectManager->HandleCommandWindowTimeoutTask(abilityRecord, sessionInfo, winCmd);
1472 };
1473 int commandWindowTimeout =
1474 AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * COMMAND_WINDOW_TIMEOUT_MULTIPLE;
1475 taskHandler_->SubmitTask(timeoutTask, taskName, commandWindowTimeout);
1476 // scheduling command ability
1477 abilityRecord->CommandAbilityWindow(sessionInfo, winCmd);
1478 }
1479 }
1480
ForegroundAbilityWindowLocked(const std::shared_ptr<AbilityRecord> & abilityRecord,const sptr<SessionInfo> & sessionInfo)1481 void AbilityConnectManager::ForegroundAbilityWindowLocked(const std::shared_ptr<AbilityRecord> &abilityRecord,
1482 const sptr<SessionInfo> &sessionInfo)
1483 {
1484 std::lock_guard guard(Lock_);
1485 if (abilityRecord == nullptr) {
1486 HILOG_ERROR("abilityRecord is nullptr");
1487 return;
1488 }
1489 if (sessionInfo == nullptr) {
1490 HILOG_ERROR("sessionInfo is nullptr");
1491 return;
1492 }
1493 CommandAbilityWindow(abilityRecord, sessionInfo, WIN_CMD_FOREGROUND);
1494 }
1495
BackgroundAbilityWindowLocked(const std::shared_ptr<AbilityRecord> & abilityRecord,const sptr<SessionInfo> & sessionInfo)1496 void AbilityConnectManager::BackgroundAbilityWindowLocked(const std::shared_ptr<AbilityRecord> &abilityRecord,
1497 const sptr<SessionInfo> &sessionInfo)
1498 {
1499 std::lock_guard guard(Lock_);
1500 if (abilityRecord == nullptr) {
1501 HILOG_ERROR("abilityRecord is nullptr");
1502 return;
1503 }
1504 if (sessionInfo == nullptr) {
1505 HILOG_ERROR("sessionInfo is nullptr");
1506 return;
1507 }
1508
1509 DoBackgroundAbilityWindow(abilityRecord, sessionInfo);
1510 }
1511
DoBackgroundAbilityWindow(const std::shared_ptr<AbilityRecord> & abilityRecord,const sptr<SessionInfo> & sessionInfo)1512 void AbilityConnectManager::DoBackgroundAbilityWindow(const std::shared_ptr<AbilityRecord> &abilityRecord,
1513 const sptr<SessionInfo> &sessionInfo)
1514 {
1515 CHECK_POINTER(abilityRecord);
1516 CHECK_POINTER(sessionInfo);
1517 HILOG_INFO("Background ability: %{public}s, persistentId: %{public}d", abilityRecord->GetURI().c_str(),
1518 sessionInfo->persistentId);
1519
1520 std::vector<AppExecFwk::Metadata> metaData = abilityRecord->GetAbilityInfo().metadata;
1521 bool isSingleton = std::any_of(metaData.begin(), metaData.end(), [](const auto &metaDataItem) {
1522 return metaDataItem.name == "UIExtensionAbilityLaunchTypeTemp" && metaDataItem.value == "singleton";
1523 });
1524 HILOG_DEBUG("State isSingleton: %{public}d.", isSingleton);
1525
1526 if (abilityRecord->IsAbilityState(AbilityState::FOREGROUND) || isSingleton) {
1527 MoveToBackground(abilityRecord);
1528 } else if (abilityRecord->IsAbilityState(AbilityState::INITIAL) ||
1529 abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING)) {
1530 HILOG_INFO("There exist initial or foregrounding task.");
1531 abilityRecord->DoBackgroundAbilityWindowDelayed(true);
1532 } else {
1533 HILOG_WARN("Invalid ability state when background.");
1534 }
1535 }
1536
TerminateAbilityWindowLocked(const std::shared_ptr<AbilityRecord> & abilityRecord,const sptr<SessionInfo> & sessionInfo)1537 void AbilityConnectManager::TerminateAbilityWindowLocked(const std::shared_ptr<AbilityRecord> &abilityRecord,
1538 const sptr<SessionInfo> &sessionInfo)
1539 {
1540 std::lock_guard guard(Lock_);
1541 if (abilityRecord == nullptr) {
1542 HILOG_ERROR("abilityRecord is nullptr");
1543 return;
1544 }
1545 if (sessionInfo == nullptr) {
1546 HILOG_ERROR("sessionInfo is nullptr");
1547 return;
1548 }
1549 DoTerminateUIExtensionAbility(abilityRecord, sessionInfo);
1550 }
1551
DoTerminateUIExtensionAbility(std::shared_ptr<AbilityRecord> abilityRecord,sptr<SessionInfo> sessionInfo)1552 void AbilityConnectManager::DoTerminateUIExtensionAbility(std::shared_ptr<AbilityRecord> abilityRecord,
1553 sptr<SessionInfo> sessionInfo)
1554 {
1555 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1556 CHECK_POINTER(abilityRecord);
1557 CHECK_POINTER(sessionInfo);
1558 HILOG_INFO("Terminate ability: %{public}s, persistentId: %{public}d", abilityRecord->GetURI().c_str(),
1559 sessionInfo->persistentId);
1560
1561 EventInfo eventInfo;
1562 eventInfo.bundleName = abilityRecord->GetAbilityInfo().bundleName;
1563 eventInfo.abilityName = abilityRecord->GetAbilityInfo().name;
1564 EventReport::SendAbilityEvent(EventName::TERMINATE_ABILITY, HiSysEventType::BEHAVIOR, eventInfo);
1565 eventInfo.errCode = TerminateAbilityInner(abilityRecord->GetToken());
1566 if (eventInfo.errCode != ERR_OK) {
1567 EventReport::SendAbilityEvent(EventName::TERMINATE_ABILITY_ERROR, HiSysEventType::FAULT, eventInfo);
1568 }
1569 }
1570
TerminateDone(const std::shared_ptr<AbilityRecord> & abilityRecord)1571 void AbilityConnectManager::TerminateDone(const std::shared_ptr<AbilityRecord> &abilityRecord)
1572 {
1573 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1574 CHECK_POINTER(abilityRecord);
1575 if (!abilityRecord->IsAbilityState(AbilityState::TERMINATING)) {
1576 std::string expect = AbilityRecord::ConvertAbilityState(AbilityState::TERMINATING);
1577 std::string actual = AbilityRecord::ConvertAbilityState(abilityRecord->GetAbilityState());
1578 HILOG_ERROR(
1579 "Transition life state error. expect %{public}s, actual %{public}s", expect.c_str(), actual.c_str());
1580 return;
1581 }
1582 IN_PROCESS_CALL_WITHOUT_RET(abilityRecord->RevokeUriPermission());
1583 abilityRecord->RemoveAbilityDeathRecipient();
1584 if (IsSceneBoard(abilityRecord)) {
1585 HILOG_INFO("To kill processes because scb exit.");
1586 KillProcessesByUserId();
1587 }
1588 DelayedSingleton<AppScheduler>::GetInstance()->TerminateAbility(abilityRecord->GetToken(), false);
1589 RemoveServiceAbility(abilityRecord);
1590 }
1591
IsAbilityConnected(const std::shared_ptr<AbilityRecord> & abilityRecord,const std::list<std::shared_ptr<ConnectionRecord>> & connectRecordList)1592 bool AbilityConnectManager::IsAbilityConnected(const std::shared_ptr<AbilityRecord> &abilityRecord,
1593 const std::list<std::shared_ptr<ConnectionRecord>> &connectRecordList)
1594 {
1595 auto isMatch = [abilityRecord](auto connectRecord) -> bool {
1596 if (abilityRecord == nullptr || connectRecord == nullptr) {
1597 return false;
1598 }
1599 if (abilityRecord != connectRecord->GetAbilityRecord()) {
1600 return false;
1601 }
1602 return true;
1603 };
1604 return std::any_of(connectRecordList.begin(), connectRecordList.end(), isMatch);
1605 }
1606
RemoveConnectionRecordFromMap(std::shared_ptr<ConnectionRecord> connection)1607 void AbilityConnectManager::RemoveConnectionRecordFromMap(std::shared_ptr<ConnectionRecord> connection)
1608 {
1609 for (auto &connectCallback : connectMap_) {
1610 auto &connectList = connectCallback.second;
1611 auto connectRecord = std::find(connectList.begin(), connectList.end(), connection);
1612 if (connectRecord != connectList.end()) {
1613 HILOG_DEBUG("connrecord(%{public}d)", (*connectRecord)->GetRecordId());
1614 connectList.remove(connection);
1615 if (connectList.empty()) {
1616 HILOG_DEBUG("connlist");
1617 sptr<IAbilityConnection> connect = iface_cast<IAbilityConnection>(connectCallback.first);
1618 RemoveConnectDeathRecipient(connect);
1619 connectMap_.erase(connectCallback.first);
1620 }
1621 return;
1622 }
1623 }
1624 }
1625
RemoveServiceAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)1626 void AbilityConnectManager::RemoveServiceAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
1627 {
1628 CHECK_POINTER(abilityRecord);
1629 HILOG_DEBUG("Remove service(%{public}s) from terminating map.", abilityRecord->GetURI().c_str());
1630 terminatingExtensionMap_.erase(abilityRecord->GetURI());
1631 }
1632
AddConnectDeathRecipient(const sptr<IAbilityConnection> & connect)1633 void AbilityConnectManager::AddConnectDeathRecipient(const sptr<IAbilityConnection> &connect)
1634 {
1635 CHECK_POINTER(connect);
1636 auto connectObject = connect->AsObject();
1637 CHECK_POINTER(connectObject);
1638 {
1639 std::lock_guard guard(recipientMapMutex_);
1640 auto it = recipientMap_.find(connectObject);
1641 if (it != recipientMap_.end()) {
1642 HILOG_ERROR("This death recipient has been added.");
1643 return;
1644 }
1645 }
1646
1647 std::weak_ptr<AbilityConnectManager> thisWeakPtr(shared_from_this());
1648 sptr<IRemoteObject::DeathRecipient> deathRecipient =
1649 new AbilityConnectCallbackRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
1650 auto abilityConnectManager = thisWeakPtr.lock();
1651 if (abilityConnectManager) {
1652 abilityConnectManager->OnCallBackDied(remote);
1653 }
1654 });
1655 if (!connectObject->AddDeathRecipient(deathRecipient)) {
1656 HILOG_ERROR("AddDeathRecipient failed.");
1657 return;
1658 }
1659 std::lock_guard guard(recipientMapMutex_);
1660 recipientMap_.emplace(connectObject, deathRecipient);
1661 }
1662
RemoveConnectDeathRecipient(const sptr<IAbilityConnection> & connect)1663 void AbilityConnectManager::RemoveConnectDeathRecipient(const sptr<IAbilityConnection> &connect)
1664 {
1665 CHECK_POINTER(connect);
1666 auto connectObject = connect->AsObject();
1667 CHECK_POINTER(connectObject);
1668 sptr<IRemoteObject::DeathRecipient> deathRecipient;
1669 {
1670 std::lock_guard guard(recipientMapMutex_);
1671 auto it = recipientMap_.find(connectObject);
1672 if (it == recipientMap_.end()) {
1673 return;
1674 }
1675 deathRecipient = it->second;
1676 recipientMap_.erase(it);
1677 }
1678
1679 connectObject->RemoveDeathRecipient(deathRecipient);
1680 }
1681
OnCallBackDied(const wptr<IRemoteObject> & remote)1682 void AbilityConnectManager::OnCallBackDied(const wptr<IRemoteObject> &remote)
1683 {
1684 auto object = remote.promote();
1685 CHECK_POINTER(object);
1686 if (taskHandler_) {
1687 auto task = [object, connectManager = shared_from_this()]() { connectManager->HandleCallBackDiedTask(object); };
1688 taskHandler_->SubmitTask(task, TASK_ON_CALLBACK_DIED);
1689 }
1690 }
1691
HandleCallBackDiedTask(const sptr<IRemoteObject> & connect)1692 void AbilityConnectManager::HandleCallBackDiedTask(const sptr<IRemoteObject> &connect)
1693 {
1694 HILOG_DEBUG("called");
1695 std::lock_guard guard(Lock_);
1696 CHECK_POINTER(connect);
1697 auto item = windowExtensionMap_.find(connect);
1698 if (item != windowExtensionMap_.end()) {
1699 windowExtensionMap_.erase(item);
1700 }
1701 auto it = connectMap_.find(connect);
1702 if (it != connectMap_.end()) {
1703 ConnectListType connectRecordList = it->second;
1704 for (auto &connRecord : connectRecordList) {
1705 connRecord->ClearConnCallBack();
1706 }
1707 } else {
1708 HILOG_INFO("Died object can't find from conn map.");
1709 return;
1710 }
1711 sptr<IAbilityConnection> object = iface_cast<IAbilityConnection>(connect);
1712 DisconnectAbilityLocked(object, true);
1713 }
1714
OnAbilityDied(const std::shared_ptr<AbilityRecord> & abilityRecord,int32_t currentUserId)1715 void AbilityConnectManager::OnAbilityDied(const std::shared_ptr<AbilityRecord> &abilityRecord, int32_t currentUserId)
1716 {
1717 CHECK_POINTER(abilityRecord);
1718 HILOG_DEBUG("On ability died: %{public}s.", abilityRecord->GetURI().c_str());
1719 if (abilityRecord->GetAbilityInfo().type != AbilityType::SERVICE &&
1720 abilityRecord->GetAbilityInfo().type != AbilityType::EXTENSION) {
1721 HILOG_DEBUG("Ability type is not service.");
1722 return;
1723 }
1724 if (taskHandler_) {
1725 auto task = [abilityRecord, connectManager = shared_from_this(), currentUserId]() {
1726 connectManager->HandleAbilityDiedTask(abilityRecord, currentUserId);
1727 };
1728 taskHandler_->SubmitTask(task, TASK_ON_ABILITY_DIED);
1729 }
1730 }
1731
OnTimeOut(uint32_t msgId,int64_t abilityRecordId)1732 void AbilityConnectManager::OnTimeOut(uint32_t msgId, int64_t abilityRecordId)
1733 {
1734 HILOG_DEBUG("On timeout, msgId is %{public}d", msgId);
1735 std::lock_guard guard(Lock_);
1736 auto abilityRecord = GetAbilityRecordById(abilityRecordId);
1737 if (abilityRecord == nullptr) {
1738 HILOG_ERROR("AbilityConnectManager on time out event: ability record is nullptr.");
1739 return;
1740 }
1741 HILOG_DEBUG("Ability timeout ,msg:%{public}d,name:%{public}s", msgId,
1742 abilityRecord->GetAbilityInfo().name.c_str());
1743
1744 switch (msgId) {
1745 case AbilityManagerService::INACTIVE_TIMEOUT_MSG:
1746 HandleInactiveTimeout(abilityRecord);
1747 break;
1748 default:
1749 break;
1750 }
1751 }
1752
HandleInactiveTimeout(const std::shared_ptr<AbilityRecord> & ability)1753 void AbilityConnectManager::HandleInactiveTimeout(const std::shared_ptr<AbilityRecord> &ability)
1754 {
1755 HILOG_DEBUG("HandleInactiveTimeout start");
1756 CHECK_POINTER(ability);
1757 if (ability->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
1758 HILOG_DEBUG("Handle root launcher inactive timeout.");
1759 // terminate the timeout root launcher.
1760 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(ability->GetToken());
1761 }
1762
1763 HILOG_DEBUG("HandleInactiveTimeout end");
1764 }
1765
IsAbilityNeedKeepAlive(const std::shared_ptr<AbilityRecord> & abilityRecord)1766 bool AbilityConnectManager::IsAbilityNeedKeepAlive(const std::shared_ptr<AbilityRecord> &abilityRecord)
1767 {
1768 if (IsSpecialAbility(abilityRecord->GetAbilityInfo())) {
1769 return true;
1770 }
1771 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
1772 CHECK_POINTER_AND_RETURN(bundleMgrHelper, false);
1773 std::vector<AppExecFwk::BundleInfo> bundleInfos;
1774 bool getBundleInfos = bundleMgrHelper->GetBundleInfos(
1775 OHOS::AppExecFwk::GET_BUNDLE_DEFAULT, bundleInfos, USER_ID_NO_HEAD);
1776 if (!getBundleInfos) {
1777 HILOG_ERROR("Handle ability died task, get bundle infos failed.");
1778 return false;
1779 }
1780
1781 auto CheckIsAbilityNeedKeepAlive = [](const AppExecFwk::HapModuleInfo &hapModuleInfo,
1782 const std::string processName, std::string &mainElement) {
1783 if (!hapModuleInfo.isModuleJson) {
1784 // old application model
1785 mainElement = hapModuleInfo.mainAbility;
1786 for (auto abilityInfo : hapModuleInfo.abilityInfos) {
1787 if (abilityInfo.process == processName && abilityInfo.name == mainElement) {
1788 return true;
1789 }
1790 }
1791 return false;
1792 }
1793
1794 // new application model
1795 if (hapModuleInfo.process == processName) {
1796 mainElement = hapModuleInfo.mainElementName;
1797 return true;
1798 }
1799 return false;
1800 };
1801
1802 auto GetKeepAliveAbilities = [&](std::vector<std::pair<std::string, std::string>> &keepAliveAbilities) {
1803 for (size_t i = 0; i < bundleInfos.size(); i++) {
1804 std::string processName = bundleInfos[i].applicationInfo.process;
1805 if (!bundleInfos[i].isKeepAlive || processName.empty()) {
1806 continue;
1807 }
1808 std::string bundleName = bundleInfos[i].name;
1809 for (auto hapModuleInfo : bundleInfos[i].hapModuleInfos) {
1810 std::string mainElement;
1811 if (CheckIsAbilityNeedKeepAlive(hapModuleInfo, processName, mainElement) && !mainElement.empty()) {
1812 keepAliveAbilities.push_back(std::make_pair(bundleName, mainElement));
1813 }
1814 }
1815 }
1816 };
1817
1818 auto findKeepAliveAbility = [abilityRecord](const std::pair<std::string, std::string> &keepAlivePair) {
1819 return ((abilityRecord->GetAbilityInfo().bundleName == keepAlivePair.first &&
1820 abilityRecord->GetAbilityInfo().name == keepAlivePair.second));
1821 };
1822
1823 std::vector<std::pair<std::string, std::string>> keepAliveAbilities;
1824 GetKeepAliveAbilities(keepAliveAbilities);
1825 auto findIter = find_if(keepAliveAbilities.begin(), keepAliveAbilities.end(), findKeepAliveAbility);
1826 if (findIter != keepAliveAbilities.end()) {
1827 abilityRecord->SetKeepAlive();
1828 return true;
1829 }
1830 return false;
1831 }
1832
HandleAbilityDiedTask(const std::shared_ptr<AbilityRecord> & abilityRecord,int32_t currentUserId)1833 void AbilityConnectManager::HandleAbilityDiedTask(
1834 const std::shared_ptr<AbilityRecord> &abilityRecord, int32_t currentUserId)
1835 {
1836 HILOG_DEBUG("called.");
1837 std::lock_guard guard(Lock_);
1838 CHECK_POINTER(abilityRecord);
1839 HILOG_INFO("Ability died: %{public}s", abilityRecord->GetURI().c_str());
1840 abilityRecord->SetConnRemoteObject(nullptr);
1841 ConnectListType connlist = abilityRecord->GetConnectRecordList();
1842 for (auto &connectRecord : connlist) {
1843 HILOG_WARN("This record complete disconnect directly. recordId:%{public}d", connectRecord->GetRecordId());
1844 RemoveExtensionDelayDisconnectTask(connectRecord);
1845 connectRecord->CompleteDisconnect(ERR_OK, true);
1846 abilityRecord->RemoveConnectRecordFromList(connectRecord);
1847 RemoveConnectionRecordFromMap(connectRecord);
1848 }
1849
1850 if (abilityRecord->IsTerminating()) {
1851 HILOG_INFO("Handle extension DiedByTerminating.");
1852 RemoveServiceAbility(abilityRecord);
1853 if (IsAbilityNeedKeepAlive(abilityRecord)) {
1854 HILOG_INFO("restart ability: %{public}s", abilityRecord->GetAbilityInfo().name.c_str());
1855 RestartAbility(abilityRecord, currentUserId);
1856 }
1857 return;
1858 }
1859
1860 if (IsUIExtensionAbility(abilityRecord)) {
1861 HandleUIExtensionDied(abilityRecord);
1862 }
1863
1864 auto token = abilityRecord->GetToken();
1865 if (GetExtensionFromServiceMapInner(abilityRecord->GetAbilityRecordId()) != nullptr) {
1866 MoveToTerminatingMap(abilityRecord);
1867 RemoveServiceAbility(abilityRecord);
1868 }
1869
1870 if (IsAbilityNeedKeepAlive(abilityRecord)) {
1871 HILOG_INFO("restart ability: %{public}s", abilityRecord->GetAbilityInfo().name.c_str());
1872 if ((IsLauncher(abilityRecord) || IsSceneBoard(abilityRecord)) && token != nullptr) {
1873 IN_PROCESS_CALL_WITHOUT_RET(DelayedSingleton<AppScheduler>::GetInstance()->ClearProcessByToken(
1874 token->AsObject()));
1875 }
1876 RestartAbility(abilityRecord, currentUserId);
1877 }
1878 }
1879
HandleUIExtensionDied(const std::shared_ptr<AbilityRecord> & abilityRecord)1880 void AbilityConnectManager::HandleUIExtensionDied(const std::shared_ptr<AbilityRecord> &abilityRecord)
1881 {
1882 HILOG_DEBUG("called");
1883 CHECK_POINTER(abilityRecord);
1884 for (auto it = uiExtensionMap_.begin(); it != uiExtensionMap_.end();) {
1885 std::shared_ptr<AbilityRecord> uiExtAbility = it->second.first.lock();
1886 if (uiExtAbility == nullptr) {
1887 HILOG_WARN("uiExtAbility is nullptr");
1888 RemoveUIExtWindowDeathRecipient(it->first);
1889 it = uiExtensionMap_.erase(it);
1890 continue;
1891 }
1892
1893 if (abilityRecord == uiExtAbility) {
1894 sptr<Rosen::ISession> sessionProxy = iface_cast<Rosen::ISession>(it->first);
1895 if (sessionProxy) {
1896 HILOG_DEBUG("start NotifyExtensionDied");
1897 sessionProxy->NotifyExtensionDied();
1898 }
1899 RemoveUIExtWindowDeathRecipient(it->first);
1900 it = uiExtensionMap_.erase(it);
1901 continue;
1902 }
1903 it++;
1904 }
1905 }
1906
RestartAbility(const std::shared_ptr<AbilityRecord> & abilityRecord,int32_t currentUserId)1907 void AbilityConnectManager::RestartAbility(const std::shared_ptr<AbilityRecord> &abilityRecord, int32_t currentUserId)
1908 {
1909 HILOG_INFO("Restart ability: %{public}s.", abilityRecord->GetURI().c_str());
1910 AbilityRequest requestInfo;
1911 requestInfo.want = abilityRecord->GetWant();
1912 requestInfo.abilityInfo = abilityRecord->GetAbilityInfo();
1913 requestInfo.appInfo = abilityRecord->GetApplicationInfo();
1914 requestInfo.restartTime = abilityRecord->GetRestartTime();
1915 requestInfo.restart = true;
1916 abilityRecord->SetRestarting(true);
1917
1918 if (AppUtils::GetInstance().IsLauncherAbility(abilityRecord->GetAbilityInfo().name)) {
1919 if (currentUserId != userId_) {
1920 HILOG_WARN("delay restart root launcher until switch user.");
1921 return;
1922 }
1923 requestInfo.want.SetParam("ohos.app.recovery", true);
1924 requestInfo.restartCount = abilityRecord->GetRestartCount();
1925 HILOG_DEBUG("restart root launcher, number:%{public}d", requestInfo.restartCount);
1926 StartAbilityLocked(requestInfo);
1927 return;
1928 }
1929
1930 // restart other resident ability
1931 if (abilityRecord->CanRestartResident()) {
1932 requestInfo.restartCount = abilityRecord->GetRestartCount();
1933 requestInfo.restartTime = AbilityUtil::SystemTimeMillis();
1934 StartAbilityLocked(requestInfo);
1935 } else {
1936 auto findRestartResidentTask = [requestInfo](const AbilityRequest &abilityRequest) {
1937 return (requestInfo.want.GetElement().GetBundleName() == abilityRequest.want.GetElement().GetBundleName() &&
1938 requestInfo.want.GetElement().GetModuleName() == abilityRequest.want.GetElement().GetModuleName() &&
1939 requestInfo.want.GetElement().GetAbilityName() == abilityRequest.want.GetElement().GetAbilityName());
1940 };
1941 auto findIter = find_if(restartResidentTaskList_.begin(), restartResidentTaskList_.end(),
1942 findRestartResidentTask);
1943 if (findIter != restartResidentTaskList_.end()) {
1944 HILOG_WARN("The restart task has been registered.");
1945 return;
1946 }
1947 restartResidentTaskList_.emplace_back(requestInfo);
1948 PostRestartResidentTask(requestInfo);
1949 }
1950 }
1951
DumpState(std::vector<std::string> & info,bool isClient,const std::string & args)1952 void AbilityConnectManager::DumpState(std::vector<std::string> &info, bool isClient, const std::string &args)
1953 {
1954 HILOG_INFO("args:%{public}s.", args.c_str());
1955 ServiceMapType serviceMapBack;
1956 {
1957 std::lock_guard guard(Lock_);
1958 serviceMapBack = serviceMap_;
1959 }
1960 if (!args.empty()) {
1961 auto it = std::find_if(serviceMapBack.begin(), serviceMapBack.end(), [&args](const auto &service) {
1962 return service.first.compare(args) == 0;
1963 });
1964 if (it != serviceMapBack.end()) {
1965 info.emplace_back("uri [ " + it->first + " ]");
1966 if (it->second != nullptr) {
1967 it->second->DumpService(info, isClient);
1968 }
1969 } else {
1970 info.emplace_back(args + ": Nothing to dump.");
1971 }
1972 } else {
1973 info.emplace_back(" ExtensionRecords:");
1974 for (auto &&service : serviceMapBack) {
1975 info.emplace_back(" uri [" + service.first + "]");
1976 if (service.second != nullptr) {
1977 service.second->DumpService(info, isClient);
1978 }
1979 }
1980 }
1981 }
1982
DumpStateByUri(std::vector<std::string> & info,bool isClient,const std::string & args,std::vector<std::string> & params)1983 void AbilityConnectManager::DumpStateByUri(std::vector<std::string> &info, bool isClient, const std::string &args,
1984 std::vector<std::string> ¶ms)
1985 {
1986 HILOG_INFO("args:%{public}s, params size: %{public}zu", args.c_str(), params.size());
1987 std::shared_ptr<AbilityRecord> extensionAbilityRecord = nullptr;
1988 {
1989 std::lock_guard guard(Lock_);
1990 auto it = std::find_if(serviceMap_.begin(), serviceMap_.end(), [&args](const auto &service) {
1991 return service.first.compare(args) == 0;
1992 });
1993 if (it != serviceMap_.end()) {
1994 info.emplace_back("uri [ " + it->first + " ]");
1995 extensionAbilityRecord = it->second;
1996 } else {
1997 info.emplace_back(args + ": Nothing to dump.");
1998 }
1999 }
2000 if (extensionAbilityRecord != nullptr) {
2001 extensionAbilityRecord->DumpService(info, params, isClient);
2002 }
2003 }
2004
GetExtensionRunningInfos(int upperLimit,std::vector<ExtensionRunningInfo> & info,const int32_t userId,bool isPerm)2005 void AbilityConnectManager::GetExtensionRunningInfos(int upperLimit, std::vector<ExtensionRunningInfo> &info,
2006 const int32_t userId, bool isPerm)
2007 {
2008 HILOG_DEBUG("Get extension running info.");
2009 std::lock_guard guard(Lock_);
2010 auto mgr = shared_from_this();
2011 auto queryInfo = [&info, upperLimit, userId, isPerm, mgr](ServiceMapType::reference service) {
2012 if (static_cast<int>(info.size()) >= upperLimit) {
2013 return;
2014 }
2015 auto abilityRecord = service.second;
2016 CHECK_POINTER(abilityRecord);
2017
2018 if (isPerm) {
2019 mgr->GetExtensionRunningInfo(abilityRecord, userId, info);
2020 } else {
2021 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
2022 auto tokenID = abilityRecord->GetApplicationInfo().accessTokenId;
2023 if (callingTokenId == tokenID) {
2024 mgr->GetExtensionRunningInfo(abilityRecord, userId, info);
2025 }
2026 }
2027 };
2028 std::for_each(serviceMap_.begin(), serviceMap_.end(), queryInfo);
2029 }
2030
GetAbilityRunningInfos(std::vector<AbilityRunningInfo> & info,bool isPerm)2031 void AbilityConnectManager::GetAbilityRunningInfos(std::vector<AbilityRunningInfo> &info, bool isPerm)
2032 {
2033 HILOG_DEBUG("call");
2034 std::lock_guard guard(Lock_);
2035
2036 auto queryInfo = [&info, isPerm](ServiceMapType::reference service) {
2037 auto abilityRecord = service.second;
2038 CHECK_POINTER(abilityRecord);
2039
2040 if (isPerm) {
2041 DelayedSingleton<AbilityManagerService>::GetInstance()->GetAbilityRunningInfo(info, abilityRecord);
2042 } else {
2043 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
2044 auto tokenID = abilityRecord->GetApplicationInfo().accessTokenId;
2045 if (callingTokenId == tokenID) {
2046 DelayedSingleton<AbilityManagerService>::GetInstance()->GetAbilityRunningInfo(info, abilityRecord);
2047 }
2048 }
2049 };
2050
2051 std::for_each(serviceMap_.begin(), serviceMap_.end(), queryInfo);
2052 }
2053
GetExtensionRunningInfo(std::shared_ptr<AbilityRecord> & abilityRecord,const int32_t userId,std::vector<ExtensionRunningInfo> & info)2054 void AbilityConnectManager::GetExtensionRunningInfo(std::shared_ptr<AbilityRecord> &abilityRecord,
2055 const int32_t userId, std::vector<ExtensionRunningInfo> &info)
2056 {
2057 ExtensionRunningInfo extensionInfo;
2058 AppExecFwk::RunningProcessInfo processInfo;
2059 extensionInfo.extension = abilityRecord->GetElementName();
2060 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
2061 CHECK_POINTER(bundleMgrHelper);
2062
2063 std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
2064 bool queryResult = IN_PROCESS_CALL(bundleMgrHelper->QueryExtensionAbilityInfos(abilityRecord->GetWant(),
2065 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, extensionInfos));
2066 if (queryResult) {
2067 HILOG_DEBUG("Success");
2068 auto abilityInfo = abilityRecord->GetAbilityInfo();
2069 auto isExist = [&abilityInfo](const AppExecFwk::ExtensionAbilityInfo &extensionInfo) {
2070 HILOG_DEBUG("%{public}s, %{public}s", extensionInfo.bundleName.c_str(), extensionInfo.name.c_str());
2071 return extensionInfo.bundleName == abilityInfo.bundleName && extensionInfo.name == abilityInfo.name
2072 && extensionInfo.applicationInfo.uid == abilityInfo.applicationInfo.uid;
2073 };
2074 auto infoIter = std::find_if(extensionInfos.begin(), extensionInfos.end(), isExist);
2075 if (infoIter != extensionInfos.end()) {
2076 HILOG_DEBUG("Get target success.");
2077 extensionInfo.type = (*infoIter).type;
2078 }
2079 }
2080 DelayedSingleton<AppScheduler>::GetInstance()->
2081 GetRunningProcessInfoByToken(abilityRecord->GetToken(), processInfo);
2082 extensionInfo.pid = processInfo.pid_;
2083 extensionInfo.uid = processInfo.uid_;
2084 extensionInfo.processName = processInfo.processName_;
2085 extensionInfo.startTime = abilityRecord->GetStartTime();
2086 ConnectListType connectRecordList = abilityRecord->GetConnectRecordList();
2087 for (auto &connectRecord : connectRecordList) {
2088 if (connectRecord == nullptr) {
2089 HILOG_DEBUG("connectRecord is nullptr.");
2090 continue;
2091 }
2092 auto callerAbilityRecord = Token::GetAbilityRecordByToken(connectRecord->GetToken());
2093 if (callerAbilityRecord == nullptr) {
2094 HILOG_DEBUG("callerAbilityRecord is nullptr.");
2095 continue;
2096 }
2097 std::string package = callerAbilityRecord->GetAbilityInfo().bundleName;
2098 extensionInfo.clientPackage.emplace_back(package);
2099 }
2100 info.emplace_back(extensionInfo);
2101 }
2102
PauseExtensions()2103 void AbilityConnectManager::PauseExtensions()
2104 {
2105 HILOG_DEBUG("begin.");
2106 std::lock_guard guard(Lock_);
2107 for (auto it = serviceMap_.begin(); it != serviceMap_.end();) {
2108 auto targetExtension = it->second;
2109 if (targetExtension != nullptr && targetExtension->GetAbilityInfo().type == AbilityType::EXTENSION &&
2110 (IsLauncher(targetExtension) || IsSceneBoard(targetExtension))) {
2111 terminatingExtensionMap_.emplace(it->first, it->second);
2112 serviceMap_.erase(it++);
2113 HILOG_INFO("terminate ability:%{public}s.", targetExtension->GetAbilityInfo().name.c_str());
2114 TerminateAbilityLocked(targetExtension->GetToken());
2115 } else {
2116 it++;
2117 }
2118 }
2119 }
2120
RemoveLauncherDeathRecipient()2121 void AbilityConnectManager::RemoveLauncherDeathRecipient()
2122 {
2123 HILOG_INFO("Call.");
2124 std::lock_guard guard(Lock_);
2125 for (auto it = serviceMap_.begin(); it != serviceMap_.end();) {
2126 auto targetExtension = it->second;
2127 if (targetExtension != nullptr && targetExtension->GetAbilityInfo().type == AbilityType::EXTENSION &&
2128 (IsLauncher(targetExtension) || IsSceneBoard(targetExtension))) {
2129 targetExtension->RemoveAbilityDeathRecipient();
2130 break;
2131 } else {
2132 it++;
2133 }
2134 }
2135 }
2136
IsLauncher(std::shared_ptr<AbilityRecord> serviceExtension) const2137 bool AbilityConnectManager::IsLauncher(std::shared_ptr<AbilityRecord> serviceExtension) const
2138 {
2139 if (serviceExtension == nullptr) {
2140 HILOG_ERROR("param is nullptr");
2141 return false;
2142 }
2143 return serviceExtension->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME &&
2144 serviceExtension->GetAbilityInfo().bundleName == AbilityConfig::LAUNCHER_BUNDLE_NAME;
2145 }
2146
IsSceneBoard(std::shared_ptr<AbilityRecord> serviceExtension) const2147 bool AbilityConnectManager::IsSceneBoard(std::shared_ptr<AbilityRecord> serviceExtension) const
2148 {
2149 if (serviceExtension == nullptr) {
2150 HILOG_ERROR("param is nullptr");
2151 return false;
2152 }
2153 return serviceExtension->GetAbilityInfo().name == AbilityConfig::SCENEBOARD_ABILITY_NAME &&
2154 serviceExtension->GetAbilityInfo().bundleName == AbilityConfig::SCENEBOARD_BUNDLE_NAME;
2155 }
2156
KillProcessesByUserId() const2157 void AbilityConnectManager::KillProcessesByUserId() const
2158 {
2159 auto appScheduler = DelayedSingleton<AppScheduler>::GetInstance();
2160 if (appScheduler == nullptr) {
2161 HILOG_ERROR("appScheduler is nullptr");
2162 return;
2163 }
2164 IN_PROCESS_CALL_WITHOUT_RET(appScheduler->KillProcessesByUserId(userId_));
2165 }
2166
MoveToForeground(const std::shared_ptr<AbilityRecord> & abilityRecord)2167 void AbilityConnectManager::MoveToForeground(const std::shared_ptr<AbilityRecord> &abilityRecord)
2168 {
2169 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
2170 if (abilityRecord == nullptr) {
2171 HILOG_ERROR("ability record is null.");
2172 return;
2173 }
2174
2175 auto self(weak_from_this());
2176 auto task = [abilityRecord, self]() {
2177 auto selfObj = self.lock();
2178 if (selfObj == nullptr) {
2179 HILOG_WARN("mgr is invalid.");
2180 return;
2181 }
2182 HILOG_ERROR("move to foreground timeout.");
2183 selfObj->PrintTimeOutLog(abilityRecord, AbilityManagerService::FOREGROUND_TIMEOUT_MSG);
2184 selfObj->HandleForegroundTimeoutTask(abilityRecord);
2185 };
2186 auto sessionInfo = abilityRecord->GetUIExtRequestSessionInfo();
2187 if (sessionInfo != nullptr) {
2188 abilityRecord->ForegroundAbility(task, sessionInfo);
2189 abilityRecord->SetUIExtRequestSessionInfo(nullptr);
2190 } else {
2191 HILOG_WARN("SessionInfo is nullptr. Move to background");
2192 abilityRecord->SetAbilityState(AbilityState::BACKGROUND);
2193 DelayedSingleton<AppScheduler>::GetInstance()->MoveToBackground(abilityRecord->GetToken());
2194 }
2195 if (taskHandler_) {
2196 taskHandler_->CancelTask(std::string("ConsumeSessionTimeout_") + std::to_string(abilityRecord->GetRecordId()));
2197 }
2198 }
2199
MoveToBackground(const std::shared_ptr<AbilityRecord> & abilityRecord)2200 void AbilityConnectManager::MoveToBackground(const std::shared_ptr<AbilityRecord> &abilityRecord)
2201 {
2202 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
2203 if (abilityRecord == nullptr) {
2204 HILOG_ERROR("Move the ui extension ability to background fail, ability record is null.");
2205 return;
2206 }
2207 HILOG_DEBUG("Move the ui extension ability to background, ability:%{public}s.",
2208 abilityRecord->GetAbilityInfo().name.c_str());
2209 abilityRecord->SetIsNewWant(false);
2210
2211 auto self(weak_from_this());
2212 auto task = [abilityRecord, self]() {
2213 auto selfObj = self.lock();
2214 if (selfObj == nullptr) {
2215 HILOG_WARN("mgr is invalid.");
2216 return;
2217 }
2218 HILOG_ERROR("move to background timeout.");
2219 selfObj->PrintTimeOutLog(abilityRecord, AbilityManagerService::BACKGROUND_TIMEOUT_MSG);
2220 selfObj->CompleteBackground(abilityRecord);
2221 };
2222 abilityRecord->BackgroundAbility(task);
2223 }
2224
CompleteForeground(const std::shared_ptr<AbilityRecord> & abilityRecord)2225 void AbilityConnectManager::CompleteForeground(const std::shared_ptr<AbilityRecord> &abilityRecord)
2226 {
2227 std::lock_guard guard(Lock_);
2228 if (abilityRecord == nullptr) {
2229 HILOG_ERROR("abilityRecord is nullptr");
2230 return;
2231 }
2232 if (abilityRecord->GetAbilityState() != AbilityState::FOREGROUNDING) {
2233 HILOG_ERROR("Ability state is %{public}d, it can't complete foreground.", abilityRecord->GetAbilityState());
2234 return;
2235 }
2236
2237 abilityRecord->SetAbilityState(AbilityState::FOREGROUND);
2238 if (abilityRecord->BackgroundAbilityWindowDelayed()) {
2239 HILOG_INFO("Response background request.");
2240 abilityRecord->DoBackgroundAbilityWindowDelayed(false);
2241 DoBackgroundAbilityWindow(abilityRecord, abilityRecord->GetSessionInfo());
2242 }
2243 CompleteStartServiceReq(abilityRecord->GetURI());
2244 }
2245
HandleForegroundTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord)2246 void AbilityConnectManager::HandleForegroundTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord)
2247 {
2248 std::lock_guard guard(Lock_);
2249 if (abilityRecord == nullptr) {
2250 HILOG_ERROR("abilityRecord is nullptr");
2251 return;
2252 }
2253 abilityRecord->SetAbilityState(AbilityState::BACKGROUND);
2254 abilityRecord->DoBackgroundAbilityWindowDelayed(false);
2255 CompleteStartServiceReq(abilityRecord->GetURI());
2256 }
2257
CompleteBackground(const std::shared_ptr<AbilityRecord> & abilityRecord)2258 void AbilityConnectManager::CompleteBackground(const std::shared_ptr<AbilityRecord> &abilityRecord)
2259 {
2260 std::lock_guard guard(Lock_);
2261 if (abilityRecord == nullptr) {
2262 HILOG_ERROR("abilityRecord is nullptr");
2263 return;
2264 }
2265 if (abilityRecord->GetAbilityState() != AbilityState::BACKGROUNDING) {
2266 HILOG_ERROR("Ability state is %{public}d, it can't complete background.", abilityRecord->GetAbilityState());
2267 return;
2268 }
2269
2270 abilityRecord->SetAbilityState(AbilityState::BACKGROUND);
2271 // send application state to AppMS.
2272 // notify AppMS to update application state.
2273 DelayedSingleton<AppScheduler>::GetInstance()->MoveToBackground(abilityRecord->GetToken());
2274 CompleteStartServiceReq(abilityRecord->GetURI());
2275 }
2276
PrintTimeOutLog(const std::shared_ptr<AbilityRecord> & ability,uint32_t msgId)2277 void AbilityConnectManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &ability, uint32_t msgId)
2278 {
2279 if (ability == nullptr) {
2280 HILOG_ERROR("ability is nullptr");
2281 return;
2282 }
2283
2284 AppExecFwk::RunningProcessInfo processInfo = {};
2285 DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByToken(ability->GetToken(), processInfo);
2286 if (processInfo.pid_ == 0) {
2287 HILOG_ERROR("error: the ability[%{public}s], app may fork fail or not running.",
2288 ability->GetAbilityInfo().name.data());
2289 return;
2290 }
2291 int typeId = AppExecFwk::AppfreezeManager::TypeAttribute::NORMAL_TIMEOUT;
2292 std::string msgContent = "ability:" + ability->GetAbilityInfo().name + " ";
2293 switch (msgId) {
2294 case AbilityManagerService::LOAD_TIMEOUT_MSG:
2295 msgContent += "load timeout";
2296 typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
2297 break;
2298 case AbilityManagerService::ACTIVE_TIMEOUT_MSG:
2299 msgContent += "active timeout";
2300 break;
2301 case AbilityManagerService::INACTIVE_TIMEOUT_MSG:
2302 msgContent += "inactive timeout";
2303 break;
2304 case AbilityManagerService::FOREGROUND_TIMEOUT_MSG:
2305 msgContent += "foreground timeout";
2306 typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
2307 break;
2308 case AbilityManagerService::BACKGROUND_TIMEOUT_MSG:
2309 msgContent += "background timeout";
2310 break;
2311 case AbilityManagerService::TERMINATE_TIMEOUT_MSG:
2312 msgContent += "terminate timeout";
2313 break;
2314 default:
2315 return;
2316 }
2317
2318 HILOG_WARN("LIFECYCLE_TIMEOUT: uid: %{public}d, pid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
2319 "msg: %{public}s", processInfo.uid_, processInfo.pid_, ability->GetAbilityInfo().bundleName.c_str(),
2320 ability->GetAbilityInfo().name.c_str(), msgContent.c_str());
2321 AppExecFwk::AppfreezeManager::ParamInfo info = {
2322 .typeId = typeId,
2323 .pid = processInfo.pid_,
2324 .eventName = AppExecFwk::AppFreezeType::LIFECYCLE_TIMEOUT,
2325 .bundleName = ability->GetAbilityInfo().bundleName,
2326 .msg = msgContent
2327 };
2328 AppExecFwk::AppfreezeManager::GetInstance()->LifecycleTimeoutHandle(info);
2329 }
2330
MoveToTerminatingMap(const std::shared_ptr<AbilityRecord> & abilityRecord)2331 void AbilityConnectManager::MoveToTerminatingMap(const std::shared_ptr<AbilityRecord>& abilityRecord)
2332 {
2333 CHECK_POINTER(abilityRecord);
2334 auto& abilityInfo = abilityRecord->GetAbilityInfo();
2335 terminatingExtensionMap_.emplace(abilityRecord->GetURI(), abilityRecord);
2336 if (FRS_BUNDLE_NAME == abilityInfo.bundleName) {
2337 AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name,
2338 abilityInfo.moduleName);
2339 serviceMap_.erase(
2340 element.GetURI() + std::to_string(abilityRecord->GetWant().GetIntParam(FRS_APP_INDEX, 0)));
2341 } else {
2342 serviceMap_.erase(abilityRecord->GetURI());
2343 }
2344 if (IsSpecialAbility(abilityRecord->GetAbilityInfo())) {
2345 HILOG_INFO("Moving ability: %{public}s", abilityRecord->GetURI().c_str());
2346 }
2347 }
2348
AddUIExtWindowDeathRecipient(const sptr<IRemoteObject> & session)2349 void AbilityConnectManager::AddUIExtWindowDeathRecipient(const sptr<IRemoteObject> &session)
2350 {
2351 CHECK_POINTER(session);
2352 auto it = uiExtRecipientMap_.find(session);
2353 if (it != uiExtRecipientMap_.end()) {
2354 HILOG_ERROR("This death recipient has been added.");
2355 return;
2356 } else {
2357 std::weak_ptr<AbilityConnectManager> thisWeakPtr(shared_from_this());
2358 sptr<IRemoteObject::DeathRecipient> deathRecipient =
2359 new AbilityConnectCallbackRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
2360 auto abilityConnectManager = thisWeakPtr.lock();
2361 if (abilityConnectManager) {
2362 abilityConnectManager->OnUIExtWindowDied(remote);
2363 }
2364 });
2365 if (!session->AddDeathRecipient(deathRecipient)) {
2366 HILOG_ERROR("AddDeathRecipient failed.");
2367 }
2368 uiExtRecipientMap_.emplace(session, deathRecipient);
2369 }
2370 }
2371
RemoveUIExtWindowDeathRecipient(const sptr<IRemoteObject> & session)2372 void AbilityConnectManager::RemoveUIExtWindowDeathRecipient(const sptr<IRemoteObject> &session)
2373 {
2374 CHECK_POINTER(session);
2375 auto it = uiExtRecipientMap_.find(session);
2376 if (it != uiExtRecipientMap_.end() && it->first != nullptr) {
2377 it->first->RemoveDeathRecipient(it->second);
2378 uiExtRecipientMap_.erase(it);
2379 return;
2380 }
2381 }
2382
OnUIExtWindowDied(const wptr<IRemoteObject> & remote)2383 void AbilityConnectManager::OnUIExtWindowDied(const wptr<IRemoteObject> &remote)
2384 {
2385 auto object = remote.promote();
2386 CHECK_POINTER(object);
2387 if (taskHandler_) {
2388 auto task = [object, connectManager = shared_from_this()]() {
2389 connectManager->HandleUIExtWindowDiedTask(object);
2390 };
2391 taskHandler_->SubmitTask(task);
2392 }
2393 }
2394
HandleUIExtWindowDiedTask(const sptr<IRemoteObject> & remote)2395 void AbilityConnectManager::HandleUIExtWindowDiedTask(const sptr<IRemoteObject> &remote)
2396 {
2397 HILOG_DEBUG("call.");
2398 std::lock_guard guard(Lock_);
2399 CHECK_POINTER(remote);
2400 auto it = uiExtensionMap_.find(remote);
2401 if (it != uiExtensionMap_.end()) {
2402 auto abilityRecord = it->second.first.lock();
2403 if (abilityRecord) {
2404 DoTerminateUIExtensionAbility(abilityRecord, it->second.second);
2405 } else {
2406 HILOG_INFO("abilityRecord is nullptr");
2407 }
2408 RemoveUIExtWindowDeathRecipient(remote);
2409 uiExtensionMap_.erase(it);
2410 } else {
2411 HILOG_INFO("Died object can't find from map.");
2412 return;
2413 }
2414 }
2415
IsUIExtensionFocused(uint32_t uiExtensionTokenId,const sptr<IRemoteObject> & focusToken)2416 bool AbilityConnectManager::IsUIExtensionFocused(uint32_t uiExtensionTokenId, const sptr<IRemoteObject>& focusToken)
2417 {
2418 HILOG_DEBUG("called, id: %{public}u", uiExtensionTokenId);
2419 CHECK_POINTER_AND_RETURN(uiExtensionAbilityRecordMgr_, false);
2420 std::lock_guard guard(Lock_);
2421 for (auto& item: uiExtensionMap_) {
2422 auto uiExtension = item.second.first.lock();
2423 auto sessionInfo = item.second.second;
2424 if (uiExtension && uiExtension->GetApplicationInfo().accessTokenId == uiExtensionTokenId) {
2425 if (uiExtensionAbilityRecordMgr_->IsFocused(uiExtension->GetUIExtensionAbilityId(), focusToken)) {
2426 HILOG_INFO("id: %{public}u, isFocused.", uiExtensionTokenId);
2427 return true;
2428 }
2429 if (sessionInfo && sessionInfo->callerToken == focusToken) {
2430 return true;
2431 }
2432 }
2433 }
2434 return false;
2435 }
2436
IsWindowExtensionFocused(uint32_t extensionTokenId,const sptr<IRemoteObject> & focusToken)2437 bool AbilityConnectManager::IsWindowExtensionFocused(uint32_t extensionTokenId, const sptr<IRemoteObject>& focusToken)
2438 {
2439 std::lock_guard guard(Lock_);
2440 for (auto& item: windowExtensionMap_) {
2441 uint32_t windowExtTokenId = item.second.first;
2442 auto sessionInfo = item.second.second;
2443 if (windowExtTokenId == extensionTokenId && sessionInfo && sessionInfo->callerToken == focusToken) {
2444 return true;
2445 }
2446 }
2447 return false;
2448 }
2449
HandleProcessFrozen(const std::vector<int32_t> & pidList,int32_t uid)2450 void AbilityConnectManager::HandleProcessFrozen(const std::vector<int32_t> &pidList, int32_t uid)
2451 {
2452 auto taskHandler = taskHandler_;
2453 if (!taskHandler) {
2454 HILOG_ERROR("taskHandler null");
2455 return;
2456 }
2457 HILOG_INFO("HandleProcessFrozen: %{public}d", uid);
2458 std::unordered_set<int32_t> pidSet(pidList.begin(), pidList.end());
2459 std::lock_guard guard(Lock_);
2460 auto weakthis = weak_from_this();
2461 for (auto [key, abilityRecord] : serviceMap_) {
2462 if (abilityRecord && abilityRecord->GetUid() == uid &&
2463 abilityRecord->GetAbilityInfo().extensionAbilityType == AppExecFwk::ExtensionAbilityType::SERVICE &&
2464 pidSet.count(abilityRecord->GetPid()) > 0 &&
2465 FROZEN_WHITE_LIST.count(abilityRecord->GetAbilityInfo().bundleName) == 0 &&
2466 abilityRecord->IsConnectListEmpty() &&
2467 !abilityRecord->GetKeepAlive() &&
2468 abilityRecord->GetStartId() != 0) { // To be honest, this is expected to be true
2469 taskHandler->SubmitTask([weakthis, record = abilityRecord]() {
2470 auto connectManager = weakthis.lock();
2471 if (record && connectManager) {
2472 HILOG_INFO("TerminateRecord: %{public}s", record->GetAbilityInfo().bundleName.c_str());
2473 std::lock_guard guard(connectManager->Lock_);
2474 connectManager->TerminateRecord(record);
2475 } else {
2476 HILOG_ERROR("connectManager null");
2477 }
2478 });
2479 }
2480 }
2481 }
2482
PostExtensionDelayDisconnectTask(const std::shared_ptr<ConnectionRecord> & connectRecord)2483 void AbilityConnectManager::PostExtensionDelayDisconnectTask(const std::shared_ptr<ConnectionRecord> &connectRecord)
2484 {
2485 HILOG_DEBUG("call");
2486 CHECK_POINTER(taskHandler_);
2487 CHECK_POINTER(connectRecord);
2488 int32_t recordId = connectRecord->GetRecordId();
2489 std::string taskName = std::string("DelayDisconnectTask_") + std::to_string(recordId);
2490
2491 auto abilityRecord = connectRecord->GetAbilityRecord();
2492 CHECK_POINTER(abilityRecord);
2493 auto typeName = abilityRecord->GetAbilityInfo().extensionTypeName;
2494 int32_t delayTime = DelayedSingleton<ExtensionConfig>::GetInstance()->GetExtensionAutoDisconnectTime(typeName);
2495 if (delayTime == AUTO_DISCONNECT_INFINITY) {
2496 HILOG_DEBUG("This extension needn't auto disconnect.");
2497 return;
2498 }
2499
2500 auto task = [connectRecord, self = weak_from_this()]() {
2501 auto selfObj = self.lock();
2502 if (selfObj == nullptr) {
2503 HILOG_WARN("mgr is invalid.");
2504 return;
2505 }
2506 HILOG_WARN("Auto disconnect the Extension's connection.");
2507 selfObj->HandleExtensionDisconnectTask(connectRecord);
2508 };
2509 taskHandler_->SubmitTask(task, taskName, delayTime);
2510 }
2511
RemoveExtensionDelayDisconnectTask(const std::shared_ptr<ConnectionRecord> & connectRecord)2512 void AbilityConnectManager::RemoveExtensionDelayDisconnectTask(const std::shared_ptr<ConnectionRecord> &connectRecord)
2513 {
2514 HILOG_DEBUG("call");
2515 CHECK_POINTER(taskHandler_);
2516 CHECK_POINTER(connectRecord);
2517 int32_t recordId = connectRecord->GetRecordId();
2518 std::string taskName = std::string("DelayDisconnectTask_") + std::to_string(recordId);
2519 taskHandler_->CancelTask(taskName);
2520 }
2521
HandleExtensionDisconnectTask(const std::shared_ptr<ConnectionRecord> & connectRecord)2522 void AbilityConnectManager::HandleExtensionDisconnectTask(const std::shared_ptr<ConnectionRecord> &connectRecord)
2523 {
2524 HILOG_DEBUG("call");
2525 std::lock_guard guard(Lock_);
2526 CHECK_POINTER(connectRecord);
2527 int result = connectRecord->DisconnectAbility();
2528 if (result != ERR_OK) {
2529 HILOG_WARN("Auto disconnect extension error, ret: %{public}d.", result);
2530 }
2531 if (connectRecord->GetConnectState() == ConnectionState::DISCONNECTED) {
2532 connectRecord->CompleteDisconnect(ERR_OK, false);
2533 RemoveConnectionRecordFromMap(connectRecord);
2534 }
2535 }
2536
IsUIExtensionAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)2537 bool AbilityConnectManager::IsUIExtensionAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
2538 {
2539 CHECK_POINTER_AND_RETURN(abilityRecord, false);
2540 return UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType);
2541 }
2542
CheckUIExtensionAbilitySessionExistLocked(const std::shared_ptr<AbilityRecord> & abilityRecord)2543 bool AbilityConnectManager::CheckUIExtensionAbilitySessionExistLocked(
2544 const std::shared_ptr<AbilityRecord> &abilityRecord)
2545 {
2546 CHECK_POINTER_AND_RETURN(abilityRecord, false);
2547
2548 for (auto it = uiExtensionMap_.begin(); it != uiExtensionMap_.end();) {
2549 std::shared_ptr<AbilityRecord> uiExtAbility = it->second.first.lock();
2550 if (abilityRecord == uiExtAbility) {
2551 return true;
2552 }
2553 it++;
2554 }
2555
2556 return false;
2557 }
2558
RemoveUIExtensionAbilityRecord(const std::shared_ptr<AbilityRecord> & abilityRecord)2559 void AbilityConnectManager::RemoveUIExtensionAbilityRecord(const std::shared_ptr<AbilityRecord> &abilityRecord)
2560 {
2561 CHECK_POINTER(abilityRecord);
2562 CHECK_POINTER(uiExtensionAbilityRecordMgr_);
2563 uiExtensionAbilityRecordMgr_->RemoveExtensionRecord(abilityRecord->GetUIExtensionAbilityId());
2564 }
2565 } // namespace AAFwk
2566 } // namespace OHOS
2567