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 "ability_util.h"
19 #include "hilog_wrapper.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 }
145 }
146
RemoveAbilityRecord(std::shared_ptr<AbilityRecord> ability)147 bool MissionRecord::RemoveAbilityRecord(std::shared_ptr<AbilityRecord> ability)
148 {
149 CHECK_POINTER_RETURN_BOOL(ability);
150 for (auto iter = abilities_.begin(); iter != abilities_.end(); iter++) {
151 if ((*iter) == ability) {
152 abilities_.erase(iter);
153 return true;
154 }
155 }
156 HILOG_ERROR("can not find ability");
157 return false;
158 }
159
RemoveTopAbilityRecord()160 bool MissionRecord::RemoveTopAbilityRecord()
161 {
162 if (abilities_.empty()) {
163 HILOG_ERROR("abilities is empty");
164 return false;
165 }
166 abilities_.pop_front();
167 return true;
168 }
169
RemoveAll()170 void MissionRecord::RemoveAll()
171 {
172 abilities_.clear();
173 }
174
Dump(std::vector<std::string> & info)175 void MissionRecord::Dump(std::vector<std::string> &info)
176 {
177 std::string dumpInfo = " MissionRecord ID #" + std::to_string(missionId_);
178 std::shared_ptr<AbilityRecord> bottomAbility = GetBottomAbilityRecord();
179 if (bottomAbility) {
180 dumpInfo += " bottom app [" + bottomAbility->GetAbilityInfo().name + "]" + " winMode #" +
181 std::to_string(option_.winModeKey);
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 for (auto &it : abilities_) {
260 it->SetMissionStackId(stackId);
261 }
262 }
263
GetMissionStack() const264 std::shared_ptr<MissionStack> MissionRecord::GetMissionStack() const
265 {
266 return parentMissionStack_.lock();
267 }
268
SetMissionOption(const MissionOption & option)269 void MissionRecord::SetMissionOption(const MissionOption &option)
270 {
271 if (option.winModeKey != option_.winModeKey) {
272 HILOG_ERROR("Batch processing notify multi window mode changed.");
273 for (auto &it : abilities_) {
274 CHECK_POINTER(it);
275 bool flag = option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY ||
276 option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_SECONDARY ||
277 option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FLOATING;
278 // true : old is multi win, target is fullscreen.
279 // false : old is fullscreen, target is multi win.
280 auto key = flag ? option.winModeKey : option_.winModeKey;
281 if (it->IsReady()) {
282 it->NotifyMultiWinModeChanged(key, flag);
283 }
284 }
285 }
286
287 option_ = option;
288 }
289
GetMissionOption() const290 const MissionOption &MissionRecord::GetMissionOption() const
291 {
292 return option_;
293 }
294
IsEmpty()295 bool MissionRecord::IsEmpty()
296 {
297 return abilities_.empty();
298 }
299
Resume(const std::shared_ptr<MissionRecord> & backup)300 void MissionRecord::Resume(const std::shared_ptr<MissionRecord> &backup)
301 {
302 HILOG_INFO("mission resume.");
303 // backup abilities_ size = 1, singleton ability need resume
304 if (std::equal(abilities_.begin(), abilities_.end(), backup->abilities_.begin()) && backup->abilities_.size() > 1) {
305 HILOG_ERROR("List equality, no resume");
306 return;
307 }
308
309 std::list<std::shared_ptr<AbilityRecord>> diffAbilitys;
310 for (auto &ability : backup->abilities_) {
311 if (abilities_.front() == ability) {
312 break;
313 }
314
315 ability->SetAbilityState(AbilityState::INITIAL);
316 diffAbilitys.emplace_back(ability);
317 }
318
319 abilities_.insert(abilities_.begin(), diffAbilitys.begin(), diffAbilitys.end());
320
321 for (auto &ability : abilities_) {
322 if (ability->IsAbilityState(AbilityState::INITIAL)) {
323 ability->ClearFlag();
324 ability->SetRestarting(true);
325 }
326 }
327 }
328
SetMissionIndexInfo(int32_t stackId,int32_t missionIndex)329 void MissionRecord::SetMissionIndexInfo(int32_t stackId, int32_t missionIndex)
330 {
331 indexInfo_.SetMissionIndexInfo(stackId, missionIndex);
332 }
333
GetMissionIndexInfo()334 MissionIndexInfo MissionRecord::GetMissionIndexInfo()
335 {
336 return indexInfo_;
337 }
338
UpdateActiveTimestamp()339 void MissionRecord::UpdateActiveTimestamp()
340 {
341 activeTimestamp_ = AbilityUtil::SystemTimeMillis();
342 }
343
GetActiveTimestamp() const344 int64_t MissionRecord::GetActiveTimestamp() const
345 {
346 return activeTimestamp_;
347 }
348 } // namespace AAFwk
349 } // namespace OHOS
350