1 /*
2 * Copyright (c) 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 "scene_board/ui_ability_lifecycle_manager.h"
17
18 #include "ability_manager_service.h"
19 #include "ability_running_info.h"
20 #include "ability_util.h"
21 #include "appfreeze_manager.h"
22 #include "app_exit_reason_data_manager.h"
23 #include "errors.h"
24 #include "hilog_wrapper.h"
25 #include "hitrace_meter.h"
26 #include "iability_info_callback.h"
27 #include "mission_info.h"
28 #include "session_info.h"
29
30 namespace OHOS {
31 namespace AAFwk {
32 namespace {
33 constexpr char EVENT_KEY_UID[] = "UID";
34 constexpr char EVENT_KEY_PID[] = "PID";
35 constexpr char EVENT_KEY_MESSAGE[] = "MSG";
36 constexpr char EVENT_KEY_PACKAGE_NAME[] = "PACKAGE_NAME";
37 constexpr char EVENT_KEY_PROCESS_NAME[] = "PROCESS_NAME";
38 const std::string DLP_INDEX = "ohos.dlp.params.index";
39 constexpr int32_t PREPARE_TERMINATE_TIMEOUT_MULTIPLE = 10;
40 #ifdef SUPPORT_ASAN
41 const int KILL_TIMEOUT_MULTIPLE = 45;
42 #else
43 const int KILL_TIMEOUT_MULTIPLE = 3;
44 #endif
45 constexpr int32_t DEFAULT_USER_ID = 0;
46 }
StartUIAbility(AbilityRequest & abilityRequest,sptr<SessionInfo> sessionInfo)47 int UIAbilityLifecycleManager::StartUIAbility(AbilityRequest &abilityRequest, sptr<SessionInfo> sessionInfo)
48 {
49 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
50 std::lock_guard<ffrt::mutex> guard(sessionLock_);
51 HILOG_DEBUG("Call.");
52 if (sessionInfo == nullptr || sessionInfo->sessionToken == nullptr) {
53 HILOG_ERROR("sessionInfo is invalid.");
54 return ERR_INVALID_VALUE;
55 }
56 auto sessionToken = iface_cast<Rosen::ISession>(sessionInfo->sessionToken);
57 auto descriptor = Str16ToStr8(sessionToken->GetDescriptor());
58 if (descriptor != "OHOS.ISession") {
59 HILOG_ERROR("token's Descriptor: %{public}s", descriptor.c_str());
60 return ERR_INVALID_VALUE;
61 }
62 abilityRequest.sessionInfo = sessionInfo;
63
64 HILOG_INFO("session id: %{public}d.", sessionInfo->persistentId);
65 std::shared_ptr<AbilityRecord> uiAbilityRecord = nullptr;
66 auto iter = sessionAbilityMap_.find(sessionInfo->persistentId);
67 if (iter != sessionAbilityMap_.end()) {
68 HILOG_DEBUG("isNewWant: %{public}d.", sessionInfo->isNewWant);
69 uiAbilityRecord = iter->second;
70 uiAbilityRecord->SetIsNewWant(sessionInfo->isNewWant);
71 if (sessionInfo->isNewWant) {
72 uiAbilityRecord->SetWant(abilityRequest.want);
73 }
74 } else {
75 if (sessionInfo->startSetting != nullptr) {
76 HILOG_DEBUG("startSetting is valid.");
77 abilityRequest.startSetting = sessionInfo->startSetting;
78 }
79 uiAbilityRecord = AbilityRecord::CreateAbilityRecord(abilityRequest);
80 HILOG_DEBUG("user id: %{public}d.", sessionInfo->userId);
81 uiAbilityRecord->SetOwnerMissionUserId(sessionInfo->userId);
82 SetRevicerInfo(abilityRequest, uiAbilityRecord);
83 SetLastExitReason(uiAbilityRecord);
84 }
85 CHECK_POINTER_AND_RETURN(uiAbilityRecord, ERR_INVALID_VALUE);
86
87 if (uiAbilityRecord->GetPendingState() == AbilityState::FOREGROUND) {
88 HILOG_DEBUG("pending state is FOREGROUND.");
89 uiAbilityRecord->SetPendingState(AbilityState::FOREGROUND);
90 return ERR_OK;
91 } else {
92 HILOG_DEBUG("pending state is not FOREGROUND.");
93 uiAbilityRecord->SetPendingState(AbilityState::FOREGROUND);
94 }
95
96 ReportEventToSuspendManager(abilityRequest.abilityInfo);
97 UpdateAbilityRecordLaunchReason(abilityRequest, uiAbilityRecord);
98 NotifyAbilityToken(uiAbilityRecord->GetToken(), abilityRequest);
99
100 uiAbilityRecord->AddCallerRecord(sessionInfo->callerToken, sessionInfo->requestCode);
101 if (iter == sessionAbilityMap_.end()) {
102 sessionAbilityMap_.emplace(sessionInfo->persistentId, uiAbilityRecord);
103 }
104 uiAbilityRecord->ProcessForegroundAbility(sessionInfo->callingTokenId);
105 if (abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::SPECIFIED && !specifiedInfoQueue_.empty()) {
106 SpecifiedInfo specifiedInfo = specifiedInfoQueue_.front();
107 specifiedInfoQueue_.pop();
108 uiAbilityRecord->SetSpecifiedFlag(specifiedInfo.flag);
109 specifiedAbilityMap_.emplace(specifiedInfo, uiAbilityRecord);
110 }
111 return ERR_OK;
112 }
113
AttachAbilityThread(const sptr<IAbilityScheduler> & scheduler,const sptr<IRemoteObject> & token)114 int UIAbilityLifecycleManager::AttachAbilityThread(const sptr<IAbilityScheduler> &scheduler,
115 const sptr<IRemoteObject> &token)
116 {
117 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
118 std::lock_guard<ffrt::mutex> guard(sessionLock_);
119 if (!IsContainsAbilityInner(token)) {
120 return ERR_INVALID_VALUE;
121 }
122 auto&& abilityRecord = Token::GetAbilityRecordByToken(token);
123 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
124 HILOG_DEBUG("AbilityMS attach abilityThread, name is %{public}s.", abilityRecord->GetAbilityInfo().name.c_str());
125
126 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
127 CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityEventHandler.");
128 handler->RemoveEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, abilityRecord->GetAbilityRecordId());
129
130 abilityRecord->SetScheduler(scheduler);
131 if (abilityRecord->IsStartedByCall()) {
132 if (abilityRecord->GetWant().GetBoolParam(Want::PARAM_RESV_CALL_TO_FOREGROUND, false)) {
133 abilityRecord->SetStartToForeground(true);
134 DelayedSingleton<AppScheduler>::GetInstance()->MoveToForeground(token);
135 } else {
136 abilityRecord->SetStartToBackground(true);
137 MoveToBackground(abilityRecord);
138 }
139 return ERR_OK;
140 }
141
142 if (abilityRecord->IsNeedToCallRequest()) {
143 abilityRecord->CallRequest();
144 }
145
146 DelayedSingleton<AppScheduler>::GetInstance()->MoveToForeground(token);
147 return ERR_OK;
148 }
149
OnAbilityRequestDone(const sptr<IRemoteObject> & token,int32_t state) const150 void UIAbilityLifecycleManager::OnAbilityRequestDone(const sptr<IRemoteObject> &token, int32_t state) const
151 {
152 HILOG_DEBUG("Ability request state %{public}d done.", state);
153 std::lock_guard<ffrt::mutex> guard(sessionLock_);
154 AppAbilityState abilityState = DelayedSingleton<AppScheduler>::GetInstance()->ConvertToAppAbilityState(state);
155 if (abilityState == AppAbilityState::ABILITY_STATE_FOREGROUND) {
156 auto&& abilityRecord = Token::GetAbilityRecordByToken(token);
157 CHECK_POINTER(abilityRecord);
158 std::string element = abilityRecord->GetWant().GetElement().GetURI();
159 HILOG_DEBUG("Ability is %{public}s, start to foreground.", element.c_str());
160 abilityRecord->ForegroundAbility();
161 }
162 }
163
AbilityTransactionDone(const sptr<IRemoteObject> & token,int state,const PacMap & saveData)164 int UIAbilityLifecycleManager::AbilityTransactionDone(const sptr<IRemoteObject> &token, int state,
165 const PacMap &saveData)
166 {
167 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
168 int targetState = AbilityRecord::ConvertLifeCycleToAbilityState(static_cast<AbilityLifeCycleState>(state));
169 std::string abilityState = AbilityRecord::ConvertAbilityState(static_cast<AbilityState>(targetState));
170 HILOG_INFO("AbilityTransactionDone, state: %{public}s.", abilityState.c_str());
171
172 std::lock_guard<ffrt::mutex> guard(sessionLock_);
173 auto abilityRecord = GetAbilityRecordByToken(token);
174 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
175
176 std::string element = abilityRecord->GetWant().GetElement().GetURI();
177 HILOG_DEBUG("ability: %{public}s, state: %{public}s", element.c_str(), abilityState.c_str());
178
179 if (targetState == AbilityState::BACKGROUND) {
180 abilityRecord->SaveAbilityState(saveData);
181 }
182
183 return DispatchState(abilityRecord, targetState);
184 }
185
NotifySCBToStartUIAbility(const AbilityRequest & abilityRequest,int32_t userId)186 int UIAbilityLifecycleManager::NotifySCBToStartUIAbility(const AbilityRequest &abilityRequest, int32_t userId)
187 {
188 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
189 HILOG_DEBUG("Call, userId: %{public}d.", userId);
190 std::lock_guard<ffrt::mutex> guard(sessionLock_);
191 auto isSpecified = (abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::SPECIFIED);
192 if (isSpecified) {
193 EnqueueAbilityToFront(abilityRequest);
194 DelayedSingleton<AppScheduler>::GetInstance()->StartSpecifiedAbility(
195 abilityRequest.want, abilityRequest.abilityInfo);
196 return ERR_OK;
197 }
198 auto sessionInfo = CreateSessionInfo(abilityRequest);
199 sessionInfo->requestCode = abilityRequest.requestCode;
200 sessionInfo->persistentId = GetPersistentIdByAbilityRequest(abilityRequest, sessionInfo->reuse, userId);
201 sessionInfo->userId = userId;
202 return NotifySCBPendingActivation(sessionInfo, abilityRequest);
203 }
204
DispatchState(const std::shared_ptr<AbilityRecord> & abilityRecord,int state)205 int UIAbilityLifecycleManager::DispatchState(const std::shared_ptr<AbilityRecord> &abilityRecord, int state)
206 {
207 switch (state) {
208 case AbilityState::INITIAL: {
209 return DispatchTerminate(abilityRecord);
210 }
211 case AbilityState::BACKGROUND: {
212 return DispatchBackground(abilityRecord);
213 }
214 case AbilityState::FOREGROUND: {
215 return DispatchForeground(abilityRecord, true);
216 }
217 case AbilityState::FOREGROUND_FAILED:
218 case AbilityState::FOREGROUND_INVALID_MODE:
219 case AbilityState::FOREGROUND_WINDOW_FREEZED: {
220 return DispatchForeground(abilityRecord, false, static_cast<AbilityState>(state));
221 }
222 default: {
223 HILOG_WARN("Don't support transiting state: %{public}d", state);
224 return ERR_INVALID_VALUE;
225 }
226 }
227 }
228
DispatchForeground(const std::shared_ptr<AbilityRecord> & abilityRecord,bool success,AbilityState state)229 int UIAbilityLifecycleManager::DispatchForeground(const std::shared_ptr<AbilityRecord> &abilityRecord, bool success,
230 AbilityState state)
231 {
232 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
233 CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityEventHandler.");
234 auto taskHandler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
235 CHECK_POINTER_AND_RETURN_LOG(taskHandler, ERR_INVALID_VALUE, "Fail to get AbilityTaskHandler.");
236 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
237
238 if (!abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING)) {
239 HILOG_ERROR("DispatchForeground Ability transition life state error. expect %{public}d, actual %{public}d",
240 AbilityState::FOREGROUNDING,
241 abilityRecord->GetAbilityState());
242 return ERR_INVALID_VALUE;
243 }
244
245 handler->RemoveEvent(AbilityManagerService::FOREGROUND_TIMEOUT_MSG, abilityRecord->GetAbilityRecordId());
246 auto self(weak_from_this());
247 if (success) {
248 HILOG_INFO("foreground succeeded.");
249 auto task = [self, abilityRecord]() {
250 auto selfObj = self.lock();
251 if (!selfObj) {
252 HILOG_WARN("mgr is invalid.");
253 return;
254 }
255 selfObj->CompleteForegroundSuccess(abilityRecord);
256 };
257 taskHandler->SubmitTask(task);
258 } else {
259 auto task = [self, abilityRecord, state]() {
260 auto selfObj = self.lock();
261 if (!selfObj) {
262 HILOG_WARN("Mission list mgr is invalid.");
263 return;
264 }
265 if (state == AbilityState::FOREGROUND_WINDOW_FREEZED) {
266 HILOG_INFO("Window was freezed.");
267 if (abilityRecord != nullptr) {
268 abilityRecord->SetAbilityState(AbilityState::BACKGROUND);
269 DelayedSingleton<AppScheduler>::GetInstance()->MoveToBackground(abilityRecord->GetToken());
270 }
271 return;
272 }
273 selfObj->HandleForegroundFailed(abilityRecord, state);
274 };
275 taskHandler->SubmitTask(task);
276 }
277 return ERR_OK;
278 }
279
DispatchBackground(const std::shared_ptr<AbilityRecord> & abilityRecord)280 int UIAbilityLifecycleManager::DispatchBackground(const std::shared_ptr<AbilityRecord> &abilityRecord)
281 {
282 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
283 CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityTaskHandler.");
284 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
285
286 if (!abilityRecord->IsAbilityState(AbilityState::BACKGROUNDING)) {
287 HILOG_ERROR("Ability transition life state error. actual %{public}d", abilityRecord->GetAbilityState());
288 return ERR_INVALID_VALUE;
289 }
290
291 // remove background timeout task.
292 handler->CancelTask("background_" + std::to_string(abilityRecord->GetAbilityRecordId()));
293 auto self(shared_from_this());
294 auto task = [self, abilityRecord]() { self->CompleteBackground(abilityRecord); };
295 handler->SubmitTask(task);
296
297 return ERR_OK;
298 }
299
DispatchTerminate(const std::shared_ptr<AbilityRecord> & abilityRecord)300 int UIAbilityLifecycleManager::DispatchTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord)
301 {
302 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
303 if (abilityRecord->GetAbilityState() != AbilityState::TERMINATING) {
304 HILOG_ERROR("DispatchTerminate error, ability state is %{public}d", abilityRecord->GetAbilityState());
305 return INNER_ERR;
306 }
307
308 // remove terminate timeout task.
309 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
310 CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityTaskHandler.");
311 handler->CancelTask("terminate_" + std::to_string(abilityRecord->GetAbilityRecordId()));
312 auto self(shared_from_this());
313 auto task = [self, abilityRecord]() { self->CompleteTerminate(abilityRecord); };
314 handler->SubmitTask(task);
315
316 return ERR_OK;
317 }
318
CompleteForegroundSuccess(const std::shared_ptr<AbilityRecord> & abilityRecord)319 void UIAbilityLifecycleManager::CompleteForegroundSuccess(const std::shared_ptr<AbilityRecord> &abilityRecord)
320 {
321 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
322 std::lock_guard<ffrt::mutex> guard(sessionLock_);
323
324 CHECK_POINTER(abilityRecord);
325 // ability do not save window mode
326 abilityRecord->RemoveWindowMode();
327 std::string element = abilityRecord->GetWant().GetElement().GetURI();
328 HILOG_DEBUG("ability: %{public}s", element.c_str());
329 abilityRecord->SetAbilityState(AbilityState::FOREGROUND);
330
331 // new version. started by caller, scheduler call request
332 if (abilityRecord->IsStartedByCall() && abilityRecord->IsStartToForeground() && abilityRecord->IsReady()) {
333 HILOG_DEBUG("call request after completing foreground state");
334 abilityRecord->CallRequest();
335 abilityRecord->SetStartToForeground(false);
336 }
337
338 if (abilityRecord->GetPendingState() == AbilityState::BACKGROUND) {
339 abilityRecord->SetMinimizeReason(true);
340 MoveToBackground(abilityRecord);
341 } else if (abilityRecord->GetPendingState() == AbilityState::FOREGROUND) {
342 HILOG_DEBUG("not continuous startup.");
343 abilityRecord->SetPendingState(AbilityState::INITIAL);
344 }
345 if (handler_ != nullptr && abilityRecord->GetSessionInfo() != nullptr) {
346 handler_->OnSessionMovedToFront(abilityRecord->GetSessionInfo()->persistentId);
347 }
348 }
349
HandleForegroundFailed(const std::shared_ptr<AbilityRecord> & ability,AbilityState state)350 void UIAbilityLifecycleManager::HandleForegroundFailed(const std::shared_ptr<AbilityRecord> &ability,
351 AbilityState state)
352 {
353 HILOG_DEBUG("state: %{public}d.", static_cast<int32_t>(state));
354 std::lock_guard<ffrt::mutex> guard(sessionLock_);
355 if (ability == nullptr) {
356 HILOG_ERROR("ability record is nullptr.");
357 return;
358 }
359
360 if (!ability->IsAbilityState(AbilityState::FOREGROUNDING)) {
361 HILOG_ERROR("this ability is not foregrounding state.");
362 return;
363 }
364
365 EraseAbilityRecord(ability);
366 // foreground failed, notify appMs force terminate the ability
367 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(ability->GetToken());
368 }
369
GetAbilityRecordByToken(const sptr<IRemoteObject> & token) const370 std::shared_ptr<AbilityRecord> UIAbilityLifecycleManager::GetAbilityRecordByToken(const sptr<IRemoteObject> &token)
371 const
372 {
373 if (token == nullptr) {
374 HILOG_ERROR("nullptr.");
375 return nullptr;
376 }
377
378 for (auto ability : terminateAbilityList_) {
379 if (ability && token == ability->GetToken()->AsObject()) {
380 return ability;
381 }
382 }
383
384 for (auto iter = sessionAbilityMap_.begin(); iter != sessionAbilityMap_.end(); iter++) {
385 if (iter->second != nullptr && iter->second->GetToken()->AsObject() == token) {
386 return iter->second;
387 }
388 }
389 return nullptr;
390 }
391
IsContainsAbility(const sptr<IRemoteObject> & token) const392 bool UIAbilityLifecycleManager::IsContainsAbility(const sptr<IRemoteObject> &token) const
393 {
394 std::lock_guard<ffrt::mutex> guard(sessionLock_);
395 return IsContainsAbilityInner(token);
396 }
397
IsContainsAbilityInner(const sptr<IRemoteObject> & token) const398 bool UIAbilityLifecycleManager::IsContainsAbilityInner(const sptr<IRemoteObject> &token) const
399 {
400 for (auto iter = sessionAbilityMap_.begin(); iter != sessionAbilityMap_.end(); iter++) {
401 if (iter->second != nullptr && iter->second->GetToken()->AsObject() == token) {
402 return true;
403 }
404 }
405 return false;
406 }
407
EraseAbilityRecord(const std::shared_ptr<AbilityRecord> & abilityRecord)408 void UIAbilityLifecycleManager::EraseAbilityRecord(const std::shared_ptr<AbilityRecord> &abilityRecord)
409 {
410 if (abilityRecord == nullptr) {
411 return;
412 }
413
414 for (auto iter = sessionAbilityMap_.begin(); iter != sessionAbilityMap_.end(); iter++) {
415 if (iter->second != nullptr && iter->second->GetToken()->AsObject() == abilityRecord->GetToken()->AsObject()) {
416 sessionAbilityMap_.erase(iter);
417 break;
418 }
419 }
420 }
421
EraseSpecifiedAbilityRecord(const std::shared_ptr<AbilityRecord> & abilityRecord)422 void UIAbilityLifecycleManager::EraseSpecifiedAbilityRecord(const std::shared_ptr<AbilityRecord> &abilityRecord)
423 {
424 for (auto iter = specifiedAbilityMap_.begin(); iter != specifiedAbilityMap_.end(); iter++) {
425 auto abilityInfo = abilityRecord->GetAbilityInfo();
426 if (iter->second != nullptr && iter->second->GetToken()->AsObject() == abilityRecord->GetToken()->AsObject() &&
427 iter->first.abilityName == abilityInfo.name && iter->first.bundleName == abilityInfo.bundleName &&
428 iter->first.flag == abilityRecord->GetSpecifiedFlag()) {
429 specifiedAbilityMap_.erase(iter);
430 break;
431 }
432 }
433 }
434
UpdateAbilityRecordLaunchReason(const AbilityRequest & abilityRequest,std::shared_ptr<AbilityRecord> & abilityRecord) const435 void UIAbilityLifecycleManager::UpdateAbilityRecordLaunchReason(
436 const AbilityRequest &abilityRequest, std::shared_ptr<AbilityRecord> &abilityRecord) const
437 {
438 if (abilityRecord == nullptr) {
439 HILOG_WARN("input record is nullptr.");
440 return;
441 }
442
443 if (abilityRequest.IsContinuation()) {
444 abilityRecord->SetLaunchReason(LaunchReason::LAUNCHREASON_CONTINUATION);
445 return;
446 }
447
448 if (abilityRequest.IsAppRecovery() || abilityRecord->GetRecoveryInfo()) {
449 abilityRecord->SetLaunchReason(LaunchReason::LAUNCHREASON_APP_RECOVERY);
450 return;
451 }
452
453 abilityRecord->SetLaunchReason(LaunchReason::LAUNCHREASON_START_ABILITY);
454 return;
455 }
456
GetUIAbilityRecordBySessionInfo(const sptr<SessionInfo> & sessionInfo)457 std::shared_ptr<AbilityRecord> UIAbilityLifecycleManager::GetUIAbilityRecordBySessionInfo(
458 const sptr<SessionInfo> &sessionInfo)
459 {
460 std::lock_guard<ffrt::mutex> guard(sessionLock_);
461 CHECK_POINTER_AND_RETURN(sessionInfo, nullptr);
462 CHECK_POINTER_AND_RETURN(sessionInfo->sessionToken, nullptr);
463 auto sessionToken = iface_cast<Rosen::ISession>(sessionInfo->sessionToken);
464 std::string descriptor = Str16ToStr8(sessionToken->GetDescriptor());
465 if (descriptor != "OHOS.ISession") {
466 HILOG_ERROR("failed, input token is not a sessionToken, token->GetDescriptor(): %{public}s",
467 descriptor.c_str());
468 return nullptr;
469 }
470
471 auto iter = sessionAbilityMap_.find(sessionInfo->persistentId);
472 if (iter != sessionAbilityMap_.end()) {
473 return iter->second;
474 }
475 return nullptr;
476 }
477
MinimizeUIAbility(const std::shared_ptr<AbilityRecord> & abilityRecord,bool fromUser)478 int UIAbilityLifecycleManager::MinimizeUIAbility(const std::shared_ptr<AbilityRecord> &abilityRecord, bool fromUser)
479 {
480 HILOG_DEBUG("call");
481 std::lock_guard<ffrt::mutex> guard(sessionLock_);
482 if (abilityRecord == nullptr) {
483 HILOG_ERROR("ability record is null");
484 return ERR_INVALID_VALUE;
485 }
486 HILOG_INFO("abilityInfoName:%{public}s", abilityRecord->GetAbilityInfo().name.c_str());
487 abilityRecord->SetMinimizeReason(fromUser);
488 abilityRecord->SetPendingState(AbilityState::BACKGROUND);
489 if (!abilityRecord->IsAbilityState(AbilityState::FOREGROUND)) {
490 HILOG_ERROR("ability state is not foreground");
491 return ERR_OK;
492 }
493 MoveToBackground(abilityRecord);
494 return ERR_OK;
495 }
496
MoveToBackground(const std::shared_ptr<AbilityRecord> & abilityRecord)497 void UIAbilityLifecycleManager::MoveToBackground(const std::shared_ptr<AbilityRecord> &abilityRecord)
498 {
499 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
500 if (abilityRecord == nullptr) {
501 HILOG_ERROR("ability record is null");
502 return;
503 }
504 abilityRecord->SetIsNewWant(false);
505 auto self(weak_from_this());
506 auto task = [abilityRecord, self]() {
507 auto selfObj = self.lock();
508 if (selfObj == nullptr) {
509 HILOG_WARN("UIAbilityLifecycleManager is invalid");
510 return;
511 }
512 HILOG_ERROR("UIAbilityLifecycleManager move to background timeout");
513 selfObj->PrintTimeOutLog(abilityRecord, AbilityManagerService::BACKGROUND_TIMEOUT_MSG);
514 selfObj->CompleteBackground(abilityRecord);
515 };
516 abilityRecord->BackgroundAbility(task);
517 }
518
ResolveLocked(const AbilityRequest & abilityRequest,int32_t userId)519 int UIAbilityLifecycleManager::ResolveLocked(const AbilityRequest &abilityRequest, int32_t userId)
520 {
521 HILOG_INFO("ability_name:%{public}s", abilityRequest.want.GetElement().GetURI().c_str());
522
523 if (!abilityRequest.IsCallType(AbilityCallType::CALL_REQUEST_TYPE)) {
524 HILOG_ERROR("%{public}s, resolve ability_name:", __func__);
525 return RESOLVE_CALL_ABILITY_INNER_ERR;
526 }
527
528 return CallAbilityLocked(abilityRequest, userId);
529 }
530
CallAbilityLocked(const AbilityRequest & abilityRequest,int32_t userId)531 int UIAbilityLifecycleManager::CallAbilityLocked(const AbilityRequest &abilityRequest, int32_t userId)
532 {
533 HILOG_DEBUG("Call.");
534 std::lock_guard<ffrt::mutex> guard(sessionLock_);
535
536 // Get target uiAbility record.
537 std::shared_ptr<AbilityRecord> uiAbilityRecord;
538 bool reuse = false;
539 auto persistentId = GetPersistentIdByAbilityRequest(abilityRequest, reuse, userId);
540 if (persistentId == 0) {
541 uiAbilityRecord = AbilityRecord::CreateAbilityRecord(abilityRequest);
542 uiAbilityRecord->SetOwnerMissionUserId(DelayedSingleton<AbilityManagerService>::GetInstance()->GetUserId());
543 SetRevicerInfo(abilityRequest, uiAbilityRecord);
544 SetLastExitReason(uiAbilityRecord);
545 } else {
546 uiAbilityRecord = sessionAbilityMap_.at(persistentId);
547 }
548
549 uiAbilityRecord->AddCallerRecord(abilityRequest.callerToken, abilityRequest.requestCode);
550 uiAbilityRecord->SetLaunchReason(LaunchReason::LAUNCHREASON_CALL);
551 NotifyAbilityToken(uiAbilityRecord->GetToken(), abilityRequest);
552
553 // new version started by call type
554 auto ret = ResolveAbility(uiAbilityRecord, abilityRequest);
555 if (ret == ResolveResultType::OK_HAS_REMOTE_OBJ) {
556 HILOG_DEBUG("target ability has been resolved.");
557 if (abilityRequest.want.GetBoolParam(Want::PARAM_RESV_CALL_TO_FOREGROUND, false)) {
558 HILOG_DEBUG("target ability needs to be switched to foreground.");
559 auto sessionInfo = CreateSessionInfo(abilityRequest);
560 sessionInfo->persistentId = persistentId;
561 sessionInfo->state = CallToState::FOREGROUND;
562 sessionInfo->reuse = reuse;
563 DelayedSingleton<AppScheduler>::GetInstance()->MoveToForeground(uiAbilityRecord->GetToken());
564 return NotifySCBPendingActivation(sessionInfo, abilityRequest);
565 }
566 } else if (ret == ResolveResultType::NG_INNER_ERROR) {
567 HILOG_ERROR("resolve failed, error: %{public}d.", RESOLVE_CALL_ABILITY_INNER_ERR);
568 return RESOLVE_CALL_ABILITY_INNER_ERR;
569 }
570
571 auto sessionInfo = CreateSessionInfo(abilityRequest);
572 sessionInfo->persistentId = persistentId;
573 sessionInfo->reuse = reuse;
574 sessionInfo->uiAbilityId = uiAbilityRecord->GetAbilityRecordId();
575 if (abilityRequest.want.GetBoolParam(Want::PARAM_RESV_CALL_TO_FOREGROUND, false)) {
576 sessionInfo->state = CallToState::FOREGROUND;
577 } else {
578 sessionInfo->state = CallToState::BACKGROUND;
579 }
580 HILOG_DEBUG("Notify scb's abilityId is %{public}" PRIu64 ".", sessionInfo->uiAbilityId);
581 tmpAbilityMap_.emplace(uiAbilityRecord->GetAbilityRecordId(), uiAbilityRecord);
582 return NotifySCBPendingActivation(sessionInfo, abilityRequest);
583 }
584
CallUIAbilityBySCB(const sptr<SessionInfo> & sessionInfo)585 void UIAbilityLifecycleManager::CallUIAbilityBySCB(const sptr<SessionInfo> &sessionInfo)
586 {
587 HILOG_DEBUG("Call.");
588 std::lock_guard<ffrt::mutex> guard(sessionLock_);
589 if (sessionInfo == nullptr || sessionInfo->sessionToken == nullptr) {
590 HILOG_ERROR("sessionInfo is invalid.");
591 return;
592 }
593 auto sessionToken = iface_cast<Rosen::ISession>(sessionInfo->sessionToken);
594 auto descriptor = Str16ToStr8(sessionToken->GetDescriptor());
595 if (descriptor != "OHOS.ISession") {
596 HILOG_ERROR("token's Descriptor: %{public}s", descriptor.c_str());
597 return;
598 }
599
600 HILOG_DEBUG("SCB output abilityId is %{public}" PRIu64 ".", sessionInfo->uiAbilityId);
601 auto search = tmpAbilityMap_.find(sessionInfo->uiAbilityId);
602 if (search == tmpAbilityMap_.end()) {
603 HILOG_WARN("Not found UIAbility.");
604 return;
605 }
606 auto uiAbilityRecord = search->second;
607 if (uiAbilityRecord == nullptr) {
608 HILOG_ERROR("UIAbility not exist.");
609 return;
610 }
611 auto sessionSearch = sessionAbilityMap_.find(sessionInfo->persistentId);
612 if (sessionSearch != sessionAbilityMap_.end()) {
613 HILOG_ERROR("Session already exist.");
614 return;
615 }
616
617 sessionAbilityMap_.emplace(sessionInfo->persistentId, uiAbilityRecord);
618 tmpAbilityMap_.erase(search);
619 uiAbilityRecord->SetSessionInfo(sessionInfo);
620
621 uiAbilityRecord->LoadAbility();
622 }
623
CreateSessionInfo(const AbilityRequest & abilityRequest) const624 sptr<SessionInfo> UIAbilityLifecycleManager::CreateSessionInfo(const AbilityRequest &abilityRequest) const
625 {
626 sptr<SessionInfo> sessionInfo = new SessionInfo();
627 sessionInfo->callerToken = abilityRequest.callerToken;
628 sessionInfo->want = abilityRequest.want;
629 if (abilityRequest.startSetting != nullptr) {
630 sessionInfo->startSetting = abilityRequest.startSetting;
631 }
632 sessionInfo->callingTokenId = IPCSkeleton::GetCallingTokenID();
633 return sessionInfo;
634 }
635
NotifySCBPendingActivation(sptr<SessionInfo> & sessionInfo,const AbilityRequest & abilityRequest) const636 int UIAbilityLifecycleManager::NotifySCBPendingActivation(sptr<SessionInfo> &sessionInfo,
637 const AbilityRequest &abilityRequest) const
638 {
639 auto abilityRecord = GetAbilityRecordByToken(abilityRequest.callerToken);
640 if (abilityRecord != nullptr) {
641 auto callerSessionInfo = abilityRecord->GetSessionInfo();
642 CHECK_POINTER_AND_RETURN(callerSessionInfo, ERR_INVALID_VALUE);
643 CHECK_POINTER_AND_RETURN(callerSessionInfo->sessionToken, ERR_INVALID_VALUE);
644 auto callerSession = iface_cast<Rosen::ISession>(callerSessionInfo->sessionToken);
645 HILOG_INFO("Call PendingSessionActivation by rootSceneSession.");
646 return static_cast<int>(callerSession->PendingSessionActivation(sessionInfo));
647 }
648 CHECK_POINTER_AND_RETURN(rootSceneSession_, ERR_INVALID_VALUE);
649 if (sessionInfo->persistentId == 0) {
650 const auto &abilityInfo = abilityRequest.abilityInfo;
651 auto isStandard = abilityInfo.launchMode == AppExecFwk::LaunchMode::STANDARD && !abilityRequest.startRecent;
652 if (!isStandard) {
653 (void)DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->GetAbilitySessionId(
654 abilityInfo.bundleName, abilityInfo.moduleName, abilityInfo.name, sessionInfo->persistentId);
655 HILOG_INFO("session id: %{public}d.", sessionInfo->persistentId);
656 }
657 }
658 HILOG_INFO("Call PendingSessionActivation by callerSession.");
659 return static_cast<int>(rootSceneSession_->PendingSessionActivation(sessionInfo));
660 }
661
ResolveAbility(const std::shared_ptr<AbilityRecord> & targetAbility,const AbilityRequest & abilityRequest) const662 int UIAbilityLifecycleManager::ResolveAbility(
663 const std::shared_ptr<AbilityRecord> &targetAbility, const AbilityRequest &abilityRequest) const
664 {
665 HILOG_DEBUG("targetAbilityRecord resolve call record.");
666 CHECK_POINTER_AND_RETURN(targetAbility, ResolveResultType::NG_INNER_ERROR);
667
668 ResolveResultType result = targetAbility->Resolve(abilityRequest);
669 switch (result) {
670 case ResolveResultType::NG_INNER_ERROR:
671 case ResolveResultType::OK_HAS_REMOTE_OBJ:
672 return result;
673 default:
674 break;
675 }
676
677 if (targetAbility->IsReady()) {
678 HILOG_DEBUG("targetAbility is ready, directly scheduler call request.");
679 targetAbility->CallRequest();
680 return ResolveResultType::OK_HAS_REMOTE_OBJ;
681 }
682
683 HILOG_DEBUG("targetAbility need to call request after lifecycle.");
684 return result;
685 }
686
NotifyAbilityToken(const sptr<IRemoteObject> & token,const AbilityRequest & abilityRequest) const687 void UIAbilityLifecycleManager::NotifyAbilityToken(const sptr<IRemoteObject> &token,
688 const AbilityRequest &abilityRequest) const
689 {
690 auto abilityInfoCallback = iface_cast<AppExecFwk::IAbilityInfoCallback>(abilityRequest.abilityInfoCallback);
691 if (abilityInfoCallback != nullptr) {
692 abilityInfoCallback->NotifyAbilityToken(token, abilityRequest.want);
693 }
694 }
695
PrintTimeOutLog(const std::shared_ptr<AbilityRecord> & ability,uint32_t msgId,bool isHalf)696 void UIAbilityLifecycleManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &ability,
697 uint32_t msgId, bool isHalf)
698 {
699 if (ability == nullptr) {
700 HILOG_ERROR("failed, ability is nullptr");
701 return;
702 }
703
704 AppExecFwk::RunningProcessInfo processInfo = {};
705 DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByToken(ability->GetToken(), processInfo);
706 if (processInfo.pid_ == 0) {
707 HILOG_ERROR("failed, error: the ability[%{public}s], app may fork fail or not running.",
708 ability->GetAbilityInfo().name.data());
709 return;
710 }
711 int typeId = AppExecFwk::AppfreezeManager::TypeAttribute::NORMAL_TIMEOUT;
712 std::string msgContent = "ability:" + ability->GetAbilityInfo().name + " ";
713 switch (msgId) {
714 case AbilityManagerService::LOAD_TIMEOUT_MSG:
715 msgContent += "load timeout";
716 typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
717 break;
718 case AbilityManagerService::FOREGROUND_TIMEOUT_MSG:
719 msgContent += "foreground timeout";
720 typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
721 break;
722 case AbilityManagerService::BACKGROUND_TIMEOUT_MSG:
723 msgContent += "background timeout";
724 break;
725 case AbilityManagerService::TERMINATE_TIMEOUT_MSG:
726 msgContent += "terminate timeout";
727 break;
728 default:
729 return;
730 }
731
732 std::string eventName = isHalf ?
733 AppExecFwk::AppFreezeType::LIFECYCLE_HALF_TIMEOUT : AppExecFwk::AppFreezeType::LIFECYCLE_TIMEOUT;
734 HILOG_WARN("%{public}s: uid: %{public}d, pid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
735 "msg: %{public}s", eventName.c_str(),
736 processInfo.uid_, processInfo.pid_, ability->GetAbilityInfo().bundleName.c_str(),
737 ability->GetAbilityInfo().name.c_str(), msgContent.c_str());
738
739 AppExecFwk::AppfreezeManager::GetInstance()->LifecycleTimeoutHandle(
740 typeId, processInfo.pid_, eventName, ability->GetAbilityInfo().bundleName, msgContent);
741 }
742
CompleteBackground(const std::shared_ptr<AbilityRecord> & abilityRecord)743 void UIAbilityLifecycleManager::CompleteBackground(const std::shared_ptr<AbilityRecord> &abilityRecord)
744 {
745 std::lock_guard<ffrt::mutex> guard(sessionLock_);
746 if (abilityRecord->GetAbilityState() != AbilityState::BACKGROUNDING) {
747 HILOG_ERROR("failed, ability state is %{public}d, it can't complete background.",
748 abilityRecord->GetAbilityState());
749 return;
750 }
751 abilityRecord->SetAbilityState(AbilityState::BACKGROUND);
752 // notify AppMS to update application state.
753 DelayedSingleton<AppScheduler>::GetInstance()->MoveToBackground(abilityRecord->GetToken());
754
755 if (abilityRecord->GetPendingState() == AbilityState::FOREGROUND) {
756 DelayedSingleton<AppScheduler>::GetInstance()->MoveToForeground(abilityRecord->GetToken());
757 } else if (abilityRecord->GetPendingState() == AbilityState::BACKGROUND) {
758 HILOG_DEBUG("not continuous startup.");
759 abilityRecord->SetPendingState(AbilityState::INITIAL);
760 }
761
762 // new version. started by caller, scheduler call request
763 if (abilityRecord->IsStartedByCall() && abilityRecord->IsStartToBackground() && abilityRecord->IsReady()) {
764 HILOG_DEBUG("call request after completing background state");
765 abilityRecord->CallRequest();
766 abilityRecord->SetStartToBackground(false);
767 }
768
769 // Abilities ahead of the one started were put in terminate list, we need to terminate them.
770 auto self(shared_from_this());
771 for (auto terminateAbility : terminateAbilityList_) {
772 if (terminateAbility->GetAbilityState() == AbilityState::BACKGROUND) {
773 auto timeoutTask = [terminateAbility, self]() {
774 HILOG_WARN("Terminate ability timeout after background.");
775 self->DelayCompleteTerminate(terminateAbility);
776 };
777 terminateAbility->Terminate(timeoutTask);
778 }
779 }
780 }
781
CloseUIAbility(const std::shared_ptr<AbilityRecord> & abilityRecord,int resultCode,const Want * resultWant)782 int UIAbilityLifecycleManager::CloseUIAbility(const std::shared_ptr<AbilityRecord> &abilityRecord,
783 int resultCode, const Want *resultWant)
784 {
785 HILOG_DEBUG("call");
786 std::lock_guard<ffrt::mutex> guard(sessionLock_);
787 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
788 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
789 std::string element = abilityRecord->GetWant().GetElement().GetURI();
790 HILOG_INFO("call, from ability: %{public}s", element.c_str());
791 if (abilityRecord->IsTerminating() && !abilityRecord->IsForeground()) {
792 HILOG_INFO("ability is on terminating");
793 return ERR_OK;
794 }
795
796 abilityRecord->SetTerminatingState();
797 // save result to caller AbilityRecord
798 if (resultWant != nullptr) {
799 abilityRecord->SaveResultToCallers(resultCode, resultWant);
800 } else {
801 Want want;
802 abilityRecord->SaveResultToCallers(-1, &want);
803 }
804
805 terminateAbilityList_.push_back(abilityRecord);
806 EraseAbilityRecord(abilityRecord);
807 abilityRecord->SendResultToCallers();
808
809 if (abilityRecord->IsAbilityState(FOREGROUND) || abilityRecord->IsAbilityState(FOREGROUNDING)) {
810 HILOG_DEBUG("current ability is active");
811 abilityRecord->SetPendingState(AbilityState::BACKGROUND);
812 MoveToBackground(abilityRecord);
813 return ERR_OK;
814 }
815
816 // ability on background, schedule to terminate.
817 if (abilityRecord->GetAbilityState() == AbilityState::BACKGROUND) {
818 auto self(shared_from_this());
819 auto task = [abilityRecord, self]() {
820 HILOG_WARN("close ability by scb timeout");
821 self->DelayCompleteTerminate(abilityRecord);
822 };
823 abilityRecord->Terminate(task);
824 }
825 return ERR_OK;
826 }
827
DelayCompleteTerminate(const std::shared_ptr<AbilityRecord> & abilityRecord)828 void UIAbilityLifecycleManager::DelayCompleteTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord)
829 {
830 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
831 CHECK_POINTER(handler);
832
833 PrintTimeOutLog(abilityRecord, AbilityManagerService::TERMINATE_TIMEOUT_MSG);
834
835 auto timeoutTask = [self = shared_from_this(), abilityRecord]() {
836 HILOG_INFO("emit delay complete terminate task.");
837 self->CompleteTerminate(abilityRecord);
838 };
839 int killTimeout = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * KILL_TIMEOUT_MULTIPLE;
840 handler->SubmitTask(timeoutTask, "DELAY_KILL_PROCESS", killTimeout);
841 }
842
CompleteTerminate(const std::shared_ptr<AbilityRecord> & abilityRecord)843 void UIAbilityLifecycleManager::CompleteTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord)
844 {
845 CHECK_POINTER(abilityRecord);
846 std::lock_guard<ffrt::mutex> guard(sessionLock_);
847 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
848
849 if (abilityRecord->GetAbilityState() != AbilityState::TERMINATING) {
850 HILOG_ERROR("failed, %{public}s, ability is not terminating.", __func__);
851 return;
852 }
853 abilityRecord->RemoveAbilityDeathRecipient();
854
855 // notify AppMS terminate
856 if (abilityRecord->TerminateAbility() != ERR_OK) {
857 // Don't return here
858 HILOG_ERROR("AppMS fail to terminate ability.");
859 }
860 abilityRecord->RevokeUriPermission();
861 EraseSpecifiedAbilityRecord(abilityRecord);
862 terminateAbilityList_.remove(abilityRecord);
863 }
864
GetPersistentIdByAbilityRequest(const AbilityRequest & abilityRequest,bool & reuse,int32_t userId) const865 int32_t UIAbilityLifecycleManager::GetPersistentIdByAbilityRequest(const AbilityRequest &abilityRequest,
866 bool &reuse, int32_t userId) const
867 {
868 if (abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::SPECIFIED) {
869 return GetReusedSpecifiedPersistentId(abilityRequest, reuse, userId);
870 }
871
872 if (abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::STANDARD) {
873 return GetReusedStandardPersistentId(abilityRequest, reuse, userId);
874 }
875
876 if (abilityRequest.abilityInfo.launchMode != AppExecFwk::LaunchMode::SINGLETON) {
877 HILOG_WARN("Launch mode is not singleton.");
878 return 0;
879 }
880
881 reuse = true;
882 for (const auto& [first, second] : sessionAbilityMap_) {
883 if (CheckProperties(second, abilityRequest, AppExecFwk::LaunchMode::SINGLETON, userId)) {
884 HILOG_DEBUG("SINGLETON: find.");
885 return first;
886 }
887 }
888
889 HILOG_DEBUG("Not find existed ui ability.");
890 return 0;
891 }
892
GetReusedSpecifiedPersistentId(const AbilityRequest & abilityRequest,bool & reuse,int32_t userId) const893 int32_t UIAbilityLifecycleManager::GetReusedSpecifiedPersistentId(const AbilityRequest &abilityRequest,
894 bool &reuse, int32_t userId) const
895 {
896 HILOG_DEBUG("Call.");
897 if (abilityRequest.abilityInfo.launchMode != AppExecFwk::LaunchMode::SPECIFIED) {
898 HILOG_WARN("Not SPECIFIED.");
899 return 0;
900 }
901
902 reuse = true;
903 // specified ability name and bundle name and module name and appIndex format is same as singleton.
904 for (const auto& [first, second] : sessionAbilityMap_) {
905 if (second->GetSpecifiedFlag() == abilityRequest.specifiedFlag &&
906 CheckProperties(second, abilityRequest, AppExecFwk::LaunchMode::SPECIFIED, userId)) {
907 HILOG_DEBUG("SPECIFIED: find.");
908 return first;
909 }
910 }
911 return 0;
912 }
913
GetReusedStandardPersistentId(const AbilityRequest & abilityRequest,bool & reuse,int32_t userId) const914 int32_t UIAbilityLifecycleManager::GetReusedStandardPersistentId(const AbilityRequest &abilityRequest,
915 bool &reuse, int32_t userId) const
916 {
917 HILOG_DEBUG("Call.");
918 if (abilityRequest.abilityInfo.launchMode != AppExecFwk::LaunchMode::STANDARD) {
919 HILOG_WARN("Not STANDARD.");
920 return 0;
921 }
922
923 if (!abilityRequest.startRecent) {
924 HILOG_WARN("startRecent is false.");
925 return 0;
926 }
927
928 reuse = true;
929 int64_t sessionTime = 0;
930 int32_t persistentId = 0;
931 for (const auto& [first, second] : sessionAbilityMap_) {
932 if (CheckProperties(second, abilityRequest, AppExecFwk::LaunchMode::STANDARD, userId) &&
933 second->GetRestartTime() >= sessionTime) {
934 persistentId = first;
935 sessionTime = second->GetRestartTime();
936 }
937 }
938 return persistentId;
939 }
940
CheckProperties(const std::shared_ptr<AbilityRecord> & abilityRecord,const AbilityRequest & abilityRequest,AppExecFwk::LaunchMode launchMode,int32_t userId) const941 bool UIAbilityLifecycleManager::CheckProperties(const std::shared_ptr<AbilityRecord> &abilityRecord,
942 const AbilityRequest &abilityRequest, AppExecFwk::LaunchMode launchMode, int32_t userId) const
943 {
944 if (userId != abilityRecord->GetOwnerMissionUserId()) {
945 HILOG_WARN("userId: %{public}d, ability's userId: %{public}d", userId, abilityRecord->GetOwnerMissionUserId());
946 return false;
947 }
948 const auto& abilityInfo = abilityRecord->GetAbilityInfo();
949 return abilityInfo.launchMode == launchMode && abilityRequest.abilityInfo.name == abilityInfo.name &&
950 abilityRequest.abilityInfo.bundleName == abilityInfo.bundleName &&
951 abilityRequest.abilityInfo.moduleName == abilityInfo.moduleName &&
952 abilityRequest.want.GetIntParam(DLP_INDEX, 0) == abilityRecord->GetAppIndex();
953 }
954
ReportEventToSuspendManager(const AppExecFwk::AbilityInfo & abilityInfo) const955 void UIAbilityLifecycleManager::ReportEventToSuspendManager(const AppExecFwk::AbilityInfo &abilityInfo) const
956 {
957 #ifdef EFFICIENCY_MANAGER_ENABLE
958 #endif // EFFICIENCY_MANAGER_ENABLE
959 }
960
OnTimeOut(uint32_t msgId,int64_t abilityRecordId,bool isHalf)961 void UIAbilityLifecycleManager::OnTimeOut(uint32_t msgId, int64_t abilityRecordId, bool isHalf)
962 {
963 HILOG_DEBUG("call, msgId is %{public}d", msgId);
964 std::lock_guard<ffrt::mutex> guard(sessionLock_);
965 std::shared_ptr<AbilityRecord> abilityRecord;
966 for (auto iter = sessionAbilityMap_.begin(); iter != sessionAbilityMap_.end(); iter++) {
967 if (iter->second != nullptr && iter->second->GetAbilityRecordId() == abilityRecordId) {
968 abilityRecord = iter->second;
969 break;
970 }
971 }
972 if (abilityRecord == nullptr) {
973 HILOG_ERROR("failed, ability record is nullptr");
974 return;
975 }
976 HILOG_DEBUG("call, msgId:%{public}d, name:%{public}s", msgId, abilityRecord->GetAbilityInfo().name.c_str());
977 abilityRecord->RevokeUriPermission();
978 PrintTimeOutLog(abilityRecord, msgId, isHalf);
979 if (isHalf) {
980 return;
981 }
982 switch (msgId) {
983 case AbilityManagerService::LOAD_TIMEOUT_MSG:
984 HandleLoadTimeout(abilityRecord);
985 break;
986 case AbilityManagerService::FOREGROUND_TIMEOUT_MSG:
987 HandleForegroundTimeout(abilityRecord);
988 break;
989 default:
990 break;
991 }
992 }
993
SetRootSceneSession(const sptr<IRemoteObject> & rootSceneSession)994 void UIAbilityLifecycleManager::SetRootSceneSession(const sptr<IRemoteObject> &rootSceneSession)
995 {
996 HILOG_DEBUG("call");
997 if (rootSceneSession == nullptr) {
998 HILOG_ERROR("rootSceneSession is invalid.");
999 return;
1000 }
1001 auto tmpSceneSession = iface_cast<Rosen::ISession>(rootSceneSession);
1002 auto descriptor = Str16ToStr8(tmpSceneSession->GetDescriptor());
1003 if (descriptor != "OHOS.ISession") {
1004 HILOG_ERROR("token's Descriptor: %{public}s", descriptor.c_str());
1005 return;
1006 }
1007 rootSceneSession_ = tmpSceneSession;
1008 }
1009
NotifySCBToHandleException(const std::shared_ptr<AbilityRecord> & abilityRecord,int32_t errorCode,std::string errorReason)1010 void UIAbilityLifecycleManager::NotifySCBToHandleException(const std::shared_ptr<AbilityRecord> &abilityRecord,
1011 int32_t errorCode, std::string errorReason)
1012 {
1013 HILOG_DEBUG("call");
1014 if (abilityRecord == nullptr) {
1015 HILOG_ERROR("ability record is nullptr");
1016 return;
1017 }
1018 auto callerSessionInfo = abilityRecord->GetSessionInfo();
1019 CHECK_POINTER(callerSessionInfo);
1020 CHECK_POINTER(callerSessionInfo->sessionToken);
1021 auto callerSession = iface_cast<Rosen::ISession>(callerSessionInfo->sessionToken);
1022 HILOG_INFO("call notifySessionException");
1023 sptr<SessionInfo> info = abilityRecord->GetSessionInfo();
1024 info->errorCode = errorCode;
1025 info->errorReason = errorReason;
1026 callerSession->NotifySessionException(info);
1027 EraseAbilityRecord(abilityRecord);
1028 }
1029
HandleLoadTimeout(const std::shared_ptr<AbilityRecord> & abilityRecord)1030 void UIAbilityLifecycleManager::HandleLoadTimeout(const std::shared_ptr<AbilityRecord> &abilityRecord)
1031 {
1032 HILOG_DEBUG("call");
1033 if (abilityRecord == nullptr) {
1034 HILOG_ERROR("failed, ability record is nullptr");
1035 return;
1036 }
1037 NotifySCBToHandleException(abilityRecord,
1038 static_cast<int32_t>(ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT), "handleLoadTimeout");
1039 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
1040 }
1041
HandleForegroundTimeout(const std::shared_ptr<AbilityRecord> & abilityRecord)1042 void UIAbilityLifecycleManager::HandleForegroundTimeout(const std::shared_ptr<AbilityRecord> &abilityRecord)
1043 {
1044 HILOG_DEBUG("call");
1045 if (abilityRecord == nullptr) {
1046 HILOG_ERROR("ability record is nullptr");
1047 return;
1048 }
1049 if (!abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING)) {
1050 HILOG_ERROR("this ability is not foregrounding state");
1051 return;
1052 }
1053 NotifySCBToHandleException(abilityRecord,
1054 static_cast<int32_t>(ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT), "handleForegroundTimeout");
1055 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
1056 EraseSpecifiedAbilityRecord(abilityRecord);
1057 }
1058
OnAbilityDied(std::shared_ptr<AbilityRecord> abilityRecord)1059 void UIAbilityLifecycleManager::OnAbilityDied(std::shared_ptr<AbilityRecord> abilityRecord)
1060 {
1061 HILOG_DEBUG("call");
1062 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1063 if (abilityRecord == nullptr) {
1064 HILOG_ERROR("failed, ability record is nullptr");
1065 return;
1066 }
1067 terminateAbilityList_.push_back(abilityRecord);
1068 abilityRecord->SetAbilityState(AbilityState::TERMINATING);
1069 NotifySCBToHandleException(abilityRecord, static_cast<int32_t>(ErrorLifecycleState::ABILITY_STATE_DIED),
1070 "onAbilityDied");
1071 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
1072 DispatchTerminate(abilityRecord);
1073 EraseSpecifiedAbilityRecord(abilityRecord);
1074 }
1075
OnAcceptWantResponse(const AAFwk::Want & want,const std::string & flag)1076 void UIAbilityLifecycleManager::OnAcceptWantResponse(const AAFwk::Want &want, const std::string &flag)
1077 {
1078 HILOG_DEBUG("call");
1079 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1080 if (abilityQueue_.empty()) {
1081 return;
1082 }
1083
1084 AbilityRequest abilityRequest = abilityQueue_.front();
1085 abilityQueue_.pop();
1086 if (abilityRequest.abilityInfo.launchMode != AppExecFwk::LaunchMode::SPECIFIED) {
1087 return;
1088 }
1089 auto callerAbility = GetAbilityRecordByToken(abilityRequest.callerToken);
1090 if (!flag.empty()) {
1091 abilityRequest.specifiedFlag = flag;
1092 bool reuse = false;
1093 auto currentAccountId = DelayedSingleton<AbilityManagerService>::GetInstance()->GetUserId();
1094 auto persistentId = GetReusedSpecifiedPersistentId(abilityRequest, reuse, currentAccountId);
1095 if (persistentId != 0) {
1096 auto abilityRecord = GetReusedSpecifiedAbility(want, flag);
1097 if (!abilityRecord) {
1098 return;
1099 }
1100 abilityRecord->SetWant(abilityRequest.want);
1101 abilityRecord->SetIsNewWant(true);
1102 UpdateAbilityRecordLaunchReason(abilityRequest, abilityRecord);
1103 if (callerAbility == nullptr) {
1104 callerAbility = Token::GetAbilityRecordByToken(abilityRequest.callerToken);
1105 }
1106 MoveAbilityToFront(abilityRequest, abilityRecord, callerAbility);
1107 NotifyRestartSpecifiedAbility(abilityRequest, abilityRecord->GetToken());
1108 return;
1109 }
1110 }
1111 NotifyStartSpecifiedAbility(abilityRequest, want);
1112 StartAbilityBySpecifed(abilityRequest, callerAbility);
1113 }
1114
StartSpecifiedAbilityBySCB(const Want & want,int32_t userId)1115 void UIAbilityLifecycleManager::StartSpecifiedAbilityBySCB(const Want &want, int32_t userId)
1116 {
1117 HILOG_DEBUG("call");
1118 AbilityRequest abilityRequest;
1119 int result = DelayedSingleton<AbilityManagerService>::GetInstance()->GenerateAbilityRequest(
1120 want, DEFAULT_INVAL_VALUE, abilityRequest, nullptr, userId);
1121 if (result != ERR_OK) {
1122 HILOG_ERROR("cannot find generate ability request");
1123 return;
1124 }
1125 {
1126 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1127 EnqueueAbilityToFront(abilityRequest);
1128 }
1129 DelayedSingleton<AppScheduler>::GetInstance()->StartSpecifiedAbility(
1130 abilityRequest.want, abilityRequest.abilityInfo);
1131 }
1132
GetReusedSpecifiedAbility(const AAFwk::Want & want,const std::string & flag)1133 std::shared_ptr<AbilityRecord> UIAbilityLifecycleManager::GetReusedSpecifiedAbility(const AAFwk::Want &want,
1134 const std::string &flag)
1135 {
1136 auto element = want.GetElement();
1137 for (const auto& [first, second] : specifiedAbilityMap_) {
1138 if (flag == first.flag && element.GetAbilityName() == first.abilityName &&
1139 element.GetBundleName() == first.bundleName) {
1140 return second;
1141 }
1142 }
1143 return nullptr;
1144 }
1145
EnqueueAbilityToFront(const AbilityRequest & abilityRequest)1146 void UIAbilityLifecycleManager::EnqueueAbilityToFront(const AbilityRequest &abilityRequest)
1147 {
1148 abilityQueue_.push(abilityRequest);
1149 }
1150
NotifyRestartSpecifiedAbility(AbilityRequest & request,const sptr<IRemoteObject> & token)1151 void UIAbilityLifecycleManager::NotifyRestartSpecifiedAbility(AbilityRequest &request,
1152 const sptr<IRemoteObject> &token)
1153 {
1154 if (request.abilityInfoCallback == nullptr) {
1155 return;
1156 }
1157 sptr<AppExecFwk::IAbilityInfoCallback> abilityInfoCallback
1158 = iface_cast<AppExecFwk::IAbilityInfoCallback> (request.abilityInfoCallback);
1159 if (abilityInfoCallback != nullptr) {
1160 HILOG_DEBUG("%{public}s called.", __func__);
1161 abilityInfoCallback->NotifyRestartSpecifiedAbility(token);
1162 }
1163 }
1164
NotifyStartSpecifiedAbility(AbilityRequest & abilityRequest,const AAFwk::Want & want)1165 void UIAbilityLifecycleManager::NotifyStartSpecifiedAbility(AbilityRequest &abilityRequest, const AAFwk::Want &want)
1166 {
1167 if (abilityRequest.abilityInfoCallback == nullptr) {
1168 return;
1169 }
1170
1171 sptr<AppExecFwk::IAbilityInfoCallback> abilityInfoCallback
1172 = iface_cast<AppExecFwk::IAbilityInfoCallback> (abilityRequest.abilityInfoCallback);
1173 if (abilityInfoCallback != nullptr) {
1174 Want newWant = want;
1175 int32_t type = static_cast<int32_t>(abilityRequest.abilityInfo.type);
1176 newWant.SetParam("abilityType", type);
1177 sptr<Want> extraParam = new (std::nothrow) Want();
1178 abilityInfoCallback->NotifyStartSpecifiedAbility(abilityRequest.callerToken, newWant,
1179 abilityRequest.requestCode, extraParam);
1180 int32_t procCode = extraParam->GetIntParam(Want::PARAM_RESV_REQUEST_PROC_CODE, 0);
1181 if (procCode != 0) {
1182 abilityRequest.want.SetParam(Want::PARAM_RESV_REQUEST_PROC_CODE, procCode);
1183 }
1184 int32_t tokenCode = extraParam->GetIntParam(Want::PARAM_RESV_REQUEST_TOKEN_CODE, 0);
1185 if (tokenCode != 0) {
1186 abilityRequest.want.SetParam(Want::PARAM_RESV_REQUEST_TOKEN_CODE, tokenCode);
1187 }
1188 }
1189 }
1190
MoveAbilityToFront(const AbilityRequest & abilityRequest,const std::shared_ptr<AbilityRecord> & abilityRecord,std::shared_ptr<AbilityRecord> callerAbility,std::shared_ptr<StartOptions> startOptions)1191 int UIAbilityLifecycleManager::MoveAbilityToFront(const AbilityRequest &abilityRequest,
1192 const std::shared_ptr<AbilityRecord> &abilityRecord, std::shared_ptr<AbilityRecord> callerAbility,
1193 std::shared_ptr<StartOptions> startOptions)
1194 {
1195 HILOG_DEBUG("call");
1196 if (!abilityRecord) {
1197 HILOG_ERROR("get target ability record failed");
1198 return ERR_INVALID_VALUE;
1199 }
1200 sptr<SessionInfo> sessionInfo = abilityRecord->GetSessionInfo();
1201 sessionInfo->want = abilityRequest.want;
1202 SendSessionInfoToSCB(callerAbility, sessionInfo);
1203 abilityRecord->RemoveWindowMode();
1204 if (startOptions != nullptr) {
1205 abilityRecord->SetWindowMode(startOptions->GetWindowMode());
1206 }
1207 return ERR_OK;
1208 }
1209
SendSessionInfoToSCB(std::shared_ptr<AbilityRecord> & callerAbility,sptr<SessionInfo> & sessionInfo)1210 int UIAbilityLifecycleManager::SendSessionInfoToSCB(std::shared_ptr<AbilityRecord> &callerAbility,
1211 sptr<SessionInfo> &sessionInfo)
1212 {
1213 HILOG_DEBUG("call");
1214 if (callerAbility != nullptr) {
1215 auto callerSessionInfo = callerAbility->GetSessionInfo();
1216 if (callerSessionInfo != nullptr && callerSessionInfo->sessionToken != nullptr) {
1217 auto callerSession = iface_cast<Rosen::ISession>(callerSessionInfo->sessionToken);
1218 callerSession->PendingSessionActivation(sessionInfo);
1219 } else {
1220 CHECK_POINTER_AND_RETURN(rootSceneSession_, ERR_INVALID_VALUE);
1221 rootSceneSession_->PendingSessionActivation(sessionInfo);
1222 }
1223 } else {
1224 CHECK_POINTER_AND_RETURN(rootSceneSession_, ERR_INVALID_VALUE);
1225 rootSceneSession_->PendingSessionActivation(sessionInfo);
1226 }
1227 return ERR_OK;
1228 }
1229
StartAbilityBySpecifed(const AbilityRequest & abilityRequest,std::shared_ptr<AbilityRecord> & callerAbility)1230 int UIAbilityLifecycleManager::StartAbilityBySpecifed(const AbilityRequest &abilityRequest,
1231 std::shared_ptr<AbilityRecord> &callerAbility)
1232 {
1233 HILOG_DEBUG("call");
1234 sptr<SessionInfo> sessionInfo = new SessionInfo();
1235 sessionInfo->callerToken = abilityRequest.callerToken;
1236 sessionInfo->want = abilityRequest.want;
1237 sessionInfo->requestCode = abilityRequest.requestCode;
1238 SpecifiedInfo specifiedInfo;
1239 specifiedInfo.abilityName = abilityRequest.abilityInfo.name;
1240 specifiedInfo.bundleName = abilityRequest.abilityInfo.bundleName;
1241 specifiedInfo.flag = abilityRequest.specifiedFlag;
1242 specifiedInfoQueue_.push(specifiedInfo);
1243
1244 SendSessionInfoToSCB(callerAbility, sessionInfo);
1245 return ERR_OK;
1246 }
1247
CallRequestDone(const std::shared_ptr<AbilityRecord> & abilityRecord,const sptr<IRemoteObject> & callStub)1248 void UIAbilityLifecycleManager::CallRequestDone(const std::shared_ptr<AbilityRecord> &abilityRecord,
1249 const sptr<IRemoteObject> &callStub)
1250 {
1251 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1252 if (abilityRecord == nullptr) {
1253 HILOG_ERROR("ability record is null.");
1254 return;
1255 }
1256 if (callStub == nullptr) {
1257 HILOG_ERROR("call stub is null.");
1258 return;
1259 }
1260 abilityRecord->CallRequestDone(callStub);
1261 }
1262
ReleaseCallLocked(const sptr<IAbilityConnection> & connect,const AppExecFwk::ElementName & element)1263 int UIAbilityLifecycleManager::ReleaseCallLocked(
1264 const sptr<IAbilityConnection> &connect, const AppExecFwk::ElementName &element)
1265 {
1266 HILOG_DEBUG("release call ability.");
1267
1268 CHECK_POINTER_AND_RETURN(connect, ERR_INVALID_VALUE);
1269 CHECK_POINTER_AND_RETURN(connect->AsObject(), ERR_INVALID_VALUE);
1270
1271 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1272
1273 auto abilityRecords = GetAbilityRecordsByName(element);
1274 auto isExist = [connect] (const std::shared_ptr<AbilityRecord> &abilityRecord) {
1275 return abilityRecord->IsExistConnection(connect);
1276 };
1277 auto findRecord = std::find_if(abilityRecords.begin(), abilityRecords.end(), isExist);
1278 if (findRecord == abilityRecords.end()) {
1279 HILOG_ERROR("not found ability record by callback");
1280 return RELEASE_CALL_ABILITY_INNER_ERR;
1281 }
1282 auto abilityRecord = *findRecord;
1283 CHECK_POINTER_AND_RETURN(abilityRecord, RELEASE_CALL_ABILITY_INNER_ERR);
1284
1285 if (!abilityRecord->ReleaseCall(connect)) {
1286 HILOG_ERROR("ability release call record failed.");
1287 return RELEASE_CALL_ABILITY_INNER_ERR;
1288 }
1289 return ERR_OK;
1290 }
1291
OnCallConnectDied(const std::shared_ptr<CallRecord> & callRecord)1292 void UIAbilityLifecycleManager::OnCallConnectDied(const std::shared_ptr<CallRecord> &callRecord)
1293 {
1294 HILOG_INFO("On callConnect died.");
1295 CHECK_POINTER(callRecord);
1296 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1297
1298 AppExecFwk::ElementName element = callRecord->GetTargetServiceName();
1299 auto abilityRecords = GetAbilityRecordsByName(element);
1300 auto isExist = [callRecord] (const std::shared_ptr<AbilityRecord> &abilityRecord) {
1301 return abilityRecord->IsExistConnection(callRecord->GetConCallBack());
1302 };
1303 auto findRecord = std::find_if(abilityRecords.begin(), abilityRecords.end(), isExist);
1304 if (findRecord == abilityRecords.end()) {
1305 HILOG_ERROR("not found ability record by callback");
1306 return;
1307 }
1308 auto abilityRecord = *findRecord;
1309 CHECK_POINTER(abilityRecord);
1310 abilityRecord->ReleaseCall(callRecord->GetConCallBack());
1311 }
1312
GetAbilityRecordsByName(const AppExecFwk::ElementName & element)1313 std::vector<std::shared_ptr<AbilityRecord>> UIAbilityLifecycleManager::GetAbilityRecordsByName(
1314 const AppExecFwk::ElementName &element)
1315 {
1316 std::vector<std::shared_ptr<AbilityRecord>> records;
1317 for (const auto& [first, second] : sessionAbilityMap_) {
1318 auto &abilityInfo = second->GetAbilityInfo();
1319 AppExecFwk::ElementName localElement(abilityInfo.deviceId, abilityInfo.bundleName,
1320 abilityInfo.name, abilityInfo.moduleName);
1321 AppExecFwk::ElementName localElementNoModuleName(abilityInfo.deviceId,
1322 abilityInfo.bundleName, abilityInfo.name);
1323 if (localElement == element || localElementNoModuleName == element) {
1324 HILOG_DEBUG("find element %{public}s", localElement.GetURI().c_str());
1325 records.push_back(second);
1326 }
1327 }
1328 return records;
1329 }
1330
GetSessionIdByAbilityToken(const sptr<IRemoteObject> & token)1331 int32_t UIAbilityLifecycleManager::GetSessionIdByAbilityToken(const sptr<IRemoteObject> &token)
1332 {
1333 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1334 for (const auto& [first, second] : sessionAbilityMap_) {
1335 if (second && second->GetToken()->AsObject() == token) {
1336 return first;
1337 }
1338 }
1339 HILOG_ERROR("not find");
1340 return 0;
1341 }
1342
GetActiveAbilityList(const std::string & bundleName,std::vector<std::string> & abilityList)1343 void UIAbilityLifecycleManager::GetActiveAbilityList(const std::string &bundleName,
1344 std::vector<std::string> &abilityList)
1345 {
1346 auto currentAccountId = DelayedSingleton<AbilityManagerService>::GetInstance()->GetUserId();
1347 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1348 for (const auto& [first, second] : sessionAbilityMap_) {
1349 if (second->GetOwnerMissionUserId() == currentAccountId) {
1350 const auto &abilityInfo = second->GetAbilityInfo();
1351 if (abilityInfo.bundleName == bundleName && !abilityInfo.name.empty()) {
1352 HILOG_DEBUG("find ability name is %{public}s", abilityInfo.name.c_str());
1353 abilityList.push_back(abilityInfo.name);
1354 }
1355 }
1356 }
1357 }
1358
SetRevicerInfo(const AbilityRequest & abilityRequest,std::shared_ptr<AbilityRecord> & abilityRecord) const1359 void UIAbilityLifecycleManager::SetRevicerInfo(const AbilityRequest &abilityRequest,
1360 std::shared_ptr<AbilityRecord> &abilityRecord) const
1361 {
1362 const auto &abilityInfo = abilityRequest.abilityInfo;
1363 auto isStandard = abilityInfo.launchMode == AppExecFwk::LaunchMode::STANDARD && !abilityRequest.startRecent;
1364 if (!isStandard) {
1365 bool hasRecoverInfo = false;
1366 (void)DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
1367 GetAbilityRecoverInfo(abilityInfo.bundleName, abilityInfo.moduleName, abilityInfo.name, hasRecoverInfo);
1368 abilityRecord->UpdateRecoveryInfo(hasRecoverInfo);
1369 (void)DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
1370 DeleteAbilityRecoverInfo(abilityInfo.bundleName, abilityInfo.moduleName, abilityInfo.name);
1371 }
1372 }
1373
SetLastExitReason(std::shared_ptr<AbilityRecord> & abilityRecord) const1374 void UIAbilityLifecycleManager::SetLastExitReason(std::shared_ptr<AbilityRecord> &abilityRecord) const
1375 {
1376 if (abilityRecord == nullptr) {
1377 HILOG_ERROR("abilityRecord is nullptr.");
1378 return;
1379 }
1380
1381 if (abilityRecord->GetAbilityInfo().bundleName.empty()) {
1382 HILOG_ERROR("bundleName is empty.");
1383 return;
1384 }
1385
1386 Reason exitReason;
1387 bool isSetReason;
1388 DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->GetAppExitReason(
1389 abilityRecord->GetAbilityInfo().bundleName, abilityRecord->GetAbilityInfo().name, isSetReason, exitReason);
1390
1391 if (isSetReason) {
1392 abilityRecord->SetLastExitReason(CovertAppExitReasonToLastReason(exitReason));
1393 }
1394 }
1395
CovertAppExitReasonToLastReason(const Reason exitReason) const1396 LastExitReason UIAbilityLifecycleManager::CovertAppExitReasonToLastReason(const Reason exitReason) const
1397 {
1398 switch (exitReason) {
1399 case REASON_NORMAL:
1400 return LASTEXITREASON_NORMAL;
1401 case REASON_CPP_CRASH:
1402 return LASTEXITREASON_CPP_CRASH;
1403 case REASON_JS_ERROR:
1404 return LASTEXITREASON_JS_ERROR;
1405 case REASON_APP_FREEZE:
1406 return LASTEXITREASON_APP_FREEZE;
1407 case REASON_PERFORMANCE_CONTROL:
1408 return LASTEXITREASON_PERFORMANCE_CONTROL;
1409 case REASON_RESOURCE_CONTROL:
1410 return LASTEXITREASON_RESOURCE_CONTROL;
1411 case REASON_UPGRADE:
1412 return LASTEXITREASON_UPGRADE;
1413 case REASON_UNKNOWN:
1414 default:
1415 return LASTEXITREASON_UNKNOWN;
1416 }
1417 }
1418
PrepareTerminateAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)1419 bool UIAbilityLifecycleManager::PrepareTerminateAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
1420 {
1421 HILOG_DEBUG("call");
1422 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1423 if (abilityRecord == nullptr) {
1424 HILOG_ERROR("ability record is null");
1425 return false;
1426 }
1427 HILOG_INFO("abilityInfoName:%{public}s", abilityRecord->GetAbilityInfo().name.c_str());
1428 if (!CheckPrepareTerminateEnable(abilityRecord)) {
1429 HILOG_DEBUG("Not support prepare terminate.");
1430 return false;
1431 }
1432 // execute onPrepareToTerminate util timeout
1433 auto taskHandler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
1434 if (taskHandler == nullptr) {
1435 HILOG_ERROR("Fail to get AbilityTaskHandler.");
1436 return false;
1437 }
1438 auto promise = std::make_shared<std::promise<bool>>();
1439 auto future = promise->get_future();
1440 auto task = [promise, abilityRecord]() {
1441 promise->set_value(abilityRecord->PrepareTerminateAbility());
1442 };
1443 taskHandler->SubmitTask(task);
1444 int prepareTerminateTimeout =
1445 AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * PREPARE_TERMINATE_TIMEOUT_MULTIPLE;
1446 std::future_status status = future.wait_for(std::chrono::milliseconds(prepareTerminateTimeout));
1447 if (status == std::future_status::timeout) {
1448 HILOG_ERROR("onPrepareToTerminate timeout.");
1449 return false;
1450 }
1451 return future.get();
1452 }
1453
CheckPrepareTerminateEnable(const std::shared_ptr<AbilityRecord> & abilityRecord)1454 bool UIAbilityLifecycleManager::CheckPrepareTerminateEnable(const std::shared_ptr<AbilityRecord> &abilityRecord)
1455 {
1456 if (abilityRecord == nullptr || abilityRecord->IsTerminating()) {
1457 HILOG_DEBUG("Ability record is not exist or is on terminating.");
1458 return false;
1459 }
1460 auto type = abilityRecord->GetAbilityInfo().type;
1461 bool isStageBasedModel = abilityRecord->GetAbilityInfo().isStageBasedModel;
1462 if (!isStageBasedModel || type != AppExecFwk::AbilityType::PAGE) {
1463 HILOG_DEBUG("ability mode not support.");
1464 return false;
1465 }
1466 auto tokenId = abilityRecord->GetApplicationInfo().accessTokenId;
1467 if (!AAFwk::PermissionVerification::GetInstance()->VerifyPrepareTerminatePermission(tokenId)) {
1468 HILOG_DEBUG("failed, please apply permission ohos.permission.PREPARE_APP_TERMINATE");
1469 return false;
1470 }
1471 return true;
1472 }
1473
SetSessionHandler(const sptr<ISessionHandler> & handler)1474 void UIAbilityLifecycleManager::SetSessionHandler(const sptr<ISessionHandler> &handler)
1475 {
1476 handler_ = handler;
1477 }
1478
GetAbilityRecordsById(int32_t sessionId) const1479 std::shared_ptr<AbilityRecord> UIAbilityLifecycleManager::GetAbilityRecordsById(int32_t sessionId) const
1480 {
1481 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1482 auto search = sessionAbilityMap_.find(sessionId);
1483 if (search == sessionAbilityMap_.end()) {
1484 HILOG_INFO("sessionId is invalid.");
1485 return nullptr;
1486 }
1487 return search->second;
1488 }
1489
GetActiveAbilityList(const std::string & bundleName,std::vector<std::string> & abilityList,int32_t targetUserId) const1490 void UIAbilityLifecycleManager::GetActiveAbilityList(const std::string &bundleName,
1491 std::vector<std::string> &abilityList, int32_t targetUserId) const
1492 {
1493 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1494 HILOG_INFO("Call.");
1495 for (const auto& [sessionId, abilityRecord] : sessionAbilityMap_) {
1496 if (abilityRecord == nullptr) {
1497 HILOG_WARN("second is nullptr.");
1498 continue;
1499 }
1500 const auto &abilityInfo = abilityRecord->GetAbilityInfo();
1501 if (abilityInfo.bundleName == bundleName && !abilityInfo.name.empty() &&
1502 (targetUserId == DEFAULT_USER_ID || abilityRecord->GetOwnerMissionUserId() == targetUserId)) {
1503 HILOG_DEBUG("find ability name is %{public}s", abilityInfo.name.c_str());
1504 abilityList.push_back(abilityInfo.name);
1505 }
1506 }
1507 if (!abilityList.empty()) {
1508 sort(abilityList.begin(), abilityList.end());
1509 abilityList.erase(unique(abilityList.begin(), abilityList.end()), abilityList.end());
1510 }
1511 }
1512
OnAppStateChanged(const AppInfo & info,int32_t targetUserId)1513 void UIAbilityLifecycleManager::OnAppStateChanged(const AppInfo &info, int32_t targetUserId)
1514 {
1515 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1516 HILOG_INFO("Call.");
1517 if (info.state == AppState::TERMINATED || info.state == AppState::END) {
1518 for (const auto& abilityRecord : terminateAbilityList_) {
1519 if (abilityRecord == nullptr) {
1520 HILOG_WARN("abilityRecord is nullptr.");
1521 continue;
1522 }
1523 if ((info.processName == abilityRecord->GetAbilityInfo().process ||
1524 info.processName == abilityRecord->GetApplicationInfo().bundleName) &&
1525 targetUserId == abilityRecord->GetOwnerMissionUserId()) {
1526 abilityRecord->SetAppState(info.state);
1527 }
1528 }
1529 return;
1530 }
1531 for (const auto& [sessionId, abilityRecord] : sessionAbilityMap_) {
1532 if (abilityRecord == nullptr) {
1533 HILOG_WARN("abilityRecord is nullptr.");
1534 continue;
1535 }
1536 if ((info.processName == abilityRecord->GetAbilityInfo().process ||
1537 info.processName == abilityRecord->GetApplicationInfo().bundleName) &&
1538 targetUserId == abilityRecord->GetOwnerMissionUserId()) {
1539 abilityRecord->SetAppState(info.state);
1540 }
1541 }
1542 }
1543
UninstallApp(const std::string & bundleName,int32_t uid,int32_t targetUserId)1544 void UIAbilityLifecycleManager::UninstallApp(const std::string &bundleName, int32_t uid, int32_t targetUserId)
1545 {
1546 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1547 HILOG_INFO("Call.");
1548 for (auto it = sessionAbilityMap_.begin(); it != sessionAbilityMap_.end();) {
1549 if (it->second == nullptr) {
1550 it++;
1551 continue;
1552 }
1553 auto &abilityInfo = it->second->GetAbilityInfo();
1554 if (abilityInfo.bundleName == bundleName && it->second->GetUid() == uid &&
1555 (targetUserId == DEFAULT_USER_ID || it->second->GetOwnerMissionUserId() == targetUserId)) {
1556 (void)DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
1557 DeleteAbilityRecoverInfo(abilityInfo.bundleName, abilityInfo.moduleName, abilityInfo.name);
1558 sessionAbilityMap_.erase(it++);
1559 continue;
1560 }
1561 it++;
1562 }
1563 }
1564
GetAbilityRunningInfos(std::vector<AbilityRunningInfo> & info,bool isPerm,int32_t userId) const1565 void UIAbilityLifecycleManager::GetAbilityRunningInfos(std::vector<AbilityRunningInfo> &info, bool isPerm,
1566 int32_t userId) const
1567 {
1568 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1569 HILOG_DEBUG("Call.");
1570 for (auto [sessionId, abilityRecord] : sessionAbilityMap_) {
1571 if (abilityRecord == nullptr || userId != abilityRecord->GetOwnerMissionUserId()) {
1572 HILOG_WARN("abilityRecord is nullptr.");
1573 continue;
1574 }
1575 if (isPerm) {
1576 DelayedSingleton<AbilityManagerService>::GetInstance()->GetAbilityRunningInfo(info, abilityRecord);
1577 } else {
1578 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
1579 auto tokenID = abilityRecord->GetApplicationInfo().accessTokenId;
1580 if (callingTokenId == tokenID) {
1581 DelayedSingleton<AbilityManagerService>::GetInstance()->GetAbilityRunningInfo(info, abilityRecord);
1582 }
1583 }
1584 }
1585 }
1586
1587 #ifdef ABILITY_COMMAND_FOR_TEST
BlockAbility(int32_t abilityRecordId,int32_t targetUserId) const1588 int UIAbilityLifecycleManager::BlockAbility(int32_t abilityRecordId, int32_t targetUserId) const
1589 {
1590 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1591 HILOG_INFO("Call.");
1592 for (const auto& [first, second] : sessionAbilityMap_) {
1593 if (second == nullptr) {
1594 HILOG_WARN("abilityRecord is nullptr.");
1595 continue;
1596 }
1597 if (second->GetRecordId() == abilityRecordId && targetUserId == abilityRecord->GetOwnerMissionUserId()) {
1598 HILOG_INFO("Call BlockAbility.");
1599 return second->BlockAbility();
1600 }
1601 }
1602 HILOG_ERROR("The abilityRecordId is invalid.");
1603 return -1;
1604 }
1605 #endif
1606 } // namespace AAFwk
1607 } // namespace OHOS