• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 
16 #define MLOG_TAG "CloudMediaAssetManager"
17 
18 #include "cloud_media_asset_manager.h"
19 
20 #include <iostream>
21 #include <chrono>
22 #include <mutex>
23 
24 #include "abs_rdb_predicates.h"
25 #include "cloud_media_asset_download_operation.h"
26 #include "cloud_media_asset_types.h"
27 #include "cloud_sync_utils.h"
28 #include "media_column.h"
29 #include "media_file_utils.h"
30 #include "media_log.h"
31 #include "medialibrary_album_fusion_utils.h"
32 #include "medialibrary_async_worker.h"
33 #include "medialibrary_command.h"
34 #include "medialibrary_db_const.h"
35 #include "medialibrary_errno.h"
36 #include "medialibrary_operation.h"
37 #include "medialibrary_rdb_utils.h"
38 #include "medialibrary_rdbstore.h"
39 #include "medialibrary_tracer.h"
40 #include "medialibrary_type_const.h"
41 #include "medialibrary_unistore_manager.h"
42 #include "medialibrary_notify.h"
43 #include "photo_album_column.h"
44 #include "rdb_store.h"
45 #include "result_set_utils.h"
46 #include "thumbnail_service.h"
47 
48 using namespace std;
49 using namespace OHOS::NativeRdb;
50 
51 namespace OHOS {
52 namespace Media {
53 using namespace FileManagement::CloudSync;
54 
55 static const std::string UNKNOWN_VALUE = "NA";
56 std::shared_ptr<CloudMediaAssetDownloadOperation> CloudMediaAssetManager::operation_ = nullptr;
57 std::mutex CloudMediaAssetManager::deleteMutex_;
58 std::mutex CloudMediaAssetManager::updateMutex_;
59 std::atomic<TaskDeleteState> CloudMediaAssetManager::doDeleteTask_ = TaskDeleteState::IDLE;
60 static const int32_t BATCH_LIMIT_COUNT = 200;
61 static const int32_t CYCLE_NUMBER = 1024 * 1024;
62 static const int32_t SLEEP_FOR_DELETE = 1000;
63 static const int32_t BATCH_NOTIFY_CLOUD_FILE = 2000;
64 static const std::string DELETE_DISPLAY_NAME = "cloud_media_asset_deleted";
65 static const int32_t ALBUM_FROM_CLOUD = 2;
66 static const int32_t ZERO_ASSET_OF_ALBUM = 0;
67 const std::string SQL_DELETE_EMPTY_CLOUD_ALBUMS = "DELETE FROM " + PhotoAlbumColumns::TABLE + " WHERE " +
68     "( " + PhotoAlbumColumns::ALBUM_IS_LOCAL + " = " + to_string(ALBUM_FROM_CLOUD) + " AND " +
69     PhotoAlbumColumns::ALBUM_ID + " NOT IN ( " +
70         "SELECT DISTINCT " + PhotoColumn::PHOTO_OWNER_ALBUM_ID +
71         " FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE " +
72         PhotoColumn::PHOTO_CLEAN_FLAG + " = " + to_string(static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN)) + " ))" +
73     " OR " + PhotoAlbumColumns::ALBUM_DIRTY + " = " + to_string(static_cast<int32_t>(DirtyType::TYPE_DELETED)) + ";";
74 
GetInstance()75 CloudMediaAssetManager& CloudMediaAssetManager::GetInstance()
76 {
77     static CloudMediaAssetManager instance;
78     return instance;
79 }
80 
CheckDownloadTypeOfTask(const CloudMediaDownloadType & type)81 int32_t CloudMediaAssetManager::CheckDownloadTypeOfTask(const CloudMediaDownloadType &type)
82 {
83     if (static_cast<int32_t>(type) < static_cast<int32_t>(CloudMediaDownloadType::DOWNLOAD_FORCE) ||
84         static_cast<int32_t>(type) > static_cast<int32_t>(CloudMediaDownloadType::DOWNLOAD_GENTLE)) {
85         MEDIA_ERR_LOG("CloudMediaDownloadType invalid input. downloadType: %{public}d", static_cast<int32_t>(type));
86         return E_ERR;
87     }
88     return E_OK;
89 }
90 
StartDownloadCloudAsset(const CloudMediaDownloadType & type)91 int32_t CloudMediaAssetManager::StartDownloadCloudAsset(const CloudMediaDownloadType &type)
92 {
93     if (operation_ == nullptr) {
94         CloudMediaAssetDownloadOperation taskOperator;
95         operation_ = taskOperator.GetInstance();
96     }
97     if (CheckDownloadTypeOfTask(type) != E_OK) {
98         return E_ERR;
99     }
100     operation_->ResetDownloadTryTime();
101     switch (operation_->GetTaskStatus()) {
102         case CloudMediaAssetTaskStatus::IDLE: {
103             return operation_->StartDownloadTask(static_cast<int32_t>(type));
104         }
105         case CloudMediaAssetTaskStatus::PAUSED: {
106             return operation_->ManualActiveRecoverTask(static_cast<int32_t>(type));
107         }
108         case CloudMediaAssetTaskStatus::DOWNLOADING: {
109             if (type == operation_->GetDownloadType()) {
110                 MEDIA_WARN_LOG("No status changed.");
111                 return E_OK;
112             }
113             if (type == CloudMediaDownloadType::DOWNLOAD_GENTLE) {
114                 return operation_->PauseDownloadTask(CloudMediaTaskPauseCause::BACKGROUND_TASK_UNAVAILABLE);
115             }
116             return E_ERR;
117         }
118         default: {
119             MEDIA_ERR_LOG("StartDownloadCloudAsset failed. now: taskStatus_, %{public}d; \
120                 downloadType_, %{public}d. input: type, %{public}d;",
121                 static_cast<int32_t>(operation_->GetTaskStatus()), static_cast<int32_t>(operation_->GetDownloadType()),
122                 static_cast<int32_t>(type));
123             return E_ERR;
124         }
125     }
126 }
127 
RecoverDownloadCloudAsset(const CloudMediaTaskRecoverCause & cause)128 int32_t CloudMediaAssetManager::RecoverDownloadCloudAsset(const CloudMediaTaskRecoverCause &cause)
129 {
130     bool cond = (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE);
131     CHECK_AND_RETURN_RET(!cond, E_ERR);
132 
133     operation_->ResetDownloadTryTime();
134     MEDIA_INFO_LOG("enter RecoverDownloadCloudAsset, RecoverCause: %{public}d", static_cast<int32_t>(cause));
135     CHECK_AND_RETURN_RET_LOG(operation_->GetTaskStatus() != CloudMediaAssetTaskStatus::DOWNLOADING, E_OK,
136         "The task status is download, no need to recover.");
137     int32_t ret = operation_->PassiveStatusRecoverTask(cause);
138     MEDIA_INFO_LOG("end to RecoverDownloadCloudAsset, status: %{public}s, ret: %{public}d.",
139         GetCloudMediaAssetTaskStatus().c_str(), ret);
140     return ret;
141 }
142 
CheckStorageAndRecoverDownloadTask()143 void CloudMediaAssetManager::CheckStorageAndRecoverDownloadTask()
144 {
145     if (operation_ == nullptr || operation_->GetTaskStatus() != CloudMediaAssetTaskStatus::PAUSED ||
146         operation_->GetTaskPauseCause() != CloudMediaTaskPauseCause::ROM_LIMIT) {
147         return;
148     }
149     MEDIA_INFO_LOG("begin to check storage and recover downloadTask.");
150     operation_->CheckStorageAndRecoverDownloadTask();
151 }
152 
PauseDownloadCloudAsset(const CloudMediaTaskPauseCause & pauseCause)153 int32_t CloudMediaAssetManager::PauseDownloadCloudAsset(const CloudMediaTaskPauseCause &pauseCause)
154 {
155     if (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE) {
156         MEDIA_INFO_LOG("no need to pause");
157         return E_OK;
158     }
159     int32_t ret = operation_->PauseDownloadTask(pauseCause);
160     MEDIA_INFO_LOG("end to PauseDownloadCloudAsset, status: %{public}s, ret: %{public}d.",
161         GetCloudMediaAssetTaskStatus().c_str(), ret);
162     return ret;
163 }
164 
CancelDownloadCloudAsset()165 int32_t CloudMediaAssetManager::CancelDownloadCloudAsset()
166 {
167     if (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE) {
168         MEDIA_INFO_LOG("no need to cancel");
169         return E_OK;
170     }
171     int32_t ret = operation_->CancelDownloadTask();
172     operation_.reset();
173     return ret;
174 }
175 
StartDeleteCloudMediaAssets()176 void CloudMediaAssetManager::StartDeleteCloudMediaAssets()
177 {
178     TaskDeleteState expect = TaskDeleteState::IDLE;
179     if (doDeleteTask_.compare_exchange_strong(expect, TaskDeleteState::BACKGROUND_DELETE)) {
180         MEDIA_INFO_LOG("start delete cloud media assets task.");
181         DeleteAllCloudMediaAssetsAsync();
182     }
183 }
184 
StopDeleteCloudMediaAssets()185 void CloudMediaAssetManager::StopDeleteCloudMediaAssets()
186 {
187     TaskDeleteState expect = TaskDeleteState::BACKGROUND_DELETE;
188     if (!doDeleteTask_.compare_exchange_strong(expect, TaskDeleteState::IDLE)) {
189         MEDIA_INFO_LOG("current status is not suitable for stop delete cloud media assets task.");
190     }
191 }
192 
DeleteBatchCloudFile(const std::vector<std::string> & fileIds)193 int32_t CloudMediaAssetManager::DeleteBatchCloudFile(const std::vector<std::string> &fileIds)
194 {
195     MediaLibraryTracer tracer;
196     tracer.Start("DeleteBatchCloudFile");
197     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
198     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "DeleteBatchCloudFile failed. rdbStore is null");
199     AbsRdbPredicates deletePredicates(PhotoColumn::PHOTOS_TABLE);
200     deletePredicates.In(MediaColumn::MEDIA_ID, fileIds);
201     int32_t deletedRows = E_HAS_DB_ERROR;
202     int32_t ret = rdbStore->Delete(deletedRows, deletePredicates);
203     if (ret != NativeRdb::E_OK || deletedRows <= 0) {
204         MEDIA_ERR_LOG("Delete operation failed. ret %{public}d. Deleted %{public}d", ret, deletedRows);
205         return E_ERR;
206     }
207     MEDIA_INFO_LOG("Delete operation successful. ret %{public}d. Deleted %{public}d", ret, deletedRows);
208     return E_OK;
209 }
210 
ReadyDataForDelete(std::vector<std::string> & fileIds,std::vector<std::string> & paths,std::vector<std::string> & dateTakens)211 int32_t CloudMediaAssetManager::ReadyDataForDelete(std::vector<std::string> &fileIds, std::vector<std::string> &paths,
212     std::vector<std::string> &dateTakens)
213 {
214     MediaLibraryTracer tracer;
215     tracer.Start("ReadyDataForDelete");
216     MEDIA_INFO_LOG("enter ReadyDataForDelete");
217     AbsRdbPredicates queryPredicates(PhotoColumn::PHOTOS_TABLE);
218     queryPredicates.EqualTo(MediaColumn::MEDIA_NAME, DELETE_DISPLAY_NAME);
219     queryPredicates.Limit(BATCH_LIMIT_COUNT);
220     vector<string> columns = {MediaColumn::MEDIA_ID, MediaColumn::MEDIA_FILE_PATH, MediaColumn::MEDIA_DATE_TAKEN};
221 
222     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
223     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "ReadyDataForDelete failed. rdbStorePtr is null");
224     auto resultSet = rdbStore->Query(queryPredicates, columns);
225     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_ERR, "ReadyDataForDelete failed. resultSet is null");
226     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
227         string path = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
228         if (path.empty()) {
229             MEDIA_WARN_LOG("Failed to get path!");
230             continue;
231         }
232         MEDIA_DEBUG_LOG("get path: %{public}s.", MediaFileUtils::DesensitizePath(path).c_str());
233         fileIds.push_back(GetStringVal(MediaColumn::MEDIA_ID, resultSet));
234         paths.push_back(path);
235         dateTakens.push_back(GetStringVal(MediaColumn::MEDIA_DATE_TAKEN, resultSet));
236     }
237     resultSet->Close();
238     return E_OK;
239 }
240 
GetEditDataDirPath(const string & path)241 static string GetEditDataDirPath(const string &path)
242 {
243     CHECK_AND_RETURN_RET(path.length() >= ROOT_MEDIA_DIR.length(), "");
244     return MEDIA_EDIT_DATA_DIR + path.substr(ROOT_MEDIA_DIR.length());
245 }
246 
DeleteEditdata(const std::string & path)247 static int32_t DeleteEditdata(const std::string &path)
248 {
249     string editDataDirPath = GetEditDataDirPath(path);
250     CHECK_AND_RETURN_RET_LOG(!editDataDirPath.empty(), E_ERR, "Cannot get editPath, path: %{private}s", path.c_str());
251     if (MediaFileUtils::IsFileExists(editDataDirPath)) {
252         CHECK_AND_RETURN_RET_LOG(MediaFileUtils::DeleteDir(editDataDirPath), E_ERR,
253             "Failed to delete edit data, path: %{private}s", editDataDirPath.c_str());
254     }
255     return E_OK;
256 }
257 
DeleteAllCloudMediaAssetsOperation(AsyncTaskData * data)258 void CloudMediaAssetManager::DeleteAllCloudMediaAssetsOperation(AsyncTaskData *data)
259 {
260     std::lock_guard<std::mutex> lock(deleteMutex_);
261     MEDIA_INFO_LOG("enter DeleteAllCloudMediaAssetsOperation");
262     MediaLibraryTracer tracer;
263     tracer.Start("DeleteAllCloudMediaAssetsOperation");
264 
265     std::vector<std::string> fileIds;
266     std::vector<std::string> paths;
267     std::vector<std::string> dateTakens;
268     int32_t cycleNumber = 0;
269     while (doDeleteTask_.load() > TaskDeleteState::IDLE && cycleNumber <= CYCLE_NUMBER) {
270         int32_t ret = ReadyDataForDelete(fileIds, paths, dateTakens);
271         if (ret != E_OK || fileIds.empty()) {
272             MEDIA_WARN_LOG("ReadyDataForDelete failed or fileIds is empty, ret: %{public}d, size: %{public}d",
273                 ret, static_cast<int32_t>(fileIds.size()));
274             break;
275         }
276         bool deleteFlag = true;
277         for (size_t i = 0; i < fileIds.size(); i++) {
278             if (DeleteEditdata(paths[i]) != E_OK || !ThumbnailService::GetInstance()->HasInvalidateThumbnail(
279                 fileIds[i], PhotoColumn::PHOTOS_TABLE, paths[i], dateTakens[i])) {
280                 MEDIA_ERR_LOG("Delete error, path: %{public}s.", MediaFileUtils::DesensitizePath(paths[i]).c_str());
281                 deleteFlag = false;
282                 break;
283             }
284             MEDIA_INFO_LOG("Detele cloud file, path: %{public}s.", MediaFileUtils::DesensitizePath(paths[i]).c_str());
285         }
286         if (!deleteFlag) {
287             MEDIA_ERR_LOG("DeleteEditdata or InvalidateThumbnail failed!");
288             break;
289         }
290         ret = DeleteBatchCloudFile(fileIds);
291         if (ret != E_OK) {
292             MEDIA_ERR_LOG("DeleteBatchCloudFile failed!");
293             break;
294         }
295         fileIds.clear();
296         paths.clear();
297         dateTakens.clear();
298         cycleNumber++;
299         this_thread::sleep_for(chrono::milliseconds(SLEEP_FOR_DELETE));
300     }
301     doDeleteTask_.store(TaskDeleteState::IDLE);
302 }
303 
DeleteAllCloudMediaAssetsAsync()304 void CloudMediaAssetManager::DeleteAllCloudMediaAssetsAsync()
305 {
306     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
307     CHECK_AND_RETURN_LOG(asyncWorker != nullptr, "Can not get asyncWorker");
308 
309     shared_ptr<MediaLibraryAsyncTask> deleteAsyncTask =
310         make_shared<MediaLibraryAsyncTask>(DeleteAllCloudMediaAssetsOperation, nullptr);
311     CHECK_AND_RETURN_LOG(deleteAsyncTask != nullptr, "Can not get deleteAsyncTask");
312 
313     asyncWorker->AddTask(deleteAsyncTask, true);
314 }
315 
HasDataForUpdate(std::vector<std::string> & updateFileIds)316 static bool HasDataForUpdate(std::vector<std::string> &updateFileIds)
317 {
318     if (!updateFileIds.empty()) {
319         MEDIA_WARN_LOG("updateFileIds is not null");
320         updateFileIds.clear();
321     }
322     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
323     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, false, "HasDataForUpdate failed. rdbStore is null.");
324     AbsRdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
325     predicates.NotEqualTo(MediaColumn::MEDIA_NAME, DELETE_DISPLAY_NAME);
326     predicates.EqualTo(PhotoColumn::PHOTO_POSITION, to_string(static_cast<int32_t>(PhotoPositionType::CLOUD)));
327     predicates.Limit(BATCH_LIMIT_COUNT);
328     std::vector<std::string> columns = { MediaColumn::MEDIA_ID };
329     auto resultSet = rdbStore->Query(predicates, columns);
330     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, false, "HasDataForUpdate failed. resultSet is null.");
331 
332     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
333         std::string fileId = GetStringVal(MediaColumn::MEDIA_ID, resultSet);
334         updateFileIds.emplace_back(fileId);
335     }
336     resultSet->Close();
337     CHECK_AND_RETURN_RET_LOG(updateFileIds.size() > 0, false, "the size of updateFileIds 0.");
338     return true;
339 }
340 
UpdateCloudAssets(const std::vector<std::string> & updateFileIds)341 static int32_t UpdateCloudAssets(const std::vector<std::string> &updateFileIds)
342 {
343     CHECK_AND_RETURN_RET_LOG(!updateFileIds.empty(), E_ERR, "updateFileIds is null.");
344     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
345     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "UpdateCloudAssets failed. rdbStore is null.");
346     AbsRdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
347     predicates.In(MediaColumn::MEDIA_ID, updateFileIds);
348 
349     ValuesBucket values;
350     values.PutString(MediaColumn::MEDIA_NAME, DELETE_DISPLAY_NAME);
351     values.PutInt(PhotoColumn::PHOTO_CLEAN_FLAG, static_cast<int32_t>(CleanType::TYPE_NEED_CLEAN));
352     values.PutInt(PhotoColumn::PHOTO_DIRTY, -1);
353     values.PutLong(PhotoColumn::PHOTO_CLOUD_VERSION, 0);
354     values.PutNull(PhotoColumn::PHOTO_CLOUD_ID);
355 
356     int32_t changedRows = -1;
357     int32_t ret = rdbStore->Update(changedRows, values, predicates);
358     CHECK_AND_RETURN_RET_LOG((ret == E_OK && changedRows > 0), E_ERR,
359         "Failed to UpdateCloudAssets, ret: %{public}d, updateRows: %{public}d", ret, changedRows);
360     return E_OK;
361 }
362 
NotifyUpdateAssetsChange(const std::vector<std::string> & notifyFileIds)363 static void NotifyUpdateAssetsChange(const std::vector<std::string> &notifyFileIds)
364 {
365     CHECK_AND_RETURN_LOG(!notifyFileIds.empty(), "notifyFileIds is null.");
366     auto watch = MediaLibraryNotify::GetInstance();
367     CHECK_AND_RETURN_LOG(watch != nullptr, "watch is null.");
368     for (size_t i = 0; i < notifyFileIds.size(); i++) {
369         watch->Notify(MediaFileUtils::GetUriByExtrConditions(PhotoColumn::PHOTO_URI_PREFIX, notifyFileIds[i]),
370             NotifyType::NOTIFY_REMOVE);
371     }
372 }
373 
UpdateCloudMeidaAssets()374 int32_t CloudMediaAssetManager::UpdateCloudMeidaAssets()
375 {
376     MediaLibraryTracer tracer;
377     tracer.Start("UpdateCloudMeidaAssets");
378     std::lock_guard<std::mutex> lock(updateMutex_);
379 
380     int32_t cycleNumber = 0;
381     std::vector<std::string> notifyFileIds = {};
382     std::vector<std::string> updateFileIds = {};
383     while (HasDataForUpdate(updateFileIds) && cycleNumber <= CYCLE_NUMBER) {
384         int32_t ret = UpdateCloudAssets(updateFileIds);
385         if (ret != E_OK) {
386             MEDIA_ERR_LOG("UpdateCloudAssets failed, ret: %{public}d", ret);
387             break;
388         }
389 
390         notifyFileIds.insert(notifyFileIds.end(), updateFileIds.begin(), updateFileIds.end());
391         updateFileIds.clear();
392         if (notifyFileIds.size() == BATCH_NOTIFY_CLOUD_FILE) {
393             NotifyUpdateAssetsChange(notifyFileIds);
394             notifyFileIds.clear();
395         }
396 
397         cycleNumber++;
398         MEDIA_INFO_LOG("cycleNumber is %{public}d", cycleNumber);
399     }
400     if (notifyFileIds.size() > 0) {
401         NotifyUpdateAssetsChange(notifyFileIds);
402         notifyFileIds.clear();
403     }
404     if (cycleNumber > 0) {
405         MEDIA_INFO_LOG("begin to refresh all albums.");
406         auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
407         CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "UpdateCloudMeidaAssets failed. rdbStore is null.");
408         MediaLibraryRdbUtils::UpdateAllAlbums(rdbStore);
409         return E_OK;
410     }
411     return E_ERR;
412 }
413 
DeleteEmptyCloudAlbums()414 int32_t CloudMediaAssetManager::DeleteEmptyCloudAlbums()
415 {
416     MEDIA_INFO_LOG("start DeleteEmptyCloudAlbums.");
417     MediaLibraryTracer tracer;
418     tracer.Start("DeleteEmptyCloudAlbums");
419     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
420     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "DeleteEmptyCloudAlbums failed. rdbStore is null");
421 
422     int32_t ret = rdbStore->ExecuteSql(SQL_DELETE_EMPTY_CLOUD_ALBUMS);
423     CHECK_AND_RETURN_RET_LOG(ret == E_OK, E_ERR, "Failed to delete. ret %{public}d.", ret);
424     MEDIA_INFO_LOG("end DeleteEmptyCloudAlbums. ret %{public}d.", ret);
425     return E_OK;
426 }
427 
ForceRetainDownloadCloudMedia()428 int32_t CloudMediaAssetManager::ForceRetainDownloadCloudMedia()
429 {
430     MEDIA_INFO_LOG("enter ForceRetainDownloadCloudMedia.");
431     MediaLibraryTracer tracer;
432     tracer.Start("ForceRetainDownloadCloudMedia");
433     int32_t ret = UpdateCloudMeidaAssets();
434     CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "UpdateCloudMeidaAssets failed. ret %{public}d.", ret);
435     ret = DeleteEmptyCloudAlbums();
436     CHECK_AND_PRINT_LOG(ret == E_OK, "DeleteEmptyCloudAlbums failed. ret %{public}d.", ret);
437 
438     auto watch = MediaLibraryNotify::GetInstance();
439     if (watch != nullptr) {
440         MEDIA_INFO_LOG("begin to notify album update.");
441         watch->Notify(PhotoAlbumColumns::ALBUM_URI_PREFIX, NotifyType::NOTIFY_UPDATE);
442     }
443 
444     MEDIA_INFO_LOG("begin to CleanGalleryDentryFile");
445     CloudSyncManager::GetInstance().CleanGalleryDentryFile();
446     MEDIA_INFO_LOG("end to CleanGalleryDentryFile");
447 
448     TaskDeleteState expect = TaskDeleteState::IDLE;
449     if (doDeleteTask_.compare_exchange_strong(expect, TaskDeleteState::ACTIVE_DELETE)) {
450         MEDIA_INFO_LOG("start delete cloud media assets task.");
451         DeleteAllCloudMediaAssetsAsync();
452     } else {
453         doDeleteTask_.store(TaskDeleteState::ACTIVE_DELETE);
454     }
455     MEDIA_INFO_LOG("end to ForceRetainDownloadCloudMedia.");
456     return ret;
457 }
458 
GetCloudMediaAssetTaskStatus()459 std::string CloudMediaAssetManager::GetCloudMediaAssetTaskStatus()
460 {
461     if (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE) {
462         MEDIA_ERR_LOG("cloud media download task not exit.");
463         return to_string(static_cast<int32_t>(CloudMediaAssetTaskStatus::IDLE)) + ",0,0,0,0,0";
464     }
465     return to_string(static_cast<int32_t>(operation_->GetTaskStatus())) + "," + operation_->GetTaskInfo() + "," +
466         to_string(static_cast<int32_t>(operation_->GetTaskPauseCause()));
467 }
468 
HandleCloudMediaAssetUpdateOperations(MediaLibraryCommand & cmd)469 int32_t CloudMediaAssetManager::HandleCloudMediaAssetUpdateOperations(MediaLibraryCommand &cmd)
470 {
471     switch (cmd.GetOprnType()) {
472         case OperationType::CLOUD_MEDIA_ASSET_TASK_START_FORCE: {
473             return StartDownloadCloudAsset(CloudMediaDownloadType::DOWNLOAD_FORCE);
474         }
475         case OperationType::CLOUD_MEDIA_ASSET_TASK_START_GENTLE: {
476             return StartDownloadCloudAsset(CloudMediaDownloadType::DOWNLOAD_GENTLE);
477         }
478         case OperationType::CLOUD_MEDIA_ASSET_TASK_PAUSE: {
479             return PauseDownloadCloudAsset(CloudMediaTaskPauseCause::USER_PAUSED);
480         }
481         case OperationType::CLOUD_MEDIA_ASSET_TASK_CANCEL: {
482             return CancelDownloadCloudAsset();
483         }
484         case OperationType::CLOUD_MEDIA_ASSET_TASK_RETAIN_FORCE: {
485             return ForceRetainDownloadCloudMedia();
486         }
487         default: {
488             MEDIA_ERR_LOG("OprnType is not exit.");
489             return E_ERR;
490         }
491     }
492 }
493 
HandleCloudMediaAssetGetTypeOperations(MediaLibraryCommand & cmd)494 string CloudMediaAssetManager::HandleCloudMediaAssetGetTypeOperations(MediaLibraryCommand &cmd)
495 {
496     switch (cmd.GetOprnType()) {
497         case OperationType::CLOUD_MEDIA_ASSET_TASK_STATUS_QUERY: {
498             return GetCloudMediaAssetTaskStatus();
499         }
500         default: {
501             MEDIA_ERR_LOG("OprnType is not exit.");
502             return "";
503         }
504     }
505 }
506 
SetIsThumbnailUpdate()507 bool CloudMediaAssetManager::SetIsThumbnailUpdate()
508 {
509     if (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE) {
510         return false;
511     }
512     if (!operation_->isThumbnailUpdate_) {
513         MEDIA_INFO_LOG("Success set isThumbnailUpdate.");
514         operation_->isThumbnailUpdate_ = true;
515     }
516     MEDIA_INFO_LOG("Update count and size of download cloud media asset.");
517     if (operation_->InitDownloadTaskInfo() != E_OK) {
518         MEDIA_INFO_LOG("remainCount of download cloud media assets is 0.");
519         operation_->CancelDownloadTask();
520     }
521     return true;
522 }
523 
GetTaskStatus()524 int32_t CloudMediaAssetManager::GetTaskStatus()
525 {
526     CHECK_AND_RETURN_RET(operation_ != nullptr, static_cast<int32_t>(CloudMediaAssetTaskStatus::IDLE));
527     return static_cast<int32_t>(operation_->GetTaskStatus());
528 }
529 
GetDownloadType()530 int32_t CloudMediaAssetManager::GetDownloadType()
531 {
532     if (operation_ == nullptr) {
533         MEDIA_INFO_LOG("cloud media download task not exit.");
534         return E_ERR;
535     }
536     return static_cast<int32_t>(operation_->GetDownloadType());
537 }
538 
SetBgDownloadPermission(const bool & flag)539 bool CloudMediaAssetManager::SetBgDownloadPermission(const bool &flag)
540 {
541     if (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE) {
542         return false;
543     }
544     MEDIA_INFO_LOG("Success set isBgDownloadPermission, flag: %{public}d.", static_cast<int32_t>(flag));
545     operation_->isBgDownloadPermission_ = flag;
546     return true;
547 }
548 } // namespace Media
549 } // namespace OHOS