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