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> ¤tTopAbility, 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> ¤tTopAbility, 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> ¤tTopAbility,
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> ¤tTopAbility, 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> ¤tTopAbility, 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> ¤tTopAbility, 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> ¤tTopAbility, 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> ¤tTopAbility, 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> ¤tTopAbility) 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