1 /*
2 * Copyright (c) 2020 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_mission_stack.h"
17
18 #include "util/abilityms_log.h"
19
20 namespace OHOS {
21
22 namespace {
23 constexpr static uint16_t MISSION_RECORD_LIST_CAPACITY = 10240;
24 }
25
AbilityMissionStack(StackType type)26 AbilityMissionStack::AbilityMissionStack(StackType type)
27 : stackType_(type)
28 {
29 }
30
~AbilityMissionStack()31 AbilityMissionStack::~AbilityMissionStack()
32 {
33 for (auto iterator = missionRecords_.begin(); iterator != missionRecords_.end();) {
34 AbilityMissionRecord *missionRecord = *iterator;
35 iterator = missionRecords_.erase(iterator);
36 delete missionRecord;
37 }
38 }
39
GetStackType() const40 StackType AbilityMissionStack::GetStackType() const
41 {
42 return stackType_;
43 }
44
PushTopMissionRecord(AbilityMissionRecord & missionRecord)45 void AbilityMissionStack::PushTopMissionRecord(AbilityMissionRecord &missionRecord)
46 {
47 missionRecord.SetMissionStack(this);
48 if (missionRecords_.size() >= MISSION_RECORD_LIST_CAPACITY) {
49 return;
50 }
51 missionRecords_.emplace_back(&missionRecord);
52 }
53
MoveMissionRecordToTop(AbilityMissionRecord & missionRecord)54 void AbilityMissionStack::MoveMissionRecordToTop(AbilityMissionRecord &missionRecord)
55 {
56 if (missionRecords_.back() != &missionRecord) {
57 missionRecords_.remove(&missionRecord);
58 missionRecords_.emplace_back(&missionRecord);
59 }
60 }
61
RemoveMissionRecord(AbilityMissionRecord & missionRecord)62 void AbilityMissionStack::RemoveMissionRecord(AbilityMissionRecord &missionRecord)
63 {
64 missionRecords_.remove(&missionRecord);
65 // clear prev mission record
66 for (const auto currentMission : missionRecords_) {
67 if (currentMission != nullptr && currentMission->GetPrevMissionRecord() == &missionRecord) {
68 currentMission->SetPrevMissionRecord(nullptr);
69 }
70 }
71 }
72
RemoveMissionRecord(AbilityConnectMission * connectMission,const char * bundleName)73 void AbilityMissionStack::RemoveMissionRecord(AbilityConnectMission *connectMission, const char *bundleName)
74 {
75 AbilityMissionRecord *missionRecord = GetTargetMissionRecord(bundleName);
76 CHECK_NULLPTR_RETURN(missionRecord, "AbilityMissionStack", "missionRecord is null");
77 missionRecord->ClearPageAbility(connectMission);
78 RemoveMissionRecord(*missionRecord);
79 delete missionRecord;
80 }
81
IsTopMissionRecord(const char * bundleName) const82 bool AbilityMissionStack::IsTopMissionRecord(const char *bundleName) const
83 {
84 if (bundleName == nullptr) {
85 return false;
86 }
87 AbilityMissionRecord *topMissionRecord = missionRecords_.back();
88 if (topMissionRecord != nullptr) {
89 return topMissionRecord->IsSameMissionRecord(bundleName);
90 }
91 return false;
92 }
93
GetTargetMissionRecord(const char * bundleName) const94 AbilityMissionRecord *AbilityMissionStack::GetTargetMissionRecord(const char *bundleName) const
95 {
96 CHECK_NULLPTR_RETURN_PTR(bundleName, "AbilityMissionStack", "invalid argument");
97 for (const auto missionRecord : missionRecords_) {
98 if (missionRecord != nullptr && missionRecord->IsSameMissionRecord(bundleName)) {
99 return missionRecord;
100 }
101 }
102 return nullptr;
103 }
104
GetTopMissionRecord() const105 const AbilityMissionRecord *AbilityMissionStack::GetTopMissionRecord() const
106 {
107 return missionRecords_.back();
108 }
109
FindPageAbility(uint64_t token) const110 PageAbilityRecord *AbilityMissionStack::FindPageAbility(uint64_t token) const
111 {
112 for (const auto missionRecord : missionRecords_) {
113 if (missionRecord == nullptr) {
114 continue;
115 }
116 PageAbilityRecord *record = missionRecord->FindPageAbility(token);
117 if (record != nullptr) {
118 return record;
119 }
120 }
121 return nullptr;
122 }
123
FindPageAbility(const Want & want) const124 PageAbilityRecord *AbilityMissionStack::FindPageAbility(const Want &want) const
125 {
126 CHECK_NULLPTR_RETURN_PTR(want.element, "AbilityMissionStack", "invalid argument");
127 AbilityMissionRecord *missionRecord = GetTargetMissionRecord(want.element->bundleName);
128 if (missionRecord != nullptr) {
129 return missionRecord->FindPageAbility(want);
130 }
131 return nullptr;
132 }
133
GetTopPageAbility() const134 const PageAbilityRecord *AbilityMissionStack::GetTopPageAbility() const
135 {
136 if (!missionRecords_.empty()) {
137 return missionRecords_.back()->GetTopPageAbility();
138 }
139 return nullptr;
140 }
141
142 #ifdef OHOS_DEBUG
DumpMissionStack() const143 AbilityMsStatus AbilityMissionStack::DumpMissionStack() const
144 {
145 if (missionRecords_.size() <= 0) {
146 return AbilityMsStatus::DumpStatus("");
147 }
148 std::string stackType = (stackType_ == LAUNCHER) ? "launcher\n" : "default\n";
149 std::string stackInfo = "MissionStack Type: " + stackType;
150 AbilityMsStatus result = AbilityMsStatus::DumpStatus(stackInfo.c_str());
151 for (const auto missionRecord : missionRecords_) {
152 if (missionRecord != nullptr) {
153 result.DumpAppend(missionRecord->DumpMissionRecord());
154 }
155 }
156 return result;
157 }
158 #endif
159 } // namespace OHOS
160