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