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> ¶ms)
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