• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ability_stack_manager.h"
17 
18 #include <singleton.h>
19 #include <map>
20 
21 #include "hilog_wrapper.h"
22 #include "ability_util.h"
23 #include "ability_manager_errors.h"
24 #include "ability_manager_service.h"
25 #include "app_scheduler.h"
26 #include "common_event.h"
27 #include "common_event_manager.h"
28 
29 namespace OHOS {
30 namespace AAFwk {
AbilityStackManager(int userId)31 AbilityStackManager::AbilityStackManager(int userId) : userId_(userId)
32 {}
33 
Init()34 void AbilityStackManager::Init()
35 {
36     launcherMissionStack_ = std::make_shared<MissionStack>(LAUNCHER_MISSION_STACK_ID, userId_);
37     missionStackList_.push_back(launcherMissionStack_);
38     defaultMissionStack_ = std::make_shared<MissionStack>(DEFAULT_MISSION_STACK_ID, userId_);
39     missionStackList_.push_back(defaultMissionStack_);
40     currentMissionStack_ = launcherMissionStack_;
41 
42     resumeMissionContainer_ = std::make_shared<ResumeMissionContainer>(
43         DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler());
44 }
45 
~AbilityStackManager()46 AbilityStackManager::~AbilityStackManager()
47 {}
48 
StartAbility(const AbilityRequest & abilityRequest)49 int AbilityStackManager::StartAbility(const AbilityRequest &abilityRequest)
50 {
51     HILOG_DEBUG("Start ability.");
52     std::lock_guard<std::recursive_mutex> guard(stackLock_);
53 
54     auto currentTopAbilityRecord = GetCurrentTopAbility();
55     if (!CanStartInLockMissionState(abilityRequest, currentTopAbilityRecord)) {
56         SendUnlockMissionMessage();
57         return LOCK_MISSION_STATE_DENY_REQUEST;
58     }
59 
60     auto abilityInfo = abilityRequest.abilityInfo;
61     auto type = abilityInfo.type;
62     if (abilityInfo.applicationInfo.isLauncherApp && type == AppExecFwk::AbilityType::PAGE && currentTopAbilityRecord &&
63         AbilityUtil::IsSystemDialogAbility(
64         currentTopAbilityRecord->GetAbilityInfo().bundleName, currentTopAbilityRecord->GetAbilityInfo().name)) {
65         HILOG_ERROR("Page ability is dialog type, cannot return to luncher.");
66         return ERR_INVALID_VALUE;
67     }
68 
69     if (!waittingAbilityQueue_.empty()) {
70         HILOG_INFO("Waiting queue is not empty, so enqueue ability for waiting.");
71         EnqueueWaittingAbility(abilityRequest);
72         return START_ABILITY_WAITING;
73     }
74 
75     if (currentTopAbilityRecord != nullptr) {
76         std::string element = currentTopAbilityRecord->GetWant().GetElement().GetURI();
77         HILOG_DEBUG("current top: %{public}s", element.c_str());
78         if (currentTopAbilityRecord->GetAbilityState() != ACTIVE) {
79             HILOG_INFO("Top ability is not active, so enqueue ability for waiting.");
80             EnqueueWaittingAbility(abilityRequest);
81             return START_ABILITY_WAITING;
82         }
83     }
84 
85     // need to start ability as special
86     if (abilityRequest.startSetting && !abilityRequest.abilityInfo.applicationInfo.isLauncherApp) {
87         auto windowkey = static_cast<AbilityWindowConfiguration>(
88             std::atoi(abilityRequest.startSetting->GetProperty(AbilityStartSetting::WINDOW_MODE_KEY).c_str()));
89         HILOG_DEBUG("Start ability with settings ...");
90         if (windowkey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FLOATING ||
91             windowkey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY) {
92             return StartAbilityAsSpecialLocked(currentTopAbilityRecord, abilityRequest);
93         }
94     }
95 
96     return StartAbilityLocked(currentTopAbilityRecord, abilityRequest);
97 }
98 
StartAbilityLocked(const std::shared_ptr<AbilityRecord> & currentTopAbility,const AbilityRequest & abilityRequest)99 int AbilityStackManager::StartAbilityLocked(
100     const std::shared_ptr<AbilityRecord> &currentTopAbility, const AbilityRequest &abilityRequest)
101 {
102     HILOG_DEBUG("Start ability locked.");
103     CHECK_POINTER_AND_RETURN(currentMissionStack_, INNER_ERR);
104     // 1. choose target mission stack
105     std::shared_ptr<MissionStack> targetStack = GetTargetMissionStack(abilityRequest);
106     CHECK_POINTER_AND_RETURN(targetStack, CREATE_MISSION_STACK_FAILED);
107     auto lastTopAbility = targetStack->GetTopAbilityRecord();
108 
109     // 2. move target mission stack to top, currentMissionStack will be changed.
110     MoveMissionStackToTop(targetStack);
111 
112     // 3. get mission record and ability recode
113     std::shared_ptr<AbilityRecord> targetAbilityRecord;
114     std::shared_ptr<MissionRecord> targetMissionRecord;
115     GetMissionRecordAndAbilityRecord(abilityRequest, currentTopAbility, targetAbilityRecord, targetMissionRecord);
116     if (targetAbilityRecord == nullptr || targetMissionRecord == nullptr) {
117         HILOG_ERROR("Failed to get ability record or mission record.");
118         MoveMissionStackToTop(lastMissionStack_);
119         return ERR_INVALID_VALUE;
120     }
121     targetAbilityRecord->AddCallerRecord(abilityRequest.callerToken, abilityRequest.requestCode);
122     MoveMissionAndAbility(currentTopAbility, targetAbilityRecord, targetMissionRecord);
123 
124     // 4. start processing ability lifecycle
125     if (currentTopAbility == nullptr) {
126         // top ability is null, then launch the first Ability.
127         targetAbilityRecord->SetLauncherRoot();
128         return targetAbilityRecord->LoadAbility();
129     } else {
130         // complete ability background if needed.
131         return StartAbilityLifeCycle(lastTopAbility, currentTopAbility, targetAbilityRecord);
132     }
133 }
134 
StartAbilityLifeCycle(std::shared_ptr<AbilityRecord> lastTopAbility,std::shared_ptr<AbilityRecord> currentTopAbility,std::shared_ptr<AbilityRecord> targetAbility)135 int AbilityStackManager::StartAbilityLifeCycle(std::shared_ptr<AbilityRecord> lastTopAbility,
136     std::shared_ptr<AbilityRecord> currentTopAbility, std::shared_ptr<AbilityRecord> targetAbility)
137 {
138     CHECK_POINTER_AND_RETURN(targetAbility, ERR_INVALID_VALUE);
139     CHECK_POINTER_AND_RETURN(currentTopAbility, ERR_INVALID_VALUE);
140     enum ChangeType { T_ACTIVE, T_CHANGE, T_DEFAULT } changeType;
141 
142     bool isMissionChanged = currentTopAbility->GetMissionRecordId() != targetAbility->GetMissionRecordId();
143     bool isStackChanged = currentTopAbility->GetMissionStackId() != targetAbility->GetMissionStackId();
144     bool isCurrentFull = IsFullScreenStack(currentTopAbility->GetMissionStackId());
145     bool isTargetFull = IsFullScreenStack(targetAbility->GetMissionStackId());
146 
147     std::shared_ptr<AbilityRecord> needBackgroundAbility;
148 
149     // set target changeType
150     if (isMissionChanged) {
151         if (isStackChanged) {
152             if (isCurrentFull && isTargetFull) {
153                 changeType = T_DEFAULT;
154             } else if (!isCurrentFull && isTargetFull) {
155                 auto needAbility = (targetAbility->GetMissionStackId() == DEFAULT_MISSION_STACK_ID)
156                                        ? launcherMissionStack_->GetTopAbilityRecord()
157                                        : defaultMissionStack_->GetTopAbilityRecord();
158                 changeType = T_CHANGE;
159                 needBackgroundAbility =
160                     (needAbility && needAbility->IsAbilityState(AbilityState::ACTIVE)) ? needAbility : lastTopAbility;
161             } else {
162                 auto self(shared_from_this());
163                 auto IsChanged = [&lastTopAbility, &targetAbility, self]() {
164                     bool isSameMission = lastTopAbility->GetMissionRecordId() == targetAbility->GetMissionRecordId();
165                     bool isSyncVisual = self->SupportSyncVisualByStackId(targetAbility->GetMissionStackId());
166                     return (isSameMission || (!isSameMission && !isSyncVisual)) &&
167                                    lastTopAbility->IsAbilityState(AbilityState::ACTIVE)
168                                ? T_CHANGE
169                                : T_ACTIVE;
170                 };
171                 changeType = lastTopAbility ? IsChanged() : T_ACTIVE;
172                 needBackgroundAbility = (changeType == T_CHANGE) ? lastTopAbility : nullptr;
173             }
174         } else {
175             if (SupportSyncVisualByStackId(targetAbility->GetMissionStackId())) {
176                 auto targetMission = targetAbility->GetMissionRecord();
177                 auto secondAbility = targetMission ? targetMission->GetLastTopAbility() : nullptr;
178                 if (secondAbility && secondAbility->IsAbilityState(AbilityState::ACTIVE)) {
179                     needBackgroundAbility = secondAbility;
180                     changeType = T_CHANGE;
181                 } else {
182                     changeType = T_ACTIVE;
183                 }
184             } else {
185                 changeType = T_DEFAULT;
186             }
187         }
188     } else {
189         changeType = T_DEFAULT;
190     }
191 
192     needBackgroundAbility = (changeType == T_DEFAULT) ? currentTopAbility : needBackgroundAbility;
193 
194     changeType = needBackgroundAbility ? changeType : T_ACTIVE;
195 
196     HILOG_DEBUG("ChangeType: %{public}d, needBackAbility : %{public}s",
197         changeType,
198         needBackgroundAbility ? needBackgroundAbility->GetAbilityInfo().name.c_str() : "none");
199 
200     // deal ability lifecycle.
201     switch (changeType) {
202         // 1. last top ability don't need inactive , target ability active directly.
203         case T_ACTIVE: {
204             targetAbility->ProcessActivate();
205             break;
206         }
207         // 2. change inactive ability, add pre and next flag.
208         case T_CHANGE: {
209             targetAbility->SetPreAbilityRecord(needBackgroundAbility);
210             needBackgroundAbility->SetNextAbilityRecord(targetAbility);
211             needBackgroundAbility->Inactivate();
212             break;
213         }
214         // 3. usually, last top ability need inactive, target ability need active.
215         case T_DEFAULT:
216         default: {
217             needBackgroundAbility->Inactivate();
218             break;
219         }
220     }
221     return ERR_OK;
222 }
223 
StartAbilityAsSpecialLocked(const std::shared_ptr<AbilityRecord> & currentTopAbility,const AbilityRequest & abilityRequest)224 int AbilityStackManager::StartAbilityAsSpecialLocked(
225     const std::shared_ptr<AbilityRecord> &currentTopAbility, const AbilityRequest &abilityRequest)
226 {
227     HILOG_DEBUG("Start ability as special locked.");
228     CHECK_POINTER_AND_RETURN(currentTopAbility, INNER_ERR);
229     CHECK_RET_RETURN_RET(
230         CheckMultiWindowCondition(currentTopAbility, abilityRequest), "Check multiwindow condition is failed.");
231 
232     // 1. choose target mission stack
233     auto targetStack = GetTargetMissionStack(abilityRequest);
234     CHECK_POINTER_AND_RETURN(targetStack, CREATE_MISSION_STACK_FAILED);
235     auto lastTopAbility = targetStack->GetTopAbilityRecord();
236 
237     // 2. get mission record and ability recode
238     std::shared_ptr<AbilityRecord> targetAbilityRecord;
239     std::shared_ptr<MissionRecord> targetMissionRecord;
240     GetMissionRecordAndAbilityRecord(abilityRequest, currentTopAbility, targetAbilityRecord, targetMissionRecord);
241     if (targetAbilityRecord == nullptr || targetMissionRecord == nullptr) {
242         HILOG_ERROR("Failed to get ability record or mission record.");
243         return ERR_INVALID_VALUE;
244     }
245     targetAbilityRecord->AddCallerRecord(abilityRequest.callerToken, abilityRequest.requestCode);
246 
247     MissionOption option;
248     option.userId = userId_;
249     option.missionId = targetMissionRecord->GetMissionRecordId();
250     option.winModeKey = static_cast<AbilityWindowConfiguration>(
251         std::atoi(abilityRequest.startSetting->GetProperty(AbilityStartSetting::WINDOW_MODE_KEY).c_str()));
252     targetMissionRecord->SetMissionOption(option);
253 
254     // 3. first create mission record or stack is not changed,
255     // just load target ability and inactive the current top ability.
256     if (targetMissionRecord->GetMissionStack() == nullptr ||
257         targetMissionRecord->GetMissionStack()->GetMissionStackId() == targetStack->GetMissionStackId()) {
258         MoveMissionStackToTop(targetStack);
259         MoveMissionAndAbility(currentTopAbility, targetAbilityRecord, targetMissionRecord);
260         HILOG_DEBUG("First create mission record ,missionId:%{public}d", targetMissionRecord->GetMissionRecordId());
261         return StartAbilityLifeCycle(lastTopAbility, currentTopAbility, targetAbilityRecord);
262     }
263 
264     // 4. mission stack is changed, move mission to target stack.
265     isMultiWinMoving_ = true;
266     CompleteMoveMissionToStack(targetMissionRecord, targetStack);
267     MoveMissionAndAbility(currentTopAbility, targetAbilityRecord, targetMissionRecord);
268     HILOG_DEBUG("Mission stack is changed, move mission to target stack ,missionId:%{public}d",
269         targetMissionRecord->GetMissionRecordId());
270     CHECK_RET_RETURN_RET(DispatchLifecycle(currentTopAbility, targetAbilityRecord, false), "Dispatch lifecycle error.");
271     // Judging target system window mode, and notify event.
272     auto willWinMode = JudgingTargetSystemWindowMode(option.winModeKey);
273     auto targetWinMode = GetTargetSystemWindowMode(willWinMode);
274     NotifyWindowModeChanged(targetWinMode);
275     return ERR_OK;
276 }
277 
MoveMissionAndAbility(const std::shared_ptr<AbilityRecord> & currentTopAbility,std::shared_ptr<AbilityRecord> & targetAbilityRecord,std::shared_ptr<MissionRecord> & targetMissionRecord)278 void AbilityStackManager::MoveMissionAndAbility(const std::shared_ptr<AbilityRecord> &currentTopAbility,
279     std::shared_ptr<AbilityRecord> &targetAbilityRecord, std::shared_ptr<MissionRecord> &targetMissionRecord)
280 {
281     HILOG_INFO("Move mission and ability.");
282     CHECK_POINTER(targetAbilityRecord);
283     CHECK_POINTER(targetMissionRecord);
284 
285     // set relationship of mission record and ability record
286     if (currentTopAbility != nullptr) {
287         targetAbilityRecord->SetPreAbilityRecord(currentTopAbility);
288         currentTopAbility->SetNextAbilityRecord(targetAbilityRecord);
289         // move mission to end, don't set pre mission
290         auto targetPreMission = targetMissionRecord->GetPreMissionRecord();
291         if (targetPreMission) {
292             currentTopAbility->GetMissionRecord()->SetPreMissionRecord(targetPreMission);
293         }
294         targetMissionRecord->SetPreMissionRecord(currentTopAbility->GetMissionRecord());
295         if (currentTopAbility->IsLauncherAbility()) {
296             targetMissionRecord->SetIsLauncherCreate();
297         }
298     }
299     // check mission window mode.
300     if (targetAbilityRecord->GetMissionRecord() == nullptr) {
301         auto option = targetMissionRecord->GetMissionOption();
302         if (option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FLOATING ||
303             option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY ||
304             option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_SECONDARY) {
305             auto setting = AbilityStartSetting::GetEmptySetting();
306             setting->AddProperty(AbilityStartSetting::WINDOW_MODE_KEY, std::to_string(option.winModeKey));
307             targetAbilityRecord->SetStartSetting(setting);
308         }
309     }
310 
311     // add caller record
312     targetAbilityRecord->SetMissionRecord(targetMissionRecord);
313     // reparent mission record, currentMissionStack is the target mission stack.
314     targetMissionRecord->SetMissionStack(currentMissionStack_, currentMissionStack_->GetMissionStackId());
315     targetAbilityRecord->SetMissionStackId(currentMissionStack_->GetMissionStackId());
316     // add ability record to mission record.
317     // if this ability record exist this mission record, do not add.
318     targetMissionRecord->AddAbilityRecordToTop(targetAbilityRecord);
319     // add mission record to mission stack.
320     // if this mission record exist this mission stack, do not add.
321     currentMissionStack_->AddMissionRecordToTop(targetMissionRecord);
322     // move mission record to top
323     // if this mission exist at top, do not move.
324     currentMissionStack_->MoveMissionRecordToTop(targetMissionRecord);
325 }
326 
TerminateAbility(const sptr<IRemoteObject> & token,int resultCode,const Want * resultWant)327 int AbilityStackManager::TerminateAbility(const sptr<IRemoteObject> &token, int resultCode, const Want *resultWant)
328 {
329     HILOG_INFO("Terminate ability.");
330     std::lock_guard<std::recursive_mutex> guard(stackLock_);
331     auto abilityRecord = Token::GetAbilityRecordByToken(token);
332     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
333     // if ability was already in terminate list, don't do anything but wait.
334     CHECK_TRUE_RETURN_RET(abilityRecord->IsTerminating(), ERR_OK, "Ability is on terminating.");
335     // check if ability is in stack to avoid user create fake token.
336     CHECK_POINTER_AND_RETURN_LOG(
337         GetAbilityRecordByToken(token), INNER_ERR, "Ability is not in stack, nor in terminating list.");
338 
339     auto missionRecord = abilityRecord->GetMissionRecord();
340     CHECK_POINTER_AND_RETURN(missionRecord, INNER_ERR);
341     if (abilityRecord->IsLauncherAbility() && abilityRecord->IsLauncherRoot()) {
342         HILOG_WARN("Don't allow terminate root launcher");
343         return TERMINATE_LAUNCHER_DENIED;
344     }
345 
346     if (!CanStopInLockMissionState(abilityRecord)) {
347         SendUnlockMissionMessage();
348         return LOCK_MISSION_STATE_DENY_REQUEST;
349     }
350 
351     HILOG_INFO("Schedule normal terminate process.");
352     abilityRecord->SetTerminatingState();
353     return TerminateAbilityLocked(abilityRecord, resultCode, resultWant);
354 }
355 
TerminateAbility(const std::shared_ptr<AbilityRecord> & caller,int requestCode)356 int AbilityStackManager::TerminateAbility(const std::shared_ptr<AbilityRecord> &caller, int requestCode)
357 {
358     HILOG_INFO("Terminate ability.");
359     std::lock_guard<std::recursive_mutex> guard(stackLock_);
360 
361     std::shared_ptr<AbilityRecord> targetAbility = nullptr;
362     int result = static_cast<int>(ABILITY_VISIBLE_FALSE_DENY_REQUEST);
363     for (auto &stack : missionStackList_) {
364         targetAbility = stack->GetAbilityRecordByCaller(caller, requestCode);
365         if (targetAbility) {
366             result = AbilityUtil::JudgeAbilityVisibleControl(targetAbility->GetAbilityInfo());
367             break;
368         }
369     }
370 
371     if (!targetAbility) {
372         HILOG_ERROR("%{public}s, Can't find target ability", __func__);
373         return NO_FOUND_ABILITY_BY_CALLER;
374     }
375     if (result != ERR_OK) {
376         HILOG_ERROR("%{public}s JudgeAbilityVisibleControl error.", __func__);
377         return result;
378     }
379 
380     if (!CanStopInLockMissionState(targetAbility)) {
381         SendUnlockMissionMessage();
382         return LOCK_MISSION_STATE_DENY_REQUEST;
383     }
384 
385     return TerminateAbility(targetAbility->GetToken(), DEFAULT_INVAL_VALUE, nullptr);
386 }
387 
TerminateAbilityLocked(const std::shared_ptr<AbilityRecord> & abilityRecord,int resultCode,const Want * resultWant)388 int AbilityStackManager::TerminateAbilityLocked(
389     const std::shared_ptr<AbilityRecord> &abilityRecord, int resultCode, const Want *resultWant)
390 {
391     HILOG_INFO("%{public}s, called", __func__);
392     if (abilityRecord == nullptr) {
393         HILOG_ERROR("abilityRecord is invalid");
394         return ERR_INVALID_VALUE;
395     }
396 
397     if (abilityRecord->IsRestarting()) {
398         HILOG_ERROR("abilityRecord is restarting, deny terminate.");
399         return ERR_INVALID_VALUE;
400     }
401     // save result to caller AbilityRecord
402     if (resultWant != nullptr) {
403         abilityRecord->SaveResultToCallers(resultCode, resultWant);
404     }
405     // common case, ability terminate at active and at top position
406     if (abilityRecord->IsAbilityState(AbilityState::ACTIVE) ||
407         abilityRecord->IsAbilityState(AbilityState::ACTIVATING) ||
408         abilityRecord->IsAbilityState(AbilityState::INITIAL)) {
409         RemoveTerminatingAbility(abilityRecord);
410         abilityRecord->Inactivate();
411         return ERR_OK;
412     }
413     // it's not common case when ability terminate at non-active state and non-top position.
414     if (abilityRecord->IsAbilityState(AbilityState::INACTIVE)) {
415         // ability on inactive, remove AbilityRecord out of stack and then schedule to background.
416         RemoveTerminatingAbility(abilityRecord);
417         abilityRecord->SendResultToCallers();
418         MoveToBackgroundTask(abilityRecord);
419     } else if (abilityRecord->IsAbilityState(AbilityState::BACKGROUND)) {
420         // ability on background, remove AbilityRecord out of stack and then schedule to terminate.
421         RemoveTerminatingAbility(abilityRecord);
422         abilityRecord->SendResultToCallers();
423         auto self(shared_from_this());
424         auto task = [abilityRecord, self]() {
425             HILOG_WARN("Disconnect ability terminate timeout.");
426             self->CompleteTerminate(abilityRecord);
427         };
428         abilityRecord->Terminate(task);
429     } else if (abilityRecord->IsAbilityState(AbilityState::INACTIVATING) ||
430                abilityRecord->IsAbilityState(AbilityState::MOVING_BACKGROUND)) {
431         // ability on inactivating or moving to background.
432         // remove AbilityRecord out of stack and waiting for ability(kit) AbilityTransitionDone.
433         RemoveTerminatingAbility(abilityRecord);
434         abilityRecord->SendResultToCallers();
435     } else {
436         HILOG_WARN("Ability state is invalid.");
437     }
438     return ERR_OK;
439 }
440 
RemoveMissionById(int missionId)441 int AbilityStackManager::RemoveMissionById(int missionId)
442 {
443     std::lock_guard<std::recursive_mutex> guard(stackLock_);
444     if (missionId < 0) {
445         HILOG_ERROR("Mission id is invalid.");
446         return ERR_INVALID_VALUE;
447     }
448     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
449         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
450         return ERR_INVALID_VALUE;
451     }
452     return RemoveMissionByIdLocked(missionId);
453 }
454 
RemoveMissionByIdLocked(int missionId)455 int AbilityStackManager::RemoveMissionByIdLocked(int missionId)
456 {
457     CHECK_POINTER_AND_RETURN_LOG(defaultMissionStack_, ERR_NO_INIT, "defaultMissionStack_ is invalid.");
458 
459     auto missionRecord = GetMissionRecordFromAllStacks(missionId);
460     CHECK_POINTER_AND_RETURN_LOG(missionRecord, REMOVE_MISSION_ID_NOT_EXIST, "Mission id is invalid.");
461     CHECK_TRUE_RETURN_RET(IsLauncherMission(missionId),
462         REMOVE_MISSION_LAUNCHER_DENIED,
463         "Don't allow to terminate mission which has launcher ability.");
464 
465     auto currentStack = missionRecord->GetMissionStack();
466     CHECK_POINTER_AND_RETURN_LOG(currentStack, REMOVE_MISSION_FAILED, "Current stack is nullptr.");
467 
468     auto topAbility = missionRecord->GetTopAbilityRecord();
469     CHECK_POINTER_AND_RETURN(topAbility, REMOVE_MISSION_FAILED);
470 
471     std::shared_ptr<AbilityRecord> activeAbility;
472     if (topAbility->IsAbilityState(ACTIVE) || topAbility->IsAbilityState(ACTIVATING)) {
473         activeAbility = topAbility;
474     }
475 
476     std::vector<AbilityRecordInfo> abilityInfos;
477     missionRecord->GetAllAbilityInfo(abilityInfos);
478     for (auto &ability : abilityInfos) {
479         auto abilityRecord = missionRecord->GetAbilityRecordById(ability.id);
480         if (abilityRecord == nullptr || abilityRecord->IsTerminating()) {
481             HILOG_WARN("Ability record is not exist or is on terminating.");
482             continue;
483         }
484 
485         if (abilityRecord == activeAbility) {
486             continue;
487         }
488 
489         if (abilityRecord->IsAbilityState(AbilityState::INITIAL)) {
490             HILOG_INFO("Ability record state is INITIAL, remove ability, continue.");
491             missionRecord->RemoveAbilityRecord(abilityRecord);
492             if (missionRecord->IsEmpty()) {
493                 RemoveMissionRecordById(missionRecord->GetMissionRecordId());
494                 JudgingIsRemoveMultiScreenStack(currentStack);
495             }
496             continue;
497         }
498 
499         abilityRecord->SetTerminatingState();
500         auto ret = TerminateAbilityLocked(abilityRecord, DEFAULT_INVAL_VALUE, nullptr);
501         if (ret != ERR_OK) {
502             HILOG_ERROR("Remove mission error: %{public}d.", ret);
503             return REMOVE_MISSION_FAILED;
504         }
505     }
506 
507     if (activeAbility) {
508         activeAbility->SetTerminatingState();
509         auto ret = TerminateAbilityLocked(activeAbility, DEFAULT_INVAL_VALUE, nullptr);
510         if (ret != ERR_OK) {
511             HILOG_ERROR("Remove mission error: %{public}d.", ret);
512             return REMOVE_MISSION_FAILED;
513         }
514     }
515 
516     return ERR_OK;
517 }
518 
RemoveStack(int stackId)519 int AbilityStackManager::RemoveStack(int stackId)
520 {
521     HILOG_DEBUG("stackId : %{public}d", stackId);
522     std::lock_guard<std::recursive_mutex> guard(stackLock_);
523     if (stackId > MAX_MISSION_STACK_ID || stackId < MIN_MISSION_STACK_ID) {
524         HILOG_ERROR("stackId:%{public}d is invalid.", stackId);
525         return ERR_INVALID_VALUE;
526     }
527 
528     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
529         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
530         return ERR_INVALID_VALUE;
531     }
532 
533     return RemoveStackLocked(stackId);
534 }
535 
RemoveStackLocked(int stackId)536 int AbilityStackManager::RemoveStackLocked(int stackId)
537 {
538     HILOG_DEBUG("stackId : %{public}d", stackId);
539     CHECK_TRUE_RETURN_RET(missionStackList_.empty(), MISSION_STACK_LIST_IS_EMPTY, "Mission stack list is empty.");
540 
541     // don't allow remove launcher mission stack.
542     CHECK_TRUE_RETURN_RET(stackId == LAUNCHER_MISSION_STACK_ID,
543         REMOVE_STACK_LAUNCHER_DENIED,
544         "Don't allow remove launcher mission stack.");
545 
546     auto isExist = [stackId](
547                        const std::shared_ptr<MissionStack> &stack) { return stackId == stack->GetMissionStackId(); };
548     auto iter = std::find_if(missionStackList_.begin(), missionStackList_.end(), isExist);
549     CHECK_TRUE_RETURN_RET(iter == missionStackList_.end(), REMOVE_STACK_ID_NOT_EXIST, "Remove stack id is not exist.");
550     // remove mission record from mission stack.
551     if (*iter != nullptr) {
552         std::vector<MissionRecordInfo> missionInfos;
553         (*iter)->GetAllMissionInfo(missionInfos);
554         for (auto &mission : missionInfos) {
555             int result = RemoveMissionByIdLocked(mission.id);
556             if (result != ERR_OK) {
557                 HILOG_ERROR("Remove mission failed, mission id : %{public}d", mission.id);
558                 return result;
559             }
560         }
561     }
562 
563     return ERR_OK;
564 }
565 
SetMissionStackSetting(const StackSetting & stackSetting)566 void AbilityStackManager::SetMissionStackSetting(const StackSetting &stackSetting)
567 {
568     HILOG_DEBUG("Set mission stack setting, stackId : %{public}d", stackSetting.stackId);
569     std::lock_guard<std::recursive_mutex> guard(stackLock_);
570     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
571         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
572         return;
573     }
574     auto isExist = [stackId = stackSetting.stackId](const StackSetting &it) { return stackId == it.stackId; };
575     auto iter = std::find_if(stackSettings_.begin(), stackSettings_.end(), isExist);
576     if (iter != stackSettings_.end()) {
577         stackSettings_.erase(iter);
578     }
579     StackSetting settings = stackSetting;
580     stackSettings_.emplace_back(settings);
581 }
582 
583 /**
584  * remove AbilityRecord from stack to terminate list.
585  * update MissionStack to prepare next top ability.
586  */
RemoveTerminatingAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)587 void AbilityStackManager::RemoveTerminatingAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
588 {
589     CHECK_POINTER(abilityRecord);
590     auto missionRecord = abilityRecord->GetMissionRecord();
591     CHECK_POINTER(missionRecord);
592     auto currentStack = missionRecord->GetMissionStack();
593     CHECK_POINTER(currentStack);
594 
595     auto isActive = (abilityRecord->IsAbilityState(AbilityState::ACTIVE) ||
596                      abilityRecord->IsAbilityState(AbilityState::ACTIVATING) ||
597                      abilityRecord->IsAbilityState(AbilityState::INITIAL));
598 
599     missionRecord->RemoveAbilityRecord(abilityRecord);
600     terminateAbilityRecordList_.push_back(abilityRecord);
601 
602     std::shared_ptr<AbilityRecord> needTopAbility;
603 
604     if (!missionRecord->IsEmpty()) {
605         needTopAbility = missionRecord->GetTopAbilityRecord();
606         CHECK_POINTER(needTopAbility);
607         abilityRecord->SetNextAbilityRecord(needTopAbility);
608         return;
609     }
610 
611     if (!isActive) {
612         RemoveMissionRecordById(missionRecord->GetMissionRecordId());
613         JudgingIsRemoveMultiScreenStack(currentStack);
614         return;
615     }
616 
617     if (currentStack->IsEqualStackId(FLOATING_MISSION_STACK_ID)) {
618         RemoveMissionRecordById(missionRecord->GetMissionRecordId());
619         JudgingIsRemoveMultiScreenStack(currentStack);
620         MoveMissionStackToTop(GetTopFullScreenStack());
621         needTopAbility = GetCurrentTopAbility();
622         abilityRecord->SetNextAbilityRecord(needTopAbility);
623         return;
624     }
625 
626     if (IsFullScreenStack(currentStack->GetMissionStackId())) {
627         auto isExist = (!missionRecord->IsLauncherCreate() && missionRecord->GetPreMissionRecord() != nullptr &&
628                         launcherMissionStack_->IsExistMissionRecord(
629                             missionRecord->GetPreMissionRecord()->GetMissionRecordId()));
630         if ((missionRecord->IsLauncherCreate()) || (missionRecord == missionStackList_.back()->GetTopMissionRecord()) ||
631             isExist || (missionRecord == missionStackList_.front()->GetBottomMissionRecord())) {
632             RemoveMissionRecordById(missionRecord->GetMissionRecordId());
633             MoveMissionStackToTop(launcherMissionStack_);
634         } else {
635             RemoveMissionRecordById(missionRecord->GetMissionRecordId());
636         }
637         auto fullScreenStack = GetTopFullScreenStack();
638         CHECK_POINTER(fullScreenStack);
639         needTopAbility = fullScreenStack->GetTopAbilityRecord();
640         CHECK_POINTER(needTopAbility);
641         abilityRecord->SetNextAbilityRecord(needTopAbility);
642     }
643 }
644 
GetAbilityStackManagerUserId() const645 int AbilityStackManager::GetAbilityStackManagerUserId() const
646 {
647     return userId_;
648 }
649 
GetCurrentTopAbility() const650 std::shared_ptr<AbilityRecord> AbilityStackManager::GetCurrentTopAbility() const
651 {
652     std::shared_ptr<MissionStack> topMissionStack = missionStackList_.front();
653     HILOG_DEBUG("Top mission stack id is %{public}d", topMissionStack->GetMissionStackId());
654     return topMissionStack->GetTopAbilityRecord();
655 }
656 
GetCurrentTopAbilityToken()657 sptr<Token> AbilityStackManager::GetCurrentTopAbilityToken()
658 {
659     std::lock_guard<std::recursive_mutex> guard(stackLock_);
660     sptr<Token> token = nullptr;
661     std::shared_ptr<MissionStack> topMissionStack = missionStackList_.front();
662     std::shared_ptr<AbilityRecord> abilityRecord = topMissionStack->GetTopAbilityRecord();
663     if (abilityRecord != nullptr) {
664         token = abilityRecord->GetToken();
665     }
666     return token;
667 }
668 
GetAbilityRecordById(const int64_t recordId)669 std::shared_ptr<AbilityRecord> AbilityStackManager::GetAbilityRecordById(const int64_t recordId)
670 {
671     std::lock_guard<std::recursive_mutex> guard(stackLock_);
672     for (auto missionStack : missionStackList_) {
673         std::shared_ptr<AbilityRecord> abilityRecord = missionStack->GetAbilityRecordById(recordId);
674         if (abilityRecord != nullptr) {
675             return abilityRecord;
676         }
677     }
678     return nullptr;
679 }
680 
GetStackById(int stackId)681 std::shared_ptr<MissionStack> AbilityStackManager::GetStackById(int stackId)
682 {
683     std::lock_guard<std::recursive_mutex> guard(stackLock_);
684     for (auto missionStack : missionStackList_) {
685         if (missionStack->GetMissionStackId() == stackId) {
686             return missionStack;
687         }
688     }
689     return nullptr;
690 }
691 
GetTopMissionRecord() const692 std::shared_ptr<MissionRecord> AbilityStackManager::GetTopMissionRecord() const
693 {
694     if (currentMissionStack_ == nullptr) {
695         HILOG_ERROR("currentMissionStack_ is nullptr.");
696         return nullptr;
697     }
698     return currentMissionStack_->GetTopMissionRecord();
699 }
700 
GetMissionRecordById(int id) const701 std::shared_ptr<MissionRecord> AbilityStackManager::GetMissionRecordById(int id) const
702 {
703     if (currentMissionStack_ == nullptr) {
704         HILOG_ERROR("currentMissionStack_ is nullptr.");
705         return nullptr;
706     }
707     return currentMissionStack_->GetMissionRecordById(id);
708 }
709 
GetMissionRecordFromAllStacks(int id) const710 std::shared_ptr<MissionRecord> AbilityStackManager::GetMissionRecordFromAllStacks(int id) const
711 {
712     for (auto missionStack : missionStackList_) {
713         std::shared_ptr<MissionRecord> missionRecord = missionStack->GetMissionRecordById(id);
714         if (missionRecord != nullptr) {
715             return missionRecord;
716         }
717     }
718     return nullptr;
719 }
720 
GetMissionRecordByName(std::string name) const721 std::shared_ptr<MissionRecord> AbilityStackManager::GetMissionRecordByName(std::string name) const
722 {
723     for (auto missionStack : missionStackList_) {
724         std::shared_ptr<MissionRecord> missionRecord = missionStack->GetTargetMissionRecord(name);
725         if (missionRecord != nullptr) {
726             return missionRecord;
727         }
728     }
729     return nullptr;
730 }
731 
GetAbilityRecordByToken(const sptr<IRemoteObject> & token)732 std::shared_ptr<AbilityRecord> AbilityStackManager::GetAbilityRecordByToken(const sptr<IRemoteObject> &token)
733 {
734     std::lock_guard<std::recursive_mutex> guard(stackLock_);
735     for (auto missionStack : missionStackList_) {
736         std::shared_ptr<AbilityRecord> abilityRecord = missionStack->GetAbilityRecordByToken(token);
737         if (abilityRecord != nullptr) {
738             return abilityRecord;
739         }
740     }
741     return nullptr;
742 }
743 
GetAbilityFromTerminateList(const sptr<IRemoteObject> & token)744 std::shared_ptr<AbilityRecord> AbilityStackManager::GetAbilityFromTerminateList(const sptr<IRemoteObject> &token)
745 {
746     std::lock_guard<std::recursive_mutex> guard(stackLock_);
747     for (auto abilityRecord : terminateAbilityRecordList_) {
748         // token is type of IRemoteObject, abilityRecord->GetToken() is type of Token extending from IRemoteObject.
749         if (abilityRecord && token == abilityRecord->GetToken()->AsObject()) {
750             return abilityRecord;
751         }
752     }
753     return nullptr;
754 }
755 
RemoveMissionRecordById(int id)756 bool AbilityStackManager::RemoveMissionRecordById(int id)
757 {
758     for (auto missionstack : missionStackList_) {
759         if (missionstack->RemoveMissionRecord(id)) {
760             return true;
761         }
762     }
763     return false;
764 }
765 
MoveMissionStackToTop(const std::shared_ptr<MissionStack> & stack)766 void AbilityStackManager::MoveMissionStackToTop(const std::shared_ptr<MissionStack> &stack)
767 {
768     if (stack == nullptr) {
769         HILOG_ERROR("Stack is nullptr.");
770         return;
771     }
772     if (missionStackList_.front() == stack) {
773         HILOG_DEBUG("Stack is at the top of list, mission id: %d", stack->GetMissionStackId());
774         return;
775     }
776     lastMissionStack_ = currentMissionStack_;
777     missionStackList_.remove(stack);
778     missionStackList_.push_front(stack);
779     currentMissionStack_ = stack;
780 }
781 
GetTargetMissionStack(const AbilityRequest & abilityRequest)782 std::shared_ptr<MissionStack> AbilityStackManager::GetTargetMissionStack(const AbilityRequest &abilityRequest)
783 {
784     // priority : starting launcher ability .
785     if (abilityRequest.abilityInfo.applicationInfo.isLauncherApp) {
786         return launcherMissionStack_;
787     }
788 
789     // next: start ability for settings(multiwindow)
790     if (abilityRequest.startSetting != nullptr) {
791         return GetTargetMissionStackBySetting(abilityRequest);
792     }
793 
794     // other: refer to the stack of the caller ability.
795     return GetTargetMissionStackByDefault(abilityRequest);
796 }
797 
GetTargetMissionStackByDefault(const AbilityRequest & abilityRequest)798 std::shared_ptr<MissionStack> AbilityStackManager::GetTargetMissionStackByDefault(const AbilityRequest &abilityRequest)
799 {
800     bool isSingleton = abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::SINGLETON;
801     std::shared_ptr<MissionRecord> requestMission = nullptr;
802     if (isSingleton) {
803         std::string bundleName = AbilityUtil::ConvertBundleNameSingleton(
804             abilityRequest.abilityInfo.bundleName, abilityRequest.abilityInfo.name);
805         requestMission = GetMissionRecordByName(bundleName);
806     } else {
807         requestMission = GetMissionRecordByName(abilityRequest.abilityInfo.bundleName);
808     }
809 
810     bool isExist = requestMission != nullptr;
811     auto currentTop = GetCurrentTopAbility();
812     if (currentTop) {
813         // caller is launcher , request is not launcher, exist ability just restart.
814         if (isExist && (currentTop->IsLauncherAbility() || (!currentTop->IsLauncherAbility() && isSingleton) ||
815             (!currentTop->IsLauncherAbility() &&
816             currentTop->GetAbilityInfo().launchMode == AppExecFwk::LaunchMode::SINGLETON))) {
817             return requestMission->GetMissionStack();
818         }
819         // caller and request is not launcher, start ability at current mission stack.
820         if (!currentTop->IsLauncherAbility() && !isSingleton &&
821             currentTop->GetAbilityInfo().launchMode != AppExecFwk::LaunchMode::SINGLETON) {
822             auto callerParent = currentTop->GetMissionRecord();
823             return callerParent->GetMissionStack();
824         }
825     }
826 
827     return defaultMissionStack_;
828 }
829 
GetTargetMissionStackBySetting(const AbilityRequest & abilityRequest)830 std::shared_ptr<MissionStack> AbilityStackManager::GetTargetMissionStackBySetting(const AbilityRequest &abilityRequest)
831 {
832     if (abilityRequest.startSetting != nullptr) {
833         AbilityWindowConfiguration windowMode = static_cast<AbilityWindowConfiguration>(
834             std::atoi(abilityRequest.startSetting->GetProperty(AbilityStartSetting::WINDOW_MODE_KEY).c_str()));
835         switch (windowMode) {
836             case AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FLOATING:
837                 return GetOrCreateMissionStack(FLOATING_MISSION_STACK_ID, true);
838             case AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY:
839                 return GetOrCreateMissionStack(SPLIT_SCREEN_MISSION_STACK_ID, true);
840             default:
841                 break;
842         }
843     }
844 
845     return defaultMissionStack_;
846 }
847 
AttachAbilityThread(const sptr<IAbilityScheduler> & scheduler,const sptr<IRemoteObject> & token)848 int AbilityStackManager::AttachAbilityThread(const sptr<IAbilityScheduler> &scheduler, const sptr<IRemoteObject> &token)
849 {
850     std::lock_guard<std::recursive_mutex> guard(stackLock_);
851     auto abilityRecord = GetAbilityRecordByToken(token);
852     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
853 
854     std::string element = abilityRecord->GetWant().GetElement().GetURI();
855     HILOG_DEBUG("Ability: %{public}s", element.c_str());
856 
857     std::shared_ptr<AbilityEventHandler> handler =
858         DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
859     CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityEventHandler.");
860     handler->RemoveEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, abilityRecord->GetEventId());
861 
862     abilityRecord->SetScheduler(scheduler);
863     if (abilityRecord->IsRestarting()) {
864         abilityRecord->RestoreAbilityState();
865     }
866     DelayedSingleton<AppScheduler>::GetInstance()->MoveToForground(token);
867 
868     return ERR_OK;
869 }
870 
AbilityTransitionDone(const sptr<IRemoteObject> & token,int state)871 int AbilityStackManager::AbilityTransitionDone(const sptr<IRemoteObject> &token, int state)
872 {
873     std::lock_guard<std::recursive_mutex> guard(stackLock_);
874     auto abilityRecord = GetAbilityRecordByToken(token);
875     if (abilityRecord == nullptr) {
876         HILOG_INFO("Ability record may in terminate list.");
877         abilityRecord = GetAbilityFromTerminateList(token);
878         CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
879     }
880 
881     std::string element = abilityRecord->GetWant().GetElement().GetURI();
882     int targetState = AbilityRecord::ConvertLifeCycleToAbilityState(static_cast<AbilityLifeCycleState>(state));
883     std::string abilityState = AbilityRecord::ConvertAbilityState(static_cast<AbilityState>(targetState));
884     HILOG_INFO("ability: %{public}s, state: %{public}s", element.c_str(), abilityState.c_str());
885 
886     return DispatchState(abilityRecord, targetState);
887 }
888 
DispatchState(const std::shared_ptr<AbilityRecord> & abilityRecord,int state)889 int AbilityStackManager::DispatchState(const std::shared_ptr<AbilityRecord> &abilityRecord, int state)
890 {
891     HILOG_DEBUG("Dispatch state.");
892     switch (state) {
893         case AbilityState::ACTIVE: {
894             return DispatchActive(abilityRecord, state);
895         }
896         case AbilityState::INACTIVE: {
897             return DispatchInactive(abilityRecord, state);
898         }
899         case AbilityState::BACKGROUND: {
900             return DispatchBackground(abilityRecord, state);
901         }
902         case AbilityState::INITIAL: {
903             return DispatchTerminate(abilityRecord, state);
904         }
905         default: {
906             HILOG_WARN("Don't support transiting state: %d", state);
907             return ERR_INVALID_VALUE;
908         }
909     }
910 }
911 
DispatchActive(const std::shared_ptr<AbilityRecord> & abilityRecord,int state)912 int AbilityStackManager::DispatchActive(const std::shared_ptr<AbilityRecord> &abilityRecord, int state)
913 {
914     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
915     CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityEventHandler.");
916     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
917 
918     if (!abilityRecord->IsAbilityState(AbilityState::ACTIVATING)) {
919         HILOG_ERROR("Ability transition life state error. expect %{public}d, actual %{public}d callback %{public}d",
920             AbilityState::ACTIVATING,
921             abilityRecord->GetAbilityState(),
922             state);
923         return ERR_INVALID_VALUE;
924     }
925 
926     handler->RemoveEvent(AbilityManagerService::ACTIVE_TIMEOUT_MSG, abilityRecord->GetEventId());
927     auto self(shared_from_this());
928     auto task = [self, abilityRecord]() { self->CompleteActive(abilityRecord); };
929     handler->PostTask(task);
930 
931     return ERR_OK;
932 }
933 
DispatchInactive(const std::shared_ptr<AbilityRecord> & abilityRecord,int state)934 int AbilityStackManager::DispatchInactive(const std::shared_ptr<AbilityRecord> &abilityRecord, int state)
935 {
936     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
937     CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityEventHandler.");
938     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
939 
940     if (!abilityRecord->IsAbilityState(AbilityState::INACTIVATING)) {
941         HILOG_ERROR("Ability transition life state error. expect %{public}d, actual %{public}d callback %{public}d",
942             AbilityState::INACTIVATING,
943             abilityRecord->GetAbilityState(),
944             state);
945         return ERR_INVALID_VALUE;
946     }
947 
948     handler->RemoveEvent(AbilityManagerService::INACTIVE_TIMEOUT_MSG, abilityRecord->GetEventId());
949     auto self(shared_from_this());
950     auto task = [self, abilityRecord]() { self->CompleteInactive(abilityRecord); };
951     handler->PostTask(task);
952 
953     return ERR_OK;
954 }
955 
DispatchBackground(const std::shared_ptr<AbilityRecord> & abilityRecord,int state)956 int AbilityStackManager::DispatchBackground(const std::shared_ptr<AbilityRecord> &abilityRecord, int state)
957 {
958     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
959     CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityEventHandler.");
960     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
961 
962     if (!abilityRecord->IsAbilityState(AbilityState::MOVING_BACKGROUND)) {
963         HILOG_ERROR("Ability transition life state error. expect %{public}d, actual %{public}d callback %{public}d",
964             AbilityState::MOVING_BACKGROUND,
965             abilityRecord->GetAbilityState(),
966             state);
967         return ERR_INVALID_VALUE;
968     }
969 
970     // remove background timeout task.
971     handler->RemoveTask(std::to_string(abilityRecord->GetEventId()));
972     auto self(shared_from_this());
973     auto task = [self, abilityRecord]() { self->CompleteBackground(abilityRecord); };
974     handler->PostTask(task);
975 
976     return ERR_OK;
977 }
978 
DispatchTerminate(const std::shared_ptr<AbilityRecord> & abilityRecord,int state)979 int AbilityStackManager::DispatchTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord, int state)
980 {
981     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
982     CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityEventHandler.");
983     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
984 
985     if (!abilityRecord->IsAbilityState(AbilityState::TERMINATING)) {
986         HILOG_ERROR("Ability transition life state error. expect %{public}d, actual %{public}d callback %{public}d",
987             AbilityState::TERMINATING,
988             abilityRecord->GetAbilityState(),
989             state);
990         return INNER_ERR;
991     }
992 
993     // remove terminate timeout task.
994     handler->RemoveTask(std::to_string(abilityRecord->GetEventId()));
995     auto self(shared_from_this());
996     auto task = [self, abilityRecord]() { self->CompleteTerminate(abilityRecord); };
997     handler->PostTask(task);
998 
999     return ERR_OK;
1000 }
1001 
AddWindowInfo(const sptr<IRemoteObject> & token,int32_t windowToken)1002 void AbilityStackManager::AddWindowInfo(const sptr<IRemoteObject> &token, int32_t windowToken)
1003 {
1004     HILOG_DEBUG("Add window id.");
1005     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1006     // create WindowInfo and add to its AbilityRecord
1007     auto abilityRecord = GetAbilityRecordByToken(token);
1008     CHECK_POINTER(abilityRecord);
1009     if (abilityRecord->GetWindowInfo()) {
1010         HILOG_DEBUG("WindowInfo is already added. Can't add again.");
1011         return;
1012     }
1013 
1014     if (!abilityRecord->IsAbilityState(ACTIVATING)) {
1015         HILOG_INFO("Add windowInfo at state: %{public}d.", abilityRecord->GetAbilityState());
1016     }
1017     if (windowTokenToAbilityMap_[windowToken] != nullptr) {
1018         // It shouldn't happen. Possible reasons for this case:
1019         // 1. windowmanager generates same window token.
1020         // 2. abilityms doesn't destroy ability in terminate process.
1021         HILOG_ERROR("Window token has been added to other AbilityRecord. ability name: %{private}s",
1022             abilityRecord->GetAbilityInfo().name.c_str());
1023     } else {
1024         abilityRecord->AddWindowInfo(windowToken);
1025         windowTokenToAbilityMap_[windowToken] = abilityRecord;
1026         HILOG_INFO("Add windowInfo complete, ability:%{public}s", abilityRecord->GetAbilityInfo().name.c_str());
1027     }
1028 }
1029 
OnAbilityRequestDone(const sptr<IRemoteObject> & token,const int32_t state)1030 void AbilityStackManager::OnAbilityRequestDone(const sptr<IRemoteObject> &token, const int32_t state)
1031 {
1032     HILOG_DEBUG("Ability request app state %{public}d done.", state);
1033     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1034     AppAbilityState abilitState = DelayedSingleton<AppScheduler>::GetInstance()->ConvertToAppAbilityState(state);
1035     if (abilitState == AppAbilityState::ABILITY_STATE_FOREGROUND) {
1036         auto abilityRecord = GetAbilityRecordByToken(token);
1037         CHECK_POINTER(abilityRecord);
1038         std::string element = abilityRecord->GetWant().GetElement().GetURI();
1039         HILOG_DEBUG("ability: %{public}s", element.c_str());
1040         abilityRecord->Activate();
1041     }
1042 }
1043 
OnAppStateChanged(const AppInfo & info)1044 void AbilityStackManager::OnAppStateChanged(const AppInfo &info)
1045 {
1046     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1047 
1048     if (info.state == AppState::TERMINATED || info.state == AppState::END) {
1049         for (auto &ability : terminateAbilityRecordList_) {
1050             if (!ability) {
1051                 continue;
1052             }
1053             if (ability->GetApplicationInfo().name == info.appName &&
1054                 (info.processName == ability->GetAbilityInfo().process ||
1055                 info.processName == ability->GetApplicationInfo().bundleName)) {
1056                 ability->SetAppState(info.state);
1057             }
1058         }
1059     } else {
1060         for (auto &stack : missionStackList_) {
1061             std::vector<MissionRecordInfo> missions;
1062             stack->GetAllMissionInfo(missions);
1063             for (auto &missionInfo : missions) {
1064                 auto mission = stack->GetMissionRecordById(missionInfo.id);
1065                 if (!mission) {
1066                     HILOG_ERROR("Mission is nullptr.");
1067                     continue;
1068                 }
1069                 std::vector<AbilityRecordInfo> abilitys;
1070                 mission->GetAllAbilityInfo(abilitys);
1071                 for (auto &abilityInfo : abilitys) {
1072                     auto ability = mission->GetAbilityRecordById(abilityInfo.id);
1073                     if (!ability) {
1074                         HILOG_ERROR("Ability is nullptr.");
1075                         continue;
1076                     }
1077 
1078                     if (ability->GetApplicationInfo().name == info.appName &&
1079                         (info.processName == ability->GetAbilityInfo().process ||
1080                         info.processName == ability->GetApplicationInfo().bundleName)) {
1081                         ability->SetAppState(info.state);
1082                     }
1083                 }
1084             }
1085         }
1086     }
1087 }
1088 
CompleteActive(const std::shared_ptr<AbilityRecord> & abilityRecord)1089 void AbilityStackManager::CompleteActive(const std::shared_ptr<AbilityRecord> &abilityRecord)
1090 {
1091     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1092 
1093     CHECK_POINTER(abilityRecord);
1094     std::string element = abilityRecord->GetWant().GetElement().GetURI();
1095     HILOG_INFO("ability: %{public}s", element.c_str());
1096 
1097     abilityRecord->SetAbilityState(AbilityState::ACTIVE);
1098     // update top active ability
1099     UpdateFocusAbilityRecord(abilityRecord);
1100 
1101     // multi window moving, complete state.
1102     if (abilityRecord->GetInMovingState()) {
1103         // top ability active at last, finish moving.
1104         if (abilityRecord == GetCurrentTopAbility()) {
1105             HILOG_DEBUG("Complete multi window moving,target state is active.");
1106             abilityRecord->SetInMovingState(false);
1107             isMultiWinMoving_ = false;
1108             return;
1109         }
1110         // background to active state.
1111         abilityRecord->SetInMovingState(false);
1112         ContinueLifecycle();
1113         return;
1114     }
1115 
1116     DelayedSingleton<AbilityManagerService>::GetInstance()->NotifyBmsAbilityLifeStatus(
1117         abilityRecord->GetAbilityInfo().bundleName,
1118         abilityRecord->GetAbilityInfo().name,
1119         AbilityUtil::UTCTimeSeconds());
1120 #if BINDER_IPC_32BIT
1121     HILOG_INFO("notify bms ability life status, bundle name:%{public}s, ability name:%{public}s, time:%{public}lld",
1122         abilityRecord->GetAbilityInfo().bundleName.c_str(),
1123         abilityRecord->GetAbilityInfo().name.c_str(),
1124         AbilityUtil::UTCTimeSeconds());
1125 #else
1126     HILOG_INFO("notify bms ability life status, bundle name:%{public}s, ability name:%{public}s, time:%{public}ld",
1127         abilityRecord->GetAbilityInfo().bundleName.c_str(),
1128         abilityRecord->GetAbilityInfo().name.c_str(),
1129         AbilityUtil::UTCTimeSeconds());
1130 #endif
1131 
1132     auto self(shared_from_this());
1133     auto startWaittingAbilityTask = [self]() { self->StartWaittingAbility(); };
1134 
1135     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
1136     CHECK_POINTER_LOG(handler, "Fail to get AbilityEventHandler.");
1137     if (abilityRecord->GetPowerState()) {
1138         CHECK_POINTER(powerStorage_);
1139         bool isActiveAbility = false;
1140         auto powerActiveStorages = powerStorage_->GetPowerOffActiveRecord();
1141         for (auto &powerActiveStorage : powerActiveStorages) {
1142             auto storageActiveAbility = powerActiveStorage.ability.lock();
1143             if (abilityRecord == storageActiveAbility) {
1144                 isActiveAbility = true;
1145             }
1146         }
1147         HILOG_DEBUG("isActiveAbility value %{public}d", static_cast<int>(isActiveAbility));
1148         if (isActiveAbility && abilityRecord == GetCurrentTopAbility()) {
1149             HILOG_DEBUG("Top ability, complete active.");
1150             abilityRecord->SetPowerState(false);
1151             handler->PostTask(startWaittingAbilityTask, "startWaittingAbility");
1152             powerStorage_.reset();
1153             return;
1154         }
1155         if (isActiveAbility) {
1156             abilityRecord->SetPowerState(false);
1157             return;
1158         }
1159         HILOG_DEBUG("Not top ability, need complete inactive.");
1160         abilityRecord->ProcessInactivate();
1161         return;
1162     }
1163 
1164     if (abilityRecord->IsToEnd()) {
1165         abilityRecord->SetToEnd(false);
1166     }
1167 
1168     /* PostTask to trigger start Ability from waiting queue */
1169     handler->PostTask(startWaittingAbilityTask, "startWaittingAbility");
1170 
1171     auto preAbilityRecord = abilityRecord->GetPreAbilityRecord();
1172     // 1. preAbility must be inactive when start ability.
1173     // move preAbility to background only if it was inactive.
1174     if (preAbilityRecord) {
1175         auto preStackId = preAbilityRecord->GetMissionStackId();
1176         auto currentStackId = abilityRecord->GetMissionStackId();
1177         auto preMissionId = preAbilityRecord->GetMissionRecordId();
1178         auto currentMissionId = abilityRecord->GetMissionRecordId();
1179         auto isBackground =
1180             (!IsTopInMission(preAbilityRecord)) || preAbilityRecord->IsToEnd() ||
1181             ((IsFullScreenStack(preStackId) && IsFullScreenStack(currentStackId)) ||
1182                 ((preStackId == FLOATING_MISSION_STACK_ID) && (currentStackId == FLOATING_MISSION_STACK_ID) &&
1183                     preMissionId == currentMissionId) ||
1184                 ((preStackId == FLOATING_MISSION_STACK_ID) && (currentStackId == FLOATING_MISSION_STACK_ID) &&
1185                     !SupportSyncVisualByStackId(FLOATING_MISSION_STACK_ID) && preMissionId != currentMissionId));
1186 
1187         if (isBackground && preAbilityRecord->IsAbilityState(AbilityState::INACTIVE) &&
1188             !AbilityUtil::IsSystemDialogAbility(
1189             abilityRecord->GetAbilityInfo().bundleName, abilityRecord->GetAbilityInfo().name)) {
1190             std::string preElement = preAbilityRecord->GetWant().GetElement().GetURI();
1191             HILOG_INFO("Pre ability record: %{public}s", preElement.c_str());
1192             // preAbility was inactive ,resume new want flag to false
1193             MoveToBackgroundTask(preAbilityRecord);
1194             // Flag completed move to end.
1195             if (preAbilityRecord->IsToEnd()) {
1196                 preAbilityRecord->SetToEnd(false);
1197             }
1198         }
1199     }
1200 
1201     // 2. nextAbility was in terminate list when terminate ability.
1202     // should move to background and then terminate.
1203     std::shared_ptr<AbilityRecord> nextAbilityRecord = abilityRecord->GetNextAbilityRecord();
1204     if (nextAbilityRecord != nullptr && nextAbilityRecord->IsAbilityState(AbilityState::INACTIVE) &&
1205         nextAbilityRecord->IsTerminating()) {
1206         std::string nextElement = nextAbilityRecord->GetWant().GetElement().GetURI();
1207         HILOG_INFO("Next ability record : %{public}s", nextElement.c_str());
1208         MoveToBackgroundTask(nextAbilityRecord);
1209     }
1210 
1211     // 3. when the mission ends and returns to lanucher directly, the next and back are inconsistent.
1212     // shoukd move back ability to background and then terminate.
1213     std::shared_ptr<AbilityRecord> backAbilityRecord = abilityRecord->GetBackAbilityRecord();
1214     if (backAbilityRecord != nullptr && backAbilityRecord->IsAbilityState(AbilityState::INACTIVE) &&
1215         backAbilityRecord->IsTerminating() &&
1216         (nextAbilityRecord == nullptr || nextAbilityRecord->GetRecordId() != backAbilityRecord->GetRecordId())) {
1217         std::string backElement = backAbilityRecord->GetWant().GetElement().GetURI();
1218         HILOG_INFO("Back ability record: %{public}s", backElement.c_str());
1219         MoveToBackgroundTask(backAbilityRecord);
1220     }
1221     if (powerOffing_ && waittingAbilityQueue_.empty()) {
1222         HILOG_INFO("Wait for the ability life cycle to complete and execute poweroff.");
1223         PowerOffLocked();
1224     }
1225 }
1226 
MoveToBackgroundTask(const std::shared_ptr<AbilityRecord> & abilityRecord)1227 void AbilityStackManager::MoveToBackgroundTask(const std::shared_ptr<AbilityRecord> &abilityRecord)
1228 {
1229     CHECK_POINTER(abilityRecord);
1230     abilityRecord->SetIsNewWant(false);
1231     std::string backElement = abilityRecord->GetWant().GetElement().GetURI();
1232     HILOG_INFO("Ability record: %{public}s", backElement.c_str());
1233     auto self(shared_from_this());
1234     auto task = [abilityRecord, self]() {
1235         HILOG_WARN("Stack manager move to background timeout.");
1236         self->CompleteBackground(abilityRecord);
1237     };
1238     abilityRecord->MoveToBackground(task);
1239 }
1240 
CompleteInactive(const std::shared_ptr<AbilityRecord> & abilityRecord)1241 void AbilityStackManager::CompleteInactive(const std::shared_ptr<AbilityRecord> &abilityRecord)
1242 {
1243     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1244     std::string element = abilityRecord->GetWant().GetElement().GetURI();
1245     HILOG_INFO("ability: %{public}s", element.c_str());
1246     abilityRecord->SetAbilityState(AbilityState::INACTIVE);
1247 
1248     // 0. multi window moving , complete lifecycle.
1249     if (abilityRecord->GetInMovingState()) {
1250         if (abilityRecord == GetCurrentTopAbility()) {
1251             ContinueLifecycle();
1252             return;
1253         }
1254         MoveToBackgroundTask(abilityRecord);
1255         abilityRecord->SetInMovingState(false);
1256         // to process next active ability
1257         ContinueLifecycle();
1258         return;
1259     }
1260 
1261     if (abilityRecord->IsToEnd()) {
1262         auto nextAbility = abilityRecord->GetNextAbilityRecord();
1263         if (!nextAbility || (nextAbility && !nextAbility->IsToEnd())) {
1264             abilityRecord->SetToEnd(false);
1265             MoveToBackgroundTask(abilityRecord);
1266             return;
1267         }
1268     }
1269 
1270     // ability state is inactive
1271     if (abilityRecord->GetPowerState()) {
1272         CHECK_POINTER(powerStorage_);
1273         auto powerActiveStorages = powerStorage_->GetPowerOffActiveRecord();
1274         for (auto &powerActiveStorage : powerActiveStorages) {
1275             auto storageActiveAbility = powerActiveStorage.ability.lock();
1276             if (abilityRecord == storageActiveAbility) {
1277                 abilityRecord->SetPowerState(false);
1278                 MoveToBackgroundTask(abilityRecord);
1279                 return;
1280             }
1281         }
1282 
1283         HILOG_DEBUG("Complete ,target state is inactive.");
1284         abilityRecord->SetPowerState(false);
1285         auto powerInActiveStorages = powerStorage_->GetPowerOffInActiveRecord();
1286         for (auto &powerInActiveStorage : powerInActiveStorages) {
1287             auto storageInActiveAbility = powerInActiveStorage.ability.lock();
1288             CHECK_POINTER_CONTINUE(storageInActiveAbility);
1289             if (storageInActiveAbility->GetPowerState()) {
1290                 HILOG_DEBUG("Wait other ability to complete lifecycle. Ability: %{public}s.",
1291                     storageInActiveAbility->GetAbilityInfo().name.c_str());
1292                 return;
1293             }
1294         }
1295         if (ChangedPowerStorageAbilityToActive(powerStorage_) != ERR_OK) {
1296             HILOG_ERROR("ChangedPowerStorageAbilityToActive Fail");
1297             return;
1298         }
1299         return;
1300     }
1301     // 1. it may be inactive callback of terminate ability.
1302     if (abilityRecord->IsTerminating()) {
1303         abilityRecord->SendResultToCallers();
1304         if (abilityRecord->IsForceTerminate()) {
1305             HILOG_WARN("Ability is forced to terminate.");
1306             MoveToBackgroundTask(abilityRecord);
1307             return;
1308         }
1309         auto nextActiveAbility = abilityRecord->GetNextAbilityRecord();
1310         CHECK_POINTER_LOG(nextActiveAbility, "No top ability! Jump to launcher.");
1311         if (nextActiveAbility->IsAbilityState(ACTIVE)) {
1312             MoveToBackgroundTask(abilityRecord);
1313             UpdateFocusAbilityRecord(nextActiveAbility, true);
1314             return;
1315         }
1316         // need to specify the back ability as the current ability
1317         nextActiveAbility->SetBackAbilityRecord(abilityRecord);
1318         // top ability.has been pushed into stack, but haven't load.
1319         // so we need load it first
1320         nextActiveAbility->ProcessActivate();
1321         return;
1322     }
1323 
1324     // 2. it may be callback of restart ability.
1325     if (abilityRecord->IsRestarting()) {
1326         HILOG_INFO("%{public}s, back ability record: %{public}s", __func__, element.c_str());
1327         MoveToBackgroundTask(abilityRecord);
1328         return;
1329     }
1330     // 3. it may be callback of start ability.
1331     // if next ability has been launched and is in bottom of mission, just resume other than loading ability.
1332     auto nextAbilityRecord = abilityRecord->GetNextAbilityRecord();
1333     CHECK_POINTER_LOG(nextAbilityRecord, "Failed to get next ability record.");
1334 
1335     std::string nextElement = nextAbilityRecord->GetWant().GetElement().GetURI();
1336     HILOG_DEBUG("Next ability record: %{public}s", nextElement.c_str());
1337     nextAbilityRecord->ProcessActivate();
1338 }
1339 
CompleteBackground(const std::shared_ptr<AbilityRecord> & abilityRecord)1340 void AbilityStackManager::CompleteBackground(const std::shared_ptr<AbilityRecord> &abilityRecord)
1341 {
1342     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1343     std::string element = abilityRecord->GetWant().GetElement().GetURI();
1344     sptr<Token> token = abilityRecord->GetToken();
1345     HILOG_INFO("ability: %{public}s", element.c_str());
1346 
1347     if (abilityRecord->GetAbilityState() == ACTIVATING || abilityRecord->GetAbilityState() == ACTIVE ||
1348         abilityRecord->GetAbilityState() == INITIAL) {
1349         HILOG_ERROR("Ability may be activing or active, it can't complete background.");
1350         return;
1351     }
1352 
1353     abilityRecord->SetAbilityState(AbilityState::BACKGROUND);
1354     // send application state to AppMS.
1355     // notify AppMS to update application state.
1356     DelayedSingleton<AppScheduler>::GetInstance()->MoveToBackground(token);
1357     // Abilities ahead of the one started with SingleTask mode were put in terminate list, we need to terminate
1358     // them.
1359     auto self(shared_from_this());
1360     for (auto terminateAbility : terminateAbilityRecordList_) {
1361         if (terminateAbility->IsAbilityState(AbilityState::BACKGROUND)) {
1362             auto timeoutTask = [terminateAbility, self]() {
1363                 HILOG_WARN("Disconnect ability terminate timeout.");
1364                 self->CompleteTerminate(terminateAbility);
1365             };
1366             terminateAbility->Terminate(timeoutTask);
1367         }
1368     }
1369 
1370     if (abilityRecord->IsRestarting() && abilityRecord->IsAbilityState(AbilityState::BACKGROUND)) {
1371         auto timeoutTask = [abilityRecord, self]() {
1372             HILOG_WARN("disconnect ability terminate timeout.");
1373             self->CompleteTerminate(abilityRecord);
1374         };
1375         abilityRecord->Terminate(timeoutTask);
1376     }
1377 }
1378 
CompleteTerminate(const std::shared_ptr<AbilityRecord> & abilityRecord)1379 void AbilityStackManager::CompleteTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord)
1380 {
1381     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1382 
1383     CHECK_POINTER(abilityRecord);
1384     std::string element = abilityRecord->GetWant().GetElement().GetURI();
1385     HILOG_INFO("ability: %{public}s", element.c_str());
1386 
1387     if (!abilityRecord->IsAbilityState(AbilityState::TERMINATING)) {
1388         HILOG_ERROR("%{public}s, ability is not terminating.", __func__);
1389         return;
1390     }
1391 
1392     // notify AppMS terminate
1393     if (abilityRecord->TerminateAbility() != ERR_OK) {
1394         // Don't return here
1395         HILOG_ERROR("AppMS fail to terminate ability.");
1396     }
1397     // destroy abilityRecord
1398     auto windowInfo = abilityRecord->GetWindowInfo();
1399     if (windowInfo != nullptr) {
1400         windowTokenToAbilityMap_.erase(windowInfo->windowToken_);
1401     }
1402 
1403     if (abilityRecord->IsRestarting()) {
1404         abilityRecord->SetAbilityState(AbilityState::INITIAL);
1405         abilityRecord->SetScheduler(nullptr);
1406         abilityRecord->LoadAbility();
1407     }
1408     for (auto it : terminateAbilityRecordList_) {
1409         if (it == abilityRecord) {
1410             terminateAbilityRecordList_.remove(it);
1411             HILOG_DEBUG("Destroy ability record count %ld", abilityRecord.use_count());
1412             break;
1413         }
1414         HILOG_WARN("Can't find ability in terminate list.");
1415     }
1416 }
1417 
Dump(std::vector<std::string> & info)1418 void AbilityStackManager::Dump(std::vector<std::string> &info)
1419 {
1420     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1421     std::string dumpInfo = "User ID #" + std::to_string(userId_);
1422     info.push_back(dumpInfo);
1423     for (auto missionStack : missionStackList_) {
1424         missionStack->Dump(info);
1425     }
1426 }
1427 
DumpStack(int missionStackId,std::vector<std::string> & info)1428 void AbilityStackManager::DumpStack(int missionStackId, std::vector<std::string> &info)
1429 {
1430     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1431     std::string dumpInfo = "User ID #" + std::to_string(userId_);
1432     info.push_back(dumpInfo);
1433     for (auto missionStack : missionStackList_) {
1434         if (missionStackId == missionStack->GetMissionStackId()) {
1435             missionStack->Dump(info);
1436             return;
1437         }
1438     }
1439     info.push_back("Invalid stack number, please see ability dump stack-list.");
1440     return;
1441 }
1442 
DumpStackList(std::vector<std::string> & info)1443 void AbilityStackManager::DumpStackList(std::vector<std::string> &info)
1444 {
1445     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1446     std::string dumpInfo = "User ID #" + std::to_string(userId_);
1447     info.push_back(dumpInfo);
1448     for (auto missionStack : missionStackList_) {
1449         missionStack->DumpStackList(info);
1450     }
1451 }
1452 
DumpFocusMap(std::vector<std::string> & info)1453 void AbilityStackManager::DumpFocusMap(std::vector<std::string> &info)
1454 {
1455     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1456     std::string dumpInfo = "User ID #" + std::to_string(userId_);
1457     info.push_back(dumpInfo);
1458     for (auto iter : focusAbilityRecordMap_) {
1459         std::string displayInfo = "  Display ID #" + std::to_string(iter.first);
1460         info.push_back(displayInfo);
1461         auto ability = iter.second;
1462         if (ability.lock()) {
1463             ability.lock()->Dump(info);
1464         }
1465     }
1466 }
1467 
GetAllStackInfo(StackInfo & stackInfo)1468 void AbilityStackManager::GetAllStackInfo(StackInfo &stackInfo)
1469 {
1470     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1471     for (auto missionStack : missionStackList_) {
1472         MissionStackInfo missionStackInfo;
1473         missionStackInfo.id = missionStack->GetMissionStackId();
1474         missionStack->GetAllMissionInfo(missionStackInfo.missionRecords);
1475         stackInfo.missionStackInfos.emplace_back(missionStackInfo);
1476     }
1477 }
1478 
DumpMission(int missionId,std::vector<std::string> & info)1479 void AbilityStackManager::DumpMission(int missionId, std::vector<std::string> &info)
1480 {
1481     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1482     std::string dumpInfo = "User ID #" + std::to_string(userId_);
1483     info.push_back(dumpInfo);
1484     for (auto missionStack : missionStackList_) {
1485         auto mission = missionStack->GetMissionRecordById(missionId);
1486         if (mission != nullptr) {
1487             mission->Dump(info);
1488             return;
1489         }
1490     }
1491     info.push_back("error: invalid mission number, please see 'ability dump --stack-list'.");
1492     return;
1493 }
1494 
DumpTopAbility(std::vector<std::string> & info)1495 void AbilityStackManager::DumpTopAbility(std::vector<std::string> &info)
1496 {
1497     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1498     std::string dumpInfo = "User ID #" + std::to_string(userId_);
1499     auto topAbility = GetCurrentTopAbility();
1500     if (topAbility) {
1501         topAbility->Dump(info);
1502     }
1503     return;
1504 }
1505 
DumpWaittingAbilityQueue(std::string & result)1506 void AbilityStackManager::DumpWaittingAbilityQueue(std::string &result)
1507 {
1508     std::queue<AbilityRequest> copyQueue;
1509     {
1510         std::lock_guard<std::recursive_mutex> guard(stackLock_);
1511         if (waittingAbilityQueue_.empty()) {
1512             result = "The waitting ability queue is empty.";
1513             return;
1514         }
1515         copyQueue = waittingAbilityQueue_;
1516     }
1517 
1518     result = "User ID #" + std::to_string(userId_) + LINE_SEPARATOR;
1519     while (!copyQueue.empty()) {
1520         auto ability = copyQueue.front();
1521         std::vector<std::string> state;
1522         ability.Dump(state);
1523 
1524         for (auto it : state) {
1525             result += it;
1526             result += LINE_SEPARATOR;
1527         }
1528         copyQueue.pop();
1529     }
1530     return;
1531 }
1532 
EnqueueWaittingAbility(const AbilityRequest & abilityRequest)1533 void AbilityStackManager::EnqueueWaittingAbility(const AbilityRequest &abilityRequest)
1534 {
1535     waittingAbilityQueue_.push(abilityRequest);
1536     return;
1537 }
1538 
StartWaittingAbility()1539 void AbilityStackManager::StartWaittingAbility()
1540 {
1541     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1542     auto topAbility = GetCurrentTopAbility();
1543     CHECK_POINTER(topAbility);
1544 
1545     if (!topAbility->IsAbilityState(ACTIVE)) {
1546         HILOG_INFO("Top ability is not active, must return for start waiting again.");
1547         return;
1548     }
1549 
1550     if (!waittingAbilityQueue_.empty()) {
1551         AbilityRequest abilityRequest = waittingAbilityQueue_.front();
1552         waittingAbilityQueue_.pop();
1553         StartAbilityLocked(topAbility, abilityRequest);
1554         return;
1555     }
1556 }
1557 
GetMissionRecordAndAbilityRecord(const AbilityRequest & abilityRequest,const std::shared_ptr<AbilityRecord> & currentTopAbility,std::shared_ptr<AbilityRecord> & targetAbilityRecord,std::shared_ptr<MissionRecord> & targetMissionRecord)1558 void AbilityStackManager::GetMissionRecordAndAbilityRecord(const AbilityRequest &abilityRequest,
1559     const std::shared_ptr<AbilityRecord> &currentTopAbility, std::shared_ptr<AbilityRecord> &targetAbilityRecord,
1560     std::shared_ptr<MissionRecord> &targetMissionRecord)
1561 {
1562     HILOG_DEBUG("Get mission record and ability record.");
1563     CHECK_POINTER(currentMissionStack_);
1564 
1565     // The singleInstance start mode, mission name is #bundleName:abilityName.
1566     if (abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::SINGLETON) {
1567         GetRecordBySingleton(abilityRequest, currentTopAbility, targetAbilityRecord, targetMissionRecord);
1568         // The standard start mode, mission name is bundle name by default.
1569     } else {
1570         GetRecordByStandard(abilityRequest, currentTopAbility, targetAbilityRecord, targetMissionRecord);
1571     }
1572 }
1573 
GetRecordBySingleton(const AbilityRequest & abilityRequest,const std::shared_ptr<AbilityRecord> & currentTopAbility,std::shared_ptr<AbilityRecord> & targetAbilityRecord,std::shared_ptr<MissionRecord> & targetMissionRecord)1574 void AbilityStackManager::GetRecordBySingleton(const AbilityRequest &abilityRequest,
1575     const std::shared_ptr<AbilityRecord> &currentTopAbility, std::shared_ptr<AbilityRecord> &targetAbilityRecord,
1576     std::shared_ptr<MissionRecord> &targetMissionRecord)
1577 {
1578     std::string bundleName =
1579         AbilityUtil::ConvertBundleNameSingleton(abilityRequest.abilityInfo.bundleName, abilityRequest.abilityInfo.name);
1580     auto missionRecord = GetMissionRecordByName(bundleName);
1581     if (missionRecord == nullptr) {
1582         targetAbilityRecord = AbilityRecord::CreateAbilityRecord(abilityRequest);
1583         targetMissionRecord = std::make_shared<MissionRecord>(bundleName);
1584     } else {
1585         targetAbilityRecord = missionRecord->GetTopAbilityRecord();
1586         if (targetAbilityRecord != nullptr) {
1587             targetAbilityRecord->SetWant(abilityRequest.want);
1588             targetAbilityRecord->SetIsNewWant(true);
1589             CheckMissionRecordIsResume(missionRecord);
1590         }
1591         targetMissionRecord = missionRecord;
1592     }
1593 }
1594 
GetRecordByStandard(const AbilityRequest & abilityRequest,const std::shared_ptr<AbilityRecord> & currentTopAbility,std::shared_ptr<AbilityRecord> & targetAbilityRecord,std::shared_ptr<MissionRecord> & targetMissionRecord)1595 void AbilityStackManager::GetRecordByStandard(const AbilityRequest &abilityRequest,
1596     const std::shared_ptr<AbilityRecord> &currentTopAbility, std::shared_ptr<AbilityRecord> &targetAbilityRecord,
1597     std::shared_ptr<MissionRecord> &targetMissionRecord)
1598 {
1599     bool isStackChanged = false;
1600     if (currentTopAbility) {
1601         isStackChanged = (currentTopAbility->IsLauncherAbility() && !IsLauncherAbility(abilityRequest)) ||
1602                          (!currentTopAbility->IsLauncherAbility() && IsLauncherAbility(abilityRequest));
1603     }
1604 
1605     if (currentTopAbility == nullptr || (currentTopAbility && isStackChanged) ||
1606         (currentTopAbility && currentTopAbility->GetAbilityInfo().launchMode == AppExecFwk::LaunchMode::SINGLETON)) {
1607         // first get target mission record by bundleName
1608         auto missionRecord = GetMissionRecordByName(abilityRequest.abilityInfo.bundleName);
1609         if (missionRecord == nullptr) {
1610             targetAbilityRecord = AbilityRecord::CreateAbilityRecord(abilityRequest);
1611             targetMissionRecord = std::make_shared<MissionRecord>(abilityRequest.abilityInfo.bundleName);
1612         } else {
1613             /* If current top ability is singleton mode, target mission record will be changed.
1614              *  Check whether the requested ability is not at the top of the stack of the target mission,
1615              *  True: Need to create a new one . Other: Restart the top ability of this mission.
1616              */
1617             CheckMissionRecordIsResume(missionRecord);
1618 
1619             if (currentTopAbility && (!isStackChanged) &&
1620                 (currentTopAbility->GetAbilityInfo().launchMode == AppExecFwk::LaunchMode::SINGLETON) &&
1621                 ((!missionRecord->IsTopAbilityRecordByName(abilityRequest.abilityInfo.name)) ||
1622                 (missionRecord->IsTopAbilityRecordByName(abilityRequest.abilityInfo.name) &&
1623                 abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::STANDARD))) {
1624                 targetAbilityRecord = AbilityRecord::CreateAbilityRecord(abilityRequest);
1625             } else {
1626                 targetAbilityRecord = missionRecord->GetTopAbilityRecord();
1627                 if (targetAbilityRecord != nullptr) {
1628                     // The third-party app is called back from the desktop,
1629                     // and the specified slice route does not take effect.
1630                     targetAbilityRecord->SetWant(abilityRequest.want);
1631                     targetAbilityRecord->SetIsNewWant(true);
1632                 }
1633             }
1634             targetMissionRecord = missionRecord;
1635         }
1636     } else if (currentTopAbility && (!isStackChanged)) {
1637         // The requested ability is already top ability. Reuse top ability.
1638         targetMissionRecord = currentTopAbility->GetMissionRecord();
1639         CheckMissionRecordIsResume(targetMissionRecord);
1640         if (abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::SINGLETOP &&
1641             currentTopAbility->GetMissionRecord()->IsTopAbilityRecordByName(abilityRequest.abilityInfo.name)) {
1642             targetAbilityRecord = currentTopAbility;
1643             targetAbilityRecord->SetWant(abilityRequest.want);
1644             targetAbilityRecord->SetIsNewWant(true);
1645         } else {
1646             targetAbilityRecord = AbilityRecord::CreateAbilityRecord(abilityRequest);
1647         }
1648     }
1649 }
1650 
IsLauncherAbility(const AbilityRequest & abilityRequest) const1651 bool AbilityStackManager::IsLauncherAbility(const AbilityRequest &abilityRequest) const
1652 {
1653     return abilityRequest.abilityInfo.applicationInfo.isLauncherApp;
1654 }
1655 
IsLauncherMission(int id)1656 bool AbilityStackManager::IsLauncherMission(int id)
1657 {
1658     if (launcherMissionStack_ == nullptr || launcherMissionStack_->GetMissionRecordById(id) == nullptr) {
1659         return false;
1660     }
1661     return true;
1662 }
1663 
GetRecentMissions(const int32_t numMax,const int32_t flags,std::vector<AbilityMissionInfo> & recentList)1664 int AbilityStackManager::GetRecentMissions(
1665     const int32_t numMax, const int32_t flags, std::vector<AbilityMissionInfo> &recentList)
1666 {
1667     HILOG_INFO("Get recent missions.");
1668     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1669     if (numMax < 0) {
1670         HILOG_ERROR("numMax is invalid");
1671         return ERR_INVALID_VALUE;
1672     }
1673     if (flags < RECENT_WITH_EXCLUDED || flags > RECENT_IGNORE_UNAVAILABLE) {
1674         HILOG_ERROR("flags is invalid");
1675         return ERR_INVALID_VALUE;
1676     }
1677 
1678     return GetRecentMissionsLocked(numMax, flags, recentList);
1679 }
1680 
GetRecentMissionsLocked(const int32_t numMax,const int32_t flags,std::vector<AbilityMissionInfo> & recentList)1681 int AbilityStackManager::GetRecentMissionsLocked(
1682     const int32_t numMax, const int32_t flags, std::vector<AbilityMissionInfo> &recentList)
1683 {
1684     HILOG_INFO("Get recent missions locked.");
1685     CHECK_POINTER_AND_RETURN(defaultMissionStack_, ERR_NO_INIT);
1686 
1687     bool withExcluded = (static_cast<uint32_t>(flags) & RECENT_WITH_EXCLUDED) != 0;
1688     std::vector<MissionRecordInfo> missionInfos;
1689     defaultMissionStack_->GetAllMissionInfo(missionInfos);
1690     for (auto &mission : missionInfos) {
1691         if (static_cast<int>(recentList.size()) >= numMax) {
1692             break;
1693         }
1694         // flags is RECENT_IGNORE_UNAVAILABLE,
1695         // You need to determine the mission optimized by the process
1696         // Then continue
1697         if (!withExcluded) {
1698             auto missionRecord = defaultMissionStack_->GetMissionRecordById(mission.id);
1699             if (!missionRecord) {
1700                 HILOG_ERROR("Mission is nullptr, continue.");
1701                 continue;
1702             }
1703             auto ability = missionRecord->GetTopAbilityRecord();
1704             if (!ability) {
1705                 HILOG_ERROR("Ability is nullptr, continue.");
1706                 continue;
1707             }
1708             if (ability->IsAbilityState(AbilityState::INITIAL)) {
1709                 HILOG_INFO("Flag is RECENT_IGNORE_UNAVAILABLE, ability state: INITIAL, continue.");
1710                 continue;
1711             }
1712         }
1713         AbilityMissionInfo recentMissionInfo;
1714         CreateRecentMissionInfo(mission, recentMissionInfo);
1715         recentList.emplace_back(recentMissionInfo);
1716     }
1717 
1718     return ERR_OK;
1719 }
1720 
CreateRecentMissionInfo(const MissionRecordInfo & mission,AbilityMissionInfo & recentMissionInfo)1721 void AbilityStackManager::CreateRecentMissionInfo(
1722     const MissionRecordInfo &mission, AbilityMissionInfo &recentMissionInfo)
1723 {
1724     HILOG_INFO("Create recent mission info.");
1725     recentMissionInfo.id = mission.id;
1726     recentMissionInfo.runingState = DEFAULT_INVAL_VALUE;
1727 
1728     auto missionRecord = GetMissionRecordFromAllStacks(mission.id);
1729     CHECK_POINTER_LOG(missionRecord, "Mission record is not exist.");
1730     auto parentStack = missionRecord->GetMissionStack();
1731     recentMissionInfo.missionStackId = parentStack->GetMissionStackId();
1732     auto baseAbility = missionRecord->GetBottomAbilityRecord();
1733     if (baseAbility != nullptr) {
1734         recentMissionInfo.baseWant = baseAbility->GetWant();
1735         OHOS::AppExecFwk::ElementName baseElement(baseAbility->GetAbilityInfo().deviceId,
1736             baseAbility->GetAbilityInfo().bundleName,
1737             baseAbility->GetAbilityInfo().name);
1738         recentMissionInfo.baseAbility = baseElement;
1739     }
1740 
1741     auto topAbility = missionRecord->GetTopAbilityRecord();
1742     if (topAbility != nullptr) {
1743         OHOS::AppExecFwk::ElementName topElement(topAbility->GetAbilityInfo().deviceId,
1744             topAbility->GetAbilityInfo().bundleName,
1745             topAbility->GetAbilityInfo().name);
1746         recentMissionInfo.topAbility = topElement;
1747 
1748         MissionDescriptionInfo missionDescription;
1749         missionDescription.label = topAbility->GetApplicationInfo().label;
1750         missionDescription.iconPath = topAbility->GetApplicationInfo().iconPath;
1751         recentMissionInfo.missionDescription = missionDescription;
1752     }
1753 
1754     if (auto desc = missionRecord->GetMissionDescriptionInfo()) {
1755         recentMissionInfo.missionDescription = *desc;
1756     }
1757 
1758     recentMissionInfo.size = missionRecord->GetAbilityRecordCount();
1759 }
1760 
SetMissionDescriptionInfo(const std::shared_ptr<AbilityRecord> & abilityRecord,const MissionDescriptionInfo & description)1761 int AbilityStackManager::SetMissionDescriptionInfo(
1762     const std::shared_ptr<AbilityRecord> &abilityRecord, const MissionDescriptionInfo &description)
1763 {
1764     HILOG_DEBUG("%{public}s called", __FUNCTION__);
1765     CHECK_POINTER_AND_RETURN(abilityRecord, SET_MISSION_INFO_FAILED);
1766 
1767     auto mission = abilityRecord->GetMissionRecord();
1768     CHECK_POINTER_AND_RETURN(mission, SET_MISSION_INFO_FAILED);
1769     auto ptr = std::make_shared<MissionDescriptionInfo>(description);
1770     mission->SetMissionDescriptionInfo(ptr);
1771 
1772     return ERR_OK;
1773 }
1774 
GetMissionLockModeState()1775 int AbilityStackManager::GetMissionLockModeState()
1776 {
1777     HILOG_DEBUG("%{public}s called", __FUNCTION__);
1778     if (!lockMissionContainer_) {
1779         return LockMissionContainer::LockMissionState::LOCK_MISSION_STATE_NONE;
1780     }
1781 
1782     return lockMissionContainer_->GetLockedMissionState();
1783 }
1784 
UpdateConfiguration(const DummyConfiguration & config)1785 int AbilityStackManager::UpdateConfiguration(const DummyConfiguration &config)
1786 {
1787     HILOG_INFO("%{public}s called", __FUNCTION__);
1788     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1789 
1790     // update all stack configuration.
1791     for (auto &stack : missionStackList_) {
1792         CHECK_POINTER_AND_RETURN(stack, ERR_INVALID_VALUE);
1793         HILOG_DEBUG("stack id : %{public}d", stack->GetMissionStackId());
1794         std::shared_ptr<DummyConfiguration> configSptr = std::make_shared<DummyConfiguration>(config);
1795         stack->UpdateConfiguration(configSptr);
1796     }
1797 
1798     return ProcessConfigurationChange();
1799 }
1800 
ProcessConfigurationChange()1801 int AbilityStackManager::ProcessConfigurationChange()
1802 {
1803     HILOG_INFO("%{public}s called.", __FUNCTION__);
1804 
1805     // all active ability check whether process onconfigurationchanged
1806     for (auto &stack : missionStackList_) {
1807         CHECK_POINTER_AND_RETURN(stack, ERR_INVALID_VALUE);
1808         HILOG_DEBUG("stack id : %{public}d", stack->GetMissionStackId());
1809         std::vector<MissionRecordInfo> missionInfos;
1810         stack->GetAllMissionInfo(missionInfos);
1811         for (auto &mission : missionInfos) {
1812             auto missionRecord = stack->GetMissionRecordById(mission.id);
1813             if (!missionRecord) {
1814                 continue;
1815             }
1816             for (auto &it : mission.abilityRecordInfos) {
1817                 auto abilityRecord = missionRecord->GetAbilityRecordById(it.id);
1818                 if (abilityRecord && abilityRecord->IsAbilityState(AbilityState::ACTIVE)) {
1819                     abilityRecord->ProcessConfigurationChange();
1820                 }
1821             }
1822         }
1823     }
1824 
1825     return ERR_OK;
1826 }
1827 
RestartAbility(const std::shared_ptr<AbilityRecord> abilityRecord)1828 void AbilityStackManager::RestartAbility(const std::shared_ptr<AbilityRecord> abilityRecord)
1829 {
1830     HILOG_INFO("%{public}s called", __FUNCTION__);
1831     CHECK_POINTER(abilityRecord);
1832     abilityRecord->SetRestarting(true);
1833     if (abilityRecord->IsAbilityState(AbilityState::ACTIVE) ||
1834         abilityRecord->IsAbilityState(AbilityState::ACTIVATING)) {
1835         abilityRecord->Inactivate();
1836     } else if (abilityRecord->IsAbilityState(AbilityState::INACTIVE) ||
1837                abilityRecord->IsAbilityState(AbilityState::INACTIVATING)) {
1838         MoveToBackgroundTask(abilityRecord);
1839     } else if (abilityRecord->IsAbilityState(AbilityState::BACKGROUND) ||
1840                abilityRecord->IsAbilityState(AbilityState::MOVING_BACKGROUND)) {
1841         auto self(shared_from_this());
1842         auto timeoutTask = [abilityRecord, self]() {
1843             HILOG_WARN("disconnect ability terminate timeout.");
1844             self->CompleteTerminate(abilityRecord);
1845         };
1846         abilityRecord->Terminate(timeoutTask);
1847     } else {
1848         HILOG_WARN("target ability can't be restarted.");
1849     }
1850 }
1851 
MoveMissionToTop(int32_t missionId)1852 int AbilityStackManager::MoveMissionToTop(int32_t missionId)
1853 {
1854     HILOG_INFO("Move mission to top.");
1855     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1856     if (missionId < 0) {
1857         HILOG_ERROR("Mission id is invalid.");
1858         return ERR_INVALID_VALUE;
1859     }
1860 
1861     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
1862         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
1863         return ERR_INVALID_VALUE;
1864     }
1865 
1866     return MoveMissionToTopLocked(missionId);
1867 }
1868 
MoveMissionToTopLocked(int32_t missionId)1869 int AbilityStackManager::MoveMissionToTopLocked(int32_t missionId)
1870 {
1871     HILOG_INFO("Move mission to top locked.");
1872 
1873     if (isMultiWinMoving_) {
1874         HILOG_ERROR("System is moving multi window state, request deny.");
1875         return MOVE_MISSION_TO_STACK_MOVING_DENIED;
1876     }
1877 
1878     CHECK_TRUE_RETURN_RET((!defaultMissionStack_ || !launcherMissionStack_), ERR_NO_INIT, "Mission stack is invalid.");
1879     auto currentTopAbility = GetCurrentTopAbility();
1880     CHECK_POINTER_AND_RETURN(currentTopAbility, MOVE_MISSION_FAILED);
1881 
1882     auto currentStack = currentTopAbility->GetMissionRecord()->GetMissionStack();
1883     CHECK_POINTER_AND_RETURN(currentStack, MOVE_MISSION_FAILED);
1884 
1885     auto requestMissionRecord = GetMissionRecordFromAllStacks(missionId);
1886     CHECK_POINTER_AND_RETURN(requestMissionRecord, MOVE_MISSION_FAILED);
1887 
1888     CheckMissionRecordIsResume(requestMissionRecord);
1889 
1890     auto requestAbilityRecord = requestMissionRecord->GetTopAbilityRecord();
1891     CHECK_POINTER_AND_RETURN(requestAbilityRecord, MOVE_MISSION_FAILED);
1892 
1893     auto requestStack = requestMissionRecord->GetMissionStack();
1894     CHECK_POINTER_AND_RETURN(requestStack, MOVE_MISSION_FAILED);
1895 
1896     // request ability active, current ability active, change focus
1897     if (requestAbilityRecord->IsAbilityState(ACTIVE)) {
1898         MoveMissionStackToTop(requestStack);
1899         requestStack->MoveMissionRecordToTop(requestMissionRecord);
1900         UpdateFocusAbilityRecord(requestAbilityRecord, true);
1901         return ERR_OK;
1902     }
1903 
1904     if (currentStack->IsEqualStackId(FLOATING_MISSION_STACK_ID) &&
1905         IsFullScreenStack(requestStack->GetMissionStackId())) {
1906         auto fullScreenStack = GetTopFullScreenStack();
1907         CHECK_POINTER_AND_RETURN(fullScreenStack, MOVE_MISSION_FAILED);
1908         currentTopAbility = fullScreenStack->GetTopAbilityRecord();
1909     }
1910 
1911     if (IsFullScreenStack(currentStack->GetMissionStackId()) &&
1912         requestStack->IsEqualStackId(FLOATING_MISSION_STACK_ID)) {
1913         auto floatingStack = GetOrCreateMissionStack(FLOATING_MISSION_STACK_ID, false);
1914         auto topAbility = floatingStack->GetTopAbilityRecord();
1915         if (SupportSyncVisualByStackId(FLOATING_MISSION_STACK_ID) ||
1916             (!SupportSyncVisualByStackId(FLOATING_MISSION_STACK_ID) && requestAbilityRecord == topAbility)) {
1917             MoveMissionStackToTop(requestStack);
1918             requestAbilityRecord->ProcessActivate();
1919             return ERR_OK;
1920         }
1921         currentTopAbility = topAbility;
1922     }
1923 
1924     MoveMissionStackToTop(requestStack);
1925     MoveMissionAndAbility(currentTopAbility, requestAbilityRecord, requestMissionRecord);
1926 
1927     currentTopAbility->Inactivate();
1928     return ERR_OK;
1929 }
1930 
MoveMissionToEnd(const sptr<IRemoteObject> & token,const bool nonFirst)1931 int AbilityStackManager::MoveMissionToEnd(const sptr<IRemoteObject> &token, const bool nonFirst)
1932 {
1933     std::lock_guard<std::recursive_mutex> guard(stackLock_);
1934 
1935     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
1936         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
1937         return ERR_INVALID_VALUE;
1938     }
1939 
1940     if (isMultiWinMoving_) {
1941         HILOG_ERROR("System is moving multi window state, request deny.");
1942         return MOVE_MISSION_TO_STACK_MOVING_DENIED;
1943     }
1944 
1945     return MoveMissionToEndLocked(token, nonFirst);
1946 }
1947 
MoveMissionToEndLocked(const sptr<IRemoteObject> & token,const bool nonFirst)1948 int AbilityStackManager::MoveMissionToEndLocked(const sptr<IRemoteObject> &token, const bool nonFirst)
1949 {
1950     HILOG_INFO("Move mission to end locked.");
1951 
1952     CHECK_POINTER_AND_RETURN(token, MOVE_MISSION_FAILED);
1953 
1954     auto abilityRecord = GetAbilityRecordByToken(token);
1955     CHECK_POINTER_AND_RETURN(abilityRecord, MOVE_MISSION_FAILED);
1956 
1957     auto missionRecord = abilityRecord->GetMissionRecord();
1958     CHECK_POINTER_AND_RETURN(missionRecord, MOVE_MISSION_FAILED);
1959 
1960     if (!nonFirst) {
1961         if (missionRecord->GetBottomAbilityRecord() != abilityRecord) {
1962             HILOG_ERROR("nonFirst is false, it's not the bottom of the mission, can't move mission to end.");
1963             return MOVE_MISSION_FAILED;
1964         }
1965     }
1966 
1967     return MoveMissionToEndLocked(missionRecord->GetMissionRecordId());
1968 }
1969 
MoveMissionToEndLocked(int missionId)1970 int AbilityStackManager::MoveMissionToEndLocked(int missionId)
1971 {
1972     HILOG_INFO("Move mission to end locked by mission id.");
1973 
1974     if (isMultiWinMoving_) {
1975         HILOG_ERROR("System is moving multi window state, request deny.");
1976         return MOVE_MISSION_TO_STACK_MOVING_DENIED;
1977     }
1978 
1979     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
1980         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
1981         return ERR_INVALID_VALUE;
1982     }
1983     auto requestMission = GetMissionRecordFromAllStacks(missionId);
1984     CHECK_POINTER_AND_RETURN(requestMission, MOVE_MISSION_FAILED);
1985     auto requestAbility = requestMission->GetTopAbilityRecord();
1986     CHECK_POINTER_AND_RETURN(requestAbility, MOVE_MISSION_FAILED);
1987     auto requestStack = requestMission->GetMissionStack();
1988     CHECK_POINTER_AND_RETURN(requestStack, MOVE_MISSION_FAILED);
1989 
1990     if (!requestAbility->IsAbilityState(AbilityState::ACTIVE) ||
1991         requestAbility->GetAbilityInfo().applicationInfo.isLauncherApp) {
1992         HILOG_ERROR("Ability is not active, or ability is launcher, can't move mission to end.");
1993         return MOVE_MISSION_FAILED;
1994     }
1995     // current top ability hold focus
1996     auto currentTopAbility = GetCurrentTopAbility();
1997     CHECK_POINTER_AND_RETURN(currentTopAbility, MOVE_MISSION_FAILED);
1998     auto currentMission = currentTopAbility->GetMissionRecord();
1999     CHECK_POINTER_AND_RETURN(currentMission, MOVE_MISSION_FAILED);
2000     auto currentStack = currentMission->GetMissionStack();
2001     CHECK_POINTER_AND_RETURN(currentStack, MOVE_MISSION_FAILED);
2002 
2003     std::shared_ptr<AbilityRecord> targetAbilityRecord;
2004     std::shared_ptr<MissionRecord> targetMissionRecord;
2005     std::shared_ptr<MissionStack> targetMissionStack;
2006 
2007     if (IsFullScreenStack(currentStack->GetMissionStackId()) &&
2008         requestStack->GetMissionStackId() == FLOATING_MISSION_STACK_ID) {
2009         requestStack->MoveMissionRecordToBottom(requestMission);
2010         requestAbility->SetToEnd(true);
2011         requestAbility->Inactivate();
2012         return ERR_OK;
2013     }
2014 
2015     if (currentStack->GetMissionStackId() == FLOATING_MISSION_STACK_ID &&
2016         requestStack->GetMissionStackId() == FLOATING_MISSION_STACK_ID) {
2017         requestStack->MoveMissionRecordToBottom(requestMission);
2018         requestAbility->SetToEnd(true);
2019         requestAbility->Inactivate();
2020         // floating hold focus, shift focus to full screen stack
2021         if (currentTopAbility == requestAbility) {
2022             auto fullScreenStack = GetTopFullScreenStack();
2023             CHECK_POINTER_AND_RETURN(fullScreenStack, MOVE_MISSION_FAILED);
2024             MoveMissionStackToTop(fullScreenStack);
2025             auto fullScreenTopAbility = fullScreenStack->GetTopAbilityRecord();
2026             CHECK_POINTER_AND_RETURN(fullScreenTopAbility, MOVE_MISSION_FAILED);
2027             UpdateFocusAbilityRecord(fullScreenTopAbility, true);
2028         }
2029         return ERR_OK;
2030     }
2031 
2032     auto isActiveLauncher = (requestMission->IsLauncherCreate() ||
2033                              requestMission->GetMissionStack()->GetBottomMissionRecord() == requestMission);
2034     requestStack->MoveMissionRecordToBottom(requestMission);
2035     requestMission->SetIsLauncherCreate();
2036 
2037     if (isActiveLauncher) {
2038         MoveMissionStackToTop(launcherMissionStack_);
2039         targetMissionStack = launcherMissionStack_;
2040         targetMissionRecord = launcherMissionStack_->GetTopMissionRecord();
2041         targetAbilityRecord = targetMissionRecord->GetTopAbilityRecord();
2042     } else {
2043         targetMissionStack = requestStack;
2044         targetMissionRecord = targetMissionStack->GetTopMissionRecord();
2045         targetAbilityRecord = targetMissionRecord->GetTopAbilityRecord();
2046     }
2047 
2048     targetAbilityRecord->SetPreAbilityRecord(requestAbility);
2049     requestAbility->SetNextAbilityRecord(targetAbilityRecord);
2050 
2051     targetAbilityRecord->SetToEnd(true);
2052     requestAbility->SetToEnd(true);
2053     requestAbility->Inactivate();
2054     return ERR_OK;
2055 }
2056 
OnAbilityDied(std::shared_ptr<AbilityRecord> abilityRecord)2057 void AbilityStackManager::OnAbilityDied(std::shared_ptr<AbilityRecord> abilityRecord)
2058 {
2059     HILOG_INFO("On ability died.");
2060     std::lock_guard<std::recursive_mutex> guard(stackLock_);
2061     CHECK_POINTER(abilityRecord);
2062     CHECK_POINTER(launcherMissionStack_);
2063     CHECK_POINTER(defaultMissionStack_);
2064 
2065     if (abilityRecord->GetAbilityInfo().type != AbilityType::PAGE) {
2066         HILOG_ERROR("Ability type is not page.");
2067         return;
2068     }
2069     // release mission when locked.
2070     auto mission = abilityRecord->GetMissionRecord();
2071     if (mission && lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
2072         if (lockMissionContainer_->IsSameLockedMission(mission->GetName())) {
2073             lockMissionContainer_->ReleaseLockedMission(mission, -1, true);
2074         }
2075     }
2076 
2077     // If the launcher ability is dead, delete the record
2078     if (abilityRecord->IsLauncherAbility()) {
2079         OnAbilityDiedByLauncher(abilityRecord);
2080         return;
2081     }
2082 
2083     OnAbilityDiedByDefault(abilityRecord);
2084 }
2085 
OnAbilityDiedByLauncher(std::shared_ptr<AbilityRecord> abilityRecord)2086 void AbilityStackManager::OnAbilityDiedByLauncher(std::shared_ptr<AbilityRecord> abilityRecord)
2087 {
2088     HILOG_INFO("On ability died by launcher.");
2089     CHECK_POINTER(abilityRecord);
2090     CHECK_POINTER(launcherMissionStack_);
2091     auto mission = abilityRecord->GetMissionRecord();
2092     if (!mission || !launcherMissionStack_->IsExistMissionRecord(mission->GetMissionRecordId()) ||
2093         !mission->IsExistAbilityRecord(abilityRecord->GetRecordId())) {
2094         HILOG_ERROR("Mission or ability record is not in launcher stack.");
2095         return;
2096     }
2097 
2098     if (!abilityRecord->IsUninstallAbility()) {
2099         HILOG_INFO("Save mission");
2100         resumeMissionContainer_->Save(mission);
2101     } else {
2102         resumeMissionContainer_->Remove(mission->GetMissionRecordId());
2103     }
2104 
2105     // Terminate launcher ability on the top of dead ability
2106     std::vector<AbilityRecordInfo> abilityInfos;
2107     mission->GetAllAbilityInfo(abilityInfos);
2108     for (auto &it : abilityInfos) {
2109         auto ability = mission->GetAbilityRecordById(it.id);
2110         if (!ability) {
2111             HILOG_WARN("Ability is nullptr.");
2112             continue;
2113         }
2114         if (ability == abilityRecord) {
2115             break;
2116         }
2117         if (ability->IsTerminating()) {
2118             HILOG_ERROR("Ability is terminating.");
2119             continue;
2120         }
2121         HILOG_DEBUG("Terminate launcher ability.");
2122         ability->SetTerminatingState();
2123         TerminateAbilityLocked(ability, DEFAULT_INVAL_VALUE, nullptr);
2124     }
2125 
2126     // Process the dead ability record
2127     if (mission->GetBottomAbilityRecord() == abilityRecord && abilityRecord->IsLauncherRoot()) {
2128         HILOG_DEBUG("Root launcher ability died, set state: INITIAL.");
2129         abilityRecord->SetAbilityState(AbilityState::INITIAL);
2130     } else {
2131         mission->RemoveAbilityRecord(abilityRecord);
2132         if (mission->IsEmpty()) {
2133             launcherMissionStack_->RemoveMissionRecord(mission->GetMissionRecordId());
2134         }
2135     }
2136 
2137     BackToLauncher();
2138 }
2139 
DelayedStartLauncher()2140 void AbilityStackManager::DelayedStartLauncher()
2141 {
2142     auto abilityManagerService = DelayedSingleton<AbilityManagerService>::GetInstance();
2143     CHECK_POINTER(abilityManagerService);
2144     auto handler = abilityManagerService->GetEventHandler();
2145     CHECK_POINTER(handler);
2146     auto timeoutTask = [stackManager = shared_from_this()]() {
2147         HILOG_DEBUG("The launcher needs to be restarted.");
2148         stackManager->BackToLauncher();
2149     };
2150     handler->PostTask(timeoutTask, "Launcher_Restart", AbilityManagerService::RESTART_TIMEOUT);
2151 }
2152 
OnAbilityDiedByDefault(std::shared_ptr<AbilityRecord> abilityRecord)2153 void AbilityStackManager::OnAbilityDiedByDefault(std::shared_ptr<AbilityRecord> abilityRecord)
2154 {
2155     HILOG_INFO("On ability died by default.");
2156     CHECK_POINTER(abilityRecord);
2157     auto mission = abilityRecord->GetMissionRecord();
2158     CHECK_POINTER(mission);
2159     if (!mission->IsExistAbilityRecord(abilityRecord->GetRecordId())) {
2160         HILOG_ERROR("Mission is nullptr or not exist.");
2161         return;
2162     }
2163 
2164     if (abilityRecord->IsAbilityState(AbilityState::ACTIVATING) ||
2165         abilityRecord->IsAbilityState(AbilityState::INITIAL)) {
2166         auto preAbility = abilityRecord->GetPreAbilityRecord();
2167         if (preAbility && preAbility->IsAbilityState(AbilityState::INACTIVE)) {
2168             MoveToBackgroundTask(preAbility);
2169         }
2170     }
2171 
2172     if (!abilityRecord->IsUninstallAbility()) {
2173         HILOG_INFO("Save mission");
2174         resumeMissionContainer_->Save(mission);
2175     } else {
2176         resumeMissionContainer_->Remove(mission->GetMissionRecordId());
2177     }
2178 
2179     auto topAbility = mission->GetTopAbilityRecord();
2180     CHECK_POINTER(topAbility);
2181     auto stack = mission->GetMissionStack();
2182     CHECK_POINTER(stack);
2183     auto isFloatingFocusDied =
2184         ((topAbility == GetCurrentTopAbility()) && stack->IsEqualStackId(FLOATING_MISSION_STACK_ID) &&
2185             (topAbility->IsAbilityState(ACTIVE) || topAbility->IsAbilityState(ACTIVATING)));
2186 
2187     auto isFullStackActiveDied = (IsFullScreenStack(stack->GetMissionStackId()) &&
2188                                   (topAbility->IsAbilityState(ACTIVE) || topAbility->IsAbilityState(ACTIVATING)));
2189 
2190     std::vector<AbilityRecordInfo> abilityInfos;
2191     mission->GetAllAbilityInfo(abilityInfos);
2192     for (auto &it : abilityInfos) {
2193         auto ability = mission->GetAbilityRecordById(it.id);
2194         if (!ability) {
2195             HILOG_ERROR("ability is nullptr,%{public}d", __LINE__);
2196             continue;
2197         }
2198         if (ability == abilityRecord) {
2199             break;
2200         }
2201         if (ability->IsTerminating()) {
2202             HILOG_ERROR("ability is terminating, %{public}d", __LINE__);
2203             continue;
2204         }
2205         HILOG_INFO("Terminate ability, %{public}d", __LINE__);
2206         ability->SetForceTerminate(true);
2207         ability->SetTerminatingState();
2208         TerminateAbilityLocked(ability, DEFAULT_INVAL_VALUE, nullptr);
2209     }
2210 
2211     if (abilityRecord->IsUninstallAbility()) {
2212         HILOG_INFO("Ability uninstall,%{public}d", __LINE__);
2213         mission->RemoveAbilityRecord(abilityRecord);
2214         if (mission->IsEmpty()) {
2215             RemoveMissionRecordById(mission->GetMissionRecordId());
2216             JudgingIsRemoveMultiScreenStack(stack);
2217         }
2218     } else {
2219         if (mission->GetBottomAbilityRecord() == abilityRecord) {
2220             HILOG_INFO("Ability died, state: INITIAL, %{public}d", __LINE__);
2221             abilityRecord->SetAbilityState(AbilityState::INITIAL);
2222         } else {
2223             HILOG_INFO("Ability died, remove record, %{public}d", __LINE__);
2224             mission->RemoveAbilityRecord(abilityRecord);
2225         }
2226     }
2227 
2228     if (isFloatingFocusDied) {
2229         HILOG_INFO("floating focus ability died, back to full stack");
2230         auto fullScreenStack = GetTopFullScreenStack();
2231         CHECK_POINTER(fullScreenStack);
2232         auto topFullScreenAbility = fullScreenStack->GetTopAbilityRecord();
2233         CHECK_POINTER(fullScreenStack);
2234         MoveMissionStackToTop(fullScreenStack);
2235         if (topFullScreenAbility->IsAbilityState(AbilityState::ACTIVE)) {
2236             UpdateFocusAbilityRecord(topFullScreenAbility, true);
2237         } else {
2238             topFullScreenAbility->ProcessActivate();
2239         }
2240         return;
2241     }
2242 
2243     if (isFullStackActiveDied) {
2244         HILOG_INFO("full stack active ability died, back to launcher.");
2245         BackToLauncher();
2246     }
2247 }
2248 
BackToLauncher()2249 void AbilityStackManager::BackToLauncher()
2250 {
2251     HILOG_INFO("Back to launcher.");
2252     std::lock_guard<std::recursive_mutex> guard(stackLock_);
2253     CHECK_POINTER(defaultMissionStack_);
2254     CHECK_POINTER(launcherMissionStack_);
2255 
2256     auto fullScreenStack = GetTopFullScreenStack();
2257     CHECK_POINTER(fullScreenStack);
2258     auto currentTopAbility = fullScreenStack->GetTopAbilityRecord();
2259     if (currentTopAbility && (currentTopAbility->IsAbilityState(AbilityState::ACTIVE))) {
2260         HILOG_WARN("Current top ability is active, no need to start launcher.");
2261         return;
2262     }
2263     auto launcherAbility = GetLauncherRootAbility();
2264     CHECK_POINTER_LOG(launcherAbility, "There is no root launcher ability record, back to launcher failed.");
2265 
2266     MoveMissionStackToTop(launcherMissionStack_);
2267 
2268     auto missionRecord = launcherAbility->GetMissionRecord();
2269     CHECK_POINTER_LOG(missionRecord, "Can't get root launcher ability record's mission, back to launcher failed.");
2270 
2271     CheckMissionRecordIsResume(missionRecord);
2272 
2273     if (currentTopAbility) {
2274         launcherAbility->SetPreAbilityRecord(currentTopAbility);
2275         currentTopAbility->SetNextAbilityRecord(launcherAbility);
2276 
2277         missionRecord->SetPreMissionRecord(currentTopAbility->GetMissionRecord());
2278         if (currentTopAbility->IsLauncherAbility()) {
2279             missionRecord->SetIsLauncherCreate();
2280         }
2281     }
2282     launcherMissionStack_->MoveMissionRecordToTop(missionRecord);
2283     launcherAbility->ProcessActivate();
2284 }
2285 
GetLauncherRootAbility() const2286 std::shared_ptr<AbilityRecord> AbilityStackManager::GetLauncherRootAbility() const
2287 {
2288     if (!launcherMissionStack_) {
2289         HILOG_ERROR("Mission stack is invalid.");
2290         return nullptr;
2291     }
2292     std::vector<MissionRecordInfo> missionInfos;
2293     launcherMissionStack_->GetAllMissionInfo(missionInfos);
2294     for (auto &mission : missionInfos) {
2295         auto missionRecord = launcherMissionStack_->GetMissionRecordById(mission.id);
2296         if (!missionRecord) {
2297             continue;
2298         }
2299         for (auto &it : mission.abilityRecordInfos) {
2300             auto abilityRecord = missionRecord->GetAbilityRecordById(it.id);
2301             if (abilityRecord && abilityRecord->IsLauncherRoot()) {
2302                 return abilityRecord;
2303             }
2304         }
2305     }
2306     return nullptr;
2307 }
2308 
UninstallApp(const std::string & bundleName)2309 void AbilityStackManager::UninstallApp(const std::string &bundleName)
2310 {
2311     HILOG_INFO("Uninstall app, bundleName: %{public}s", bundleName.c_str());
2312     auto abilityManagerService = DelayedSingleton<AbilityManagerService>::GetInstance();
2313     CHECK_POINTER(abilityManagerService);
2314     auto handler = abilityManagerService->GetEventHandler();
2315     CHECK_POINTER(handler);
2316     auto task = [bundleName, this]() { AddUninstallTags(bundleName); };
2317     handler->PostTask(task);
2318 }
2319 
AddUninstallTags(const std::string & bundleName)2320 void AbilityStackManager::AddUninstallTags(const std::string &bundleName)
2321 {
2322     HILOG_INFO("Add uninstall tags, bundleName: %{public}s", bundleName.c_str());
2323     std::lock_guard<std::recursive_mutex> guard(stackLock_);
2324     for (auto &stack : missionStackList_) {
2325         std::vector<MissionRecordInfo> missions;
2326         stack->GetAllMissionInfo(missions);
2327         for (auto &missionInfo : missions) {
2328             auto mission = stack->GetMissionRecordById(missionInfo.id);
2329             if (!mission) {
2330                 HILOG_ERROR("Mission is nullptr.");
2331                 continue;
2332             }
2333             std::vector<AbilityRecordInfo> abilitys;
2334             mission->GetAllAbilityInfo(abilitys);
2335             for (auto &abilityInfo : abilitys) {
2336                 auto ability = mission->GetAbilityRecordById(abilityInfo.id);
2337                 if (!ability) {
2338                     HILOG_ERROR("Ability is nullptr.");
2339                     continue;
2340                 }
2341 
2342                 if (ability->GetAbilityInfo().bundleName == bundleName) {
2343                     if (ability->IsAbilityState(AbilityState::INITIAL)) {
2344                         mission->RemoveAbilityRecord(ability);
2345                         if (mission->IsEmpty()) {
2346                             stack->RemoveMissionRecord(mission->GetMissionRecordId());
2347                         }
2348                         CHECK_POINTER(resumeMissionContainer_);
2349                         resumeMissionContainer_->Remove(mission->GetMissionRecordId());
2350                         if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
2351                             if (lockMissionContainer_->IsSameLockedMission(mission->GetName())) {
2352                                 lockMissionContainer_->ReleaseLockedMission(mission, -1, true);
2353                             }
2354                         }
2355                         continue;
2356                     }
2357                     ability->SetIsUninstallAbility();
2358                 }
2359             }
2360         }
2361     }
2362     // Multi screen stack may be empty
2363     auto floatingStack = GetOrCreateMissionStack(FLOATING_MISSION_STACK_ID, false);
2364     JudgingIsRemoveMultiScreenStack(floatingStack);
2365     auto splitScreenStack = GetOrCreateMissionStack(SPLIT_SCREEN_MISSION_STACK_ID, false);
2366     JudgingIsRemoveMultiScreenStack(splitScreenStack);
2367 }
2368 
GetAbilityRecordByEventId(int64_t eventId) const2369 std::shared_ptr<AbilityRecord> AbilityStackManager::GetAbilityRecordByEventId(int64_t eventId) const
2370 {
2371     HILOG_DEBUG("Get ability record by eventId.");
2372     for (auto &stack : missionStackList_) {
2373         std::vector<MissionRecordInfo> missionInfos;
2374         stack->GetAllMissionInfo(missionInfos);
2375         for (auto &mission : missionInfos) {
2376             auto missionRecord = stack->GetMissionRecordById(mission.id);
2377             if (!missionRecord) {
2378                 continue;
2379             }
2380             for (auto &it : mission.abilityRecordInfos) {
2381                 auto abilityRecord = missionRecord->GetAbilityRecordById(it.id);
2382                 if (abilityRecord && abilityRecord->GetEventId() == eventId) {
2383                     return abilityRecord;
2384                 }
2385             }
2386         }
2387     }
2388     return nullptr;
2389 }
2390 
OnTimeOut(uint32_t msgId,int64_t eventId)2391 void AbilityStackManager::OnTimeOut(uint32_t msgId, int64_t eventId)
2392 {
2393     HILOG_DEBUG("On timeout.");
2394     std::lock_guard<std::recursive_mutex> guard(stackLock_);
2395     auto abilityRecord = GetAbilityRecordByEventId(eventId);
2396     if (abilityRecord == nullptr) {
2397         HILOG_ERROR("stack manager on time out event: ability record is nullptr.");
2398         return;
2399     }
2400 
2401     // release mission when locked.
2402     auto mission = abilityRecord->GetMissionRecord();
2403     if (mission && lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
2404         if (lockMissionContainer_->IsSameLockedMission(mission->GetName())) {
2405             lockMissionContainer_->ReleaseLockedMission(mission, -1, true);
2406         }
2407     }
2408     CHECK_POINTER_LOG(abilityRecord, "stack manager on time out event: ability record is nullptr.");
2409 
2410     HILOG_DEBUG("Ability timeout ,msg:%{public}d,name:%{public}s", msgId, abilityRecord->GetAbilityInfo().name.c_str());
2411 
2412     switch (msgId) {
2413         case AbilityManagerService::LOAD_TIMEOUT_MSG:
2414             ActiveTopAbility(abilityRecord);
2415             break;
2416         case AbilityManagerService::ACTIVE_TIMEOUT_MSG:
2417             HandleActiveTimeout(abilityRecord);
2418             break;
2419         case AbilityManagerService::INACTIVE_TIMEOUT_MSG:
2420             CompleteInactive(abilityRecord);
2421             break;
2422         default:
2423             break;
2424     }
2425 }
2426 
HandleActiveTimeout(const std::shared_ptr<AbilityRecord> & ability)2427 void AbilityStackManager::HandleActiveTimeout(const std::shared_ptr<AbilityRecord> &ability)
2428 {
2429     HILOG_DEBUG("Handle active timeout");
2430     CHECK_POINTER(ability);
2431     DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(ability->GetToken());
2432 
2433     if (ability->IsLauncherRoot()) {
2434         HILOG_INFO("Launcher root load timeout, restart.");
2435         BackToLauncher();
2436         return;
2437     }
2438 
2439     auto missionRecord = ability->GetMissionRecord();
2440     CHECK_POINTER(missionRecord);
2441     auto stack = missionRecord->GetMissionStack();
2442     CHECK_POINTER(stack);
2443     missionRecord->RemoveAbilityRecord(ability);
2444     if (missionRecord->IsEmpty()) {
2445         RemoveMissionRecordById(missionRecord->GetMissionRecordId());
2446         JudgingIsRemoveMultiScreenStack(stack);
2447     }
2448 
2449     BackToLauncher();
2450 }
2451 
MoveMissionToFloatingStack(const MissionOption & missionOption)2452 int AbilityStackManager::MoveMissionToFloatingStack(const MissionOption &missionOption)
2453 {
2454     HILOG_DEBUG("Move mission to floating stack, missionId: %{public}d", missionOption.missionId);
2455     std::lock_guard<std::recursive_mutex> guard(stackLock_);
2456     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
2457         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
2458         return ERR_INVALID_VALUE;
2459     }
2460     if (missionOption.missionId == DEFAULT_INVAL_VALUE) {
2461         HILOG_ERROR("Mission id is invalid.");
2462         return ERR_INVALID_DATA;
2463     }
2464     if (JudgingTargetSystemWindowMode(missionOption.winModeKey) != SystemWindowMode::FLOATING_WINDOW_MODE) {
2465         HILOG_ERROR("The requested mode is error.");
2466         return ERR_INVALID_DATA;
2467     }
2468     std::list<MissionOption> missionOptions;
2469     MissionOption option = missionOption;
2470     missionOptions.push_back(option);
2471 
2472     return MoveMissionsToStackLocked(missionOptions);
2473 }
2474 
MoveMissionToSplitScreenStack(const MissionOption & missionOption)2475 int AbilityStackManager::MoveMissionToSplitScreenStack(const MissionOption &missionOption)
2476 {
2477     HILOG_DEBUG("Move mission to split screen stack, missionId:%{public}d", missionOption.missionId);
2478     std::lock_guard<std::recursive_mutex> guard(stackLock_);
2479     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
2480         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
2481         return ERR_INVALID_VALUE;
2482     }
2483     if (missionOption.missionId == DEFAULT_INVAL_VALUE) {
2484         HILOG_ERROR("mission id is invalid.");
2485         return ERR_INVALID_DATA;
2486     }
2487     if (JudgingTargetSystemWindowMode(missionOption.winModeKey) != SystemWindowMode::SPLITSCREEN_WINDOW_MODE) {
2488         HILOG_ERROR("The requested mode is error.");
2489         return ERR_INVALID_DATA;
2490     }
2491     std::list<MissionOption> missionOptions;
2492     MissionOption option = missionOption;
2493     missionOptions.push_back(option);
2494 
2495     return MoveMissionsToStackLocked(missionOptions);
2496 }
2497 
MoveMissionsToStackLocked(const std::list<MissionOption> & missionOptions)2498 int AbilityStackManager::MoveMissionsToStackLocked(const std::list<MissionOption> &missionOptions)
2499 {
2500 #if BINDER_IPC_32BIT
2501     HILOG_DEBUG("Request mission option size :%{public}u", missionOptions.size());
2502 #else
2503     HILOG_DEBUG("Request mission option size :%{public}lu", missionOptions.size());
2504 #endif
2505 
2506     // check condition whether can enter or exit multiwindow mode.
2507     CHECK_RET_RETURN_RET(CheckMultiWindowCondition(missionOptions), "check multiwindow condition is failed.");
2508 
2509     // complete mission stack moving and notify ability window mode has changed.
2510     auto lastTopAbility = GetCurrentTopAbility();
2511     isMultiWinMoving_ = true;
2512     for (auto &it : missionOptions) {
2513         auto sourceMission = GetMissionRecordFromAllStacks(it.missionId);
2514         CheckMissionRecordIsResume(sourceMission);
2515         CHECK_POINTER_AND_RETURN(sourceMission, MOVE_MISSION_TO_STACK_NOT_EXIST_MISSION);
2516         CHECK_RET_RETURN_RET(CompleteMissionMoving(sourceMission, JudgingTargetStackId(it.winModeKey)),
2517             "complete mission moving failed.");
2518         sourceMission->SetMissionOption(it);
2519     }
2520 
2521     // to do ,split srceen mode ,change second screen missionoption.
2522 
2523     // schulde ability lifescycle (all stack)
2524     auto currentTopAbility = GetCurrentTopAbility();
2525     bool isFullScreen =
2526         missionOptions.front().winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FULLSCREEN;
2527     // top ability active and display fullscreen, others background state.
2528     CHECK_RET_RETURN_RET(
2529         DispatchLifecycle(lastTopAbility, currentTopAbility, isFullScreen), "Dispatch lifecycle error.");
2530 
2531     // Judging target system window mode, and notify event.
2532     auto willWinMode = JudgingTargetSystemWindowMode(missionOptions.front().winModeKey);
2533     auto targetWinMode = GetTargetSystemWindowMode(willWinMode);
2534     NotifyWindowModeChanged(targetWinMode);
2535 
2536     return ERR_OK;
2537 }
2538 
MaximizeMultiWindow(int missionId)2539 int AbilityStackManager::MaximizeMultiWindow(int missionId)
2540 {
2541     HILOG_DEBUG("Maximize multi window, missionId:%{public}d", missionId);
2542     std::lock_guard<std::recursive_mutex> guard(stackLock_);
2543     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
2544         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
2545         return ERR_INVALID_VALUE;
2546     }
2547 
2548     auto missionRecord = GetMissionRecordFromAllStacks(missionId);
2549     CHECK_POINTER_AND_RETURN(missionRecord, MAXIMIZE_MULTIWINDOW_NOT_EXIST);
2550     auto parentStack = missionRecord->GetMissionStack();
2551     CHECK_POINTER_AND_RETURN(parentStack, ERR_INVALID_DATA);
2552     if (!parentStack->IsEqualStackId(FLOATING_MISSION_STACK_ID)) {
2553         HILOG_ERROR("This mission is not exist in multiwindow stack.");
2554         return MAXIMIZE_MULTIWINDOW_NOT_EXIST;
2555     }
2556     auto topAbility = missionRecord->GetTopAbilityRecord();
2557     CHECK_POINTER_AND_RETURN(topAbility, ERR_INVALID_DATA);
2558     if (!topAbility->IsAbilityState(AbilityState::INACTIVE) && !topAbility->IsAbilityState(AbilityState::ACTIVE)) {
2559         HILOG_ERROR("This mission is not visible, maximize failed.");
2560         return MAXIMIZE_MULTIWINDOW_FAILED;
2561     }
2562     // construct mission option, request to move mission to default stack.
2563     MissionOption option;
2564     option.missionId = missionId;
2565     option.winModeKey = AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FULLSCREEN;
2566     std::list<MissionOption> missionOptions;
2567     missionOptions.push_back(option);
2568 
2569     return MoveMissionsToStackLocked(missionOptions);
2570 }
2571 
ContinueLifecycle()2572 void AbilityStackManager::ContinueLifecycle()
2573 {
2574     HILOG_INFO("Continue lifecycle.");
2575     for (auto &stack : missionStackList_) {
2576         CHECK_POINTER(stack);
2577         std::vector<MissionRecordInfo> missionInfos;
2578         stack->GetAllMissionInfo(missionInfos);
2579         for (auto &it : missionInfos) {
2580             std::shared_ptr<MissionRecord> missionRecord = stack->GetMissionRecordById(it.id);
2581             CHECK_POINTER(missionRecord);
2582             auto topAbility = missionRecord->GetTopAbilityRecord();
2583             CHECK_POINTER(topAbility);
2584             if (topAbility->GetInMovingState() && topAbility != GetCurrentTopAbility()) {
2585                 HILOG_DEBUG("Wait other ability to complete lifecycle. Ability: %{public}s.",
2586                     topAbility->GetAbilityInfo().name.c_str());
2587                 return;
2588             }
2589         }
2590     }
2591 
2592     auto currentTopAbility = GetCurrentTopAbility();
2593     CHECK_POINTER(currentTopAbility);
2594     HILOG_DEBUG("At last, complete top ability lifecycle, target state is active.");
2595     if (currentTopAbility->IsAbilityState(AbilityState::ACTIVE)) {
2596         UpdateFocusAbilityRecord(currentTopAbility, true);
2597         currentTopAbility->SetInMovingState(false);
2598         isMultiWinMoving_ = false;
2599     } else {
2600         currentTopAbility->ProcessActivate();
2601     }
2602 }
2603 
DispatchLifecycle(const std::shared_ptr<AbilityRecord> & lastTopAbility,const std::shared_ptr<AbilityRecord> & currentTopAbility,bool isTopFullScreen)2604 int AbilityStackManager::DispatchLifecycle(const std::shared_ptr<AbilityRecord> &lastTopAbility,
2605     const std::shared_ptr<AbilityRecord> &currentTopAbility, bool isTopFullScreen)
2606 {
2607     CHECK_POINTER_AND_RETURN(lastTopAbility, ERR_INVALID_DATA);
2608     CHECK_POINTER_AND_RETURN(currentTopAbility, ERR_INVALID_DATA);
2609 
2610     auto lastMission = lastTopAbility->GetMissionRecord();
2611     CHECK_POINTER_AND_RETURN(lastMission, ERR_INVALID_DATA);
2612     auto lastMissionStack = lastMission->GetMissionStack();
2613     CHECK_POINTER_AND_RETURN(lastMissionStack, ERR_INVALID_DATA);
2614 
2615     auto topFullStack = GetTopFullScreenStack();
2616     CHECK_POINTER_AND_RETURN(topFullStack, ERR_INVALID_DATA);
2617 
2618     for (auto &stack : missionStackList_) {
2619         CHECK_POINTER_AND_RETURN(stack, ERR_INVALID_DATA);
2620         bool isSyncVisual = SupportSyncVisualByStackId(stack->GetMissionStackId());
2621 
2622         HILOG_DEBUG("Processing stack lifescycle: stack id: %{public}d, isSyncVisual: %{public}d",
2623             stack->GetMissionStackId(),
2624             isSyncVisual);
2625 
2626         std::vector<MissionRecordInfo> missionInfos;
2627         stack->GetAllMissionInfo(missionInfos);
2628         for (auto &it : missionInfos) {
2629             std::shared_ptr<MissionRecord> missionRecord = stack->GetMissionRecordById(it.id);
2630             CHECK_POINTER_AND_RETURN(missionRecord, ERR_INVALID_DATA);
2631             auto topAbility = missionRecord->GetTopAbilityRecord();
2632             CHECK_POINTER_AND_RETURN(topAbility, ERR_INVALID_DATA);
2633             // last top active ability , need to inactive.
2634             if (topAbility == lastTopAbility || topAbility == currentTopAbility) {
2635                 HILOG_DEBUG("Last top active ability or Current top ability, lifecycle at last.");
2636                 topAbility->SetInMovingState(true);
2637                 continue;
2638             }
2639             // top ability active , others need to background state.
2640             if (isTopFullScreen) {
2641                 HILOG_DEBUG("Top ability will full screen, others need to background.");
2642                 topAbility->ProcessInactivateInMoving();
2643                 continue;
2644             }
2645             // Except the top mission of the stack, all the others are in the background state,
2646             // When this mission stack not support sync visual.
2647             if (!stack->IsTopMissionRecord(missionRecord)) {
2648                 if (!isSyncVisual) {
2649                     HILOG_DEBUG("This mission stack not support sync visual. need to background.");
2650                     topAbility->ProcessInactivateInMoving();
2651                 }
2652                 continue;
2653             }
2654             // process top mission.
2655             // fullscreen stack, only the top ability is active state, others keep background state.
2656             if (stack == topFullStack) {
2657                 HILOG_DEBUG("Fullscreen stack ,top abiltiy need to active.");
2658                 topAbility->ProcessActivateInMoving();
2659                 continue;
2660             }
2661             // others force background state.
2662             HILOG_DEBUG("Others keep background state.");
2663             topAbility->ProcessInactivateInMoving();
2664         }
2665     }
2666 
2667     bool isNotTopInFullScreen =
2668         IsFullScreenStack(lastTopAbility->GetMissionStackId()) &&
2669         (!lastMissionStack->IsTopMissionRecord(lastMission) || lastMissionStack != topFullStack);
2670     bool isNotTopInMultiWin = !IsFullScreenStack(lastTopAbility->GetMissionStackId()) &&
2671                               !SupportSyncVisualByStackId(lastTopAbility->GetMissionStackId()) &&
2672                               (!lastMissionStack->IsTopMissionRecord(lastMission) ||
2673                                   (lastMission->GetMissionRecordId() == (currentTopAbility->GetMissionRecordId())));
2674     if (lastTopAbility == currentTopAbility) {
2675         HILOG_DEBUG("Lasttopability is equal to currenttopability.");
2676     } else if (isNotTopInFullScreen || isNotTopInMultiWin || isTopFullScreen) {
2677         HILOG_DEBUG("Last top active ability , need to inactive.");
2678         lastTopAbility->ProcessInactivateInMoving();
2679     } else {
2680         lastTopAbility->SetInMovingState(false);
2681     }
2682 
2683     // if there is no ability to wait for processing active, just active top ability immediately
2684     ContinueLifecycle();
2685 
2686     return ERR_OK;
2687 }
2688 
GetTargetSystemWindowMode(const SystemWindowMode & willWinMode)2689 SystemWindowMode AbilityStackManager::GetTargetSystemWindowMode(const SystemWindowMode &willWinMode)
2690 {
2691     if (curSysWindowMode_ == willWinMode) {
2692         return curSysWindowMode_;
2693     }
2694 
2695     bool isCrossFlag = curSysWindowMode_ == SystemWindowMode::FLOATING_AND_SPLITSCREEN_WINDOW_MODE;
2696     switch (willWinMode) {
2697         case SystemWindowMode::SPLITSCREEN_WINDOW_MODE:
2698         case SystemWindowMode::FLOATING_WINDOW_MODE:
2699             return (isCrossFlag || curSysWindowMode_ != SystemWindowMode::DEFAULT_WINDOW_MODE) ? curSysWindowMode_
2700                                                                                                : willWinMode;
2701         default:
2702             break;
2703     }
2704 
2705     // will win mode is default mode ,need to check current mission stack list.
2706     bool isFloating = GetOrCreateMissionStack(FLOATING_MISSION_STACK_ID, false) != nullptr;
2707     bool isSplitScreen = GetOrCreateMissionStack(SPLIT_SCREEN_MISSION_STACK_ID, false) != nullptr;
2708 
2709     if (isFloating && isSplitScreen) {
2710         return SystemWindowMode::FLOATING_AND_SPLITSCREEN_WINDOW_MODE;
2711     } else if (isFloating) {
2712         return SystemWindowMode::FLOATING_WINDOW_MODE;
2713     } else if (isSplitScreen) {
2714         return SystemWindowMode::SPLITSCREEN_WINDOW_MODE;
2715     } else {
2716         return willWinMode;
2717     }
2718 }
2719 
CheckMultiWindowCondition(const std::list<MissionOption> & missionOptions) const2720 int AbilityStackManager::CheckMultiWindowCondition(const std::list<MissionOption> &missionOptions) const
2721 {
2722     HILOG_DEBUG("Check multi window condition.");
2723     if (isMultiWinMoving_) {
2724         HILOG_ERROR("System is moving multi window state, request deny.");
2725         return MOVE_MISSION_TO_STACK_MOVING_DENIED;
2726     }
2727 
2728     auto currentTopAbilityRecord = GetCurrentTopAbility();
2729     if (currentTopAbilityRecord &&
2730         AbilityUtil::IsSystemDialogAbility(
2731         currentTopAbilityRecord->GetAbilityInfo().bundleName, currentTopAbilityRecord->GetAbilityInfo().name)) {
2732         HILOG_ERROR("Top page ability is dialog type, cannot return to launcher");
2733         return MOVE_MISSION_TO_STACK_MOVING_DENIED;
2734     }
2735 
2736     if (missionOptions.empty() || missionOptions.size() > MAX_CAN_MOVE_MISSIONS) {
2737         HILOG_ERROR("Moving missions has been out of size, Maximum:%{public}d.", MAX_CAN_MOVE_MISSIONS);
2738         return MOVE_MISSION_TO_STACK_OUT_OF_SIZE;
2739     }
2740     // check request missions exist, and has same window mode.
2741     auto lastOption = missionOptions.front();
2742     for (auto &it : missionOptions) {
2743         if (!it.IsSameWindowMode(lastOption.winModeKey)) {
2744             HILOG_ERROR("Mission options are not in same win mode.");
2745             return MOVE_MISSION_TO_STACK_NOT_SAME_WIN_MODE;
2746         }
2747         auto targetMission = GetMissionRecordFromAllStacks(it.missionId);
2748         if (!targetMission) {
2749             HILOG_ERROR("Moving mission record is not exist.");
2750             return MOVE_MISSION_TO_STACK_NOT_EXIST_MISSION;
2751         }
2752         auto parentStack = targetMission->GetMissionStack();
2753         if (parentStack && parentStack->GetMissionStackId() == JudgingTargetStackId(it.winModeKey)) {
2754             HILOG_ERROR("Refuse moving mission to its own stack.");
2755             return MOVE_MISSION_TO_STACK_NOT_EXIST_MISSION;
2756         }
2757         if (!targetMission->SupportMultWindow()) {
2758             HILOG_ERROR("Moving mission record is not support multi window.");
2759             return MOVE_MISSION_TO_STACK_NOT_SUPPORT_MULTI_WIN;
2760         }
2761     }
2762 
2763     // check whether target mission stack will be overflow.
2764     if (!CheckMissionStackWillOverflow(missionOptions)) {
2765         HILOG_ERROR("Mission stack will overflow, refuse to move mission.");
2766         return MOVE_MISSION_TO_STACK_TARGET_STACK_OVERFLOW;
2767     }
2768 
2769     return ERR_OK;
2770 }
2771 
CheckMultiWindowCondition(const std::shared_ptr<AbilityRecord> & currentTopAbility,const AbilityRequest & abilityRequest) const2772 int AbilityStackManager::CheckMultiWindowCondition(
2773     const std::shared_ptr<AbilityRecord> &currentTopAbility, const AbilityRequest &abilityRequest) const
2774 {
2775     HILOG_DEBUG("Check multi window condition.");
2776     CHECK_POINTER_AND_RETURN_LOG(abilityRequest.startSetting, START_ABILITY_SETTING_FAILED, "startsetting is nullptr.");
2777 
2778     if (isMultiWinMoving_) {
2779         HILOG_ERROR("System is moving multi window state, request deny.");
2780         return START_ABILITY_SETTING_FAILED;
2781     }
2782 
2783     if (currentTopAbility &&
2784         AbilityUtil::IsSystemDialogAbility(
2785         currentTopAbility->GetAbilityInfo().bundleName, currentTopAbility->GetAbilityInfo().name)) {
2786         HILOG_ERROR("Top page ability is dialog type, cannot return to launcher.");
2787         return START_ABILITY_SETTING_FAILED;
2788     }
2789     // check whether target mission stack will be overflow.
2790     MissionOption option;
2791     option.winModeKey = static_cast<AbilityWindowConfiguration>(
2792         std::atoi(abilityRequest.startSetting->GetProperty(AbilityStartSetting::WINDOW_MODE_KEY).c_str()));
2793     std::list<MissionOption> list;
2794     list.push_back(option);
2795     if (!CheckMissionStackWillOverflow(list)) {
2796         HILOG_ERROR("Mission stack will overflow.");
2797         return START_ABILITY_SETTING_NOT_SUPPORT_MULTI_WIN;
2798     }
2799 
2800     return ERR_OK;
2801 }
2802 
CheckMissionStackWillOverflow(const std::list<MissionOption> & missionOptions) const2803 bool AbilityStackManager::CheckMissionStackWillOverflow(const std::list<MissionOption> &missionOptions) const
2804 {
2805     std::map<int, int> calcMap;
2806     for (auto &it : missionStackList_) {
2807         calcMap.emplace(it->GetMissionStackId(), it->GetMissionRecordCount());
2808     }
2809 
2810     auto isOverFlow = [&](int stackId, std::map<int, int> &calcMap) {
2811         calcMap[stackId]++;
2812         if (GetMaxHoldMissionsByStackId(stackId) > 0 && calcMap[stackId] > GetMaxHoldMissionsByStackId(stackId)) {
2813             HILOG_ERROR(
2814                 "Over limit of holding mission, stackId:%{public}d , size:%{public}d", stackId, calcMap[stackId]);
2815             return false;
2816         }
2817         return true;
2818     };
2819 
2820     // check whether splitscreen and floating stack will overflow.
2821     for (auto &option : missionOptions) {
2822         auto stackId = JudgingTargetStackId(option.winModeKey);
2823         if (!isOverFlow(stackId, calcMap)) {
2824             return false;
2825         }
2826     }
2827 
2828     return true;
2829 }
2830 
CompleteMissionMoving(std::shared_ptr<MissionRecord> & sourceMission,int stackId)2831 int AbilityStackManager::CompleteMissionMoving(std::shared_ptr<MissionRecord> &sourceMission, int stackId)
2832 {
2833     CHECK_POINTER_AND_RETURN(sourceMission, MOVE_MISSION_TO_STACK_NOT_EXIST_MISSION);
2834     auto targetStack = GetOrCreateMissionStack(stackId, true);
2835     CHECK_POINTER_AND_RETURN(targetStack, ERR_INVALID_DATA);
2836 
2837     CHECK_RET_RETURN_RET(CompleteMoveMissionToStack(sourceMission, targetStack), "Moving mission record failed.");
2838 
2839     return ERR_OK;
2840 }
2841 
GetOrCreateMissionStack(int stackId,bool isCreateFlag)2842 std::shared_ptr<MissionStack> AbilityStackManager::GetOrCreateMissionStack(int stackId, bool isCreateFlag)
2843 {
2844     HILOG_DEBUG("Target stack id:%{public}d", stackId);
2845     if (stackId > MAX_MISSION_STACK_ID || stackId < MIN_MISSION_STACK_ID) {
2846         HILOG_ERROR("stack id:%{public}d is not defined.", stackId);
2847         return nullptr;
2848     }
2849     auto isExist = [stackId](
2850                        const std::shared_ptr<MissionStack> &stack) { return stackId == stack->GetMissionStackId(); };
2851     auto iter = std::find_if(missionStackList_.begin(), missionStackList_.end(), isExist);
2852     if (iter != missionStackList_.end()) {
2853         HILOG_DEBUG("Get target mission stack success.");
2854         return *iter;
2855     }
2856 
2857     if (isCreateFlag) {
2858         HILOG_DEBUG("Target mission stack is not exist, need to create.");
2859         std::shared_ptr<MissionStack> missionStack = std::make_shared<MissionStack>(stackId, userId_);
2860         missionStackList_.push_back(missionStack);
2861 #if BINDER_IPC_32BIT
2862         HILOG_DEBUG("Add stackId(%{public}d) to missionStackList, mission stack size:%{public}u",
2863             stackId,
2864             missionStackList_.size());
2865 #else
2866         HILOG_DEBUG("Add stackId(%{public}d) to missionStackList, mission stack size:%{public}lu",
2867             stackId,
2868             missionStackList_.size());
2869 #endif
2870         return missionStack;
2871     }
2872 
2873     HILOG_DEBUG("Target mission stack is not exist.");
2874     return nullptr;
2875 }
2876 
CompleteMoveMissionToStack(const std::shared_ptr<MissionRecord> & sourceMission,const std::shared_ptr<MissionStack> & targetStack)2877 int AbilityStackManager::CompleteMoveMissionToStack(
2878     const std::shared_ptr<MissionRecord> &sourceMission, const std::shared_ptr<MissionStack> &targetStack)
2879 {
2880     CHECK_POINTER_AND_RETURN(sourceMission, ERR_INVALID_DATA);
2881     CHECK_POINTER_AND_RETURN(targetStack, ERR_INVALID_DATA);
2882     auto sourceStack = sourceMission->GetMissionStack();
2883     CHECK_POINTER_AND_RETURN(sourceStack, ERR_INVALID_DATA);
2884 
2885     bool isTop = sourceMission->IsLauncherCreate() && sourceMission == GetTopMissionRecord();
2886 
2887     HILOG_DEBUG("Mission reparent : src stack id:%{public}d, target stack id:%{public}d, isTop:%{public}d",
2888         sourceStack->GetMissionStackId(),
2889         targetStack->GetMissionStackId(),
2890         isTop);
2891 
2892     // remove mission record from source stack.
2893     sourceStack->RemoveMissionRecord(sourceMission->GetMissionRecordId());
2894     // add mission to target mission stack top.
2895     targetStack->AddMissionRecordToTop(sourceMission);
2896     targetStack->MoveMissionRecordToTop(sourceMission);
2897     sourceMission->SetMissionStack(targetStack, targetStack->GetMissionStackId());
2898     if ((sourceStack->IsEmpty() || isTop) && targetStack != defaultMissionStack_) {
2899         MoveMissionStackToTop(launcherMissionStack_);
2900     }
2901     if (sourceStack->IsEmpty() && (!IsFullScreenStack(sourceStack->GetMissionStackId()))) {
2902         HILOG_DEBUG("Remove stack when mission count is zero. stack:%{public}d.", sourceStack->GetMissionStackId());
2903         missionStackList_.remove(sourceStack);
2904     }
2905     // move target mission stack to top.
2906     MoveMissionStackToTop(targetStack);
2907 
2908     return ERR_OK;
2909 }
2910 
ActiveTopAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)2911 void AbilityStackManager::ActiveTopAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
2912 {
2913     HILOG_INFO("Active top ability.");
2914     CHECK_POINTER(abilityRecord);
2915 
2916     DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
2917 
2918     if (abilityRecord->IsLauncherRoot()) {
2919         HILOG_INFO("Launcher root load timeout, restart.");
2920         BackToLauncher();
2921         return;
2922     }
2923 
2924     // Pre ability does not need to judge null
2925     auto preAbility = abilityRecord->GetPreAbilityRecord();
2926     auto missionRecord = abilityRecord->GetMissionRecord();
2927     CHECK_POINTER(missionRecord);
2928     auto stack = missionRecord->GetMissionStack();
2929     CHECK_POINTER(stack);
2930 
2931     // remove ability and mission and stack
2932     missionRecord->RemoveAbilityRecord(abilityRecord);
2933     if (missionRecord->IsEmpty()) {
2934         RemoveMissionRecordById(missionRecord->GetMissionRecordId());
2935         JudgingIsRemoveMultiScreenStack(stack);
2936     }
2937 
2938     if (preAbility && preAbility->IsAbilityState(INACTIVE)) {
2939         HILOG_INFO("Load timeout, restart pre ability.");
2940         MoveMissionStackToTop(preAbility->GetMissionRecord()->GetMissionStack());
2941         preAbility->ProcessActivate();
2942     } else {
2943         auto topFullScreenStack = GetTopFullScreenStack();
2944         CHECK_POINTER(topFullScreenStack);
2945         auto topFullScreenAbility = topFullScreenStack->GetTopAbilityRecord();
2946         if (topFullScreenAbility && topFullScreenAbility->IsAbilityState(INACTIVE)) {
2947             HILOG_INFO("Load timeout, top full screen ability restart.");
2948             MoveMissionStackToTop(topFullScreenStack);
2949             topFullScreenAbility->ProcessActivate();
2950         } else {
2951             HILOG_INFO("Load timeout, back to launcher.");
2952             BackToLauncher();
2953         }
2954     }
2955 }
2956 
GetMaxHoldMissionsByStackId(int stackId) const2957 int AbilityStackManager::GetMaxHoldMissionsByStackId(int stackId) const
2958 {
2959     for (auto &it : stackSettings_) {
2960         if (it.stackId == stackId) {
2961             return it.maxHoldMission;
2962         }
2963     }
2964     return DEFAULT_INVAL_VALUE;
2965 }
2966 
SupportSyncVisualByStackId(int stackId) const2967 bool AbilityStackManager::SupportSyncVisualByStackId(int stackId) const
2968 {
2969     for (auto &it : stackSettings_) {
2970         if (it.stackId == stackId && (!IsFullScreenStack(stackId))) {
2971             return it.isSyncVisual;
2972         }
2973     }
2974     return false;
2975 }
2976 
JudgingTargetSystemWindowMode(AbilityWindowConfiguration config) const2977 SystemWindowMode AbilityStackManager::JudgingTargetSystemWindowMode(AbilityWindowConfiguration config) const
2978 {
2979     switch (config) {
2980         // to do, split multi screen ,add key
2981         case AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY:
2982         case AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_SECONDARY:
2983             return SystemWindowMode::SPLITSCREEN_WINDOW_MODE;
2984         case AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FLOATING:
2985             return SystemWindowMode::FLOATING_WINDOW_MODE;
2986         default:
2987             return SystemWindowMode::DEFAULT_WINDOW_MODE;
2988     }
2989 }
2990 
JudgingTargetStackId(AbilityWindowConfiguration config) const2991 int AbilityStackManager::JudgingTargetStackId(AbilityWindowConfiguration config) const
2992 {
2993     switch (config) {
2994         // to do, split multi screen ,add key
2995         case AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY:
2996             return SPLIT_SCREEN_MISSION_STACK_ID;
2997         case AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FLOATING:
2998             return FLOATING_MISSION_STACK_ID;
2999         default:
3000             return DEFAULT_MISSION_STACK_ID;
3001     }
3002 }
3003 
IsFirstInMission(const sptr<IRemoteObject> & token)3004 bool AbilityStackManager::IsFirstInMission(const sptr<IRemoteObject> &token)
3005 {
3006     HILOG_INFO("Is first in mission.");
3007     std::lock_guard<std::recursive_mutex> guard(stackLock_);
3008 
3009     CHECK_POINTER_RETURN_BOOL(token);
3010     auto abilityRecord = GetAbilityRecordByToken(token);
3011     CHECK_POINTER_RETURN_BOOL(abilityRecord);
3012 
3013     auto missionRecord = abilityRecord->GetMissionRecord();
3014     CHECK_POINTER_RETURN_BOOL(missionRecord);
3015 
3016     return (missionRecord->GetBottomAbilityRecord() == abilityRecord);
3017 }
3018 
PowerOff()3019 int AbilityStackManager::PowerOff()
3020 {
3021     HILOG_INFO("Power off.");
3022     std::lock_guard<std::recursive_mutex> guard(stackLock_);
3023     return PowerOffLocked();
3024 }
3025 
PowerOffLocked()3026 int AbilityStackManager::PowerOffLocked()
3027 {
3028     HILOG_INFO("Power off locked.");
3029     auto currentTopAbility = GetCurrentTopAbility();
3030     if ((currentTopAbility && !currentTopAbility->IsAbilityState(AbilityState::ACTIVE)) ||
3031         !waittingAbilityQueue_.empty()) {
3032         HILOG_WARN("Current top ability is not active, waiting ability lifecycle complete");
3033         // In CompleteActive,waiting ability lifecycle complete,execute PowerOffLocked again
3034         powerOffing_ = true;
3035         return POWER_OFF_WAITING;
3036     }
3037 
3038     powerStorage_ = std::make_shared<PowerStorage>();
3039     CHECK_POINTER_AND_RETURN(powerStorage_, POWER_OFF_FAILED);
3040     for (auto &stack : missionStackList_) {
3041         std::vector<MissionRecordInfo> missionInfos;
3042         stack->GetAllMissionInfo(missionInfos);
3043         auto checkAbility = [&](const MissionRecordInfo &missionInfo) {
3044             auto missionRecord = stack->GetMissionRecordById(missionInfo.id);
3045             CHECK_POINTER(missionRecord);
3046             auto abilityRecord = missionRecord->GetTopAbilityRecord();
3047             CHECK_POINTER(abilityRecord);
3048             if (abilityRecord->IsAbilityState(AbilityState::ACTIVE)) {
3049                 powerStorage_->SetPowerOffActiveRecord(abilityRecord);
3050                 abilityRecord->SetPowerState(true);
3051                 abilityRecord->ProcessInactivate();
3052             }
3053             if (abilityRecord->IsAbilityState(AbilityState::INACTIVE)) {
3054                 powerStorage_->SetPowerOffInActiveRecord(abilityRecord);
3055                 MoveToBackgroundTask(abilityRecord);
3056             }
3057         };
3058         for_each(missionInfos.begin(), missionInfos.end(), checkAbility);
3059     }
3060     return ERR_OK;
3061 }
3062 
PowerOn()3063 int AbilityStackManager::PowerOn()
3064 {
3065     HILOG_INFO("Power on.");
3066     std::lock_guard<std::recursive_mutex> guard(stackLock_);
3067     return PowerOnLocked();
3068 }
3069 
PowerOnLocked()3070 int AbilityStackManager::PowerOnLocked()
3071 {
3072     HILOG_INFO("Power on locked.");
3073     powerOffing_ = false;
3074 
3075     CHECK_POINTER_AND_RETURN(powerStorage_, POWER_ON_FAILED);
3076     auto powerInActiveStorages = powerStorage_->GetPowerOffInActiveRecord();
3077     if (powerInActiveStorages.empty()) {
3078         if (ChangedPowerStorageAbilityToActive(powerStorage_) != ERR_OK) {
3079             HILOG_ERROR("ChangedPowerStorageAbilityToActive Fail");
3080             return POWER_ON_FAILED;
3081         }
3082         return ERR_OK;
3083     }
3084 
3085     for (auto &powerInActiveStorage : powerInActiveStorages) {
3086         auto storageInActiveAbility = powerInActiveStorage.ability.lock();
3087         CHECK_POINTER_CONTINUE(storageInActiveAbility);
3088         storageInActiveAbility->SetPowerState(true);
3089         storageInActiveAbility->ProcessActivate();
3090     }
3091     return ERR_OK;
3092 }
3093 
ChangedPowerStorageAbilityToActive(std::shared_ptr<PowerStorage> & powerStorage)3094 int AbilityStackManager::ChangedPowerStorageAbilityToActive(std::shared_ptr<PowerStorage> &powerStorage)
3095 {
3096     HILOG_INFO("%{public}s", __func__);
3097     CHECK_POINTER_AND_RETURN(powerStorage, ERR_INVALID_VALUE);
3098     auto powerActiveStorages = powerStorage->GetPowerOffActiveRecord();
3099     // Start the ability except the top of the stack
3100     for (auto &powerActiveStorage : powerActiveStorages) {
3101         auto storageActiveAbility = powerActiveStorage.ability.lock();
3102         CHECK_POINTER_CONTINUE(storageActiveAbility);
3103         storageActiveAbility->SetPowerState(true);
3104         if (storageActiveAbility == GetCurrentTopAbility()) {
3105             HILOG_DEBUG("There is no ability in active state except the top of the stack");
3106             continue;
3107         }
3108         storageActiveAbility->ProcessActivate();
3109     }
3110     // Finally,Start stack top ability
3111     auto currentTopAbility = GetCurrentTopAbility();
3112     CHECK_POINTER_AND_RETURN(currentTopAbility, ERR_INVALID_VALUE);
3113     currentTopAbility->ProcessActivate();
3114     HILOG_DEBUG("start the ability at the top of the stack");
3115     return ERR_OK;
3116 }
3117 
StartLockMission(int uid,int missionId,bool isSystemApp,int isLock)3118 int AbilityStackManager::StartLockMission(int uid, int missionId, bool isSystemApp, int isLock)
3119 {
3120     HILOG_INFO("%{public}s", __func__);
3121     std::lock_guard<std::recursive_mutex> guard(stackLock_);
3122 
3123     if (lockMissionContainer_ == nullptr) {
3124         lockMissionContainer_ = std::make_shared<LockMissionContainer>();
3125         CHECK_POINTER_AND_RETURN(lockMissionContainer_, INNER_ERR);
3126     }
3127 
3128     std::shared_ptr<MissionRecord> missionRecord;
3129     int lockUid = -1;
3130     if (!CheckLockMissionCondition(uid, missionId, isLock, isSystemApp, missionRecord, lockUid)) {
3131         HILOG_ERROR("check lock mission condition failed.");
3132         return LOCK_MISSION_DENY_FAILED;
3133     }
3134 
3135     // lock mission
3136     if (isLock) {
3137         if (!lockMissionContainer_->SetLockedMission(missionRecord, lockUid, isSystemApp)) {
3138             HILOG_ERROR("lock mission error.");
3139             return LOCK_MISSION_DENY_FAILED;
3140         }
3141         // notify wms mission locked state.
3142 
3143         // move lock mission to top
3144         return MoveMissionToTopLocked(missionRecord->GetMissionRecordId());
3145     }
3146 
3147     // unlock mission
3148     if (!lockMissionContainer_->ReleaseLockedMission(missionRecord, uid, isSystemApp)) {
3149         HILOG_ERROR("unlock mission error.");
3150         return UNLOCK_MISSION_DENY_FAILED;
3151     }
3152     return ERR_OK;
3153 }
3154 
CheckLockMissionCondition(int uid,int missionId,int isLock,bool isSystemApp,std::shared_ptr<MissionRecord> & mission,int & lockUid)3155 bool AbilityStackManager::CheckLockMissionCondition(
3156     int uid, int missionId, int isLock, bool isSystemApp, std::shared_ptr<MissionRecord> &mission, int &lockUid)
3157 {
3158     CHECK_POINTER_RETURN_BOOL(lockMissionContainer_);
3159     // lock or unlock mission by uid and missionId.
3160     if ((isLock && lockMissionContainer_->IsLockedMissionState()) ||
3161         (!isLock && !lockMissionContainer_->IsLockedMissionState())) {
3162         return false;
3163     }
3164 
3165     mission = GetMissionRecordFromAllStacks(missionId);
3166     if (missionId < 0 || mission == nullptr) {
3167         HILOG_ERROR("target mission is not exist.");
3168         return false;
3169     }
3170 
3171     auto fullScreenStack = IsFullScreenStack(mission->GetMissionStack()->GetMissionStackId());
3172     if (!fullScreenStack) {
3173         HILOG_ERROR("Multi-window active,lock mission failed.");
3174         return false;
3175     }
3176 
3177     auto topability = mission->GetTopAbilityRecord();
3178     auto bottomability = mission->GetBottomAbilityRecord();
3179     auto abilityManagerService = DelayedSingleton<AbilityManagerService>::GetInstance();
3180     CHECK_POINTER_RETURN_BOOL(topability);
3181     CHECK_POINTER_RETURN_BOOL(bottomability);
3182     CHECK_POINTER_RETURN_BOOL(abilityManagerService);
3183     lockUid = abilityManagerService->GetUidByBundleName(bottomability->GetAbilityInfo().bundleName);
3184     HILOG_INFO("target mission uid :%{public}d", lockUid);
3185 
3186     if (isLock && !isSystemApp) {
3187         // caller and locking ability must be same uid, and forground state.
3188         return (lockUid == uid) &&
3189                (topability->IsAbilityState(AbilityState::ACTIVE) || topability->IsAbilityState(AbilityState::INACTIVE));
3190     }
3191 
3192     return true;
3193 }
3194 
CanStartInLockMissionState(const AbilityRequest & abilityRequest,const std::shared_ptr<AbilityRecord> & currentTopAbility) const3195 bool AbilityStackManager::CanStartInLockMissionState(
3196     const AbilityRequest &abilityRequest, const std::shared_ptr<AbilityRecord> &currentTopAbility) const
3197 {
3198     if (currentTopAbility == nullptr || lockMissionContainer_ == nullptr) {
3199         return true;
3200     }
3201 
3202     if (!lockMissionContainer_->IsLockedMissionState()) {
3203         return true;
3204     }
3205 
3206     // current ability singeton mode
3207     if (currentTopAbility->GetAbilityInfo().launchMode == AppExecFwk::LaunchMode::SINGLETON) {
3208         if (abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::SINGLETON) {
3209             std::string bundleName = AbilityConfig::MISSION_NAME_MARK_HEAD + abilityRequest.abilityInfo.bundleName +
3210                                      AbilityConfig::MISSION_NAME_SEPARATOR + abilityRequest.abilityInfo.name;
3211             return lockMissionContainer_->IsSameLockedMission(bundleName);
3212         }
3213         return false;
3214     }
3215     // current ability standard mode
3216     if (abilityRequest.abilityInfo.launchMode != AppExecFwk::LaunchMode::SINGLETON) {
3217         bool isStackNotChanged = (currentTopAbility->IsLauncherAbility() && IsLauncherAbility(abilityRequest)) ||
3218                                  (!currentTopAbility->IsLauncherAbility() && !IsLauncherAbility(abilityRequest));
3219         // ability request will add to same mission.
3220         return isStackNotChanged;
3221     }
3222 
3223     return false;
3224 }
3225 
CanStopInLockMissionState(const std::shared_ptr<AbilityRecord> & terminateAbility) const3226 bool AbilityStackManager::CanStopInLockMissionState(const std::shared_ptr<AbilityRecord> &terminateAbility) const
3227 {
3228     if (lockMissionContainer_ == nullptr) {
3229         return true;
3230     }
3231 
3232     if (!lockMissionContainer_->IsLockedMissionState()) {
3233         return true;
3234     }
3235 
3236     auto mission = terminateAbility->GetMissionRecord();
3237     auto bottom = mission->GetBottomAbilityRecord();
3238     CHECK_POINTER_RETURN_BOOL(mission);
3239     CHECK_POINTER_RETURN_BOOL(bottom);
3240     return (lockMissionContainer_->IsSameLockedMission(mission->GetName()) && terminateAbility != bottom);
3241 }
3242 
SendUnlockMissionMessage()3243 void AbilityStackManager::SendUnlockMissionMessage()
3244 {
3245     HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
3246 }
3247 
IsTopInMission(const std::shared_ptr<AbilityRecord> & abilityRecord) const3248 bool AbilityStackManager::IsTopInMission(const std::shared_ptr<AbilityRecord> &abilityRecord) const
3249 {
3250     CHECK_POINTER_RETURN_BOOL(abilityRecord);
3251     auto missionRecord = abilityRecord->GetMissionRecord();
3252     CHECK_POINTER_RETURN_BOOL(missionRecord);
3253 
3254     return (missionRecord->GetTopAbilityRecord() == abilityRecord);
3255 }
3256 
IsFrontInAllStack(const std::shared_ptr<MissionStack> & stack) const3257 bool AbilityStackManager::IsFrontInAllStack(const std::shared_ptr<MissionStack> &stack) const
3258 {
3259     return stack == missionStackList_.front();
3260 }
3261 
IsFullScreenStack(int stackId) const3262 bool AbilityStackManager::IsFullScreenStack(int stackId) const
3263 {
3264     return (stackId == DEFAULT_MISSION_STACK_ID || stackId == LAUNCHER_MISSION_STACK_ID);
3265 }
3266 
GetTopFullScreenStack()3267 std::shared_ptr<MissionStack> AbilityStackManager::GetTopFullScreenStack()
3268 {
3269     auto isExist = [&](const std::shared_ptr<MissionStack> &stack) {
3270         return IsFullScreenStack(stack->GetMissionStackId());
3271     };
3272     auto iter = std::find_if(missionStackList_.begin(), missionStackList_.end(), isExist);
3273     if (iter != missionStackList_.end()) {
3274         return (*iter);
3275     }
3276     return nullptr;
3277 }
3278 
MinimizeMultiWindow(int missionId)3279 int AbilityStackManager::MinimizeMultiWindow(int missionId)
3280 {
3281     std::lock_guard<std::recursive_mutex> guard(stackLock_);
3282     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
3283         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
3284         return ERR_INVALID_VALUE;
3285     }
3286     return MinimizeMultiWindowLocked(missionId);
3287 }
3288 
MinimizeMultiWindowLocked(int missionId)3289 int AbilityStackManager::MinimizeMultiWindowLocked(int missionId)
3290 {
3291     HILOG_INFO("Minimize multi window locked.");
3292     auto missionRecord = GetMissionRecordFromAllStacks(missionId);
3293     CHECK_POINTER_AND_RETURN(missionRecord, MINIMIZE_MULTI_WINDOW_FAILED);
3294 
3295     auto stack = missionRecord->GetMissionStack();
3296     CHECK_POINTER_AND_RETURN(stack, MINIMIZE_MULTI_WINDOW_FAILED);
3297 
3298     if (!stack->IsEqualStackId(FLOATING_MISSION_STACK_ID)) {
3299         HILOG_ERROR("Mission is not in the float stack, can't be minimized.");
3300         return MINIMIZE_MULTI_WINDOW_FAILED;
3301     }
3302 
3303     return MoveMissionToEndLocked(missionRecord->GetMissionRecordId());
3304 }
3305 
ChangeFocusAbility(const sptr<IRemoteObject> & lostFocusToken,const sptr<IRemoteObject> & getFocusToken)3306 int AbilityStackManager::ChangeFocusAbility(
3307     const sptr<IRemoteObject> &lostFocusToken, const sptr<IRemoteObject> &getFocusToken)
3308 {
3309     HILOG_INFO("Change focus ability.");
3310     std::lock_guard<std::recursive_mutex> guard(stackLock_);
3311     CHECK_POINTER_AND_RETURN(lostFocusToken, ERR_INVALID_VALUE);
3312     CHECK_POINTER_AND_RETURN(getFocusToken, ERR_INVALID_VALUE);
3313     if (getFocusToken == lostFocusToken) {
3314         HILOG_WARN("get token is equal to lost token.");
3315         return CHANGE_FOCUS_ABILITY_FAILED;
3316     }
3317 
3318     auto currentAbility = GetCurrentTopAbility();
3319     CHECK_POINTER_AND_RETURN(currentAbility, CHANGE_FOCUS_ABILITY_FAILED);
3320     if (!currentAbility->IsAbilityState(AbilityState::ACTIVE) || !waittingAbilityQueue_.empty()) {
3321         HILOG_WARN("Top ability is not active or waiting queue is not empty, change focus failed");
3322         return CHANGE_FOCUS_ABILITY_FAILED;
3323     }
3324 
3325     auto targetAbility = Token::GetAbilityRecordByToken(getFocusToken);
3326     CHECK_POINTER_AND_RETURN(targetAbility, CHANGE_FOCUS_ABILITY_FAILED);
3327     return ChangeFocusAbilityLocked(targetAbility);
3328 }
3329 
ChangeFocusAbilityLocked(const std::shared_ptr<AbilityRecord> & targetAbility)3330 int AbilityStackManager::ChangeFocusAbilityLocked(const std::shared_ptr<AbilityRecord> &targetAbility)
3331 {
3332     HILOG_INFO("Change focus ability locked.");
3333     CHECK_POINTER_AND_RETURN(targetAbility, ERR_INVALID_VALUE);
3334 
3335     auto currentAbility = GetCurrentTopAbility();
3336     CHECK_POINTER_AND_RETURN(currentAbility, CHANGE_FOCUS_ABILITY_FAILED);
3337 
3338     if (targetAbility == currentAbility || !targetAbility->IsAbilityState(ACTIVE)) {
3339         HILOG_ERROR("Target ability is current ability, or target ability is not active, can't change focus.");
3340         return CHANGE_FOCUS_ABILITY_FAILED;
3341     }
3342 
3343     auto targetMission = targetAbility->GetMissionRecord();
3344     CHECK_POINTER_AND_RETURN_LOG(
3345         targetMission, CHANGE_FOCUS_ABILITY_FAILED, " TargetMission is  nullptr, change focus failed.");
3346 
3347     return MoveMissionToTop(targetMission->GetMissionRecordId());
3348 }
3349 
GetFloatingMissions(std::vector<AbilityMissionInfo> & list)3350 int AbilityStackManager::GetFloatingMissions(std::vector<AbilityMissionInfo> &list)
3351 {
3352     HILOG_INFO("Get floating missions.");
3353     std::lock_guard<std::recursive_mutex> guard(stackLock_);
3354 
3355     auto floatingStack = GetOrCreateMissionStack(FLOATING_MISSION_STACK_ID, false);
3356     CHECK_POINTER_AND_RETURN_LOG(
3357         floatingStack, GET_FLOATING_STACK_FAILED, "Floating stack is not exist, get floating missions failed.");
3358 
3359     std::vector<MissionRecordInfo> missionInfos;
3360     floatingStack->GetAllMissionInfo(missionInfos);
3361     for (auto &mission : missionInfos) {
3362         AbilityMissionInfo recentMissionInfo;
3363         CreateRecentMissionInfo(mission, recentMissionInfo);
3364         list.emplace_back(recentMissionInfo);
3365     }
3366 
3367     return ERR_OK;
3368 }
3369 
CloseMultiWindow(int missionId)3370 int AbilityStackManager::CloseMultiWindow(int missionId)
3371 {
3372     HILOG_INFO("Close multi window.");
3373     std::lock_guard<std::recursive_mutex> guard(stackLock_);
3374     if (lockMissionContainer_ && lockMissionContainer_->IsLockedMissionState()) {
3375         HILOG_ERROR("current is lock mission state, refusing to operate other mission.");
3376         return ERR_INVALID_VALUE;
3377     }
3378 
3379     auto mission = GetMissionRecordFromAllStacks(missionId);
3380     CHECK_POINTER_AND_RETURN(mission, CLOSE_MULTI_WINDOW_FAILED);
3381 
3382     auto stack = mission->GetMissionStack();
3383     CHECK_POINTER_AND_RETURN(stack, CLOSE_MULTI_WINDOW_FAILED);
3384 
3385     if (IsFullScreenStack(stack->GetMissionStackId())) {
3386         HILOG_ERROR("Full screen stack is not close.");
3387         return CLOSE_MULTI_WINDOW_FAILED;
3388     }
3389 
3390     return RemoveMissionByIdLocked(missionId);
3391 }
3392 
JudgingIsRemoveMultiScreenStack(std::shared_ptr<MissionStack> & stack)3393 void AbilityStackManager::JudgingIsRemoveMultiScreenStack(std::shared_ptr<MissionStack> &stack)
3394 {
3395     HILOG_INFO("Judging is remove multi screen stack.");
3396 
3397     if (stack && !IsFullScreenStack(stack->GetMissionStackId()) && stack->IsEmpty()) {
3398         HILOG_DEBUG("Current stack is empty, remove.");
3399         missionStackList_.remove(stack);
3400 
3401         auto targetWinMode = GetTargetSystemWindowMode(SystemWindowMode::DEFAULT_WINDOW_MODE);
3402         NotifyWindowModeChanged(targetWinMode);
3403     }
3404 }
3405 
NotifyWindowModeChanged(const SystemWindowMode & windowMode)3406 void AbilityStackManager::NotifyWindowModeChanged(const SystemWindowMode &windowMode)
3407 {
3408     HILOG_INFO("Notify window mode changed, will window mode: %{public}d", windowMode);
3409     if (curSysWindowMode_ == windowMode) {
3410         HILOG_ERROR("change mode is current mode");
3411         return;
3412     }
3413 
3414     HILOG_INFO("current mode : %{public}d , target window mode : %{public}d", curSysWindowMode_, windowMode);
3415 
3416     curSysWindowMode_ = windowMode;
3417 
3418     std::string data;
3419     switch (windowMode) {
3420         case SystemWindowMode::SPLITSCREEN_WINDOW_MODE:
3421             data = "SPLITSCREEN_WINDOW_MODE";
3422             break;
3423         case SystemWindowMode::FLOATING_WINDOW_MODE:
3424             data = "FLOATING_WINDOW_MODE";
3425             break;
3426         case SystemWindowMode::FLOATING_AND_SPLITSCREEN_WINDOW_MODE:
3427             data = "FLOATING_AND_SPLITSCREEN_WINDOW_MODE";
3428             break;
3429         default:
3430             data = "DEFAULT_WINDOW_MODE";
3431             break;
3432     }
3433 
3434     HILOG_INFO("Publish common event : system window mode changed");
3435     EventFwk::CommonEventData commonData;
3436     Want want;
3437     want.SetAction(AbilityConfig::EVENT_SYSTEM_WINDOW_MODE_CHANGED);
3438     commonData.SetWant(want);
3439     commonData.SetCode(AbilityConfig::EVENT_CODE_SYSTEM_WINDOW_MODE_CHANGED);
3440     commonData.SetData(data);
3441     EventFwk::CommonEventManager::PublishCommonEvent(commonData);
3442 }
3443 
UpdateFocusAbilityRecord(const std::shared_ptr<AbilityRecord> & abilityRecord,bool isNotify)3444 void AbilityStackManager::UpdateFocusAbilityRecord(const std::shared_ptr<AbilityRecord> &abilityRecord, bool isNotify)
3445 {
3446     CHECK_POINTER(abilityRecord);
3447     auto getMissionOptionDisplayId = [target = abilityRecord]() {
3448         auto missionRecord = target->GetMissionRecord();
3449         return missionRecord ? missionRecord->GetMissionOption().displayKey : DISPLAY_DEFAULT_ID;
3450     };
3451     auto setting = abilityRecord->GetStartSetting();
3452     int displayId = setting ? std::atoi(setting->GetProperty(AbilityStartSetting::WINDOW_DISPLAY_ID_KEY).c_str())
3453                             : getMissionOptionDisplayId();
3454     UpdateFocusAbilityRecord(displayId, abilityRecord, isNotify);
3455 }
3456 
UpdateFocusAbilityRecord(int displayId,const std::shared_ptr<AbilityRecord> & focusAbility,bool isNotify)3457 void AbilityStackManager::UpdateFocusAbilityRecord(
3458     int displayId, const std::shared_ptr<AbilityRecord> &focusAbility, bool isNotify)
3459 {
3460     CHECK_POINTER(focusAbility);
3461     auto iter = focusAbilityRecordMap_.find(displayId);
3462     if (iter != focusAbilityRecordMap_.end()) {
3463         auto loseFocusAbility = iter->second.lock();
3464         if (loseFocusAbility && isNotify) {
3465             loseFocusAbility->TopActiveAbilityChanged(false);
3466         }
3467         focusAbilityRecordMap_.erase(iter);
3468     }
3469 
3470     HILOG_INFO("top active ability changed, displayId:%{public}d, name:%{public}s",
3471         displayId,
3472         focusAbility->GetAbilityInfo().name.c_str());
3473 
3474     if (isNotify) {
3475         focusAbility->TopActiveAbilityChanged(true);
3476     }
3477     focusAbilityRecordMap_.emplace(displayId, focusAbility);
3478 }
3479 
CheckMissionRecordIsResume(const std::shared_ptr<MissionRecord> & mission)3480 void AbilityStackManager::CheckMissionRecordIsResume(const std::shared_ptr<MissionRecord> &mission)
3481 {
3482     if (resumeMissionContainer_ && resumeMissionContainer_->IsResume(mission->GetMissionRecordId())) {
3483         resumeMissionContainer_->Resume(mission);
3484     }
3485 }
3486 }  // namespace AAFwk
3487 }  // namespace OHOS
3488