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 = 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 EraseAbilityRecord(abilityRecord);
806 if (abilityRecord->GetAbilityState() == AbilityState::INITIAL) {
807 if (abilityRecord->GetScheduler() == nullptr) {
808 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
809 CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityEventHandler.");
810 handler->RemoveEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, abilityRecord->GetAbilityRecordId());
811 }
812 return abilityRecord->TerminateAbility();
813 }
814
815 terminateAbilityList_.push_back(abilityRecord);
816 abilityRecord->SendResultToCallers();
817
818 if (abilityRecord->IsAbilityState(FOREGROUND) || abilityRecord->IsAbilityState(FOREGROUNDING)) {
819 HILOG_DEBUG("current ability is active");
820 abilityRecord->SetPendingState(AbilityState::BACKGROUND);
821 MoveToBackground(abilityRecord);
822 return ERR_OK;
823 }
824
825 // ability on background, schedule to terminate.
826 if (abilityRecord->GetAbilityState() == AbilityState::BACKGROUND) {
827 auto self(shared_from_this());
828 auto task = [abilityRecord, self]() {
829 HILOG_WARN("close ability by scb timeout");
830 self->DelayCompleteTerminate(abilityRecord);
831 };
832 abilityRecord->Terminate(task);
833 }
834 return ERR_OK;
835 }
836
DelayCompleteTerminate(const std::shared_ptr<AbilityRecord> & abilityRecord)837 void UIAbilityLifecycleManager::DelayCompleteTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord)
838 {
839 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
840 CHECK_POINTER(handler);
841
842 PrintTimeOutLog(abilityRecord, AbilityManagerService::TERMINATE_TIMEOUT_MSG);
843
844 auto timeoutTask = [self = shared_from_this(), abilityRecord]() {
845 HILOG_INFO("emit delay complete terminate task.");
846 self->CompleteTerminate(abilityRecord);
847 };
848 int killTimeout = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * KILL_TIMEOUT_MULTIPLE;
849 handler->SubmitTask(timeoutTask, "DELAY_KILL_PROCESS", killTimeout);
850 }
851
CompleteTerminate(const std::shared_ptr<AbilityRecord> & abilityRecord)852 void UIAbilityLifecycleManager::CompleteTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord)
853 {
854 CHECK_POINTER(abilityRecord);
855 std::lock_guard<ffrt::mutex> guard(sessionLock_);
856 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
857
858 if (abilityRecord->GetAbilityState() != AbilityState::TERMINATING) {
859 HILOG_ERROR("failed, %{public}s, ability is not terminating.", __func__);
860 return;
861 }
862 abilityRecord->RemoveAbilityDeathRecipient();
863
864 // notify AppMS terminate
865 if (abilityRecord->TerminateAbility() != ERR_OK) {
866 // Don't return here
867 HILOG_ERROR("AppMS fail to terminate ability.");
868 }
869 abilityRecord->RevokeUriPermission();
870 EraseSpecifiedAbilityRecord(abilityRecord);
871 terminateAbilityList_.remove(abilityRecord);
872 }
873
GetPersistentIdByAbilityRequest(const AbilityRequest & abilityRequest,bool & reuse,int32_t userId) const874 int32_t UIAbilityLifecycleManager::GetPersistentIdByAbilityRequest(const AbilityRequest &abilityRequest,
875 bool &reuse, int32_t userId) const
876 {
877 if (abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::SPECIFIED) {
878 return GetReusedSpecifiedPersistentId(abilityRequest, reuse, userId);
879 }
880
881 if (abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::STANDARD) {
882 return GetReusedStandardPersistentId(abilityRequest, reuse, userId);
883 }
884
885 if (abilityRequest.abilityInfo.launchMode != AppExecFwk::LaunchMode::SINGLETON) {
886 HILOG_WARN("Launch mode is not singleton.");
887 return 0;
888 }
889
890 reuse = true;
891 for (const auto& [first, second] : sessionAbilityMap_) {
892 if (CheckProperties(second, abilityRequest, AppExecFwk::LaunchMode::SINGLETON, userId)) {
893 HILOG_DEBUG("SINGLETON: find.");
894 return first;
895 }
896 }
897
898 HILOG_DEBUG("Not find existed ui ability.");
899 return 0;
900 }
901
GetReusedSpecifiedPersistentId(const AbilityRequest & abilityRequest,bool & reuse,int32_t userId) const902 int32_t UIAbilityLifecycleManager::GetReusedSpecifiedPersistentId(const AbilityRequest &abilityRequest,
903 bool &reuse, int32_t userId) const
904 {
905 HILOG_DEBUG("Call.");
906 if (abilityRequest.abilityInfo.launchMode != AppExecFwk::LaunchMode::SPECIFIED) {
907 HILOG_WARN("Not SPECIFIED.");
908 return 0;
909 }
910
911 reuse = true;
912 // specified ability name and bundle name and module name and appIndex format is same as singleton.
913 for (const auto& [first, second] : sessionAbilityMap_) {
914 if (second->GetSpecifiedFlag() == abilityRequest.specifiedFlag &&
915 CheckProperties(second, abilityRequest, AppExecFwk::LaunchMode::SPECIFIED, userId)) {
916 HILOG_DEBUG("SPECIFIED: find.");
917 return first;
918 }
919 }
920 return 0;
921 }
922
GetReusedStandardPersistentId(const AbilityRequest & abilityRequest,bool & reuse,int32_t userId) const923 int32_t UIAbilityLifecycleManager::GetReusedStandardPersistentId(const AbilityRequest &abilityRequest,
924 bool &reuse, int32_t userId) const
925 {
926 HILOG_DEBUG("Call.");
927 if (abilityRequest.abilityInfo.launchMode != AppExecFwk::LaunchMode::STANDARD) {
928 HILOG_WARN("Not STANDARD.");
929 return 0;
930 }
931
932 if (!abilityRequest.startRecent) {
933 HILOG_WARN("startRecent is false.");
934 return 0;
935 }
936
937 reuse = true;
938 int64_t sessionTime = 0;
939 int32_t persistentId = 0;
940 for (const auto& [first, second] : sessionAbilityMap_) {
941 if (CheckProperties(second, abilityRequest, AppExecFwk::LaunchMode::STANDARD, userId) &&
942 second->GetRestartTime() >= sessionTime) {
943 persistentId = first;
944 sessionTime = second->GetRestartTime();
945 }
946 }
947 return persistentId;
948 }
949
CheckProperties(const std::shared_ptr<AbilityRecord> & abilityRecord,const AbilityRequest & abilityRequest,AppExecFwk::LaunchMode launchMode,int32_t userId) const950 bool UIAbilityLifecycleManager::CheckProperties(const std::shared_ptr<AbilityRecord> &abilityRecord,
951 const AbilityRequest &abilityRequest, AppExecFwk::LaunchMode launchMode, int32_t userId) const
952 {
953 if (userId != abilityRecord->GetOwnerMissionUserId()) {
954 HILOG_WARN("userId: %{public}d, ability's userId: %{public}d", userId, abilityRecord->GetOwnerMissionUserId());
955 return false;
956 }
957 const auto& abilityInfo = abilityRecord->GetAbilityInfo();
958 return abilityInfo.launchMode == launchMode && abilityRequest.abilityInfo.name == abilityInfo.name &&
959 abilityRequest.abilityInfo.bundleName == abilityInfo.bundleName &&
960 abilityRequest.abilityInfo.moduleName == abilityInfo.moduleName &&
961 abilityRequest.want.GetIntParam(DLP_INDEX, 0) == abilityRecord->GetAppIndex();
962 }
963
ReportEventToSuspendManager(const AppExecFwk::AbilityInfo & abilityInfo) const964 void UIAbilityLifecycleManager::ReportEventToSuspendManager(const AppExecFwk::AbilityInfo &abilityInfo) const
965 {
966 #ifdef EFFICIENCY_MANAGER_ENABLE
967 #endif // EFFICIENCY_MANAGER_ENABLE
968 }
969
OnTimeOut(uint32_t msgId,int64_t abilityRecordId,bool isHalf)970 void UIAbilityLifecycleManager::OnTimeOut(uint32_t msgId, int64_t abilityRecordId, bool isHalf)
971 {
972 HILOG_DEBUG("call, msgId is %{public}d", msgId);
973 std::lock_guard<ffrt::mutex> guard(sessionLock_);
974 std::shared_ptr<AbilityRecord> abilityRecord;
975 for (auto iter = sessionAbilityMap_.begin(); iter != sessionAbilityMap_.end(); iter++) {
976 if (iter->second != nullptr && iter->second->GetAbilityRecordId() == abilityRecordId) {
977 abilityRecord = iter->second;
978 break;
979 }
980 }
981 if (abilityRecord == nullptr) {
982 HILOG_ERROR("failed, ability record is nullptr");
983 return;
984 }
985 HILOG_DEBUG("call, msgId:%{public}d, name:%{public}s", msgId, abilityRecord->GetAbilityInfo().name.c_str());
986 abilityRecord->RevokeUriPermission();
987 PrintTimeOutLog(abilityRecord, msgId, isHalf);
988 if (isHalf) {
989 return;
990 }
991 switch (msgId) {
992 case AbilityManagerService::LOAD_TIMEOUT_MSG:
993 HandleLoadTimeout(abilityRecord);
994 break;
995 case AbilityManagerService::FOREGROUND_TIMEOUT_MSG:
996 HandleForegroundTimeout(abilityRecord);
997 break;
998 default:
999 break;
1000 }
1001 }
1002
SetRootSceneSession(const sptr<IRemoteObject> & rootSceneSession)1003 void UIAbilityLifecycleManager::SetRootSceneSession(const sptr<IRemoteObject> &rootSceneSession)
1004 {
1005 HILOG_DEBUG("call");
1006 if (rootSceneSession == nullptr) {
1007 HILOG_ERROR("rootSceneSession is invalid.");
1008 return;
1009 }
1010 auto tmpSceneSession = iface_cast<Rosen::ISession>(rootSceneSession);
1011 auto descriptor = Str16ToStr8(tmpSceneSession->GetDescriptor());
1012 if (descriptor != "OHOS.ISession") {
1013 HILOG_ERROR("token's Descriptor: %{public}s", descriptor.c_str());
1014 return;
1015 }
1016 rootSceneSession_ = tmpSceneSession;
1017 }
1018
NotifySCBToHandleException(const std::shared_ptr<AbilityRecord> & abilityRecord,int32_t errorCode,std::string errorReason)1019 void UIAbilityLifecycleManager::NotifySCBToHandleException(const std::shared_ptr<AbilityRecord> &abilityRecord,
1020 int32_t errorCode, std::string errorReason)
1021 {
1022 HILOG_DEBUG("call");
1023 if (abilityRecord == nullptr) {
1024 HILOG_ERROR("ability record is nullptr");
1025 return;
1026 }
1027 auto callerSessionInfo = abilityRecord->GetSessionInfo();
1028 CHECK_POINTER(callerSessionInfo);
1029 CHECK_POINTER(callerSessionInfo->sessionToken);
1030 auto callerSession = iface_cast<Rosen::ISession>(callerSessionInfo->sessionToken);
1031 HILOG_INFO("call notifySessionException");
1032 sptr<SessionInfo> info = abilityRecord->GetSessionInfo();
1033 info->errorCode = errorCode;
1034 info->errorReason = errorReason;
1035 callerSession->NotifySessionException(info);
1036 EraseAbilityRecord(abilityRecord);
1037 }
1038
HandleLoadTimeout(const std::shared_ptr<AbilityRecord> & abilityRecord)1039 void UIAbilityLifecycleManager::HandleLoadTimeout(const std::shared_ptr<AbilityRecord> &abilityRecord)
1040 {
1041 HILOG_DEBUG("call");
1042 if (abilityRecord == nullptr) {
1043 HILOG_ERROR("failed, ability record is nullptr");
1044 return;
1045 }
1046 NotifySCBToHandleException(abilityRecord,
1047 static_cast<int32_t>(ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT), "handleLoadTimeout");
1048 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
1049 }
1050
HandleForegroundTimeout(const std::shared_ptr<AbilityRecord> & abilityRecord)1051 void UIAbilityLifecycleManager::HandleForegroundTimeout(const std::shared_ptr<AbilityRecord> &abilityRecord)
1052 {
1053 HILOG_DEBUG("call");
1054 if (abilityRecord == nullptr) {
1055 HILOG_ERROR("ability record is nullptr");
1056 return;
1057 }
1058 if (!abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING)) {
1059 HILOG_ERROR("this ability is not foregrounding state");
1060 return;
1061 }
1062 NotifySCBToHandleException(abilityRecord,
1063 static_cast<int32_t>(ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT), "handleForegroundTimeout");
1064 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
1065 EraseSpecifiedAbilityRecord(abilityRecord);
1066 }
1067
OnAbilityDied(std::shared_ptr<AbilityRecord> abilityRecord)1068 void UIAbilityLifecycleManager::OnAbilityDied(std::shared_ptr<AbilityRecord> abilityRecord)
1069 {
1070 HILOG_DEBUG("call");
1071 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1072 if (abilityRecord == nullptr) {
1073 HILOG_ERROR("failed, ability record is nullptr");
1074 return;
1075 }
1076 terminateAbilityList_.push_back(abilityRecord);
1077 abilityRecord->SetAbilityState(AbilityState::TERMINATING);
1078 NotifySCBToHandleException(abilityRecord, static_cast<int32_t>(ErrorLifecycleState::ABILITY_STATE_DIED),
1079 "onAbilityDied");
1080 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
1081 DispatchTerminate(abilityRecord);
1082 EraseSpecifiedAbilityRecord(abilityRecord);
1083 }
1084
OnAcceptWantResponse(const AAFwk::Want & want,const std::string & flag)1085 void UIAbilityLifecycleManager::OnAcceptWantResponse(const AAFwk::Want &want, const std::string &flag)
1086 {
1087 HILOG_DEBUG("call");
1088 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1089 if (abilityQueue_.empty()) {
1090 return;
1091 }
1092
1093 AbilityRequest abilityRequest = abilityQueue_.front();
1094 abilityQueue_.pop();
1095 if (abilityRequest.abilityInfo.launchMode != AppExecFwk::LaunchMode::SPECIFIED) {
1096 return;
1097 }
1098 auto callerAbility = GetAbilityRecordByToken(abilityRequest.callerToken);
1099 if (!flag.empty()) {
1100 abilityRequest.specifiedFlag = flag;
1101 bool reuse = false;
1102 auto currentAccountId = DelayedSingleton<AbilityManagerService>::GetInstance()->GetUserId();
1103 auto persistentId = GetReusedSpecifiedPersistentId(abilityRequest, reuse, currentAccountId);
1104 if (persistentId != 0) {
1105 auto abilityRecord = GetReusedSpecifiedAbility(want, flag);
1106 if (!abilityRecord) {
1107 return;
1108 }
1109 abilityRecord->SetWant(abilityRequest.want);
1110 abilityRecord->SetIsNewWant(true);
1111 UpdateAbilityRecordLaunchReason(abilityRequest, abilityRecord);
1112 if (callerAbility == nullptr) {
1113 callerAbility = Token::GetAbilityRecordByToken(abilityRequest.callerToken);
1114 }
1115 MoveAbilityToFront(abilityRequest, abilityRecord, callerAbility);
1116 NotifyRestartSpecifiedAbility(abilityRequest, abilityRecord->GetToken());
1117 return;
1118 }
1119 }
1120 NotifyStartSpecifiedAbility(abilityRequest, want);
1121 StartAbilityBySpecifed(abilityRequest, callerAbility);
1122 }
1123
StartSpecifiedAbilityBySCB(const Want & want,int32_t userId)1124 void UIAbilityLifecycleManager::StartSpecifiedAbilityBySCB(const Want &want, int32_t userId)
1125 {
1126 HILOG_DEBUG("call");
1127 AbilityRequest abilityRequest;
1128 int result = DelayedSingleton<AbilityManagerService>::GetInstance()->GenerateAbilityRequest(
1129 want, DEFAULT_INVAL_VALUE, abilityRequest, nullptr, userId);
1130 if (result != ERR_OK) {
1131 HILOG_ERROR("cannot find generate ability request");
1132 return;
1133 }
1134 {
1135 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1136 EnqueueAbilityToFront(abilityRequest);
1137 }
1138 DelayedSingleton<AppScheduler>::GetInstance()->StartSpecifiedAbility(
1139 abilityRequest.want, abilityRequest.abilityInfo);
1140 }
1141
GetReusedSpecifiedAbility(const AAFwk::Want & want,const std::string & flag)1142 std::shared_ptr<AbilityRecord> UIAbilityLifecycleManager::GetReusedSpecifiedAbility(const AAFwk::Want &want,
1143 const std::string &flag)
1144 {
1145 auto element = want.GetElement();
1146 for (const auto& [first, second] : specifiedAbilityMap_) {
1147 if (flag == first.flag && element.GetAbilityName() == first.abilityName &&
1148 element.GetBundleName() == first.bundleName) {
1149 return second;
1150 }
1151 }
1152 return nullptr;
1153 }
1154
EnqueueAbilityToFront(const AbilityRequest & abilityRequest)1155 void UIAbilityLifecycleManager::EnqueueAbilityToFront(const AbilityRequest &abilityRequest)
1156 {
1157 abilityQueue_.push(abilityRequest);
1158 }
1159
NotifyRestartSpecifiedAbility(AbilityRequest & request,const sptr<IRemoteObject> & token)1160 void UIAbilityLifecycleManager::NotifyRestartSpecifiedAbility(AbilityRequest &request,
1161 const sptr<IRemoteObject> &token)
1162 {
1163 if (request.abilityInfoCallback == nullptr) {
1164 return;
1165 }
1166 sptr<AppExecFwk::IAbilityInfoCallback> abilityInfoCallback
1167 = iface_cast<AppExecFwk::IAbilityInfoCallback> (request.abilityInfoCallback);
1168 if (abilityInfoCallback != nullptr) {
1169 HILOG_DEBUG("%{public}s called.", __func__);
1170 abilityInfoCallback->NotifyRestartSpecifiedAbility(token);
1171 }
1172 }
1173
NotifyStartSpecifiedAbility(AbilityRequest & abilityRequest,const AAFwk::Want & want)1174 void UIAbilityLifecycleManager::NotifyStartSpecifiedAbility(AbilityRequest &abilityRequest, const AAFwk::Want &want)
1175 {
1176 if (abilityRequest.abilityInfoCallback == nullptr) {
1177 return;
1178 }
1179
1180 sptr<AppExecFwk::IAbilityInfoCallback> abilityInfoCallback
1181 = iface_cast<AppExecFwk::IAbilityInfoCallback> (abilityRequest.abilityInfoCallback);
1182 if (abilityInfoCallback != nullptr) {
1183 Want newWant = want;
1184 int32_t type = static_cast<int32_t>(abilityRequest.abilityInfo.type);
1185 newWant.SetParam("abilityType", type);
1186 sptr<Want> extraParam = new (std::nothrow) Want();
1187 abilityInfoCallback->NotifyStartSpecifiedAbility(abilityRequest.callerToken, newWant,
1188 abilityRequest.requestCode, extraParam);
1189 int32_t procCode = extraParam->GetIntParam(Want::PARAM_RESV_REQUEST_PROC_CODE, 0);
1190 if (procCode != 0) {
1191 abilityRequest.want.SetParam(Want::PARAM_RESV_REQUEST_PROC_CODE, procCode);
1192 }
1193 int32_t tokenCode = extraParam->GetIntParam(Want::PARAM_RESV_REQUEST_TOKEN_CODE, 0);
1194 if (tokenCode != 0) {
1195 abilityRequest.want.SetParam(Want::PARAM_RESV_REQUEST_TOKEN_CODE, tokenCode);
1196 }
1197 }
1198 }
1199
MoveAbilityToFront(const AbilityRequest & abilityRequest,const std::shared_ptr<AbilityRecord> & abilityRecord,std::shared_ptr<AbilityRecord> callerAbility,std::shared_ptr<StartOptions> startOptions)1200 int UIAbilityLifecycleManager::MoveAbilityToFront(const AbilityRequest &abilityRequest,
1201 const std::shared_ptr<AbilityRecord> &abilityRecord, std::shared_ptr<AbilityRecord> callerAbility,
1202 std::shared_ptr<StartOptions> startOptions)
1203 {
1204 HILOG_DEBUG("call");
1205 if (!abilityRecord) {
1206 HILOG_ERROR("get target ability record failed");
1207 return ERR_INVALID_VALUE;
1208 }
1209 sptr<SessionInfo> sessionInfo = abilityRecord->GetSessionInfo();
1210 sessionInfo->want = abilityRequest.want;
1211 SendSessionInfoToSCB(callerAbility, sessionInfo);
1212 abilityRecord->RemoveWindowMode();
1213 if (startOptions != nullptr) {
1214 abilityRecord->SetWindowMode(startOptions->GetWindowMode());
1215 }
1216 return ERR_OK;
1217 }
1218
SendSessionInfoToSCB(std::shared_ptr<AbilityRecord> & callerAbility,sptr<SessionInfo> & sessionInfo)1219 int UIAbilityLifecycleManager::SendSessionInfoToSCB(std::shared_ptr<AbilityRecord> &callerAbility,
1220 sptr<SessionInfo> &sessionInfo)
1221 {
1222 HILOG_DEBUG("call");
1223 if (callerAbility != nullptr) {
1224 auto callerSessionInfo = callerAbility->GetSessionInfo();
1225 if (callerSessionInfo != nullptr && callerSessionInfo->sessionToken != nullptr) {
1226 auto callerSession = iface_cast<Rosen::ISession>(callerSessionInfo->sessionToken);
1227 callerSession->PendingSessionActivation(sessionInfo);
1228 } else {
1229 CHECK_POINTER_AND_RETURN(rootSceneSession_, ERR_INVALID_VALUE);
1230 rootSceneSession_->PendingSessionActivation(sessionInfo);
1231 }
1232 } else {
1233 CHECK_POINTER_AND_RETURN(rootSceneSession_, ERR_INVALID_VALUE);
1234 rootSceneSession_->PendingSessionActivation(sessionInfo);
1235 }
1236 return ERR_OK;
1237 }
1238
StartAbilityBySpecifed(const AbilityRequest & abilityRequest,std::shared_ptr<AbilityRecord> & callerAbility)1239 int UIAbilityLifecycleManager::StartAbilityBySpecifed(const AbilityRequest &abilityRequest,
1240 std::shared_ptr<AbilityRecord> &callerAbility)
1241 {
1242 HILOG_DEBUG("call");
1243 sptr<SessionInfo> sessionInfo = new SessionInfo();
1244 sessionInfo->callerToken = abilityRequest.callerToken;
1245 sessionInfo->want = abilityRequest.want;
1246 sessionInfo->requestCode = abilityRequest.requestCode;
1247 SpecifiedInfo specifiedInfo;
1248 specifiedInfo.abilityName = abilityRequest.abilityInfo.name;
1249 specifiedInfo.bundleName = abilityRequest.abilityInfo.bundleName;
1250 specifiedInfo.flag = abilityRequest.specifiedFlag;
1251 specifiedInfoQueue_.push(specifiedInfo);
1252
1253 SendSessionInfoToSCB(callerAbility, sessionInfo);
1254 return ERR_OK;
1255 }
1256
CallRequestDone(const std::shared_ptr<AbilityRecord> & abilityRecord,const sptr<IRemoteObject> & callStub)1257 void UIAbilityLifecycleManager::CallRequestDone(const std::shared_ptr<AbilityRecord> &abilityRecord,
1258 const sptr<IRemoteObject> &callStub)
1259 {
1260 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1261 if (abilityRecord == nullptr) {
1262 HILOG_ERROR("ability record is null.");
1263 return;
1264 }
1265 if (callStub == nullptr) {
1266 HILOG_ERROR("call stub is null.");
1267 return;
1268 }
1269 abilityRecord->CallRequestDone(callStub);
1270 }
1271
ReleaseCallLocked(const sptr<IAbilityConnection> & connect,const AppExecFwk::ElementName & element)1272 int UIAbilityLifecycleManager::ReleaseCallLocked(
1273 const sptr<IAbilityConnection> &connect, const AppExecFwk::ElementName &element)
1274 {
1275 HILOG_DEBUG("release call ability.");
1276
1277 CHECK_POINTER_AND_RETURN(connect, ERR_INVALID_VALUE);
1278 CHECK_POINTER_AND_RETURN(connect->AsObject(), ERR_INVALID_VALUE);
1279
1280 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1281
1282 auto abilityRecords = GetAbilityRecordsByName(element);
1283 auto isExist = [connect] (const std::shared_ptr<AbilityRecord> &abilityRecord) {
1284 return abilityRecord->IsExistConnection(connect);
1285 };
1286 auto findRecord = std::find_if(abilityRecords.begin(), abilityRecords.end(), isExist);
1287 if (findRecord == abilityRecords.end()) {
1288 HILOG_ERROR("not found ability record by callback");
1289 return RELEASE_CALL_ABILITY_INNER_ERR;
1290 }
1291 auto abilityRecord = *findRecord;
1292 CHECK_POINTER_AND_RETURN(abilityRecord, RELEASE_CALL_ABILITY_INNER_ERR);
1293
1294 if (!abilityRecord->ReleaseCall(connect)) {
1295 HILOG_ERROR("ability release call record failed.");
1296 return RELEASE_CALL_ABILITY_INNER_ERR;
1297 }
1298 return ERR_OK;
1299 }
1300
OnCallConnectDied(const std::shared_ptr<CallRecord> & callRecord)1301 void UIAbilityLifecycleManager::OnCallConnectDied(const std::shared_ptr<CallRecord> &callRecord)
1302 {
1303 HILOG_INFO("On callConnect died.");
1304 CHECK_POINTER(callRecord);
1305 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1306
1307 AppExecFwk::ElementName element = callRecord->GetTargetServiceName();
1308 auto abilityRecords = GetAbilityRecordsByName(element);
1309 auto isExist = [callRecord] (const std::shared_ptr<AbilityRecord> &abilityRecord) {
1310 return abilityRecord->IsExistConnection(callRecord->GetConCallBack());
1311 };
1312 auto findRecord = std::find_if(abilityRecords.begin(), abilityRecords.end(), isExist);
1313 if (findRecord == abilityRecords.end()) {
1314 HILOG_ERROR("not found ability record by callback");
1315 return;
1316 }
1317 auto abilityRecord = *findRecord;
1318 CHECK_POINTER(abilityRecord);
1319 abilityRecord->ReleaseCall(callRecord->GetConCallBack());
1320 }
1321
GetAbilityRecordsByName(const AppExecFwk::ElementName & element)1322 std::vector<std::shared_ptr<AbilityRecord>> UIAbilityLifecycleManager::GetAbilityRecordsByName(
1323 const AppExecFwk::ElementName &element)
1324 {
1325 std::vector<std::shared_ptr<AbilityRecord>> records;
1326 for (const auto& [first, second] : sessionAbilityMap_) {
1327 auto &abilityInfo = second->GetAbilityInfo();
1328 AppExecFwk::ElementName localElement(abilityInfo.deviceId, abilityInfo.bundleName,
1329 abilityInfo.name, abilityInfo.moduleName);
1330 AppExecFwk::ElementName localElementNoModuleName(abilityInfo.deviceId,
1331 abilityInfo.bundleName, abilityInfo.name);
1332 if (localElement == element || localElementNoModuleName == element) {
1333 HILOG_DEBUG("find element %{public}s", localElement.GetURI().c_str());
1334 records.push_back(second);
1335 }
1336 }
1337 return records;
1338 }
1339
GetSessionIdByAbilityToken(const sptr<IRemoteObject> & token)1340 int32_t UIAbilityLifecycleManager::GetSessionIdByAbilityToken(const sptr<IRemoteObject> &token)
1341 {
1342 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1343 for (const auto& [first, second] : sessionAbilityMap_) {
1344 if (second && second->GetToken()->AsObject() == token) {
1345 return first;
1346 }
1347 }
1348 HILOG_ERROR("not find");
1349 return 0;
1350 }
1351
GetActiveAbilityList(const std::string & bundleName,std::vector<std::string> & abilityList)1352 void UIAbilityLifecycleManager::GetActiveAbilityList(const std::string &bundleName,
1353 std::vector<std::string> &abilityList)
1354 {
1355 auto currentAccountId = DelayedSingleton<AbilityManagerService>::GetInstance()->GetUserId();
1356 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1357 for (const auto& [first, second] : sessionAbilityMap_) {
1358 if (second->GetOwnerMissionUserId() == currentAccountId) {
1359 const auto &abilityInfo = second->GetAbilityInfo();
1360 if (abilityInfo.bundleName == bundleName && !abilityInfo.name.empty()) {
1361 HILOG_DEBUG("find ability name is %{public}s", abilityInfo.name.c_str());
1362 abilityList.push_back(abilityInfo.name);
1363 }
1364 }
1365 }
1366 }
1367
SetRevicerInfo(const AbilityRequest & abilityRequest,std::shared_ptr<AbilityRecord> & abilityRecord) const1368 void UIAbilityLifecycleManager::SetRevicerInfo(const AbilityRequest &abilityRequest,
1369 std::shared_ptr<AbilityRecord> &abilityRecord) const
1370 {
1371 const auto &abilityInfo = abilityRequest.abilityInfo;
1372 auto isStandard = abilityInfo.launchMode == AppExecFwk::LaunchMode::STANDARD && !abilityRequest.startRecent;
1373 if (!isStandard) {
1374 bool hasRecoverInfo = false;
1375 (void)DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
1376 GetAbilityRecoverInfo(abilityInfo.bundleName, abilityInfo.moduleName, abilityInfo.name, hasRecoverInfo);
1377 abilityRecord->UpdateRecoveryInfo(hasRecoverInfo);
1378 (void)DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
1379 DeleteAbilityRecoverInfo(abilityInfo.bundleName, abilityInfo.moduleName, abilityInfo.name);
1380 }
1381 }
1382
SetLastExitReason(std::shared_ptr<AbilityRecord> & abilityRecord) const1383 void UIAbilityLifecycleManager::SetLastExitReason(std::shared_ptr<AbilityRecord> &abilityRecord) const
1384 {
1385 if (abilityRecord == nullptr) {
1386 HILOG_ERROR("abilityRecord is nullptr.");
1387 return;
1388 }
1389
1390 if (abilityRecord->GetAbilityInfo().bundleName.empty()) {
1391 HILOG_ERROR("bundleName is empty.");
1392 return;
1393 }
1394
1395 Reason exitReason;
1396 bool isSetReason;
1397 DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->GetAppExitReason(
1398 abilityRecord->GetAbilityInfo().bundleName, abilityRecord->GetAbilityInfo().name, isSetReason, exitReason);
1399
1400 if (isSetReason) {
1401 abilityRecord->SetLastExitReason(CovertAppExitReasonToLastReason(exitReason));
1402 }
1403 }
1404
CovertAppExitReasonToLastReason(const Reason exitReason) const1405 LastExitReason UIAbilityLifecycleManager::CovertAppExitReasonToLastReason(const Reason exitReason) const
1406 {
1407 switch (exitReason) {
1408 case REASON_NORMAL:
1409 return LASTEXITREASON_NORMAL;
1410 case REASON_CPP_CRASH:
1411 return LASTEXITREASON_CPP_CRASH;
1412 case REASON_JS_ERROR:
1413 return LASTEXITREASON_JS_ERROR;
1414 case REASON_APP_FREEZE:
1415 return LASTEXITREASON_APP_FREEZE;
1416 case REASON_PERFORMANCE_CONTROL:
1417 return LASTEXITREASON_PERFORMANCE_CONTROL;
1418 case REASON_RESOURCE_CONTROL:
1419 return LASTEXITREASON_RESOURCE_CONTROL;
1420 case REASON_UPGRADE:
1421 return LASTEXITREASON_UPGRADE;
1422 case REASON_UNKNOWN:
1423 default:
1424 return LASTEXITREASON_UNKNOWN;
1425 }
1426 }
1427
PrepareTerminateAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)1428 bool UIAbilityLifecycleManager::PrepareTerminateAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
1429 {
1430 HILOG_DEBUG("call");
1431 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1432 if (abilityRecord == nullptr) {
1433 HILOG_ERROR("ability record is null");
1434 return false;
1435 }
1436 HILOG_INFO("abilityInfoName:%{public}s", abilityRecord->GetAbilityInfo().name.c_str());
1437 if (!CheckPrepareTerminateEnable(abilityRecord)) {
1438 HILOG_DEBUG("Not support prepare terminate.");
1439 return false;
1440 }
1441 // execute onPrepareToTerminate util timeout
1442 auto taskHandler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
1443 if (taskHandler == nullptr) {
1444 HILOG_ERROR("Fail to get AbilityTaskHandler.");
1445 return false;
1446 }
1447 auto promise = std::make_shared<std::promise<bool>>();
1448 auto future = promise->get_future();
1449 auto task = [promise, abilityRecord]() {
1450 promise->set_value(abilityRecord->PrepareTerminateAbility());
1451 };
1452 taskHandler->SubmitTask(task);
1453 int prepareTerminateTimeout =
1454 AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * PREPARE_TERMINATE_TIMEOUT_MULTIPLE;
1455 std::future_status status = future.wait_for(std::chrono::milliseconds(prepareTerminateTimeout));
1456 if (status == std::future_status::timeout) {
1457 HILOG_ERROR("onPrepareToTerminate timeout.");
1458 return false;
1459 }
1460 return future.get();
1461 }
1462
CheckPrepareTerminateEnable(const std::shared_ptr<AbilityRecord> & abilityRecord)1463 bool UIAbilityLifecycleManager::CheckPrepareTerminateEnable(const std::shared_ptr<AbilityRecord> &abilityRecord)
1464 {
1465 if (abilityRecord == nullptr || abilityRecord->IsTerminating()) {
1466 HILOG_DEBUG("Ability record is not exist or is on terminating.");
1467 return false;
1468 }
1469 auto type = abilityRecord->GetAbilityInfo().type;
1470 bool isStageBasedModel = abilityRecord->GetAbilityInfo().isStageBasedModel;
1471 if (!isStageBasedModel || type != AppExecFwk::AbilityType::PAGE) {
1472 HILOG_DEBUG("ability mode not support.");
1473 return false;
1474 }
1475 auto tokenId = abilityRecord->GetApplicationInfo().accessTokenId;
1476 if (!AAFwk::PermissionVerification::GetInstance()->VerifyPrepareTerminatePermission(tokenId)) {
1477 HILOG_DEBUG("failed, please apply permission ohos.permission.PREPARE_APP_TERMINATE");
1478 return false;
1479 }
1480 return true;
1481 }
1482
SetSessionHandler(const sptr<ISessionHandler> & handler)1483 void UIAbilityLifecycleManager::SetSessionHandler(const sptr<ISessionHandler> &handler)
1484 {
1485 handler_ = handler;
1486 }
1487
GetAbilityRecordsById(int32_t sessionId) const1488 std::shared_ptr<AbilityRecord> UIAbilityLifecycleManager::GetAbilityRecordsById(int32_t sessionId) const
1489 {
1490 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1491 auto search = sessionAbilityMap_.find(sessionId);
1492 if (search == sessionAbilityMap_.end()) {
1493 HILOG_INFO("sessionId is invalid.");
1494 return nullptr;
1495 }
1496 return search->second;
1497 }
1498
GetActiveAbilityList(const std::string & bundleName,std::vector<std::string> & abilityList,int32_t targetUserId) const1499 void UIAbilityLifecycleManager::GetActiveAbilityList(const std::string &bundleName,
1500 std::vector<std::string> &abilityList, int32_t targetUserId) const
1501 {
1502 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1503 HILOG_INFO("Call.");
1504 for (const auto& [sessionId, abilityRecord] : sessionAbilityMap_) {
1505 if (abilityRecord == nullptr) {
1506 HILOG_WARN("second is nullptr.");
1507 continue;
1508 }
1509 const auto &abilityInfo = abilityRecord->GetAbilityInfo();
1510 if (abilityInfo.bundleName == bundleName && !abilityInfo.name.empty() &&
1511 (targetUserId == DEFAULT_USER_ID || abilityRecord->GetOwnerMissionUserId() == targetUserId)) {
1512 HILOG_DEBUG("find ability name is %{public}s", abilityInfo.name.c_str());
1513 abilityList.push_back(abilityInfo.name);
1514 }
1515 }
1516 if (!abilityList.empty()) {
1517 sort(abilityList.begin(), abilityList.end());
1518 abilityList.erase(unique(abilityList.begin(), abilityList.end()), abilityList.end());
1519 }
1520 }
1521
OnAppStateChanged(const AppInfo & info,int32_t targetUserId)1522 void UIAbilityLifecycleManager::OnAppStateChanged(const AppInfo &info, int32_t targetUserId)
1523 {
1524 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1525 HILOG_INFO("Call.");
1526 if (info.state == AppState::TERMINATED || info.state == AppState::END) {
1527 for (const auto& abilityRecord : terminateAbilityList_) {
1528 if (abilityRecord == nullptr) {
1529 HILOG_WARN("abilityRecord is nullptr.");
1530 continue;
1531 }
1532 if ((info.processName == abilityRecord->GetAbilityInfo().process ||
1533 info.processName == abilityRecord->GetApplicationInfo().bundleName) &&
1534 targetUserId == abilityRecord->GetOwnerMissionUserId()) {
1535 abilityRecord->SetAppState(info.state);
1536 }
1537 }
1538 return;
1539 }
1540 for (const auto& [sessionId, abilityRecord] : sessionAbilityMap_) {
1541 if (abilityRecord == nullptr) {
1542 HILOG_WARN("abilityRecord is nullptr.");
1543 continue;
1544 }
1545 if ((info.processName == abilityRecord->GetAbilityInfo().process ||
1546 info.processName == abilityRecord->GetApplicationInfo().bundleName) &&
1547 targetUserId == abilityRecord->GetOwnerMissionUserId()) {
1548 abilityRecord->SetAppState(info.state);
1549 }
1550 }
1551 }
1552
UninstallApp(const std::string & bundleName,int32_t uid,int32_t targetUserId)1553 void UIAbilityLifecycleManager::UninstallApp(const std::string &bundleName, int32_t uid, int32_t targetUserId)
1554 {
1555 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1556 HILOG_INFO("Call.");
1557 for (auto it = sessionAbilityMap_.begin(); it != sessionAbilityMap_.end();) {
1558 if (it->second == nullptr) {
1559 it++;
1560 continue;
1561 }
1562 auto &abilityInfo = it->second->GetAbilityInfo();
1563 if (abilityInfo.bundleName == bundleName && it->second->GetUid() == uid &&
1564 (targetUserId == DEFAULT_USER_ID || it->second->GetOwnerMissionUserId() == targetUserId)) {
1565 (void)DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
1566 DeleteAbilityRecoverInfo(abilityInfo.bundleName, abilityInfo.moduleName, abilityInfo.name);
1567 sessionAbilityMap_.erase(it++);
1568 continue;
1569 }
1570 it++;
1571 }
1572 }
1573
GetAbilityRunningInfos(std::vector<AbilityRunningInfo> & info,bool isPerm,int32_t userId) const1574 void UIAbilityLifecycleManager::GetAbilityRunningInfos(std::vector<AbilityRunningInfo> &info, bool isPerm,
1575 int32_t userId) const
1576 {
1577 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1578 HILOG_DEBUG("Call.");
1579 for (auto [sessionId, abilityRecord] : sessionAbilityMap_) {
1580 if (abilityRecord == nullptr || userId != abilityRecord->GetOwnerMissionUserId()) {
1581 HILOG_WARN("abilityRecord is nullptr.");
1582 continue;
1583 }
1584 if (isPerm) {
1585 DelayedSingleton<AbilityManagerService>::GetInstance()->GetAbilityRunningInfo(info, abilityRecord);
1586 } else {
1587 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
1588 auto tokenID = abilityRecord->GetApplicationInfo().accessTokenId;
1589 if (callingTokenId == tokenID) {
1590 DelayedSingleton<AbilityManagerService>::GetInstance()->GetAbilityRunningInfo(info, abilityRecord);
1591 }
1592 }
1593 }
1594 }
1595
1596 #ifdef ABILITY_COMMAND_FOR_TEST
BlockAbility(int32_t abilityRecordId,int32_t targetUserId) const1597 int UIAbilityLifecycleManager::BlockAbility(int32_t abilityRecordId, int32_t targetUserId) const
1598 {
1599 std::lock_guard<ffrt::mutex> guard(sessionLock_);
1600 HILOG_INFO("Call.");
1601 for (const auto& [first, second] : sessionAbilityMap_) {
1602 if (second == nullptr) {
1603 HILOG_WARN("abilityRecord is nullptr.");
1604 continue;
1605 }
1606 if (second->GetRecordId() == abilityRecordId && targetUserId == abilityRecord->GetOwnerMissionUserId()) {
1607 HILOG_INFO("Call BlockAbility.");
1608 return second->BlockAbility();
1609 }
1610 }
1611 HILOG_ERROR("The abilityRecordId is invalid.");
1612 return -1;
1613 }
1614 #endif
1615 } // namespace AAFwk
1616 } // namespace OHOS