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