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