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 "mission_record.h"
17
18 #include "hilog_wrapper.h"
19 #include "ability_util.h"
20
21 namespace OHOS {
22 namespace AAFwk {
23 int MissionRecord::nextMissionId_ = 0;
24
MissionRecord(const std::string & bundleName)25 MissionRecord::MissionRecord(const std::string &bundleName) : bundleName_(bundleName)
26 {
27 missionId_ = GetNextMissionId();
28 option_.missionId = missionId_;
29 }
30
MissionRecord(const std::shared_ptr<MissionRecord> & mission)31 MissionRecord::MissionRecord(const std::shared_ptr<MissionRecord> &mission)
32 {
33 bundleName_ = mission->bundleName_;
34 missionId_ = mission->missionId_;
35 abilities_.insert(abilities_.begin(), mission->abilities_.begin(), mission->abilities_.end());
36 isLauncherCreate_ = mission->isLauncherCreate_;
37 preMissionRecord_ = mission->preMissionRecord_;
38 parentMissionStack_ = mission->parentMissionStack_;
39 missionDescriptionInfo_ = mission->missionDescriptionInfo_;
40 }
41
~MissionRecord()42 MissionRecord::~MissionRecord()
43 {}
44
GetNextMissionId()45 int MissionRecord::GetNextMissionId()
46 {
47 return nextMissionId_++;
48 }
49
GetMissionRecordId() const50 int MissionRecord::GetMissionRecordId() const
51 {
52 return missionId_;
53 }
54
GetAbilityRecordCount() const55 int MissionRecord::GetAbilityRecordCount() const
56 {
57 return abilities_.size();
58 }
59
GetBottomAbilityRecord() const60 std::shared_ptr<AbilityRecord> MissionRecord::GetBottomAbilityRecord() const
61 {
62 if (abilities_.empty()) {
63 HILOG_ERROR("abilities is empty");
64 return nullptr;
65 }
66 return abilities_.back();
67 }
68
GetTopAbilityRecord() const69 std::shared_ptr<AbilityRecord> MissionRecord::GetTopAbilityRecord() const
70 {
71 if (abilities_.empty()) {
72 HILOG_ERROR("abilities is empty");
73 return nullptr;
74 }
75 return abilities_.front();
76 }
77
GetLastTopAbility() const78 std::shared_ptr<AbilityRecord> MissionRecord::GetLastTopAbility() const
79 {
80 if (abilities_.empty() || abilities_.size() == 1) {
81 HILOG_WARN("no last top ability.");
82 return nullptr;
83 }
84 auto iter = abilities_.begin();
85 return (*(++iter));
86 }
87
GetAbilityRecordByToken(const sptr<IRemoteObject> & token) const88 std::shared_ptr<AbilityRecord> MissionRecord::GetAbilityRecordByToken(const sptr<IRemoteObject> &token) const
89 {
90 auto abilityToFind = Token::GetAbilityRecordByToken(token);
91 CHECK_POINTER_AND_RETURN(abilityToFind, nullptr);
92
93 auto isExist = [targetAbility = abilityToFind](const std::shared_ptr<AbilityRecord> &ability) {
94 if (ability == nullptr) {
95 return false;
96 }
97 return targetAbility == ability;
98 };
99
100 auto iter = std::find_if(abilities_.begin(), abilities_.end(), isExist);
101 if (iter != abilities_.end()) {
102 return *iter;
103 }
104
105 return nullptr;
106 }
107
GetAbilityRecordById(const int64_t recordId) const108 std::shared_ptr<AbilityRecord> MissionRecord::GetAbilityRecordById(const int64_t recordId) const
109 {
110 for (std::shared_ptr<AbilityRecord> ability : abilities_) {
111 if (ability != nullptr && ability->GetRecordId() == recordId) {
112 return ability;
113 }
114 }
115 return nullptr;
116 }
117
GetAbilityRecordByCaller(const std::shared_ptr<AbilityRecord> & caller,int requestCode)118 std::shared_ptr<AbilityRecord> MissionRecord::GetAbilityRecordByCaller(
119 const std::shared_ptr<AbilityRecord> &caller, int requestCode)
120 {
121 for (auto &ability : abilities_) {
122 auto callerList = ability->GetCallerRecordList();
123 for (auto callerAbility : callerList) {
124 if (callerAbility->GetCaller() == caller && callerAbility->GetRequestCode() == requestCode) {
125 return ability;
126 }
127 }
128 }
129 return nullptr;
130 }
131
AddAbilityRecordToTop(std::shared_ptr<AbilityRecord> ability)132 void MissionRecord::AddAbilityRecordToTop(std::shared_ptr<AbilityRecord> ability)
133 {
134 CHECK_POINTER(ability);
135 auto isExist = [targetAbility = ability](const std::shared_ptr<AbilityRecord> &ability) {
136 if (ability == nullptr) {
137 return false;
138 }
139 return targetAbility == ability;
140 };
141 auto iter = std::find_if(abilities_.begin(), abilities_.end(), isExist);
142 if (iter == abilities_.end()) {
143 abilities_.push_front(ability);
144 ability->ForceProcessConfigurationChange(GetConfiguration());
145 }
146 }
147
RemoveAbilityRecord(std::shared_ptr<AbilityRecord> ability)148 bool MissionRecord::RemoveAbilityRecord(std::shared_ptr<AbilityRecord> ability)
149 {
150 CHECK_POINTER_RETURN_BOOL(ability);
151 for (auto iter = abilities_.begin(); iter != abilities_.end(); iter++) {
152 if ((*iter) == ability) {
153 abilities_.erase(iter);
154 return true;
155 }
156 }
157 HILOG_ERROR("can not find ability");
158 return false;
159 }
160
RemoveTopAbilityRecord()161 bool MissionRecord::RemoveTopAbilityRecord()
162 {
163 if (abilities_.empty()) {
164 HILOG_ERROR("abilities is empty");
165 return false;
166 }
167 abilities_.pop_front();
168 return true;
169 }
170
RemoveAll()171 void MissionRecord::RemoveAll()
172 {
173 abilities_.clear();
174 }
175
Dump(std::vector<std::string> & info)176 void MissionRecord::Dump(std::vector<std::string> &info)
177 {
178 std::string dumpInfo = " MissionRecord ID #" + std::to_string(missionId_);
179 std::shared_ptr<AbilityRecord> bottomAbility = GetBottomAbilityRecord();
180 if (bottomAbility) {
181 dumpInfo += " bottom app [" + bottomAbility->GetAbilityInfo().name + "]";
182 info.push_back(dumpInfo);
183 for (auto abilityRecord : abilities_) {
184 abilityRecord->Dump(info);
185 }
186 }
187 }
188
IsSameMissionRecord(const std::string & bundleName) const189 bool MissionRecord::IsSameMissionRecord(const std::string &bundleName) const
190 {
191 if (bundleName.empty() || bundleName_.empty()) {
192 return false;
193 }
194 return (bundleName == bundleName_);
195 }
196
GetAllAbilityInfo(std::vector<AbilityRecordInfo> & abilityInfos)197 void MissionRecord::GetAllAbilityInfo(std::vector<AbilityRecordInfo> &abilityInfos)
198 {
199 for (auto ability : abilities_) {
200 AbilityRecordInfo abilityInfo;
201 ability->GetAbilityRecordInfo(abilityInfo);
202 abilityInfos.emplace_back(abilityInfo);
203 }
204 }
205
IsTopAbilityRecordByName(const std::string & abilityName)206 bool MissionRecord::IsTopAbilityRecordByName(const std::string &abilityName)
207 {
208 std::shared_ptr<AbilityRecord> topAbility = GetTopAbilityRecord();
209 if (topAbility == nullptr) {
210 return false;
211 }
212
213 return (topAbility->GetAbilityInfo().name.compare(abilityName) == 0);
214 }
215
SetIsLauncherCreate()216 void MissionRecord::SetIsLauncherCreate()
217 {
218 isLauncherCreate_ = true;
219 }
220
IsLauncherCreate() const221 bool MissionRecord::IsLauncherCreate() const
222 {
223 return isLauncherCreate_;
224 }
225
SetPreMissionRecord(const std::shared_ptr<MissionRecord> & record)226 void MissionRecord::SetPreMissionRecord(const std::shared_ptr<MissionRecord> &record)
227 {
228 preMissionRecord_ = record;
229 }
230
GetPreMissionRecord() const231 std::shared_ptr<MissionRecord> MissionRecord::GetPreMissionRecord() const
232 {
233 return preMissionRecord_.lock();
234 }
235
IsExistAbilityRecord(int32_t id)236 bool MissionRecord::IsExistAbilityRecord(int32_t id)
237 {
238 for (auto &it : abilities_) {
239 if (it->GetRecordId() == id) {
240 return true;
241 }
242 }
243 return false;
244 }
245
SupportMultWindow() const246 bool MissionRecord::SupportMultWindow() const
247 {
248 auto bottom = GetBottomAbilityRecord();
249 if (bottom != nullptr) {
250 return bottom->SupportMultWindow();
251 }
252 return false;
253 }
254
SetMissionStack(const std::shared_ptr<MissionStack> & missionStack,int stackId)255 void MissionRecord::SetMissionStack(const std::shared_ptr<MissionStack> &missionStack, int stackId)
256 {
257 CHECK_POINTER(missionStack);
258 parentMissionStack_ = missionStack;
259 ConfigurationHolder::Init(missionStack->GetConfiguration());
260 for (auto &it : abilities_) {
261 it->SetMissionStackId(stackId);
262 }
263 }
264
GetMissionStack() const265 std::shared_ptr<MissionStack> MissionRecord::GetMissionStack() const
266 {
267 return parentMissionStack_.lock();
268 }
269
SetMissionOption(const MissionOption & option)270 void MissionRecord::SetMissionOption(const MissionOption &option)
271 {
272 if (option.winModeKey != option_.winModeKey) {
273 HILOG_ERROR("Batch processing notify multi window mode changed.");
274 for (auto &it : abilities_) {
275 CHECK_POINTER(it);
276 bool flag = option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY ||
277 option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_SECONDARY ||
278 option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FLOATING;
279 // true : old is multi win, target is fullscreen.
280 // false : old is fullscreen, target is multi win.
281 auto key = flag ? option.winModeKey : option_.winModeKey;
282 if (it->IsReady()) {
283 it->NotifyMultiWinModeChanged(key, flag);
284 }
285 }
286 }
287
288 option_ = option;
289 }
290
GetMissionOption() const291 const MissionOption &MissionRecord::GetMissionOption() const
292 {
293 return option_;
294 }
295
IsEmpty()296 bool MissionRecord::IsEmpty()
297 {
298 return abilities_.empty();
299 }
300
GetParent()301 std::shared_ptr<ConfigurationHolder> MissionRecord::GetParent()
302 {
303 return parentMissionStack_.lock();
304 }
305
GetChildSize()306 unsigned int MissionRecord::GetChildSize()
307 {
308 return abilities_.size();
309 }
310
FindChild(unsigned int index)311 std::shared_ptr<ConfigurationHolder> MissionRecord::FindChild(unsigned int index)
312 {
313 if (index < abilities_.size() && index >= 0) {
314 auto iter = abilities_.begin();
315 std::advance(iter, index);
316 return (*iter);
317 }
318 return nullptr;
319 }
320
Resume(const std::shared_ptr<MissionRecord> & backup)321 void MissionRecord::Resume(const std::shared_ptr<MissionRecord> &backup)
322 {
323 HILOG_INFO("mission resume.");
324 // backup abilities_ size = 1, singleton ability need resume
325 if (std::equal(abilities_.begin(), abilities_.end(), backup->abilities_.begin()) && backup->abilities_.size() > 1) {
326 HILOG_ERROR("List equality, no resume");
327 return;
328 }
329
330 std::list<std::shared_ptr<AbilityRecord>> diffAbilitys;
331 for (auto &ability : backup->abilities_) {
332 if (abilities_.front() == ability) {
333 break;
334 }
335
336 ability->SetAbilityState(AbilityState::INITIAL);
337 diffAbilitys.emplace_back(ability);
338 }
339
340 abilities_.insert(abilities_.begin(), diffAbilitys.begin(), diffAbilitys.end());
341
342 for (auto &ability : abilities_) {
343 if (ability->IsAbilityState(AbilityState::INITIAL)) {
344 ability->ClearFlag();
345 ability->SetRestarting(true);
346 }
347 }
348 }
349 } // namespace AAFwk
350 } // namespace OHOS
351