1 /*
2 * Copyright (c) 2021-2023 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_list.h"
17
18 #include "hilog_wrapper.h"
19
20 namespace OHOS {
21 namespace AAFwk {
MissionList(MissionListType type)22 MissionList::MissionList(MissionListType type) : type_(type)
23 {
24 }
25
~MissionList()26 MissionList::~MissionList()
27 {
28 }
29
AddMissionToTop(const std::shared_ptr<Mission> & mission)30 void MissionList::AddMissionToTop(const std::shared_ptr<Mission> &mission)
31 {
32 if (!mission) {
33 return;
34 }
35
36 if (!missions_.empty() && missions_.front() == mission) {
37 HILOG_DEBUG("mission is already at the top of list");
38 return;
39 }
40
41 missions_.remove(mission);
42 missions_.push_front(mission);
43 mission->SetMissionList(shared_from_this());
44 }
45
RemoveMission(const std::shared_ptr<Mission> & mission)46 void MissionList::RemoveMission(const std::shared_ptr<Mission> &mission)
47 {
48 for (auto iter = missions_.begin(); iter != missions_.end(); iter++) {
49 if (*iter == mission) {
50 missions_.erase(iter);
51 return;
52 }
53 }
54 }
55
GetTopMission() const56 std::shared_ptr<Mission> MissionList::GetTopMission() const
57 {
58 if (missions_.empty()) {
59 return nullptr;
60 }
61
62 return missions_.front();
63 }
64
GetSingletonMissionByName(const std::string & missionName) const65 std::shared_ptr<Mission> MissionList::GetSingletonMissionByName(const std::string &missionName) const
66 {
67 if (missionName.empty()) {
68 return nullptr;
69 }
70
71 for (auto mission : missions_) {
72 if (mission && mission->IsSingletonAbility() && mission->GetMissionName() == missionName) {
73 return mission;
74 }
75 }
76
77 return nullptr;
78 }
79
GetSpecifiedMission(const std::string & missionName,const std::string & flag) const80 std::shared_ptr<Mission> MissionList::GetSpecifiedMission(
81 const std::string &missionName, const std::string& flag) const
82 {
83 if (missionName.empty() || flag.empty()) {
84 return nullptr;
85 }
86
87 for (auto& mission : missions_) {
88 if (mission && mission->IsSpecifiedAbility() && mission->GetMissionName() == missionName &&
89 mission->GetSpecifiedFlag() == flag) {
90 return mission;
91 }
92 }
93
94 return nullptr;
95 }
96
GetRecentStandardMission(const std::string & missionName) const97 std::shared_ptr<Mission> MissionList::GetRecentStandardMission(const std::string &missionName) const
98 {
99 if (missionName.empty()) {
100 return nullptr;
101 }
102
103 std::string missionTime = "0";
104 std::shared_ptr<Mission> result = nullptr;
105 for (auto& mission : missions_) {
106 if (mission && mission->IsStandardAbility() && mission->GetMissionName() == missionName &&
107 mission->GetMissionTime() >= missionTime) {
108 result = mission;
109 missionTime = mission->GetMissionTime();
110 }
111 }
112
113 return result;
114 }
115
GetAbilityRecordByToken(const sptr<IRemoteObject> & token) const116 std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordByToken(const sptr<IRemoteObject> &token) const
117 {
118 for (auto mission : missions_) {
119 if (!mission) {
120 continue;
121 }
122 std::shared_ptr<AbilityRecord> abilityRecord = mission->GetAbilityRecord();
123 if (abilityRecord && token == abilityRecord->GetToken()->AsObject()) {
124 return abilityRecord;
125 }
126 }
127
128 return nullptr;
129 }
130
RemoveMissionByAbilityRecord(const std::shared_ptr<AbilityRecord> & abilityRecord)131 void MissionList::RemoveMissionByAbilityRecord(const std::shared_ptr<AbilityRecord> &abilityRecord)
132 {
133 for (auto iter = missions_.begin(); iter != missions_.end(); iter++) {
134 if ((*iter)->GetAbilityRecord() == abilityRecord) {
135 missions_.erase(iter);
136 return;
137 }
138 }
139 }
140
GetMissionById(int missionId) const141 std::shared_ptr<Mission> MissionList::GetMissionById(int missionId) const
142 {
143 for (auto mission : missions_) {
144 if (mission && mission->GetMissionId() == missionId) {
145 return mission;
146 }
147 }
148
149 return nullptr;
150 }
151
GetMissionBySpecifiedFlag(const AAFwk::Want & want,const std::string & flag) const152 std::shared_ptr<Mission> MissionList::GetMissionBySpecifiedFlag(const AAFwk::Want &want, const std::string &flag) const
153 {
154 for (auto mission : missions_) {
155 if (!mission) {
156 return nullptr;
157 }
158
159 auto ability = mission->GetAbilityRecord();
160 if (!ability) {
161 return nullptr;
162 }
163
164 std::string srcAbilityName = ability->GetAbilityInfo().name;
165 std::string srcBundleName = ability->GetApplicationInfo().bundleName;
166 std::string tarAbilityName = want.GetElement().GetAbilityName();
167 std::string tarBundleName = want.GetElement().GetBundleName();
168 if ((srcBundleName == tarBundleName) &&
169 (srcAbilityName == tarAbilityName) &&
170 (ability->GetSpecifiedFlag() == flag)) {
171 return mission;
172 }
173 }
174
175 return nullptr;
176 }
177
IsEmpty()178 bool MissionList::IsEmpty()
179 {
180 return missions_.empty();
181 }
182
GetTopAbility() const183 std::shared_ptr<AbilityRecord> MissionList::GetTopAbility() const
184 {
185 if (missions_.empty()) {
186 return nullptr;
187 }
188
189 auto& topMission = missions_.front();
190 if (topMission) {
191 return topMission->GetAbilityRecord();
192 }
193 return nullptr;
194 }
195
GetAllMissions()196 std::list<std::shared_ptr<Mission>>& MissionList::GetAllMissions()
197 {
198 return missions_;
199 }
200
GetType() const201 MissionListType MissionList::GetType() const
202 {
203 return type_;
204 }
205
GetLauncherRoot() const206 std::shared_ptr<AbilityRecord> MissionList::GetLauncherRoot() const
207 {
208 for (auto mission : missions_) {
209 if (!mission) {
210 continue;
211 }
212
213 std::shared_ptr<AbilityRecord> ability = mission->GetAbilityRecord();
214 if (ability && ability->IsLauncherRoot()) {
215 return ability;
216 }
217 }
218 return nullptr;
219 }
220
GetAbilityRecordById(int64_t abilityRecordId) const221 std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordById(int64_t abilityRecordId) const
222 {
223 for (std::shared_ptr<Mission> mission : missions_) {
224 if (mission && mission->GetAbilityRecord()->GetAbilityRecordId() == abilityRecordId) {
225 return mission->GetAbilityRecord();
226 }
227 }
228 return nullptr;
229 }
230
GetAbilityRecordByCaller(const std::shared_ptr<AbilityRecord> & caller,int requestCode)231 std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordByCaller(
232 const std::shared_ptr<AbilityRecord> &caller, int requestCode)
233 {
234 for (auto mission : missions_) {
235 auto callerList = mission->GetAbilityRecord()->GetCallerRecordList();
236 if (callerList.empty()) {
237 continue;
238 }
239
240 for (auto callerAbility : callerList) {
241 if (callerAbility->GetCaller() == caller && callerAbility->GetRequestCode() == requestCode) {
242 return mission->GetAbilityRecord();
243 }
244 }
245 }
246 return nullptr;
247 }
248
GetAbilityRecordByName(const AppExecFwk::ElementName & element)249 std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordByName(const AppExecFwk::ElementName &element)
250 {
251 for (auto mission : missions_) {
252 if (mission) {
253 const AppExecFwk::AbilityInfo &abilityInfo = mission->GetAbilityRecord()->GetAbilityInfo();
254 AppExecFwk::ElementName localElement(abilityInfo.deviceId, abilityInfo.bundleName,
255 abilityInfo.name, abilityInfo.moduleName);
256 AppExecFwk::ElementName localElementNoModuleName(abilityInfo.deviceId,
257 abilityInfo.bundleName, abilityInfo.name); // note: moduleName of input param element maybe empty
258 if (localElement == element || localElementNoModuleName == element) {
259 return mission->GetAbilityRecord();
260 }
261 }
262 }
263 return nullptr;
264 }
265
GetAbilityRecordsByName(const AppExecFwk::ElementName & element,std::vector<std::shared_ptr<AbilityRecord>> & records)266 void MissionList::GetAbilityRecordsByName(
267 const AppExecFwk::ElementName &element, std::vector<std::shared_ptr<AbilityRecord>> &records)
268 {
269 for (auto mission : missions_) {
270 if (mission && mission->GetAbilityRecord() != nullptr) {
271 const AppExecFwk::AbilityInfo &abilityInfo = mission->GetAbilityRecord()->GetAbilityInfo();
272 AppExecFwk::ElementName localElement(abilityInfo.deviceId, abilityInfo.bundleName,
273 abilityInfo.name, abilityInfo.moduleName);
274 AppExecFwk::ElementName localElementNoModuleName(abilityInfo.deviceId,
275 abilityInfo.bundleName, abilityInfo.name);
276 if (localElement == element || localElementNoModuleName == element) {
277 HILOG_DEBUG("find element %{public}s", localElement.GetURI().c_str());
278 records.push_back(mission->GetAbilityRecord());
279 }
280 }
281 }
282 }
283
GetAbilityTokenByMissionId(int32_t missionId)284 sptr<IRemoteObject> MissionList::GetAbilityTokenByMissionId(int32_t missionId)
285 {
286 for (auto mission : missions_) {
287 if (mission && mission->GetMissionId() == missionId) {
288 auto abilityRecord = mission->GetAbilityRecord();
289 if (abilityRecord) {
290 return abilityRecord->GetToken();
291 }
292 }
293 }
294
295 return nullptr;
296 }
297
GetTypeName()298 std::string MissionList::GetTypeName()
299 {
300 switch (type_) {
301 case MissionListType::CURRENT: {
302 return "NORMAL";
303 }
304 case MissionListType::DEFAULT_STANDARD: {
305 return "DEFAULT_STANDARD";
306 }
307 case MissionListType::DEFAULT_SINGLE: {
308 return "DEFAULT_SINGLE";
309 }
310 case MissionListType::LAUNCHER: {
311 return "LAUNCHER";
312 }
313 default: {
314 return "INVALID";
315 }
316 }
317 }
318
HandleUnInstallApp(const std::string & bundleName,int32_t uid)319 void MissionList::HandleUnInstallApp(const std::string &bundleName, int32_t uid)
320 {
321 for (auto it = missions_.begin(); it != missions_.end();) {
322 auto mission = *it;
323 if (MatchedInitialMission(mission, bundleName, uid)) {
324 missions_.erase(it++);
325 } else {
326 it++;
327 }
328 }
329 }
330
MatchedInitialMission(const std::shared_ptr<Mission> & mission,const std::string & bundleName,int32_t uid)331 bool MissionList::MatchedInitialMission(const std::shared_ptr<Mission>& mission,
332 const std::string &bundleName, int32_t uid)
333 {
334 if (!mission) {
335 return false;
336 }
337
338 auto abilityRecord = mission->GetAbilityRecord();
339 if (!abilityRecord) {
340 return false;
341 }
342
343 if (abilityRecord->GetAbilityInfo().bundleName == bundleName && abilityRecord->GetUid() == uid) {
344 abilityRecord->SetIsUninstallAbility();
345 if (abilityRecord->IsAbilityState(AbilityState::INITIAL)) {
346 return true;
347 }
348 }
349
350 return false;
351 }
352
353
Dump(std::vector<std::string> & info)354 void MissionList::Dump(std::vector<std::string>& info)
355 {
356 std::string dumpInfo = " MissionList Type #" + GetTypeName();
357 info.push_back(dumpInfo);
358 for (const auto& mission : missions_) {
359 if (mission) {
360 mission->Dump(info);
361 }
362 }
363 }
364
DumpStateByRecordId(std::vector<std::string> & info,bool isClient,int32_t abilityRecordId,const std::vector<std::string> & params)365 void MissionList::DumpStateByRecordId(
366 std::vector<std::string> &info, bool isClient, int32_t abilityRecordId, const std::vector<std::string> ¶ms)
367 {
368 for (const auto& mission : missions_) {
369 if (mission) {
370 auto abilityRecord = mission->GetAbilityRecord();
371 if (abilityRecord) {
372 if (abilityRecord->GetRecordId() == abilityRecordId) {
373 HILOG_INFO("record begin to call DumpAbilityState %{public}s", __func__);
374 abilityRecord->DumpAbilityState(info, isClient, params);
375 return;
376 }
377 }
378 }
379 }
380 }
DumpList(std::vector<std::string> & info,bool isClient)381 void MissionList::DumpList(std::vector<std::string> &info, bool isClient)
382 {
383 std::string dumpInfo = " MissionList Type #" + GetTypeName();
384 info.push_back(dumpInfo);
385
386 for (const auto& mission : missions_) {
387 if (mission) {
388 dumpInfo = " Mission ID #" + std::to_string(mission->GetMissionId());
389 dumpInfo += " mission name #[" + mission->GetMissionName() + "]" +
390 " lockedState #" + std::to_string(mission->IsLockedState());
391 info.push_back(dumpInfo);
392
393 auto abilityRecord = mission->GetAbilityRecord();
394 if (abilityRecord) {
395 HILOG_INFO("record begin to call DumpAbilityState %{public}s", __func__);
396 std::vector<std::string> params;
397 abilityRecord->DumpAbilityState(info, isClient, params);
398 }
399 }
400 }
401 }
402
403 #ifdef ABILITY_COMMAND_FOR_TEST
BlockAbilityByRecordId(int32_t abilityRecordId)404 int MissionList::BlockAbilityByRecordId(int32_t abilityRecordId)
405 {
406 int ret = -1;
407 for (const auto& mission : missions_) {
408 if (mission) {
409 auto abilityRecord = mission->GetAbilityRecord();
410 if (abilityRecord) {
411 if (abilityRecord->GetRecordId() == abilityRecordId) {
412 HILOG_INFO("record begin to call BlockAbilityByRecordId %{public}s", __func__);
413 return abilityRecord->BlockAbility();
414 }
415 }
416 }
417 }
418 return ret;
419 }
420 #endif
421
GetMissionCountByUid(int32_t targetUid) const422 int32_t MissionList::GetMissionCountByUid(int32_t targetUid) const
423 {
424 int32_t count = 0;
425 for (const auto& mission : missions_) {
426 if (!mission) {
427 continue;
428 }
429
430 auto abilityRecord = mission->GetAbilityRecord();
431 if (!abilityRecord) {
432 continue;
433 }
434
435 if (abilityRecord->GetUid() == targetUid) {
436 count++;
437 }
438 }
439 return count;
440 }
441
FindEarliestMission(std::shared_ptr<Mission> & targetMission) const442 void MissionList::FindEarliestMission(std::shared_ptr<Mission>& targetMission) const
443 {
444 for (const auto& mission : missions_) {
445 if (!mission) {
446 continue;
447 }
448 auto abilityRecord = mission->GetAbilityRecord();
449 if (!abilityRecord) {
450 continue;
451 }
452 if (!abilityRecord->IsAbilityState(AbilityState::BACKGROUND) ||
453 (targetMission && targetMission->GetMissionTime() < mission->GetMissionTime())) {
454 continue;
455 }
456 targetMission = mission;
457 }
458 }
459
GetMissionCount() const460 int32_t MissionList::GetMissionCount() const
461 {
462 return static_cast<int32_t>(missions_.size());
463 }
464
GetActiveAbilityList(const std::string & bundleName,std::vector<std::string> & abilityList)465 void MissionList::GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList)
466 {
467 for (auto mission : missions_) {
468 if (!mission) {
469 continue;
470 }
471
472 auto abilityRecord = mission->GetAbilityRecord();
473 if (!abilityRecord) {
474 continue;
475 }
476
477 const AppExecFwk::AbilityInfo &abilityInfo = abilityRecord->GetAbilityInfo();
478 if (abilityInfo.bundleName == bundleName && !abilityInfo.name.empty()) {
479 HILOG_DEBUG("find ability name is %{public}s", abilityInfo.name.c_str());
480 abilityList.push_back(abilityInfo.name);
481 }
482 }
483 }
484 } // namespace AAFwk
485 } // namespace OHOS
486