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