• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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