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