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