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