• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #define MLOG_TAG "MultiStagesPhotoCaptureManager"
17 
18 #include "multistages_capture_manager.h"
19 
20 #include "database_adapter.h"
21 #include "image_packer.h"
22 #include "exif_utils.h"
23 #include "medialibrary_asset_operations.h"
24 #include "medialibrary_bundle_manager.h"
25 #include "medialibrary_command.h"
26 #include "medialibrary_errno.h"
27 #include "medialibrary_rdbstore.h"
28 #include "medialibrary_type_const.h"
29 #include "medialibrary_tracer.h"
30 #include "media_file_uri.h"
31 #include "media_file_utils.h"
32 #include "media_log.h"
33 #include "medialibrary_formmap_operations.h"
34 #include "picture_manager_thread.h"
35 #include "multistages_capture_dfx_first_visit.h"
36 #include "multistages_capture_dfx_request_policy.h"
37 #include "multistages_capture_dfx_total_time.h"
38 #include "multistages_capture_dfx_trigger_ratio.h"
39 #include "multistages_capture_request_task_manager.h"
40 #include "request_policy.h"
41 #include "result_set_utils.h"
42 #include "userfilemgr_uri.h"
43 
44 using namespace std;
45 #ifdef ABILITY_CAMERA_SUPPORT
46 using namespace OHOS::CameraStandard;
47 #endif
48 
49 namespace OHOS {
50 namespace Media {
51 const int32_t SAVE_PICTURE_TIMEOUT_SEC = 20;
52 const std::string MEDIA_DATA_DB_DEFERRED_PROC_TYPE = "deferred_proc_type";
53 
MultiStagesPhotoCaptureManager()54 MultiStagesPhotoCaptureManager::MultiStagesPhotoCaptureManager()
55 {
56     deferredProcSession_ = make_shared<DeferredPhotoProcessingAdapter>();
57 }
58 
~MultiStagesPhotoCaptureManager()59 MultiStagesPhotoCaptureManager::~MultiStagesPhotoCaptureManager() {}
60 
GetInstance()61 MultiStagesPhotoCaptureManager& MultiStagesPhotoCaptureManager::GetInstance()
62 {
63     static MultiStagesPhotoCaptureManager instance;
64     return instance;
65 }
66 
Init()67 bool MultiStagesPhotoCaptureManager::Init()
68 {
69     SyncWithDeferredProcSessionInternal();
70     return true;
71 }
72 
CancelRequestAndRemoveImage(const vector<string> & columns)73 void MultiStagesPhotoCaptureManager::CancelRequestAndRemoveImage(const vector<string> &columns)
74 {
75     CHECK_AND_RETURN_LOG(columns.size() >= 1, "invalid param");
76     int32_t fileId = stoi(columns[0]);
77     string photoId = MultiStagesCaptureRequestTaskManager::GetProcessingPhotoId(fileId);
78     MEDIA_INFO_LOG("fileId: %{public}d, photoId: %{public}s", fileId, photoId.c_str());
79     CancelProcessRequest(photoId);
80     RemoveImage(photoId, false);
81 }
82 
HandleMultiStagesOperation(MediaLibraryCommand & cmd,const vector<string> & columns)83 shared_ptr<OHOS::NativeRdb::ResultSet> MultiStagesPhotoCaptureManager::HandleMultiStagesOperation(
84     MediaLibraryCommand &cmd, const vector<string> &columns)
85 {
86     switch (cmd.GetOprnType()) {
87         case OperationType::PROCESS_IMAGE: {
88             int fileId = std::stoi(columns[0]); // 0 indicates file id
89             int deliveryMode = std::stoi(columns[1]); // 1 indicates delivery mode
90             ProcessImage(fileId, deliveryMode);
91             MultiStagesCaptureDfxTriggerRatio::GetInstance().SetTrigger(MultiStagesCaptureTriggerType::THIRD_PART);
92             break;
93         }
94         case OperationType::ADD_IMAGE: {
95             AddImage(cmd);
96             break;
97         }
98         case OperationType::SET_LOCATION: {
99             UpdateLocation(cmd.GetValueBucket(), false);
100             break;
101         }
102         case OperationType::CANCEL_PROCESS_IMAGE: {
103             string photoId = columns[0]; // 0 indicates photo id
104             MEDIA_INFO_LOG("cancel request photoId: %{public}s", photoId.c_str());
105             CancelProcessRequest(photoId);
106             break;
107         }
108         case OperationType::REMOVE_MSC_TASK: {
109             CancelRequestAndRemoveImage(columns);
110             break;
111         }
112         case OperationType::ADD_LOWQUALITY_IMAGE: {
113             MEDIA_DEBUG_LOG("save low quality Image");
114             SaveLowQualityImageInfo(cmd);
115             break;
116         }
117         default:
118             break;
119     }
120     return nullptr;
121 }
122 
SaveLowQualityImageInfo(MediaLibraryCommand & cmd)123 void MultiStagesPhotoCaptureManager::SaveLowQualityImageInfo(MediaLibraryCommand &cmd)
124 {
125     auto values = cmd.GetValueBucket();
126     string photoId = "";
127     ValueObject valueObject;
128     if (values.GetObject(PhotoColumn::PHOTO_ID, valueObject)) {
129         valueObject.GetString(photoId);
130     }
131     int32_t deferredProcType = -1;
132     if (values.GetObject(PhotoColumn::PHOTO_DEFERRED_PROC_TYPE, valueObject)) {
133         valueObject.GetInt(deferredProcType);
134     }
135     int32_t fileId = 0;
136     if (values.GetObject(MediaColumn::MEDIA_ID, valueObject)) {
137         valueObject.GetInt(fileId);
138     }
139 }
140 
141 // 低质量入缓存
DealLowQualityPicture(const std::string & imageId,std::shared_ptr<Media::Picture> picture,bool isEdited)142 void MultiStagesPhotoCaptureManager::DealLowQualityPicture(const std::string &imageId,
143     std::shared_ptr<Media::Picture> picture, bool isEdited)
144 {
145     auto pictureManagerThread = PictureManagerThread::GetInstance();
146     CHECK_AND_RETURN_LOG(pictureManagerThread != nullptr, "pictureManagerThread not init yet");
147     CHECK_AND_RETURN_LOG(!pictureManagerThread->IsExsitPictureByImageId(imageId),
148         "current photo already in the cache");
149 
150     // 将低质量图存入缓存
151     time_t currentTime;
152     if ((currentTime = time(NULL)) == -1) {
153         MEDIA_ERR_LOG("Get time is error");
154         currentTime = time(NULL);
155     }
156     time_t expireTime = currentTime + SAVE_PICTURE_TIMEOUT_SEC;
157     std::string imageIdInPair = imageId;
158     sptr<PicturePair> picturePair = new PicturePair(std::move(picture), imageIdInPair, expireTime, true, false);
159     // 存低质量裸picture
160     pictureManagerThread->InsertPictureData(imageId, picturePair, LOW_QUALITY_PICTURE);
161     MEDIA_INFO_LOG("MultistagesCapture photoid: %{public}s", imageId.c_str());
162 }
163 
IsHighQualityPhotoExist(const std::string & uri)164 bool MultiStagesPhotoCaptureManager::IsHighQualityPhotoExist(const std::string &uri)
165 {
166     string filePath = MediaFileUri::GetPathFromUri(uri, true);
167     string filePathTemp = filePath + ".high";
168     return MediaFileUtils::IsFileExists(filePathTemp) || MediaFileUtils::IsFileExists(filePath);
169 }
170 
SaveLowQualityPicture(const std::string & imageId)171 void MultiStagesPhotoCaptureManager::SaveLowQualityPicture(const std::string &imageId)
172 {
173     MEDIA_INFO_LOG("photoid: %{public}s", imageId.c_str());
174     auto pictureManagerThread = PictureManagerThread::GetInstance();
175     CHECK_AND_RETURN_LOG(pictureManagerThread != nullptr, "pictureManagerThread not init yet");
176     pictureManagerThread->SaveLowQualityPicture(imageId);
177 }
178 
179 // 高质量编辑图片存20S
DealHighQualityPicture(const std::string & imageId,std::shared_ptr<Media::Picture> picture,bool isEdited,bool isTakeEffect)180 void MultiStagesPhotoCaptureManager::DealHighQualityPicture(const std::string &imageId,
181     std::shared_ptr<Media::Picture> picture, bool isEdited, bool isTakeEffect)
182 {
183     MEDIA_INFO_LOG("photoid: %{public}s", imageId.c_str());
184     auto pictureManagerThread = PictureManagerThread::GetInstance();
185     CHECK_AND_RETURN_LOG(pictureManagerThread != nullptr, "pictureManagerThread not init yet");
186     // 将低质量图存入缓存
187     time_t currentTime;
188     if ((currentTime = time(NULL)) == -1) {
189         MEDIA_ERR_LOG("Get time is error");
190         currentTime = time(NULL);
191     }
192     time_t expireTime = currentTime + SAVE_PICTURE_TIMEOUT_SEC;
193     std::string imageIdInPair = imageId;
194     sptr<PicturePair> picturePair= new PicturePair(std::move(picture), imageIdInPair, expireTime, true, isEdited);
195     picturePair->SetTakeEffect(isTakeEffect);
196     pictureManagerThread->InsertPictureData(imageId, picturePair, HIGH_QUALITY_PICTURE);
197     // delete raw file
198     MultiStagesPhotoCaptureManager::GetInstance().RemoveImage(imageId, false);
199 }
200 
UpdateDbInfo(MediaLibraryCommand & cmd)201 int32_t MultiStagesPhotoCaptureManager::UpdateDbInfo(MediaLibraryCommand &cmd)
202 {
203     MediaLibraryCommand cmdLocal (OperationObject::FILESYSTEM_PHOTO, OperationType::UPDATE);
204     auto values = cmd.GetValueBucket();
205     ValueObject valueObject;
206     int32_t photoQuality = static_cast<int32_t>(MultiStagesPhotoQuality::LOW);
207     if (values.GetObject(PhotoColumn::PHOTO_QUALITY, valueObject)) {
208         valueObject.GetInt(photoQuality);
209     }
210     if (photoQuality == static_cast<int32_t>(MultiStagesPhotoQuality::LOW)) {
211         values.PutInt(MEDIA_DATA_DB_DIRTY, -1); // prevent uploading low-quality photo
212     }
213     cmdLocal.SetValueBucket(values);
214     cmdLocal.GetAbsRdbPredicates()->SetWhereClause(cmd.GetAbsRdbPredicates()->GetWhereClause());
215     cmdLocal.GetAbsRdbPredicates()->SetWhereArgs(cmd.GetAbsRdbPredicates()->GetWhereArgs());
216     auto result = DatabaseAdapter::Update(cmdLocal);
217     if (result != NativeRdb::E_OK) {
218         MEDIA_ERR_LOG("update failed");
219     }
220     return result;
221 }
222 
QueryPathByFileId(const int32_t & fileId)223 static std::string QueryPathByFileId(const int32_t &fileId)
224 {
225     MediaLibraryCommand queryCmd(OperationObject::FILESYSTEM_PHOTO, OperationType::QUERY);
226     std::string where = MediaColumn::MEDIA_ID + " = " + to_string(fileId);
227     queryCmd.GetAbsRdbPredicates()->SetWhereClause(where);
228 
229     std::vector<std::string> columns { MediaColumn::MEDIA_FILE_PATH };
230     auto resultSet = DatabaseAdapter::Query(queryCmd, columns);
231     bool cond = (resultSet == nullptr || resultSet->GoToFirstRow() != 0);
232     CHECK_AND_RETURN_RET_LOG(!cond, "", "result set is empty");
233 
234     std::string path = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
235     return path;
236 }
237 
WriteGpsInfoAndUpdateDb(const std::string & path,const int32_t & fileId,const double longitude,const double latitude)238 static int32_t WriteGpsInfoAndUpdateDb(const std::string &path, const int32_t &fileId, const double longitude,
239     const double latitude)
240 {
241     MediaLibraryTracer tracer;
242     tracer.Start("WriteGpsInfoAndUpdateDb, path");
243     auto ret = ExifUtils::WriteGpsExifInfo(path, longitude, latitude);
244     tracer.Finish();
245     CHECK_AND_RETURN_RET_LOG(ret == E_OK, E_ERR, "write gps info fail");
246 
247     std::string originPath = MediaLibraryAssetOperations::GetEditDataSourcePath(path);
248     if (MediaFileUtils::IsFileExists(originPath)) {
249         // write gps info if this photo was edited.
250         tracer.Start("WriteGpsInfoAndUpdateDb, originPath");
251         auto ret = ExifUtils::WriteGpsExifInfo(originPath, longitude, latitude);
252         tracer.Finish();
253         CHECK_AND_RETURN_RET_LOG(ret == E_OK, E_ERR, "write origin file gps info fail");
254     }
255 
256     MediaLibraryCommand cmd(OperationObject::FILESYSTEM_PHOTO, OperationType::UPDATE);
257     cmd.GetAbsRdbPredicates()->EqualTo(PhotoColumn::MEDIA_ID, fileId);
258 
259     ValuesBucket updateValues;
260     updateValues.PutDouble(PhotoColumn::PHOTO_LATITUDE, latitude);
261     updateValues.PutDouble(PhotoColumn::PHOTO_LONGITUDE, longitude);
262     cmd.SetValueBucket(updateValues);
263 
264     auto result = DatabaseAdapter::Update(cmd);
265     CHECK_AND_RETURN_RET_LOG(result == NativeRdb::E_OK, E_ERR, "update fail fileId: %{public}d", fileId);
266 
267     return E_OK;
268 }
269 
UpdateLocation(const NativeRdb::ValuesBucket & values,bool isWriteGpsAdvanced,const std::string & path,const int32_t & id)270 void MultiStagesPhotoCaptureManager::UpdateLocation(const NativeRdb::ValuesBucket &values, bool isWriteGpsAdvanced,
271     const std::string &path, const int32_t &id)
272 {
273     MediaLibraryTracer tracer;
274     tracer.Start("UpdateLocation");
275     MEDIA_INFO_LOG("UpdateLocation begin, isWriteGpsAdvanced: %{public}d, path: %{public}s, fileId: %{public}d",
276         isWriteGpsAdvanced, MediaFileUtils::DesensitizePath(path).c_str(), id);
277     ValueObject valueObject;
278     double longitude = 0;
279     if (values.GetObject(PhotoColumn::PHOTO_LONGITUDE, valueObject)) {
280         valueObject.GetDouble(longitude);
281     }
282     double latitude = 0;
283     if (values.GetObject(PhotoColumn::PHOTO_LATITUDE, valueObject)) {
284         valueObject.GetDouble(latitude);
285     }
286 
287     std::string filePath;
288     int32_t fileId = 0;
289     if (isWriteGpsAdvanced) {
290         filePath = path;
291         fileId = id;
292     } else {
293         if (values.GetObject(MediaColumn::MEDIA_ID, valueObject)) {
294             valueObject.GetInt(fileId);
295         }
296         filePath = QueryPathByFileId(fileId);
297     }
298     CHECK_AND_RETURN_LOG((!filePath.empty() && fileId > 0), "UpdateLocation invalid value!");
299     WriteGpsInfoAndUpdateDb(filePath, fileId, longitude, latitude);
300     MEDIA_INFO_LOG("UpdateLocation success");
301 }
302 
AddImageInternal(int32_t fileId,const string & photoId,int32_t deferredProcType,bool discardable)303 void MultiStagesPhotoCaptureManager::AddImageInternal(int32_t fileId, const string &photoId, int32_t deferredProcType,
304     bool discardable)
305 {
306     MultiStagesCaptureRequestTaskManager::AddPhotoInProgress(fileId, photoId, discardable);
307 
308 #ifdef ABILITY_CAMERA_SUPPORT
309     DpsMetadata metadata;
310     metadata.Set(CameraStandard::DEFERRED_PROCESSING_TYPE_KEY, deferredProcType);
311     deferredProcSession_->AddImage(photoId, metadata, discardable);
312 #endif
313 }
314 
AddImage(int32_t fileId,const string & photoId,int32_t deferredProcType)315 void MultiStagesPhotoCaptureManager::AddImage(int32_t fileId, const string &photoId, int32_t deferredProcType)
316 {
317     if (photoId.empty()) {
318         MEDIA_ERR_LOG("photo is empty");
319         return;
320     }
321     MEDIA_INFO_LOG("enter AddImage, fileId: %{public}d, photoId: %{public}s, deferredProcType: %{public}d", fileId,
322         photoId.c_str(), deferredProcType);
323 
324     // called when camera low quality photo saved, isTrashed must be false.
325     AddImageInternal(fileId, photoId, deferredProcType, false);
326 }
327 
AddImage(MediaLibraryCommand & cmd)328 void MultiStagesPhotoCaptureManager::AddImage(MediaLibraryCommand &cmd)
329 {
330     MEDIA_DEBUG_LOG("calling addImage");
331     auto pictureManagerThread = PictureManagerThread::GetInstance();
332     if (pictureManagerThread == nullptr) {
333         return;
334     }
335     auto values = cmd.GetValueBucket();
336     ValueObject valueObject;
337     int32_t photoQuality = static_cast<int32_t>(MultiStagesPhotoQuality::LOW);
338     if (values.GetObject(PhotoColumn::PHOTO_QUALITY, valueObject)) {
339         valueObject.GetInt(photoQuality);
340     }
341 
342     string photoId = "";
343     if (values.GetObject(PhotoColumn::PHOTO_ID, valueObject)) {
344         valueObject.GetString(photoId);
345     }
346     if (photoQuality == static_cast<int32_t>(MultiStagesPhotoQuality::FULL)) {
347         pictureManagerThread->SavePictureWithImageId(photoId);
348         UpdatePictureQuality(photoId);
349         return;
350     }
351     int32_t deferredProcType = -1;
352     if (values.GetObject(PhotoColumn::PHOTO_DEFERRED_PROC_TYPE, valueObject)) {
353         valueObject.GetInt(deferredProcType);
354     }
355     int32_t fileId = 0;
356     if (values.GetObject(MediaColumn::MEDIA_ID, valueObject)) {
357         valueObject.GetInt(fileId);
358     }
359 
360     AddImage(fileId, photoId, deferredProcType);
361     MultiStagesCaptureDfxTotalTime::GetInstance().AddStartTime(photoId);
362     MultiStagesCaptureDfxTriggerRatio::GetInstance().SetTrigger(MultiStagesCaptureTriggerType::AUTO);
363     if (OPRN_ADD_LOWQUALITY_IMAGE == cmd.GetQuerySetParam("save_picture")) {
364         MEDIA_DEBUG_LOG("save last low quality Image");
365         SaveLowQualityImageInfo(cmd);
366     }
367 }
368 
UpdatePictureQuality(const std::string & photoId)369 int32_t MultiStagesPhotoCaptureManager::UpdatePictureQuality(const std::string &photoId)
370 {
371     MediaLibraryTracer tracer;
372     tracer.Start("UpdatePictureQuality " + photoId);
373     MediaLibraryCommand updateCmd(OperationObject::FILESYSTEM_PHOTO, OperationType::UPDATE);
374     NativeRdb::ValuesBucket updateValues;
375     updateValues.PutInt(PhotoColumn::PHOTO_QUALITY, static_cast<int32_t>(MultiStagesPhotoQuality::FULL));
376     updateCmd.SetValueBucket(updateValues);
377     updateCmd.GetAbsRdbPredicates()->EqualTo(PhotoColumn::PHOTO_ID, photoId);
378     int32_t updatePhotoQualityResult = DatabaseAdapter::Update(updateCmd);
379 
380     updateCmd.GetAbsRdbPredicates()->EqualTo(PhotoColumn::PHOTO_IS_TEMP, false);
381     updateCmd.GetAbsRdbPredicates()->NotEqualTo(PhotoColumn::PHOTO_SUBTYPE,
382         to_string(static_cast<int32_t>(PhotoSubType::MOVING_PHOTO)));
383     NativeRdb::ValuesBucket updateValuesDirty;
384     updateValuesDirty.PutInt(PhotoColumn::PHOTO_DIRTY, static_cast<int32_t>(DirtyType::TYPE_NEW));
385     updateCmd.SetValueBucket(updateValuesDirty);
386     auto isDirtyResult = DatabaseAdapter::Update(updateCmd);
387     CHECK_AND_PRINT_LOG(isDirtyResult >= 0, "update dirty flag fail, photoId: %{public}s", photoId.c_str());
388     return updatePhotoQualityResult;
389 }
390 
SyncWithDeferredProcSessionInternal()391 void MultiStagesPhotoCaptureManager::SyncWithDeferredProcSessionInternal()
392 {
393     MEDIA_INFO_LOG("enter");
394     // 进程重启场景,媒体库需要和延时子服务同步
395     MediaLibraryCommand cmd(OperationObject::FILESYSTEM_PHOTO, OperationType::QUERY);
396     string where = MEDIA_DATA_DB_PHOTO_ID + " is not null and " +
397         MEDIA_DATA_DB_PHOTO_QUALITY + " > 0 and " + MEDIA_DATA_DB_MEDIA_TYPE + " = " +
398         to_string(static_cast<int32_t>(MediaType::MEDIA_TYPE_IMAGE));
399     cmd.GetAbsRdbPredicates()->SetWhereClause(where);
400     vector<string> columns { MEDIA_DATA_DB_ID, MEDIA_DATA_DB_PHOTO_ID, MEDIA_DATA_DB_DATE_TRASHED,
401         MEDIA_DATA_DB_DEFERRED_PROC_TYPE };
402     auto resultSet = DatabaseAdapter::Query(cmd, columns);
403     bool cond = (resultSet == nullptr || resultSet->GoToFirstRow() != 0);
404     CHECK_AND_RETURN_LOG(!cond, "result set is empty");
405     MediaLibraryTracer tracer;
406     tracer.Start("MultiStagesPhotoCaptureManager::SyncWithDeferredProcSession");
407     deferredProcSession_->BeginSynchronize();
408 
409     do {
410         int32_t fileId = GetInt32Val(MEDIA_DATA_DB_ID, resultSet);
411         string photoId = GetStringVal(MEDIA_DATA_DB_PHOTO_ID, resultSet);
412         bool isTrashed = GetInt32Val(MEDIA_DATA_DB_DATE_TRASHED, resultSet) > 0;
413         if (setOfDeleted_.find(fileId) != setOfDeleted_.end()) {
414             MEDIA_INFO_LOG("remove image, fileId: %{public}d, photoId: %{public}s", fileId, photoId.c_str());
415             deferredProcSession_->RemoveImage(photoId);
416             continue;
417         }
418         MEDIA_INFO_LOG("AddImage fileId: %{public}d, photoId: %{public}s", fileId, photoId.c_str());
419         int32_t deferredProcType = GetInt32Val(MEDIA_DATA_DB_DEFERRED_PROC_TYPE, resultSet);
420         AddImageInternal(fileId, photoId, deferredProcType, isTrashed);
421     } while (!resultSet->GoToNextRow());
422     resultSet->Close();
423     deferredProcSession_->EndSynchronize();
424     MEDIA_INFO_LOG("exit");
425 }
426 
SyncWithDeferredPhotoProcSessionAsync(AsyncTaskData * data)427 static void SyncWithDeferredPhotoProcSessionAsync(AsyncTaskData *data)
428 {
429     MultiStagesPhotoCaptureManager::GetInstance().SyncWithDeferredProcSessionInternal();
430 }
431 
SyncWithDeferredProcSession()432 void MultiStagesPhotoCaptureManager::SyncWithDeferredProcSession()
433 {
434     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
435     CHECK_AND_RETURN_LOG(asyncWorker != nullptr, "can not get async worker");
436     shared_ptr<MediaLibraryAsyncTask> asyncTask =
437         make_shared<MediaLibraryAsyncTask>(SyncWithDeferredPhotoProcSessionAsync, nullptr);
438     CHECK_AND_RETURN_LOG(asyncTask != nullptr, "SyncWithDeferredProcSession create task fail");
439     MEDIA_INFO_LOG("SyncWithDeferredProcSession add task success");
440     asyncWorker->AddTask(asyncTask, false);
441 }
442 
443 #ifdef ABILITY_CAMERA_SUPPORT
SetProcessImageDoneCallback(const ProcessDoneHandler & func)444 void MultiStagesPhotoCaptureManager::SetProcessImageDoneCallback(const ProcessDoneHandler &func)
445 {
446     if (deferredProcSession_ != nullptr) {
447         deferredProcSession_->SetProcessImageDoneCallback(func);
448     }
449 }
450 #endif
451 
CancelProcessRequest(const string & photoId)452 bool MultiStagesPhotoCaptureManager::CancelProcessRequest(const string &photoId)
453 {
454     CHECK_AND_RETURN_RET_LOG(MultiStagesCaptureRequestTaskManager::IsPhotoInProcess(photoId), false,
455         "photoId is empty or not in process");
456     int32_t currentRequestCount =
457         MultiStagesCaptureRequestTaskManager::UpdatePhotoInProcessRequestCount(photoId, RequestType::CANCEL_REQUEST);
458     CHECK_AND_RETURN_RET_LOG(currentRequestCount <= 0, false,
459         "not cancel request because request count(%{public}d) greater than 0", currentRequestCount);
460     auto isCancelSucc = deferredProcSession_->CancelProcessImage(photoId);
461     MEDIA_INFO_LOG("cancel request isCancelSucc: %{public}d", isCancelSucc);
462     return true;
463 }
464 
RemoveImage(const string & photoId,bool isRestorable)465 void MultiStagesPhotoCaptureManager::RemoveImage(const string &photoId, bool isRestorable)
466 {
467     if (!MultiStagesCaptureRequestTaskManager::IsPhotoInProcess(photoId)) {
468         // In order to ensure image can be completely deleted, do not return here, only record the log.
469         MEDIA_ERR_LOG("photoId is empty or not in process ");
470     }
471 
472     MultiStagesCaptureRequestTaskManager::RemovePhotoInProgress(photoId, isRestorable);
473     deferredProcSession_->RemoveImage(photoId, isRestorable);
474 }
475 
RestoreImage(const string & photoId)476 void MultiStagesPhotoCaptureManager::RestoreImage(const string &photoId)
477 {
478     CHECK_AND_PRINT_LOG(!photoId.empty(), "photoId is empty");
479     MultiStagesCaptureRequestTaskManager::UpdatePhotoInProgress(photoId);
480     deferredProcSession_->RestoreImage(photoId);
481 }
482 
ProcessImage(int fileId,int deliveryMode)483 void MultiStagesPhotoCaptureManager::ProcessImage(int fileId, int deliveryMode)
484 {
485     string photoId = MultiStagesCaptureRequestTaskManager::GetProcessingPhotoId(fileId) ;
486     CHECK_AND_RETURN_LOG(photoId.size() != 0, "processimage image id is invalid, fileId:"
487         " %{public}d", fileId);
488 
489     string callerBundleName = MediaLibraryBundleManager::GetInstance()->GetClientBundleName();
490     MultiStagesCaptureDfxTriggerRatio::GetInstance().SetTrigger(MultiStagesCaptureTriggerType::THIRD_PART);
491     MultiStagesCaptureDfxRequestPolicy::GetInstance().SetPolicy(callerBundleName,
492         static_cast<RequestPolicy>(deliveryMode));
493     MultiStagesCaptureDfxFirstVisit::GetInstance().Report(photoId);
494     int32_t currentRequestCount =
495         MultiStagesCaptureRequestTaskManager::UpdatePhotoInProcessRequestCount(photoId, RequestType::REQUEST);
496     MEDIA_INFO_LOG("processimage, pkg name: %{public}s, photoid %{public}s, mode: %{public}d, count: %{public}d",
497         callerBundleName.c_str(), photoId.c_str(), deliveryMode, currentRequestCount);
498     if ((deliveryMode == static_cast<int32_t>(RequestPolicy::HIGH_QUALITY_MODE) ||
499         deliveryMode == static_cast<int32_t>(RequestPolicy::BALANCE_MODE)) &&
500         currentRequestCount <= 1) {
501         deferredProcSession_->ProcessImage(callerBundleName, photoId);
502     }
503 }
504 
IsPhotoDeleted(const std::string & photoId)505 bool MultiStagesPhotoCaptureManager::IsPhotoDeleted(const std::string &photoId)
506 {
507     if (!MultiStagesCaptureRequestTaskManager::IsPhotoInProcess(photoId)) {
508         return false;
509     }
510 
511     return true;
512 }
513 } // namespace Media
514 } // namespace OHOS