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> ¬ifyFileIds)
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