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