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