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