• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2023 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 "FileExtension"
16 
17 #include "media_file_extention_utils.h"
18 
19 #include <fcntl.h>
20 
21 #include "file_access_extension_info.h"
22 #include "media_file_uri.h"
23 #include "media_file_utils.h"
24 #include "media_log.h"
25 #include "media_thumbnail_helper.h"
26 #include "medialibrary_client_errno.h"
27 #include "medialibrary_data_manager.h"
28 #include "medialibrary_data_manager_utils.h"
29 #include "medialibrary_errno.h"
30 #include "medialibrary_object_utils.h"
31 #include "medialibrary_smartalbum_map_operations.h"
32 #include "medialibrary_type_const.h"
33 #include "media_file_utils.h"
34 #include "mimetype_utils.h"
35 #include "result_set_utils.h"
36 #include "scanner_utils.h"
37 #include "thumbnail_utils.h"
38 #include "n_error.h"
39 #include "unique_fd.h"
40 #include "userfile_manager_types.h"
41 
42 using namespace std;
43 using namespace OHOS::NativeRdb;
44 using namespace OHOS::DataShare;
45 using namespace OHOS::FileAccessFwk;
46 using namespace OHOS::FileManagement::LibN;
47 
48 namespace OHOS {
49 namespace Media {
50 namespace {
51     constexpr int64_t MAX_COUNT = 2000;
52     constexpr int COPY_EXCEPTION = -1;
53     constexpr int COPY_NOEXCEPTION = -2;
54 }
55 constexpr int32_t ALBUM_MODE_READONLY = DOCUMENT_FLAG_REPRESENTS_DIR | DOCUMENT_FLAG_SUPPORTS_READ;
56 constexpr int32_t ALBUM_MODE_RW =
57     DOCUMENT_FLAG_REPRESENTS_DIR | DOCUMENT_FLAG_SUPPORTS_READ | DOCUMENT_FLAG_SUPPORTS_WRITE;
58 constexpr int32_t FILE_MODE_RW =
59     DOCUMENT_FLAG_REPRESENTS_FILE | DOCUMENT_FLAG_SUPPORTS_READ | DOCUMENT_FLAG_SUPPORTS_WRITE;
60 
61 static const std::vector<std::string> FILEINFO_COLUMNS = {
62     MEDIA_DATA_DB_ID, MEDIA_DATA_DB_SIZE, MEDIA_DATA_DB_DATE_MODIFIED, MEDIA_DATA_DB_MIME_TYPE, MEDIA_DATA_DB_NAME,
63     MEDIA_DATA_DB_MEDIA_TYPE, MEDIA_DATA_DB_IS_TRASH, MEDIA_DATA_DB_RELATIVE_PATH
64 };
65 
66 static const std::unordered_map<int32_t, std::pair<int32_t, string>> mediaErrCodeMap {
67     { E_PERMISSION_DENIED, { FILEIO_SYS_CAP_TAG + E_PERM,        "Operation not permitted"                    } },
68     { E_NO_SUCH_FILE,      { FILEIO_SYS_CAP_TAG + E_NOENT,       "No such file or directory in media library" } },
69     { E_FILE_EXIST,        { FILEIO_SYS_CAP_TAG + E_EXIST,       "The file is exist in media library"         } },
70     { E_NO_MEMORY,         { FILEIO_SYS_CAP_TAG + E_NOMEM,       "Out of memory"                              } },
71     { E_URI_INVALID,       { OHOS::FileManagement::LibN::E_URIS, "Invalid URI"                                } },
72     { E_INVALID_URI,       { OHOS::FileManagement::LibN::E_URIS, "Invalid URI"                                } },
73 };
74 
75 #ifdef MEDIALIBRARY_COMPATIBILITY
CheckDestRelativePath(const string destRelativePath)76 bool CheckDestRelativePath(const string destRelativePath)
77 {
78     if (destRelativePath == "") {
79         return true;
80     }
81     size_t size = destRelativePath.find_first_of("/");
82     if (size == string::npos) {
83         return false;
84     }
85     string path = destRelativePath.substr(0, size + 1);
86     if ((path != DOC_DIR_VALUES) && (path != DOWNLOAD_DIR_VALUES)) {
87         return false;
88     }
89     return true;
90 }
91 #endif
92 
OpenFile(const Uri & uri,const int flags,int & fd)93 int MediaFileExtentionUtils::OpenFile(const Uri &uri, const int flags, int &fd)
94 {
95     fd = -1;
96     if (!CheckUriValid(uri.ToString())) {
97         return E_URI_INVALID;
98     }
99     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(uri.ToString());
100     if (!networkId.empty() && flags != O_RDONLY) {
101         return E_OPENFILE_INVALID_FLAG;
102     }
103     string mode;
104     if (flags == O_RDONLY) {
105         mode = MEDIA_FILEMODE_READONLY;
106     } else if (flags == O_WRONLY) {
107         mode = MEDIA_FILEMODE_WRITEONLY;
108     } else if (flags == O_RDWR) {
109         mode = MEDIA_FILEMODE_READWRITE;
110     } else {
111         MEDIA_ERR_LOG("invalid OpenFile flags %{public}d", flags);
112         return E_OPENFILE_INVALID_FLAG;
113     }
114 #ifdef MEDIALIBRARY_COMPATIBILITY
115     string realUri = MediaFileUtils::GetRealUriFromVirtualUri(uri.ToString());
116     MediaLibraryCommand cmd(Uri(realUri), OperationType::OPEN);
117 #else
118     MediaLibraryCommand cmd(uri, OperationType::OPEN);
119 #endif
120     auto ret = MediaLibraryDataManager::GetInstance()->OpenFile(cmd, mode);
121     if (ret > 0) {
122         fd = ret;
123     }
124     return ret;
125 }
126 
127 #ifdef MEDIALIBRARY_COMPATIBILITY
GetUriFromId(int32_t id,const string & networkId)128 static inline string GetUriFromId(int32_t id, const string &networkId)
129 {
130     int64_t fileId = MediaFileUtils::GetVirtualIdByType(id, MediaType::MEDIA_TYPE_FILE);
131     return MediaFileUri(MediaType::MEDIA_TYPE_FILE, to_string(fileId), networkId).ToString();
132 }
133 #endif
134 
CreateFile(const Uri & parentUri,const string & displayName,Uri & newFileUri)135 int MediaFileExtentionUtils::CreateFile(const Uri &parentUri, const string &displayName,  Uri &newFileUri)
136 {
137     if (MediaFileUtils::CheckFileDisplayName(displayName) < 0) {
138         MEDIA_ERR_LOG("invalid file displayName %{private}s", displayName.c_str());
139         return E_INVALID_DISPLAY_NAME;
140     }
141     string parentUriStr = parentUri.ToString();
142     auto ret = MediaFileExtentionUtils::CheckUriSupport(parentUriStr);
143     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid uri");
144     vector<string> columns = { MEDIA_DATA_DB_FILE_PATH };
145     auto result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_URI, parentUriStr, columns);
146     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_URI_INVALID, "CreateFile parent uri is not correct: %{public}s",
147         parentUriStr.c_str());
148     string albumPath = GetStringVal(MEDIA_DATA_DB_FILE_PATH, result);
149     result->Close();
150     string relativePath = albumPath.substr(ROOT_MEDIA_DIR.size()) + SLASH_CHAR;
151 #ifdef MEDIALIBRARY_COMPATIBILITY
152     if (!CheckDestRelativePath(relativePath)) {
153         return JS_ERR_PERMISSION_DENIED;
154     }
155 #endif
156     string destPath = albumPath + SLASH_CHAR + displayName;
157     DataShareValuesBucket valuesBucket;
158     valuesBucket.Put(MEDIA_DATA_DB_NAME, displayName);
159     valuesBucket.Put(MEDIA_DATA_DB_RELATIVE_PATH, relativePath);
160     valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, MediaFileUtils::GetMediaType(displayName));
161     Uri createFileUri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_FILEOPRN + SLASH_CHAR + MEDIA_FILEOPRN_CREATEASSET);
162     MediaLibraryCommand cmd(createFileUri);
163     ret = MediaLibraryDataManager::GetInstance()->Insert(cmd, valuesBucket);
164     if (ret > 0) {
165 #ifdef MEDIALIBRARY_COMPATIBILITY
166         newFileUri = Uri(GetUriFromId(ret, ""));
167 #else
168         newFileUri = Uri(MediaFileUtils::GetUriByNameAndId(displayName, "", ret));
169 #endif
170     }
171     return ret;
172 }
173 
Mkdir(const Uri & parentUri,const string & displayName,Uri & newFileUri)174 int MediaFileExtentionUtils::Mkdir(const Uri &parentUri, const string &displayName, Uri &newFileUri)
175 {
176     string parentUriStr = parentUri.ToString();
177     MediaFileUriType uriType;
178     FileAccessFwk::FileInfo parentInfo;
179     parentInfo.uri = parentUriStr;
180     auto ret = MediaFileExtentionUtils::ResolveUri(parentInfo, uriType);
181     if (ret != E_SUCCESS) {
182         MEDIA_ERR_LOG("Mkdir::invalid input fileInfo");
183         return ret;
184     }
185     string relativePath;
186     ret = MediaFileExtentionUtils::CheckMkdirValid(uriType, parentUriStr, displayName);
187     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid uri");
188     if (uriType != MediaFileUriType::URI_FILE_ROOT) {
189         CHECK_AND_RETURN_RET_LOG(MediaFileExtentionUtils::GetAlbumRelativePathFromDB(parentUriStr, relativePath),
190             E_URI_IS_NOT_ALBUM, "selectUri is not valid album uri %{public}s", parentUriStr.c_str());
191     }
192     Uri mkdirUri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_DIROPRN + SLASH_CHAR + MEDIA_DIROPRN_FMS_CREATEDIR);
193     string dirPath = ROOT_MEDIA_DIR + relativePath + displayName;
194     if (MediaFileExtentionUtils::IsFileExistInDb(dirPath)) {
195         MEDIA_ERR_LOG("Create dir is existed %{private}s", dirPath.c_str());
196         return E_FILE_EXIST;
197     }
198     relativePath = relativePath + displayName + SLASH_CHAR;
199 #ifdef MEDIALIBRARY_COMPATIBILITY
200     if (!CheckDestRelativePath(relativePath)) {
201         return JS_ERR_PERMISSION_DENIED;
202     }
203 #endif
204     DataShareValuesBucket valuesBucket;
205     valuesBucket.Put(MEDIA_DATA_DB_RELATIVE_PATH, relativePath);
206     MediaLibraryCommand cmd(mkdirUri);
207     ret = MediaLibraryDataManager::GetInstance()->Insert(cmd, valuesBucket);
208     if (ret > 0) {
209 #ifdef MEDIALIBRARY_COMPATIBILITY
210         newFileUri = Uri(GetUriFromId(ret, ""));
211 #else
212         newFileUri = Uri(MediaFileUtils::GetUriByNameAndId(displayName, "", ret));
213 #endif
214     }
215     return ret;
216 }
217 
Delete(const Uri & sourceFileUri)218 int MediaFileExtentionUtils::Delete(const Uri &sourceFileUri)
219 {
220     string sourceUri = sourceFileUri.ToString();
221     auto ret = MediaFileExtentionUtils::CheckUriSupport(sourceUri);
222     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid uri");
223     vector<string> columns = { MEDIA_DATA_DB_MEDIA_TYPE, MEDIA_DATA_DB_RELATIVE_PATH };
224     auto result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_URI, sourceUri, columns);
225     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_URI_INVALID, "GetResultSetFromDb failed, uri: %{public}s",
226         sourceUri.c_str());
227 #ifdef MEDIALIBRARY_COMPATIBILITY
228     string relativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
229     if (!CheckDestRelativePath(relativePath)) {
230         return JS_ERR_PERMISSION_DENIED;
231     }
232 #endif
233     int mediaType = GetInt32Val(MEDIA_DATA_DB_MEDIA_TYPE, result);
234     result->Close();
235     int fileId = stoi(MediaLibraryDataManagerUtils::GetIdFromUri(sourceUri));
236     DataShareValuesBucket valuesBucket;
237     if (mediaType == MEDIA_TYPE_ALBUM) {
238 #ifdef MEDIALIBRARY_COMPATIBILITY
239         valuesBucket.Put(MEDIA_DATA_DB_ID,
240             (int) MediaFileUtils::GetRealIdByTable(fileId, MEDIALIBRARY_TABLE));
241 #else
242         valuesBucket.Put(MEDIA_DATA_DB_ID, fileId);
243 #endif
244         Uri trashAlbumUri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_DIROPRN + SLASH_CHAR +
245             MEDIA_DIROPRN_FMS_TRASHDIR);
246         MediaLibraryCommand cmd(trashAlbumUri);
247         ret = MediaLibraryDataManager::GetInstance()->Insert(cmd, valuesBucket);
248     } else {
249         valuesBucket.Put(SMARTALBUMMAP_DB_ALBUM_ID, TRASH_ALBUM_ID_VALUES);
250 #ifdef MEDIALIBRARY_COMPATIBILITY
251         valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID,
252             (int) MediaFileUtils::GetRealIdByTable(fileId, MEDIALIBRARY_TABLE));
253 #else
254         valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID, fileId);
255 #endif
256         Uri trashAssetUri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_SMARTALBUMMAPOPRN + SLASH_CHAR +
257             MEDIA_SMARTALBUMMAPOPRN_ADDSMARTALBUM);
258         MediaLibraryCommand cmd(trashAssetUri);
259         ret = MediaLibraryDataManager::GetInstance()->Insert(cmd, valuesBucket);
260     }
261     return ret;
262 }
263 
CheckUriValid(const string & uri)264 bool MediaFileExtentionUtils::CheckUriValid(const string &uri)
265 {
266     return MediaFileUri(uri).IsValid();
267 }
268 
CheckDistributedUri(const string & uri)269 bool MediaFileExtentionUtils::CheckDistributedUri(const string &uri)
270 {
271     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(uri);
272     if (!networkId.empty()) {
273         MEDIA_ERR_LOG("not support distributed operation %{public}s", uri.c_str());
274         return false;
275     }
276     return true;
277 }
278 
CheckUriSupport(const string & uri)279 int32_t MediaFileExtentionUtils::CheckUriSupport(const string &uri)
280 {
281     if (!MediaFileExtentionUtils::CheckUriValid(uri)) {
282         MEDIA_ERR_LOG("Invalid uri");
283         return E_URI_INVALID;
284     }
285     if (!MediaFileExtentionUtils::CheckDistributedUri(uri)) {
286         MEDIA_ERR_LOG("CreateFile not support distributed operation");
287         return E_DISTIBUTED_URI_NO_SUPPORT;
288     }
289     return E_SUCCESS;
290 }
291 
GetResultSetFromDb(string field,const string & value,const vector<string> & columns)292 shared_ptr<NativeRdb::ResultSet> MediaFileExtentionUtils::GetResultSetFromDb(string field, const string &value,
293     const vector<string> &columns)
294 {
295     string networkId;
296     string input = value;
297     if (field == MEDIA_DATA_DB_URI) {
298         field = MEDIA_DATA_DB_ID;
299         networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(input);
300         input = MediaLibraryDataManagerUtils::GetIdFromUri(input);
301     }
302     Uri queryUri(MEDIALIBRARY_DATA_ABILITY_PREFIX + networkId + MEDIALIBRARY_DATA_URI_IDENTIFIER);
303     MediaLibraryCommand cmd(queryUri, OperationType::QUERY);
304     DataSharePredicates predicates;
305     predicates.EqualTo(field, input)->And()->EqualTo(MEDIA_DATA_DB_IS_TRASH, NOT_TRASHED);
306     int errCode = 0;
307     auto queryResultSet = MediaLibraryDataManager::GetInstance()->QueryRdb(cmd, columns, predicates, errCode);
308     CHECK_AND_RETURN_RET_LOG(queryResultSet != nullptr, nullptr,
309         "Failed to obtain value from database, field: %{public}s, value: %{public}s", field.c_str(), input.c_str());
310     auto ret = queryResultSet->GoToFirstRow();
311     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, nullptr, "Failed to shift at first row, ret: %{public}d", ret);
312     return queryResultSet;
313 }
314 
IsFileExistInDb(const std::string & path)315 bool MediaFileExtentionUtils::IsFileExistInDb(const std::string &path)
316 {
317     vector<string> columns = { MEDIA_DATA_DB_ID };
318     return (GetResultSetFromDb(MEDIA_DATA_DB_FILE_PATH, path, columns) != nullptr);
319 }
320 
ResolveRootUri(string uri,MediaFileUriType & uriType)321 int32_t ResolveRootUri(string uri, MediaFileUriType &uriType)
322 {
323     int32_t ret = E_INVALID_URI;
324     uri = uri.substr(MEDIALIBRARY_ROOT.length());
325     if (uri == MEDIALIBRARY_TYPE_FILE_URI) {
326         uriType = MediaFileUriType::URI_FILE_ROOT;
327         ret = E_SUCCESS;
328     } else if ((uri == MEDIALIBRARY_TYPE_IMAGE_URI) ||
329                (uri == MEDIALIBRARY_TYPE_VIDEO_URI) ||
330                (uri == MEDIALIBRARY_TYPE_AUDIO_URI)) {
331         uriType = MediaFileUriType::URI_MEDIA_ROOT;
332         ret = E_SUCCESS;
333     }
334     return ret;
335 }
336 
337 #ifndef MEDIALIBRARY_COMPATIBILITY
ResolveUriWithType(const string & mimeType,MediaFileUriType & uriType)338 int32_t ResolveUriWithType(const string &mimeType, MediaFileUriType &uriType)
339 {
340     if ((mimeType.find(DEFAULT_IMAGE_MIME_TYPE_PREFIX) == 0) ||
341         (mimeType.find(DEFAULT_VIDEO_MIME_TYPE_PREFIX) == 0) ||
342         (mimeType.find(DEFAULT_AUDIO_MIME_TYPE_PREFIX) == 0)) {
343         uriType = MediaFileUriType::URI_ALBUM;
344         return E_SUCCESS;
345     }
346     uriType = MediaFileUriType::URI_DIR;
347     return E_SUCCESS;
348 }
349 #endif
350 
351 /**
352  * URI_ROOT Return four uri of media type(images, audios, videos and file).
353  *  datashare:///media/root
354  * URI_MEDIA_ROOT Return all albums of the specified type.
355  *  datashare:///media/root/image|audio|video
356  * URI_FILE_ROOT Return the files and folders under the root directory.
357  *  datashare:///media/root/file
358  * URI_DIR Return the files and folders in the directory.
359  *  datashare:///media/file/1
360  */
ResolveUri(const FileInfo & fileInfo,MediaFileUriType & uriType)361 int32_t MediaFileExtentionUtils::ResolveUri(const FileInfo &fileInfo, MediaFileUriType &uriType)
362 {
363     MediaFileUri uri(fileInfo.uri);
364     string scheme = uri.GetScheme();
365     if (scheme != ML_FILE_SCHEME &&
366         scheme != ML_DATA_SHARE_SCHEME) {
367         return E_INVALID_URI;
368     }
369 
370     if (uri.ToString().find(MEDIALIBRARY_DATA_URI_IDENTIFIER) == string::npos) {
371         return E_INVALID_URI;
372     }
373 
374     string path = uri.GetPath();
375     if (scheme == ML_DATA_SHARE_SCHEME) {
376         if (path.length() > MEDIALIBRARY_DATA_URI_IDENTIFIER.length()) {
377             path = path.substr(MEDIALIBRARY_DATA_URI_IDENTIFIER.length());
378         } else {
379             return E_INVALID_URI;
380         }
381     }
382 
383     if (path == MEDIALIBRARY_ROOT) {
384         uriType = MediaFileUriType::URI_ROOT;
385         return E_SUCCESS;
386     }
387     if (path.find(MEDIALIBRARY_ROOT) == 0) {
388         return ResolveRootUri(path, uriType);
389     }
390     if (path.find(MEDIALIBRARY_TYPE_FILE_URI) == 0) {
391 #ifndef MEDIALIBRARY_COMPATIBILITY
392         return ResolveUriWithType(fileInfo.mimeType, uriType);
393 #else
394         uriType = MediaFileUriType::URI_DIR;
395         return E_SUCCESS;
396 #endif
397     }
398     if (MediaFileExtentionUtils::CheckUriValid(fileInfo.uri)) {
399         uriType = MediaFileUriType::URI_FILE;
400         return E_SUCCESS;
401     }
402 
403     return E_INVALID_URI;
404 }
405 
CheckValidDirName(const string & displayName)406 bool MediaFileExtentionUtils::CheckValidDirName(const string &displayName)
407 {
408     for (auto &dir : directoryEnumValues) {
409         if (displayName == dir) {
410             return true;
411         }
412     }
413     return false;
414 }
415 
CheckMkdirValid(MediaFileUriType uriType,const string & parentUriStr,const string & displayName)416 int32_t MediaFileExtentionUtils::CheckMkdirValid(MediaFileUriType uriType, const string &parentUriStr,
417     const string &displayName)
418 {
419     if (uriType == MediaFileUriType::URI_FILE_ROOT) {
420         CHECK_AND_RETURN_RET_LOG(MediaFileExtentionUtils::CheckDistributedUri(parentUriStr),
421             E_DISTIBUTED_URI_NO_SUPPORT, "Mkdir not support distributed operation");
422         CHECK_AND_RETURN_RET_LOG(MediaFileExtentionUtils::CheckValidDirName(displayName + SLASH_CHAR),
423             E_INVALID_DISPLAY_NAME, "invalid directory displayName %{private}s", displayName.c_str());
424     } else {
425         auto ret = MediaFileExtentionUtils::CheckUriSupport(parentUriStr);
426         CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid uri");
427         CHECK_AND_RETURN_RET_LOG(MediaFileUtils::CheckDentryName(displayName) == E_OK,
428             E_INVALID_DISPLAY_NAME, "invalid directory displayName %{private}s", displayName.c_str());
429     }
430     return E_SUCCESS;
431 }
432 
GetAlbumRelativePathFromDB(const string & selectUri,string & relativePath)433 bool MediaFileExtentionUtils::GetAlbumRelativePathFromDB(const string &selectUri, string &relativePath)
434 {
435     vector<string> columns = { MEDIA_DATA_DB_NAME, MEDIA_DATA_DB_MEDIA_TYPE, MEDIA_DATA_DB_RELATIVE_PATH };
436     auto result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_URI, selectUri, columns);
437     CHECK_AND_RETURN_RET_LOG(result != nullptr, false, "Get album relativePath failed.");
438     int mediaType = GetInt32Val(MEDIA_DATA_DB_MEDIA_TYPE, result);
439     CHECK_AND_RETURN_RET_LOG(mediaType == MEDIA_TYPE_ALBUM, false, "selectUri is not album");
440     relativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
441     relativePath += GetStringVal(MEDIA_DATA_DB_NAME, result) + SLASH_CHAR;
442     return true;
443 }
444 
GetQueryUri(const FileInfo & parentInfo,MediaFileUriType uriType)445 string GetQueryUri(const FileInfo &parentInfo, MediaFileUriType uriType)
446 {
447     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
448     string queryUri = MEDIALIBRARY_DATA_ABILITY_PREFIX + networkId + MEDIALIBRARY_DATA_URI_IDENTIFIER;
449     if (uriType == URI_MEDIA_ROOT) {
450 #ifndef MEDIALIBRARY_COMPATIBILITY
451         queryUri += SLASH_CHAR + MEDIA_ALBUMOPRN_QUERYALBUM;
452 #else
453         int32_t mediaType = MimeTypeUtils::GetMediaTypeFromMimeType(parentInfo.mimeType);
454         switch (mediaType) {
455             case MEDIA_TYPE_IMAGE:
456             case MEDIA_TYPE_VIDEO:
457                 queryUri += SLASH_CHAR + MEDIA_PHOTOOPRN + SLASH_CHAR + OPRN_QUERY;
458                 break;
459             case MEDIA_TYPE_AUDIO:
460                 queryUri += SLASH_CHAR + MEDIA_AUDIOOPRN + SLASH_CHAR + OPRN_QUERY;
461                 break;
462             case MEDIA_TYPE_FILE:
463             default:
464                 MEDIA_ERR_LOG("GetMediaTypeFromMimeType failed");
465                 break;
466         }
467         MediaFileUtils::UriAppendKeyValue(queryUri, URI_PARAM_API_VERSION);
468 #endif
469     }
470     return queryUri;
471 }
472 
ChangeToLowerCase(vector<string> & vec)473 void ChangeToLowerCase(vector<string> &vec)
474 {
475     for (auto &s : vec) {
476         transform(s.begin(), s.end(), s.begin(), ::tolower);
477     }
478 }
479 
GetListFilePredicates(const FileInfo & parentInfo,const FileAccessFwk::FileFilter & filter,string & selection,vector<string> & selectionArgs)480 int32_t GetListFilePredicates(const FileInfo &parentInfo, const FileAccessFwk::FileFilter &filter, string &selection,
481     vector<string> &selectionArgs)
482 {
483     string selectUri = parentInfo.uri;
484     if (!MediaFileExtentionUtils::CheckUriValid(selectUri)) {
485         MEDIA_ERR_LOG("selectUri is not valid uri %{public}s", selectUri.c_str());
486         return E_URI_INVALID;
487     }
488     string relativePath;
489     if (!MediaFileExtentionUtils::GetAlbumRelativePathFromDB(selectUri, relativePath)) {
490         MEDIA_ERR_LOG("selectUri is not valid album uri %{public}s", selectUri.c_str());
491         return E_URI_IS_NOT_ALBUM;
492     }
493     selection = MEDIA_DATA_DB_RELATIVE_PATH + " = ? AND " + MEDIA_DATA_DB_IS_TRASH + " = ? ";
494     selectionArgs = { relativePath, to_string(NOT_TRASHED) };
495     if (!filter.GetHasFilter()) {
496         return E_SUCCESS;
497     }
498     vector<string> displayName = filter.GetDisplayName();
499     ChangeToLowerCase(displayName);
500     if (!displayName.empty()) {
501         selection += " AND (" + MEDIA_DATA_DB_TITLE + " = ? ";
502         selectionArgs.push_back(displayName[0]);
503         for (size_t i = 1; i < displayName.size(); i++) {
504             selection += " OR " + MEDIA_DATA_DB_TITLE + " = ? ";
505             selectionArgs.push_back(displayName[i]);
506         }
507         selection += ") ";
508     }
509     vector<string> suffix = filter.GetSuffix();
510     ChangeToLowerCase(suffix);
511     if (!suffix.empty()) {
512         selection += " AND ( " + MEDIA_DATA_DB_NAME + " LIKE ? ";
513         selectionArgs.push_back("%" + suffix[0]);
514         for (size_t i = 1; i < suffix.size(); i++) {
515             selection += " OR " + MEDIA_DATA_DB_NAME + " LIKE ? ";
516             selectionArgs.push_back("%" + suffix[i]);
517         }
518         selection += ") ";
519     }
520     return E_SUCCESS;
521 }
522 
RootListFile(const FileInfo & parentInfo,vector<FileInfo> & fileList)523 static int32_t RootListFile(const FileInfo &parentInfo, vector<FileInfo> &fileList)
524 {
525     string selectUri = parentInfo.uri;
526     fileList.emplace_back(selectUri + MEDIALIBRARY_TYPE_FILE_URI, "", "MEDIA_TYPE_FILE", ALBUM_MODE_READONLY,
527         DEFAULT_FILE_MIME_TYPE);
528     fileList.emplace_back(selectUri + MEDIALIBRARY_TYPE_IMAGE_URI, "", "MEDIA_TYPE_IMAGE", ALBUM_MODE_READONLY,
529         DEFAULT_IMAGE_MIME_TYPE);
530     fileList.emplace_back(selectUri + MEDIALIBRARY_TYPE_VIDEO_URI, "", "MEDIA_TYPE_VIDEO", ALBUM_MODE_READONLY,
531         DEFAULT_VIDEO_MIME_TYPE);
532     fileList.emplace_back(selectUri + MEDIALIBRARY_TYPE_AUDIO_URI, "", "MEDIA_TYPE_AUDIO", ALBUM_MODE_READONLY,
533         DEFAULT_AUDIO_MIME_TYPE);
534     return E_SUCCESS;
535 }
536 
GetResult(const Uri & uri,MediaFileUriType uriType,const string & selection,const vector<string> & selectionArgs)537 shared_ptr<NativeRdb::ResultSet> GetResult(const Uri &uri, MediaFileUriType uriType, const string &selection,
538     const vector<string> &selectionArgs)
539 {
540     MediaLibraryCommand cmd(uri, OperationType::QUERY);
541     DataSharePredicates predicates;
542     predicates.SetWhereClause(selection);
543     predicates.SetWhereArgs(selectionArgs);
544     int errCode = 0;
545     vector<string> columns = { MEDIA_DATA_DB_ID, MEDIA_DATA_DB_SIZE, MEDIA_DATA_DB_DATE_ADDED,
546         MEDIA_DATA_DB_DATE_MODIFIED, MEDIA_DATA_DB_MIME_TYPE, MEDIA_DATA_DB_NAME, MEDIA_DATA_DB_MEDIA_TYPE,
547         MEDIA_DATA_DB_RELATIVE_PATH };
548     return MediaLibraryDataManager::GetInstance()->QueryRdb(cmd, columns, predicates, errCode);
549 }
550 
MimeType2MediaType(const string & mimeType)551 static string MimeType2MediaType(const string &mimeType)
552 {
553     // album view not support file type, so image as default
554     int res = MEDIA_TYPE_IMAGE;
555     if (mimeType.find(DEFAULT_VIDEO_MIME_TYPE_PREFIX) == 0) {
556         res = MEDIA_TYPE_VIDEO;
557     } else if (mimeType.find(DEFAULT_AUDIO_MIME_TYPE_PREFIX) == 0) {
558         res = MEDIA_TYPE_AUDIO;
559     }
560     return to_string(res);
561 }
562 
GetMediaRootResult(const FileInfo & parentInfo,MediaFileUriType uriType,const int64_t offset,const int64_t maxCount)563 shared_ptr<NativeRdb::ResultSet> GetMediaRootResult(const FileInfo &parentInfo, MediaFileUriType uriType,
564     const int64_t offset, const int64_t maxCount)
565 {
566 #ifndef MEDIALIBRARY_COMPATIBILITY
567     Uri uri(GetQueryUri(parentInfo, uriType));
568     MediaLibraryCommand cmd(uri, OperationType::QUERY);
569     DataSharePredicates predicates;
570     predicates.EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, MimeType2MediaType(parentInfo.mimeType));
571     predicates.EqualTo(MEDIA_DATA_DB_IS_TRASH, to_string(NOT_TRASHED));
572     predicates.Limit(maxCount, offset);
573     int errCode = 0;
574     vector<string> columns = { MEDIA_DATA_DB_BUCKET_ID, MEDIA_DATA_DB_TITLE, MEDIA_DATA_DB_DATE_MODIFIED,
575         MEDIA_DATA_DB_RELATIVE_PATH };
576 #else
577     Uri uri(GetQueryUri(parentInfo, uriType));
578     DataSharePredicates predicates;
579     predicates.EqualTo(MediaColumn::MEDIA_TYPE, MimeType2MediaType(parentInfo.mimeType));
580     predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(NOT_TRASHED));
581     if ((MimeTypeUtils::GetMediaTypeFromMimeType(parentInfo.mimeType) == MEDIA_TYPE_IMAGE) ||
582         (MimeTypeUtils::GetMediaTypeFromMimeType(parentInfo.mimeType) == MEDIA_TYPE_VIDEO)) {
583         predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(0));
584     }
585     predicates.Limit(maxCount, offset);
586     int errCode = 0;
587     vector<string> columns = { MediaColumn::MEDIA_RELATIVE_PATH, MediaColumn::MEDIA_NAME, MediaColumn::MEDIA_ID,
588         MediaColumn::MEDIA_DATE_MODIFIED };
589 #endif
590     MediaLibraryCommand cmd(uri, OperationType::QUERY);
591     return MediaLibraryDataManager::GetInstance()->QueryRdb(cmd, columns, predicates, errCode);
592 }
593 
GetListRootResult(const FileInfo & parentInfo,MediaFileUriType uriType,const int64_t offset,const int64_t maxCount)594 shared_ptr<NativeRdb::ResultSet> GetListRootResult(const FileInfo &parentInfo, MediaFileUriType uriType,
595     const int64_t offset, const int64_t maxCount)
596 {
597 #ifndef MEDIALIBRARY_COMPATIBILITY
598     string selection = MEDIA_DATA_DB_PARENT_ID + " = ? AND " + MEDIA_DATA_DB_MEDIA_TYPE + " <> ? AND " +
599         MEDIA_DATA_DB_IS_TRASH + " = ? LIMIT " + to_string(offset) + ", " + to_string(maxCount);
600     vector<string> selectionArgs = { to_string(ROOT_PARENT_ID), to_string(MEDIA_TYPE_NOFILE), to_string(NOT_TRASHED) };
601     Uri uri(GetQueryUri(parentInfo, uriType));
602     return GetResult(uri, uriType, selection, selectionArgs);
603 #else
604     string selection = MEDIA_DATA_DB_PARENT_ID + " = ? AND " + MEDIA_DATA_DB_MEDIA_TYPE + " = ? AND " +
605         MEDIA_DATA_DB_IS_TRASH + " = ? LIMIT " + to_string(offset) + ", " + to_string(maxCount);
606     vector<string> selectionArgs = { to_string(ROOT_PARENT_ID), to_string(MEDIA_TYPE_ALBUM), to_string(NOT_TRASHED) };
607     Uri uri(GetQueryUri(parentInfo, uriType));
608     return GetResult(uri, uriType, selection, selectionArgs);
609 #endif
610 }
611 
GetListDirResult(const FileInfo & parentInfo,MediaFileUriType uriType,const int64_t offset,const int64_t maxCount,const FileAccessFwk::FileFilter & filter)612 shared_ptr<NativeRdb::ResultSet> GetListDirResult(const FileInfo &parentInfo, MediaFileUriType uriType,
613     const int64_t offset, const int64_t maxCount, const FileAccessFwk::FileFilter &filter)
614 {
615     string selection;
616     vector<string> selectionArgs;
617     int32_t ret = GetListFilePredicates(parentInfo, filter, selection, selectionArgs);
618     if (ret != E_SUCCESS) {
619         return nullptr;
620     }
621     selection += " AND " + MEDIA_DATA_DB_MEDIA_TYPE + " <> ? LIMIT " + to_string(offset) + ", " + to_string(maxCount);
622     selectionArgs.push_back(to_string(MEDIA_TYPE_NOFILE));
623     Uri uri(GetQueryUri(parentInfo, uriType));
624     return GetResult(uri, uriType, selection, selectionArgs);
625 }
626 
627 #ifndef MEDIALIBRARY_COMPATIBILITY
GetListAlbumResult(const FileInfo & parentInfo,MediaFileUriType uriType,const int64_t offset,const int64_t maxCount,const FileAccessFwk::FileFilter & filter)628 shared_ptr<NativeRdb::ResultSet> GetListAlbumResult(const FileInfo &parentInfo, MediaFileUriType uriType,
629     const int64_t offset, const int64_t maxCount, const FileAccessFwk::FileFilter &filter)
630 {
631     string selection;
632     vector<string> selectionArgs;
633     int32_t ret = GetListFilePredicates(parentInfo, filter, selection, selectionArgs);
634     if (ret != E_SUCCESS) {
635         return nullptr;
636     }
637     selection += " AND " + MEDIA_DATA_DB_MEDIA_TYPE + " = ? LIMIT " + to_string(offset) + ", " + to_string(maxCount);
638     selectionArgs.push_back(MimeType2MediaType(parentInfo.mimeType));
639     Uri uri(GetQueryUri(parentInfo, uriType));
640     return GetResult(uri, uriType, selection, selectionArgs);
641 }
642 #endif
643 
GetFileInfo(FileInfo & fileInfo,const shared_ptr<NativeRdb::ResultSet> & result,const string & networkId="")644 int GetFileInfo(FileInfo &fileInfo, const shared_ptr<NativeRdb::ResultSet> &result, const string &networkId = "")
645 {
646     int64_t fileId = GetInt32Val(MEDIA_DATA_DB_ID, result);
647     int mediaType = GetInt32Val(MEDIA_DATA_DB_MEDIA_TYPE, result);
648 #ifdef MEDIALIBRARY_COMPATIBILITY
649     fileId = MediaFileUtils::GetVirtualIdByType(fileId, MediaType::MEDIA_TYPE_FILE);
650     fileInfo.uri = MediaFileUri(MediaType::MEDIA_TYPE_FILE, to_string(fileId), networkId).ToString();
651 #else
652     fileInfo.uri = MediaFileUri(MediaType(mediaType), to_string(fileId), networkId).ToString();
653 #endif
654     fileInfo.relativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
655     fileInfo.fileName = GetStringVal(MEDIA_DATA_DB_NAME, result);
656     fileInfo.mimeType = GetStringVal(MEDIA_DATA_DB_MIME_TYPE, result);
657     if (mediaType == MEDIA_TYPE_ALBUM) {
658         fileInfo.mode = ALBUM_MODE_RW;
659     } else {
660         fileInfo.size = GetInt64Val(MEDIA_DATA_DB_SIZE, result);
661         fileInfo.mode = FILE_MODE_RW;
662     }
663     fileInfo.mtime = GetInt64Val(MEDIA_DATA_DB_DATE_MODIFIED, result);
664     return E_SUCCESS;
665 }
666 
667 #ifndef MEDIALIBRARY_COMPATIBILITY
GetAlbumInfoFromResult(const FileInfo & parentInfo,shared_ptr<NativeRdb::ResultSet> & result,vector<FileInfo> & fileList)668 int32_t GetAlbumInfoFromResult(const FileInfo &parentInfo, shared_ptr<NativeRdb::ResultSet> &result,
669     vector<FileInfo> &fileList)
670 {
671     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_FAIL, "ResultSet is nullptr");
672     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
673     FileInfo fileInfo;
674     while (result->GoToNextRow() == NativeRdb::E_OK) {
675         int fileId = GetInt32Val(MEDIA_DATA_DB_BUCKET_ID, result);
676         fileInfo.fileName = GetStringVal(MEDIA_DATA_DB_TITLE, result);
677         fileInfo.mimeType = parentInfo.mimeType;
678         fileInfo.uri = MediaFileUri(MEDIA_TYPE_ALBUM, to_string(fileId), networkId).ToString();
679         fileInfo.relativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
680         fileInfo.mtime = GetInt64Val(MEDIA_DATA_DB_DATE_MODIFIED, result);
681         fileInfo.mode = ALBUM_MODE_RW;
682         fileList.push_back(fileInfo);
683     }
684     return E_SUCCESS;
685 }
686 #else
GetMediaFileInfoFromResult(const FileInfo & parentInfo,shared_ptr<NativeRdb::ResultSet> & result,vector<FileInfo> & fileList)687 int32_t GetMediaFileInfoFromResult(const FileInfo &parentInfo, shared_ptr<NativeRdb::ResultSet> &result,
688     vector<FileInfo> &fileList)
689 {
690     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_FAIL, "ResultSet is nullptr");
691     FileInfo fileInfo;
692     while (result->GoToNextRow() == NativeRdb::E_OK) {
693         int fileId = GetInt32Val(MediaColumn::MEDIA_ID, result);
694         fileInfo.fileName = GetStringVal(MEDIA_DATA_DB_TITLE, result);
695         fileInfo.mimeType = parentInfo.mimeType;
696         fileInfo.uri = MediaFileUri(MEDIA_TYPE_ALBUM, to_string(fileId), "").ToString();
697         fileInfo.relativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
698         fileInfo.mtime = GetInt64Val(MEDIA_DATA_DB_DATE_MODIFIED, result);
699         fileInfo.mode = ALBUM_MODE_RW;
700         fileList.push_back(fileInfo);
701     }
702     return E_SUCCESS;
703 }
704 #endif
705 
706 #ifndef MEDIALIBRARY_COMPATIBILITY
GetFileInfoFromResult(const FileInfo & parentInfo,shared_ptr<NativeRdb::ResultSet> & result,vector<FileInfo> & fileList)707 int32_t GetFileInfoFromResult(const FileInfo &parentInfo, shared_ptr<NativeRdb::ResultSet> &result,
708     vector<FileInfo> &fileList)
709 {
710     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_FAIL, "ResultSet is nullptr");
711     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
712     while (result->GoToNextRow() == NativeRdb::E_OK) {
713         FileInfo fileInfo;
714         GetFileInfo(fileInfo, result, networkId);
715         fileList.push_back(fileInfo);
716     }
717     return E_SUCCESS;
718 }
719 #else
GetFileInfoFromResult(const FileInfo & parentInfo,shared_ptr<NativeRdb::ResultSet> & result,vector<FileInfo> & fileList,MediaFileUriType uriType)720 int32_t GetFileInfoFromResult(const FileInfo &parentInfo, shared_ptr<NativeRdb::ResultSet> &result,
721     vector<FileInfo> &fileList, MediaFileUriType uriType)
722 {
723     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_FAIL, "ResultSet is nullptr");
724     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
725     while (result->GoToNextRow() == NativeRdb::E_OK) {
726         FileInfo fileInfo;
727         GetFileInfo(fileInfo, result, networkId);
728         switch (uriType) {
729             case URI_FILE_ROOT:
730                 if (fileInfo.relativePath == "" && (fileInfo.fileName == "Documents" ||
731                     fileInfo.fileName == "Download")) {
732                     fileList.push_back(fileInfo);
733                 }
734                 break;
735             case URI_DIR:
736                 fileList.push_back(fileInfo);
737                 break;
738             default:
739                 return E_FAIL;
740         }
741     }
742     return E_SUCCESS;
743 }
744 #endif
745 
ListFile(const FileInfo & parentInfo,const int64_t offset,const int64_t maxCount,const FileAccessFwk::FileFilter & filter,vector<FileInfo> & fileList)746 int32_t MediaFileExtentionUtils::ListFile(const FileInfo &parentInfo, const int64_t offset, const int64_t maxCount,
747     const FileAccessFwk::FileFilter &filter, vector<FileInfo> &fileList)
748 {
749     MediaFileUriType uriType;
750     auto ret = MediaFileExtentionUtils::ResolveUri(parentInfo, uriType);
751     MEDIA_DEBUG_LOG("ListFile:: uriType: %d", uriType);
752     if (ret != E_SUCCESS) {
753         MEDIA_ERR_LOG("ResolveUri::invalid input fileInfo");
754         return ret;
755     }
756     shared_ptr<NativeRdb::ResultSet> result = nullptr;
757     switch (uriType) {
758         case URI_ROOT:
759             return RootListFile(parentInfo, fileList);
760 #ifndef MEDIALIBRARY_COMPATIBILITY
761         case URI_MEDIA_ROOT:
762             result = GetMediaRootResult(parentInfo, uriType, offset, maxCount);
763             return GetAlbumInfoFromResult(parentInfo, result, fileList);
764         case URI_FILE_ROOT:
765             result = GetListRootResult(parentInfo, uriType, offset, maxCount);
766             return GetFileInfoFromResult(parentInfo, result, fileList);
767         case URI_DIR:
768             result = GetListDirResult(parentInfo, uriType, offset, maxCount, filter);
769             return GetFileInfoFromResult(parentInfo, result, fileList);
770         case URI_ALBUM:
771             result = GetListAlbumResult(parentInfo, uriType, offset, maxCount, filter);
772             return GetFileInfoFromResult(parentInfo, result, fileList);
773 #else
774         case URI_MEDIA_ROOT:
775             result = GetMediaRootResult(parentInfo, uriType, offset, maxCount);
776             return GetMediaFileInfoFromResult(parentInfo, result, fileList);
777         case URI_FILE_ROOT:
778             result = GetListRootResult(parentInfo, uriType, offset, maxCount);
779             return GetFileInfoFromResult(parentInfo, result, fileList, uriType);
780         case URI_DIR:
781             result = GetListDirResult(parentInfo, uriType, offset, maxCount, filter);
782             return GetFileInfoFromResult(parentInfo, result, fileList, uriType);
783 #endif
784         default:
785             return E_FAIL;
786     }
787 }
788 
GetScanFileFileInfoFromResult(const FileInfo & parentInfo,shared_ptr<NativeRdb::ResultSet> & result,vector<FileInfo> & fileList)789 int32_t GetScanFileFileInfoFromResult(const FileInfo &parentInfo, shared_ptr<NativeRdb::ResultSet> &result,
790     vector<FileInfo> &fileList)
791 {
792 #ifndef MEDIALIBRARY_COMPATIBILITY
793     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_FAIL, "the result is nullptr");
794 #else
795     if (result == nullptr) {
796         return E_ERR;
797     }
798 #endif
799     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
800     while (result->GoToNextRow() == NativeRdb::E_OK) {
801         FileInfo fileInfo;
802         GetFileInfo(fileInfo, result, networkId);
803         fileList.push_back(fileInfo);
804     }
805     return E_SUCCESS;
806 }
807 
GetScanFileResult(const Uri & uri,MediaFileUriType uriType,const string & selection,const vector<string> & selectionArgs)808 shared_ptr<NativeRdb::ResultSet> GetScanFileResult(const Uri &uri, MediaFileUriType uriType, const string &selection,
809     const vector<string> &selectionArgs)
810 {
811     MediaLibraryCommand cmd(uri, OperationType::QUERY);
812     DataSharePredicates predicates;
813     predicates.SetWhereClause(selection);
814     predicates.SetWhereArgs(selectionArgs);
815     int errCode  = 0;
816     vector<string> columns {
817         MEDIA_DATA_DB_BUCKET_ID,
818         MEDIA_DATA_DB_TITLE,
819         MEDIA_DATA_DB_ID,
820         MEDIA_DATA_DB_SIZE,
821         MEDIA_DATA_DB_DATE_MODIFIED,
822         MEDIA_DATA_DB_MIME_TYPE,
823         MEDIA_DATA_DB_NAME,
824         MEDIA_DATA_DB_MEDIA_TYPE,
825         MEDIA_DATA_DB_RELATIVE_PATH
826     };
827     return MediaLibraryDataManager::GetInstance()->QueryRdb(cmd, columns, predicates, errCode);
828 }
829 
SetScanFileSelection(const FileInfo & parentInfo,MediaFileUriType uriType,const int64_t offset,const int64_t maxCount,const FileAccessFwk::FileFilter & filter)830 shared_ptr<NativeRdb::ResultSet> SetScanFileSelection(const FileInfo &parentInfo, MediaFileUriType uriType,
831     const int64_t offset, const int64_t maxCount, const FileAccessFwk::FileFilter &filter)
832 {
833     string filePath;
834     vector<string> selectionArgs;
835     if (uriType == MediaFileUriType::URI_ROOT) {
836         filePath = ROOT_MEDIA_DIR;
837         selectionArgs.push_back(filePath + "%");
838     } else {
839         vector<string> columns = { MEDIA_DATA_DB_FILE_PATH, MEDIA_DATA_DB_RELATIVE_PATH };
840         auto result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_URI, parentInfo.uri, columns);
841         CHECK_AND_RETURN_RET_LOG(result != nullptr, nullptr, "Get file path failed, uri: %{public}s",
842             parentInfo.uri.c_str());
843         filePath = GetStringVal(MEDIA_DATA_DB_FILE_PATH, result);
844         selectionArgs.push_back(filePath + "/%");
845 #ifdef MEDIALIBRARY_COMPATIBILITY
846         string relativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
847         if (!CheckDestRelativePath(relativePath)) {
848             return nullptr;
849         }
850 #endif
851     }
852     MEDIA_DEBUG_LOG("ScanFile filepath: %{private}s", filePath.c_str());
853     string selection = MEDIA_DATA_DB_FILE_PATH + " LIKE ? ";
854     if (filter.GetSuffix().size() > 0) {
855         selection += " AND ( " + Media::MEDIA_DATA_DB_NAME + " LIKE ? ";
856         selectionArgs.emplace_back("%" + filter.GetSuffix()[0]);
857     }
858     for (size_t i = 1; i < filter.GetSuffix().size(); i++) {
859         selection += " OR " + Media::MEDIA_DATA_DB_NAME + " LIKE ? ";
860         selectionArgs.emplace_back("%" + filter.GetSuffix()[i]);
861     }
862     if (filter.GetSuffix().size() > 0) {
863         selection += ")";
864     }
865     selection += " AND " + MEDIA_DATA_DB_MEDIA_TYPE + " <> " + to_string(MEDIA_TYPE_ALBUM);
866     selection += " AND " + MEDIA_DATA_DB_MEDIA_TYPE + " <> " + to_string(MEDIA_TYPE_NOFILE);
867     selection += " AND " + MEDIA_DATA_DB_IS_TRASH + " = ? LIMIT " + to_string(offset) + ", " + to_string(maxCount);
868     selectionArgs.push_back(to_string(NOT_TRASHED));
869     Uri uri(GetQueryUri(parentInfo, uriType));
870     return GetScanFileResult(uri, uriType, selection, selectionArgs);
871 }
872 
ScanFile(const FileInfo & parentInfo,const int64_t offset,const int64_t maxCount,const FileAccessFwk::FileFilter & filter,vector<FileInfo> & fileList)873 int32_t MediaFileExtentionUtils::ScanFile(const FileInfo &parentInfo, const int64_t offset, const int64_t maxCount,
874     const FileAccessFwk::FileFilter &filter, vector<FileInfo> &fileList)
875 {
876     MediaFileUriType uriType;
877     auto ret = MediaFileExtentionUtils::ResolveUri(parentInfo, uriType);
878     MEDIA_DEBUG_LOG("ScanFile:: uriType: %d", uriType);
879     if (ret != E_SUCCESS) {
880         MEDIA_ERR_LOG("ResolveUri::invalid input fileInfo");
881         return ret;
882     }
883     auto result = SetScanFileSelection(parentInfo, uriType, offset, maxCount, filter);
884     return GetScanFileFileInfoFromResult(parentInfo, result, fileList);
885 }
886 
QueryDirSize(FileInfo fileInfo)887 static int QueryDirSize(FileInfo fileInfo)
888 {
889     vector<FileInfo> fileInfoVec;
890     FileAccessFwk::FileFilter filter;
891     int64_t offset { 0 };
892     int32_t ret = E_ERR;
893     int64_t size = 0;
894     do {
895         fileInfoVec.clear();
896         ret = MediaFileExtentionUtils::ScanFile(fileInfo, offset, MAX_COUNT, filter, fileInfoVec);
897         if (ret != E_SUCCESS) {
898             MEDIA_ERR_LOG("ScanFile get result error, code:%{public}d", ret);
899             return ret;
900         }
901         for (auto info : fileInfoVec) {
902             size += info.size;
903         }
904         offset += MAX_COUNT;
905     } while (fileInfoVec.size() == MAX_COUNT);
906     return size;
907 }
908 
Query(const Uri & uri,std::vector<std::string> & columns,std::vector<std::string> & results)909 int32_t MediaFileExtentionUtils::Query(const Uri &uri, std::vector<std::string> &columns,
910     std::vector<std::string> &results)
911 {
912     string queryUri = uri.ToString();
913     if (!CheckUriValid(queryUri)) {
914         return E_URI_INVALID;
915     }
916 
917     bool isExist = false;
918     int ret = Access(uri, isExist);
919     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "Access uri error, code:%{public}d", ret);
920     CHECK_AND_RETURN_RET(isExist, E_NO_SUCH_FILE);
921 
922     auto resultSet = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_URI, queryUri, columns);
923     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_URI_INVALID, "Get resultSet failed, uri: %{public}s",
924         queryUri.c_str());
925     for (auto column : columns) {
926         if (column == MEDIA_DATA_DB_SIZE) {
927             FileInfo fileInfo;
928             int ret = GetFileInfoFromUri(uri, fileInfo);
929             CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "Get fileInfo from uri error, code:%{public}d", ret);
930             if (fileInfo.mode & DOCUMENT_FLAG_REPRESENTS_DIR) {
931                 ret = QueryDirSize(fileInfo);
932                 CHECK_AND_RETURN_RET_LOG(ret >= 0, ret, "Query directory size error, code:%{public}d", ret);
933                 results.push_back(std::to_string(ret));
934                 continue;
935             }
936         }
937         auto memberType = FILE_RESULT_TYPE.at(column);
938         switch (memberType) {
939             case STRING_TYPE:
940                 results.push_back(GetStringVal(column, resultSet));
941                 break;
942             case INT32_TYPE:
943                 results.push_back(std::to_string(GetInt32Val(column, resultSet)));
944                 break;
945             case INT64_TYPE:
946                 results.push_back(std::to_string(GetInt64Val(column, resultSet)));
947                 break;
948             default:
949                 MEDIA_ERR_LOG("not match  memberType %{public}d", memberType);
950                 break;
951         }
952     }
953     resultSet->Close();
954     return E_SUCCESS;
955 }
956 
GetRootInfo(shared_ptr<NativeRdb::ResultSet> & result,RootInfo & rootInfo)957 bool GetRootInfo(shared_ptr<NativeRdb::ResultSet> &result, RootInfo &rootInfo)
958 {
959     string networkId = GetStringVal(DEVICE_DB_NETWORK_ID, result);
960     rootInfo.uri = ML_FILE_URI_PREFIX + "/" + networkId + MEDIALIBRARY_ROOT;
961     rootInfo.displayName = GetStringVal(DEVICE_DB_NAME, result);
962     rootInfo.deviceFlags = DEVICE_FLAG_SUPPORTS_READ;
963     rootInfo.deviceType = DEVICE_SHARED_TERMINAL;
964     return true;
965 }
966 
GetRootInfoFromResult(shared_ptr<NativeRdb::ResultSet> & result,vector<RootInfo> & rootList)967 void GetRootInfoFromResult(shared_ptr<NativeRdb::ResultSet> &result, vector<RootInfo> &rootList)
968 {
969     int count = 0;
970     result->GetRowCount(count);
971     CHECK_AND_RETURN_LOG(count > 0, "ResultSet empty");
972     auto ret = result->GoToFirstRow();
973     CHECK_AND_RETURN_LOG(ret == 0, "Failed to shift at first row");
974     rootList.reserve(count + 1);
975     for (int i = 0; i < count; i++) {
976         RootInfo rootInfo;
977         GetRootInfo(result, rootInfo);
978         rootList.push_back(rootInfo);
979         ret = result->GoToNextRow();
980         CHECK_AND_RETURN_LOG(ret == 0, "Failed to GoToNextRow");
981     }
982 }
983 
GetActivePeer(shared_ptr<NativeRdb::ResultSet> & result)984 void GetActivePeer(shared_ptr<NativeRdb::ResultSet> &result)
985 {
986     string strQueryCondition = DEVICE_DB_DATE_MODIFIED + " = 0";
987     DataShare::DataSharePredicates predicates;
988     predicates.SetWhereClause(strQueryCondition);
989     vector<string> columns;
990     Uri uri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_DEVICE_QUERYACTIVEDEVICE);
991     MediaLibraryCommand cmd(uri, OperationType::QUERY);
992     int errCode = 0;
993     result = MediaLibraryDataManager::GetInstance()->QueryRdb(cmd, columns, predicates, errCode);
994 }
995 
GetRoots(vector<RootInfo> & rootList)996 int32_t MediaFileExtentionUtils::GetRoots(vector<RootInfo> &rootList)
997 {
998     return E_SUCCESS;
999 }
1000 
Access(const Uri & uri,bool & isExist)1001 int MediaFileExtentionUtils::Access(const Uri &uri, bool &isExist)
1002 {
1003     isExist = false;
1004     string sourceUri = uri.ToString();
1005     CHECK_AND_RETURN_RET_LOG(MediaFileExtentionUtils::CheckUriValid(sourceUri), E_URI_INVALID,
1006         "Access::invalid uri: %{public}s", sourceUri.c_str());
1007     vector<string> columns = { MEDIA_DATA_DB_ID };
1008     auto result = GetResultSetFromDb(MEDIA_DATA_DB_URI, sourceUri, columns);
1009     if (result == nullptr) {
1010         MEDIA_ERR_LOG("Access::uri is not correct: %{public}s", sourceUri.c_str());
1011         return E_INVALID_URI;
1012     }
1013     isExist = true;
1014     return E_SUCCESS;
1015 }
1016 
GetVirtualNodeFileInfo(const string & uri,FileInfo & fileInfo)1017 int GetVirtualNodeFileInfo(const string &uri, FileInfo &fileInfo)
1018 {
1019     size_t pos = uri.rfind('/');
1020     if (pos == string::npos) {
1021         return E_INVALID_URI;
1022     }
1023 
1024     static const unordered_map<string, FileInfo> virtualNodes = {
1025         { MEDIALIBRARY_TYPE_AUDIO_URI, { uri, "", "MEDIA_TYPE_AUDIO", ALBUM_MODE_READONLY, DEFAULT_AUDIO_MIME_TYPE } },
1026         { MEDIALIBRARY_TYPE_VIDEO_URI, { uri, "", "MEDIA_TYPE_VIDEO", ALBUM_MODE_READONLY, DEFAULT_VIDEO_MIME_TYPE } },
1027         { MEDIALIBRARY_TYPE_IMAGE_URI, { uri, "", "MEDIA_TYPE_IMAGE", ALBUM_MODE_READONLY, DEFAULT_IMAGE_MIME_TYPE } },
1028         { MEDIALIBRARY_TYPE_FILE_URI, { uri, "", "MEDIA_TYPE_FILE", ALBUM_MODE_READONLY, DEFAULT_FILE_MIME_TYPE } },
1029     };
1030     string uriSuffix = uri.substr(pos);
1031     if (virtualNodes.find(uriSuffix) != virtualNodes.end()) {
1032         fileInfo = virtualNodes.at(uriSuffix);
1033         return E_SUCCESS;
1034     } else {
1035         return E_INVALID_URI;
1036     }
1037 }
1038 
GetThumbnail(const Uri & uri,const Size & size,std::unique_ptr<PixelMap> & pixelMap)1039 int MediaFileExtentionUtils::GetThumbnail(const Uri &uri, const Size &size, std::unique_ptr<PixelMap> &pixelMap)
1040 {
1041     string queryUriStr = uri.ToString();
1042     if (!CheckUriValid(queryUriStr)) {
1043         MEDIA_ERR_LOG("GetThumbnail::invalid uri: %{public}s", queryUriStr.c_str());
1044         return E_URI_INVALID;
1045     }
1046 #ifdef MEDIALIBRARY_COMPATIBILITY
1047     string realUri = MediaFileUtils::GetRealUriFromVirtualUri(queryUriStr);
1048     string pixelMapUri = realUri + "?" + MEDIA_OPERN_KEYWORD + "=" + MEDIA_DATA_DB_THUMBNAIL + "&" +
1049         MEDIA_DATA_DB_WIDTH + "=" + std::to_string(size.width) + "&" + MEDIA_DATA_DB_HEIGHT + "=" +
1050         std::to_string(size.height);
1051 #else
1052     string pixelMapUri = queryUriStr + "?" + MEDIA_OPERN_KEYWORD + "=" + MEDIA_DATA_DB_THUMBNAIL + "&" +
1053         MEDIA_DATA_DB_WIDTH + "=" + std::to_string(size.width) + "&" + MEDIA_DATA_DB_HEIGHT + "=" +
1054         std::to_string(size.height);
1055 #endif
1056     UniqueFd uniqueFd(MediaLibraryDataManager::GetInstance()->GetThumbnail(pixelMapUri));
1057     if (uniqueFd.Get() < 0) {
1058         MEDIA_ERR_LOG("queryThumb is null, errCode is %{public}d", uniqueFd.Get());
1059         return E_FAIL;
1060     }
1061     uint32_t err = 0;
1062     SourceOptions opts;
1063     unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(uniqueFd.Get(), opts, err);
1064     if (imageSource  == nullptr) {
1065         MEDIA_ERR_LOG("CreateImageSource err %{public}d", err);
1066         return E_FAIL;
1067     }
1068     DecodeOptions decodeOpts;
1069     decodeOpts.desiredSize = size;
1070     decodeOpts.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
1071     pixelMap = imageSource->CreatePixelMap(decodeOpts, err);
1072     return E_OK;
1073 }
1074 
GetFileInfoFromUri(const Uri & selectFile,FileInfo & fileInfo)1075 int MediaFileExtentionUtils::GetFileInfoFromUri(const Uri &selectFile, FileInfo &fileInfo)
1076 {
1077     string uri = selectFile.ToString();
1078     MediaFileUriType uriType = URI_FILE;
1079 
1080     FileInfo tempInfo;
1081     tempInfo.uri = uri;
1082     tempInfo.mimeType = DEFAULT_FILE_MIME_TYPE;
1083     auto ret = MediaFileExtentionUtils::ResolveUri(tempInfo, uriType);
1084     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "GetFileInfoFromUri::invalid uri: %{public}s", uri.c_str());
1085 
1086     switch (uriType) {
1087         case URI_ROOT:
1088             fileInfo.uri = uri;
1089             return E_SUCCESS;
1090         case URI_MEDIA_ROOT:
1091         case URI_FILE_ROOT:
1092             return GetVirtualNodeFileInfo(uri, fileInfo);
1093         case URI_DIR:
1094         case URI_ALBUM:
1095         case URI_FILE: {
1096             vector<string> columns = FILEINFO_COLUMNS;
1097             auto result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_URI, uri, columns);
1098             CHECK_AND_RETURN_RET_LOG(result != nullptr, E_INVALID_URI,
1099                 "GetFileInfoFromUri::uri is not correct: %{public}s", uri.c_str());
1100             const string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(uri);
1101             return GetFileInfo(fileInfo, result, networkId);
1102         }
1103         default:
1104             return E_INVALID_URI;
1105     }
1106 }
1107 
GetFileInfoFromRelativePath(const string & relativePath,FileAccessFwk::FileInfo & fileInfo)1108 int MediaFileExtentionUtils::GetFileInfoFromRelativePath(const string &relativePath, FileAccessFwk::FileInfo &fileInfo)
1109 {
1110     if (relativePath.empty()) {
1111         fileInfo = { MEDIALIBRARY_DATA_URI + MEDIALIBRARY_TYPE_FILE_URI, "", "MEDIA_TYPE_FILE", ALBUM_MODE_READONLY,
1112             DEFAULT_FILE_MIME_TYPE };
1113         return E_SUCCESS;
1114     }
1115 
1116     string path = ROOT_MEDIA_DIR + relativePath;
1117     if (path.back() == '/') {
1118         path.pop_back();
1119     }
1120     vector<string> columns = FILEINFO_COLUMNS;
1121     auto result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_FILE_PATH, path, columns);
1122     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_NO_SUCH_FILE,
1123         "GetFileInfoFromRelativePath::Get FileInfo failed, relativePath: %{private}s", relativePath.c_str());
1124     return GetFileInfo(fileInfo, result);
1125 }
1126 
HandleFileRename(const shared_ptr<FileAsset> & fileAsset)1127 int32_t HandleFileRename(const shared_ptr<FileAsset> &fileAsset)
1128 {
1129     string uri = MEDIALIBRARY_DATA_URI;
1130     Uri updateAssetUri(uri + SLASH_CHAR + MEDIA_FILEOPRN + SLASH_CHAR + MEDIA_FILEOPRN_MODIFYASSET);
1131     DataShare::DataSharePredicates predicates;
1132     DataShare::DataShareValuesBucket valuesBucket;
1133     valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, fileAsset->GetMediaType());
1134 #ifdef MEDIALIBRARY_COMPATIBILITY
1135     string fileUri = fileAsset->GetUri() + SLASH_CHAR + to_string(MediaFileUtils::GetVirtualIdByType(
1136         fileAsset->GetId(), MediaType::MEDIA_TYPE_FILE));
1137 #else
1138     string fileUri = fileAsset->GetUri() + SLASH_CHAR + to_string(fileAsset->GetId());
1139 #endif
1140     valuesBucket.Put(MEDIA_DATA_DB_URI, fileUri);
1141     valuesBucket.Put(MEDIA_DATA_DB_NAME, fileAsset->GetDisplayName());
1142     valuesBucket.Put(MEDIA_DATA_DB_RELATIVE_PATH, fileAsset->GetRelativePath());
1143     predicates.SetWhereClause(MEDIA_DATA_DB_ID + " = ? ");
1144     predicates.SetWhereArgs({ to_string(fileAsset->GetId()) });
1145     MediaLibraryCommand cmd(updateAssetUri);
1146     auto ret = MediaLibraryDataManager::GetInstance()->Update(cmd, valuesBucket, predicates);
1147     if (ret > 0) {
1148         return E_SUCCESS;
1149     } else {
1150         MEDIA_ERR_LOG("HandleFileRename Update ret %{public}d", ret);
1151         return ret;
1152     }
1153 }
1154 
GetRelativePathFromPath(const string & path)1155 string GetRelativePathFromPath(const string &path)
1156 {
1157     string relativePath = "";
1158     if (path.length() > ROOT_MEDIA_DIR.length()) {
1159         relativePath = path.substr(ROOT_MEDIA_DIR.length());
1160     }
1161     return relativePath;
1162 }
1163 
UpdateRenamedAlbumInfo(const string & srcId,const string & displayName,const string & newAlbumPath)1164 int32_t UpdateRenamedAlbumInfo(const string &srcId, const string &displayName, const string &newAlbumPath)
1165 {
1166     int64_t date_modified = MediaFileUtils::GetAlbumDateModified(newAlbumPath);
1167     AbsRdbPredicates absPredicates(MEDIALIBRARY_TABLE);
1168     absPredicates.EqualTo(MEDIA_DATA_DB_ID, srcId);
1169     ValuesBucket valuesBucket;
1170     valuesBucket.PutLong(MEDIA_DATA_DB_DATE_MODIFIED, date_modified);
1171     valuesBucket.PutString(MEDIA_DATA_DB_FILE_PATH, newAlbumPath);
1172     valuesBucket.PutString(MEDIA_DATA_DB_TITLE, displayName);
1173     valuesBucket.PutString(MEDIA_DATA_DB_NAME, displayName);
1174     valuesBucket.PutString(MEDIA_DATA_DB_BUCKET_NAME, displayName);
1175     int32_t count = 0;
1176     return MediaLibraryDataManager::GetInstance()->rdbStore_->Update(count, valuesBucket, absPredicates);
1177 }
1178 
UpdateSubFilesPath(const string & srcPath,const string & newAlbumPath)1179 int32_t UpdateSubFilesPath(const string &srcPath, const string &newAlbumPath)
1180 {
1181     int64_t date_modified = MediaFileUtils::GetAlbumDateModified(newAlbumPath);
1182     string modifySql = "UPDATE " + MEDIALIBRARY_TABLE + " SET ";
1183     // Update data "old albumPath/%" -> "new albumPath/%"
1184     modifySql += MEDIA_DATA_DB_FILE_PATH + " = replace("
1185         + MEDIA_DATA_DB_FILE_PATH + ", '" + srcPath + "/' , '" + newAlbumPath + "/'), ";
1186     // Update relative_path "old album relativePath/%" -> "new album relativePath/%"
1187     modifySql += MEDIA_DATA_DB_RELATIVE_PATH + " = replace(" + MEDIA_DATA_DB_RELATIVE_PATH
1188         + ", '" + GetRelativePathFromPath(srcPath) + "/', '" + GetRelativePathFromPath(newAlbumPath) + "/'), ";
1189     // Update date_modified "old time" -> "new time"
1190     modifySql += MEDIA_DATA_DB_DATE_MODIFIED + " = " + to_string(date_modified);
1191     modifySql += " WHERE " + MEDIA_DATA_DB_FILE_PATH + " LIKE '" + srcPath + "/%' AND " +
1192         MEDIA_DATA_DB_IS_TRASH + " = " + to_string(NOT_TRASHED);
1193     MEDIA_DEBUG_LOG("UpdateSubFilesPath modifySql %{private}s", modifySql.c_str());
1194     return MediaLibraryDataManager::GetInstance()->rdbStore_->ExecuteSql(modifySql);
1195 }
1196 
UpdateSubFilesBucketName(const string & srcId,const string & displayName)1197 int32_t UpdateSubFilesBucketName(const string &srcId, const string &displayName)
1198 {
1199     // Update bucket_display_name "old album displayName" -> "new album displayName"
1200     string modifySql = "UPDATE " + MEDIALIBRARY_TABLE + " SET " + MEDIA_DATA_DB_BUCKET_NAME + " = '" + displayName;
1201     modifySql += "' WHERE " + MEDIA_DATA_DB_PARENT_ID + " = " + srcId + " AND " +
1202         MEDIA_DATA_DB_MEDIA_TYPE + " <> " + to_string(MEDIA_TYPE_ALBUM) + " AND " +
1203         MEDIA_DATA_DB_IS_TRASH + " = " + to_string(NOT_TRASHED);
1204     MEDIA_DEBUG_LOG("UpdateSubFilesBucketName modifySql %{private}s", modifySql.c_str());
1205     return MediaLibraryDataManager::GetInstance()->rdbStore_->ExecuteSql(modifySql);
1206 }
1207 
HandleAlbumRename(const shared_ptr<FileAsset> & fileAsset)1208 int32_t HandleAlbumRename(const shared_ptr<FileAsset> &fileAsset)
1209 {
1210     if (fileAsset->GetRelativePath().empty()) {
1211         MEDIA_ERR_LOG("Rename dir in root dir, denied");
1212         return E_DENIED_RENAME;
1213     }
1214     string srcPath = fileAsset->GetPath();
1215     size_t slashIndex = srcPath.rfind(SLASH_CHAR);
1216     string destPath = srcPath.substr(0, slashIndex) + SLASH_CHAR + fileAsset->GetDisplayName();
1217     if (MediaFileExtentionUtils::IsFileExistInDb(destPath)) {
1218         MEDIA_ERR_LOG("Rename file is existed %{private}s", destPath.c_str());
1219         return E_FILE_EXIST;
1220     }
1221     bool succ = MediaFileUtils::RenameDir(srcPath, destPath);
1222     if (!succ) {
1223         MEDIA_ERR_LOG("Failed RenameDir errno %{public}d", errno);
1224         return E_MODIFY_DATA_FAIL;
1225     }
1226     // update parent info
1227     string parentPath = ROOT_MEDIA_DIR + fileAsset->GetRelativePath();
1228     parentPath.pop_back();
1229     MediaLibraryObjectUtils::UpdateDateModified(parentPath);
1230 
1231     // update album info
1232     string srcId = to_string(fileAsset->GetId());
1233     int32_t updateResult = UpdateRenamedAlbumInfo(srcId, fileAsset->GetDisplayName(), destPath);
1234     CHECK_AND_RETURN_RET_LOG(updateResult == NativeRdb::E_OK, E_UPDATE_DB_FAIL, "UpdateRenamedAlbumInfo failed");
1235 
1236     // update child info
1237     updateResult = UpdateSubFilesPath(srcPath, destPath);
1238     CHECK_AND_RETURN_RET_LOG(updateResult == NativeRdb::E_OK, E_UPDATE_DB_FAIL, "UpdateSubFilesPath failed");
1239     updateResult = UpdateSubFilesBucketName(srcId, fileAsset->GetDisplayName());
1240     CHECK_AND_RETURN_RET_LOG(updateResult == NativeRdb::E_OK, E_UPDATE_DB_FAIL,
1241         "UpdateSubFilesBucketName failed");
1242     return E_SUCCESS;
1243 }
1244 
Rename(const Uri & sourceFileUri,const string & displayName,Uri & newFileUri)1245 int32_t MediaFileExtentionUtils::Rename(const Uri &sourceFileUri, const string &displayName, Uri &newFileUri)
1246 {
1247     string sourceUri = sourceFileUri.ToString();
1248     auto ret = MediaFileExtentionUtils::CheckUriSupport(sourceUri);
1249     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid uri");
1250     vector<string> columns = { MEDIA_DATA_DB_ID, MEDIA_DATA_DB_URI, MEDIA_DATA_DB_FILE_PATH, MEDIA_DATA_DB_MEDIA_TYPE,
1251         MEDIA_DATA_DB_RELATIVE_PATH };
1252     auto result = GetResultSetFromDb(MEDIA_DATA_DB_URI, sourceUri, columns);
1253     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_MODIFY_DATA_FAIL, "Rename source uri is not correct %{public}s",
1254         sourceUri.c_str());
1255 
1256     auto fileAsset = make_shared<FileAsset>();
1257     fileAsset->SetId(GetInt32Val(MEDIA_DATA_DB_ID, result));
1258     fileAsset->SetUri(GetStringVal(MEDIA_DATA_DB_URI, result));
1259     fileAsset->SetPath(GetStringVal(MEDIA_DATA_DB_FILE_PATH, result));
1260     fileAsset->SetDisplayName(displayName);
1261     fileAsset->SetMediaType(static_cast<MediaType>(GetInt32Val(MEDIA_DATA_DB_MEDIA_TYPE, result)));
1262 #ifdef MEDIALIBRARY_COMPATIBILITY
1263     string relativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
1264     if (!CheckDestRelativePath(relativePath)) {
1265         return JS_ERR_PERMISSION_DENIED;
1266     }
1267 #endif
1268     fileAsset->SetRelativePath(GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result));
1269     result->Close();
1270 
1271     if (fileAsset->GetMediaType() == MediaType::MEDIA_TYPE_ALBUM) {
1272         if (MediaFileUtils::CheckDentryName(displayName) < 0) {
1273             MEDIA_ERR_LOG("invalid albumName %{private}s", displayName.c_str());
1274             return E_INVALID_DISPLAY_NAME;
1275         }
1276         ret = HandleAlbumRename(fileAsset);
1277     } else {
1278         if (MediaFileUtils::CheckFileDisplayName(displayName) < 0) {
1279             MEDIA_ERR_LOG("invalid displayName %{private}s", displayName.c_str());
1280             return E_INVALID_DISPLAY_NAME;
1281         }
1282         ret = HandleFileRename(fileAsset);
1283     }
1284     if (ret == E_SUCCESS) {
1285         newFileUri = Uri(sourceUri);
1286     }
1287     return ret;
1288 }
1289 
HandleFileMove(const shared_ptr<FileAsset> & fileAsset,const string & destRelativePath)1290 int32_t HandleFileMove(const shared_ptr<FileAsset> &fileAsset, const string &destRelativePath)
1291 {
1292     string uri = MEDIALIBRARY_DATA_URI;
1293     Uri updateAssetUri(uri + SLASH_CHAR + MEDIA_FILEOPRN + SLASH_CHAR + MEDIA_FILEOPRN_MODIFYASSET);
1294     DataShare::DataSharePredicates predicates;
1295     DataShare::DataShareValuesBucket valuesBucket;
1296     valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, fileAsset->GetMediaType());
1297 #ifdef MEDIALIBRARY_COMPATIBILITY
1298     string fileUri = fileAsset->GetUri() + SLASH_CHAR + to_string(MediaFileUtils::GetVirtualIdByType(
1299         fileAsset->GetId(), MediaType::MEDIA_TYPE_FILE));
1300 #else
1301     string fileUri = fileAsset->GetUri() + SLASH_CHAR + to_string(fileAsset->GetId());
1302 #endif
1303     valuesBucket.Put(MEDIA_DATA_DB_URI, fileUri);
1304     valuesBucket.Put(MEDIA_DATA_DB_NAME, fileAsset->GetDisplayName());
1305     valuesBucket.Put(MEDIA_DATA_DB_RELATIVE_PATH, destRelativePath);
1306     predicates.SetWhereClause(MEDIA_DATA_DB_ID + " = ? ");
1307     predicates.SetWhereArgs({ to_string(fileAsset->GetId()) });
1308     MediaLibraryCommand cmd(updateAssetUri);
1309     auto ret = MediaLibraryDataManager::GetInstance()->Update(cmd, valuesBucket, predicates);
1310     if (ret > 0) {
1311         return E_SUCCESS;
1312     } else {
1313         MEDIA_ERR_LOG("HandleFileMove Update ret %{public}d", ret);
1314         return ret;
1315     }
1316 }
1317 
UpdateMovedAlbumInfo(const shared_ptr<FileAsset> & fileAsset,const string & bucketId,const string & newAlbumPath,const string & destRelativePath)1318 int32_t UpdateMovedAlbumInfo(const shared_ptr<FileAsset> &fileAsset, const string &bucketId, const string &newAlbumPath,
1319     const string &destRelativePath)
1320 {
1321     int64_t date_modified = MediaFileUtils::GetAlbumDateModified(newAlbumPath);
1322     AbsRdbPredicates absPredicates(MEDIALIBRARY_TABLE);
1323     absPredicates.EqualTo(MEDIA_DATA_DB_ID, to_string(fileAsset->GetId()));
1324     ValuesBucket valuesBucket;
1325     valuesBucket.PutLong(MEDIA_DATA_DB_DATE_MODIFIED, date_modified);
1326     valuesBucket.PutInt(MEDIA_DATA_DB_PARENT_ID, stoi(bucketId));
1327     valuesBucket.PutInt(MEDIA_DATA_DB_BUCKET_ID, stoi(bucketId));
1328     valuesBucket.PutString(MEDIA_DATA_DB_FILE_PATH, newAlbumPath);
1329     valuesBucket.PutString(MEDIA_DATA_DB_RELATIVE_PATH, destRelativePath);
1330     int32_t count = 0;
1331     return MediaLibraryDataManager::GetInstance()->rdbStore_->Update(count, valuesBucket, absPredicates);
1332 }
1333 
HandleAlbumMove(const shared_ptr<FileAsset> & fileAsset,const string & destRelativePath,const string & bucketId)1334 int32_t HandleAlbumMove(const shared_ptr<FileAsset> &fileAsset, const string &destRelativePath, const string &bucketId)
1335 {
1336     string destPath = ROOT_MEDIA_DIR + destRelativePath + fileAsset->GetDisplayName();
1337     if (MediaFileExtentionUtils::IsFileExistInDb(destPath)) {
1338         MEDIA_ERR_LOG("Move file is existed %{private}s", destPath.c_str());
1339         return E_FILE_EXIST;
1340     }
1341     string srcPath = fileAsset->GetPath();
1342     bool succ = MediaFileUtils::RenameDir(srcPath, destPath);
1343     if (!succ) {
1344         MEDIA_ERR_LOG("Failed RenameDir errno %{public}d", errno);
1345         return E_MODIFY_DATA_FAIL;
1346     }
1347     // update parent info
1348     string srcParentPath = ROOT_MEDIA_DIR + fileAsset->GetRelativePath();
1349     srcParentPath.pop_back();
1350     string destParentPath = ROOT_MEDIA_DIR + destRelativePath;
1351     destParentPath.pop_back();
1352     MediaLibraryObjectUtils::UpdateDateModified(srcParentPath);
1353     MediaLibraryObjectUtils::UpdateDateModified(destParentPath);
1354 
1355     // update album info
1356     int32_t updateResult = UpdateMovedAlbumInfo(fileAsset, bucketId, destPath, destRelativePath);
1357     CHECK_AND_RETURN_RET_LOG(updateResult == NativeRdb::E_OK, E_UPDATE_DB_FAIL, "UpdateMovedAlbumInfo failed");
1358 
1359     // update child info
1360     updateResult = UpdateSubFilesPath(srcPath, destPath);
1361     CHECK_AND_RETURN_RET_LOG(updateResult == NativeRdb::E_OK, E_UPDATE_DB_FAIL, "UpdateSubFilesPath failed");
1362     return E_SUCCESS;
1363 }
1364 
GetMoveSubFile(const string & srcPath,shared_ptr<NativeRdb::ResultSet> & result)1365 void GetMoveSubFile(const string &srcPath, shared_ptr<NativeRdb::ResultSet> &result)
1366 {
1367     string queryUri = MEDIALIBRARY_DATA_URI;
1368     string selection = MEDIA_DATA_DB_FILE_PATH + " LIKE ? ";
1369     vector<string> selectionArgs = { srcPath + SLASH_CHAR + "%" };
1370     vector<string> columns = { MEDIA_DATA_DB_FILE_PATH, MEDIA_DATA_DB_NAME, MEDIA_DATA_DB_MEDIA_TYPE };
1371     DataShare::DataSharePredicates predicates;
1372     predicates.SetWhereClause(selection);
1373     predicates.SetWhereArgs(selectionArgs);
1374     Uri uri(queryUri);
1375     MediaLibraryCommand cmd(uri, OperationType::QUERY);
1376     int errCode = 0;
1377     result = MediaLibraryDataManager::GetInstance()->QueryRdb(cmd, columns, predicates, errCode);
1378 }
1379 
CheckSubFileExtension(const string & srcPath,const string & destRelPath)1380 bool CheckSubFileExtension(const string &srcPath, const string &destRelPath)
1381 {
1382     shared_ptr<NativeRdb::ResultSet> result;
1383     GetMoveSubFile(srcPath, result);
1384     CHECK_AND_RETURN_RET_LOG(result != nullptr, false, "GetSrcFileFromResult Get fail");
1385     int count = 0;
1386     result->GetRowCount(count);
1387     CHECK_AND_RETURN_RET_LOG(count > 0, true, "ResultSet empty");
1388     while (result->GoToNextRow() == NativeRdb::E_OK) {
1389         int32_t mediaType = GetInt32Val(MEDIA_DATA_DB_MEDIA_TYPE, result);
1390         string path = GetStringVal(MEDIA_DATA_DB_FILE_PATH, result);
1391         string name = GetStringVal(MEDIA_DATA_DB_NAME, result);
1392         if (mediaType == MEDIA_TYPE_ALBUM) {
1393             continue;
1394         }
1395         if (MediaLibraryObjectUtils::CheckDirExtension(destRelPath, name) != E_SUCCESS) {
1396             return false;
1397         }
1398     }
1399     return true;
1400 }
1401 
CheckRootDir(const shared_ptr<FileAsset> & fileAsset,const string & destRelPath)1402 bool CheckRootDir(const shared_ptr<FileAsset> &fileAsset, const string &destRelPath)
1403 {
1404     string srcRelPath = fileAsset->GetRelativePath();
1405     if (srcRelPath.empty()) {
1406         MEDIA_ERR_LOG("Can not move the first level directories, like Pictures, Audios, ...");
1407         return false;
1408     }
1409     if (destRelPath.empty()) {
1410         MEDIA_ERR_LOG("Can not move to root dir");
1411         return false;
1412     }
1413     size_t srcPos = srcRelPath.find(SLASH_CHAR);
1414     size_t destPos = destRelPath.find(SLASH_CHAR);
1415     if (srcPos == string::npos || destPos == string::npos) {
1416         MEDIA_ERR_LOG("Invalid relativePath %{private}s, %{private}s", srcRelPath.c_str(), destRelPath.c_str());
1417         return false;
1418     }
1419     if (srcRelPath.substr(0, srcPos) != destRelPath.substr(0, destPos)) {
1420         MEDIA_INFO_LOG("move dir to other root dir");
1421         return CheckSubFileExtension(fileAsset->GetPath(), destRelPath);
1422     }
1423     return true;
1424 }
1425 
Move(const Uri & sourceFileUri,const Uri & targetParentUri,Uri & newFileUri)1426 int32_t MediaFileExtentionUtils::Move(const Uri &sourceFileUri, const Uri &targetParentUri, Uri &newFileUri)
1427 {
1428     string sourceUri = sourceFileUri.ToString();
1429     string targetUri = targetParentUri.ToString();
1430     CHECK_AND_RETURN_RET_LOG(sourceUri != targetUri, E_TWO_URI_ARE_THE_SAME,
1431         "sourceUri is the same as TargetUri");
1432     auto ret = CheckUriSupport(sourceUri);
1433     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid source uri");
1434     ret = CheckUriSupport(targetUri);
1435     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid targetUri uri");
1436 
1437     string destRelativePath;
1438     if (!GetAlbumRelativePathFromDB(targetUri, destRelativePath)) {
1439         MEDIA_ERR_LOG("Move target parent uri is not correct %{public}s", targetUri.c_str());
1440         return E_MODIFY_DATA_FAIL;
1441     }
1442 #ifdef MEDIALIBRARY_COMPATIBILITY
1443     if (!CheckDestRelativePath(destRelativePath)) {
1444         return JS_ERR_PERMISSION_DENIED;
1445     }
1446 #endif
1447     vector<string> columns = { MEDIA_DATA_DB_ID, MEDIA_DATA_DB_URI, MEDIA_DATA_DB_FILE_PATH, MEDIA_DATA_DB_NAME,
1448         MEDIA_DATA_DB_MEDIA_TYPE, MEDIA_DATA_DB_RELATIVE_PATH };
1449     auto result = GetResultSetFromDb(MEDIA_DATA_DB_URI, sourceUri, columns);
1450     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_MODIFY_DATA_FAIL, "Move source uri is not correct %{public}s",
1451         sourceUri.c_str());
1452 
1453     auto fileAsset = make_shared<FileAsset>();
1454     fileAsset->SetId(GetInt32Val(MEDIA_DATA_DB_ID, result));
1455     fileAsset->SetUri(GetStringVal(MEDIA_DATA_DB_URI, result));
1456     fileAsset->SetPath(GetStringVal(MEDIA_DATA_DB_FILE_PATH, result));
1457     fileAsset->SetDisplayName(GetStringVal(MEDIA_DATA_DB_NAME, result));
1458     fileAsset->SetMediaType(static_cast<MediaType>(GetInt32Val(MEDIA_DATA_DB_MEDIA_TYPE, result)));
1459 #ifdef MEDIALIBRARY_COMPATIBILITY
1460     string relativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
1461     if (!CheckDestRelativePath(relativePath)) {
1462         return JS_ERR_PERMISSION_DENIED;
1463     }
1464 #endif
1465     fileAsset->SetRelativePath(GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result));
1466     result->Close();
1467 
1468     if (fileAsset->GetMediaType() == MediaType::MEDIA_TYPE_ALBUM) {
1469         if (!CheckRootDir(fileAsset, destRelativePath)) {
1470             MEDIA_ERR_LOG("Move file to another type album, denied");
1471             return E_DENIED_MOVE;
1472         }
1473         string bucketId = MediaLibraryDataManagerUtils::GetIdFromUri(targetUri);
1474         ret = HandleAlbumMove(fileAsset, destRelativePath, bucketId);
1475     } else {
1476         ret = HandleFileMove(fileAsset, destRelativePath);
1477     }
1478     if (ret == E_SUCCESS) {
1479         newFileUri = Uri(sourceUri);
1480     }
1481     return ret;
1482 }
1483 
TranslateCopyResult(CopyResult & copyResult)1484 void TranslateCopyResult(CopyResult &copyResult)
1485 {
1486     auto iter = mediaErrCodeMap.find(copyResult.errCode);
1487     if (iter != mediaErrCodeMap.end()) {
1488         copyResult.errCode = iter->second.first;
1489         if (copyResult.errMsg.empty()) {
1490             copyResult.errMsg = iter->second.second;
1491         }
1492     }
1493 }
1494 
GetUriByRelativePath(const string & relativePath,string & fileUriStr)1495 void GetUriByRelativePath(const string &relativePath, string &fileUriStr)
1496 {
1497     string path = ROOT_MEDIA_DIR + relativePath;
1498     if (path.back() == '/') {
1499         path.pop_back();
1500     }
1501 
1502     vector<string> columns = { MEDIA_DATA_DB_ID, MEDIA_DATA_DB_MEDIA_TYPE };
1503     auto result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_FILE_PATH, path, columns);
1504     CHECK_AND_RETURN_LOG(result != nullptr,
1505         "Get Uri failed, relativePath: %{private}s", relativePath.c_str());
1506     int64_t fileId = GetInt32Val(MEDIA_DATA_DB_ID, result);
1507 #ifdef MEDIALIBRARY_COMPATIBILITY
1508     fileId = MediaFileUtils::GetVirtualIdByType(fileId, MediaType::MEDIA_TYPE_FILE);
1509     fileUriStr = MediaFileUri(MediaType::MEDIA_TYPE_FILE, to_string(fileId)).ToString();
1510 #else
1511     int mediaType = GetInt32Val(MEDIA_DATA_DB_MEDIA_TYPE, result);
1512     fileUriStr = MediaFileUri(MediaType(mediaType), to_string(fileId)).ToString();
1513 #endif
1514 }
1515 
GetRelativePathByUri(const string & uriStr,string & relativePath)1516 int GetRelativePathByUri(const string &uriStr, string &relativePath)
1517 {
1518     vector<string> columns = { MEDIA_DATA_DB_RELATIVE_PATH, MEDIA_DATA_DB_NAME };
1519     auto result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_URI, uriStr, columns);
1520     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_NO_SUCH_FILE,
1521         "Get uri failed, relativePath: %{private}s", relativePath.c_str());
1522     relativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
1523     relativePath += GetStringVal(MEDIA_DATA_DB_NAME, result) + SLASH_CHAR;
1524 #ifdef MEDIALIBRARY_COMPATIBILITY
1525     if (!CheckDestRelativePath(relativePath)) {
1526         return JS_ERR_PERMISSION_DENIED;
1527     }
1528 #endif
1529     return E_SUCCESS;
1530 }
1531 
GetDuplicateDirectory(const string & srcUriStr,const string & destUriStr,Uri & uri)1532 int GetDuplicateDirectory(const string &srcUriStr, const string &destUriStr, Uri &uri)
1533 {
1534     vector<string> srcColumns = { MEDIA_DATA_DB_NAME };
1535     auto result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_URI, srcUriStr, srcColumns);
1536     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_NO_SUCH_FILE,
1537         "Get source uri failed, relativePath: %{private}s", srcUriStr.c_str());
1538     string srcDirName = GetStringVal(MEDIA_DATA_DB_NAME, result);
1539 
1540     string destRelativePath;
1541     vector<string> destColumns = { MEDIA_DATA_DB_RELATIVE_PATH, MEDIA_DATA_DB_NAME };
1542     result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_URI, destUriStr, destColumns);
1543     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_NO_SUCH_FILE,
1544         "Get destination uri failed, relativePath: %{private}s", destUriStr.c_str());
1545     destRelativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
1546 #ifdef MEDIALIBRARY_COMPATIBILITY
1547     if (!CheckDestRelativePath(destRelativePath)) {
1548         return JS_ERR_PERMISSION_DENIED;
1549     }
1550 #endif
1551     destRelativePath += GetStringVal(MEDIA_DATA_DB_NAME, result) + SLASH_CHAR;
1552     string existUriStr;
1553     GetUriByRelativePath(destRelativePath + srcDirName, existUriStr);
1554     uri = Uri { existUriStr };
1555     return E_SUCCESS;
1556 }
1557 
InsertFileOperation(string & destRelativePath,string & srcUriStr)1558 int32_t InsertFileOperation(string &destRelativePath, string &srcUriStr)
1559 {
1560     DataShareValuesBucket valuesBucket;
1561     valuesBucket.Put(MEDIA_DATA_DB_RELATIVE_PATH, destRelativePath);
1562     valuesBucket.Put(MEDIA_DATA_DB_URI, srcUriStr);
1563     Uri copyUri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_FILEOPRN + SLASH_CHAR +
1564                     MEDIA_FILEOPRN_COPYASSET);
1565     MediaLibraryCommand cmd(copyUri);
1566     return MediaLibraryDataManager::GetInstance()->Insert(cmd, valuesBucket);
1567 }
1568 
CopyFileOperation(string & srcUriStr,string & destRelativePath,CopyResult & copyResult,bool force)1569 int CopyFileOperation(string &srcUriStr, string &destRelativePath, CopyResult &copyResult, bool force)
1570 {
1571     vector<string> columns = { MEDIA_DATA_DB_RELATIVE_PATH, MEDIA_DATA_DB_NAME };
1572     auto result = MediaFileExtentionUtils::GetResultSetFromDb(MEDIA_DATA_DB_URI, srcUriStr, columns);
1573     if (result == nullptr) {
1574         MEDIA_ERR_LOG("Get Uri failed, relativePath: %{private}s", srcUriStr.c_str());
1575         copyResult.errCode = E_NO_SUCH_FILE;
1576         copyResult.errMsg = "";
1577         TranslateCopyResult(copyResult);
1578         return COPY_EXCEPTION;
1579     }
1580     string srcRelativePath = GetStringVal(MEDIA_DATA_DB_RELATIVE_PATH, result);
1581 #ifdef MEDIALIBRARY_COMPATIBILITY
1582     if (!CheckDestRelativePath(srcRelativePath)) {
1583         return JS_ERR_PERMISSION_DENIED;
1584     }
1585 #endif
1586     string srcFileName = GetStringVal(MEDIA_DATA_DB_NAME, result);
1587     string existFile;
1588     GetUriByRelativePath(destRelativePath + srcFileName, existFile);
1589     if (!existFile.empty()) {
1590         if (force) {
1591             Uri existFileUri { existFile };
1592             MediaFileExtentionUtils::Delete(existFileUri);
1593         } else {
1594             copyResult.sourceUri = srcUriStr;
1595             copyResult.destUri = existFile;
1596             copyResult.errCode = E_FILE_EXIST;
1597             copyResult.errMsg = "";
1598             TranslateCopyResult(copyResult);
1599             return COPY_NOEXCEPTION;
1600         }
1601     }
1602 #ifdef MEDIALIBRARY_COMPATIBILITY
1603     if (!CheckDestRelativePath(destRelativePath)) {
1604         return JS_ERR_PERMISSION_DENIED;
1605     }
1606 #endif
1607     int fileId = InsertFileOperation(destRelativePath, srcUriStr);
1608     if (fileId < 0) {
1609         MEDIA_ERR_LOG("Insert media library error, fileId: %{public}d", fileId);
1610         copyResult.sourceUri = srcUriStr;
1611         copyResult.errCode = fileId;
1612         copyResult.errMsg = "Insert media library fail";
1613         TranslateCopyResult(copyResult);
1614         return COPY_NOEXCEPTION;
1615     }
1616     return E_SUCCESS;
1617 }
1618 
CopyDirectoryOperation(FileInfo & fileInfo,Uri & destUri,vector<CopyResult> & copyResult,bool force)1619 int CopyDirectoryOperation(FileInfo &fileInfo, Uri &destUri, vector<CopyResult> &copyResult, bool force)
1620 {
1621     vector<FileInfo> fileInfoVec;
1622     FileAccessFwk::FileFilter filter { {}, {}, {}, -1, -1, false, false };
1623     int64_t offset = 0;
1624     int copyRet = E_SUCCESS;
1625     int ret = E_SUCCESS;
1626     string prevDestUriStr;
1627     string destRelativePath;
1628     do {
1629         fileInfoVec.clear();
1630         ret = MediaFileExtentionUtils::ListFile(fileInfo, offset, MAX_COUNT, filter, fileInfoVec);
1631         if (ret != E_SUCCESS) {
1632             MEDIA_ERR_LOG("ListFile get result error, code:%{public}d", ret);
1633             CopyResult result { "", "", ret, "" };
1634             copyResult.clear();
1635             copyResult.push_back(result);
1636             return COPY_EXCEPTION;
1637         }
1638 
1639         for (auto info : fileInfoVec) {
1640             if (info.mode & DOCUMENT_FLAG_REPRESENTS_DIR) {
1641                 Uri dUri { "" };
1642                 ret = MediaFileExtentionUtils::Mkdir(destUri, info.fileName, dUri);
1643                 if (ret == E_FILE_EXIST) {
1644                     GetDuplicateDirectory(info.uri, destUri.ToString(), dUri);
1645                 } else if (ret < 0) {
1646                     MEDIA_ERR_LOG("Mkdir get result error, code:%{public}d", ret);
1647                     CopyResult result { "", "", ret, "" };
1648                     copyResult.clear();
1649                     copyResult.push_back(result);
1650                     return COPY_EXCEPTION;
1651                 }
1652                 ret = CopyDirectoryOperation(info, dUri, copyResult, force);
1653                 if (ret == COPY_EXCEPTION) {
1654                     MEDIA_ERR_LOG("Recursive directory copy error");
1655                     return ret;
1656                 }
1657                 if (ret == COPY_NOEXCEPTION) {
1658                     copyRet = ret;
1659                 }
1660             } else if (info.mode & DOCUMENT_FLAG_REPRESENTS_FILE) {
1661                 CopyResult result;
1662                 string destUriStr = destUri.ToString();
1663                 if (destUriStr != prevDestUriStr) {
1664                     ret = GetRelativePathByUri(destUriStr, destRelativePath);
1665                     if (ret != E_SUCCESS) {
1666                         MEDIA_ERR_LOG("Get relative Path error");
1667                         result.errCode = ret;
1668                         TranslateCopyResult(result);
1669                         copyResult.clear();
1670                         copyResult.push_back(result);
1671                         return ret;
1672                     }
1673                     prevDestUriStr = destUriStr;
1674                 }
1675                 ret = CopyFileOperation(info.uri, destRelativePath, result, force);
1676                 if (ret == COPY_EXCEPTION) {
1677                     MEDIA_ERR_LOG("Copy file exception");
1678                     copyResult.clear();
1679                     copyResult.push_back(result);
1680                     return ret;
1681                 }
1682                 if (ret == COPY_NOEXCEPTION) {
1683                     copyResult.push_back(result);
1684                     copyRet = ret;
1685                 }
1686             }
1687         }
1688         offset += MAX_COUNT;
1689     } while (fileInfoVec.size() == MAX_COUNT);
1690     return copyRet;
1691 }
1692 
Copy(const Uri & sourceUri,const Uri & destUri,vector<CopyResult> & copyResult,bool force)1693 int32_t MediaFileExtentionUtils::Copy(const Uri &sourceUri, const Uri &destUri, vector<CopyResult> &copyResult,
1694     bool force)
1695 {
1696     FileAccessFwk::FileInfo fileInfo;
1697     int ret = GetFileInfoFromUri(sourceUri, fileInfo);
1698     if (ret != E_SUCCESS) {
1699         MEDIA_ERR_LOG("get FileInfo from uri error, code:%{public}d", ret);
1700         CopyResult result { "", "", ret, "" };
1701         TranslateCopyResult(result);
1702         copyResult.clear();
1703         copyResult.push_back(result);
1704         return COPY_EXCEPTION;
1705     }
1706 
1707     string srcUriStr = sourceUri.ToString();
1708     string destUriStr = destUri.ToString();
1709     Uri newDestUri { "" };
1710     if (fileInfo.mode & DOCUMENT_FLAG_REPRESENTS_DIR) {
1711         ret = Mkdir(destUri, fileInfo.fileName, newDestUri);
1712         if (ret == E_FILE_EXIST) {
1713             GetDuplicateDirectory(srcUriStr, destUriStr, newDestUri);
1714         } else if (ret < 0) {
1715             CopyResult result { "", "", ret, "" };
1716             TranslateCopyResult(result);
1717             copyResult.clear();
1718             copyResult.push_back(result);
1719             return COPY_EXCEPTION;
1720         }
1721         ret = CopyDirectoryOperation(fileInfo, newDestUri, copyResult, force);
1722     } else if (fileInfo.mode & DOCUMENT_FLAG_REPRESENTS_FILE) {
1723         CopyResult result;
1724         string destRelativePath;
1725         ret = GetRelativePathByUri(destUriStr, destRelativePath);
1726         if (ret != E_SUCCESS) {
1727             MEDIA_ERR_LOG("Get relative Path error");
1728             result.errCode = ret;
1729             TranslateCopyResult(result);
1730             copyResult.clear();
1731             copyResult.push_back(result);
1732             return ret;
1733         }
1734         ret = CopyFileOperation(srcUriStr, destRelativePath, result, force);
1735         if (ret != E_SUCCESS) {
1736             copyResult.push_back(result);
1737         }
1738     }
1739     return ret;
1740 }
1741 } // Media
1742 } // OHOS
1743