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