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