• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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