• 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 "PhotoAssetProxy"
17 
18 #include <cstdint>
19 #include <string>
20 #include <sstream>
21 
22 #include "media_photo_asset_proxy.h"
23 
24 #include "datashare_abs_result_set.h"
25 #include "datashare_predicates.h"
26 #include "fetch_result.h"
27 #include "media_file_utils.h"
28 #include "media_log.h"
29 #include "medialibrary_errno.h"
30 #include "image_packer.h"
31 #include "media_column.h"
32 #include "datashare_values_bucket.h"
33 #include "media_file_uri.h"
34 #include "medialibrary_tracer.h"
35 #include "userfilemgr_uri.h"
36 #include "datashare_helper.h"
37 #include "media_exif.h"
38 
39 using namespace std;
40 
41 namespace OHOS {
42 namespace Media {
43 const string API_VERSION = "api_version";
44 const string SAVE_PICTURE = "save_picture";
45 const double TIMER_MULTIPLIER = 60.0;
46 const std::unordered_map<CameraShotType, PhotoSubType> CAMERASHOT_TO_SUBTYPE_MAP = {
47     {CameraShotType::MOVING_PHOTO, PhotoSubType::MOVING_PHOTO},
48     {CameraShotType::BURST, PhotoSubType::BURST},
49     {CameraShotType::IMAGE, PhotoSubType::CAMERA},
50     {CameraShotType::VIDEO, PhotoSubType::CAMERA},
51 };
PhotoAssetProxy()52 PhotoAssetProxy::PhotoAssetProxy() {}
53 
PhotoAssetProxy(shared_ptr<DataShare::DataShareHelper> dataShareHelper,CameraShotType cameraShotType,uint32_t callingUid,int32_t userId)54 PhotoAssetProxy::PhotoAssetProxy(shared_ptr<DataShare::DataShareHelper> dataShareHelper, CameraShotType cameraShotType,
55     uint32_t callingUid, int32_t userId)
56 {
57     dataShareHelper_ = dataShareHelper;
58     cameraShotType_ = cameraShotType;
59     callingUid_ = callingUid;
60     userId_ = userId;
61     auto itr = CAMERASHOT_TO_SUBTYPE_MAP.find(cameraShotType);
62     if (itr == CAMERASHOT_TO_SUBTYPE_MAP.end()) {
63         subType_ = PhotoSubType::CAMERA;
64     } else {
65         subType_ = itr->second;
66     }
67     MEDIA_INFO_LOG("init success, shottype: %{public}d, callingUid: %{public}d, userid: %{public}d",
68         static_cast<int32_t>(cameraShotType), callingUid, userId);
69 }
70 
~PhotoAssetProxy()71 PhotoAssetProxy::~PhotoAssetProxy()
72 {
73     if (cameraShotType_ == CameraShotType::MOVING_PHOTO && !isMovingPhotoVideoSaved_) {
74         if (dataShareHelper_ == nullptr) {
75             MEDIA_WARN_LOG("datashareHelper is nullptr");
76             return;
77         }
78         string uri = PAH_DEGENERATE_MOVING_PHOTO;
79         MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
80         Uri updateUri(uri);
81         DataShare::DataSharePredicates predicates;
82         DataShare::DataShareValuesBucket valuesBucket;
83         string fileId = MediaFileUtils::GetIdFromUri(uri_);
84         predicates.EqualTo(MediaColumn::MEDIA_ID, fileId);
85         valuesBucket.Put(PhotoColumn::PHOTO_SUBTYPE, static_cast<int32_t>(PhotoSubType::DEFAULT));
86         int32_t changeRows = dataShareHelper_->Update(updateUri, predicates, valuesBucket);
87         MEDIA_WARN_LOG("Degenerate moving photo: %{public}s, ret: %{public}d", fileId.c_str(), changeRows);
88     }
89 }
90 
91 // 调用之前,必须先AddPhotoProxy,否则无法获取FileAsset对象
GetFileAsset()92 unique_ptr<FileAsset> PhotoAssetProxy::GetFileAsset()
93 {
94     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, nullptr,
95         "Failed to create Asset, datashareHelper is nullptr");
96     string uri = PAH_QUERY_PHOTO;
97     MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
98     Uri queryUri(uri);
99     DataShare::DataSharePredicates predicates;
100     predicates.EqualTo(MediaColumn::MEDIA_ID, fileId_);
101     DataShare::DatashareBusinessError businessError;
102     vector<string> columns;
103 
104     auto resultSet = dataShareHelper_->Query(queryUri, predicates, columns, &businessError);
105     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, nullptr, "Failed to query asset, fileId_: %{public}d", fileId_);
106     auto fetchResult = make_unique<FetchResult<FileAsset>>(resultSet);
107     CHECK_AND_RETURN_RET_LOG(fetchResult != nullptr, nullptr, "fetchResult is nullptr, %{public}d", fileId_);
108 
109     unique_ptr<FileAsset> fileAsset = fetchResult->GetFirstObject();
110     if (fileAsset != nullptr) {
111         fileAsset->SetResultNapiType(ResultNapiType::TYPE_PHOTOACCESS_HELPER);
112     }
113     return fileAsset;
114 }
115 
GetPhotoAssetUri()116 string PhotoAssetProxy::GetPhotoAssetUri()
117 {
118     return uri_;
119 }
120 
HandleAssetValues(const sptr<PhotoProxy> & photoProxy,const string & displayName,const MediaType & mediaType)121 DataShare::DataShareValuesBucket PhotoAssetProxy::HandleAssetValues(const sptr<PhotoProxy> &photoProxy,
122     const string &displayName, const MediaType &mediaType)
123 {
124     DataShare::DataShareValuesBucket values;
125     values.Put(MediaColumn::MEDIA_NAME, displayName);
126     values.Put(MediaColumn::MEDIA_TYPE, static_cast<int32_t>(mediaType));
127     if (cameraShotType_ == CameraShotType::MOVING_PHOTO) {
128         values.Put(PhotoColumn::PHOTO_SUBTYPE, static_cast<int32_t>(PhotoSubType::MOVING_PHOTO));
129         values.Put(PhotoColumn::STAGE_VIDEO_TASK_STATUS, static_cast<int32_t>(StageVideoTaskStatus::NEED_TO_STAGE));
130     }
131     if (cameraShotType_ == CameraShotType::BURST) {
132         values.Put(PhotoColumn::PHOTO_SUBTYPE, static_cast<int32_t>(PhotoSubType::BURST));
133         values.Put(PhotoColumn::PHOTO_BURST_KEY, photoProxy->GetBurstKey());
134         values.Put(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
135             photoProxy->IsCoverPhoto() ? static_cast<int32_t>(BurstCoverLevelType::COVER)
136                                        : static_cast<int32_t>(BurstCoverLevelType::MEMBER));
137         values.Put(PhotoColumn::PHOTO_DIRTY, -1);
138     }
139     values.Put(MEDIA_DATA_CALLING_UID, static_cast<int32_t>(callingUid_));
140     values.Put(PhotoColumn::PHOTO_IS_TEMP, true);
141     if (photoProxy->GetCloudImageEnhanceFlag() != static_cast<uint32_t>(CloudEnhancementAvailableType::NOT_SUPPORT) &&
142         photoProxy->GetPhotoId().size() > 0) {
143         values.Put(PhotoColumn::PHOTO_CE_AVAILABLE, static_cast<int32_t>(photoProxy->GetCloudImageEnhanceFlag()));
144         values.Put(PhotoColumn::PHOTO_ID, photoProxy->GetPhotoId());
145     }
146 
147     if (photoProxy->GetPhotoQuality() == PhotoQuality::LOW ||
148         (photoProxy->GetFormat() == PhotoFormat::YUV && subType_ != PhotoSubType::BURST)) {
149         values.Put(PhotoColumn::PHOTO_DEFERRED_PROC_TYPE, static_cast<int32_t>(photoProxy->GetDeferredProcType()));
150         values.Put(PhotoColumn::PHOTO_SUBTYPE, static_cast<int32_t>(cameraShotType_));
151         values.Put(PhotoColumn::PHOTO_QUALITY, static_cast<int32_t>(photoProxy->GetPhotoQuality()));
152         SetPhotoIdForAsset(photoProxy, values);
153     }
154     return values;
155 }
156 
CreatePhotoAsset(const sptr<PhotoProxy> & photoProxy)157 void PhotoAssetProxy::CreatePhotoAsset(const sptr<PhotoProxy> &photoProxy)
158 {
159     CHECK_AND_RETURN_LOG(dataShareHelper_ != nullptr, "Failed to create Asset, datashareHelper is nullptr");
160     CHECK_AND_RETURN_LOG(!(photoProxy->GetTitle().empty()), "Failed to create Asset, displayName is empty");
161     bool cond = (cameraShotType_ == CameraShotType::BURST && photoProxy->GetBurstKey().empty());
162     CHECK_AND_RETURN_LOG(!cond, "Failed to create Asset, burstKey is empty when CameraShotType::BURST");
163 
164     string displayName = photoProxy->GetTitle() + "." + photoProxy->GetExtension();
165     MediaType mediaType = MediaFileUtils::GetMediaType(displayName);
166     cond = ((mediaType != MEDIA_TYPE_IMAGE) && (mediaType != MEDIA_TYPE_VIDEO));
167     CHECK_AND_RETURN_LOG(!cond,
168         "Failed to create Asset, invalid file type %{public}d", static_cast<int32_t>(mediaType));
169     DataShare::DataShareValuesBucket values = HandleAssetValues(photoProxy, displayName, mediaType);
170     string uri = PAH_CREATE_PHOTO;
171     MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
172     Uri createUri(uri);
173     fileId_ = dataShareHelper_->InsertExt(createUri, values, uri_);
174     CHECK_AND_RETURN_LOG(fileId_ >= 0, "Failed to create Asset, insert database error!");
175     MEDIA_INFO_LOG(
176         "MultistagesCapture Success, photoId: %{public}s, fileId: %{public}d, uri: %{public}s, burstKey: %{public}s "
177         "ceAvailable: %{public}u", photoProxy->GetPhotoId().c_str(), fileId_, uri_.c_str(),
178         photoProxy->GetBurstKey().c_str(), photoProxy->GetCloudImageEnhanceFlag());
179 }
180 
isHighQualityPhotoExist(string uri)181 static bool isHighQualityPhotoExist(string uri)
182 {
183     string filePath = MediaFileUri::GetPathFromUri(uri, true);
184     string filePathTemp = filePath + ".high";
185     return MediaFileUtils::IsFileExists(filePathTemp) || MediaFileUtils::IsFileExists(filePath);
186 }
187 
SetPhotoIdForAsset(const sptr<PhotoProxy> & photoProxy,DataShare::DataShareValuesBucket & values)188 void PhotoAssetProxy::SetPhotoIdForAsset(const sptr<PhotoProxy> &photoProxy, DataShare::DataShareValuesBucket &values)
189 {
190     if (photoProxy->GetPhotoId() == "") {
191         stringstream result;
192         string displayName = photoProxy->GetTitle();
193         for (size_t i = 0; i < displayName.length(); i++) {
194             if (isdigit(displayName[i])) {
195                 result << displayName[i];
196             }
197         }
198         values.Put(PhotoColumn::PHOTO_ID, result.str());
199     } else {
200         values.Put(PhotoColumn::PHOTO_ID, photoProxy->GetPhotoId());
201     }
202 }
203 
CloseFd(const shared_ptr<DataShare::DataShareHelper> & dataShareHelper,const string & uri,const int32_t fd)204 int32_t CloseFd(const shared_ptr<DataShare::DataShareHelper> &dataShareHelper, const string &uri, const int32_t fd)
205 {
206     MediaLibraryTracer tracer;
207     tracer.Start("CloseFd");
208 
209     int32_t retVal = E_FAIL;
210     DataShare::DataShareValuesBucket valuesBucket;
211     valuesBucket.Put(MEDIA_DATA_DB_URI, uri);
212 
213     if (dataShareHelper != nullptr) {
214         string uriStr = PAH_SCAN_WITHOUT_ALBUM_UPDATE;
215         MediaFileUtils::UriAppendKeyValue(uriStr, API_VERSION, to_string(MEDIA_API_VERSION_V10));
216         Uri closeAssetUri(uriStr);
217 
218         if (close(fd) == E_SUCCESS) {
219             retVal = dataShareHelper->Insert(closeAssetUri, valuesBucket);
220         }
221         CHECK_AND_PRINT_LOG(retVal != E_FAIL, "Failed to close the file");
222     }
223 
224     return retVal;
225 }
226 
SaveImage(int fd,const string & uri,const string & photoId,void * output,size_t writeSize)227 int PhotoAssetProxy::SaveImage(int fd, const string &uri, const string &photoId, void *output, size_t writeSize)
228 {
229     MediaLibraryTracer tracer;
230     tracer.Start("SaveImage");
231     CHECK_AND_RETURN_RET_LOG(fd > 0, E_ERR, "invalid fd");
232     if (isHighQualityPhotoExist(uri)) {
233         MEDIA_INFO_LOG("high quality photo exists, discard low quality photo. photoId: %{public}s", photoId.c_str());
234         return E_OK;
235     }
236 
237     int ret = write(fd, output, writeSize);
238     CHECK_AND_RETURN_RET_LOG(ret >= 0, ret, "write err %{public}d", errno);
239     MEDIA_INFO_LOG("Save Low Quality file Success, photoId: %{public}s, size: %{public}zu, ret: %{public}d",
240         photoId.c_str(), writeSize, ret);
241     return E_OK;
242 }
243 
PackAndSaveImage(int fd,const string & uri,const sptr<PhotoProxy> & photoProxy)244 int PhotoAssetProxy::PackAndSaveImage(int fd, const string &uri, const sptr<PhotoProxy> &photoProxy)
245 {
246     MediaLibraryTracer tracer;
247     tracer.Start("PackAndSaveImage");
248 
249     void *imageAddr = photoProxy->GetFileDataAddr();
250     size_t imageSize = photoProxy->GetFileSize();
251     bool cond = (imageAddr == nullptr || imageSize == 0);
252     CHECK_AND_RETURN_RET_LOG(!cond, E_ERR, "imageAddr is nullptr or imageSize(%{public}zu)==0", imageSize);
253 
254     MEDIA_DEBUG_LOG("start pack PixelMap");
255     Media::InitializationOptions opts;
256     opts.pixelFormat = Media::PixelFormat::RGBA_8888;
257     opts.size = {
258         .width = photoProxy->GetWidth(),
259         .height = photoProxy->GetHeight()
260     };
261 
262     auto pixelMap = Media::PixelMap::Create(opts);
263     CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, E_ERR, "Create pixelMap failed.");
264     pixelMap->SetPixelsAddr(imageAddr, nullptr, imageSize, Media::AllocatorType::SHARE_MEM_ALLOC, nullptr);
265     auto pixelSize = static_cast<uint32_t>(pixelMap->GetByteCount());
266     CHECK_AND_RETURN_RET_LOG(pixelSize != 0, E_ERR, "pixel size is 0.");
267 
268     // encode rgba to jpeg
269     auto buffer = new (std::nothrow) uint8_t[pixelSize];
270     CHECK_AND_RETURN_RET_LOG(buffer != nullptr, E_ERR, "Failed to new buffer");
271     int64_t packedSize = 0L;
272     Media::ImagePacker imagePacker;
273     Media::PackOption packOption;
274     packOption.format = "image/jpeg";
275     imagePacker.StartPacking(buffer, pixelSize, packOption);
276     imagePacker.AddImage(*pixelMap);
277     uint32_t packResult = imagePacker.FinalizePacking(packedSize);
278     if (packResult != E_OK || buffer == nullptr) {
279         MEDIA_ERR_LOG("packet pixelMap failed packResult: %{public}d", packResult);
280         delete[] buffer;
281         return E_ERR;
282     }
283     MEDIA_INFO_LOG("pack pixelMap success, packedSize: %{public}" PRId64, packedSize);
284 
285     auto ret = SaveImage(fd, uri, photoProxy->GetPhotoId(), buffer, packedSize);
286     SetShootingModeAndGpsInfo(buffer, packedSize, photoProxy, fd);
287     delete[] buffer;
288     return ret;
289 }
290 
SetShootingModeAndGpsInfo(const uint8_t * data,uint32_t size,const sptr<PhotoProxy> & photoProxy,int fd)291 void PhotoAssetProxy::SetShootingModeAndGpsInfo(const uint8_t *data, uint32_t size,
292     const sptr<PhotoProxy> &photoProxy, int fd)
293 {
294     MediaLibraryTracer tracer;
295     tracer.Start("SetShootingModeAndGpsInfo");
296     int32_t shootingMode = photoProxy->GetShootingMode();
297     double latitude = photoProxy->GetLatitude();
298     double longitude = photoProxy->GetLongitude();
299     uint32_t errorCode = 0;
300     SourceOptions opts;
301     tracer.Start("CreateImageSource");
302     unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(data, size, opts, errorCode);
303     tracer.Finish();
304 
305     CHECK_AND_RETURN_LOG(imageSource != nullptr, "imageSource is nullptr");
306     uint32_t index = 0;
307     uint32_t ret = imageSource->ModifyImageProperty(index, PHOTO_DATA_IMAGE_ISO_SPEED_LATITUDE_ZZZ,
308         to_string(shootingMode));
309     CHECK_AND_PRINT_LOG(ret == E_OK, "modify image property shooting mode fail %{public}d", ret);
310 
311     ret = imageSource->ModifyImageProperty(index, PHOTO_DATA_IMAGE_GPS_LONGITUDE, LocationValueToString(longitude));
312     CHECK_AND_PRINT_LOG(ret == E_OK, "modify image property longitude fail %{public}d", ret);
313 
314     ret = imageSource->ModifyImageProperty(index, PHOTO_DATA_IMAGE_GPS_LONGITUDE_REF, longitude > 0.0 ? "E" : "W");
315     CHECK_AND_PRINT_LOG(ret == E_OK, "modify image property longitude ref fail %{public}d", ret);
316 
317     ret = imageSource->ModifyImageProperty(index, PHOTO_DATA_IMAGE_GPS_LATITUDE, LocationValueToString(latitude));
318     CHECK_AND_PRINT_LOG(ret == E_OK, "modify image property latitude fail %{public}d", ret);
319 
320     tracer.Start("ModifyImageProperty");
321     ret = imageSource->ModifyImageProperty(index, PHOTO_DATA_IMAGE_GPS_LATITUDE_REF, latitude > 0.0 ? "N" : "S", fd);
322     tracer.Finish();
323     CHECK_AND_PRINT_LOG(ret == E_OK, "modify image property latitude ref fail %{public}d", ret);
324     MEDIA_INFO_LOG("Success.");
325 }
326 
LocationValueToString(double value)327 std::string PhotoAssetProxy::LocationValueToString(double value)
328 {
329     string result = "";
330     double stringValue = value;
331     if (value < 0.0) {
332         stringValue = 0.0 - value;
333     }
334 
335     int degrees = static_cast<int32_t>(stringValue);
336     result = result + to_string(degrees) + ", ";
337     stringValue -= (double)degrees;
338     stringValue *= TIMER_MULTIPLIER;
339     int minutes = (int)stringValue;
340     result = result + to_string(minutes) + ", ";
341     stringValue -= (double)minutes;
342     stringValue *= TIMER_MULTIPLIER;
343     result = result + to_string(stringValue);
344     return result;
345 }
346 
AddProcessImage(shared_ptr<DataShare::DataShareHelper> & dataShareHelper,const sptr<PhotoProxy> & photoProxy,int32_t fileId,int32_t subType)347 int32_t PhotoAssetProxy::AddProcessImage(shared_ptr<DataShare::DataShareHelper> &dataShareHelper,
348     const sptr<PhotoProxy> &photoProxy, int32_t fileId, int32_t subType)
349 {
350     string uri = PAH_ADD_IMAGE;
351     MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
352     if (photoProxy->GetFormat() == PhotoFormat::YUV) {
353         MediaFileUtils::UriAppendKeyValue(uri, SAVE_PICTURE, OPRN_ADD_LOWQUALITY_IMAGE);
354     }
355     Uri updateAssetUri(uri);
356     DataShare::DataSharePredicates predicates;
357     predicates.SetWhereClause(MediaColumn::MEDIA_ID + " = ? ");
358     predicates.SetWhereArgs({ to_string(fileId) });
359 
360     DataShare::DataShareValuesBucket valuesBucket;
361     SetPhotoIdForAsset(photoProxy, valuesBucket);
362     valuesBucket.Put(PhotoColumn::PHOTO_DEFERRED_PROC_TYPE, static_cast<int32_t>(photoProxy->GetDeferredProcType()));
363     valuesBucket.Put(MediaColumn::MEDIA_ID, fileId);
364     valuesBucket.Put(PhotoColumn::PHOTO_SUBTYPE, static_cast<int32_t>(subType));
365     valuesBucket.Put(PhotoColumn::PHOTO_QUALITY, static_cast<int32_t>(photoProxy->GetPhotoQuality()));
366 
367     int32_t changeRows = dataShareHelper->Update(updateAssetUri, predicates, valuesBucket);
368     CHECK_AND_PRINT_LOG(changeRows >= 0, "update fail, error: %{public}d", changeRows);
369     MEDIA_INFO_LOG("MultistagesCapture photoId: %{public}s, fileId: %{public}d",
370         photoProxy->GetPhotoId().c_str(), fileId);
371     return changeRows;
372 }
373 
SaveLowQualityPhoto(std::shared_ptr<DataShare::DataShareHelper> & dataShareHelper,const sptr<PhotoProxy> & photoProxy,int32_t fileId,int32_t subType)374 int PhotoAssetProxy::SaveLowQualityPhoto(std::shared_ptr<DataShare::DataShareHelper>  &dataShareHelper,
375     const sptr<PhotoProxy> &photoProxy, int32_t fileId, int32_t subType)
376 {
377     MediaLibraryTracer tracer;
378     tracer.Start("SaveLowQualityPhoto");
379     string uri = PAH_ADD_LOWQUALITY_IMAGE;
380     MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
381     Uri updateAssetUri(uri);
382     DataShare::DataSharePredicates predicates;
383     predicates.SetWhereClause(MediaColumn::MEDIA_ID + " = ? ");
384     predicates.SetWhereArgs({ to_string(fileId) });
385 
386     DataShare::DataShareValuesBucket valuesBucket;
387     valuesBucket.Put(PhotoColumn::PHOTO_ID, photoProxy->GetPhotoId());
388     valuesBucket.Put(PhotoColumn::PHOTO_DEFERRED_PROC_TYPE, static_cast<int32_t>(photoProxy->GetDeferredProcType()));
389     valuesBucket.Put(MediaColumn::MEDIA_ID, fileId);
390     valuesBucket.Put(PhotoColumn::PHOTO_SUBTYPE, static_cast<int32_t>(subType));
391     valuesBucket.Put(PhotoColumn::PHOTO_LATITUDE, photoProxy->GetLatitude());
392     valuesBucket.Put(PhotoColumn::PHOTO_LONGITUDE, photoProxy->GetLongitude());
393 
394     int32_t changeRows = dataShareHelper->Update(updateAssetUri, predicates, valuesBucket);
395     CHECK_AND_PRINT_LOG(changeRows >= 0, "update fail, error: %{public}d", changeRows);
396     MEDIA_INFO_LOG("photoId: %{public}s,", photoProxy->GetPhotoId().c_str());
397     photoProxy->Release();
398     return E_OK;
399 }
400 
DealWithLowQualityPhoto(shared_ptr<DataShare::DataShareHelper> & dataShareHelper,int fd,const string & uri,const sptr<PhotoProxy> & photoProxy)401 void PhotoAssetProxy::DealWithLowQualityPhoto(shared_ptr<DataShare::DataShareHelper> &dataShareHelper,
402     int fd, const string &uri, const sptr<PhotoProxy> &photoProxy)
403 {
404     MediaLibraryTracer tracer;
405     tracer.Start("DealWithLowQualityPhoto");
406     MEDIA_INFO_LOG("start photoId: %{public}s format: %{public}d, quality: %{public}d",
407         photoProxy->GetPhotoId().c_str(), photoProxy->GetFormat(), photoProxy->GetPhotoQuality());
408 
409     PhotoFormat photoFormat = photoProxy->GetFormat();
410     if (photoFormat == PhotoFormat::RGBA) {
411         PackAndSaveImage(fd, uri, photoProxy);
412     } else if (photoFormat == PhotoFormat::DNG) {
413         auto ret = SaveImage(fd, uri, photoProxy->GetPhotoId(), photoProxy->GetFileDataAddr(),
414             photoProxy->GetFileSize());
415         MEDIA_INFO_LOG("direct save dng file, ret: %{public}d", ret);
416     } else {
417         SaveImage(fd, uri, photoProxy->GetPhotoId(), photoProxy->GetFileDataAddr(), photoProxy->GetFileSize());
418     }
419     photoProxy->Release();
420     CloseFd(dataShareHelper, uri, fd);
421     MEDIA_INFO_LOG("end");
422 }
423 
AddPhotoProxy(const sptr<PhotoProxy> & photoProxy)424 void PhotoAssetProxy::AddPhotoProxy(const sptr<PhotoProxy> &photoProxy)
425 {
426     bool cond = (photoProxy == nullptr || dataShareHelper_ == nullptr);
427     CHECK_AND_RETURN_LOG(!cond, "input param invalid, photo proxy is nullptr");
428     MediaLibraryTracer tracer;
429     tracer.Start("PhotoAssetProxy::AddPhotoProxy " + photoProxy->GetPhotoId());
430     MEDIA_INFO_LOG("MultistagesCapture, photoId: %{public}s", photoProxy->GetPhotoId().c_str());
431     tracer.Start("PhotoAssetProxy CreatePhotoAsset");
432     CreatePhotoAsset(photoProxy);
433     CHECK_AND_RETURN_INFO_LOG(cameraShotType_ != CameraShotType::VIDEO, "MultistagesCapture exit for VIDEO");
434 
435     if (photoProxy->GetPhotoQuality() == PhotoQuality::LOW ||
436         (photoProxy->GetFormat() == PhotoFormat::YUV && subType_ != PhotoSubType::BURST)) {
437         AddProcessImage(dataShareHelper_, photoProxy, fileId_, static_cast<int32_t>(cameraShotType_));
438     }
439     if (photoProxy->GetFormat() == PhotoFormat::YUV) {
440         photoProxy->Release();
441         MEDIA_INFO_LOG("MultistagesCapture exit for YUV");
442         tracer.Finish();
443         return;
444     }
445     tracer.Finish();
446 
447     Uri openUri(uri_);
448     int fd = dataShareHelper_->OpenFile(openUri, MEDIA_FILEMODE_READWRITE);
449     CHECK_AND_RETURN_LOG(fd >= 0, "fd.Get() < 0 fd %{public}d status %{public}d", fd, errno);
450     DealWithLowQualityPhoto(dataShareHelper_, fd, uri_, photoProxy);
451     MEDIA_INFO_LOG("MultistagesCapture exit");
452 }
453 
GetVideoFd()454 int32_t PhotoAssetProxy::GetVideoFd()
455 {
456     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, E_ERR,
457         "Failed to read video of moving photo, datashareHelper is nullptr");
458     string videoUri = uri_;
459     MediaFileUtils::UriAppendKeyValue(videoUri, MEDIA_MOVING_PHOTO_OPRN_KEYWORD, CREATE_MOVING_PHOTO_VIDEO);
460     Uri openVideoUri(videoUri);
461     int32_t fd = dataShareHelper_->OpenFile(openVideoUri, MEDIA_FILEMODE_READWRITE);
462     MEDIA_INFO_LOG("GetVideoFd enter, video path: %{public}s, fd: %{public}d", videoUri.c_str(), fd);
463     return fd;
464 }
465 
NotifyVideoSaveFinished()466 void PhotoAssetProxy::NotifyVideoSaveFinished()
467 {
468     isMovingPhotoVideoSaved_ = true;
469     CHECK_AND_RETURN_LOG(dataShareHelper_ != nullptr, "datashareHelper is nullptr");
470     string uriStr = PAH_ADD_FILTERS;
471     Uri uri(uriStr);
472     DataShare::DataShareValuesBucket valuesBucket;
473     valuesBucket.Put(PhotoColumn::MEDIA_ID, fileId_);
474     valuesBucket.Put(NOTIFY_VIDEO_SAVE_FINISHED, uri_);
475     dataShareHelper_->Insert(uri, valuesBucket);
476     MEDIA_INFO_LOG("video save finished %{public}s", uri_.c_str());
477 }
478 } // Media
479 } // OHOS