1 /*
2 * Copyright (C) 2021 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 "SmartAlbum"
16
17 #include "medialibrary_smartalbum_map_operations.h"
18
19 #include "datashare_predicates.h"
20 #include "datashare_result_set.h"
21 #include "fetch_result.h"
22 #include "medialibrary_common_utils.h"
23 #include "medialibrary_dir_operations.h"
24 #include "medialibrary_errno.h"
25 #include "medialibrary_file_operations.h"
26 #include "medialibrary_object_utils.h"
27 #include "media_file_utils.h"
28 #include "media_log.h"
29 #include "rdb_utils.h"
30 #include "result_set_utils.h"
31
32 using namespace std;
33 using namespace OHOS::NativeRdb;
34 using namespace OHOS::DataShare;
35 using namespace OHOS::RdbDataShareAdapter;
36
37 namespace OHOS {
38 namespace Media {
39 static const std::string HASH_COLLISION_SUFFIX = "(1)";
40 static const std::string ASSET_RECYCLE_SUFFIX = "-copy";
41 static const std::string DIR_RECYCLE_SUFFIX = "_recycle";
42 const std::string RECYCLE_DIR = ".recycle/";
43 static const int64_t ONEDAY_TO_MS = 60*60*24*1000;
44 static const int32_t DEFAULT_RECYCLE_DAYS = 30;
45
InsertAlbumAssetsInfoUtil(SmartAlbumMapQueryData & smartAlbumMapQueryData)46 int32_t MediaLibrarySmartAlbumMapOperations::InsertAlbumAssetsInfoUtil(
47 SmartAlbumMapQueryData &smartAlbumMapQueryData)
48 {
49 ValuesBucket values = const_cast<ValuesBucket &>(smartAlbumMapQueryData.values);
50 int32_t insertResult = const_cast<MediaLibrarySmartAlbumMapDb &>(smartAlbumMapQueryData.smartAlbumMapDbOprn)
51 .InsertSmartAlbumMapInfo(values, smartAlbumMapQueryData.rdbStore);
52 return insertResult;
53 }
54
InsertTrashAssetsInfoUtil(const int32_t & fileAssetId,SmartAlbumMapQueryData & smartAlbumMapQueryData)55 int32_t MediaLibrarySmartAlbumMapOperations::InsertTrashAssetsInfoUtil(const int32_t &fileAssetId,
56 SmartAlbumMapQueryData &smartAlbumMapQueryData)
57 {
58 int32_t errorCode = E_FAIL;
59 string uri = MEDIALIBRARY_DATA_ABILITY_PREFIX +
60 MEDIALIBRARY_DATA_URI_IDENTIFIER + MEDIALIBRARY_TYPE_FILE_URI + "/" + to_string(fileAssetId);
61 shared_ptr<FileAsset> fileAsset = MediaLibraryObjectUtils::GetFileAssetFromDb(uri);
62 if (fileAsset == nullptr) {
63 MEDIA_ERR_LOG("fileAsset is nullptr");
64 return errorCode;
65 }
66 if (fileAsset->GetDateTrashed() == 0) {
67 if (fileAsset->GetMediaType() != MEDIA_TYPE_ALBUM) {
68 errorCode = TrashFileAssetsInfoUtil(fileAssetId, smartAlbumMapQueryData);
69 } else {
70 errorCode = TrashDirAssetsInfoUtil(fileAssetId, smartAlbumMapQueryData);
71 }
72 } else {
73 errorCode = E_IS_RECYCLED;
74 }
75 return errorCode;
76 }
77
78
UpdateFavoriteAssetsInfoUtil(const int32_t & fileAssetId,const bool & isFavorite,SmartAlbumMapQueryData & smartAlbumMapQueryData)79 int32_t MediaLibrarySmartAlbumMapOperations::UpdateFavoriteAssetsInfoUtil(const int32_t &fileAssetId,
80 const bool &isFavorite, SmartAlbumMapQueryData &smartAlbumMapQueryData)
81 {
82 int32_t errorCode = E_FAIL;
83 ValuesBucket fileValues;
84 fileValues.PutBool(MEDIA_DATA_DB_IS_FAV, isFavorite);
85 errorCode = (smartAlbumMapQueryData.smartAlbumMapDbOprn).UpdateFavoriteInfo(fileAssetId,
86 fileValues, smartAlbumMapQueryData.rdbStore);
87 return errorCode;
88 }
89
TrashFileAssetsInfoUtil(const int32_t & assetId,SmartAlbumMapQueryData & smartAlbumMapQueryData)90 int32_t MediaLibrarySmartAlbumMapOperations::TrashFileAssetsInfoUtil(const int32_t &assetId,
91 SmartAlbumMapQueryData &smartAlbumMapQueryData)
92 {
93 string trashDirPath, oldPath, recyclePath;
94 int32_t errorCode = GetAssetRecycle(assetId,
95 oldPath, trashDirPath, smartAlbumMapQueryData.rdbStore, smartAlbumMapQueryData.dirQuerySetMap);
96 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to GetAssetRecycle");
97 if (!MediaFileUtils::IsDirectory(trashDirPath)) {
98 if (!MediaFileUtils::CreateDirectory(trashDirPath)) {
99 return E_FAIL;
100 }
101 }
102 errorCode = MakeRecycleDisplayName(
103 assetId, recyclePath, trashDirPath, smartAlbumMapQueryData.rdbStore);
104 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to make recycle display name");
105 FileAsset fileAsset;
106 errorCode = fileAsset.ModifyAsset(oldPath, recyclePath);
107 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS,
108 errorCode, "TrashFileAssetsInfoUtil Failed to ModifyAsset");
109 int64_t trashDate = MediaFileUtils::UTCTimeSeconds();
110 errorCode = (smartAlbumMapQueryData.smartAlbumMapDbOprn).UpdateAssetTrashInfo(assetId,
111 trashDate, smartAlbumMapQueryData.rdbStore, recyclePath, oldPath);
112 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to UpdateAssetTrashInfo");
113 return errorCode;
114 }
115
TrashDirAssetsInfoUtil(const int32_t & assetId,SmartAlbumMapQueryData & smartAlbumMapQueryData)116 int32_t MediaLibrarySmartAlbumMapOperations::TrashDirAssetsInfoUtil(const int32_t &assetId,
117 SmartAlbumMapQueryData &smartAlbumMapQueryData)
118 {
119 string trashDirPath, oldPath, recyclePath;
120 int32_t errorCode = GetAssetRecycle(assetId,
121 oldPath, trashDirPath, smartAlbumMapQueryData.rdbStore, smartAlbumMapQueryData.dirQuerySetMap);
122 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to GetAssetRecycle");
123 if (!MediaFileUtils::IsDirectory(trashDirPath)) {
124 if (!MediaFileUtils::CreateDirectory(trashDirPath)) {
125 return E_FAIL;
126 }
127 }
128 errorCode = MakeRecycleDisplayName(
129 assetId, recyclePath, trashDirPath, smartAlbumMapQueryData.rdbStore);
130 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to MakeRecycleDisplayName");
131 if (!MediaFileUtils::RenameDir(oldPath, recyclePath)) {
132 return E_MODIFY_DATA_FAIL;
133 };
134 int64_t trashDate = MediaFileUtils::UTCTimeSeconds();
135 errorCode = TrashChildAssetsInfoUtil(assetId, trashDate, smartAlbumMapQueryData);
136 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to TrashChildAssetsInfoUtil");
137 (smartAlbumMapQueryData.smartAlbumMapDbOprn).UpdateDirTrashInfo(assetId,
138 trashDate, smartAlbumMapQueryData.rdbStore, recyclePath, oldPath);
139 return errorCode;
140 }
141
TrashChildAssetsInfoUtil(const int32_t & parentId,const int64_t & trashDate,SmartAlbumMapQueryData & smartAlbumMapQueryData)142 int32_t MediaLibrarySmartAlbumMapOperations::TrashChildAssetsInfoUtil(const int32_t &parentId,
143 const int64_t &trashDate, SmartAlbumMapQueryData &smartAlbumMapQueryData)
144 {
145 vector<string> columns;
146 AbsRdbPredicates dirAbsPred(MEDIALIBRARY_TABLE);
147 dirAbsPred.EqualTo(MEDIA_DATA_DB_PARENT_ID, to_string(parentId))->And()->EqualTo(MEDIA_DATA_DB_IS_TRASH,
148 to_string(NOT_ISTRASH));
149 shared_ptr<AbsSharedResultSet> queryResultSet = smartAlbumMapQueryData.rdbStore->Query(
150 dirAbsPred, columns);
151 auto count = 0;
152 auto ret = queryResultSet->GetRowCount(count);
153 if (ret != NativeRdb::E_OK) {
154 MEDIA_ERR_LOG("get rdbstore failed");
155 return E_HAS_DB_ERROR;
156 }
157 MEDIA_INFO_LOG("count = %{public}d", (int)count);
158 if (count != 0) {
159 while (queryResultSet->GoToNextRow() == NativeRdb::E_OK) {
160 int32_t columnIndexId, idVal;
161 queryResultSet->GetColumnIndex(MEDIA_DATA_DB_ID, columnIndexId);
162 queryResultSet->GetInt(columnIndexId, idVal);
163 (smartAlbumMapQueryData.smartAlbumMapDbOprn).UpdateChildTrashInfo(idVal,
164 smartAlbumMapQueryData.rdbStore, trashDate);
165 TrashChildAssetsInfoUtil(idVal, trashDate, smartAlbumMapQueryData);
166 }
167 }
168 return E_SUCCESS;
169 }
170
RemoveAlbumAssetsInfoUtil(const int32_t & albumId,SmartAlbumMapQueryData & smartAlbumMapQueryData)171 int32_t MediaLibrarySmartAlbumMapOperations::RemoveAlbumAssetsInfoUtil(const int32_t &albumId,
172 SmartAlbumMapQueryData &smartAlbumMapQueryData)
173 {
174 ValuesBucket values = const_cast<ValuesBucket &>(smartAlbumMapQueryData.values);
175 ValueObject valueObject;
176 int32_t assetId = 0;
177 if (values.GetObject(SMARTALBUMMAP_DB_CHILD_ASSET_ID, valueObject)) {
178 valueObject.GetInt(assetId);
179 }
180 int32_t deleteResult = const_cast<MediaLibrarySmartAlbumMapDb &>(smartAlbumMapQueryData.smartAlbumMapDbOprn)
181 .DeleteSmartAlbumMapInfo(albumId, assetId, smartAlbumMapQueryData.rdbStore);
182 return deleteResult;
183 }
184
HandleAddAssetOperations(const int32_t & albumId,const int32_t & childFileAssetId,SmartAlbumMapQueryData & smartAlbumMapQueryData)185 int32_t MediaLibrarySmartAlbumMapOperations::HandleAddAssetOperations(const int32_t &albumId,
186 const int32_t &childFileAssetId,
187 SmartAlbumMapQueryData &smartAlbumMapQueryData)
188 {
189 int32_t errorCode = E_FAIL;
190 if (albumId == TRASH_ALBUM_ID_VALUES) {
191 errorCode = InsertTrashAssetsInfoUtil(childFileAssetId, smartAlbumMapQueryData);
192 } else if (albumId == FAVOURITE_ALBUM_ID_VALUES) {
193 errorCode = UpdateFavoriteAssetsInfoUtil(childFileAssetId, true, smartAlbumMapQueryData);
194 }
195 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to HandleAddAssetOperations");
196 errorCode = InsertAlbumAssetsInfoUtil(smartAlbumMapQueryData);
197 return errorCode;
198 }
199
MakeSuffixPathName(string & assetPath)200 string MediaLibrarySmartAlbumMapOperations::MakeSuffixPathName(string &assetPath)
201 {
202 string outSuffixPath;
203 size_t displayNameIndex = assetPath.find(".");
204 if (displayNameIndex != string::npos) {
205 string extension, noExtensionPath;
206 extension = assetPath.substr(displayNameIndex);
207 noExtensionPath = assetPath.substr(0, displayNameIndex);
208 MEDIA_INFO_LOG("extension = %{public}s", extension.c_str());
209 MEDIA_INFO_LOG("noExtensionPath = %{public}s", noExtensionPath.c_str());
210 outSuffixPath = noExtensionPath + ASSET_RECYCLE_SUFFIX + extension;
211 } else {
212 outSuffixPath = assetPath + ASSET_RECYCLE_SUFFIX;
213 }
214 MEDIA_INFO_LOG("outSuffixPath = %{public}s", outSuffixPath.c_str());
215 return outSuffixPath;
216 }
217
RecycleFile(const shared_ptr<FileAsset> & fileAsset,const string & recyclePath,string & sameNamePath,SmartAlbumMapQueryData & smartAlbumMapQueryData)218 int32_t MediaLibrarySmartAlbumMapOperations::RecycleFile(const shared_ptr<FileAsset> &fileAsset,
219 const string &recyclePath,
220 string &sameNamePath,
221 SmartAlbumMapQueryData &smartAlbumMapQueryData)
222 {
223 int32_t errorCode = E_FAIL;
224 NativeAlbumAsset nativeAlbumAsset;
225 string assetPath = fileAsset->GetRecyclePath();
226 if (!MediaLibraryObjectUtils::IsAssetExistInDb(fileAsset->GetParent())) {
227 MEDIA_INFO_LOG("RecycleFile GetRelativePath() = %{private}s", fileAsset->GetRelativePath().c_str());
228 int32_t albumId = MediaLibraryObjectUtils::CreateDirWithPath(ROOT_MEDIA_DIR + fileAsset->GetRelativePath());
229 nativeAlbumAsset.SetAlbumId(albumId);
230 nativeAlbumAsset = GetAlbumAsset(to_string(albumId), smartAlbumMapQueryData.rdbStore);
231 errorCode = const_cast<MediaLibrarySmartAlbumMapDb &>(smartAlbumMapQueryData.smartAlbumMapDbOprn)
232 .UpdateParentDirRecycleInfo(fileAsset->GetId(), nativeAlbumAsset.GetAlbumId(),
233 nativeAlbumAsset.GetAlbumName(), smartAlbumMapQueryData.rdbStore);
234 }
235
236 bool hasSameName = false;
237 while (MediaLibraryObjectUtils::IsFileExistInDb(assetPath)) {
238 hasSameName = true;
239 assetPath = MakeSuffixPathName(assetPath);
240 }
241 errorCode = fileAsset->ModifyAsset(recyclePath, assetPath);
242 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to ModifyAsset");
243 if (hasSameName) {
244 string assetDisplayName = MediaLibraryDataManagerUtils::GetDisPlayNameFromPath(assetPath);
245 smartAlbumMapQueryData.smartAlbumMapDbOprn.UpdateSameNameInfo(fileAsset->GetId(),
246 assetDisplayName, assetPath, smartAlbumMapQueryData.rdbStore);
247 sameNamePath = assetPath;
248 }
249
250 MEDIA_INFO_LOG("RecycleFile assetPath = %{private}s", assetPath.c_str());
251 MEDIA_INFO_LOG("RecycleFile recyclePath = %{private}s", recyclePath.c_str());
252 return errorCode;
253 }
254
GetNewPath(const string & path,const string & srcRelPath,const string & newRelPath)255 string GetNewPath(const string &path, const string &srcRelPath, const string &newRelPath)
256 {
257 string newPath = newRelPath;
258 if (path.find(ROOT_MEDIA_DIR) != string::npos) {
259 newPath = ROOT_MEDIA_DIR + newPath;
260 }
261 newPath += path.substr(path.find(srcRelPath) + srcRelPath.length());
262 return newPath;
263 }
264
RecycleChildSameNameInfoUtil(const int32_t & parentId,const string & srcRelPath,const string & newRelPath,bool isFirstLevel,shared_ptr<RdbStore> rdbStore)265 void RecycleChildSameNameInfoUtil(const int32_t &parentId, const string &srcRelPath, const string &newRelPath,
266 bool isFirstLevel, shared_ptr<RdbStore> rdbStore)
267 {
268 vector<string> columns;
269 AbsRdbPredicates queryPredicates(MEDIALIBRARY_TABLE);
270 queryPredicates.EqualTo(MEDIA_DATA_DB_PARENT_ID, to_string(parentId));
271 auto result = rdbStore->Query(queryPredicates, columns);
272 CHECK_AND_RETURN_LOG(result != nullptr, "Failed to obtain value from database");
273
274 while (result->GoToNextRow() == NativeRdb::E_OK) {
275 ValuesBucket values;
276 string relativePath =
277 get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_RELATIVE_PATH, result, TYPE_STRING));
278 values.PutString(MEDIA_DATA_DB_RELATIVE_PATH, GetNewPath(relativePath, srcRelPath, newRelPath));
279
280 int32_t mediaType =
281 get<int32_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_MEDIA_TYPE, result, TYPE_INT32));
282 if (isFirstLevel && (mediaType != MEDIA_TYPE_ALBUM)) {
283 string newParentName = newRelPath;
284 // delete the final '/' in relative_path
285 newParentName.pop_back();
286 newParentName = MediaLibraryDataManagerUtils::GetDisPlayNameFromPath(newParentName);
287 values.PutString(MEDIA_DATA_DB_BUCKET_NAME, newParentName);
288 }
289
290 // Update recycle_path for ASSET_ISTRASH and DIR_ISTRASH, update data for ASSET_ISTRASH.
291 int32_t isTrash = get<int32_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_IS_TRASH, result, TYPE_INT32));
292 if (isTrash == CHILD_ISTRASH) {
293 string path = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_FILE_PATH, result, TYPE_STRING));
294 values.PutString(MEDIA_DATA_DB_FILE_PATH, GetNewPath(path, srcRelPath, newRelPath));
295 } else {
296 string recyclePath =
297 get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_RECYCLE_PATH, result, TYPE_STRING));
298 values.PutString(MEDIA_DATA_DB_RECYCLE_PATH, GetNewPath(recyclePath, srcRelPath, newRelPath));
299 }
300
301 int32_t fileId = get<int32_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_ID, result, TYPE_INT32));
302 AbsRdbPredicates updatePredicates(MEDIALIBRARY_TABLE);
303 updatePredicates.EqualTo(MEDIA_DATA_DB_ID, to_string(fileId));
304 int32_t changedRows = -1;
305 string testpath = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_FILE_PATH, result, TYPE_STRING));
306 auto ret = rdbStore->Update(changedRows, values, updatePredicates);
307 if ((ret != NativeRdb::E_OK) || (changedRows <= 0)) {
308 MEDIA_ERR_LOG("Update DB failed. Ret: %{public}d. Update fileId: %{private}d", ret, fileId);
309 }
310
311 if (mediaType == MEDIA_TYPE_ALBUM) {
312 RecycleChildSameNameInfoUtil(fileId, srcRelPath, newRelPath, false, rdbStore);
313 }
314 }
315 }
316
IsAlbumExistInDb(const string & path,const shared_ptr<RdbStore> & rdbStore)317 bool IsAlbumExistInDb(const string &path, const shared_ptr<RdbStore> &rdbStore)
318 {
319 string realPath = path;
320 if (realPath.back() == '/') {
321 realPath.pop_back();
322 }
323 MEDIA_DEBUG_LOG("isAlbumExistInDb path = %{private}s", realPath.c_str());
324 AbsRdbPredicates absPredicates(MEDIALIBRARY_TABLE);
325 absPredicates.EqualTo(MEDIA_DATA_DB_FILE_PATH, realPath);
326 absPredicates.And()->EqualTo(MEDIA_DATA_DB_IS_TRASH, "0");
327 vector<string> columns;
328 unique_ptr<NativeRdb::ResultSet> queryResultSet = rdbStore->Query(absPredicates, columns);
329 if (queryResultSet == nullptr || queryResultSet->GoToNextRow() != NativeRdb::E_OK) {
330 return false;
331 }
332 int32_t columnIndexId;
333 int32_t idVal;
334 queryResultSet->GetColumnIndex(MEDIA_DATA_DB_ID, columnIndexId);
335 queryResultSet->GetInt(columnIndexId, idVal);
336 MEDIA_DEBUG_LOG("id = %{private}d", idVal);
337 return true;
338 }
339
RecycleDir(const shared_ptr<FileAsset> & fileAsset,shared_ptr<RdbStore> rdbStore)340 int32_t RecycleDir(const shared_ptr<FileAsset> &fileAsset, shared_ptr<RdbStore> rdbStore)
341 {
342 ValuesBucket values;
343 if (!MediaLibraryObjectUtils::IsAssetExistInDb(fileAsset->GetParent())) {
344 int32_t parentId = MediaLibraryObjectUtils::CreateDirWithPath(ROOT_MEDIA_DIR + fileAsset->GetRelativePath());
345 values.PutInt(MEDIA_DATA_DB_PARENT_ID, parentId);
346 values.PutInt(MEDIA_DATA_DB_BUCKET_ID, parentId);
347 }
348
349 bool hasSameName = false;
350 string assetPath = fileAsset->GetRecyclePath();
351 while (IsAlbumExistInDb(assetPath, rdbStore)) {
352 hasSameName = true;
353 assetPath = assetPath + DIR_RECYCLE_SUFFIX;
354 }
355
356 if (!MediaFileUtils::RenameDir(fileAsset->GetPath(), assetPath)) {
357 return E_RDIR_FAIL;
358 }
359
360 if (hasSameName) {
361 fileAsset->SetRecyclePath(assetPath);
362 // update parent info
363 string newName = MediaLibraryDataManagerUtils::GetDisPlayNameFromPath(assetPath);
364 values.PutString(MEDIA_DATA_DB_NAME, newName);
365 values.PutString(MEDIA_DATA_DB_TITLE, newName);
366 values.PutString(MEDIA_DATA_DB_BUCKET_NAME, newName);
367 values.PutString(MEDIA_DATA_DB_RECYCLE_PATH, assetPath);
368
369 // update child info
370 string srcRelPath = fileAsset->GetRelativePath() + fileAsset->GetDisplayName() + "/";
371 string newRelPath = fileAsset->GetRelativePath() + newName + "/";
372 RecycleChildSameNameInfoUtil(fileAsset->GetId(), srcRelPath, newRelPath, true, rdbStore);
373 }
374
375 if (!values.IsEmpty()) {
376 AbsRdbPredicates updatePredicates(MEDIALIBRARY_TABLE);
377 updatePredicates.EqualTo(MEDIA_DATA_DB_ID, to_string(fileAsset->GetId()));
378 int32_t changedRows = -1;
379 return rdbStore->Update(changedRows, values, updatePredicates);
380 }
381
382 return E_SUCCESS;
383 }
384
RecycleFileAssetsInfoUtil(const shared_ptr<FileAsset> & fileAsset,SmartAlbumMapQueryData & smartAlbumMapQueryData)385 int32_t MediaLibrarySmartAlbumMapOperations::RecycleFileAssetsInfoUtil(const shared_ptr<FileAsset> &fileAsset,
386 SmartAlbumMapQueryData &smartAlbumMapQueryData)
387 {
388 string recyclePath;
389 int32_t errorCode = E_FAIL;
390 if (!IsRecycleAssetExist(fileAsset->GetId(),
391 recyclePath, smartAlbumMapQueryData.rdbStore)) {
392 return E_RECYCLE_FILE_IS_NULL;
393 }
394 MEDIA_INFO_LOG("recyclePath = %{private}s", recyclePath.c_str());
395 string sameNamePath;
396 errorCode = RecycleFile(fileAsset, recyclePath, sameNamePath, smartAlbumMapQueryData);
397 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to RecycleFile");
398 string fileRealPath;
399 if (sameNamePath.empty()) {
400 fileRealPath = fileAsset->GetRecyclePath();
401 } else {
402 fileRealPath = sameNamePath;
403 }
404 errorCode = (smartAlbumMapQueryData.smartAlbumMapDbOprn).UpdateRecycleInfo(fileAsset->GetId(),
405 smartAlbumMapQueryData.rdbStore, fileRealPath);
406 return errorCode;
407 }
408
RecycleChildAssetsInfoUtil(const int32_t & parentId,const int64_t & recycleDate,SmartAlbumMapQueryData & smartAlbumMapQueryData)409 int32_t MediaLibrarySmartAlbumMapOperations::RecycleChildAssetsInfoUtil(const int32_t &parentId,
410 const int64_t &recycleDate, SmartAlbumMapQueryData &smartAlbumMapQueryData)
411 {
412 vector<string> columns;
413 AbsRdbPredicates dirAbsPred(MEDIALIBRARY_TABLE);
414 dirAbsPred.EqualTo(MEDIA_DATA_DB_PARENT_ID, to_string(parentId));
415 dirAbsPred.EqualTo(MEDIA_DATA_DB_IS_TRASH, to_string(CHILD_ISTRASH));
416 shared_ptr<AbsSharedResultSet> queryResultSet = smartAlbumMapQueryData.rdbStore->Query(
417 dirAbsPred, columns);
418 auto count = 0;
419 auto ret = queryResultSet->GetRowCount(count);
420 if (ret != NativeRdb::E_OK) {
421 MEDIA_ERR_LOG("get rdbstore failed");
422 return E_HAS_DB_ERROR;
423 }
424 MEDIA_INFO_LOG("count = %{public}d", (int)count);
425 if (count != 0) {
426 while (queryResultSet->GoToNextRow() == NativeRdb::E_OK) {
427 int32_t columnIndexId, idVal;
428 queryResultSet->GetColumnIndex(MEDIA_DATA_DB_ID, columnIndexId);
429 queryResultSet->GetInt(columnIndexId, idVal);
430 (smartAlbumMapQueryData.smartAlbumMapDbOprn).UpdateChildRecycleInfo(idVal,
431 smartAlbumMapQueryData.rdbStore, recycleDate);
432 RecycleChildAssetsInfoUtil(idVal, recycleDate, smartAlbumMapQueryData);
433 }
434 }
435 return E_SUCCESS;
436 }
437
RecycleDirAssetsInfoUtil(const shared_ptr<FileAsset> & fileAsset,SmartAlbumMapQueryData & smartAlbumMapQueryData)438 int32_t MediaLibrarySmartAlbumMapOperations::RecycleDirAssetsInfoUtil(const shared_ptr<FileAsset> &fileAsset,
439 SmartAlbumMapQueryData &smartAlbumMapQueryData)
440 {
441 if (!MediaFileUtils::IsDirectory(fileAsset->GetPath())) {
442 MEDIA_ERR_LOG("recycle dir is not exists");
443 return E_RECYCLE_FILE_IS_NULL;
444 }
445 auto errorCode = RecycleDir(fileAsset, smartAlbumMapQueryData.rdbStore);
446 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to RecycleDir");
447 int64_t recycleDate = MediaFileUtils::UTCTimeSeconds();
448 errorCode = RecycleChildAssetsInfoUtil(fileAsset->GetId(), recycleDate, smartAlbumMapQueryData);
449 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to RecycleChildAssetsInfoUtil");
450 string dirRealPath = fileAsset->GetRecyclePath();
451 errorCode = (smartAlbumMapQueryData.smartAlbumMapDbOprn).UpdateRecycleInfo(fileAsset->GetId(),
452 smartAlbumMapQueryData.rdbStore, dirRealPath);
453 return errorCode;
454 }
455
RemoveTrashAssetsInfoUtil(const int32_t & fileAssetId,SmartAlbumMapQueryData & smartAlbumMapQueryData)456 int32_t MediaLibrarySmartAlbumMapOperations::RemoveTrashAssetsInfoUtil(const int32_t &fileAssetId,
457 SmartAlbumMapQueryData &smartAlbumMapQueryData)
458 {
459 int32_t errorCode = E_FAIL;
460 string uri = MEDIALIBRARY_DATA_ABILITY_PREFIX +
461 MEDIALIBRARY_DATA_URI_IDENTIFIER + MEDIALIBRARY_TYPE_FILE_URI + "/" + to_string(fileAssetId);
462 shared_ptr<FileAsset> fileAsset = MediaLibraryObjectUtils::GetFileAssetFromDb(uri);
463 if (fileAsset == nullptr) {
464 MEDIA_ERR_LOG("fileAsset is nullptr");
465 return errorCode;
466 }
467 if (fileAsset->GetMediaType() != MEDIA_TYPE_ALBUM) {
468 errorCode = RecycleFileAssetsInfoUtil(fileAsset, smartAlbumMapQueryData);
469 } else {
470 errorCode = RecycleDirAssetsInfoUtil(fileAsset, smartAlbumMapQueryData);
471 }
472 return errorCode;
473 }
474
HandleRemoveAssetOperations(const int32_t & albumId,const int32_t & childFileAssetId,SmartAlbumMapQueryData & smartAlbumMapQueryData)475 int32_t MediaLibrarySmartAlbumMapOperations::HandleRemoveAssetOperations(const int32_t &albumId,
476 const int32_t &childFileAssetId,
477 SmartAlbumMapQueryData &smartAlbumMapQueryData)
478 {
479 if (albumId == TRASH_ALBUM_ID_VALUES) {
480 RemoveTrashAssetsInfoUtil(childFileAssetId, smartAlbumMapQueryData);
481 } else if (albumId == FAVOURITE_ALBUM_ID_VALUES) {
482 UpdateFavoriteAssetsInfoUtil(childFileAssetId, false, smartAlbumMapQueryData);
483 }
484 return RemoveAlbumAssetsInfoUtil(albumId, smartAlbumMapQueryData);
485 }
486
DeleteDir(const string & recyclePath)487 int32_t MediaLibrarySmartAlbumMapOperations::DeleteDir(const string &recyclePath)
488 {
489 int32_t errorCode = E_FAIL;
490 if (MediaFileUtils::DeleteDir(recyclePath)) {
491 errorCode = E_SUCCESS;
492 }
493 return errorCode;
494 }
495
DeleteFile(const unique_ptr<FileAsset> & fileAsset,const string & recyclePath)496 int32_t MediaLibrarySmartAlbumMapOperations::DeleteFile(const unique_ptr<FileAsset> &fileAsset,
497 const string &recyclePath)
498 {
499 int32_t errorCode = fileAsset->DeleteAsset(recyclePath);
500 MEDIA_INFO_LOG("DeleteFile errorCode = %{public}d", errorCode);
501 if (errorCode >= 0) {
502 errorCode = E_SUCCESS;
503 }
504 return errorCode;
505 }
506
DeleteFileAssetsInfoUtil(const unique_ptr<FileAsset> & fileAsset,SmartAlbumMapQueryData & smartAlbumMapQueryData)507 int32_t MediaLibrarySmartAlbumMapOperations::DeleteFileAssetsInfoUtil(const unique_ptr<FileAsset> &fileAsset,
508 SmartAlbumMapQueryData &smartAlbumMapQueryData)
509 {
510 string recyclePath;
511 int32_t errorCode = E_FAIL;
512 if (!IsRecycleAssetExist(fileAsset->GetId(),
513 recyclePath, smartAlbumMapQueryData.rdbStore)) {
514 return E_RECYCLE_FILE_IS_NULL;
515 }
516 MEDIA_INFO_LOG("DeleteFileAssetsInfoUtil recyclePath = %{private}s", recyclePath.c_str());
517 errorCode = DeleteFile(fileAsset, recyclePath);
518 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to DeleteFile");
519 errorCode = (smartAlbumMapQueryData.smartAlbumMapDbOprn).DeleteTrashInfo(fileAsset->GetId(),
520 smartAlbumMapQueryData.rdbStore);
521 return errorCode;
522 }
523
DeleteDirAssetsInfoUtil(const unique_ptr<FileAsset> & fileAsset,SmartAlbumMapQueryData & smartAlbumMapQueryData)524 int32_t MediaLibrarySmartAlbumMapOperations::DeleteDirAssetsInfoUtil(const unique_ptr<FileAsset> &fileAsset,
525 SmartAlbumMapQueryData &smartAlbumMapQueryData)
526 {
527 string recyclePath;
528 int32_t errorCode = E_FAIL;
529 if (fileAsset->GetIsTrash() == DIR_ISTRASH) {
530 if (!IsRecycleAssetExist(fileAsset->GetId(),
531 recyclePath, smartAlbumMapQueryData.rdbStore)) {
532 return E_RECYCLE_FILE_IS_NULL;
533 }
534 MEDIA_INFO_LOG("DeleteDirAssetsInfoUtil recyclePath = %{private}s", recyclePath.c_str());
535 errorCode = DeleteDir(recyclePath);
536 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, errorCode, "Failed to DeleteDir");
537 }
538 errorCode = (smartAlbumMapQueryData.smartAlbumMapDbOprn).DeleteTrashInfo(fileAsset->GetId(),
539 smartAlbumMapQueryData.rdbStore);
540 return errorCode;
541 }
542
HandleAgeingOperations(SmartAlbumMapQueryData & smartAlbumMapQueryData)543 int32_t MediaLibrarySmartAlbumMapOperations::HandleAgeingOperations(SmartAlbumMapQueryData &smartAlbumMapQueryData)
544 {
545 shared_ptr<AbsSharedResultSet> resultSet = QueryAgeingTrashFiles(smartAlbumMapQueryData.rdbStore);
546 shared_ptr<ResultSetBridge> rsBridge = RdbUtils::ToResultSetBridge(resultSet);
547 shared_ptr<DataShareResultSet> dataShareRs = make_shared<DataShareResultSet>(rsBridge);
548 shared_ptr<FetchResult<FileAsset>> fetchFileResult = make_shared<FetchResult<FileAsset>>(dataShareRs);
549 int32_t errorCode = E_FAIL;
550 unique_ptr<FileAsset> fileAsset = fetchFileResult->GetFirstObject();
551 while (fileAsset != nullptr) {
552 MEDIA_INFO_LOG("fileAsset->GetIsTrash() = %{public}d", fileAsset->GetIsTrash());
553 if (fileAsset->GetIsTrash() == ASSET_ISTRASH) {
554 errorCode = DeleteFileAssetsInfoUtil(fileAsset, smartAlbumMapQueryData);
555 } else {
556 errorCode = DeleteDirAssetsInfoUtil(fileAsset, smartAlbumMapQueryData);
557 }
558 fileAsset = fetchFileResult->GetNextObject();
559 }
560 return errorCode;
561 }
562
HandleSmartAlbumMapOperations(const string & oprn,const ValuesBucket & valuesBucket,const shared_ptr<RdbStore> & rdbStore,const unordered_map<string,DirAsset> & dirQuerySetMap)563 int32_t MediaLibrarySmartAlbumMapOperations::HandleSmartAlbumMapOperations(const string &oprn,
564 const ValuesBucket &valuesBucket,
565 const shared_ptr<RdbStore> &rdbStore,
566 const unordered_map<string, DirAsset> &dirQuerySetMap)
567 {
568 MediaLibrarySmartAlbumMapDb smartAlbumMapDbOprn;
569 SmartAlbumMapQueryData smartAlbumMapQueryData;
570 smartAlbumMapQueryData.smartAlbumMapDbOprn = smartAlbumMapDbOprn;
571 smartAlbumMapQueryData.values = valuesBucket;
572 smartAlbumMapQueryData.rdbStore = rdbStore;
573 smartAlbumMapQueryData.dirQuerySetMap = dirQuerySetMap;
574 int32_t albumId = 0;
575 int32_t childAssetId = 0;
576 ValueObject valueObject;
577 ValuesBucket values = const_cast<ValuesBucket &>(valuesBucket);
578 if (values.GetObject(SMARTALBUMMAP_DB_ALBUM_ID, valueObject)) {
579 valueObject.GetInt(albumId);
580 }
581 if (values.GetObject(SMARTALBUMMAP_DB_CHILD_ASSET_ID, valueObject)) {
582 valueObject.GetInt(childAssetId);
583 }
584 int32_t errorCode = E_FAIL;
585 if (oprn == MEDIA_SMARTALBUMMAPOPRN_ADDSMARTALBUM) {
586 errorCode = HandleAddAssetOperations(albumId, childAssetId, smartAlbumMapQueryData);
587 } else if (oprn == MEDIA_SMARTALBUMMAPOPRN_REMOVESMARTALBUM) {
588 errorCode = HandleRemoveAssetOperations(albumId, childAssetId, smartAlbumMapQueryData);
589 } else if (oprn == MEDIA_SMARTALBUMMAPOPRN_AGEINGSMARTALBUM) {
590 errorCode = HandleAgeingOperations(smartAlbumMapQueryData);
591 }
592 return errorCode;
593 }
594
GetAlbumAsset(const std::string & id,const std::shared_ptr<NativeRdb::RdbStore> & rdbStore)595 NativeAlbumAsset MediaLibrarySmartAlbumMapOperations::GetAlbumAsset(const std::string &id,
596 const std::shared_ptr<NativeRdb::RdbStore> &rdbStore)
597 {
598 NativeAlbumAsset albumAsset;
599 vector<string> columns;
600 AbsRdbPredicates absPredicates(MEDIALIBRARY_TABLE);
601 absPredicates.EqualTo(MEDIA_DATA_DB_ID, id);
602 unique_ptr<NativeRdb::ResultSet> queryResultSet = rdbStore->Query(absPredicates, columns);
603 if (queryResultSet->GoToNextRow() != NativeRdb::E_OK) {
604 return albumAsset;
605 }
606
607 int32_t columnIndexId;
608 int32_t idVal;
609 int32_t columnIndexName;
610 string nameVal;
611 queryResultSet->GetColumnIndex(MEDIA_DATA_DB_ID, columnIndexId);
612 queryResultSet->GetInt(columnIndexId, idVal);
613 queryResultSet->GetColumnIndex(MEDIA_DATA_DB_TITLE, columnIndexName);
614 queryResultSet->GetString(columnIndexName, nameVal);
615 albumAsset.SetAlbumId(idVal);
616 albumAsset.SetAlbumName(nameVal);
617 MEDIA_DEBUG_LOG("idVal = %{private}d, nameVal = %{private}s", idVal, nameVal.c_str());
618 return albumAsset;
619 }
620
GetAssetRecycle(const int32_t & assetId,string & outOldPath,string & outTrashDirPath,const shared_ptr<RdbStore> & rdbStore,const unordered_map<string,DirAsset> & dirQuerySetMap)621 int32_t MediaLibrarySmartAlbumMapOperations::GetAssetRecycle(const int32_t &assetId,
622 string &outOldPath, string &outTrashDirPath, const shared_ptr<RdbStore> &rdbStore,
623 const unordered_map<string, DirAsset> &dirQuerySetMap)
624 {
625 string path = MediaLibraryObjectUtils::GetPathByIdFromDb(to_string(assetId));
626 outOldPath = path;
627 int32_t errorCode = E_FAIL;
628 string rootPath;
629 for (pair<string, DirAsset> dirPair : dirQuerySetMap) {
630 DirAsset dirAsset = dirPair.second;
631 rootPath = ROOT_MEDIA_DIR + dirAsset.GetDirectory();
632 if (path.find(rootPath) != string::npos) {
633 MEDIA_DEBUG_LOG("GetAssetRecycle = %{public}s", rootPath.c_str());
634 errorCode = E_SUCCESS;
635 break;
636 }
637 }
638 outTrashDirPath = rootPath + RECYCLE_DIR;
639 return errorCode;
640 }
641
IsRecycleAssetExist(const int32_t & assetId,string & outRecyclePath,const shared_ptr<RdbStore> & rdbStore)642 bool MediaLibrarySmartAlbumMapOperations::IsRecycleAssetExist(const int32_t &assetId,
643 string &outRecyclePath, const shared_ptr<RdbStore> &rdbStore)
644 {
645 string uri = MEDIALIBRARY_DATA_ABILITY_PREFIX +
646 MEDIALIBRARY_DATA_URI_IDENTIFIER + MEDIALIBRARY_TYPE_FILE_URI + "/" + to_string(assetId);
647 shared_ptr<FileAsset> fileAsset = MediaLibraryObjectUtils::GetFileAssetFromDb(uri);
648 if (fileAsset == nullptr) {
649 MEDIA_ERR_LOG("fileAsset is nullptr");
650 return false;
651 }
652 outRecyclePath = fileAsset->GetPath();
653 MEDIA_DEBUG_LOG("assetRescyclePath = %{private}s", outRecyclePath.c_str());
654 if (fileAsset->GetMediaType() == MEDIA_TYPE_ALBUM) {
655 return MediaFileUtils::IsDirectory(outRecyclePath);
656 }
657 return MediaFileUtils::IsFileExists(outRecyclePath);
658 }
659
MakeRecycleDisplayName(const int32_t & assetId,string & outRecyclePath,const string & trashDirPath,const shared_ptr<RdbStore> & rdbStore)660 int32_t MediaLibrarySmartAlbumMapOperations::MakeRecycleDisplayName(const int32_t &assetId,
661 string &outRecyclePath, const string &trashDirPath, const shared_ptr<RdbStore> &rdbStore)
662 {
663 string uri = MEDIALIBRARY_DATA_ABILITY_PREFIX +
664 MEDIALIBRARY_DATA_URI_IDENTIFIER + MEDIALIBRARY_TYPE_FILE_URI + "/" + to_string(assetId);
665 shared_ptr<FileAsset> fileAsset = MediaLibraryObjectUtils::GetFileAssetFromDb(uri);
666 if (fileAsset == nullptr) {
667 MEDIA_ERR_LOG("fileAsset not found");
668 return E_FAIL;
669 }
670 string extension = "";
671 string hashDisplayName = "";
672 string name = to_string(fileAsset->GetId()) +
673 fileAsset->GetRelativePath() + fileAsset->GetDisplayName();
674 int32_t errorCode = MediaLibraryCommonUtils::GenKeySHA256(name, hashDisplayName);
675 if (errorCode < 0) {
676 MEDIA_ERR_LOG("Failed to make hash display name, err: %{public}d", errorCode);
677 return errorCode;
678 }
679 MEDIA_DEBUG_LOG("hashDisplayName = %{public}s", hashDisplayName.c_str());
680 outRecyclePath = trashDirPath + hashDisplayName;
681 if (fileAsset->GetMediaType() != MEDIA_TYPE_ALBUM) {
682 size_t displayNameIndex = fileAsset->GetDisplayName().find(".");
683 if (displayNameIndex != string::npos) {
684 extension = fileAsset->GetDisplayName().substr(displayNameIndex);
685 }
686 outRecyclePath = outRecyclePath + extension;
687 MEDIA_DEBUG_LOG("asset outRecyclePath = %{public}s", outRecyclePath.c_str());
688 }
689 while (MediaLibraryObjectUtils::IsColumnValueExist(outRecyclePath, MEDIA_DATA_DB_RECYCLE_PATH)) {
690 name = name + HASH_COLLISION_SUFFIX;
691 MEDIA_DEBUG_LOG("name = %{public}s", name.c_str());
692 errorCode = MediaLibraryCommonUtils::GenKeySHA256(name, hashDisplayName);
693 if (errorCode < 0) {
694 MEDIA_ERR_LOG("Failed to make hash display name, err: %{public}d", errorCode);
695 return errorCode;
696 }
697 if (!extension.empty()) {
698 outRecyclePath = trashDirPath + hashDisplayName + extension;
699 }
700 outRecyclePath = trashDirPath + hashDisplayName;
701 MEDIA_DEBUG_LOG("outRecyclePath = %{public}s", outRecyclePath.c_str());
702 }
703 return errorCode;
704 }
705
QueryAgeingTrashFiles(const shared_ptr<RdbStore> & rdbStore)706 shared_ptr<AbsSharedResultSet> MediaLibrarySmartAlbumMapOperations::QueryAgeingTrashFiles(
707 const shared_ptr<RdbStore> &rdbStore)
708 {
709 vector<string> selectionArgs = {SMARTALBUM_DB_EXPIRED_TIME};
710 string strQueryCondition = SMARTALBUM_DB_ID + " = " + to_string(TRASH_ALBUM_ID_VALUES);
711 AbsRdbPredicates absPredicates(SMARTALBUM_TABLE);
712 absPredicates.SetWhereClause(strQueryCondition);
713 absPredicates.SetWhereArgs(selectionArgs);
714 vector<string> columns;
715 int32_t columnIndex;
716 int32_t recycleDays = DEFAULT_RECYCLE_DAYS;
717 shared_ptr<AbsSharedResultSet> resultSet = rdbStore->Query(absPredicates, columns);
718 if (resultSet->GoToFirstRow() == NativeRdb::E_OK) {
719 resultSet->GetColumnIndex(SMARTALBUM_DB_EXPIRED_TIME, columnIndex);
720 resultSet->GetInt(columnIndex, recycleDays);
721 }
722 int64_t dateAgeing = MediaFileUtils::UTCTimeSeconds();
723 string strAgeingQueryCondition = to_string(dateAgeing) + " - " +
724 MEDIA_DATA_DB_DATE_TRASHED + " > " + to_string(recycleDays * ONEDAY_TO_MS);
725
726 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
727 cmd.GetAbsRdbPredicates()->SetWhereClause(strAgeingQueryCondition);
728 return MediaLibraryObjectUtils::QueryWithCondition(cmd, {});
729 }
730 } // namespace Media
731 } // namespace OHOS
732