1 /*
2 * Copyright (c) 2021-2022 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 eventId) const221 std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordById(int64_t eventId) const
222 {
223 for (std::shared_ptr<Mission> mission : missions_) {
224 if (mission && mission->GetAbilityRecord()->GetEventId() == eventId) {
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
GetAbilityTokenByMissionId(int32_t missionId)266 sptr<IRemoteObject> MissionList::GetAbilityTokenByMissionId(int32_t missionId)
267 {
268 for (auto mission : missions_) {
269 if (mission && mission->GetMissionId() == missionId) {
270 auto abilityRecord = mission->GetAbilityRecord();
271 if (abilityRecord) {
272 return abilityRecord->GetToken();
273 }
274 }
275 }
276
277 return nullptr;
278 }
279
GetTypeName()280 std::string MissionList::GetTypeName()
281 {
282 switch (type_) {
283 case MissionListType::CURRENT: {
284 return "NORMAL";
285 }
286 case MissionListType::DEFAULT_STANDARD: {
287 return "DEFAULT_STANDARD";
288 }
289 case MissionListType::DEFAULT_SINGLE: {
290 return "DEFAULT_SINGLE";
291 }
292 case MissionListType::LAUNCHER: {
293 return "LAUNCHER";
294 }
295 default: {
296 return "INVALID";
297 }
298 }
299 }
300
HandleUnInstallApp(const std::string & bundleName,int32_t uid)301 void MissionList::HandleUnInstallApp(const std::string &bundleName, int32_t uid)
302 {
303 for (auto it = missions_.begin(); it != missions_.end();) {
304 auto mission = *it;
305 if (MatchedInitialMission(mission, bundleName, uid)) {
306 missions_.erase(it++);
307 } else {
308 it++;
309 }
310 }
311 }
312
MatchedInitialMission(const std::shared_ptr<Mission> & mission,const std::string & bundleName,int32_t uid)313 bool MissionList::MatchedInitialMission(const std::shared_ptr<Mission>& mission,
314 const std::string &bundleName, int32_t uid)
315 {
316 if (!mission) {
317 return false;
318 }
319
320 auto abilityRecord = mission->GetAbilityRecord();
321 if (!abilityRecord) {
322 return false;
323 }
324
325 if (abilityRecord->GetAbilityInfo().bundleName == bundleName && abilityRecord->GetUid() == uid) {
326 abilityRecord->SetIsUninstallAbility();
327 if (abilityRecord->IsAbilityState(AbilityState::INITIAL)) {
328 return true;
329 }
330 }
331
332 return false;
333 }
334
335
Dump(std::vector<std::string> & info)336 void MissionList::Dump(std::vector<std::string>& info)
337 {
338 std::string dumpInfo = " MissionList Type #" + GetTypeName();
339 info.push_back(dumpInfo);
340 for (const auto& mission : missions_) {
341 if (mission) {
342 mission->Dump(info);
343 }
344 }
345 }
346
DumpStateByRecordId(std::vector<std::string> & info,bool isClient,int32_t abilityRecordId,const std::vector<std::string> & params)347 void MissionList::DumpStateByRecordId(
348 std::vector<std::string> &info, bool isClient, int32_t abilityRecordId, const std::vector<std::string> ¶ms)
349 {
350 for (const auto& mission : missions_) {
351 if (mission) {
352 auto abilityRecord = mission->GetAbilityRecord();
353 if (abilityRecord) {
354 if (abilityRecord->GetRecordId() == abilityRecordId) {
355 HILOG_INFO("record begin to call DumpAbilityState %{public}s", __func__);
356 abilityRecord->DumpAbilityState(info, isClient, params);
357 return;
358 }
359 }
360 }
361 }
362 }
DumpList(std::vector<std::string> & info,bool isClient)363 void MissionList::DumpList(std::vector<std::string> &info, bool isClient)
364 {
365 std::string dumpInfo = " MissionList Type #" + GetTypeName();
366 info.push_back(dumpInfo);
367
368 for (const auto& mission : missions_) {
369 if (mission) {
370 dumpInfo = " Mission ID #" + std::to_string(mission->GetMissionId());
371 dumpInfo += " mission name #[" + mission->GetMissionName() + "]" +
372 " lockedState #" + std::to_string(mission->IsLockedState());
373 info.push_back(dumpInfo);
374
375 auto abilityRecord = mission->GetAbilityRecord();
376 if (abilityRecord) {
377 HILOG_INFO("record begin to call DumpAbilityState %{public}s", __func__);
378 std::vector<std::string> params;
379 abilityRecord->DumpAbilityState(info, isClient, params);
380 }
381 }
382 }
383 }
384
385 #ifdef ABILITY_COMMAND_FOR_TEST
BlockAbilityByRecordId(int32_t abilityRecordId)386 int MissionList::BlockAbilityByRecordId(int32_t abilityRecordId)
387 {
388 int ret = -1;
389 for (const auto& mission : missions_) {
390 if (mission) {
391 auto abilityRecord = mission->GetAbilityRecord();
392 if (abilityRecord) {
393 if (abilityRecord->GetRecordId() == abilityRecordId) {
394 HILOG_INFO("record begin to call BlockAbilityByRecordId %{public}s", __func__);
395 return abilityRecord->BlockAbility();
396 }
397 }
398 }
399 }
400 return ret;
401 }
402 #endif
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 } // namespace AAFwk
424 } // namespace OHOS
425