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