• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define MLOG_TAG "PhotoFileOperation"
16 
17 #include "photo_file_operation.h"
18 
19 #include <sstream>
20 
21 #include "media_log.h"
22 #include "medialibrary_errno.h"
23 #include "medialibrary_kvstore_utils.h"
24 #include "userfile_manager_types.h"
25 #include "media_file_utils.h"
26 #include "media_column.h"
27 #include "result_set_utils.h"
28 
29 namespace OHOS::Media {
ToString(const PhotoAssetInfo & photoInfo)30 std::string PhotoFileOperation::ToString(const PhotoAssetInfo &photoInfo)
31 {
32     std::stringstream ss;
33     ss << "PhotoAssetInfo[displayName: " << photoInfo.displayName << ", filePath: " << photoInfo.filePath
34        << ", dateModified: " << photoInfo.dateModified << ", subtype: " << photoInfo.subtype
35        << ", videoFilePath: " << photoInfo.videoFilePath << ", editDataFolder: " << photoInfo.editDataFolder
36        << ", thumbnailFolder: " << photoInfo.thumbnailFolder << "]";
37     return ss.str();
38 }
39 
40 /**
41  * @brief Copy Photo File, include photo file, video file and edit data folder.
42  */
CopyPhoto(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,const std::string & targetPath)43 int32_t PhotoFileOperation::CopyPhoto(
44     const std::shared_ptr<NativeRdb::ResultSet> &resultSet, const std::string &targetPath)
45 {
46     bool cond = (resultSet == nullptr || targetPath.empty());
47     CHECK_AND_RETURN_RET_LOG(!cond, E_FAIL,
48         "Media_Operation: CopyPhoto failed, resultSet is null or targetPath is empty");
49 
50     // Build the Original Photo Asset Info
51     PhotoFileOperation::PhotoAssetInfo sourcePhotoInfo;
52     sourcePhotoInfo.displayName = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
53     sourcePhotoInfo.filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
54     sourcePhotoInfo.subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
55     sourcePhotoInfo.dateModified = GetInt64Val(MediaColumn::MEDIA_DATE_MODIFIED, resultSet);
56     sourcePhotoInfo.videoFilePath = this->FindVideoFilePath(sourcePhotoInfo);
57     sourcePhotoInfo.editDataFolder = this->FindEditDataFolder(sourcePhotoInfo);
58     // Build the Target Photo Asset Info
59     PhotoFileOperation::PhotoAssetInfo targetPhotoInfo;
60     targetPhotoInfo.displayName = sourcePhotoInfo.displayName;
61     targetPhotoInfo.filePath = targetPath;
62     targetPhotoInfo.subtype = sourcePhotoInfo.subtype;
63     targetPhotoInfo.dateModified = sourcePhotoInfo.dateModified;
64     // No need to copy video file if the Original Photo is not a moving photo.
65     if (!sourcePhotoInfo.videoFilePath.empty()) {
66         targetPhotoInfo.videoFilePath = this->GetVideoFilePath(targetPhotoInfo);
67     }
68     // No need to copy edit data folder if the Original Photo is not edited.
69     if (!sourcePhotoInfo.editDataFolder.empty()) {
70         targetPhotoInfo.editDataFolder = this->BuildEditDataFolder(targetPhotoInfo);
71     }
72     MEDIA_INFO_LOG("Media_Operation: sourcePhotoInfo: %{public}s, targetPhotoInfo: %{public}s",
73         this->ToString(sourcePhotoInfo).c_str(),
74         this->ToString(targetPhotoInfo).c_str());
75     return this->CopyPhoto(sourcePhotoInfo, targetPhotoInfo);
76 }
77 
78 /**
79  * @brief Copy thumbnail, include folder and astc data.
80  */
CopyThumbnail(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,const std::string & targetPath,int64_t & newAssetId)81 int32_t PhotoFileOperation::CopyThumbnail(
82     const std::shared_ptr<NativeRdb::ResultSet> &resultSet, const std::string &targetPath, int64_t &newAssetId)
83 {
84     bool cond = (resultSet == nullptr || targetPath.empty());
85     CHECK_AND_RETURN_RET_LOG(!cond, E_FAIL,
86         "Media_Operation: CopyPhoto failed, resultSet is null or targetPath is empty");
87 
88     // Build the Original Photo Asset Info
89     PhotoFileOperation::PhotoAssetInfo sourcePhotoInfo;
90     sourcePhotoInfo.filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
91     sourcePhotoInfo.thumbnailFolder = this->FindThumbnailFolder(sourcePhotoInfo);
92     if (sourcePhotoInfo.thumbnailFolder.empty()) {
93         MEDIA_INFO_LOG("Source thumbnail is empty, skip copy. thumbnailFolder:%{public}s",
94             sourcePhotoInfo.thumbnailFolder.c_str());
95         return E_FAIL;
96     }
97 
98     // copy folder
99     PhotoFileOperation::PhotoAssetInfo targetPhotoInfo;
100     targetPhotoInfo.filePath = targetPath;
101     targetPhotoInfo.thumbnailFolder = this->BuildThumbnailFolder(targetPhotoInfo);
102     int32_t opRet = this->CopyPhotoRelatedThumbnail(sourcePhotoInfo, targetPhotoInfo);
103     CHECK_AND_RETURN_RET(opRet == E_OK, opRet);
104 
105     std::string dateTaken = to_string(GetInt64Val(MediaColumn::MEDIA_DATE_TAKEN, resultSet));
106     std::string oldAssetId = to_string(GetInt64Val(MediaColumn::MEDIA_ID, resultSet));
107     return HandleThumbnailAstcData(dateTaken, oldAssetId, to_string(newAssetId));
108 }
109 
HandleThumbnailAstcData(const std::string & dateTaken,const std::string & oldAssetId,const std::string & newAssetId)110 int32_t PhotoFileOperation::HandleThumbnailAstcData(const std::string &dateTaken, const std::string &oldAssetId,
111     const std::string &newAssetId)
112 {
113     // 取旧key拿value,然后在put新key和value(和旧的value一样)到kvstore中
114     string oldKey;
115     CHECK_AND_RETURN_RET_LOG(MediaFileUtils::GenerateKvStoreKey(oldAssetId, dateTaken, oldKey), E_ERR,
116         "GenerateKvStoreKey failed");
117 
118     string newKey;
119     CHECK_AND_RETURN_RET_LOG(MediaFileUtils::GenerateKvStoreKey(newAssetId, dateTaken, newKey), E_ERR,
120         "GenerateKvStoreKey failed");
121 
122     int32_t err = MediaLibraryKvStoreUtils::CopyAstcDataToKvStoreByType(KvStoreValueType::MONTH_ASTC, oldKey, newKey);
123     CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "CopyAstcDataToKvStoreByType failed, err: %{public}d", err);
124 
125     err = MediaLibraryKvStoreUtils::CopyAstcDataToKvStoreByType(KvStoreValueType::YEAR_ASTC, oldKey, newKey);
126     CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "CopyAstcDataToKvStoreByType failed, err: %{public}d", err);
127     MEDIA_INFO_LOG("Success to copy thumbnail. oldKey:%{public}s, newKey:%{public}s", oldKey.c_str(), newKey.c_str());
128     return E_OK;
129 }
130 
131 /**
132  * @brief Copy Photo File, include photo file, video file and edit data folder.
133  */
CopyPhoto(const PhotoFileOperation::PhotoAssetInfo & sourcePhotoInfo,const PhotoFileOperation::PhotoAssetInfo & targetPhotoInfo)134 int32_t PhotoFileOperation::CopyPhoto(const PhotoFileOperation::PhotoAssetInfo &sourcePhotoInfo,
135     const PhotoFileOperation::PhotoAssetInfo &targetPhotoInfo)
136 {
137     int32_t opRet = this->CopyPhotoFile(sourcePhotoInfo, targetPhotoInfo);
138     CHECK_AND_RETURN_RET(opRet == E_OK, opRet);
139 
140     opRet = this->CopyPhotoRelatedVideoFile(sourcePhotoInfo, targetPhotoInfo);
141     CHECK_AND_RETURN_RET(opRet == E_OK, opRet);
142 
143     return this->CopyPhotoRelatedExtraData(sourcePhotoInfo, targetPhotoInfo);
144 }
145 
146 /**
147  * @brief Get the video file path of the photo, without any check.
148  * @return the video file path of the photo. Only replace the suffix of file extension, such as .jpg to .mp4.
149  * @example if filePath is /xxx/.../xxx/123456789.jpg, then return /xxx/.../xxx/123456789.mp4.
150  */
GetVideoFilePath(const PhotoFileOperation::PhotoAssetInfo & photoInfo)151 std::string PhotoFileOperation::GetVideoFilePath(const PhotoFileOperation::PhotoAssetInfo &photoInfo)
152 {
153     return MediaFileUtils::GetMovingPhotoVideoPath(photoInfo.filePath);
154 }
155 
156 /**
157  * @brief Get the video file path of the photo, without any check.
158  * @return the video file path of the photo. Only replace the suffix of file extension, such as .jpg to .mp4.
159  *         If the photo is not a moving photo, return an empty string.
160  *         If the photo's file path is empty, return an empty string.
161  *         If the photo is a moving photo, return the video file path of the photo.
162  */
FindVideoFilePath(const PhotoFileOperation::PhotoAssetInfo & photoInfo)163 std::string PhotoFileOperation::FindVideoFilePath(const PhotoFileOperation::PhotoAssetInfo &photoInfo)
164 {
165     if (photoInfo.subtype != static_cast<int32_t>(PhotoSubType::MOVING_PHOTO)) {
166         return "";
167     }
168     // If file path is empty, return empty string. Trace log will be printed in CopyPhotoFile.
169     CHECK_AND_RETURN_RET(!photoInfo.filePath.empty(), "");
170 
171     std::string videoFilePath = this->GetVideoFilePath(photoInfo);
172     if (!MediaFileUtils::IsFileExists(videoFilePath)) {
173         MEDIA_WARN_LOG("Media_Operation: videoFilePath not exists, videoFilePath: %{public}s, Object: %{public}s.",
174             videoFilePath.c_str(),
175             this->ToString(photoInfo).c_str());
176         return "";
177     }
178     return videoFilePath;
179 }
180 
181 /**
182  * @brief Find the Relative Path of filePath.
183  * @return Relative Path.
184  *         If prefix of filePath is "/storage/cloud/files", return the relative path of cloud prefix.
185  *         If prefix of filePath is "/storage/media/local/files", return the relative path of local prefix.
186  *         Otherwise, return empty string.
187  */
FindRelativePath(const std::string & filePath)188 std::string PhotoFileOperation::FindRelativePath(const std::string &filePath)
189 {
190     std::string prefix = "/storage/cloud/files";
191     size_t pos = filePath.find(prefix);
192     CHECK_AND_RETURN_RET(pos == std::string::npos, filePath.substr(pos + prefix.size()));
193 
194     prefix = "/storage/media/local/files";
195     pos = filePath.find(prefix);
196     CHECK_AND_RETURN_RET(pos == std::string::npos, filePath.substr(pos + prefix.size()));
197     MEDIA_ERR_LOG("Media_Operation: Find RelativePath failed, filePath: %{public}s", filePath.c_str());
198     return "";
199 }
200 
201 /**
202  * @brief Find the prefix of photo Data Folder.
203  * @return Return the prefix of photo Data Folder.
204  *         There are two prefixes, one is local, the other is cloud.
205  *         If the prefix of filePath is cloud, return "/storage/cloud/files/" + dataName.
206  *         If the prefix of filePath is local, return "/storage/media/local/files/" + dataName;
207  *         If the prefix of filePath is not found, return "".
208  */
FindPrefixDataFolder(const std::string & filePath,const std::string & dataName)209 std::string PhotoFileOperation::FindPrefixDataFolder(const std::string &filePath, const std::string &dataName)
210 {
211     std::string prefix = "/storage/cloud/files";
212     size_t pos = filePath.find(prefix);
213     if (pos != std::string::npos) {
214         return "/storage/cloud/files/" + dataName;
215     }
216     prefix = "/storage/media/local/files";
217     pos = filePath.find(prefix);
218     if (pos != std::string::npos) {
219         return "/storage/media/local/files/" + dataName;
220     }
221     MEDIA_WARN_LOG("Media_Operation: Get Prefix failed, filePath: %{public}s", filePath.c_str());
222     return "";
223 }
224 
225 /**
226  * @brief Find the prefix of Edit Data Folder.
227  * @return Return the prefix of Edit Data Folder.
228  *         There are two prefixes, one is local, the other is cloud.
229  *         If the prefix of filePath is cloud, return "/storage/cloud/files/.editData".
230  *         If the prefix of filePath is local, return "/storage/media/local/files/.editData";
231  *         If the prefix of filePath is not found, return "".
232  */
FindPrefixOfEditDataFolder(const std::string & filePath)233 std::string PhotoFileOperation::FindPrefixOfEditDataFolder(const std::string &filePath)
234 {
235     return FindPrefixDataFolder(filePath, ".editData");
236 }
237 
238 /**
239  * @brief Find the prefix of thumbs Data Folder.
240  * @return Return the prefix of thumbs Data Folder.
241  *         There are two prefixes, one is local, the other is cloud.
242  *         If the prefix of filePath is cloud, return "/storage/cloud/files/.thumbs".
243  *         If the prefix of filePath is local, return "/storage/media/local/files/.thumbs";
244  *         If the prefix of filePath is not found, return "".
245  */
FindPrefixOfThumbnailFolder(const std::string & filePath)246 std::string PhotoFileOperation::FindPrefixOfThumbnailFolder(const std::string &filePath)
247 {
248     return FindPrefixDataFolder(filePath, ".thumbs");
249 }
250 
251 /**
252  * @brief Build the Edit Data Folder for the Photo file, without any check.
253  * @return Return the Edit Data Folder for the Photo file.
254  *         If the filePath is cloud, return "/storage/cloud/files/.editData/" + the relativePath of Photo file.
255  *         If the filePath is local, return "/storage/media/local/files/.editData/" + the relativePath of Photo file.
256  *         If the filePath is not identified, return "".
257  */
BuildEditDataFolder(const PhotoFileOperation::PhotoAssetInfo & photoInfo)258 std::string PhotoFileOperation::BuildEditDataFolder(const PhotoFileOperation::PhotoAssetInfo &photoInfo)
259 {
260     std::string prefix = this->FindPrefixOfEditDataFolder(photoInfo.filePath);
261     std::string relativePath = this->FindRelativePath(photoInfo.filePath);
262     if (prefix.empty() || relativePath.empty()) {
263         return "";
264     }
265     return prefix + relativePath;
266 }
267 
268 /**
269  * @brief Build the thumbs Data Folder for the Photo file, without any check.
270  * @return Return the thumbs Data Folder for the Photo file.
271  *         If the filePath is cloud, return "/storage/cloud/files/.thumbs/" + the relativePath of Photo file.
272  *         If the filePath is local, return "/storage/media/local/files/.thumbs/" + the relativePath of Photo file.
273  *         If the filePath is not identified, return "".
274  */
BuildThumbnailFolder(const PhotoFileOperation::PhotoAssetInfo & photoInfo)275 std::string PhotoFileOperation::BuildThumbnailFolder(const PhotoFileOperation::PhotoAssetInfo &photoInfo)
276 {
277     std::string prefix = this->FindPrefixOfThumbnailFolder(photoInfo.filePath);
278     std::string relativePath = this->FindRelativePath(photoInfo.filePath);
279     if (prefix.empty() || relativePath.empty()) {
280         return "";
281     }
282     return prefix + relativePath;
283 }
284 
285 /**
286  * @brief Find the thumbs Data Folder for the Photo file.
287  * @return Return the thumbs Data Folder path. If the thumbs Data Folder is invalid, return empty string.
288  *         If the thumbs Data Folder is not exist, has 3 scenario:
289  *         1. The photo file is not thumbs. Normal scenario.
290  *         2. The photo file is not MOVING_PHOTO. Noraml scenario.
291  *         3. The photo file is thumbs or MOVING_PHOTO, but the thumbs Data Folder is not exist. Exceptional scenario.
292  */
FindThumbnailFolder(const PhotoFileOperation::PhotoAssetInfo & photoInfo)293 std::string PhotoFileOperation::FindThumbnailFolder(const PhotoFileOperation::PhotoAssetInfo &photoInfo)
294 {
295     std::string thumbnailFolderPath = this->BuildThumbnailFolder(photoInfo);
296     if (!thumbnailFolderPath.empty() && !MediaFileUtils::IsFileExists(thumbnailFolderPath)) {
297         MEDIA_INFO_LOG("Media_Operation: thumbnailFolder not exists, Object: %{public}s.",
298             this->ToString(photoInfo).c_str());
299         return "";
300     }
301     return thumbnailFolderPath;
302 }
303 
304 /**
305  * @brief Find the Edit Data Folder for the Photo file.
306  * @return Return the Edit Data Folder path. If the Edit Data Folder is invalid, return empty string.
307  *         If the Edit Data Folder is not exist, has 3 scenario:
308  *         1. The photo file is not edited. Normal scenario.
309  *         2. The photo file is not MOVING_PHOTO. Noraml scenario.
310  *         3. The photo file is edited or MOVING_PHOTO, but the Edit Data Folder is not exist. Exceptional scenario.
311  */
FindEditDataFolder(const PhotoFileOperation::PhotoAssetInfo & photoInfo)312 std::string PhotoFileOperation::FindEditDataFolder(const PhotoFileOperation::PhotoAssetInfo &photoInfo)
313 {
314     std::string editDataFolderPath = this->BuildEditDataFolder(photoInfo);
315     if (!editDataFolderPath.empty() && !MediaFileUtils::IsFileExists(editDataFolderPath)) {
316         MEDIA_INFO_LOG("Media_Operation: EditDataFolder not exists, It may not be edited photo or moving photo. "
317                        "Object: %{public}s.",
318             this->ToString(photoInfo).c_str());
319         return "";
320     }
321     return editDataFolderPath;
322 }
323 
324 /**
325  * @brief Copy Photo File, only include the photo file defined in the Photos table.
326  * @return E_OK if success,
327  *         E_INVALID_PATH if the source file or target file is invalid,
328  *         E_FILE_OPER_FAIL if the copy operation failed.
329  */
CopyPhotoFile(const PhotoFileOperation::PhotoAssetInfo & sourcePhotoInfo,const PhotoFileOperation::PhotoAssetInfo & targetPhotoInfo)330 int32_t PhotoFileOperation::CopyPhotoFile(const PhotoFileOperation::PhotoAssetInfo &sourcePhotoInfo,
331     const PhotoFileOperation::PhotoAssetInfo &targetPhotoInfo)
332 {
333     std::string srcPath = sourcePhotoInfo.filePath;
334     std::string targetPath = targetPhotoInfo.filePath;
335     int64_t dateModified = targetPhotoInfo.dateModified;
336     // If File Path is empty, return E_INVALID_PATH.
337     if (srcPath.empty() || targetPath.empty()) {
338         MEDIA_ERR_LOG("Media_Operation: CopyPhotoFile failed, srcPath or targetPath is empty. "
339                       "Source Object: %{public}s, Target Object: %{public}s",
340             this->ToString(sourcePhotoInfo).c_str(),
341             this->ToString(targetPhotoInfo).c_str());
342         return E_INVALID_PATH;
343     }
344     int32_t opRet = this->CopyFile(srcPath, targetPath);
345     if (opRet != E_OK) {
346         MEDIA_ERR_LOG("Media_Operation: CopyPhoto failed, srcPath: %{public}s, targetPath: %{public}s",
347             srcPath.c_str(),
348             targetPath.c_str());
349         return opRet;
350     }
351     MediaFileUtils::ModifyFile(targetPath, dateModified / MSEC_TO_SEC);
352     MEDIA_INFO_LOG("Media_Operation: CopyPhotoFile success, srcPath: %{public}s, targetPath: %{public}s",
353         srcPath.c_str(),
354         targetPath.c_str());
355     return E_OK;
356 }
357 
358 /**
359  * @brief Copy Photo File, only include the vide file related to the photo file defined in the Photos table.
360  * @return E_OK if success or not MOVING_PHOTO or video file empty,
361  *         E_INVALID_PATH if the source file or target file is invalid,
362  *         E_FILE_OPER_FAIL if the copy operation failed.
363  */
CopyPhotoRelatedVideoFile(const PhotoFileOperation::PhotoAssetInfo & sourcePhotoInfo,const PhotoFileOperation::PhotoAssetInfo & targetPhotoInfo)364 int32_t PhotoFileOperation::CopyPhotoRelatedVideoFile(const PhotoFileOperation::PhotoAssetInfo &sourcePhotoInfo,
365     const PhotoFileOperation::PhotoAssetInfo &targetPhotoInfo)
366 {
367     // If photoSubtype is MOVING_PHOTO, copy video file.
368     CHECK_AND_RETURN_RET(sourcePhotoInfo.subtype == static_cast<int32_t>(PhotoSubType::MOVING_PHOTO), E_OK);
369     std::string srcVideoPath = sourcePhotoInfo.videoFilePath;
370     std::string targetVideoPath = targetPhotoInfo.videoFilePath;
371     int64_t dateModified = targetPhotoInfo.dateModified;
372     // If video file is empty, return E_OK. Trace log will be printed in FindVideoFilePath.
373     bool cond = (srcVideoPath.empty() || targetVideoPath.empty());
374     CHECK_AND_RETURN_RET(!cond, E_OK);
375 
376     int32_t opRet = this->CopyFile(srcVideoPath, targetVideoPath);
377     CHECK_AND_RETURN_RET_LOG(opRet == E_OK, opRet,
378         "Media_Operation: CopyPhoto Video failed, srcPath: %{public}s, targetPath: %{public}s", srcVideoPath.c_str(),
379         targetVideoPath.c_str());
380     MediaFileUtils::ModifyFile(targetVideoPath, dateModified / MSEC_TO_SEC);
381     MEDIA_INFO_LOG("Media_Operation: CopyPhotoRelatedVideoFile success, srcPath: %{public}s, targetPath: %{public}s",
382         srcVideoPath.c_str(),
383         targetVideoPath.c_str());
384     return E_OK;
385 }
386 
CopyPhotoRelatedData(const PhotoFileOperation::PhotoAssetInfo & sourcePhotoInfo,const PhotoFileOperation::PhotoAssetInfo & targetPhotoInfo,const std::string & srcFolder,const std::string & targetFolder)387 int32_t PhotoFileOperation::CopyPhotoRelatedData(const PhotoFileOperation::PhotoAssetInfo &sourcePhotoInfo,
388     const PhotoFileOperation::PhotoAssetInfo &targetPhotoInfo,
389     const std::string& srcFolder, const std::string& targetFolder)
390 {
391     bool cond = (srcFolder.empty() || targetFolder.empty());
392     CHECK_AND_RETURN_RET(!cond, E_OK);
393 
394     if (!MediaFileUtils::IsFileExists(srcFolder)) {
395         MEDIA_ERR_LOG("Media_Operation: %{public}s doesn't exist. %{public}s",
396             srcFolder.c_str(), this->ToString(sourcePhotoInfo).c_str());
397         return E_NO_SUCH_FILE;
398     }
399     int32_t opRet = MediaFileUtils::CopyDirectory(srcFolder, targetFolder);
400     CHECK_AND_RETURN_RET_LOG(opRet == E_OK, opRet,
401         "Media_Operation: CopyPhoto extraData failed, sourceInfo: %{public}s, targetInfo: %{public}s",
402         this->ToString(sourcePhotoInfo).c_str(), this->ToString(targetPhotoInfo).c_str());
403 
404     MEDIA_INFO_LOG("Media_Operation: CopyPhotoRelatedExtraData success, sourceInfo:%{public}s, targetInfo:%{public}s",
405         this->ToString(sourcePhotoInfo).c_str(), this->ToString(targetPhotoInfo).c_str());
406     return E_OK;
407 }
408 
409 /**
410  * @brief Copy the Edit Data.
411  * @return E_OK if success or not edited photo.
412  *         E_NO_SUCH_FILE if the source Edit Data Folder not exits.
413  *         E_FAIL if the copy operation failed.
414  */
CopyPhotoRelatedExtraData(const PhotoFileOperation::PhotoAssetInfo & sourcePhotoInfo,const PhotoFileOperation::PhotoAssetInfo & targetPhotoInfo)415 int32_t PhotoFileOperation::CopyPhotoRelatedExtraData(const PhotoFileOperation::PhotoAssetInfo &sourcePhotoInfo,
416     const PhotoFileOperation::PhotoAssetInfo &targetPhotoInfo)
417 {
418     std::string srcEditDataFolder = sourcePhotoInfo.editDataFolder;
419     std::string targetEditDataFolder = targetPhotoInfo.editDataFolder;
420     return CopyPhotoRelatedData(sourcePhotoInfo, targetPhotoInfo, srcEditDataFolder, targetEditDataFolder);
421 }
422 
423 /**
424  * @brief Copy the thumbnail Data.
425  * @return E_OK if success or not thumbnail folder.
426  *         E_NO_SUCH_FILE if the source Edit Data Folder not exits.
427  *         E_FAIL if the copy operation failed.
428  */
CopyPhotoRelatedThumbnail(const PhotoFileOperation::PhotoAssetInfo & sourcePhotoInfo,const PhotoFileOperation::PhotoAssetInfo & targetPhotoInfo)429 int32_t PhotoFileOperation::CopyPhotoRelatedThumbnail(const PhotoFileOperation::PhotoAssetInfo &sourcePhotoInfo,
430     const PhotoFileOperation::PhotoAssetInfo &targetPhotoInfo)
431 {
432     std::string srcThumbnailFolder = sourcePhotoInfo.thumbnailFolder;
433     std::string targetThumbnailFolder = targetPhotoInfo.thumbnailFolder;
434     int32_t opRet = CopyPhotoRelatedData(sourcePhotoInfo, targetPhotoInfo, srcThumbnailFolder, targetThumbnailFolder);
435     CHECK_AND_RETURN_RET_LOG(opRet == E_OK, opRet,
436         "Media_Operation: CopyPhoto thumbnail failed, srcPath: %{public}s, targetPath: %{public}s",
437         srcThumbnailFolder.c_str(), targetThumbnailFolder.c_str());
438 
439     return E_OK;
440 }
441 
442 /**
443  * @brief Copy File.
444  * @return E_OK if success,
445  *         E_INVALID_PATH if the source file or target file is invalid,
446  *         E_FILE_OPER_FAIL if the copy operation failed.
447  */
CopyFile(const std::string & srcPath,std::string & targetPath)448 int32_t PhotoFileOperation::CopyFile(const std::string &srcPath, std::string &targetPath)
449 {
450     if (srcPath.empty() || !MediaFileUtils::IsFileExists((srcPath)) || !MediaFileUtils::IsFileValid(srcPath)) {
451         MEDIA_ERR_LOG("Media_Operation: source file invalid! srcPath: %{public}s", srcPath.c_str());
452         return E_INVALID_PATH;
453     }
454     if (targetPath.empty()) {
455         MEDIA_ERR_LOG("Media_Operation: target file invalid! targetPath: %{public}s", targetPath.c_str());
456         return E_INVALID_PATH;
457     }
458     bool opRet = MediaFileUtils::CopyFileUtil(srcPath, targetPath);
459     opRet = opRet && MediaFileUtils::IsFileExists(targetPath);
460     if (!opRet) {
461         MEDIA_ERR_LOG("Media_Operation: CopyFile failed, filePath: %{public}s, errmsg: %{public}s",
462             srcPath.c_str(),
463             strerror(errno));
464         return E_FILE_OPER_FAIL;
465     }
466     return E_OK;
467 }
468 }  // namespace OHOS::Media