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