1 /*
2 * Copyright (C) 2025 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 "Media_Cloud_Utils"
17
18 #include "cloud_media_sync_utils.h"
19
20 #include <algorithm>
21 #include <string>
22 #include <sys/time.h>
23 #include <utime.h>
24
25 #include "cloud_media_file_utils.h"
26 #include "exif_rotate_utils.h"
27 #include "media_file_utils.h"
28 #include "media_image_framework_utils.h"
29 #include "media_log.h"
30 #include "media_player_framework_utils.h"
31 #include "medialibrary_errno.h"
32 #include "medialibrary_type_const.h"
33 #include "cloud_media_sync_const.h"
34 #include "photo_file_utils.h"
35 #include "thumbnail_const.h"
36 #include "moving_photo_file_utils.h"
37 #include "cloud_media_uri_utils.h"
38
39 using namespace std;
40
41 namespace OHOS::Media::CloudSync {
FillPhotosDto(CloudSync::PhotosDto & photosDto,const std::string & path,const int32_t & orientation,const int32_t exifRotate,const int32_t & thumbState)42 int32_t CloudMediaSyncUtils::FillPhotosDto(
43 CloudSync::PhotosDto &photosDto, const std::string &path, const int32_t &orientation,
44 const int32_t exifRotate, const int32_t &thumbState)
45 {
46 MEDIA_INFO_LOG("FillPhotosDto enter %{public}s", path.c_str());
47 bool isRotation = orientation != ROTATE_ANGLE_0 || exifRotate > static_cast<int32_t>(ExifRotateType::TOP_LEFT);
48 std::string thumbSuffix = isRotation ? THUMBNAIL_THUMB_EX_SUFFIX : THUMBNAIL_THUMB_SUFFIX;
49 std::string lcdSuffix = isRotation ? THUMBNAIL_LCD_EX_SUFFIX : THUMBNAIL_LCD_SUFFIX;
50
51 std::string thumbLocalPath = GetThumbnailPath(path, thumbSuffix);
52 std::string lcdLocalPath = GetThumbnailPath(path, lcdSuffix);
53
54 /**
55 * oritentaion = 0 fieldKey = thumbnail/lcd attachmentPath = /storage/cloud/files/.thumbs/Photo/1/IMGxxx.jpg
56 * oritentaion != 0 fieldKey = thumbnail attachmentPath = /storage/cloud/files/.thumbs/Photo/1/IMGxxx.jpg/THM_EX
57 * oritentaion != 0 fieldKey = lcd attachmentPath = /storage/cloud/files/.thumbs/Photo/1/IMGxxx.jpg/LCD_EX
58 */
59 CloudSync::CloudFileDataDto dtoThm;
60 CloudMediaFileUtils::GetParentPathAndFilename(thumbLocalPath, dtoThm.path, dtoThm.fileName);
61 size_t thumbFileSize = 0;
62 CloudMediaFileUtils::GetFileSizeV2(thumbLocalPath, thumbFileSize);
63 dtoThm.size = static_cast<int64_t>(thumbFileSize);
64 photosDto.attachment["thumbnail"] = dtoThm;
65
66 CloudSync::CloudFileDataDto dtoLcd;
67 CloudMediaFileUtils::GetParentPathAndFilename(lcdLocalPath, dtoLcd.path, dtoLcd.fileName);
68 size_t lcdFileSize = 0;
69 CloudMediaFileUtils::GetFileSizeV2(lcdLocalPath, lcdFileSize);
70 dtoLcd.size = static_cast<int64_t>(lcdFileSize);
71 photosDto.attachment["lcd"] = dtoLcd;
72 MEDIA_INFO_LOG("FillPhotosDto end %{public}s", path.c_str());
73 return E_OK;
74 }
75
FillPhotosDto(CloudSync::PhotosDto & photosDto,const CloudSync::CloudMediaPullDataDto & data)76 int32_t CloudMediaSyncUtils::FillPhotosDto(
77 CloudSync::PhotosDto &photosDto, const CloudSync::CloudMediaPullDataDto &data)
78 {
79 constexpr uint64_t DEFAULT_SIZE = 2 * 1024 * 1024; // thumbnail and lcd default size is 2MB
80 bool isRotation = data.propertiesRotate != ROTATE_ANGLE_0 ||
81 data.exifRotate > static_cast<int32_t>(ExifRotateType::TOP_LEFT);
82 std::string thumbSuffix = isRotation ? THUMBNAIL_THUMB_EX_SUFFIX : THUMBNAIL_THUMB_SUFFIX;
83 std::string lcdSuffix = isRotation ? THUMBNAIL_LCD_EX_SUFFIX : THUMBNAIL_LCD_SUFFIX;
84
85 std::string thumbLocalPath = GetThumbnailPath(data.localPath, thumbSuffix);
86 std::string lcdLocalPath = GetThumbnailPath(data.localPath, lcdSuffix);
87
88 CloudSync::CloudFileDataDto dtoThm;
89 CloudMediaFileUtils::GetParentPathAndFilename(thumbLocalPath, dtoThm.path, dtoThm.fileName);
90 bool isValid = data.thmSize != 0 && data.lcdSize != 0;
91 CHECK_AND_PRINT_LOG(isValid, "invalid size, thmSize: %{public}" PRId64", lcdSize: %{public}" PRId64,
92 data.thmSize, data.lcdSize);
93 dtoThm.size = (data.thmSize <= 0) ? DEFAULT_SIZE : data.thmSize;
94 photosDto.attachment["thumbnail"] = dtoThm;
95
96 CloudSync::CloudFileDataDto dtoLcd;
97 CloudMediaFileUtils::GetParentPathAndFilename(lcdLocalPath, dtoLcd.path, dtoLcd.fileName);
98 dtoLcd.size = (data.lcdSize <= 0) ? DEFAULT_SIZE : data.lcdSize;
99 photosDto.attachment["lcd"] = dtoLcd;
100
101 return E_OK;
102 }
103
IsLocalDirty(int32_t dirty,bool isDelete)104 bool CloudMediaSyncUtils::IsLocalDirty(int32_t dirty, bool isDelete)
105 {
106 MEDIA_INFO_LOG("dirty: %{public}d, isDelete: %{public}d", dirty, static_cast<int32_t>(isDelete));
107 bool localDirty = (dirty == static_cast<int32_t>(DirtyType::TYPE_MDIRTY)) ||
108 (dirty == static_cast<int32_t>(DirtyType::TYPE_FDIRTY));
109 if (isDelete) {
110 return localDirty;
111 } else {
112 return localDirty || (dirty == static_cast<int32_t>(DirtyType::TYPE_DELETED));
113 }
114 }
115
FileIsLocal(const int32_t position)116 bool CloudMediaSyncUtils::FileIsLocal(const int32_t position)
117 {
118 MEDIA_INFO_LOG("position: %{public}d.", position);
119 return !!(static_cast<uint32_t>(position) & 1);
120 }
121
GetCloudPath(const std::string & path,const std::string & prefixCloud)122 std::string CloudMediaSyncUtils::GetCloudPath(const std::string &path, const std::string &prefixCloud)
123 {
124 std::string cloudPath;
125 if (path.find(prefixCloud) == 0) {
126 cloudPath = prefixCloud + path.substr(prefixCloud.size());
127 } else {
128 MEDIA_ERR_LOG("Failed to get cloud path: %{public}s", MediaFileUtils::DesensitizePath(path).c_str());
129 cloudPath = "";
130 }
131 return cloudPath;
132 }
133
GetThumbParentPath(const std::string & path,const std::string & prefixCloud)134 std::string CloudMediaSyncUtils::GetThumbParentPath(const std::string &path, const std::string &prefixCloud)
135 {
136 size_t pos = path.find(prefixCloud);
137 if (pos == std::string::npos) {
138 MEDIA_ERR_LOG("invalid path %{public}s", MediaFileUtils::DesensitizePath(path).c_str());
139 return "";
140 }
141 /* transform sandbox path to hmdfs local path*/
142 return "/storage/cloud/files/.thumbs" + path.substr(pos + prefixCloud.size());
143 }
144
RemoveThmParentPath(const std::string & path,const std::string & prefixCloud)145 void CloudMediaSyncUtils::RemoveThmParentPath(const std::string &path, const std::string &prefixCloud)
146 {
147 std::string thmPath = GetThumbParentPath(path, prefixCloud);
148 MEDIA_INFO_LOG("filePath: %{public}s, thmbFileParentDir: %{public}s",
149 MediaFileUtils::DesensitizePath(path).c_str(),
150 MediaFileUtils::DesensitizePath(thmPath).c_str());
151 MediaFileUtils::DeleteDir(thmPath);
152 }
153
RemoveEditDataParentPath(const std::string & path,const std::string & prefixCloud)154 void CloudMediaSyncUtils::RemoveEditDataParentPath(const std::string &path, const std::string &prefixCloud)
155 {
156 std::string editParentPath = PhotoFileUtils::GetEditDataDir(path);
157
158 MEDIA_INFO_LOG("filePath: %{public}s, editDataParentDir: %{public}s",
159 MediaFileUtils::DesensitizePath(path).c_str(),
160 MediaFileUtils::DesensitizePath(editParentPath).c_str());
161 MediaFileUtils::DeleteDir(editParentPath);
162 }
163
RemoveMetaDataPath(const std::string & path,const std::string & prefixCloud)164 void CloudMediaSyncUtils::RemoveMetaDataPath(const std::string &path, const std::string &prefixCloud)
165 {
166 std::string metaDataPath = PhotoFileUtils::GetMetaDataRealPath(path);
167
168 MEDIA_INFO_LOG("filePath: %{public}s, metaDataPath: %{public}s",
169 MediaFileUtils::DesensitizePath(path).c_str(),
170 MediaFileUtils::DesensitizePath(metaDataPath).c_str());
171 MediaFileUtils::DeleteFile(metaDataPath.c_str());
172 }
173
GetVideoCachePath(const std::string & filePath)174 static std::string GetVideoCachePath(const std::string &filePath)
175 {
176 std::string result = "";
177 const std::string sandboxPrefix = "/storage/cloud";
178 const std::string cachePathPrefix = "/data/service/el2/hmdfs/cache/cloud_cache/pread_cache";
179 size_t pos = filePath.find(sandboxPrefix);
180 if (pos != 0 || pos == std::string::npos) {
181 MEDIA_ERR_LOG(
182 "GetVideoCachePath Invalid filePath, path: %{public}s", MediaFileUtils::DesensitizePath(filePath).c_str());
183 return result;
184 }
185 std::string cachePath = cachePathPrefix + filePath.substr(sandboxPrefix.length());
186 auto resolvedPath = realpath(cachePath.c_str(), nullptr);
187 if (resolvedPath == nullptr) {
188 if (errno != ENOENT) {
189 MEDIA_ERR_LOG("GetVideoCachePath realpath failed, path: %{public}s",
190 MediaFileUtils::DesensitizePath(filePath).c_str());
191 }
192 return result;
193 }
194 if (strncmp(resolvedPath, cachePath.c_str(), cachePath.size()) != 0) {
195 MEDIA_ERR_LOG("GetVideoCachePath Invalid videoCachePath, path: %{public}s",
196 MediaFileUtils::DesensitizePath(cachePath).c_str());
197 free(resolvedPath);
198 return result;
199 }
200 free(resolvedPath);
201 return cachePath;
202 }
203
InvalidVideoCache(const std::string & localPath)204 void CloudMediaSyncUtils::InvalidVideoCache(const std::string &localPath)
205 {
206 MEDIA_INFO_LOG("InvalidVideoCache loca path: %{public}s", MediaFileUtils::DesensitizePath(localPath).c_str());
207 const std::string sandboxPrefix = "/storage/cloud";
208 size_t pos = localPath.find(sandboxPrefix);
209 CHECK_AND_RETURN_LOG(pos == 0 && pos != std::string::npos,
210 "InvalidVideoCache Invalid localPath, sandboxPrefix: %{public}s",
211 sandboxPrefix.c_str());
212 std::string videoCachePath = GetVideoCachePath(localPath);
213 CHECK_AND_RETURN_LOG(!videoCachePath.empty(), "InvalidVideoCache Invalid videoCachePath");
214 CHECK_AND_RETURN_LOG(unlink(videoCachePath.c_str()) >= 0,
215 "InvalidVideoCache Failed to unlink video cache: %{public}s, errno: %{public}d",
216 MediaFileUtils::DesensitizePath(videoCachePath).c_str(),
217 errno);
218 MEDIA_INFO_LOG(
219 "InvalidVideoCache VideoCachePath: %{public}s", MediaFileUtils::DesensitizePath(videoCachePath).c_str());
220 }
221
GetMovingPhotoExtraDataDir(const std::string & localPath)222 std::string CloudMediaSyncUtils::GetMovingPhotoExtraDataDir(const std::string &localPath)
223 {
224 if (localPath.length() < ROOT_MEDIA_DIR.length() || !MediaFileUtils::StartsWith(localPath, ROOT_MEDIA_DIR)) {
225 return "";
226 }
227 return MEDIA_EDIT_DATA_DIR + localPath.substr(ROOT_MEDIA_DIR.length());
228 }
229
GetMovingPhotoExtraDataPath(const std::string & localPath)230 std::string CloudMediaSyncUtils::GetMovingPhotoExtraDataPath(const std::string &localPath)
231 {
232 std::string parentPath = GetMovingPhotoExtraDataDir(localPath);
233 if (parentPath.empty()) {
234 return "";
235 }
236 return parentPath + "/extraData";
237 }
238
CheckPhotoPath(const std::string & localPath)239 static bool CheckPhotoPath(const std::string &localPath)
240 {
241 return localPath.length() >= ROOT_MEDIA_DIR.length() && MediaFileUtils::StartsWith(localPath, ROOT_MEDIA_DIR);
242 }
243
GetEditDataSourcePath(const string & photoPath)244 std::string CloudMediaSyncUtils::GetEditDataSourcePath(const string& photoPath)
245 {
246 string parentPath = GetEditDataDir(photoPath);
247 if (parentPath.empty()) {
248 return "";
249 }
250 return parentPath + "/source." + MediaFileUtils::GetExtensionFromPath(photoPath);
251 }
252
GetSourceMovingPhotoImagePath(const string & imagePath)253 std::string CloudMediaSyncUtils::GetSourceMovingPhotoImagePath(const string& imagePath)
254 {
255 return GetEditDataSourcePath(imagePath);
256 }
257
GetSourceMovingPhotoVideoPath(const string & imagePath)258 std::string CloudMediaSyncUtils::GetSourceMovingPhotoVideoPath(const string& imagePath)
259 {
260 return GetMovingPhotoVideoPath(GetSourceMovingPhotoImagePath(imagePath));
261 }
262
GetEditDataDir(const std::string & localPath)263 std::string CloudMediaSyncUtils::GetEditDataDir(const std::string &localPath)
264 {
265 if (!CheckPhotoPath(localPath)) {
266 return "";
267 }
268
269 return MEDIA_EDIT_DATA_DIR + localPath.substr(ROOT_MEDIA_DIR.length());
270 }
271
GetEditDataPath(const std::string & localPath)272 std::string CloudMediaSyncUtils::GetEditDataPath(const std::string &localPath)
273 {
274 std::string parentPath = GetEditDataDir(localPath);
275 if (parentPath.empty()) {
276 return "";
277 }
278 return parentPath + "/editdata";
279 }
280
GetMovingPhotoVideoPath(const std::string & localPath)281 std::string CloudMediaSyncUtils::GetMovingPhotoVideoPath(const std::string &localPath)
282 {
283 size_t splitIndex = localPath.find_last_of('.');
284 size_t lastSlashIndex = localPath.find_last_of('/');
285 if (splitIndex == std::string::npos || (lastSlashIndex != std::string::npos && lastSlashIndex > splitIndex)) {
286 return "";
287 }
288 return localPath.substr(0, splitIndex) + ".mp4";
289 }
290
GetMovingPhotoTmpPath(const std::string & localPath)291 std::string CloudMediaSyncUtils::GetMovingPhotoTmpPath(const std::string &localPath)
292 {
293 std::string tempDownloadParent = "/mnt/hmdfs/account/device_view/local/files/.cloud_cache/download_cache/";
294 if (!CheckPhotoPath(localPath)) {
295 return "";
296 }
297 return tempDownloadParent + localPath.substr(ROOT_MEDIA_DIR.length());
298 }
299
RemoveEditDataPath(const std::string & localPath)300 void CloudMediaSyncUtils::RemoveEditDataPath(const std::string &localPath)
301 {
302 std::string editDataPath = GetEditDataPath(localPath);
303 MEDIA_INFO_LOG("RemoveEditDataPath EditDataPath: %{public}s", editDataPath.c_str());
304 if (unlink(editDataPath.c_str()) != 0 && errno != ENOENT) {
305 MEDIA_ERR_LOG("unlink editData failed, errno %{public}d", errno);
306 }
307 }
308
RemoveMovingPhoto(const std::string & localPath)309 void CloudMediaSyncUtils::RemoveMovingPhoto(const std::string &localPath)
310 {
311 MEDIA_INFO_LOG("RemoveMovingPhoto MovingPhotoVideoPath: %{public}s", GetMovingPhotoVideoPath(localPath).c_str());
312 if (unlink(GetMovingPhotoVideoPath(localPath).c_str()) != 0 && errno != ENOENT) {
313 MEDIA_ERR_LOG("unlink moving photo's video failed, errno %{public}d", errno);
314 }
315 MEDIA_INFO_LOG("RemoveMovingPhoto ExtraDataPath: %{public}s", GetMovingPhotoExtraDataPath(localPath).c_str());
316 if (unlink(GetMovingPhotoExtraDataPath(localPath).c_str()) != 0 && errno != ENOENT) {
317 MEDIA_ERR_LOG("unlink moving photo's video failed, errno %{public}d", errno);
318 }
319 }
320
HandleHashCode(const std::string & str)321 int32_t HandleHashCode(const std::string &str) __attribute__((no_sanitize("signed-integer-overflow")))
322 {
323 int32_t hash = 0;
324 for (uint32_t i = 0; i < str.length(); i++) {
325 char c = str.at(i);
326 hash = hash * CloudSync::HASH_VLAUE + c;
327 }
328 return hash;
329 }
330
GenerateCloudIdWithHash(CloudSync::PhotoAlbumPo & record)331 uint32_t CloudMediaSyncUtils::GenerateCloudIdWithHash(CloudSync::PhotoAlbumPo &record)
332 {
333 std::string cloudId = record.cloudId.value_or("");
334 if (!cloudId.empty()) {
335 MEDIA_INFO_LOG("cloudId is not empty, it is %{public}s", cloudId.c_str());
336 return E_CLOUDID_IS_NOT_NULL;
337 }
338 std::string lpath = record.lpath.value_or("");
339 int64_t dateAdded = record.dateAdded.value_or(0);
340 if (dateAdded == 0) {
341 struct timeval tv;
342 gettimeofday(&tv, nullptr);
343 dateAdded = tv.tv_sec * CloudSync::MILLISECOND_TO_SECOND + tv.tv_usec / CloudSync::MILLISECOND_TO_SECOND;
344 }
345 int32_t hashValue = HandleHashCode(lpath);
346 cloudId = "default-album-200-" + to_string(hashValue) + "-" + to_string(dateAdded);
347 MEDIA_INFO_LOG("lpath is %{public}s, cloudid is %{public}s", lpath.c_str(), cloudId.c_str());
348 record.cloudId = cloudId;
349 return E_OK;
350 }
351
GetLpathFromSourcePath(const std::string & sourcePath)352 std::string CloudMediaSyncUtils::GetLpathFromSourcePath(const std::string &sourcePath)
353 {
354 size_t pos = sourcePath.find(SOURCE_PATH_PERFIX);
355 if (pos == std::string::npos) {
356 MEDIA_ERR_LOG("invalid path %{private}s", MediaFileUtils::DesensitizePath(sourcePath).c_str());
357 return "";
358 }
359
360 size_t lpathStart = pos + SOURCE_PATH_PERFIX.length();
361 size_t lpathEnd = sourcePath.rfind('/');
362 if (lpathEnd == std::string::npos || lpathEnd <= lpathStart) {
363 MEDIA_ERR_LOG("invalid path %{private}s", MediaFileUtils::DesensitizePath(sourcePath).c_str());
364 return "";
365 }
366 return sourcePath.substr(lpathStart, lpathEnd - lpathStart);
367 }
368
GetLpath(const CloudSync::CloudMediaPullDataDto & pullData)369 std::string CloudMediaSyncUtils::GetLpath(const CloudSync::CloudMediaPullDataDto &pullData)
370 {
371 CHECK_AND_RETURN_RET_LOG(!pullData.propertiesSourcePath.empty(), "", "PullData cannot find attributes::sourcePath");
372 std::string sourcePath = pullData.propertiesSourcePath;
373 size_t pos = sourcePath.find(SCREENSHOT_ALBUM_PATH);
374 if (pos != std::string::npos) {
375 int32_t fileType = pullData.basicFileType;
376 if (fileType == -1) {
377 MEDIA_ERR_LOG("Cannot find basic::fileType");
378 }
379
380 std::string displayName = pullData.basicFileName;
381 if (displayName.empty()) {
382 MEDIA_ERR_LOG("Cannot find basic::fileName");
383 }
384
385 if (fileType == CloudSync::FILE_TYPE_VIDEO) {
386 sourcePath = SCREENRECORD_ALBUM_PATH + displayName;
387 }
388 }
389 return GetLpathFromSourcePath(sourcePath);
390 }
391
GetLocalPath(const std::string & path)392 std::string CloudMediaSyncUtils::GetLocalPath(const std::string &path)
393 {
394 std::string localPath = path;
395 size_t pos = localPath.find(PHOTO_CLOUD_PATH_URI);
396 if (pos != std::string::npos) {
397 localPath.replace(pos, PHOTO_CLOUD_PATH_URI.length(), PHOTO_MEDIA_PATH_URI);
398 }
399 return localPath;
400 }
401
IsMovingPhoto(const PhotosPo & photosPo)402 bool CloudMediaSyncUtils::IsMovingPhoto(const PhotosPo &photosPo)
403 {
404 int32_t subtype = photosPo.subtype.value_or(0);
405 int32_t movingPhotoEffectMode = photosPo.movingPhotoEffectMode.value_or(0);
406 int32_t originalSubtype = photosPo.originalSubtype.value_or(0);
407 return MovingPhotoFileUtils::IsMovingPhoto(subtype, movingPhotoEffectMode, originalSubtype);
408 }
409
IsGraffiti(const PhotosPo & photosPo)410 bool CloudMediaSyncUtils::IsGraffiti(const PhotosPo &photosPo)
411 {
412 int32_t subtype = photosPo.subtype.value_or(0);
413 int32_t originalSubtype = photosPo.originalSubtype.value_or(0);
414 return MovingPhotoFileUtils::IsGraffiti(subtype, originalSubtype);
415 }
416
IsLivePhoto(const PhotosPo & photosPo)417 bool CloudMediaSyncUtils::IsLivePhoto(const PhotosPo &photosPo)
418 {
419 std::string path = photosPo.data.value_or("");
420 std::string localPath = GetLocalPath(path);
421 return MovingPhotoFileUtils::IsLivePhoto(localPath);
422 }
423
UpdateModifyTime(const std::string & localPath,int64_t localMtime)424 int32_t CloudMediaSyncUtils::UpdateModifyTime(const std::string &localPath, int64_t localMtime)
425 {
426 struct utimbuf ubuf {
427 .actime = localMtime / MILLISECOND_TO_SECOND, .modtime = localMtime / MILLISECOND_TO_SECOND
428 };
429 if (utime(localPath.c_str(), &ubuf) < 0) {
430 MEDIA_ERR_LOG(
431 "utime failed %{public}d, lPath: %{public}s", errno, MediaFileUtils::DesensitizePath(localPath).c_str());
432 return errno;
433 }
434 return E_OK;
435 }
436
IsUserAlbumPath(const std::string & lpath)437 bool CloudMediaSyncUtils::IsUserAlbumPath(const std::string &lpath)
438 {
439 std::string prefix = "/pictures/users/";
440 if (lpath.size() < prefix.size()) {
441 return false;
442 }
443 return lpath.substr(0, prefix.size()) == prefix;
444 }
445
CanUpdateExifRotateOnly(int32_t mediaType,int32_t oldExifRotate,int32_t newExifRotate)446 bool CloudMediaSyncUtils::CanUpdateExifRotateOnly(int32_t mediaType, int32_t oldExifRotate, int32_t newExifRotate)
447 {
448 if (mediaType == static_cast<int32_t>(MediaType::MEDIA_TYPE_IMAGE)) {
449 return oldExifRotate == 0 && newExifRotate == static_cast<int32_t>(ExifRotateType::TOP_LEFT);
450 } else {
451 return !ExifRotateUtils::IsExifRotateWithFlip(newExifRotate);
452 }
453 }
454
GetExifRotate(int32_t mediaType,const std::string & path)455 int32_t CloudMediaSyncUtils::GetExifRotate(int32_t mediaType, const std::string &path)
456 {
457 int32_t exifRotate = static_cast<int32_t>(ExifRotateType::TOP_LEFT);
458 if (mediaType == static_cast<int32_t>(MediaType::MEDIA_TYPE_IMAGE)) {
459 MediaImageFrameWorkUtils::GetExifRotate(path, exifRotate);
460 } else {
461 MediaPlayerFrameWorkUtils::GetExifRotate(path, exifRotate);
462 }
463 return exifRotate;
464 }
465 } // namespace OHOS::Media::CloudSync
466