• 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_info.h"
17 #include "mission_info_mgr.h"
18 
19 #include "ability_manager_service.h"
20 #include "hilog_wrapper.h"
21 #include "hitrace_meter.h"
22 #include "nlohmann/json.hpp"
23 #ifdef SUPPORT_GRAPHICS
24 #include "pixel_map.h"
25 #include "securec.h"
26 #endif
27 
28 namespace OHOS {
29 namespace AAFwk {
MissionInfoMgr()30 MissionInfoMgr::MissionInfoMgr()
31 {
32     HILOG_INFO("MissionInfoMgr instance is created");
33 }
34 
~MissionInfoMgr()35 MissionInfoMgr::~MissionInfoMgr()
36 {
37     HILOG_INFO("MissionInfoMgr instance is destroyed");
38 }
39 
GenerateMissionId(int32_t & missionId)40 bool MissionInfoMgr::GenerateMissionId(int32_t &missionId)
41 {
42     std::lock_guard<ffrt::mutex> lock(mutex_);
43     if (currentMissionId_ == MAX_MISSION_ID) {
44         currentMissionId_ = MIN_MISSION_ID;
45     }
46 
47     for (int32_t index = currentMissionId_; index < MAX_MISSION_ID; index++) {
48         if (missionIdMap_.find(index) == missionIdMap_.end()) {
49             missionId = index;
50             missionIdMap_[missionId] = false;
51             currentMissionId_ = missionId + 1;
52             return true;
53         }
54     }
55 
56     HILOG_ERROR("cannot generate mission id");
57     return false;
58 }
59 
Init(int userId)60 bool MissionInfoMgr::Init(int userId)
61 {
62     std::lock_guard<ffrt::mutex> lock(mutex_);
63     if (!taskDataPersistenceMgr_) {
64         taskDataPersistenceMgr_ = DelayedSingleton<TaskDataPersistenceMgr>::GetInstance();
65         if (!taskDataPersistenceMgr_) {
66             HILOG_ERROR("taskDataPersistenceMgr_ is nullptr");
67             return false;
68         }
69     }
70 
71     if (!taskDataPersistenceMgr_->Init(userId)) {
72         return false;
73     }
74 
75     missionInfoList_.clear();
76     missionIdMap_.clear();
77     if (!LoadAllMissionInfo()) {
78         return false;
79     }
80 
81     return true;
82 }
83 
AddMissionInfo(const InnerMissionInfo & missionInfo)84 bool MissionInfoMgr::AddMissionInfo(const InnerMissionInfo &missionInfo)
85 {
86     std::lock_guard<ffrt::mutex> lock(mutex_);
87     return AddMissionInfoInner(missionInfo);
88 }
89 
AddMissionInfoInner(const InnerMissionInfo & missionInfo)90 bool MissionInfoMgr::AddMissionInfoInner(const InnerMissionInfo &missionInfo)
91 {
92     auto id = missionInfo.missionInfo.id;
93     if (missionIdMap_.find(id) != missionIdMap_.end() && missionIdMap_[id]) {
94         HILOG_ERROR("add mission info failed, missionId %{public}d already exists", id);
95         return false;
96     }
97 
98     auto listIter = missionInfoList_.begin();
99     for (; listIter != missionInfoList_.end(); listIter++) {
100         if (listIter->missionInfo.time < missionInfo.missionInfo.time) {
101             break;  // first listIter->time < missionInfo.time
102         }
103     }
104 
105     if (!taskDataPersistenceMgr_->SaveMissionInfo(missionInfo)) {
106         HILOG_ERROR("save mission info failed");
107         return false;
108     }
109 
110     missionInfoList_.insert(listIter, missionInfo);
111     missionIdMap_[id] = true;
112     return true;
113 }
114 
UpdateMissionInfo(const InnerMissionInfo & missionInfo)115 bool MissionInfoMgr::UpdateMissionInfo(const InnerMissionInfo &missionInfo)
116 {
117     std::lock_guard<ffrt::mutex> lock(mutex_);
118     auto id = missionInfo.missionInfo.id;
119     if (missionIdMap_.find(id) == missionIdMap_.end() || !missionIdMap_[id]) {
120         HILOG_ERROR("update mission info failed, missionId %{public}d not exists", id);
121         return false;
122     }
123 
124     auto listIter = missionInfoList_.begin();
125     for (; listIter != missionInfoList_.end(); listIter++) {
126         if (listIter->missionInfo.id == id) {
127             break;
128         }
129     }
130 
131     if (listIter == missionInfoList_.end()) {
132         HILOG_ERROR("update mission info failed, missionId %{public}d not exists", id);
133         return false;
134     }
135 
136     if (missionInfo.missionInfo.time == listIter->missionInfo.time) {
137         // time not changes, no need sort again
138         *listIter = missionInfo;
139         if (!taskDataPersistenceMgr_->SaveMissionInfo(missionInfo)) {
140             HILOG_ERROR("save mission info failed.");
141             return false;
142         }
143         return true;
144     }
145 
146     missionInfoList_.erase(listIter);
147     missionIdMap_.erase(id);
148     return AddMissionInfoInner(missionInfo);
149 }
150 
DeleteMissionInfo(int missionId)151 bool MissionInfoMgr::DeleteMissionInfo(int missionId)
152 {
153     std::lock_guard<ffrt::mutex> lock(mutex_);
154     if (missionIdMap_.find(missionId) == missionIdMap_.end()) {
155         HILOG_WARN("missionId %{public}d not exists, no need delete", missionId);
156         return true;
157     }
158 
159     if (!missionIdMap_[missionId]) {
160         HILOG_WARN("missionId %{public}d distributed but not saved, no need delete", missionId);
161         missionIdMap_.erase(missionId);
162         return true;
163     }
164 
165     if (!taskDataPersistenceMgr_) {
166         HILOG_ERROR("taskDataPersistenceMgr_ is nullptr");
167         return false;
168     }
169 
170     if (!taskDataPersistenceMgr_->DeleteMissionInfo(missionId)) {
171         HILOG_ERROR("delete mission info failed");
172         return false;
173     }
174 
175     for (auto listIter = missionInfoList_.begin(); listIter != missionInfoList_.end(); listIter++) {
176         if (listIter->missionInfo.id == missionId) {
177             missionInfoList_.erase(listIter);
178             break;
179         }
180     }
181 
182     missionIdMap_.erase(missionId);
183     return true;
184 }
185 
DeleteAllMissionInfos(const std::shared_ptr<MissionListenerController> & listenerController)186 bool MissionInfoMgr::DeleteAllMissionInfos(const std::shared_ptr<MissionListenerController> &listenerController)
187 {
188     std::lock_guard<ffrt::mutex> lock(mutex_);
189     if (!taskDataPersistenceMgr_) {
190         HILOG_ERROR("taskDataPersistenceMgr_ is nullptr");
191         return false;
192     }
193 
194     auto abilityMs_ = OHOS::DelayedSingleton<AbilityManagerService>::GetInstance();
195 
196     for (auto listIter = missionInfoList_.begin(); listIter != missionInfoList_.end();) {
197         auto isUnclearable = ((listIter->missionInfo.unclearable) && (listIter->missionInfo.runningState == 0));
198         if (!((listIter->missionInfo.lockedState) ||
199             (abilityMs_->IsBackgroundTaskUid(listIter->uid)) || isUnclearable)) {
200             missionIdMap_.erase(listIter->missionInfo.id);
201             taskDataPersistenceMgr_->DeleteMissionInfo(listIter->missionInfo.id);
202             if (listenerController) {
203                 listenerController->NotifyMissionDestroyed(listIter->missionInfo.id);
204             }
205             missionInfoList_.erase(listIter++);
206         } else {
207             ++listIter;
208         }
209     }
210     return true;
211 }
212 
DoesNotShowInTheMissionList(const InnerMissionInfo & mission)213 static bool DoesNotShowInTheMissionList(const InnerMissionInfo &mission)
214 {
215     bool isStartByCall = false;
216     switch (static_cast<StartMethod>(mission.startMethod)) {
217         case StartMethod::START_CALL:
218             isStartByCall = true;
219             break;
220         default:
221             isStartByCall = false;
222     }
223     return (isStartByCall && !mission.missionInfo.want.GetBoolParam(Want::PARAM_RESV_CALL_TO_FOREGROUND, false));
224 }
225 
GetMissionInfos(int32_t numMax,std::vector<MissionInfo> & missionInfos)226 int MissionInfoMgr::GetMissionInfos(int32_t numMax, std::vector<MissionInfo> &missionInfos)
227 {
228     HILOG_INFO("numMax:%{public}d", numMax);
229     if (numMax < 0) {
230         return -1;
231     }
232 
233     std::lock_guard<ffrt::mutex> lock(mutex_);
234     for (auto &mission : missionInfoList_) {
235         if (static_cast<int>(missionInfos.size()) >= numMax) {
236             break;
237         }
238 
239         if (DoesNotShowInTheMissionList(mission)) {
240             HILOG_INFO("MissionId[%{public}d] don't show in mission list", mission.missionInfo.id);
241             continue;
242         }
243         MissionInfo info = mission.missionInfo;
244         missionInfos.emplace_back(info);
245     }
246 
247     return 0;
248 }
249 
GetMissionInfoById(int32_t missionId,MissionInfo & missionInfo)250 int MissionInfoMgr::GetMissionInfoById(int32_t missionId, MissionInfo &missionInfo)
251 {
252     HILOG_INFO("missionId:%{public}d", missionId);
253     std::lock_guard<ffrt::mutex> lock(mutex_);
254     if (missionIdMap_.find(missionId) == missionIdMap_.end()) {
255         HILOG_ERROR("missionId %{public}d not exists, get mission info failed", missionId);
256         return -1;
257     }
258 
259     auto it = std::find_if(missionInfoList_.begin(), missionInfoList_.end(),
260         [&missionId](const InnerMissionInfo item) {
261             return item.missionInfo.id == missionId;
262         }
263     );
264     if (it == missionInfoList_.end()) {
265         HILOG_ERROR("no such mission:%{public}d", missionId);
266         return -1;
267     }
268 
269     if (DoesNotShowInTheMissionList(*it)) {
270         HILOG_INFO("MissionId[%{public}d] don't show in mission list", (*it).missionInfo.id);
271         return -1;
272     }
273 
274     HILOG_INFO("ok missionId:%{public}d", missionId);
275     missionInfo = (*it).missionInfo;
276     return 0;
277 }
278 
GetInnerMissionInfoById(int32_t missionId,InnerMissionInfo & innerMissionInfo)279 int MissionInfoMgr::GetInnerMissionInfoById(int32_t missionId, InnerMissionInfo &innerMissionInfo)
280 {
281     std::lock_guard<ffrt::mutex> lock(mutex_);
282     if (missionIdMap_.find(missionId) == missionIdMap_.end()) {
283         HILOG_ERROR("missionId %{public}d not exists, get inner mission info failed", missionId);
284         return MISSION_NOT_FOUND;
285     }
286 
287     auto it = std::find_if(missionInfoList_.begin(), missionInfoList_.end(),
288         [&missionId](const InnerMissionInfo item) {
289             return item.missionInfo.id == missionId;
290         }
291     );
292     if (it == missionInfoList_.end()) {
293         HILOG_ERROR("no such mission:%{public}d", missionId);
294         return MISSION_NOT_FOUND;
295     }
296     innerMissionInfo = *it;
297     return 0;
298 }
299 
FindReusedMissionInfo(const std::string & missionName,const std::string & missionAffinity,const std::string & flag,bool isFindRecentStandard,bool isFromCollaborator,InnerMissionInfo & info)300 bool MissionInfoMgr::FindReusedMissionInfo(const std::string &missionName, const std::string &missionAffinity,
301     const std::string &flag, bool isFindRecentStandard, bool isFromCollaborator, InnerMissionInfo &info)
302 {
303     if (missionName.empty()) {
304         return false;
305     }
306 
307     std::lock_guard<ffrt::mutex> lock(mutex_);
308     auto it = std::find_if(missionInfoList_.begin(), missionInfoList_.end(),
309         [&missionName, &missionAffinity, &flag, &isFindRecentStandard, &isFromCollaborator](
310             const InnerMissionInfo item) {
311             if (isFromCollaborator && missionAffinity == item.missionAffinity &&
312                 item.collaboratorType != CollaboratorType::DEFAULT_TYPE) {
313                 return true;
314             }
315 
316             if (missionName != item.missionName) {
317                 return false;
318             }
319 
320             // already sorted, return head of list
321             if (isFindRecentStandard && item.launchMode == static_cast<int32_t>(AppExecFwk::LaunchMode::STANDARD)) {
322                 return true;
323             }
324 
325             if (item.launchMode == static_cast<int32_t>(AppExecFwk::LaunchMode::SINGLETON)) {
326                 return true;
327             }
328 
329             if (item.launchMode == static_cast<int32_t>(AppExecFwk::LaunchMode::SPECIFIED)) {
330                 return flag == item.specifiedFlag;
331             }
332             return false;
333         }
334     );
335     if (it == missionInfoList_.end()) {
336         HILOG_WARN("can not find target singleton mission:%{public}s", missionName.c_str());
337         return false;
338     }
339     info = *it;
340     return true;
341 }
342 
UpdateMissionContinueState(int32_t missionId,const AAFwk::ContinueState & state)343 int MissionInfoMgr::UpdateMissionContinueState(int32_t missionId, const AAFwk::ContinueState &state)
344 {
345     HILOG_INFO("UpdateMissionContinueState Start. Mission id: %{public}d, state: %{public}d",
346         missionId, state);
347 
348     if (missionId <= 0) {
349         HILOG_ERROR("UpdateMissionContinueState failed, missionId %{public}d invalid", missionId);
350         return -1;
351     }
352 
353     std::lock_guard<ffrt::mutex> lock(mutex_);
354     auto it = find_if(missionInfoList_.begin(), missionInfoList_.end(), [missionId](const InnerMissionInfo &info) {
355         return missionId == info.missionInfo.id;
356     });
357     if (it == missionInfoList_.end()) {
358         HILOG_ERROR("UpdateMissionContinueState to %{public}d failed, missionId %{public}d not exists.",
359             state, missionId);
360         return -1;
361     }
362 
363     it->missionInfo.continueState = state;
364 
365     HILOG_INFO("UpdateMissionContinueState success. Mission id: %{public}d, ContinueState set to: %{public}d",
366         missionId, state);
367     return 0;
368 }
369 
UpdateMissionLabel(int32_t missionId,const std::string & label)370 int MissionInfoMgr::UpdateMissionLabel(int32_t missionId, const std::string& label)
371 {
372     std::lock_guard<ffrt::mutex> lock(mutex_);
373     if (!taskDataPersistenceMgr_) {
374         HILOG_ERROR("task data persist not init.");
375         return -1;
376     }
377     auto it = find_if(missionInfoList_.begin(), missionInfoList_.end(), [missionId](const InnerMissionInfo &info) {
378         return missionId == info.missionInfo.id;
379     });
380     if (it == missionInfoList_.end()) {
381         HILOG_ERROR("UpdateMissionLabel failed, missionId %{public}d not exists", missionId);
382         return -1;
383     }
384 
385     it->missionInfo.label = label;
386     if (!taskDataPersistenceMgr_->SaveMissionInfo(*it)) {
387         HILOG_ERROR("save mission info failed.");
388         return -1;
389     }
390     return 0;
391 }
392 
SetMissionAbilityState(int32_t missionId,AbilityState state)393 void MissionInfoMgr::SetMissionAbilityState(int32_t missionId, AbilityState state)
394 {
395     if (missionId <= 0) {
396         return;
397     }
398     std::lock_guard<ffrt::mutex> lock(mutex_);
399     auto it = find_if(missionInfoList_.begin(), missionInfoList_.end(), [missionId](const InnerMissionInfo &info) {
400         return missionId == info.missionInfo.id;
401     });
402     if (it == missionInfoList_.end()) {
403         HILOG_ERROR("SetMissionAbilityState failed, missionId %{public}d not exists", missionId);
404         return;
405     }
406     it->missionInfo.abilityState = state;
407 }
408 
LoadAllMissionInfo()409 bool MissionInfoMgr::LoadAllMissionInfo()
410 {
411     if (!taskDataPersistenceMgr_) {
412         HILOG_ERROR("taskDataPersistenceMgr_ is nullptr");
413         return false;
414     }
415 
416     if (!taskDataPersistenceMgr_->LoadAllMissionInfo(missionInfoList_)) {
417         HILOG_ERROR("load mission info failed");
418         return false;
419     }
420 
421     // sort by time
422     auto cmpFunc = [] (const InnerMissionInfo &infoBase, const InnerMissionInfo &infoCmp) {
423         return infoBase.missionInfo.time > infoCmp.missionInfo.time;
424     };
425     missionInfoList_.sort(cmpFunc);
426 
427     for (const auto &info : missionInfoList_) {
428         missionIdMap_[info.missionInfo.id] = true;
429     }
430     return true;
431 }
432 
HandleUnInstallApp(const std::string & bundleName,int32_t uid,std::list<int32_t> & missions)433 void MissionInfoMgr::HandleUnInstallApp(const std::string &bundleName, int32_t uid, std::list<int32_t> &missions)
434 {
435     HILOG_INFO("bundleName:%{public}s, uid:%{public}d", bundleName.c_str(), uid);
436     GetMatchedMission(bundleName, uid, missions);
437     if (missions.empty()) {
438         return;
439     }
440 
441     for (auto missionId : missions) {
442         DeleteMissionInfo(missionId);
443     }
444 }
445 
GetMatchedMission(const std::string & bundleName,int32_t uid,std::list<int32_t> & missions)446 void MissionInfoMgr::GetMatchedMission(const std::string &bundleName, int32_t uid, std::list<int32_t> &missions)
447 {
448     std::lock_guard<ffrt::mutex> lock(mutex_);
449     for (const auto& innerMissionInfo : missionInfoList_) {
450         if (innerMissionInfo.bundleName == bundleName && innerMissionInfo.uid == uid) {
451             missions.push_back(innerMissionInfo.missionInfo.id);
452         }
453     }
454 }
455 
Dump(std::vector<std::string> & info)456 void MissionInfoMgr::Dump(std::vector<std::string> &info)
457 {
458     std::lock_guard<ffrt::mutex> lock(mutex_);
459     for (const auto& innerMissionInfo : missionInfoList_) {
460         innerMissionInfo.Dump(info);
461     }
462 }
463 
RegisterSnapshotHandler(const sptr<ISnapshotHandler> & handler)464 void MissionInfoMgr::RegisterSnapshotHandler(const sptr<ISnapshotHandler>& handler)
465 {
466     std::lock_guard<ffrt::mutex> lock(mutex_);
467     snapshotHandler_ = handler;
468 }
469 
UpdateMissionSnapshot(int32_t missionId,const std::shared_ptr<Media::PixelMap> & pixelMap,bool isPrivate)470 void MissionInfoMgr::UpdateMissionSnapshot(int32_t missionId, const std::shared_ptr<Media::PixelMap> &pixelMap,
471     bool isPrivate)
472 {
473     HILOG_INFO("Update mission snapshot, missionId:%{public}d.", missionId);
474     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
475     MissionSnapshot savedSnapshot;
476     {
477         HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "FindTargetMissionSnapshot");
478         std::lock_guard<ffrt::mutex> lock(mutex_);
479         auto it = find_if(missionInfoList_.begin(), missionInfoList_.end(), [missionId](const InnerMissionInfo &info) {
480             return missionId == info.missionInfo.id;
481         });
482         if (it == missionInfoList_.end()) {
483             HILOG_ERROR("snapshot: get mission failed, missionId %{public}d not exists", missionId);
484             return;
485         }
486         savedSnapshot.topAbility = it->missionInfo.want.GetElement();
487     }
488     if (!taskDataPersistenceMgr_) {
489         HILOG_ERROR("snapshot: taskDataPersistenceMgr_ is nullptr");
490         return;
491     }
492 
493     savedSnapshot.isPrivate = isPrivate;
494     Snapshot snapshot;
495     snapshot.SetPixelMap(pixelMap);
496 
497 #ifdef SUPPORT_GRAPHICS
498     if (isPrivate) {
499         CreateWhitePixelMap(snapshot);
500     }
501     savedSnapshot.snapshot = snapshot.GetPixelMap();
502 #endif
503 
504     if (!taskDataPersistenceMgr_->SaveMissionSnapshot(missionId, savedSnapshot)) {
505         HILOG_ERROR("snapshot: save mission snapshot failed");
506     }
507 }
508 
UpdateMissionSnapshot(int32_t missionId,const sptr<IRemoteObject> & abilityToken,MissionSnapshot & missionSnapshot,bool isLowResolution)509 bool MissionInfoMgr::UpdateMissionSnapshot(int32_t missionId, const sptr<IRemoteObject>& abilityToken,
510     MissionSnapshot& missionSnapshot, bool isLowResolution)
511 {
512     HILOG_INFO("missionId:%{public}d.", missionId);
513     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
514     {
515         HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "FindTargetMissionSnapshot");
516         std::lock_guard<ffrt::mutex> lock(mutex_);
517         auto it = find_if(missionInfoList_.begin(), missionInfoList_.end(), [missionId](const InnerMissionInfo &info) {
518             return missionId == info.missionInfo.id;
519         });
520         if (it == missionInfoList_.end()) {
521             HILOG_ERROR("snapshot: get mission failed, missionId %{public}d not exists", missionId);
522             return false;
523         }
524         missionSnapshot.topAbility = it->missionInfo.want.GetElement();
525     }
526     if (!taskDataPersistenceMgr_) {
527         HILOG_ERROR("snapshot: taskDataPersistenceMgr_ is nullptr");
528         return false;
529     }
530     if (!snapshotHandler_) {
531         HILOG_ERROR("snapshot: snapshotHandler_ is nullptr");
532         return false;
533     }
534     Snapshot snapshot;
535     int32_t result = snapshotHandler_->GetSnapshot(abilityToken, snapshot);
536     if (result != 0) {
537         HILOG_ERROR("snapshot: get WMS snapshot failed, result = %{public}d", result);
538         return false;
539     }
540 
541 #ifdef SUPPORT_GRAPHICS
542     if (missionSnapshot.isPrivate) {
543         CreateWhitePixelMap(snapshot);
544     }
545     missionSnapshot.snapshot = isLowResolution ?
546         MissionDataStorage::GetReducedPixelMap(snapshot.GetPixelMap()) : snapshot.GetPixelMap();
547 #endif
548 
549     MissionSnapshot savedSnapshot = missionSnapshot;
550 #ifdef SUPPORT_GRAPHICS
551     savedSnapshot.snapshot = snapshot.GetPixelMap();
552 #endif
553     {
554         std::lock_guard<ffrt::mutex> lock(savingSnapshotLock_);
555         auto search = savingSnapshot_.find(missionId);
556         if (search == savingSnapshot_.end()) {
557             savingSnapshot_[missionId] = 1;
558         } else {
559             auto savingCount = search->second + 1;
560             savingSnapshot_.insert_or_assign(missionId, savingCount);
561         }
562     }
563     if (!taskDataPersistenceMgr_->SaveMissionSnapshot(missionId, savedSnapshot)) {
564         HILOG_ERROR("snapshot: save mission snapshot failed");
565         CompleteSaveSnapshot(missionId);
566         return false;
567     }
568     HILOG_INFO("success");
569     return true;
570 }
571 
CompleteSaveSnapshot(int32_t missionId)572 void MissionInfoMgr::CompleteSaveSnapshot(int32_t missionId)
573 {
574     std::unique_lock<ffrt::mutex> lock(savingSnapshotLock_);
575     auto search = savingSnapshot_.find(missionId);
576     if (search != savingSnapshot_.end()) {
577         auto savingCount = search->second - 1;
578         if (savingCount == 0) {
579             savingSnapshot_.erase(search);
580             waitSavingCondition_.notify_one();
581         } else {
582             savingSnapshot_.insert_or_assign(missionId, savingCount);
583         }
584     }
585 }
586 
587 #ifdef SUPPORT_GRAPHICS
GetSnapshot(int32_t missionId) const588 std::shared_ptr<Media::PixelMap> MissionInfoMgr::GetSnapshot(int32_t missionId) const
589 {
590     HILOG_INFO("missionId:%{public}d", missionId);
591     {
592         std::lock_guard<ffrt::mutex> lock(mutex_);
593         auto it = find_if(missionInfoList_.begin(), missionInfoList_.end(), [missionId](const InnerMissionInfo &info) {
594             return missionId == info.missionInfo.id;
595         });
596         if (it == missionInfoList_.end()) {
597             HILOG_ERROR("snapshot: get mission failed, missionId %{public}d not exists", missionId);
598             return nullptr;
599         }
600     }
601     if (!taskDataPersistenceMgr_) {
602         HILOG_ERROR("snapshot: taskDataPersistenceMgr_ is nullptr");
603         return nullptr;
604     }
605 
606     return taskDataPersistenceMgr_->GetSnapshot(missionId);
607 }
608 #endif
609 
GetMissionSnapshot(int32_t missionId,const sptr<IRemoteObject> & abilityToken,MissionSnapshot & missionSnapshot,bool isLowResolution,bool force)610 bool MissionInfoMgr::GetMissionSnapshot(int32_t missionId, const sptr<IRemoteObject>& abilityToken,
611     MissionSnapshot& missionSnapshot, bool isLowResolution, bool force)
612 {
613     HILOG_INFO("missionId:%{public}d, force:%{public}d", missionId, force);
614     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
615     {
616         std::lock_guard<ffrt::mutex> lock(mutex_);
617         auto it = find_if(missionInfoList_.begin(), missionInfoList_.end(), [missionId](const InnerMissionInfo &info) {
618             return missionId == info.missionInfo.id;
619         });
620         if (it == missionInfoList_.end()) {
621             HILOG_ERROR("snapshot: get mission failed, missionId %{public}d not exists", missionId);
622             return false;
623         }
624         missionSnapshot.topAbility = it->missionInfo.want.GetElement();
625     }
626     if (!taskDataPersistenceMgr_) {
627         HILOG_ERROR("snapshot: taskDataPersistenceMgr_ is nullptr");
628         return false;
629     }
630 
631     if (force) {
632         HILOG_INFO("force");
633         return UpdateMissionSnapshot(missionId, abilityToken, missionSnapshot, isLowResolution);
634     }
635     {
636         std::unique_lock<ffrt::mutex> lock(savingSnapshotLock_);
637         auto search = savingSnapshot_.find(missionId);
638         if (search != savingSnapshot_.end()) {
639             auto savingSnapshotTimeout = 100; // ms
640             std::chrono::milliseconds timeout { savingSnapshotTimeout };
641             auto waitingCount = 5;
642             auto waitingNum = 0;
643             while (waitSavingCondition_.wait_for(lock, timeout) == ffrt::cv_status::no_timeout) {
644                 ++waitingNum;
645                 auto iter = savingSnapshot_.find(missionId);
646                 if (iter == savingSnapshot_.end() || waitingNum == waitingCount) {
647                     HILOG_INFO("Saved successfully or waiting failed.");
648                     break;
649                 }
650             }
651         }
652     }
653 
654     if (taskDataPersistenceMgr_->GetMissionSnapshot(missionId, missionSnapshot, isLowResolution)) {
655         HILOG_ERROR("mission_list_info GetMissionSnapshot, find snapshot OK, missionId:%{public}d", missionId);
656         return true;
657     }
658     HILOG_INFO("create new snapshot");
659     return UpdateMissionSnapshot(missionId, abilityToken, missionSnapshot, isLowResolution);
660 }
661 
662 #ifdef SUPPORT_GRAPHICS
CreateWhitePixelMap(Snapshot & snapshot) const663 void MissionInfoMgr::CreateWhitePixelMap(Snapshot &snapshot) const
664 {
665     if (snapshot.GetPixelMap() == nullptr) {
666         HILOG_ERROR("CreateWhitePixelMap error.");
667         return;
668     }
669     int32_t dataLength = snapshot.GetPixelMap()->GetByteCount();
670     const uint8_t *pixelData = snapshot.GetPixelMap()->GetPixels();
671     uint8_t *data = const_cast<uint8_t *>(pixelData);
672     if (memset_s(data, dataLength, 0xff, dataLength) != EOK) {
673         HILOG_ERROR("CreateWhitePixelMap memset_s error.");
674     }
675 }
676 #endif
677 }  // namespace AAFwk
678 }  // namespace OHOS
679