• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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