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