• 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 
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> &params)
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