• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetRecentStandardMissionWithAffinity(const std::string & missionAffinity) const116 std::shared_ptr<Mission> MissionList::GetRecentStandardMissionWithAffinity(const std::string &missionAffinity) const
117 {
118     if (missionAffinity.empty()) {
119         return nullptr;
120     }
121 
122     std::string missionTime = "0";
123     std::shared_ptr<Mission> result = nullptr;
124     for (auto& mission : missions_) {
125         if (mission && mission->IsStandardAbility() && mission->GetMissionAffinity() == missionAffinity &&
126             mission->GetMissionTime() >= missionTime) {
127             result = mission;
128             missionTime = mission->GetMissionTime();
129         }
130     }
131 
132     return result;
133 }
134 
GetAbilityRecordByToken(const sptr<IRemoteObject> & token) const135 std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordByToken(const sptr<IRemoteObject> &token) const
136 {
137     for (auto mission : missions_) {
138         if (!mission) {
139             continue;
140         }
141         std::shared_ptr<AbilityRecord> abilityRecord = mission->GetAbilityRecord();
142         if (abilityRecord && token == abilityRecord->GetToken()->AsObject()) {
143             return abilityRecord;
144         }
145     }
146 
147     return nullptr;
148 }
149 
RemoveMissionByAbilityRecord(const std::shared_ptr<AbilityRecord> & abilityRecord)150 void MissionList::RemoveMissionByAbilityRecord(const std::shared_ptr<AbilityRecord> &abilityRecord)
151 {
152     for (auto iter = missions_.begin(); iter != missions_.end(); iter++) {
153         if ((*iter)->GetAbilityRecord() == abilityRecord) {
154             missions_.erase(iter);
155             return;
156         }
157     }
158 }
159 
GetMissionById(int missionId) const160 std::shared_ptr<Mission> MissionList::GetMissionById(int missionId) const
161 {
162     for (auto mission : missions_) {
163         if (mission && mission->GetMissionId() == missionId) {
164             return mission;
165         }
166     }
167 
168     return nullptr;
169 }
170 
GetMissionBySpecifiedFlag(const AAFwk::Want & want,const std::string & flag) const171 std::shared_ptr<Mission> MissionList::GetMissionBySpecifiedFlag(const AAFwk::Want &want, const std::string &flag) const
172 {
173     for (auto mission : missions_) {
174         if (!mission) {
175             return nullptr;
176         }
177 
178         auto ability = mission->GetAbilityRecord();
179         if (!ability) {
180             return nullptr;
181         }
182 
183         std::string srcAbilityName = ability->GetAbilityInfo().name;
184         std::string srcBundleName = ability->GetApplicationInfo().bundleName;
185         std::string tarAbilityName = want.GetElement().GetAbilityName();
186         std::string tarBundleName = want.GetElement().GetBundleName();
187         if ((srcBundleName == tarBundleName) &&
188             (srcAbilityName == tarAbilityName) &&
189             (ability->GetSpecifiedFlag() == flag)) {
190             return mission;
191         }
192     }
193 
194     return nullptr;
195 }
196 
IsEmpty()197 bool MissionList::IsEmpty()
198 {
199     return missions_.empty();
200 }
201 
GetTopAbility() const202 std::shared_ptr<AbilityRecord> MissionList::GetTopAbility() const
203 {
204     if (missions_.empty()) {
205         return nullptr;
206     }
207 
208     auto& topMission = missions_.front();
209     if (topMission) {
210         return topMission->GetAbilityRecord();
211     }
212     return nullptr;
213 }
214 
GetAllMissions()215 std::list<std::shared_ptr<Mission>>& MissionList::GetAllMissions()
216 {
217     return missions_;
218 }
219 
GetType() const220 MissionListType MissionList::GetType() const
221 {
222     return type_;
223 }
224 
GetLauncherRoot() const225 std::shared_ptr<AbilityRecord> MissionList::GetLauncherRoot() const
226 {
227     for (auto mission : missions_) {
228         if (!mission) {
229             continue;
230         }
231 
232         std::shared_ptr<AbilityRecord> ability = mission->GetAbilityRecord();
233         if (ability && ability->IsLauncherRoot()) {
234             return ability;
235         }
236     }
237     return nullptr;
238 }
239 
GetAbilityRecordById(int64_t abilityRecordId) const240 std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordById(int64_t abilityRecordId) const
241 {
242     for (std::shared_ptr<Mission> mission : missions_) {
243         if (mission && mission->GetAbilityRecord()->GetAbilityRecordId() == abilityRecordId) {
244             return mission->GetAbilityRecord();
245         }
246     }
247     return nullptr;
248 }
249 
GetAbilityRecordByCaller(const std::shared_ptr<AbilityRecord> & caller,int requestCode)250 std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordByCaller(
251     const std::shared_ptr<AbilityRecord> &caller, int requestCode)
252 {
253     for (auto mission : missions_) {
254         auto callerList = mission->GetAbilityRecord()->GetCallerRecordList();
255         if (callerList.empty()) {
256             continue;
257         }
258 
259         for (auto callerAbility : callerList) {
260             if (callerAbility->GetCaller() == caller && callerAbility->GetRequestCode() == requestCode) {
261                 return mission->GetAbilityRecord();
262             }
263         }
264     }
265     return nullptr;
266 }
267 
GetAbilityRecordByName(const AppExecFwk::ElementName & element)268 std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordByName(const AppExecFwk::ElementName &element)
269 {
270     for (auto mission : missions_) {
271         if (mission) {
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); // note: moduleName of input param element maybe empty
277             if (localElement == element || localElementNoModuleName == element) {
278                 return mission->GetAbilityRecord();
279             }
280         }
281     }
282     return nullptr;
283 }
284 
GetAbilityRecordsByName(const AppExecFwk::ElementName & element,std::vector<std::shared_ptr<AbilityRecord>> & records)285 void MissionList::GetAbilityRecordsByName(
286     const AppExecFwk::ElementName &element, std::vector<std::shared_ptr<AbilityRecord>> &records)
287 {
288     for (auto mission : missions_) {
289         if (mission && mission->GetAbilityRecord() != nullptr) {
290             const AppExecFwk::AbilityInfo &abilityInfo = mission->GetAbilityRecord()->GetAbilityInfo();
291             AppExecFwk::ElementName localElement(abilityInfo.deviceId, abilityInfo.bundleName,
292                 abilityInfo.name, abilityInfo.moduleName);
293             AppExecFwk::ElementName localElementNoModuleName(abilityInfo.deviceId,
294                 abilityInfo.bundleName, abilityInfo.name);
295             if (localElement == element || localElementNoModuleName == element) {
296                 HILOG_DEBUG("find element %{public}s", localElement.GetURI().c_str());
297                 records.push_back(mission->GetAbilityRecord());
298             }
299         }
300     }
301 }
302 
GetAbilityTokenByMissionId(int32_t missionId)303 sptr<IRemoteObject> MissionList::GetAbilityTokenByMissionId(int32_t missionId)
304 {
305     for (auto mission : missions_) {
306         if (mission && mission->GetMissionId() == missionId) {
307             auto abilityRecord = mission->GetAbilityRecord();
308             if (abilityRecord) {
309                 return abilityRecord->GetToken();
310             }
311         }
312     }
313 
314     return nullptr;
315 }
316 
GetTypeName()317 std::string MissionList::GetTypeName()
318 {
319     switch (type_) {
320         case MissionListType::CURRENT: {
321             return "NORMAL";
322         }
323         case MissionListType::DEFAULT_STANDARD: {
324             return "DEFAULT_STANDARD";
325         }
326         case MissionListType::DEFAULT_SINGLE: {
327             return "DEFAULT_SINGLE";
328         }
329         case MissionListType::LAUNCHER: {
330             return "LAUNCHER";
331         }
332         default: {
333             return "INVALID";
334         }
335     }
336 }
337 
HandleUnInstallApp(const std::string & bundleName,int32_t uid)338 void MissionList::HandleUnInstallApp(const std::string &bundleName, int32_t uid)
339 {
340     for (auto it = missions_.begin(); it != missions_.end();) {
341         auto mission = *it;
342         if (MatchedInitialMission(mission, bundleName, uid)) {
343             missions_.erase(it++);
344         } else {
345             it++;
346         }
347     }
348 }
349 
MatchedInitialMission(const std::shared_ptr<Mission> & mission,const std::string & bundleName,int32_t uid)350 bool MissionList::MatchedInitialMission(const std::shared_ptr<Mission>& mission,
351     const std::string &bundleName, int32_t uid)
352 {
353     if (!mission) {
354         return false;
355     }
356 
357     auto abilityRecord = mission->GetAbilityRecord();
358     if (!abilityRecord) {
359         return false;
360     }
361 
362     if (abilityRecord->GetAbilityInfo().bundleName == bundleName && abilityRecord->GetUid() == uid) {
363         abilityRecord->SetIsUninstallAbility();
364         if (abilityRecord->IsAbilityState(AbilityState::INITIAL)) {
365             return true;
366         }
367     }
368 
369     return false;
370 }
371 
372 
Dump(std::vector<std::string> & info)373 void MissionList::Dump(std::vector<std::string>& info)
374 {
375     std::string dumpInfo = "  MissionList Type #" + GetTypeName();
376     info.push_back(dumpInfo);
377     for (const auto& mission : missions_) {
378         if (mission) {
379             mission->Dump(info);
380         }
381     }
382 }
383 
DumpStateByRecordId(std::vector<std::string> & info,bool isClient,int32_t abilityRecordId,const std::vector<std::string> & params)384 void MissionList::DumpStateByRecordId(
385     std::vector<std::string> &info, bool isClient, int32_t abilityRecordId, const std::vector<std::string> &params)
386 {
387     for (const auto& mission : missions_) {
388         if (mission) {
389             auto abilityRecord = mission->GetAbilityRecord();
390             if (abilityRecord) {
391                 if (abilityRecord->GetRecordId() == abilityRecordId) {
392                     HILOG_INFO("record begin to call DumpAbilityState %{public}s", __func__);
393                     abilityRecord->DumpAbilityState(info, isClient, params);
394                     return;
395                 }
396             }
397         }
398     }
399 }
DumpList(std::vector<std::string> & info,bool isClient)400 void MissionList::DumpList(std::vector<std::string> &info, bool isClient)
401 {
402     std::string dumpInfo = "    MissionList Type #" + GetTypeName();
403     info.push_back(dumpInfo);
404 
405     for (const auto& mission : missions_) {
406         if (mission) {
407             dumpInfo = "      Mission ID #" + std::to_string(mission->GetMissionId());
408             dumpInfo += "  mission name #[" + mission->GetMissionName() + "]" +
409                 "  lockedState #" + std::to_string(mission->IsLockedState());
410             info.push_back(dumpInfo);
411 
412             auto abilityRecord = mission->GetAbilityRecord();
413             if (abilityRecord) {
414                 HILOG_INFO("record begin to call DumpAbilityState %{public}s", __func__);
415                 std::vector<std::string> params;
416                 abilityRecord->DumpAbilityState(info, isClient, params);
417             }
418         }
419     }
420 }
421 
422 #ifdef ABILITY_COMMAND_FOR_TEST
BlockAbilityByRecordId(int32_t abilityRecordId)423 int MissionList::BlockAbilityByRecordId(int32_t abilityRecordId)
424 {
425     int ret = -1;
426     for (const auto& mission : missions_) {
427         if (mission) {
428             auto abilityRecord = mission->GetAbilityRecord();
429             if (abilityRecord) {
430                 if (abilityRecord->GetRecordId() == abilityRecordId) {
431                     HILOG_INFO("record begin to call BlockAbilityByRecordId %{public}s", __func__);
432                     return abilityRecord->BlockAbility();
433                 }
434             }
435         }
436     }
437     return ret;
438 }
439 #endif
440 
GetMissionCountByUid(int32_t targetUid) const441 int32_t MissionList::GetMissionCountByUid(int32_t targetUid) const
442 {
443     int32_t count = 0;
444     for (const auto& mission : missions_) {
445         if (!mission) {
446             continue;
447         }
448 
449         auto abilityRecord = mission->GetAbilityRecord();
450         if (!abilityRecord) {
451             continue;
452         }
453 
454         if (abilityRecord->GetUid() == targetUid) {
455             count++;
456         }
457     }
458     return count;
459 }
460 
FindEarliestMission(std::shared_ptr<Mission> & targetMission) const461 void MissionList::FindEarliestMission(std::shared_ptr<Mission>& targetMission) const
462 {
463     for (const auto& mission : missions_) {
464         if (!mission) {
465             continue;
466         }
467         auto abilityRecord = mission->GetAbilityRecord();
468         if (!abilityRecord) {
469             continue;
470         }
471         if (!abilityRecord->IsAbilityState(AbilityState::BACKGROUND) ||
472             (targetMission && targetMission->GetMissionTime() < mission->GetMissionTime())) {
473             continue;
474         }
475         targetMission = mission;
476     }
477 }
478 
GetMissionCount() const479 int32_t MissionList::GetMissionCount() const
480 {
481     return static_cast<int32_t>(missions_.size());
482 }
483 
GetActiveAbilityList(const std::string & bundleName,std::vector<std::string> & abilityList)484 void MissionList::GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList)
485 {
486     for (auto mission : missions_) {
487         if (!mission) {
488             continue;
489         }
490 
491         auto abilityRecord = mission->GetAbilityRecord();
492         if (!abilityRecord) {
493             continue;
494         }
495 
496         const AppExecFwk::AbilityInfo &abilityInfo = abilityRecord->GetAbilityInfo();
497         if (abilityInfo.bundleName == bundleName && !abilityInfo.name.empty()) {
498             HILOG_DEBUG("find ability name is %{public}s", abilityInfo.name.c_str());
499             abilityList.push_back(abilityInfo.name);
500         }
501     }
502 }
503 }  // namespace AAFwk
504 }  // namespace OHOS
505