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