• 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 "MultiStagesCaptureDeferredPhotoProcSessionCallback"
17 
18 #include "multistages_capture_deferred_photo_proc_session_callback.h"
19 
20 #include "database_adapter.h"
21 #include "file_utils.h"
22 #include "media_exif.h"
23 #include "media_file_utils.h"
24 #include "media_file_uri.h"
25 #include "media_log.h"
26 #include "medialibrary_asset_operations.h"
27 #include "medialibrary_errno.h"
28 #include "medialibrary_notify.h"
29 #include "medialibrary_object_utils.h"
30 #include "medialibrary_photo_operations.h"
31 #include "medialibrary_tracer.h"
32 #include "multistages_capture_manager.h"
33 #include "multistages_capture_dfx_result.h"
34 #include "multistages_capture_dfx_total_time.h"
35 #include "multistages_capture_request_task_manager.h"
36 #include "multistages_moving_photo_capture_manager.h"
37 #include "result_set_utils.h"
38 #include "media_change_effect.h"
39 #include "exif_metadata.h"
40 #include "picture_adapter.h"
41 #ifdef MEDIALIBRARY_FEATURE_CLOUD_ENHANCEMENT
42 #include "enhancement_manager.h"
43 #endif
44 
45 using namespace std;
46 using namespace OHOS::CameraStandard;
47 
48 constexpr int32_t ORIENTATION_0 = 1;
49 constexpr int32_t ORIENTATION_90 = 6;
50 constexpr int32_t ORIENTATION_180 = 3;
51 constexpr int32_t ORIENTATION_270 = 8;
52 constexpr uint32_t MANUAL_ENHANCEMENT = 1;
53 constexpr uint32_t AUTO_ENHANCEMENT = 1 << 1;
54 
55 static const std::unordered_map<int, int> ORIENTATION_MAP = {
56     {0, ORIENTATION_0},
57     {90, ORIENTATION_90},
58     {180, ORIENTATION_180},
59     {270, ORIENTATION_270}
60 };
61 
62 const std::string HIGH_TEMPERATURE = "high_temperature";
63 
64 namespace OHOS {
65 namespace Media {
MultiStagesCaptureDeferredPhotoProcSessionCallback()66 MultiStagesCaptureDeferredPhotoProcSessionCallback::MultiStagesCaptureDeferredPhotoProcSessionCallback()
67 {}
68 
~MultiStagesCaptureDeferredPhotoProcSessionCallback()69 MultiStagesCaptureDeferredPhotoProcSessionCallback::~MultiStagesCaptureDeferredPhotoProcSessionCallback()
70 {}
71 
NotifyIfTempFile(shared_ptr<NativeRdb::ResultSet> resultSet,bool isError)72 void MultiStagesCaptureDeferredPhotoProcSessionCallback::NotifyIfTempFile(
73     shared_ptr<NativeRdb::ResultSet> resultSet, bool isError)
74 {
75     CHECK_AND_RETURN_LOG(resultSet != nullptr, "resultSet is nullptr");
76     string displayName = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
77     string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
78     int32_t mediaType = GetInt32Val(MediaColumn::MEDIA_TYPE, resultSet);
79     int32_t fileId = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
80     resultSet->Close();
81 
82     auto watch = MediaLibraryNotify::GetInstance();
83     CHECK_AND_RETURN_LOG(watch != nullptr, "get instance notify failed NotifyIfTempFile abortion");
84 
85     string extrUri = MediaFileUtils::GetExtraUri(displayName, filePath);
86     auto notifyUri = MediaFileUtils::GetUriByExtrConditions(ML_FILE_URI_PREFIX + MediaFileUri::GetMediaTypeUri(
87         static_cast<MediaType>(mediaType), MEDIA_API_VERSION_V10) + "/", to_string(fileId), extrUri);
88     notifyUri = MediaFileUtils::GetUriWithoutDisplayname(notifyUri);
89     if (isError) {
90         notifyUri += HIGH_TEMPERATURE;
91     }
92     MEDIA_DEBUG_LOG("MultistagesCapture notify: %{public}s", notifyUri.c_str());
93     watch->Notify(notifyUri, NOTIFY_UPDATE);
94 }
95 
UpdatePhotoQuality(const string & photoId)96 int32_t MultiStagesCaptureDeferredPhotoProcSessionCallback::UpdatePhotoQuality(const string &photoId)
97 {
98     MediaLibraryTracer tracer;
99     tracer.Start("UpdatePhotoQuality " + photoId);
100     MediaLibraryCommand updateCmd(OperationObject::FILESYSTEM_PHOTO, OperationType::UPDATE);
101     NativeRdb::ValuesBucket updateValues;
102     updateValues.PutInt(PhotoColumn::PHOTO_QUALITY, static_cast<int32_t>(MultiStagesPhotoQuality::FULL));
103     updateCmd.SetValueBucket(updateValues);
104     updateCmd.GetAbsRdbPredicates()->EqualTo(PhotoColumn::PHOTO_ID, photoId);
105     int32_t updatePhotoQualityResult = DatabaseAdapter::Update(updateCmd);
106 
107     updateCmd.GetAbsRdbPredicates()->EqualTo(PhotoColumn::PHOTO_IS_TEMP, false);
108     updateCmd.GetAbsRdbPredicates()->NotEqualTo(PhotoColumn::PHOTO_SUBTYPE,
109         to_string(static_cast<int32_t>(PhotoSubType::MOVING_PHOTO)));
110     NativeRdb::ValuesBucket updateValuesDirty;
111     updateValuesDirty.PutInt(PhotoColumn::PHOTO_DIRTY, static_cast<int32_t>(DirtyType::TYPE_NEW));
112     updateCmd.SetValueBucket(updateValuesDirty);
113     auto isDirtyResult = DatabaseAdapter::Update(updateCmd);
114     CHECK_AND_PRINT_LOG(isDirtyResult >= 0, "update dirty flag fail, photoId: %{public}s", photoId.c_str());
115     return updatePhotoQualityResult;
116 }
117 
UpdateCEAvailable(const string & photoId,uint32_t cloudImageEnhanceFlag,int32_t modifyType)118 void MultiStagesCaptureDeferredPhotoProcSessionCallback::UpdateCEAvailable(const string& photoId,
119     uint32_t cloudImageEnhanceFlag, int32_t modifyType)
120 {
121     MEDIA_INFO_LOG("photoId: %{public}s, modify type is %{public}d", photoId.c_str(), modifyType);
122     MediaLibraryCommand updateCEAvailableCmd(OperationObject::FILESYSTEM_PHOTO, OperationType::UPDATE);
123     NativeRdb::ValuesBucket updateCEAvailable;
124     int32_t ceAvailable = static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT);
125     if (modifyType == static_cast<int32_t>(FirstStageModifyType::EDITED)) {
126         MEDIA_INFO_LOG("photoId: %{public}s edited", photoId.c_str());
127         ceAvailable = static_cast<int32_t>(CloudEnhancementAvailableType::EDIT);
128     } else if (modifyType == static_cast<int32_t>(FirstStageModifyType::TRASHED)) {
129         MEDIA_INFO_LOG("photoId: %{public}s trashed", photoId.c_str());
130         ceAvailable = static_cast<int32_t>(CloudEnhancementAvailableType::TRASH);
131     }
132     updateCEAvailableCmd.GetAbsRdbPredicates()->EqualTo(PhotoColumn::PHOTO_ID, photoId);
133     if (cloudImageEnhanceFlag & AUTO_ENHANCEMENT) {
134         MEDIA_INFO_LOG("photoId: %{public}s is AUTO_ENHANCEMENT", photoId.c_str());
135         updateCEAvailable.PutInt(PhotoColumn::PHOTO_IS_AUTO, static_cast<int32_t>(CloudEnhancementIsAutoType::AUTO));
136         updateCEAvailable.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE, ceAvailable);
137     } else if (cloudImageEnhanceFlag & MANUAL_ENHANCEMENT) {
138         MEDIA_INFO_LOG("photoId: %{public}s is MANUAL_ENHANCEMENT", photoId.c_str());
139         updateCEAvailable.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE, ceAvailable);
140     } else {
141         MEDIA_INFO_LOG("photoId: %{public}s doesn't support enhancement", photoId.c_str());
142         updateCEAvailable.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE,
143             static_cast<int32_t>(CloudEnhancementAvailableType::NOT_SUPPORT));
144     }
145     updateCEAvailableCmd.SetValueBucket(updateCEAvailable);
146     auto ceAvailableResult = DatabaseAdapter::Update(updateCEAvailableCmd);
147     CHECK_AND_RETURN_LOG(ceAvailableResult >= 0, "update CE available fail, photoId: %{public}s", photoId.c_str());
148 }
149 
QueryPhotoData(const std::string & imageId)150 std::shared_ptr<NativeRdb::ResultSet> QueryPhotoData(const std::string &imageId)
151 {
152     MediaLibraryCommand cmd(OperationObject::FILESYSTEM_PHOTO, OperationType::QUERY);
153     string where = PhotoColumn::PHOTO_ID + " = ? ";
154     vector<string> whereArgs { imageId };
155     cmd.GetAbsRdbPredicates()->SetWhereClause(where);
156     cmd.GetAbsRdbPredicates()->SetWhereArgs(whereArgs);
157     vector<string> columns { MediaColumn::MEDIA_ID, MediaColumn::MEDIA_FILE_PATH, PhotoColumn::PHOTO_EDIT_TIME,
158         PhotoColumn::MEDIA_NAME, MediaColumn::MEDIA_MIME_TYPE, PhotoColumn::PHOTO_SUBTYPE, PhotoColumn::PHOTO_IS_TEMP,
159         PhotoColumn::PHOTO_ORIENTATION, PhotoColumn::MEDIA_TYPE, MediaColumn::MEDIA_DATE_TRASHED };
160     return DatabaseAdapter::Query(cmd, columns);
161 }
162 
OnError(const string & imageId,const DpsErrorCode error)163 void MultiStagesCaptureDeferredPhotoProcSessionCallback::OnError(const string &imageId, const DpsErrorCode error)
164 {
165     switch (error) {
166         case ERROR_SESSION_SYNC_NEEDED:
167             MultiStagesPhotoCaptureManager::GetInstance().SyncWithDeferredProcSession();
168             break;
169         case ERROR_IMAGE_PROC_INVALID_PHOTO_ID:
170         case ERROR_IMAGE_PROC_FAILED: {
171             MultiStagesPhotoCaptureManager::GetInstance().RemoveImage(imageId, false);
172             UpdatePhotoQuality(imageId);
173             MEDIA_ERR_LOG("error %{public}d, photoid: %{public}s", static_cast<int32_t>(error), imageId.c_str());
174             break;
175         }
176         case ERROR_IMAGE_PROC_ABNORMAL: {
177             auto resultSet = QueryPhotoData(imageId);
178             if (resultSet == nullptr || resultSet->GoToFirstRow() != E_OK) {
179                 MEDIA_INFO_LOG("result set is empty.");
180                 return;
181             }
182             NotifyIfTempFile(resultSet, true);
183             break;
184         }
185         default:
186             break;
187     }
188 
189     if (error != ERROR_SESSION_SYNC_NEEDED) {
190         int32_t mediaType = (MultiStagesCaptureManager::QuerySubType(imageId) ==
191             static_cast<int32_t>(PhotoSubType::MOVING_PHOTO)) ?
192             static_cast<int32_t>(MultiStagesCaptureMediaType::MOVING_PHOTO_IMAGE) :
193             static_cast<int32_t>(MultiStagesCaptureMediaType::IMAGE);
194         MultiStagesCaptureDfxResult::Report(imageId, static_cast<int32_t>(error), mediaType);
195     }
196     CallProcessImageDone(false, imageId);
197 }
198 
ProcessAndSaveHighQualityImage(const std::string & imageId,std::shared_ptr<Media::Picture> picture,std::shared_ptr<NativeRdb::ResultSet> resultSet,uint32_t cloudImageEnhanceFlag,int32_t modifyType)199 void MultiStagesCaptureDeferredPhotoProcSessionCallback::ProcessAndSaveHighQualityImage(
200     const std::string& imageId, std::shared_ptr<Media::Picture> picture,
201     std::shared_ptr<NativeRdb::ResultSet> resultSet, uint32_t cloudImageEnhanceFlag, int32_t modifyType)
202 {
203     bool cond = (resultSet == nullptr || resultSet->GoToFirstRow() != E_OK);
204     CHECK_AND_RETURN_LOG(!cond, "resultset is empty.");
205 
206     string data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
207     bool isEdited = (GetInt64Val(PhotoColumn::PHOTO_EDIT_TIME, resultSet) > 0);
208     int32_t fileId = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
209     string mimeType = GetStringVal(MediaColumn::MEDIA_MIME_TYPE, resultSet);
210     bool isMovingPhoto = (GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet) ==
211         static_cast<int32_t>(PhotoSubType::MOVING_PHOTO));
212     int32_t mediaType = isMovingPhoto ? static_cast<int32_t>(MultiStagesCaptureMediaType::MOVING_PHOTO_IMAGE) :
213         static_cast<int32_t>(MultiStagesCaptureMediaType::IMAGE);
214     int32_t orientation = GetInt32Val(PhotoColumn::PHOTO_ORIENTATION, resultSet);
215     if (orientation != 0) {
216         auto metadata = picture->GetExifMetadata();
217         CHECK_AND_RETURN_LOG(metadata != nullptr, "metadata is null");
218         auto imageSourceOrientation = ORIENTATION_MAP.find(orientation);
219         CHECK_AND_RETURN_LOG(imageSourceOrientation != ORIENTATION_MAP.end(),
220             "imageSourceOrientation value is invalid.");
221         metadata->SetValue(PHOTO_DATA_IMAGE_ORIENTATION, std::to_string(imageSourceOrientation->second));
222     }
223 
224     // 裸picture落盘处理
225     std::shared_ptr<Media::Picture> resultPicture = nullptr;
226     bool isTakeEffect = false;
227     int ret = MediaLibraryPhotoOperations::ProcessMultistagesPhotoForPicture(
228         isEdited, data, picture, fileId, mimeType, resultPicture, isTakeEffect);
229     if (ret != E_OK) {
230         MEDIA_ERR_LOG("Save high quality image failed. ret: %{public}d, errno: %{public}d", ret, errno);
231         MultiStagesCaptureDfxResult::Report(imageId,
232             static_cast<int32_t>(MultiStagesCaptureResultErrCode::SAVE_IMAGE_FAIL), mediaType);
233         return;
234     }
235 
236     MultiStagesPhotoCaptureManager::GetInstance().DealHighQualityPicture(
237         imageId, std::move(picture), isEdited, isTakeEffect);
238     UpdateHighQualityPictureInfo(imageId, cloudImageEnhanceFlag, modifyType);
239     MediaLibraryObjectUtils::ScanFileAsync(
240         data, to_string(fileId), MediaLibraryApi::API_10, isMovingPhoto, resultPicture);
241     NotifyIfTempFile(resultSet);
242 
243     MultiStagesCaptureDfxTotalTime::GetInstance().Report(imageId, mediaType);
244     MultiStagesCaptureDfxResult::Report(imageId,
245         static_cast<int32_t>(MultiStagesCaptureResultErrCode::SUCCESS), mediaType);
246     if (isMovingPhoto) {
247         MultiStagesMovingPhotoCaptureManager::AddVideoFromMovingPhoto(imageId);
248     }
249     MEDIA_INFO_LOG("MultistagesCapture yuv success photoid: %{public}s", imageId.c_str());
250 }
251 
GetPictureFromPictureIntf(std::shared_ptr<CameraStandard::PictureIntf> pictureIntf)252 std::shared_ptr<Media::Picture> GetPictureFromPictureIntf(std::shared_ptr<CameraStandard::PictureIntf> pictureIntf)
253 {
254     if (pictureIntf == nullptr) {
255         return nullptr;
256     }
257     auto pictureAdapter = reinterpret_cast<CameraStandard::PictureAdapter*>(pictureIntf.get());
258     if (pictureAdapter == nullptr) {
259         return nullptr;
260     }
261     return pictureAdapter->GetPicture();
262 }
263 
OnProcessImageDone(const std::string & imageId,std::shared_ptr<CameraStandard::PictureIntf> pictureIntf,uint32_t cloudImageEnhanceFlag)264 void MultiStagesCaptureDeferredPhotoProcSessionCallback::OnProcessImageDone(const std::string &imageId,
265     std::shared_ptr<CameraStandard::PictureIntf> pictureIntf, uint32_t cloudImageEnhanceFlag)
266 {
267     MediaLibraryTracer tracer;
268     tracer.Start("OnProcessImageDone " + imageId);
269     std::shared_ptr<Media::Picture> picture = GetPictureFromPictureIntf(pictureIntf);
270     if (picture == nullptr || picture->GetMainPixel() == nullptr) {
271         tracer.Finish();
272         MEDIA_ERR_LOG("MultistagesCapture picture is null");
273         return;
274     }
275     // 1. 分段式拍照已经处理完成,保存全质量图
276     MEDIA_INFO_LOG("MultistagesCapture yuv photoid: %{public}s, cloudImageEnhanceFlag: %{public}u enter",
277         imageId.c_str(), cloudImageEnhanceFlag);
278     tracer.Start("Query");
279     auto resultSet = QueryPhotoData(imageId);
280     if (resultSet == nullptr || resultSet->GoToFirstRow() != E_OK) {
281         tracer.Finish();
282         MEDIA_INFO_LOG("result set is empty.");
283         // 高质量图先上来,直接保存
284         MultiStagesPhotoCaptureManager::GetInstance().DealHighQualityPicture(imageId, std::move(picture), false, false);
285         MultiStagesCaptureDfxTotalTime::GetInstance().RemoveStartTime(imageId);
286         // When subType query failed, default mediaType is Image
287         MultiStagesCaptureDfxResult::Report(imageId, static_cast<int32_t>(MultiStagesCaptureResultErrCode::SQL_ERR),
288             static_cast<int32_t>(MultiStagesCaptureMediaType::IMAGE));
289         return;
290     }
291     tracer.Finish();
292     int32_t isTemp = GetInt32Val(PhotoColumn::PHOTO_IS_TEMP, resultSet);
293     bool isEdited = (GetInt64Val(PhotoColumn::PHOTO_EDIT_TIME, resultSet) > 0);
294     bool isTrashed = (GetInt64Val(MediaColumn::MEDIA_DATE_TRASHED, resultSet) > 0);
295     int32_t modifyType = isEdited ? static_cast<int32_t>(FirstStageModifyType::EDITED) :
296         (isTrashed ? static_cast<int32_t>(FirstStageModifyType::TRASHED) :
297             static_cast<int32_t>(FirstStageModifyType::NOT_MODIFIED));
298     if (isTemp) {
299         MEDIA_INFO_LOG("MultistagesCapture, this picture is temp.");
300         MultiStagesPhotoCaptureManager::GetInstance().DealHighQualityPicture(imageId, std::move(picture), false, false);
301         UpdateHighQualityPictureInfo(imageId, cloudImageEnhanceFlag, modifyType);
302         return;
303     }
304     ProcessAndSaveHighQualityImage(imageId, picture, resultSet, cloudImageEnhanceFlag, modifyType);
305     CallProcessImageDone(true, imageId);
306 }
307 
GetCommandByImageId(const std::string & imageId,MediaLibraryCommand & cmd)308 void MultiStagesCaptureDeferredPhotoProcSessionCallback::GetCommandByImageId(const std::string &imageId,
309     MediaLibraryCommand &cmd)
310 {
311     size_t slashIndex = imageId.rfind("/");
312     string where = "";
313     vector<string> whereArgs;
314     if (slashIndex != string::npos) {
315         string fileId = MediaFileUtils::GetIdFromUri(imageId);
316         where = PhotoColumn::MEDIA_ID + " = ? ";
317         whereArgs = { fileId };
318     }
319     cmd.GetAbsRdbPredicates()->SetWhereClause(where);
320     cmd.GetAbsRdbPredicates()->SetWhereArgs(whereArgs);
321 }
322 
UpdateHighQualityPictureInfo(const std::string & imageId,uint32_t cloudImageEnhanceFlag,int32_t modifyType)323 void MultiStagesCaptureDeferredPhotoProcSessionCallback::UpdateHighQualityPictureInfo(const std::string &imageId,
324     uint32_t cloudImageEnhanceFlag, int32_t modifyType)
325 {
326     // 2. 更新数据库 photoQuality 到高质量
327     UpdatePhotoQuality(imageId);
328     // 3. update cloud enhancement avaiable
329     if (cloudImageEnhanceFlag) {
330         UpdateCEAvailable(imageId, cloudImageEnhanceFlag, modifyType);
331     }
332 }
333 
334 
OnDeliveryLowQualityImage(const std::string & imageId,std::shared_ptr<PictureIntf> pictureIntf)335 void MultiStagesCaptureDeferredPhotoProcSessionCallback::OnDeliveryLowQualityImage(const std::string &imageId,
336     std::shared_ptr<PictureIntf> pictureIntf)
337 {
338     MEDIA_INFO_LOG("MultistagesCapture photoid: %{public}s", imageId.c_str());
339     std::shared_ptr<Media::Picture> picture = GetPictureFromPictureIntf(pictureIntf);
340     if (picture != nullptr && picture->GetMainPixel() != nullptr) {
341         MEDIA_INFO_LOG("MultistagesCapture picture is not null");
342     } else {
343         MEDIA_INFO_LOG("MultistagesCapture picture is null");
344         return;
345     }
346     MediaLibraryTracer tracer;
347     tracer.Start("OnDeliveryLowQualityImage " + imageId);
348     MediaLibraryCommand cmd(OperationObject::FILESYSTEM_PHOTO, OperationType::QUERY);
349     GetCommandByImageId(imageId, cmd);
350     vector<string> columns { MediaColumn::MEDIA_ID, MediaColumn::MEDIA_FILE_PATH, PhotoColumn::PHOTO_EDIT_TIME,
351         PhotoColumn::PHOTO_SUBTYPE, PhotoColumn::PHOTO_ID};
352     tracer.Start("Query");
353     auto resultSet = DatabaseAdapter::Query(cmd, columns);
354     if (resultSet == nullptr || resultSet->GoToFirstRow() != E_OK) {
355         tracer.Finish();
356         MEDIA_INFO_LOG("MultistagesCapture result set is empty");
357         return;
358     }
359     tracer.Finish();
360     string photoId = GetStringVal(PhotoColumn::PHOTO_ID, resultSet);
361     string data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
362     bool isEdited = (GetInt64Val(PhotoColumn::PHOTO_EDIT_TIME, resultSet) > 0);
363     resultSet->Close();
364     MultiStagesPhotoCaptureManager::GetInstance().DealLowQualityPicture(photoId, std::move(picture), isEdited);
365     MEDIA_INFO_LOG("MultistagesCapture save low quality image end");
366 }
367 
OnProcessImageDone(const string & imageId,const uint8_t * addr,const long bytes,uint32_t cloudImageEnhanceFlag)368 void MultiStagesCaptureDeferredPhotoProcSessionCallback::OnProcessImageDone(const string &imageId, const uint8_t *addr,
369     const long bytes, uint32_t cloudImageEnhanceFlag)
370 {
371     CHECK_AND_RETURN_LOG((addr != nullptr) && (bytes != 0), "addr is nullptr or bytes(%{public}ld) is 0", bytes);
372     CHECK_AND_RETURN_LOG(MultiStagesCaptureRequestTaskManager::IsPhotoInProcess(imageId),
373         "this photo was delete or err photoId: %{public}s", imageId.c_str());
374     MediaLibraryTracer tracer;
375     tracer.Start("OnProcessImageDone " + imageId);
376 
377     // 1. 分段式拍照已经处理完成,保存全质量图
378     MEDIA_INFO_LOG("photoid: %{public}s, bytes: %{public}ld, cloudImageEnhanceFlag: %{public}u enter",
379         imageId.c_str(), bytes, cloudImageEnhanceFlag);
380     tracer.Start("Query");
381     auto resultSet = QueryPhotoData(imageId);
382     if (resultSet == nullptr || resultSet->GoToFirstRow() != E_OK) {
383         tracer.Finish();
384         MEDIA_INFO_LOG("result set is empty");
385         MultiStagesCaptureDfxTotalTime::GetInstance().RemoveStartTime(imageId);
386         // When subTyoe query failed, default mediaType is Image
387         MultiStagesCaptureDfxResult::Report(imageId, static_cast<int32_t>(MultiStagesCaptureResultErrCode::SQL_ERR),
388             static_cast<int32_t>(MultiStagesCaptureMediaType::IMAGE));
389         return;
390     }
391     tracer.Finish();
392     string data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
393     bool isEdited = (GetInt64Val(PhotoColumn::PHOTO_EDIT_TIME, resultSet) > 0);
394     bool isTrashed = (GetInt64Val(MediaColumn::MEDIA_DATE_TRASHED, resultSet) > 0);
395     int32_t modifyType = isEdited ? static_cast<int32_t>(FirstStageModifyType::EDITED) :
396         (isTrashed ? static_cast<int32_t>(FirstStageModifyType::TRASHED) :
397             static_cast<int32_t>(FirstStageModifyType::NOT_MODIFIED));
398     int32_t fileId = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
399     bool isMovingPhoto = (GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet) ==
400         static_cast<int32_t>(PhotoSubType::MOVING_PHOTO));
401     int32_t mediaType = isMovingPhoto ? static_cast<int32_t>(MultiStagesCaptureMediaType::MOVING_PHOTO_IMAGE) :
402         static_cast<int32_t>(MultiStagesCaptureMediaType::IMAGE);
403     int ret = MediaLibraryPhotoOperations::ProcessMultistagesPhoto(isEdited, data, addr, bytes, fileId);
404     if (ret != E_OK) {
405         MEDIA_ERR_LOG("Save high quality image failed. ret: %{public}d, errno: %{public}d", ret, errno);
406         MultiStagesCaptureDfxResult::Report(imageId,
407             static_cast<int32_t>(MultiStagesCaptureResultErrCode::SAVE_IMAGE_FAIL), mediaType);
408         return;
409     }
410 
411     UpdateHighQualityPictureInfo(imageId, cloudImageEnhanceFlag, modifyType);
412 
413     MediaLibraryObjectUtils::ScanFileAsync(data, to_string(fileId), MediaLibraryApi::API_10, isMovingPhoto);
414     NotifyIfTempFile(resultSet);
415 
416     MultiStagesCaptureDfxTotalTime::GetInstance().Report(imageId, mediaType);
417     MultiStagesCaptureDfxResult::Report(imageId,
418         static_cast<int32_t>(MultiStagesCaptureResultErrCode::SUCCESS), mediaType);
419 
420     // delete raw file
421     MultiStagesPhotoCaptureManager::GetInstance().RemoveImage(imageId, false);
422 
423     if (isMovingPhoto) {
424         MultiStagesMovingPhotoCaptureManager::AddVideoFromMovingPhoto(imageId);
425     }
426     CallProcessImageDone(true, imageId);
427     MEDIA_INFO_LOG("success photoid: %{public}s", imageId.c_str());
428 }
429 
OnStateChanged(const DpsStatusCode state)430 void MultiStagesCaptureDeferredPhotoProcSessionCallback::OnStateChanged(const DpsStatusCode state)
431 {
432     MEDIA_INFO_LOG("OnStateChanged, status: %{public}d", state);
433 #ifdef MEDIALIBRARY_FEATURE_CLOUD_ENHANCEMENT
434     EnhancementManager::GetInstance().HandleStateChangedOperation(state == DpsStatusCode::SESSION_STATE_IDLE);
435 #endif
436 }
437 
SetProcessImageDoneCallback(const ProcessDoneHandler & func)438 void MultiStagesCaptureDeferredPhotoProcSessionCallback::SetProcessImageDoneCallback(const ProcessDoneHandler &func)
439 {
440     processDoneCallback_ = func;
441 }
442 
CallProcessImageDone(bool success,const std::string & photoId)443 void MultiStagesCaptureDeferredPhotoProcSessionCallback::CallProcessImageDone(bool success, const std::string &photoId)
444 {
445     if (processDoneCallback_ != nullptr) {
446         processDoneCallback_(success, photoId);
447     }
448 }
449 } // namespace Media
450 } // namespace OHOS