• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 "media_file_utils.h"
20 #include "media_log.h"
21 #include "medialibrary_data_manager.h"
22 #include "medialibrary_data_manager_utils.h"
23 #include "medialibrary_dir_operations.h"
24 #include "medialibrary_errno.h"
25 #include "medialibrary_object_utils.h"
26 #include "medialibrary_type_const.h"
27 #include "medialibrary_smartalbum_map_db.h"
28 #include "result_set_utils.h"
29 #include "scanner_utils.h"
30 #include "uri_helper.h"
31 
32 using namespace std;
33 using namespace OHOS::NativeRdb;
34 using namespace OHOS::DataShare;
35 using namespace OHOS::FileAccessFwk;
36 
37 namespace OHOS {
38 namespace Media {
39 constexpr int32_t ALBUM_MODE_RW =
40     DOCUMENT_FLAG_REPRESENTS_DIR | DOCUMENT_FLAG_SUPPORTS_READ | DOCUMENT_FLAG_SUPPORTS_WRITE;
41 constexpr int32_t FILE_MODE_RW =
42     DOCUMENT_FLAG_REPRESENTS_FILE | DOCUMENT_FLAG_SUPPORTS_READ | DOCUMENT_FLAG_SUPPORTS_WRITE;
43 
OpenFile(const Uri & uri,const int flags,int & fd)44 int MediaFileExtentionUtils::OpenFile(const Uri &uri, const int flags, int &fd)
45 {
46     fd = -1;
47     if (!MediaFileExtentionUtils::CheckUriValid(uri.ToString())) {
48         return E_URI_INVALID;
49     }
50     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(uri.ToString());
51     if (!networkId.empty() && flags != O_RDONLY) {
52         return E_OPENFILE_INVALID_FLAG;
53     }
54     string mode;
55     if (flags == O_RDONLY) {
56         mode = MEDIA_FILEMODE_READONLY;
57     } else if (flags == O_WRONLY) {
58         mode = MEDIA_FILEMODE_WRITEONLY;
59     } else if (flags == O_RDWR) {
60         mode = MEDIA_FILEMODE_READWRITE;
61     } else {
62         MEDIA_ERR_LOG("invalid OpenFile flags %{private}d", flags);
63         return E_OPENFILE_INVALID_FLAG;
64     }
65     auto ret = MediaLibraryDataManager::GetInstance()->OpenFile(uri, mode);
66     if (ret < 0) {
67         return ret;
68     } else {
69         fd = ret;
70         return E_SUCCESS;
71     }
72 }
73 
CreateFile(const Uri & parentUri,const string & displayName,Uri & newFileUri)74 int MediaFileExtentionUtils::CreateFile(const Uri &parentUri, const string &displayName,  Uri &newFileUri)
75 {
76     if (!MediaFileUtils::CheckDisplayName(displayName)) {
77         MEDIA_ERR_LOG("invalid file displayName %{private}s", displayName.c_str());
78         return E_INVAVLID_DISPLAY_NAME;
79     }
80     string parentUriStr = parentUri.ToString();
81     auto ret = MediaFileExtentionUtils::CheckUriSupport(parentUriStr);
82     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid uri");
83     Uri createFileUri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_FILEOPRN + SLASH_CHAR + MEDIA_FILEOPRN_CREATEASSET);
84     string albumId = MediaLibraryDataManagerUtils::GetIdFromUri(parentUriStr);
85     string albumPath = MediaLibraryObjectUtils::GetPathByIdFromDb(albumId);
86     string relativePath = albumPath.substr(ROOT_MEDIA_DIR.size()) + SLASH_CHAR;
87     string destPath = albumPath + SLASH_CHAR + displayName;
88     DataShareValuesBucket valuesBucket;
89     valuesBucket.Put(MEDIA_DATA_DB_NAME, displayName);
90     valuesBucket.Put(MEDIA_DATA_DB_RELATIVE_PATH, relativePath);
91     valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, MediaFileUtils::GetMediaType(displayName));
92     ret = MediaLibraryDataManager::GetInstance()->Insert(createFileUri, valuesBucket);
93     if (ret > 0) {
94         newFileUri = Uri(MediaFileUtils::GetUriByNameAndId(displayName, "", ret));
95         return E_SUCCESS;
96     } else {
97         MEDIA_ERR_LOG("CreateFile insert fail, %{public}d", ret);
98         return ret;
99     }
100 }
101 
Mkdir(const Uri & parentUri,const string & displayName,Uri & newFileUri)102 int MediaFileExtentionUtils::Mkdir(const Uri &parentUri, const string &displayName, Uri &newFileUri)
103 {
104     string parentUriStr = parentUri.ToString();
105     MediaFileUriType uriType;
106     FileAccessFwk::FileInfo parentInfo;
107     parentInfo.uri = parentUriStr;
108     auto ret = MediaFileExtentionUtils::ResolveUri(parentInfo, uriType);
109     if (ret != E_SUCCESS) {
110         MEDIA_ERR_LOG("Mkdir::invalid input fileInfo");
111         return ret;
112     }
113     string relativePath;
114     ret = MediaFileExtentionUtils::CheckMkdirValid(uriType, parentUriStr, displayName);
115     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid uri");
116     if (uriType != MediaFileUriType::URI_FILE_ROOT) {
117         CHECK_AND_RETURN_RET_LOG(MediaFileExtentionUtils::GetAlbumRelativePathFromDB(parentUriStr, "", relativePath),
118             E_URI_IS_NOT_ALBUM, "selectUri is not valid album uri %{private}s", parentUriStr.c_str());
119     }
120     Uri mkdirUri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_DIROPRN + SLASH_CHAR + MEDIA_DIROPRN_FMS_CREATEDIR);
121     string dirPath = ROOT_MEDIA_DIR + relativePath + displayName;
122     if (MediaLibraryObjectUtils::IsFileExistInDb(dirPath)) {
123         MEDIA_ERR_LOG("Create dir is existed %{private}s", dirPath.c_str());
124         return E_FILE_EXIST;
125     }
126     relativePath = relativePath + displayName + SLASH_CHAR;
127     DataShareValuesBucket valuesBucket;
128     valuesBucket.Put(MEDIA_DATA_DB_RELATIVE_PATH, relativePath);
129     ret = MediaLibraryDataManager::GetInstance()->Insert(mkdirUri, valuesBucket);
130     if (ret > 0) {
131         int32_t dirId = MediaLibraryObjectUtils::GetParentIdByIdFromDb(to_string(ret));
132         newFileUri = Uri(MediaFileUtils::GetUriByNameAndId(displayName, "", dirId));
133         return E_SUCCESS;
134     } else {
135         MEDIA_ERR_LOG("mkdir insert fail, %{public}d", ret);
136         return ret;
137     }
138 }
139 
Delete(const Uri & sourceFileUri)140 int MediaFileExtentionUtils::Delete(const Uri &sourceFileUri)
141 {
142     string sourceUri = sourceFileUri.ToString();
143     auto ret = MediaFileExtentionUtils::CheckUriSupport(sourceUri);
144     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid uri");
145     auto result = MediaFileExtentionUtils::GetFileFromDB(sourceUri, "");
146     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_FAIL, "GetFileFromDB result set is nullptr");
147     int count = 0;
148     result->GetRowCount(count);
149     CHECK_AND_RETURN_RET_LOG(count > 0, E_FAIL, "AbsSharedResultSet empty");
150     ret = result->GoToFirstRow();
151     CHECK_AND_RETURN_RET_LOG(ret == 0, E_FAIL, "Failed to shift at first row");
152     int mediaType = get<int32_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_MEDIA_TYPE, result, TYPE_INT32));
153     string id = MediaLibraryDataManagerUtils::GetIdFromUri(sourceUri);
154     int fileId = stoi(id);
155     int errCode = 0;
156     DataShareValuesBucket valuesBucket;
157     if (mediaType == MEDIA_TYPE_ALBUM) {
158         valuesBucket.Put(MEDIA_DATA_DB_ID, fileId);
159         Uri trashAlbumUri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_DIROPRN + SLASH_CHAR +
160             MEDIA_DIROPRN_FMS_TRASHDIR);
161         errCode = MediaLibraryDataManager::GetInstance()->Insert(trashAlbumUri, valuesBucket);
162     } else {
163         valuesBucket.Put(SMARTALBUMMAP_DB_ALBUM_ID, TRASH_ALBUM_ID_VALUES);
164         valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID, fileId);
165         Uri trashAssetUri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_SMARTALBUMMAPOPRN + SLASH_CHAR +
166             MEDIA_SMARTALBUMMAPOPRN_ADDSMARTALBUM);
167         errCode = MediaLibraryDataManager::GetInstance()->Insert(trashAssetUri, valuesBucket);
168     }
169     return errCode;
170 }
171 
CheckUriValid(const string & uri)172 bool MediaFileExtentionUtils::CheckUriValid(const string &uri)
173 {
174     size_t pos = uri.find(MEDIALIBRARY_DATA_ABILITY_PREFIX);
175     if (pos == string::npos) {
176         MEDIA_ERR_LOG("invalid uri %{private}s", uri.c_str());
177         return false;
178     }
179     size_t slashIndex = uri.rfind(SLASH_CHAR);
180     if (slashIndex == string::npos) {
181         MEDIA_ERR_LOG("invalid uri %{private}s", uri.c_str());
182         return false;
183     }
184     string id = uri.substr(slashIndex + 1);
185     if (id.empty()) {
186         MEDIA_ERR_LOG("invalid uri %{private}s", uri.c_str());
187         return false;
188     }
189     for (const char &c : id) {
190         if (!isdigit(c)) {
191             MEDIA_ERR_LOG("invalid uri %{private}s", uri.c_str());
192             return false;
193         }
194     }
195     return true;
196 }
197 
CheckUriSupport(const string & uri)198 int32_t MediaFileExtentionUtils::CheckUriSupport(const string &uri)
199 {
200     if (!MediaFileExtentionUtils::CheckUriValid(uri)) {
201         MEDIA_ERR_LOG("Invalid uri");
202         return E_URI_INVALID;
203     }
204     if (!MediaFileExtentionUtils::CheckDistributedUri(uri)) {
205         MEDIA_ERR_LOG("CreateFile not support distributed operation");
206         return E_DISTIBUTED_URI_NO_SUPPORT;
207     }
208     return E_SUCCESS;
209 }
210 
ResolveRootUri(string uri,MediaFileUriType & uriType)211 int32_t ResolveRootUri(string uri, MediaFileUriType &uriType)
212 {
213     int32_t ret = E_INVALID_URI;
214     uri = uri.substr(MEDIALIBRARY_ROOT.length());
215     if (uri == MEDIALIBRARY_TYPE_FILE_URI) {
216         uriType = MediaFileUriType::URI_FILE_ROOT;
217         ret = E_SUCCESS;
218     } else if ((uri == MEDIALIBRARY_TYPE_IMAGE_URI) ||
219                (uri == MEDIALIBRARY_TYPE_VIDEO_URI) ||
220                (uri == MEDIALIBRARY_TYPE_AUDIO_URI)) {
221         uriType = MediaFileUriType::URI_MEDIA_ROOT;
222         ret = E_SUCCESS;
223     }
224     return ret;
225 }
226 
ResolveUriWithType(const string & mimeType,MediaFileUriType & uriType)227 int32_t ResolveUriWithType(const string &mimeType, MediaFileUriType &uriType)
228 {
229     if ((mimeType.find(DEFAULT_IMAGE_MIME_TYPE_PREFIX) == 0) ||
230         (mimeType.find(DEFAULT_VIDEO_MIME_TYPE_PREFIX) == 0) ||
231         (mimeType.find(DEFAULT_AUDIO_MIME_TYPE_PREFIX) == 0)) {
232         uriType = MediaFileUriType::URI_ALBUM;
233         return E_SUCCESS;
234     }
235     uriType = MediaFileUriType::URI_DIR;
236     return E_SUCCESS;
237 }
238 
239 /**
240  * URI_ROOT Return four uri of media type(images, audios, videos and file).
241  *  datashare:///media/root
242  * URI_MEDIA_ROOT Return all albums of the specified type.
243  *  datashare:///media/root/image|audio|video
244  * URI_FILE_ROOT Return the files and folders under the root directory.
245  *  datashare:///media/root/file
246  * URI_DIR Return the files and folders in the directory.
247  *  datashare:///media/file/1
248  * URI_ALBUM Return the specified media type assets in the Album.
249  *  datashare:///media/file/1
250  */
ResolveUri(const FileInfo & fileInfo,MediaFileUriType & uriType)251 int32_t MediaFileExtentionUtils::ResolveUri(const FileInfo &fileInfo, MediaFileUriType &uriType)
252 {
253     string uri = fileInfo.uri;
254     if (uri.find(MEDIALIBRARY_DATA_ABILITY_PREFIX) != 0) {
255         return E_INVALID_URI;
256     }
257     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(uri);
258     uri = uri.substr(MEDIALIBRARY_DATA_ABILITY_PREFIX.length() + networkId.length());
259     if (uri.find(MEDIALIBRARY_DATA_URI_IDENTIFIER) != 0) {
260         return E_INVALID_URI;
261     }
262     uri = uri.substr(MEDIALIBRARY_DATA_URI_IDENTIFIER.length());
263     if (uri == MEDIALIBRARY_ROOT) {
264         uriType = MediaFileUriType::URI_ROOT;
265         return E_SUCCESS;
266     }
267     if (uri.find(MEDIALIBRARY_ROOT) == 0) {
268         return ResolveRootUri(uri, uriType);
269     }
270     if (uri.find(MEDIALIBRARY_TYPE_FILE_URI) == 0) {
271         return ResolveUriWithType(fileInfo.mimeType, uriType);
272     }
273     return E_INVALID_URI;
274 }
275 
CheckValidDirName(const std::string & displayName)276 bool MediaFileExtentionUtils::CheckValidDirName(const std::string &displayName)
277 {
278     AbsRdbPredicates absPredicates(MEDIATYPE_DIRECTORY_TABLE);
279     absPredicates.EqualTo(CATEGORY_MEDIATYPE_DIRECTORY_DB_DIRECTORY, displayName);
280     vector<string> columns;
281     auto queryResultSet = MediaLibraryDataManager::GetInstance()->rdbStore_->Query(absPredicates, columns);
282     CHECK_AND_RETURN_RET_LOG(queryResultSet != nullptr, false, "Query functionality failed");
283     int32_t count = 0;
284     queryResultSet->GetRowCount(count);
285     return count > 0;
286 }
287 
CheckMkdirValid(MediaFileUriType uriType,const string & parentUriStr,const string & displayName)288 int32_t MediaFileExtentionUtils::CheckMkdirValid(MediaFileUriType uriType, const string &parentUriStr,
289     const string &displayName)
290 {
291     if (uriType == MediaFileUriType::URI_FILE_ROOT) {
292         CHECK_AND_RETURN_RET_LOG(MediaFileExtentionUtils::CheckDistributedUri(parentUriStr),
293             E_DISTIBUTED_URI_NO_SUPPORT, "Mkdir not support distributed operation");
294         CHECK_AND_RETURN_RET_LOG(MediaFileExtentionUtils::CheckValidDirName(displayName + SLASH_CHAR),
295             E_INVAVLID_DISPLAY_NAME, "invalid directory displayName %{private}s", displayName.c_str());
296     } else {
297         auto ret = MediaFileExtentionUtils::CheckUriSupport(parentUriStr);
298         CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid uri");
299         CHECK_AND_RETURN_RET_LOG(MediaFileUtils::CheckDisplayName(displayName),
300             E_INVAVLID_DISPLAY_NAME, "invalid directory displayName %{private}s", displayName.c_str());
301     }
302     return E_SUCCESS;
303 }
304 
GetFileFromDB(const string & selectUri,const string & networkId)305 shared_ptr<AbsSharedResultSet> MediaFileExtentionUtils::GetFileFromDB(const string &selectUri, const string &networkId)
306 {
307     string queryUri = MEDIALIBRARY_DATA_URI;
308     if (!networkId.empty()) {
309         queryUri = MEDIALIBRARY_DATA_ABILITY_PREFIX + networkId + MEDIALIBRARY_DATA_URI_IDENTIFIER;
310     }
311     string selection = MEDIA_DATA_DB_ID + " = ? ";
312     string id = MediaLibraryDataManagerUtils::GetIdFromUri(selectUri);
313     vector<string> selectionArgs = { id };
314     vector<string> columns;
315     DataShare::DataSharePredicates predicates;
316     predicates.SetWhereClause(selection);
317     predicates.SetWhereArgs(selectionArgs);
318     Uri uri(queryUri);
319     return MediaLibraryDataManager::GetInstance()->QueryRdb(uri, columns, predicates);
320 }
321 
GetAlbumRelativePathFromDB(const string & selectUri,const string & networkId,string & relativePath)322 bool MediaFileExtentionUtils::GetAlbumRelativePathFromDB(const string &selectUri, const string &networkId,
323     string &relativePath)
324 {
325     auto result = MediaFileExtentionUtils::GetFileFromDB(selectUri, networkId);
326     CHECK_AND_RETURN_RET_LOG(result != nullptr, false, "GetFileFromResult Get fail");
327     int count = 0;
328     result->GetRowCount(count);
329     CHECK_AND_RETURN_RET_LOG(count > 0, false, "AbsSharedResultSet empty");
330     auto ret = result->GoToFirstRow();
331     CHECK_AND_RETURN_RET_LOG(ret == 0, false, "Failed to shift at first row");
332     int mediaType = get<int32_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_MEDIA_TYPE, result, TYPE_INT32));
333     CHECK_AND_RETURN_RET_LOG(mediaType == MEDIA_TYPE_ALBUM, false, "selectUri is not album");
334     relativePath = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_RELATIVE_PATH, result, TYPE_STRING));
335     string displayname = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_NAME, result, TYPE_STRING));
336     relativePath = relativePath + displayname + SLASH_CHAR;
337     return true;
338 }
339 
GetQueryUri(const FileInfo & parentInfo,MediaFileUriType uriType)340 string GetQueryUri(const FileInfo &parentInfo, MediaFileUriType uriType)
341 {
342     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
343     string queryUri;
344     if (!networkId.empty()) {
345         queryUri = MEDIALIBRARY_DATA_ABILITY_PREFIX + networkId + MEDIALIBRARY_DATA_URI_IDENTIFIER;
346     } else {
347         queryUri = MEDIALIBRARY_DATA_URI;
348     }
349     if (uriType == URI_MEDIA_ROOT) {
350         queryUri += SLASH_CHAR + MEDIA_ALBUMOPRN_QUERYALBUM;
351     }
352     return queryUri;
353 }
354 
ChangeToLowerCase(vector<string> & vec)355 void ChangeToLowerCase(vector<string> &vec)
356 {
357     for (auto &s : vec) {
358         std::transform(s.begin(), s.end(), s.begin(), ::tolower);
359     }
360 }
361 
GetListFilePredicates(const FileInfo & parentInfo,const DistributedFS::FileFilter & filter,string & selection,vector<string> & selectionArgs)362 int32_t GetListFilePredicates(const FileInfo &parentInfo, const DistributedFS::FileFilter &filter, string &selection,
363     vector<string> &selectionArgs)
364 {
365     string selectUri = parentInfo.uri;
366     if (!MediaFileExtentionUtils::CheckUriValid(selectUri)) {
367         MEDIA_ERR_LOG("selectUri is not valid uri %{private}s", selectUri.c_str());
368         return E_URI_INVALID;
369     }
370     string relativePath;
371     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
372     if (!MediaFileExtentionUtils::GetAlbumRelativePathFromDB(selectUri, networkId, relativePath)) {
373         MEDIA_ERR_LOG("selectUri is not valid album uri %{private}s", selectUri.c_str());
374         return E_URI_IS_NOT_ALBUM;
375     }
376     selection = MEDIA_DATA_DB_RELATIVE_PATH + " = ? AND " + MEDIA_DATA_DB_IS_TRASH + " = ? ";
377     selectionArgs = { relativePath, to_string(NOT_ISTRASH) };
378     if (!filter.GetHasFilter()) {
379         return E_SUCCESS;
380     }
381     vector<string> displayName = filter.GetDisplayName();
382     ChangeToLowerCase(displayName);
383     if (!displayName.empty()) {
384         selection += " AND (" + MEDIA_DATA_DB_TITLE + " = ? ";
385         selectionArgs.push_back(displayName[0]);
386         for (size_t i = 1; i < displayName.size(); i++) {
387             selection += " OR " + MEDIA_DATA_DB_TITLE + " = ? ";
388             selectionArgs.push_back(displayName[i]);
389         }
390         selection += ") ";
391     }
392     vector<string> suffix = filter.GetSuffix();
393     ChangeToLowerCase(suffix);
394     if (!suffix.empty()) {
395         selection += " AND ( " + MEDIA_DATA_DB_NAME + " LIKE ? ";
396         selectionArgs.push_back("%" + suffix[0]);
397         for (size_t i = 1; i < suffix.size(); i++) {
398             selection += " OR " + MEDIA_DATA_DB_NAME + " LIKE ? ";
399             selectionArgs.push_back("%" + suffix[i]);
400         }
401         selection += ") ";
402     }
403     return E_SUCCESS;
404 }
405 
RootListFile(const FileInfo & parentInfo,vector<FileInfo> & fileList)406 static int32_t RootListFile(const FileInfo &parentInfo, vector<FileInfo> &fileList)
407 {
408     FileInfo fileInfo;
409     fileInfo.mode = DOCUMENT_FLAG_REPRESENTS_DIR | DOCUMENT_FLAG_SUPPORTS_READ;
410     string selectUri = parentInfo.uri;
411     fileInfo.fileName = "MEDIA_TYPE_FILE";
412     fileInfo.uri = selectUri + MEDIALIBRARY_TYPE_FILE_URI;
413     fileInfo.mimeType = DEFAULT_FILE_MIME_TYPE;
414     fileList.push_back(fileInfo);
415     fileInfo.fileName = "MEDIA_TYPE_IMAGE";
416     fileInfo.uri = selectUri + MEDIALIBRARY_TYPE_IMAGE_URI;
417     fileInfo.mimeType = DEFAULT_IMAGE_MIME_TYPE;
418     fileList.push_back(fileInfo);
419     fileInfo.fileName = "MEDIA_TYPE_VIDEO";
420     fileInfo.uri = selectUri + MEDIALIBRARY_TYPE_VIDEO_URI;
421     fileInfo.mimeType = DEFAULT_VIDEO_MIME_TYPE;
422     fileList.push_back(fileInfo);
423     fileInfo.fileName = "MEDIA_TYPE_AUDIO";
424     fileInfo.uri = selectUri + MEDIALIBRARY_TYPE_AUDIO_URI;
425     fileInfo.mimeType = DEFAULT_AUDIO_MIME_TYPE;
426     fileList.push_back(fileInfo);
427     return E_SUCCESS;
428 }
429 
GetResult(const Uri & uri,MediaFileUriType uriType,const string & selection,const vector<string> & selectionArgs)430 std::shared_ptr<AbsSharedResultSet> GetResult(const Uri &uri, MediaFileUriType uriType, const string &selection,
431     const vector<string> &selectionArgs)
432 {
433     DataSharePredicates predicates;
434     predicates.SetWhereClause(selection);
435     predicates.SetWhereArgs(selectionArgs);
436     vector<string> columns = { MEDIA_DATA_DB_ID, MEDIA_DATA_DB_SIZE, MEDIA_DATA_DB_DATE_MODIFIED,
437         MEDIA_DATA_DB_MIME_TYPE, MEDIA_DATA_DB_NAME, MEDIA_DATA_DB_MEDIA_TYPE };
438     return MediaLibraryDataManager::GetInstance()->QueryRdb(uri, columns, predicates);
439 }
440 
MimeType2MediaType(const string & mimeType)441 static string MimeType2MediaType(const string &mimeType)
442 {
443     // album view not support file type, so image as default
444     int res = MEDIA_TYPE_IMAGE;
445     if (mimeType.find(DEFAULT_VIDEO_MIME_TYPE_PREFIX) == 0) {
446         res = MEDIA_TYPE_VIDEO;
447     } else if (mimeType.find(DEFAULT_AUDIO_MIME_TYPE_PREFIX) == 0) {
448         res = MEDIA_TYPE_AUDIO;
449     }
450     return to_string(res);
451 }
452 
GetMediaRootResult(const FileInfo & parentInfo,MediaFileUriType uriType,const int64_t offset,const int64_t maxCount)453 std::shared_ptr<AbsSharedResultSet> GetMediaRootResult(const FileInfo &parentInfo, MediaFileUriType uriType,
454     const int64_t offset, const int64_t maxCount)
455 {
456     Uri uri(GetQueryUri(parentInfo, uriType));
457     DataSharePredicates predicates;
458     predicates.EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, MimeType2MediaType(parentInfo.mimeType));
459     predicates.EqualTo(MEDIA_DATA_DB_IS_TRASH, to_string(NOT_ISTRASH));
460     predicates.Limit(maxCount, offset);
461     vector<string> columns = { MEDIA_DATA_DB_BUCKET_ID, MEDIA_DATA_DB_TITLE, MEDIA_DATA_DB_DATE_MODIFIED };
462     return MediaLibraryDataManager::GetInstance()->QueryRdb(uri, columns, predicates);
463 }
464 
GetListRootResult(const FileInfo & parentInfo,MediaFileUriType uriType,const int64_t offset,const int64_t maxCount)465 std::shared_ptr<AbsSharedResultSet> GetListRootResult(const FileInfo &parentInfo, MediaFileUriType uriType,
466     const int64_t offset, const int64_t maxCount)
467 {
468     string selection = MEDIA_DATA_DB_PARENT_ID + " = ? AND " + MEDIA_DATA_DB_MEDIA_TYPE + " <> ? AND " +
469         MEDIA_DATA_DB_IS_TRASH + " = ? LIMIT ?, ?";
470     vector<string> selectionArgs = { to_string(ROOT_PARENT_ID), to_string(MEDIA_TYPE_NOFILE), to_string(NOT_ISTRASH),
471         to_string(offset), to_string(maxCount) };
472     Uri uri(GetQueryUri(parentInfo, uriType));
473     return GetResult(uri, uriType, selection, selectionArgs);
474 }
475 
GetListDirResult(const FileInfo & parentInfo,MediaFileUriType uriType,const int64_t offset,const int64_t maxCount,const DistributedFS::FileFilter & filter)476 std::shared_ptr<AbsSharedResultSet> GetListDirResult(const FileInfo &parentInfo, MediaFileUriType uriType,
477     const int64_t offset, const int64_t maxCount, const DistributedFS::FileFilter &filter)
478 {
479     string selection;
480     vector<string> selectionArgs;
481     int32_t ret = GetListFilePredicates(parentInfo, filter, selection, selectionArgs);
482     if (ret != E_SUCCESS) {
483         return nullptr;
484     }
485     selection += " AND " + MEDIA_DATA_DB_MEDIA_TYPE + " <> ? LIMIT ?, ?";
486     selectionArgs.push_back(to_string(MEDIA_TYPE_NOFILE));
487     selectionArgs.push_back(to_string(offset));
488     selectionArgs.push_back(to_string(maxCount));
489     Uri uri(GetQueryUri(parentInfo, uriType));
490     return GetResult(uri, uriType, selection, selectionArgs);
491 }
492 
GetListAlbumResult(const FileInfo & parentInfo,MediaFileUriType uriType,const int64_t offset,const int64_t maxCount,const DistributedFS::FileFilter & filter)493 std::shared_ptr<AbsSharedResultSet> GetListAlbumResult(const FileInfo &parentInfo, MediaFileUriType uriType,
494     const int64_t offset, const int64_t maxCount, const DistributedFS::FileFilter &filter)
495 {
496     string selection;
497     vector<string> selectionArgs;
498     int32_t ret = GetListFilePredicates(parentInfo, filter, selection, selectionArgs);
499     if (ret != E_SUCCESS) {
500         return nullptr;
501     }
502     selection += " AND " + MEDIA_DATA_DB_MEDIA_TYPE + " = ? LIMIT ?, ?";
503     selectionArgs.push_back(MimeType2MediaType(parentInfo.mimeType));
504     selectionArgs.push_back(to_string(offset));
505     selectionArgs.push_back(to_string(maxCount));
506     Uri uri(GetQueryUri(parentInfo, uriType));
507     return GetResult(uri, uriType, selection, selectionArgs);
508 }
509 
GetFileInfo(FileInfo & fileInfo,const shared_ptr<NativeRdb::ResultSet> & result,const string & networkId="")510 int GetFileInfo(FileInfo &fileInfo, const shared_ptr<NativeRdb::ResultSet> &result, const string &networkId = "")
511 {
512     int fileId = GetInt32Val(MEDIA_DATA_DB_ID, result);
513     int mediaType = GetInt32Val(MEDIA_DATA_DB_MEDIA_TYPE, result);
514     fileInfo.uri =
515         MediaFileUtils::GetFileMediaTypeUri(MediaType(mediaType), networkId) + SLASH_CHAR + to_string(fileId);
516     fileInfo.fileName = GetStringVal(MEDIA_DATA_DB_NAME, result);
517     fileInfo.mimeType = GetStringVal(MEDIA_DATA_DB_MIME_TYPE, result);
518     if (mediaType == MEDIA_TYPE_ALBUM) {
519         fileInfo.mode = ALBUM_MODE_RW;
520     } else {
521         fileInfo.size = GetInt64Val(MEDIA_DATA_DB_SIZE, result);
522         fileInfo.mode = FILE_MODE_RW;
523     }
524     fileInfo.mtime = GetInt64Val(MEDIA_DATA_DB_DATE_MODIFIED, result);
525     return E_SUCCESS;
526 }
527 
GetAlbumInfoFromResult(const FileInfo & parentInfo,shared_ptr<AbsSharedResultSet> & result,vector<FileInfo> & fileList)528 int32_t GetAlbumInfoFromResult(const FileInfo &parentInfo, shared_ptr<AbsSharedResultSet> &result,
529     vector<FileInfo> &fileList)
530 {
531     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_FAIL, "AbsSharedResultSet is nullptr");
532     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
533     FileInfo fileInfo;
534     while (result->GoToNextRow() == NativeRdb::E_OK) {
535         int fileId = get<int32_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_BUCKET_ID, result, TYPE_INT32));
536         fileInfo.fileName = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_TITLE, result, TYPE_STRING));
537         fileInfo.mimeType = parentInfo.mimeType;
538         fileInfo.uri =
539             MediaFileUtils::GetFileMediaTypeUri(MEDIA_TYPE_ALBUM, networkId) + SLASH_CHAR + to_string(fileId);
540         fileInfo.mtime =
541             get<int64_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_DATE_MODIFIED, result, TYPE_INT64));
542         fileInfo.mode = DOCUMENT_FLAG_REPRESENTS_DIR | DOCUMENT_FLAG_SUPPORTS_READ | DOCUMENT_FLAG_SUPPORTS_WRITE;
543         fileList.push_back(fileInfo);
544     }
545     return E_SUCCESS;
546 }
547 
GetFileInfoFromResult(const FileInfo & parentInfo,shared_ptr<AbsSharedResultSet> & result,vector<FileInfo> & fileList)548 int32_t GetFileInfoFromResult(const FileInfo &parentInfo, shared_ptr<AbsSharedResultSet> &result,
549     vector<FileInfo> &fileList)
550 {
551     CHECK_AND_RETURN_RET_LOG(result != nullptr, E_FAIL, "AbsSharedResultSet is nullptr");
552     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
553     while (result->GoToNextRow() == NativeRdb::E_OK) {
554         FileInfo fileInfo;
555         GetFileInfo(fileInfo, result, networkId);
556         fileList.push_back(fileInfo);
557     }
558     return E_SUCCESS;
559 }
560 
ListFile(const FileInfo & parentInfo,const int64_t offset,const int64_t maxCount,const DistributedFS::FileFilter & filter,vector<FileInfo> & fileList)561 int32_t MediaFileExtentionUtils::ListFile(const FileInfo &parentInfo, const int64_t offset, const int64_t maxCount,
562     const DistributedFS::FileFilter &filter, vector<FileInfo> &fileList)
563 {
564     MediaFileUriType uriType;
565     auto ret = MediaFileExtentionUtils::ResolveUri(parentInfo, uriType);
566     MEDIA_DEBUG_LOG("ListFile:: uriType: %d", uriType);
567     if (ret != E_SUCCESS) {
568         MEDIA_ERR_LOG("ResolveUri::invalid input fileInfo");
569         return ret;
570     }
571     std::shared_ptr<AbsSharedResultSet> resultSet = nullptr;
572     switch (uriType) {
573         case URI_ROOT:
574             return RootListFile(parentInfo, fileList);
575         case URI_MEDIA_ROOT:
576             resultSet = GetMediaRootResult(parentInfo, uriType, offset, maxCount);
577             return GetAlbumInfoFromResult(parentInfo, resultSet, fileList);
578         case URI_FILE_ROOT:
579             resultSet = GetListRootResult(parentInfo, uriType, offset, maxCount);
580             return GetFileInfoFromResult(parentInfo, resultSet, fileList);
581         case URI_DIR:
582             resultSet = GetListDirResult(parentInfo, uriType, offset, maxCount, filter);
583             return GetFileInfoFromResult(parentInfo, resultSet, fileList);
584         case URI_ALBUM:
585             resultSet = GetListAlbumResult(parentInfo, uriType, offset, maxCount, filter);
586             return GetFileInfoFromResult(parentInfo, resultSet, fileList);
587         default:
588             return E_FAIL;
589     }
590 }
591 
GetScanFileFileInfoFromResult(const FileInfo & parentInfo,shared_ptr<AbsSharedResultSet> & result,vector<FileInfo> & fileList)592 int32_t GetScanFileFileInfoFromResult(const FileInfo &parentInfo, shared_ptr<AbsSharedResultSet> &result,
593     vector<FileInfo> &fileList)
594 {
595     if (result == nullptr) {
596         return E_FAIL;
597     }
598     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
599     while (result->GoToNextRow() == NativeRdb::E_OK) {
600         FileInfo fileInfo;
601         GetFileInfo(fileInfo, result, networkId);
602         fileList.push_back(fileInfo);
603     }
604     return E_SUCCESS;
605 }
606 
GetScanFileResult(const Uri & uri,MediaFileUriType uriType,const string & selection,const vector<string> & selectionArgs)607 std::shared_ptr<AbsSharedResultSet> GetScanFileResult(const Uri &uri, MediaFileUriType uriType, const string &selection,
608     const vector<string> &selectionArgs)
609 {
610     DataSharePredicates predicates;
611     predicates.SetWhereClause(selection);
612     predicates.SetWhereArgs(selectionArgs);
613     vector<string> columns {
614         MEDIA_DATA_DB_BUCKET_ID,
615         MEDIA_DATA_DB_TITLE,
616         MEDIA_DATA_DB_ID,
617         MEDIA_DATA_DB_SIZE,
618         MEDIA_DATA_DB_DATE_MODIFIED,
619         MEDIA_DATA_DB_MIME_TYPE,
620         MEDIA_DATA_DB_NAME,
621         MEDIA_DATA_DB_MEDIA_TYPE
622     };
623     return MediaLibraryDataManager::GetInstance()->QueryRdb(uri, columns, predicates);
624 }
625 
SetScanFileSelection(const FileInfo & parentInfo,MediaFileUriType uriType,const int64_t offset,const int64_t maxCount,const DistributedFS::FileFilter & filter)626 std::shared_ptr<AbsSharedResultSet> SetScanFileSelection(const FileInfo &parentInfo, MediaFileUriType uriType,
627     const int64_t offset, const int64_t maxCount, const DistributedFS::FileFilter &filter)
628 {
629     string filePath;
630     vector<string> selectionArgs;
631     if (uriType == MediaFileUriType::URI_ROOT) {
632         filePath = ROOT_MEDIA_DIR;
633         selectionArgs.push_back(filePath + "%");
634     } else {
635         string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(parentInfo.uri);
636         auto result = MediaFileExtentionUtils::GetFileFromDB(parentInfo.uri, networkId);
637         CHECK_AND_RETURN_RET_LOG(result != nullptr, nullptr, "GetFileFromDB Get fail");
638         int count = 0;
639         result->GetRowCount(count);
640         CHECK_AND_RETURN_RET_LOG(count > 0, nullptr, "AbsSharedResultSet empty");
641         auto ret = result->GoToFirstRow();
642         CHECK_AND_RETURN_RET_LOG(ret == 0, nullptr, "Failed to shift at first row");
643         filePath = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_FILE_PATH, result, TYPE_STRING));
644         selectionArgs.push_back(filePath + "/%");
645     }
646     MEDIA_DEBUG_LOG("ScanFile filepath: %{private}s", filePath.c_str());
647     string selection = MEDIA_DATA_DB_FILE_PATH + " LIKE ? ";
648     if (filter.GetSuffix().size() > 0) {
649         selection += " AND ( " + Media::MEDIA_DATA_DB_NAME + " LIKE ? ";
650         selectionArgs.emplace_back("%" + filter.GetSuffix()[0]);
651     }
652     for (size_t i = 1; i < filter.GetSuffix().size(); i++) {
653         selection += " OR " + Media::MEDIA_DATA_DB_NAME + " LIKE ? ";
654         selectionArgs.emplace_back("%" + filter.GetSuffix()[i]);
655     }
656     if (filter.GetSuffix().size() > 0) {
657         selection += ")";
658     }
659     selection += " AND " + MEDIA_DATA_DB_MEDIA_TYPE + " <> " + to_string(MEDIA_TYPE_ALBUM);
660     selection += " AND " + MEDIA_DATA_DB_MEDIA_TYPE + " <> " + to_string(MEDIA_TYPE_NOFILE);
661     selection += " AND " + MEDIA_DATA_DB_IS_TRASH + " = ? LIMIT ?, ?";
662     selectionArgs.push_back(to_string(NOT_ISTRASH));
663     selectionArgs.push_back(to_string(offset));
664     selectionArgs.push_back(to_string(maxCount));
665     Uri uri(GetQueryUri(parentInfo, uriType));
666     return GetScanFileResult(uri, uriType, selection, selectionArgs);
667 }
668 
ScanFile(const FileInfo & parentInfo,const int64_t offset,const int64_t maxCount,const DistributedFS::FileFilter & filter,vector<FileInfo> & fileList)669 int32_t MediaFileExtentionUtils::ScanFile(const FileInfo &parentInfo, const int64_t offset, const int64_t maxCount,
670     const DistributedFS::FileFilter &filter, vector<FileInfo> &fileList)
671 {
672     MediaFileUriType uriType;
673     auto ret = MediaFileExtentionUtils::ResolveUri(parentInfo, uriType);
674     MEDIA_DEBUG_LOG("ScanFile:: uriType: %d", uriType);
675     if (ret != E_SUCCESS) {
676         MEDIA_ERR_LOG("ResolveUri::invalid input fileInfo");
677         return ret;
678     }
679     std::shared_ptr<AbsSharedResultSet> resultSet = SetScanFileSelection(parentInfo, uriType, offset, maxCount,
680         filter);
681     return GetScanFileFileInfoFromResult(parentInfo, resultSet, fileList);
682 }
683 
GetRootInfo(shared_ptr<AbsSharedResultSet> & result,RootInfo & rootInfo)684 bool GetRootInfo(shared_ptr<AbsSharedResultSet> &result, RootInfo &rootInfo)
685 {
686     string networkId = get<string>(ResultSetUtils::GetValFromColumn(DEVICE_DB_NETWORK_ID, result, TYPE_STRING));
687     rootInfo.uri = MEDIALIBRARY_DATA_ABILITY_PREFIX + networkId + MEDIALIBRARY_DATA_URI_IDENTIFIER + MEDIALIBRARY_ROOT;
688     rootInfo.displayName = get<string>(ResultSetUtils::GetValFromColumn(DEVICE_DB_NAME, result, TYPE_STRING));
689     rootInfo.deviceFlags = DEVICE_FLAG_SUPPORTS_READ;
690     rootInfo.deviceType = DEVICE_SHARED_TERMINAL;
691     return true;
692 }
693 
GetRootInfoFromResult(shared_ptr<AbsSharedResultSet> & result,vector<RootInfo> & rootList)694 void GetRootInfoFromResult(shared_ptr<AbsSharedResultSet> &result, vector<RootInfo> &rootList)
695 {
696     int count = 0;
697     result->GetRowCount(count);
698     CHECK_AND_RETURN_LOG(count > 0, "AbsSharedResultSet empty");
699     auto ret = result->GoToFirstRow();
700     CHECK_AND_RETURN_LOG(ret == 0, "Failed to shift at first row");
701     rootList.reserve(count + 1);
702     for (int i = 0; i < count; i++) {
703         RootInfo rootInfo;
704         GetRootInfo(result, rootInfo);
705         rootList.push_back(rootInfo);
706         ret = result->GoToNextRow();
707         CHECK_AND_RETURN_LOG(ret == 0, "Failed to GoToNextRow");
708     }
709 }
710 
GetActivePeer(shared_ptr<AbsSharedResultSet> & result)711 void GetActivePeer(shared_ptr<AbsSharedResultSet> &result)
712 {
713     std::string strQueryCondition = DEVICE_DB_DATE_MODIFIED + " = 0";
714     DataShare::DataSharePredicates predicates;
715     predicates.SetWhereClause(strQueryCondition);
716     vector<string> columns;
717     Uri uri(MEDIALIBRARY_DATA_URI + SLASH_CHAR + MEDIA_DEVICE_QUERYACTIVEDEVICE);
718     result = MediaLibraryDataManager::GetInstance()->QueryRdb(uri, columns, predicates);
719 }
720 
GetRoots(vector<RootInfo> & rootList)721 int32_t MediaFileExtentionUtils::GetRoots(vector<RootInfo> &rootList)
722 {
723     RootInfo rootInfo;
724     // add local root
725     rootInfo.uri = MEDIALIBRARY_DATA_URI + MEDIALIBRARY_ROOT;
726     rootInfo.displayName = MEDIALIBRARY_LOCAL_DEVICE_NAME;
727     rootInfo.deviceFlags = DEVICE_FLAG_SUPPORTS_READ | DEVICE_FLAG_SUPPORTS_WRITE;
728     rootInfo.deviceType = DEVICE_LOCAL_DISK;
729     rootList.push_back(rootInfo);
730     shared_ptr<AbsSharedResultSet> resultSet;
731     GetActivePeer(resultSet);
732     GetRootInfoFromResult(resultSet, rootList);
733     return E_SUCCESS;
734 }
735 
Access(const Uri & uri,bool & isExist)736 int MediaFileExtentionUtils::Access(const Uri &uri, bool &isExist)
737 {
738     isExist = false;
739     string sourceUri = uri.ToString();
740     CHECK_AND_RETURN_RET_LOG(MediaFileExtentionUtils::CheckUriValid(sourceUri), E_URI_INVALID,
741         "Access::invalid uri: %{public}s", sourceUri.c_str());
742     shared_ptr<FileAsset> srcAsset = MediaLibraryObjectUtils::GetFileAssetFromDb(sourceUri);
743     if ((srcAsset == nullptr) || (srcAsset->GetIsTrash() != NOT_ISTRASH)) {
744         MEDIA_ERR_LOG("Access::uri is not correct: %{public}s", sourceUri.c_str());
745         return E_INVALID_URI;
746     }
747     isExist = true;
748     return E_SUCCESS;
749 }
750 
CheckDistributedUri(const string & uri)751 bool MediaFileExtentionUtils::CheckDistributedUri(const string &uri)
752 {
753     string networkId = MediaLibraryDataManagerUtils::GetNetworkIdFromUri(uri);
754     if (!networkId.empty()) {
755         MEDIA_ERR_LOG("not support distributed operation %{public}s", uri.c_str());
756         return false;
757     }
758     return true;
759 }
760 
GetRelativePathFromDB(const string & selectUri,const string & networkId,string & relativePath)761 static bool GetRelativePathFromDB(const string &selectUri, const string &networkId, string &relativePath)
762 {
763     auto result = MediaFileExtentionUtils::GetFileFromDB(selectUri, networkId);
764     CHECK_AND_RETURN_RET_LOG(result != nullptr, false, "GetFileFromResult Get fail");
765     int count = 0;
766     result->GetRowCount(count);
767     CHECK_AND_RETURN_RET_LOG(count > 0, false, "AbsSharedResultSet empty");
768     auto ret = result->GoToFirstRow();
769     CHECK_AND_RETURN_RET_LOG(ret == 0, false, "Failed to shift at first row");
770     relativePath = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_RELATIVE_PATH, result, TYPE_STRING));
771     return true;
772 }
773 
HandleFileRename(const shared_ptr<FileAsset> & srcAsset,const string & displayName,const string & destRelativePath)774 int32_t HandleFileRename(const shared_ptr<FileAsset> &srcAsset, const string &displayName,
775     const string &destRelativePath)
776 {
777     string uri = MEDIALIBRARY_DATA_URI;
778     Uri updateAssetUri(uri + SLASH_CHAR + MEDIA_FILEOPRN + SLASH_CHAR + MEDIA_FILEOPRN_MODIFYASSET);
779     DataShare::DataSharePredicates predicates;
780     DataShare::DataShareValuesBucket valuesBucket;
781     valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, srcAsset->GetMediaType());
782     valuesBucket.Put(MEDIA_DATA_DB_URI, srcAsset->GetUri());
783     valuesBucket.Put(MEDIA_DATA_DB_NAME, displayName);
784     valuesBucket.Put(MEDIA_DATA_DB_RELATIVE_PATH, destRelativePath);
785     predicates.SetWhereClause(MEDIA_DATA_DB_ID + " = ? ");
786     predicates.SetWhereArgs({ MediaLibraryDataManagerUtils::GetIdFromUri(srcAsset->GetUri()) });
787     auto ret = MediaLibraryDataManager::GetInstance()->Update(updateAssetUri, valuesBucket, predicates);
788     if (ret > 0) {
789         return E_SUCCESS;
790     } else {
791         MEDIA_ERR_LOG("HandleFileRename Update ret %{private}d", ret);
792         return ret;
793     }
794 }
795 
GetRelativePathFromPath(const string & path)796 string GetRelativePathFromPath(const string &path)
797 {
798     string relativePath = "";
799     if (path.length() > ROOT_MEDIA_DIR.length()) {
800         relativePath = path.substr(ROOT_MEDIA_DIR.length());
801     }
802     return relativePath;
803 }
804 
UpdateRenamedAlbumInfo(const string & srcId,const string & displayName,const string & newAlbumPath)805 int32_t UpdateRenamedAlbumInfo(const string &srcId, const string &displayName, const string &newAlbumPath)
806 {
807     int64_t date_modified = MediaFileUtils::GetAlbumDateModified(newAlbumPath);
808     AbsRdbPredicates absPredicates(MEDIALIBRARY_TABLE);
809     absPredicates.EqualTo(MEDIA_DATA_DB_ID, srcId);
810     ValuesBucket valuesBucket;
811     valuesBucket.PutLong(MEDIA_DATA_DB_DATE_MODIFIED, date_modified);
812     valuesBucket.PutString(MEDIA_DATA_DB_FILE_PATH, newAlbumPath);
813     valuesBucket.PutString(MEDIA_DATA_DB_TITLE, displayName);
814     valuesBucket.PutString(MEDIA_DATA_DB_NAME, displayName);
815     valuesBucket.PutString(MEDIA_DATA_DB_BUCKET_NAME, displayName);
816     int32_t count = 0;
817     return MediaLibraryDataManager::GetInstance()->rdbStore_->Update(count, valuesBucket, absPredicates);
818 }
819 
UpdateSubFilesPath(const string & srcPath,const string & newAlbumPath)820 int32_t UpdateSubFilesPath(const string &srcPath, const string &newAlbumPath)
821 {
822     int64_t date_modified = MediaFileUtils::GetAlbumDateModified(newAlbumPath);
823     std::string modifySql = "UPDATE " + MEDIALIBRARY_TABLE + " SET ";
824     // Update data "old albumPath/%" -> "new albumPath/%"
825     modifySql += MEDIA_DATA_DB_FILE_PATH + " = replace("
826         + MEDIA_DATA_DB_FILE_PATH + ", '" + srcPath + "/' , '" + newAlbumPath + "/'), ";
827     // Update relative_path "old album relativePath/%" -> "new album relativePath/%"
828     modifySql += MEDIA_DATA_DB_RELATIVE_PATH + " = replace(" + MEDIA_DATA_DB_RELATIVE_PATH
829         + ", '" + GetRelativePathFromPath(srcPath) + "/', '" + GetRelativePathFromPath(newAlbumPath) + "/'), ";
830     // Update date_modified "old time" -> "new time"
831     modifySql += MEDIA_DATA_DB_DATE_MODIFIED + " = " + to_string(date_modified);
832     modifySql += " WHERE " + MEDIA_DATA_DB_FILE_PATH + " LIKE '" + srcPath + "/%'";
833     MEDIA_DEBUG_LOG("UpdateSubFilesPath modifySql %{private}s", modifySql.c_str());
834     return MediaLibraryDataManager::GetInstance()->rdbStore_->ExecuteSql(modifySql);
835 }
836 
UpdateSubFilesBucketName(const string & srcId,const string & displayName)837 int32_t UpdateSubFilesBucketName(const string &srcId, const string &displayName)
838 {
839     // Update bucket_display_name "old album displayName" -> "new album displayName"
840     string modifySql = "UPDATE " + MEDIALIBRARY_TABLE + " SET " + MEDIA_DATA_DB_BUCKET_NAME + " = '" + displayName;
841     modifySql += "' WHERE " + MEDIA_DATA_DB_PARENT_ID + " = " + srcId + " AND " +
842         MEDIA_DATA_DB_MEDIA_TYPE + " <> " + to_string(MEDIA_TYPE_ALBUM);
843     MEDIA_DEBUG_LOG("UpdateSubFilesBucketName modifySql %{private}s", modifySql.c_str());
844     return MediaLibraryDataManager::GetInstance()->rdbStore_->ExecuteSql(modifySql);
845 }
846 
HandleAlbumRename(const shared_ptr<FileAsset> & srcAsset,const string & displayName)847 int32_t HandleAlbumRename(const shared_ptr<FileAsset> &srcAsset, const string &displayName)
848 {
849     if (srcAsset->GetRelativePath().empty()) {
850         MEDIA_ERR_LOG("Rename dir in root dir, denied");
851         return E_DENIED_RENAME;
852     }
853     string srcPath = srcAsset->GetPath();
854     size_t slashIndex = srcPath.rfind(SLASH_CHAR);
855     string destPath = srcPath.substr(0, slashIndex) + SLASH_CHAR + displayName;
856     if (MediaLibraryObjectUtils::IsFileExistInDb(destPath)) {
857         MEDIA_ERR_LOG("Rename file is existed %{private}s", destPath.c_str());
858         return E_FILE_EXIST;
859     }
860     bool succ = MediaFileUtils::RenameDir(srcPath, destPath);
861     if (!succ) {
862         MEDIA_ERR_LOG("Failed RenameDir errno %{public}d", errno);
863         return E_MODIFY_DATA_FAIL;
864     }
865     // update parent info
866     string parentPath = ROOT_MEDIA_DIR + srcAsset->GetRelativePath();
867     parentPath.pop_back();
868     MediaLibraryObjectUtils::UpdateDateModified(parentPath);
869 
870     // update album info
871     string srcId = to_string(srcAsset->GetId());
872     int32_t updateResult = UpdateRenamedAlbumInfo(srcId, displayName, destPath);
873     CHECK_AND_RETURN_RET_LOG(updateResult == NativeRdb::E_OK, E_UPDATE_DB_FAIL, "UpdateRenamedAlbumInfo failed");
874 
875     // update child info
876     updateResult = UpdateSubFilesPath(srcPath, destPath);
877     CHECK_AND_RETURN_RET_LOG(updateResult == NativeRdb::E_OK, E_UPDATE_DB_FAIL, "UpdateSubFilesPath failed");
878     updateResult = UpdateSubFilesBucketName(srcId, displayName);
879     CHECK_AND_RETURN_RET_LOG(updateResult == NativeRdb::E_OK, E_UPDATE_DB_FAIL,
880         "UpdateSubFilesBucketName failed");
881     return E_SUCCESS;
882 }
883 
Rename(const Uri & sourceFileUri,const std::string & displayName,Uri & newFileUri)884 int32_t MediaFileExtentionUtils::Rename(const Uri &sourceFileUri, const std::string &displayName, Uri &newFileUri)
885 {
886     string sourceUri = sourceFileUri.ToString();
887     auto ret = MediaFileExtentionUtils::CheckUriSupport(sourceUri);
888     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid uri");
889     if (!MediaFileUtils::CheckDisplayName(displayName)) {
890         MEDIA_ERR_LOG("invalid displayName %{private}s", displayName.c_str());
891         return E_INVAVLID_DISPLAY_NAME;
892     }
893     shared_ptr<FileAsset> srcAsset = MediaLibraryObjectUtils::GetFileAssetFromDb(sourceUri);
894     if (srcAsset == nullptr) {
895         MEDIA_ERR_LOG("Rename source uri is not correct %{private}s", sourceUri.c_str());
896         return E_MODIFY_DATA_FAIL;
897     }
898     string destRelativePath;
899     if (!GetRelativePathFromDB(sourceUri, "", destRelativePath)) {
900         MEDIA_ERR_LOG("Rename uri is not correct %{private}s", sourceUri.c_str());
901         return E_MODIFY_DATA_FAIL;
902     }
903     if (srcAsset->GetMediaType() == MediaType::MEDIA_TYPE_ALBUM) {
904         ret = HandleAlbumRename(srcAsset, displayName);
905     } else {
906         ret = HandleFileRename(srcAsset, displayName, destRelativePath);
907     }
908     if (ret == E_SUCCESS) {
909         newFileUri = Uri(sourceUri);
910     }
911     return ret;
912 }
913 
HandleFileMove(const shared_ptr<FileAsset> & srcAsset,const string & destRelativePath)914 int32_t HandleFileMove(const shared_ptr<FileAsset> &srcAsset, const string &destRelativePath)
915 {
916     string uri = MEDIALIBRARY_DATA_URI;
917     Uri updateAssetUri(uri + SLASH_CHAR + MEDIA_FILEOPRN + SLASH_CHAR + MEDIA_FILEOPRN_MODIFYASSET);
918     DataShare::DataSharePredicates predicates;
919     DataShare::DataShareValuesBucket valuesBucket;
920     valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, srcAsset->GetMediaType());
921     valuesBucket.Put(MEDIA_DATA_DB_URI, srcAsset->GetUri());
922     valuesBucket.Put(MEDIA_DATA_DB_NAME, srcAsset->GetDisplayName());
923     valuesBucket.Put(MEDIA_DATA_DB_RELATIVE_PATH, destRelativePath);
924     predicates.SetWhereClause(MEDIA_DATA_DB_ID + " = ? ");
925     predicates.SetWhereArgs({ MediaLibraryDataManagerUtils::GetIdFromUri(srcAsset->GetUri()) });
926     auto ret = MediaLibraryDataManager::GetInstance()->Update(updateAssetUri, valuesBucket, predicates);
927     if (ret > 0) {
928         return E_SUCCESS;
929     } else {
930         MEDIA_ERR_LOG("HandleFileMove Update ret %{private}d", ret);
931         return ret;
932     }
933 }
934 
UpdateMovedAlbumInfo(const shared_ptr<FileAsset> & srcAsset,const string & bucketId,const string & newAlbumPath,const string & destRelativePath)935 int32_t UpdateMovedAlbumInfo(const shared_ptr<FileAsset> &srcAsset, const string &bucketId, const string &newAlbumPath,
936     const string &destRelativePath)
937 {
938     int64_t date_modified = MediaFileUtils::GetAlbumDateModified(newAlbumPath);
939     AbsRdbPredicates absPredicates(MEDIALIBRARY_TABLE);
940     absPredicates.EqualTo(MEDIA_DATA_DB_ID, to_string(srcAsset->GetId()));
941     ValuesBucket valuesBucket;
942     valuesBucket.PutLong(MEDIA_DATA_DB_DATE_MODIFIED, date_modified);
943     valuesBucket.PutInt(MEDIA_DATA_DB_PARENT_ID, stoi(bucketId));
944     valuesBucket.PutInt(MEDIA_DATA_DB_BUCKET_ID, stoi(bucketId));
945     valuesBucket.PutString(MEDIA_DATA_DB_FILE_PATH, newAlbumPath);
946     valuesBucket.PutString(MEDIA_DATA_DB_RELATIVE_PATH, destRelativePath);
947     int32_t count = 0;
948     return MediaLibraryDataManager::GetInstance()->rdbStore_->Update(count, valuesBucket, absPredicates);
949 }
950 
HandleAlbumMove(const shared_ptr<FileAsset> & srcAsset,const string & destRelativePath,const string & bucketId)951 int32_t HandleAlbumMove(const shared_ptr<FileAsset> &srcAsset, const string &destRelativePath, const string &bucketId)
952 {
953     string destPath = ROOT_MEDIA_DIR + destRelativePath + srcAsset->GetDisplayName();
954     if (MediaLibraryObjectUtils::IsFileExistInDb(destPath)) {
955         MEDIA_ERR_LOG("Move file is existed %{private}s", destPath.c_str());
956         return E_FILE_EXIST;
957     }
958     bool succ = MediaFileUtils::RenameDir(srcAsset->GetPath(), destPath);
959     if (!succ) {
960         MEDIA_ERR_LOG("Failed RenameDir errno %{public}d", errno);
961         return E_MODIFY_DATA_FAIL;
962     }
963 
964     // update parent info
965     string srcParentPath = ROOT_MEDIA_DIR + srcAsset->GetRelativePath();
966     srcParentPath.pop_back();
967     string tarParentPath = ROOT_MEDIA_DIR + destRelativePath;
968     tarParentPath.pop_back();
969     MediaLibraryObjectUtils::UpdateDateModified(srcParentPath);
970     MediaLibraryObjectUtils::UpdateDateModified(tarParentPath);
971 
972     // update album info
973     int32_t updateResult = UpdateMovedAlbumInfo(srcAsset, bucketId, destPath, destRelativePath);
974     CHECK_AND_RETURN_RET_LOG(updateResult == NativeRdb::E_OK, E_UPDATE_DB_FAIL, "UpdateMovedAlbumInfo failed");
975 
976     // update child info
977     updateResult = UpdateSubFilesPath(srcAsset->GetPath(), destPath);
978     CHECK_AND_RETURN_RET_LOG(updateResult == NativeRdb::E_OK, E_UPDATE_DB_FAIL, "UpdateSubFilesPath failed");
979     return E_SUCCESS;
980 }
981 
CheckFileExtension(const string & relativePath,const string & name,int32_t mediaType)982 int32_t CheckFileExtension(const string &relativePath, const string &name, int32_t mediaType)
983 {
984     std::unordered_map<std::string, DirAsset> dirQuerySetMap;
985     MediaLibraryDataManager::GetInstance()->MakeDirQuerySetMap(dirQuerySetMap);
986     MediaLibraryDirOperations dirOprn;
987     ValuesBucket values;
988     values.PutString(MEDIA_DATA_DB_NAME, name);
989     values.PutString(MEDIA_DATA_DB_RELATIVE_PATH, relativePath);
990     values.PutInt(MEDIA_DATA_DB_MEDIA_TYPE, mediaType);
991     return dirOprn.HandleDirOperations(MEDIA_DIROPRN_CHECKDIR_AND_EXTENSION,
992         values, MediaLibraryDataManager::GetInstance()->rdbStore_, dirQuerySetMap);
993 }
994 
GetMoveSubFile(const string & srcPath,shared_ptr<AbsSharedResultSet> & result)995 void GetMoveSubFile(const string &srcPath, shared_ptr<AbsSharedResultSet> &result)
996 {
997     string queryUri = MEDIALIBRARY_DATA_URI;
998     string selection = MEDIA_DATA_DB_FILE_PATH + " LIKE ? ";
999     vector<string> selectionArgs = { srcPath + SLASH_CHAR + "%" };
1000     vector<string> columns;
1001     DataShare::DataSharePredicates predicates;
1002     predicates.SetWhereClause(selection);
1003     predicates.SetWhereArgs(selectionArgs);
1004     Uri uri(queryUri);
1005     result = MediaLibraryDataManager::GetInstance()->QueryRdb(uri, columns, predicates);
1006 }
1007 
CheckSubFileExtension(const string & srcPath,const string & destRelPath)1008 bool CheckSubFileExtension(const string &srcPath, const string &destRelPath)
1009 {
1010     shared_ptr<AbsSharedResultSet> result;
1011     GetMoveSubFile(srcPath, result);
1012     CHECK_AND_RETURN_RET_LOG(result != nullptr, false, "GetSrcFileFromResult Get fail");
1013     int count = 0;
1014     result->GetRowCount(count);
1015     CHECK_AND_RETURN_RET_LOG(count > 0, true, "AbsSharedResultSet empty");
1016     while (result->GoToNextRow() == NativeRdb::E_OK) {
1017         int32_t mediaType = get<int32_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_MEDIA_TYPE,
1018             result, TYPE_INT32));
1019         string path = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_FILE_PATH,
1020             result, TYPE_STRING));
1021         string name = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_NAME,
1022             result, TYPE_STRING));
1023         if (mediaType == MEDIA_TYPE_ALBUM) {
1024             continue;
1025         }
1026         if (CheckFileExtension(destRelPath, name, mediaType) != E_SUCCESS) {
1027             return false;
1028         }
1029     }
1030     return true;
1031 }
1032 
CheckRootDir(const shared_ptr<FileAsset> & srcAsset,const string & destRelPath)1033 bool CheckRootDir(const shared_ptr<FileAsset> &srcAsset, const string &destRelPath)
1034 {
1035     string srcRelPath = srcAsset->GetRelativePath();
1036     if (srcAsset->GetRelativePath().empty()) {
1037         MEDIA_ERR_LOG("Can not move the first level directories, like Pictures, Audios, ...");
1038         return false;
1039     }
1040     if (destRelPath.empty()) {
1041         MEDIA_ERR_LOG("Can not move to root dir");
1042         return false;
1043     }
1044     size_t srcPos = srcRelPath.find(SLASH_CHAR);
1045     size_t destPos = destRelPath.find(SLASH_CHAR);
1046     if (srcPos == string::npos || destPos == string::npos) {
1047         MEDIA_ERR_LOG("Invalid relativePath %{private}s, %{private}s", srcRelPath.c_str(), destRelPath.c_str());
1048         return false;
1049     }
1050     if (srcRelPath.substr(0, srcPos) != destRelPath.substr(0, destPos)) {
1051         MEDIA_INFO_LOG("move dir to other root dir");
1052         return CheckSubFileExtension(srcAsset->GetPath(), destRelPath);
1053     }
1054     return true;
1055 }
1056 
Move(const Uri & sourceFileUri,const Uri & targetParentUri,Uri & newFileUri)1057 int32_t MediaFileExtentionUtils::Move(const Uri &sourceFileUri, const Uri &targetParentUri, Uri &newFileUri)
1058 {
1059     string sourceUri = sourceFileUri.ToString();
1060     string targetUri = targetParentUri.ToString();
1061     CHECK_AND_RETURN_RET_LOG(sourceUri != targetUri, E_TWO_URI_ARE_THE_SAME,
1062         "sourceUri is the same as TargetUri");
1063     auto ret = MediaFileExtentionUtils::CheckUriSupport(sourceUri);
1064     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid source uri");
1065     ret = MediaFileExtentionUtils::CheckUriSupport(targetUri);
1066     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "invalid targetUri uri");
1067     shared_ptr<FileAsset> srcAsset = MediaLibraryObjectUtils::GetFileAssetFromDb(sourceUri);
1068     if (srcAsset == nullptr) {
1069         MEDIA_ERR_LOG("Move source uri is not correct %{private}s", sourceUri.c_str());
1070         return E_MODIFY_DATA_FAIL;
1071     }
1072     string destRelativePath;
1073     if (!GetAlbumRelativePathFromDB(targetUri, "", destRelativePath)) {
1074         MEDIA_ERR_LOG("Move target parent uri is not correct %{private}s", targetUri.c_str());
1075         return E_MODIFY_DATA_FAIL;
1076     }
1077     if (srcAsset->GetMediaType() == MediaType::MEDIA_TYPE_ALBUM) {
1078         if (!CheckRootDir(srcAsset, destRelativePath)) {
1079             MEDIA_ERR_LOG("Move file to another type alubm, denied");
1080             return E_DENIED_MOVE;
1081         }
1082         string bucketId = MediaLibraryDataManagerUtils::GetIdFromUri(targetUri);
1083         ret = HandleAlbumMove(srcAsset, destRelativePath, bucketId);
1084     } else {
1085         ret = HandleFileMove(srcAsset, destRelativePath);
1086     }
1087     if (ret == E_SUCCESS) {
1088         newFileUri = Uri(sourceUri);
1089     }
1090     return ret;
1091 }
1092 } // Media
1093 } // OHOS
1094