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