1 /*
2 * Copyright (C) 2024-2025 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 #include <cinttypes>
24
25 #include "abs_rdb_predicates.h"
26 #include "album_accurate_refresh.h"
27 #include "asset_accurate_refresh.h"
28 #include "cloud_media_asset_download_operation.h"
29 #include "cloud_media_asset_types.h"
30 #include "cloud_sync_notify_handler.h"
31 #include "cloud_sync_helper.h"
32 #include "cloud_sync_utils.h"
33 #include "media_column.h"
34 #include "media_file_utils.h"
35 #include "media_log.h"
36 #include "medialibrary_album_fusion_utils.h"
37 #include "medialibrary_async_worker.h"
38 #include "medialibrary_command.h"
39 #include "medialibrary_db_const.h"
40 #include "medialibrary_errno.h"
41 #ifdef META_RECOVERY_SUPPORT
42 #include "medialibrary_meta_recovery.h"
43 #endif
44 #include "medialibrary_operation.h"
45 #include "medialibrary_rdb_utils.h"
46 #include "medialibrary_rdbstore.h"
47 #include "medialibrary_tracer.h"
48 #include "medialibrary_type_const.h"
49 #include "medialibrary_unistore_manager.h"
50 #include "medialibrary_notify.h"
51 #include "parameters.h"
52 #include "photo_album_column.h"
53 #include "rdb_store.h"
54 #include "result_set_utils.h"
55 #include "thumbnail_service.h"
56 #include "cloud_media_asset_uri.h"
57 #include "dfx_const.h"
58
59 using namespace std;
60 using namespace OHOS::NativeRdb;
61
62 namespace OHOS {
63 namespace Media {
64 using namespace FileManagement::CloudSync;
65
66 static const std::string UNKNOWN_VALUE = "NA";
67 // batch limit count of update cloud data
68 constexpr int32_t BATCH_UPDATE_LIMIT_COUNT = 500;
69 // batch limit count of delete cloud data
70 constexpr int32_t BATCH_DELETE_LIMIT_COUNT = 300;
71 static const int32_t CYCLE_NUMBER = 1024 * 1024;
72 static const int32_t SLEEP_FOR_DELETE = 600;
73 static const int32_t BATCH_NOTIFY_CLOUD_FILE = 2000;
74 static const std::string DELETE_DISPLAY_NAME = "cloud_media_asset_deleted";
75 static const int32_t ALBUM_FROM_CLOUD = 2;
76 static const int32_t ZERO_ASSET_OF_ALBUM = 0;
77 const std::string START_QUERY_ZERO = "0";
78
79 const std::string SQL_CONDITION_EMPTY_CLOUD_ALBUMS = "FROM " + PhotoAlbumColumns::TABLE + " WHERE " +
80 "( " + PhotoAlbumColumns::ALBUM_IS_LOCAL + " = " + to_string(ALBUM_FROM_CLOUD) + " AND " +
81 PhotoAlbumColumns::ALBUM_ID + " NOT IN ( " +
82 "SELECT DISTINCT " + PhotoColumn::PHOTO_OWNER_ALBUM_ID +
83 " FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE " +
84 PhotoColumn::PHOTO_CLEAN_FLAG + " = " + to_string(static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN)) + " ))" +
85 " OR " + PhotoAlbumColumns::ALBUM_DIRTY + " = " + to_string(static_cast<int32_t>(DirtyType::TYPE_DELETED));
86 const std::string SQL_QUERY_EMPTY_CLOUD_ALBUMS = "SELECT * " + SQL_CONDITION_EMPTY_CLOUD_ALBUMS;
87 const std::string SQL_DELETE_EMPTY_CLOUD_ALBUMS = "DELETE " + SQL_CONDITION_EMPTY_CLOUD_ALBUMS;
88
89 // 持久化清除状态, 防止重启后清除错误服务端的图片数据: 时间戳|0
90 static const std::string CLOUD_RETIAN_STATUS_KEY = "persist.multimedia.medialibrary.retain.cloud.status";
91 static const std::string HDC_RETIAN_STATUS_KEY = "persist.multimedia.medialibrary.retain.hdc.status";
92
93 static const std::string MEIDA_RESTORE_FLAG = "multimedia.medialibrary.restoreFlag";
94 static const std::string MEIDA_BACKUP_FLAG = "multimedia.medialibrary.backupFlag";
95
96 // 同步服务模块使用: 时间戳|0,时间戳表征任务正在清理中,0表示无清理任务
97 static const std::string CLOUDSYNC_SWITCH_STATUS_KEY = "persist.kernel.cloudsync.switch_status"; // ms
98
99 // 超时时间 ForceRetainDownloadCloudMedia
100 static constexpr int64_t SOUTH_DEVICE_CLEAN_DATA_TIMEOUT_MILLISECOND = 12 * 60 * 60 * 1000;
101 static constexpr int64_t FORCE_RETAIN_CLOUD_MEDIA_WAIT_RESTORE_TIMEOUT_SECOND = 6 * 60 * 60;
102 static constexpr int64_t FORCE_RETAIN_CLOUD_MEDIA_WAIT_BACKUP_TIMEOUT_SECOND = 2 * 60 * 60;
103 static constexpr int64_t FORCE_RETAIN_CLOUD_MEDIA_WAIT_BACKUP_OR_RESTORE_SLEEP_TIME_MILLISECOND = 15000;
104
105 static std::mutex g_syncStatusMutex;
SetSystemParameter(const std::string & key,int64_t value)106 static bool SetSystemParameter(const std::string& key, int64_t value)
107 {
108 std::string valueStr = std::to_string(value);
109 return system::SetParameter(key, valueStr);
110 }
111
SetSouthDeviceSyncSwitchStatus(CloudSyncStatus status)112 static void SetSouthDeviceSyncSwitchStatus(CloudSyncStatus status)
113 {
114 std::lock_guard<std::mutex> lock(g_syncStatusMutex);
115 bool retFlag = false;
116 if (status == CloudSyncStatus::CLOUD_CLEANING) {
117 auto timeStamp = MediaFileUtils::UTCTimeMilliSeconds();
118 retFlag = SetSystemParameter(CLOUDSYNC_SWITCH_STATUS_KEY, timeStamp);
119 } else {
120 retFlag = SetSystemParameter(CLOUDSYNC_SWITCH_STATUS_KEY, 0);
121 }
122 MEDIA_INFO_LOG("set CloudSyncStatus: %{public}d, result bool: %{public}d", static_cast<int32_t>(status), retFlag);
123 }
124
SetSouthDeviceCleanStatus(CloudMediaRetainType retainType,CloudSyncStatus statusKey)125 static void SetSouthDeviceCleanStatus(CloudMediaRetainType retainType, CloudSyncStatus statusKey)
126 {
127 auto retainTypeToInt = static_cast<int32_t>(retainType);
128 // 防止一直无法恢复, 使用时间戳代替开关
129 int64_t timeStamp = 0;
130 if (statusKey == CloudSyncStatus::CLOUD_CLEANING) {
131 timeStamp = MediaFileUtils::UTCTimeMilliSeconds();
132 }
133
134 std::lock_guard<std::mutex> lock(g_syncStatusMutex);
135 bool retFlag = false;
136 if (retainType == CloudMediaRetainType::RETAIN_FORCE) {
137 retFlag = SetSystemParameter(CLOUD_RETIAN_STATUS_KEY, timeStamp);
138 } else if (retainType == CloudMediaRetainType::HDC_RETAIN_FORCE) {
139 retFlag = SetSystemParameter(HDC_RETIAN_STATUS_KEY, timeStamp);
140 } else {
141 MEDIA_ERR_LOG("invalid retainType: %{public}d, status: %{public}d", retainTypeToInt, statusKey);
142 return;
143 }
144 MEDIA_INFO_LOG("set retainType: %{public}d, status: %{public}d, result bool: %{public}d",
145 retainTypeToInt, statusKey, retFlag);
146 }
147
IsSouthDeviceSyncCleaning(CloudMediaRetainType retainType,bool checkTimeout=true)148 static bool IsSouthDeviceSyncCleaning(CloudMediaRetainType retainType, bool checkTimeout = true)
149 {
150 std::lock_guard<std::mutex> lock(g_syncStatusMutex);
151 int64_t timeStamp = 0;
152 if (retainType == CloudMediaRetainType::RETAIN_FORCE) {
153 timeStamp = system::GetIntParameter(CLOUD_RETIAN_STATUS_KEY, timeStamp);
154 } else if (retainType == CloudMediaRetainType::HDC_RETAIN_FORCE) {
155 timeStamp = system::GetIntParameter(HDC_RETIAN_STATUS_KEY, timeStamp);
156 } else {
157 MEDIA_ERR_LOG("get invalid retainType: %{public}d", static_cast<int32_t>(retainType));
158 }
159 if (timeStamp == 0) {
160 return false;
161 }
162
163 if (!checkTimeout) {
164 return true;
165 }
166
167 auto nowTime = MediaFileUtils::UTCTimeSeconds();
168 return ((nowTime - timeStamp) < SOUTH_DEVICE_CLEAN_DATA_TIMEOUT_MILLISECOND);
169 }
170
WaitIfBackUpingOrRestoring(const std::string & key,int64_t waitTimeout,const std::string & info="unknown")171 static void WaitIfBackUpingOrRestoring(const std::string& key, int64_t waitTimeout, const std::string& info = "unknown")
172 {
173 constexpr int64_t defaultValueTime = 0;
174 int64_t startTimeClone = system::GetIntParameter(key, defaultValueTime);
175 int64_t startTimeWait = MediaFileUtils::UTCTimeSeconds();
176 MEDIA_INFO_LOG("Wait for %{public}s to exit. startTimeWait: %{public}" PRId64
177 ", startTimeClone: %{public}" PRId64, info.c_str(), startTimeWait, startTimeClone);
178 while (startTimeClone > 0) {
179 auto nowTime = MediaFileUtils::UTCTimeSeconds();
180 if ((nowTime - startTimeWait) > waitTimeout) {
181 MEDIA_WARN_LOG("[%{public}s] timeout: now: %{public}" PRId64", startTimeWait: %{public}" PRId64
182 ", startTimeClone: %{public}" PRId64, info.c_str(), nowTime, startTimeWait, startTimeClone);
183 break;
184 }
185 MEDIA_DEBUG_LOG("[%{public}s] waiting: now: %{public}" PRId64", startTimeWait: %{public}" PRId64
186 ", startTimeClone: %{public}" PRId64, info.c_str(), nowTime, startTimeWait, startTimeClone);
187 std::this_thread::sleep_for(chrono::milliseconds(
188 FORCE_RETAIN_CLOUD_MEDIA_WAIT_BACKUP_OR_RESTORE_SLEEP_TIME_MILLISECOND));
189 startTimeClone = system::GetIntParameter(key, defaultValueTime);
190 }
191
192 MEDIA_INFO_LOG("the %{public}s has exited, currtime: %{public}" PRId64,
193 info.c_str(), MediaFileUtils::UTCTimeSeconds());
194 }
195
WaitIfBackUpingOrRestoring()196 static void WaitIfBackUpingOrRestoring()
197 {
198 WaitIfBackUpingOrRestoring(MEIDA_RESTORE_FLAG,
199 FORCE_RETAIN_CLOUD_MEDIA_WAIT_RESTORE_TIMEOUT_SECOND, "db restore");
200
201 WaitIfBackUpingOrRestoring(MEIDA_BACKUP_FLAG,
202 FORCE_RETAIN_CLOUD_MEDIA_WAIT_BACKUP_TIMEOUT_SECOND, "db backup");
203 }
204
205 enum class SouthDeviceType : int32_t {
206 SOUTH_DEVICE_NULL = 0,
207 SOUTH_DEVICE_CLOUD = 1,
208 SOUTH_DEVICE_HDC = 2
209 };
210
GetInstance()211 CloudMediaAssetManager& CloudMediaAssetManager::GetInstance()
212 {
213 static CloudMediaAssetManager instance;
214 return instance;
215 }
216
CheckDownloadTypeOfTask(const CloudMediaDownloadType & type)217 int32_t CloudMediaAssetManager::CheckDownloadTypeOfTask(const CloudMediaDownloadType &type)
218 {
219 if (static_cast<int32_t>(type) < static_cast<int32_t>(CloudMediaDownloadType::DOWNLOAD_FORCE) ||
220 static_cast<int32_t>(type) > static_cast<int32_t>(CloudMediaDownloadType::DOWNLOAD_GENTLE)) {
221 MEDIA_ERR_LOG("CloudMediaDownloadType invalid input. downloadType: %{public}d", static_cast<int32_t>(type));
222 return E_ERR;
223 }
224 return E_OK;
225 }
226
StartDownloadCloudAsset(const CloudMediaDownloadType & type)227 int32_t CloudMediaAssetManager::StartDownloadCloudAsset(const CloudMediaDownloadType &type)
228 {
229 if (operation_ == nullptr) {
230 CloudMediaAssetDownloadOperation taskOperator;
231 operation_ = taskOperator.GetInstance();
232 }
233 if (CheckDownloadTypeOfTask(type) != E_OK) {
234 return E_ERR;
235 }
236 operation_->ResetDownloadTryTime();
237 switch (operation_->GetTaskStatus()) {
238 case CloudMediaAssetTaskStatus::IDLE: {
239 return operation_->StartDownloadTask(static_cast<int32_t>(type));
240 }
241 case CloudMediaAssetTaskStatus::PAUSED: {
242 return operation_->ManualActiveRecoverTask(static_cast<int32_t>(type));
243 }
244 case CloudMediaAssetTaskStatus::DOWNLOADING: {
245 if (type == operation_->GetDownloadType()) {
246 MEDIA_WARN_LOG("No status changed.");
247 return E_OK;
248 }
249 if (type == CloudMediaDownloadType::DOWNLOAD_GENTLE) {
250 return operation_->PauseDownloadTask(CloudMediaTaskPauseCause::BACKGROUND_TASK_UNAVAILABLE);
251 }
252 return E_ERR;
253 }
254 default: {
255 MEDIA_ERR_LOG("StartDownloadCloudAsset failed. now: taskStatus_, %{public}d; \
256 downloadType_, %{public}d. input: type, %{public}d;",
257 static_cast<int32_t>(operation_->GetTaskStatus()), static_cast<int32_t>(operation_->GetDownloadType()),
258 static_cast<int32_t>(type));
259 return E_ERR;
260 }
261 }
262 }
263
RecoverDownloadCloudAsset(const CloudMediaTaskRecoverCause & cause)264 int32_t CloudMediaAssetManager::RecoverDownloadCloudAsset(const CloudMediaTaskRecoverCause &cause)
265 {
266 bool cond = (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE);
267 CHECK_AND_RETURN_RET(!cond, E_ERR);
268
269 operation_->ResetDownloadTryTime();
270 MEDIA_INFO_LOG("enter RecoverDownloadCloudAsset, RecoverCause: %{public}d", static_cast<int32_t>(cause));
271 CHECK_AND_RETURN_RET_LOG(operation_->GetTaskStatus() != CloudMediaAssetTaskStatus::DOWNLOADING, E_OK,
272 "The task status is download, no need to recover.");
273 int32_t ret = operation_->PassiveStatusRecoverTask(cause);
274 MEDIA_INFO_LOG("end to RecoverDownloadCloudAsset, status: %{public}s, ret: %{public}d.",
275 GetCloudMediaAssetTaskStatus().c_str(), ret);
276 return ret;
277 }
278
CheckStorageAndRecoverDownloadTask()279 void CloudMediaAssetManager::CheckStorageAndRecoverDownloadTask()
280 {
281 bool cond = (operation_ == nullptr || operation_->GetTaskStatus() != CloudMediaAssetTaskStatus::PAUSED ||
282 operation_->GetTaskPauseCause() != CloudMediaTaskPauseCause::ROM_LIMIT);
283 CHECK_AND_RETURN(!cond);
284 MEDIA_INFO_LOG("begin to check storage and recover downloadTask.");
285 operation_->CheckStorageAndRecoverDownloadTask();
286 }
287
PauseDownloadCloudAsset(const CloudMediaTaskPauseCause & pauseCause)288 int32_t CloudMediaAssetManager::PauseDownloadCloudAsset(const CloudMediaTaskPauseCause &pauseCause)
289 {
290 if (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE) {
291 MEDIA_INFO_LOG("no need to pause");
292 return E_OK;
293 }
294 int32_t ret = operation_->PauseDownloadTask(pauseCause);
295 MEDIA_INFO_LOG("end to PauseDownloadCloudAsset, status: %{public}s, ret: %{public}d.",
296 GetCloudMediaAssetTaskStatus().c_str(), ret);
297 return ret;
298 }
299
CancelDownloadCloudAsset()300 int32_t CloudMediaAssetManager::CancelDownloadCloudAsset()
301 {
302 if (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE) {
303 MEDIA_INFO_LOG("no need to cancel");
304 return E_OK;
305 }
306 int32_t ret = operation_->CancelDownloadTask();
307 operation_.reset();
308 return ret;
309 }
310
StartDeleteCloudMediaAssets()311 void CloudMediaAssetManager::StartDeleteCloudMediaAssets()
312 {
313 TaskDeleteState expect = TaskDeleteState::IDLE;
314 if (doDeleteTask_.compare_exchange_strong(expect, TaskDeleteState::BACKGROUND_DELETE)) {
315 MEDIA_INFO_LOG("start delete cloud media assets task.");
316 DeleteAllCloudMediaAssetsAsync();
317 }
318 }
319
StopDeleteCloudMediaAssets()320 void CloudMediaAssetManager::StopDeleteCloudMediaAssets()
321 {
322 TaskDeleteState expect = TaskDeleteState::BACKGROUND_DELETE;
323 if (!doDeleteTask_.compare_exchange_strong(expect, TaskDeleteState::IDLE)) {
324 MEDIA_INFO_LOG("current status is not suitable for stop delete cloud media assets task.");
325 }
326 }
327
DeleteBatchCloudFile(const std::vector<std::string> & fileIds)328 int32_t CloudMediaAssetManager::DeleteBatchCloudFile(const std::vector<std::string> &fileIds)
329 {
330 MediaLibraryTracer tracer;
331 tracer.Start("DeleteBatchCloudFile");
332 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
333 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "DeleteBatchCloudFile failed. rdbStore is null");
334 AbsRdbPredicates deletePredicates(PhotoColumn::PHOTOS_TABLE);
335 deletePredicates.In(MediaColumn::MEDIA_ID, fileIds);
336 int32_t deletedRows = E_HAS_DB_ERROR;
337 int32_t ret = rdbStore->Delete(deletedRows, deletePredicates);
338 if (ret != NativeRdb::E_OK || deletedRows <= 0) {
339 MEDIA_ERR_LOG("Delete db operation failed. ret %{public}d. Deleted %{public}d", ret, deletedRows);
340 return E_ERR;
341 }
342 MEDIA_INFO_LOG("Delete db operation successful. ret %{public}d. Deleted %{public}d", ret, deletedRows);
343 return E_OK;
344 }
345
ReadyDataForDelete(std::vector<std::string> & fileIds,std::vector<std::string> & paths,std::vector<std::string> & dateTakens)346 int32_t CloudMediaAssetManager::ReadyDataForDelete(std::vector<std::string> &fileIds, std::vector<std::string> &paths,
347 std::vector<std::string> &dateTakens)
348 {
349 MediaLibraryTracer tracer;
350 tracer.Start("ReadyDataForDelete");
351 MEDIA_INFO_LOG("enter ReadyDataForDelete");
352 AbsRdbPredicates queryPredicates(PhotoColumn::PHOTOS_TABLE);
353 queryPredicates.EqualTo(MediaColumn::MEDIA_NAME, DELETE_DISPLAY_NAME);
354 queryPredicates.Limit(BATCH_DELETE_LIMIT_COUNT);
355 vector<string> columns = {MediaColumn::MEDIA_ID, MediaColumn::MEDIA_FILE_PATH, MediaColumn::MEDIA_DATE_TAKEN};
356
357 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
358 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "ReadyDataForDelete failed. rdbStorePtr is null");
359 auto resultSet = rdbStore->Query(queryPredicates, columns);
360 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_ERR, "ReadyDataForDelete failed. resultSet is null");
361 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
362 string path = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
363 if (path.empty()) {
364 MEDIA_WARN_LOG("Failed to get path!");
365 continue;
366 }
367 MEDIA_DEBUG_LOG("get path: %{public}s.", MediaFileUtils::DesensitizePath(path).c_str());
368 fileIds.emplace_back(GetStringVal(MediaColumn::MEDIA_ID, resultSet));
369 paths.emplace_back(path);
370 dateTakens.emplace_back(GetStringVal(MediaColumn::MEDIA_DATE_TAKEN, resultSet));
371 }
372 resultSet->Close();
373 return E_OK;
374 }
375
GetEditDataDirPath(const std::string & path)376 std::string CloudMediaAssetManager::GetEditDataDirPath(const std::string &path)
377 {
378 CHECK_AND_RETURN_RET(path.length() >= ROOT_MEDIA_DIR.length(), "");
379 return MEDIA_EDIT_DATA_DIR + path.substr(ROOT_MEDIA_DIR.length());
380 }
381
DeleteEditdata(const std::string & path)382 int32_t CloudMediaAssetManager::DeleteEditdata(const std::string &path)
383 {
384 string editDataDirPath = GetEditDataDirPath(path);
385 CHECK_AND_RETURN_RET_LOG(!editDataDirPath.empty(), E_ERR, "Cannot get editPath, path: %{private}s", path.c_str());
386 if (MediaFileUtils::IsFileExists(editDataDirPath)) {
387 CHECK_AND_RETURN_RET_LOG(MediaFileUtils::DeleteDir(editDataDirPath), E_ERR,
388 "Failed to delete edit data, path: %{private}s", editDataDirPath.c_str());
389 }
390 return E_OK;
391 }
392
DeleteAllCloudMediaAssetsOperation(AsyncTaskData * data)393 void CloudMediaAssetManager::DeleteAllCloudMediaAssetsOperation(AsyncTaskData *data)
394 {
395 std::lock_guard<std::mutex> lock(deleteMutex_);
396 MEDIA_INFO_LOG("enter DeleteAllCloudMediaAssetsOperation");
397 MediaLibraryTracer tracer;
398 tracer.Start("DeleteAllCloudMediaAssetsOperation");
399
400 std::vector<std::string> fileIds;
401 fileIds.reserve(BATCH_DELETE_LIMIT_COUNT);
402 std::vector<std::string> paths;
403 paths.reserve(BATCH_DELETE_LIMIT_COUNT);
404 std::vector<std::string> dateTakens;
405 dateTakens.reserve(BATCH_DELETE_LIMIT_COUNT);
406 int32_t cycleNumber = 0;
407 while (doDeleteTask_.load() > TaskDeleteState::IDLE && cycleNumber <= CYCLE_NUMBER) {
408 int32_t ret = ReadyDataForDelete(fileIds, paths, dateTakens);
409 if (ret != E_OK || fileIds.empty()) {
410 MEDIA_WARN_LOG("ReadyDataForDelete failed or fileIds is empty, ret: %{public}d, size: %{public}d",
411 ret, static_cast<int32_t>(fileIds.size()));
412 break;
413 }
414 ret = DeleteBatchCloudFile(fileIds);
415 CHECK_AND_BREAK_ERR_LOG(ret == E_OK, "DeleteBatchCloudFile failed!");
416 for (size_t i = 0; i < fileIds.size(); i++) {
417 CHECK_AND_PRINT_LOG(DeleteEditdata(paths[i]) == E_OK, "DeleteEditdata error.");
418 #ifdef META_RECOVERY_SUPPORT
419 CHECK_AND_PRINT_LOG(MediaLibraryMetaRecovery::DeleteMetaDataByPath(paths[i]) == E_OK,
420 "DeleteMetaDataByPath error.");
421 #endif
422 CloudSyncManager::GetInstance().CleanGalleryDentryFile(paths[i]);
423 }
424 MEDIA_INFO_LOG("delete thumb files.");
425 CHECK_AND_PRINT_LOG(ThumbnailService::GetInstance()->BatchDeleteThumbnailDirAndAstc(PhotoColumn::PHOTOS_TABLE,
426 fileIds, paths, dateTakens), "DeleteThumbnailDirAndAstc error.");
427 MEDIA_INFO_LOG("delete all cloud media asset. loop: %{public}d, deleted asset number: %{public}zu",
428 cycleNumber, fileIds.size());
429 fileIds.clear();
430 paths.clear();
431 dateTakens.clear();
432 cycleNumber++;
433 this_thread::sleep_for(chrono::milliseconds(SLEEP_FOR_DELETE));
434 }
435 doDeleteTask_.store(TaskDeleteState::IDLE);
436 MEDIA_INFO_LOG("exit DeleteAllCloudMediaAssetsOperation");
437 }
438
DeleteAllCloudMediaAssetsAsync()439 void CloudMediaAssetManager::DeleteAllCloudMediaAssetsAsync()
440 {
441 shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
442 CHECK_AND_RETURN_LOG(asyncWorker != nullptr, "Can not get asyncWorker");
443
444 shared_ptr<MediaLibraryAsyncTask> deleteAsyncTask =
445 make_shared<MediaLibraryAsyncTask>(DeleteAllCloudMediaAssetsOperation, nullptr);
446 CHECK_AND_RETURN_LOG(deleteAsyncTask != nullptr, "Can not get deleteAsyncTask");
447
448 asyncWorker->AddTask(deleteAsyncTask, true);
449 }
450
HasDataForUpdate(CloudMediaRetainType retainType,std::vector<std::string> & updateFileIds,const std::string & lastFileId)451 bool CloudMediaAssetManager::HasDataForUpdate(CloudMediaRetainType retainType,
452 std::vector<std::string> &updateFileIds, const std::string &lastFileId)
453 {
454 updateFileIds.clear();
455 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
456 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, false, "HasDataForUpdate failed. rdbStore is null.");
457 AbsRdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
458 predicates.GreaterThan(MediaColumn::MEDIA_ID, lastFileId);
459 predicates.EqualTo(PhotoColumn::PHOTO_POSITION, to_string(static_cast<int32_t>(PhotoPositionType::CLOUD)));
460 predicates.NotEqualTo(MediaColumn::MEDIA_NAME, DELETE_DISPLAY_NAME);
461 predicates.OrderByAsc(MediaColumn::MEDIA_ID);
462 predicates.Limit(BATCH_UPDATE_LIMIT_COUNT);
463 std::vector<std::string> columns = { MediaColumn::MEDIA_ID };
464 auto resultSet = rdbStore->Query(predicates, columns);
465 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, false, "HasDataForUpdate failed. resultSet is null.");
466
467 updateFileIds.reserve(BATCH_UPDATE_LIMIT_COUNT);
468 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
469 std::string fileId = GetStringVal(MediaColumn::MEDIA_ID, resultSet);
470 updateFileIds.emplace_back(fileId);
471 }
472 resultSet->Close();
473 CHECK_AND_RETURN_RET_LOG(updateFileIds.size() > 0, false, "the size of updateFileIds 0.");
474 return true;
475 }
476
UpdateCloudAssets(const std::vector<std::string> & updateFileIds)477 int32_t CloudMediaAssetManager::UpdateCloudAssets(const std::vector<std::string> &updateFileIds)
478 {
479 MediaLibraryTracer tracer;
480 tracer.Start("UpdateCloudAssets");
481 CHECK_AND_RETURN_RET_LOG(!updateFileIds.empty(), E_ERR, "updateFileIds is null.");
482 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
483 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "UpdateCloudAssets failed. rdbStore is null.");
484 AbsRdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
485 predicates.In(MediaColumn::MEDIA_ID, updateFileIds);
486
487 ValuesBucket values;
488 values.PutString(MediaColumn::MEDIA_NAME, DELETE_DISPLAY_NAME);
489 values.PutInt(PhotoColumn::PHOTO_CLEAN_FLAG, static_cast<int32_t>(CleanType::TYPE_NEED_CLEAN));
490 values.PutInt(PhotoColumn::PHOTO_DIRTY, -1);
491 values.PutLong(PhotoColumn::PHOTO_CLOUD_VERSION, 0);
492 values.PutNull(PhotoColumn::PHOTO_CLOUD_ID);
493
494 int32_t changedRows = -1;
495 int32_t ret = rdbStore->Update(changedRows, values, predicates);
496 CHECK_AND_RETURN_RET_LOG((ret == E_OK && changedRows > 0), E_ERR,
497 "Failed to UpdateCloudAssets, ret: %{public}d, updateRows: %{public}d", ret, changedRows);
498 MEDIA_INFO_LOG("UpdateCloudAssets successfully. ret: %{public}d, updateRows: %{public}d", ret, changedRows);
499 return E_OK;
500 }
501
NotifyUpdateAssetsChange(const std::vector<std::string> & notifyFileIds)502 void CloudMediaAssetManager::NotifyUpdateAssetsChange(const std::vector<std::string> ¬ifyFileIds)
503 {
504 AccurateRefresh::AssetAccurateRefresh::NotifyForReCheck();
505 CHECK_AND_RETURN_LOG(!notifyFileIds.empty(), "notifyFileIds is null.");
506 auto watch = MediaLibraryNotify::GetInstance();
507 CHECK_AND_RETURN_LOG(watch != nullptr, "watch is null.");
508 for (size_t i = 0; i < notifyFileIds.size(); i++) {
509 watch->Notify(MediaFileUtils::GetUriByExtrConditions(PhotoColumn::PHOTO_URI_PREFIX, notifyFileIds[i]),
510 NotifyType::NOTIFY_REMOVE);
511 }
512 }
513
UpdateCloudMediaAssets(CloudMediaRetainType retainType)514 int32_t CloudMediaAssetManager::UpdateCloudMediaAssets(CloudMediaRetainType retainType)
515 {
516 MediaLibraryTracer tracer;
517 tracer.Start("UpdateCloudMediaAssets");
518
519 int32_t cycleNumber = 0;
520 std::string lastFileId = START_QUERY_ZERO;
521 std::vector<std::string> notifyFileIds;
522 notifyFileIds.reserve(BATCH_NOTIFY_CLOUD_FILE);
523 std::vector<std::string> updateFileIds;
524 int32_t actualRet = E_OK;
525 MEDIA_INFO_LOG("begin UpdateCloudMediaAssets");
526 while (HasDataForUpdate(retainType, updateFileIds, lastFileId) && cycleNumber <= CYCLE_NUMBER) {
527 int32_t ret = UpdateCloudAssets(updateFileIds);
528 if (ret != E_OK) {
529 MEDIA_WARN_LOG("UpdateCloudAssets failed, and try again ret: %{public}d", ret);
530 ret = UpdateCloudAssets(updateFileIds);
531 }
532 if (ret != E_OK) {
533 MEDIA_ERR_LOG("UpdateCloudAssets failed, ret: %{public}d", ret);
534 actualRet = ret;
535 continue;
536 }
537 lastFileId = updateFileIds.back();
538 notifyFileIds.insert(notifyFileIds.end(), updateFileIds.begin(), updateFileIds.end());
539 if (notifyFileIds.size() >= BATCH_NOTIFY_CLOUD_FILE) {
540 NotifyUpdateAssetsChange(notifyFileIds);
541 notifyFileIds.clear();
542 }
543
544 cycleNumber++;
545 }
546 MEDIA_INFO_LOG("end UpdateCloudMediaAssets");
547 if (notifyFileIds.size() > 0) {
548 NotifyUpdateAssetsChange(notifyFileIds);
549 notifyFileIds.clear();
550 }
551 if (cycleNumber > 0) {
552 MEDIA_INFO_LOG("begin to refresh all albums.");
553 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
554 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_OK, "UpdateAllAlbums failed. rdbStore is null.");
555 MediaLibraryRdbUtils::UpdateAllAlbums(rdbStore);
556 }
557 return actualRet;
558 }
559
DeleteEmptyCloudAlbums()560 int32_t CloudMediaAssetManager::DeleteEmptyCloudAlbums()
561 {
562 MEDIA_INFO_LOG("start DeleteEmptyCloudAlbums.");
563 MediaLibraryTracer tracer;
564 tracer.Start("DeleteEmptyCloudAlbums");
565 std::shared_ptr<AccurateRefresh::AlbumAccurateRefresh> albumRefresh =
566 std::make_shared<AccurateRefresh::AlbumAccurateRefresh>();
567 CHECK_AND_RETURN_RET_LOG(albumRefresh != nullptr, E_ERR, "DeleteEmptyCloudAlbums failed. albumRefresh is null");
568 int32_t ret = albumRefresh->Init(SQL_QUERY_EMPTY_CLOUD_ALBUMS, std::vector<NativeRdb::ValueObject>());
569 CHECK_AND_RETURN_RET_LOG(ret == AccurateRefresh::ACCURATE_REFRESH_RET_OK, E_ERR, "Failed to init albumRefresh");
570
571 ret = albumRefresh->ExecuteSql(SQL_DELETE_EMPTY_CLOUD_ALBUMS, AccurateRefresh::RdbOperation::RDB_OPERATION_REMOVE);
572 CHECK_AND_RETURN_RET_LOG(ret == AccurateRefresh::ACCURATE_REFRESH_RET_OK, E_ERR,
573 "Failed to delete. ret %{public}d.", ret);
574 albumRefresh->Notify();
575 MEDIA_INFO_LOG("end DeleteEmptyCloudAlbums. ret %{public}d.", ret);
576 return E_OK;
577 }
578
HasLocalAndCloudAssets(CloudMediaRetainType retainType,std::vector<std::string> & updateFileIds,const string & lastFileId)579 bool CloudMediaAssetManager::HasLocalAndCloudAssets(CloudMediaRetainType retainType,
580 std::vector<std::string> &updateFileIds, const string &lastFileId)
581 {
582 updateFileIds.clear();
583 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
584 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, false, "HasLocalAndCloudAssets failed. rdbStore is null.");
585
586 AbsRdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
587 predicates.GreaterThan(MediaColumn::MEDIA_ID, lastFileId);
588 predicates.BeginWrap();
589 predicates.EqualTo(PhotoColumn::PHOTO_POSITION, static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD));
590 predicates.Or();
591 predicates.BeginWrap();
592 predicates.EqualTo(PhotoColumn::PHOTO_POSITION, static_cast<int32_t>(PhotoPositionType::LOCAL));
593 predicates.BeginWrap();
594 predicates.IsNotNull(PhotoColumn::PHOTO_CLOUD_ID);
595 predicates.Or();
596 predicates.NotEqualTo(PhotoColumn::PHOTO_CLOUD_VERSION, 0);
597 predicates.Or();
598 predicates.NotEqualTo(PhotoColumn::PHOTO_DIRTY, static_cast<int32_t>(DirtyType::TYPE_NEW));
599 predicates.EndWrap();
600 predicates.EndWrap();
601 predicates.EndWrap();
602 predicates.OrderByAsc(MediaColumn::MEDIA_ID);
603 predicates.Limit(BATCH_UPDATE_LIMIT_COUNT);
604
605 std::vector<std::string> columns = { MediaColumn::MEDIA_ID };
606 auto resultSet = rdbStore->Query(predicates, columns);
607 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, false,
608 "HasLocalAndCloudAssets failed. resultSet is null.");
609
610 updateFileIds.reserve(BATCH_UPDATE_LIMIT_COUNT);
611 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
612 std::string fileId = GetStringVal(MediaColumn::MEDIA_ID, resultSet);
613 updateFileIds.emplace_back(fileId);
614 }
615 resultSet->Close();
616 CHECK_AND_RETURN_RET_LOG(updateFileIds.size() > 0, false, "the size of updateFileIds 0.");
617 return true;
618 }
619
UpdateLocalAndCloudAssets(const std::vector<std::string> & updateFileIds)620 int32_t CloudMediaAssetManager::UpdateLocalAndCloudAssets(const std::vector<std::string> &updateFileIds)
621 {
622 MediaLibraryTracer tracer;
623 tracer.Start("UpdateLocalAndCloudAssets");
624 CHECK_AND_RETURN_RET_LOG(!updateFileIds.empty(), E_ERR, "updateFileIds is null.");
625 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
626 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "UpdateLocalAndCloudAssets failed. rdbStore is null.");
627 AbsRdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
628 predicates.In(MediaColumn::MEDIA_ID, updateFileIds);
629
630 ValuesBucket values;
631 values.PutInt(PhotoColumn::PHOTO_DIRTY, static_cast<int32_t>(DirtyType::TYPE_NEW));
632 values.PutLong(PhotoColumn::PHOTO_CLOUD_VERSION, 0);
633 values.PutNull(PhotoColumn::PHOTO_CLOUD_ID);
634 values.PutInt(PhotoColumn::PHOTO_POSITION, static_cast<int32_t>(PhotoPositionType::LOCAL));
635
636 int32_t changedRows = -1;
637 int32_t ret = rdbStore->Update(changedRows, values, predicates);
638 CHECK_AND_RETURN_RET_LOG((ret == E_OK && changedRows >= 0), E_ERR,
639 "Failed to UpdateLocalAndCloudAssets, ret: %{public}d, updateRows: %{public}d", ret, changedRows);
640 MEDIA_INFO_LOG("UpdateLocalAndCloudAssets successfully. ret: %{public}d, updateRows: %{public}d", ret, changedRows);
641 return E_OK;
642 }
643
ClearDeletedDbData()644 int32_t CloudMediaAssetManager::ClearDeletedDbData()
645 {
646 MEDIA_INFO_LOG("start ClearDeletedDbData.");
647 MediaLibraryTracer tracer;
648 tracer.Start("ClearDeletedDbData");
649
650 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
651 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "ClearDeletedDbData failed. rdbStore is null.");
652
653 AbsRdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
654 predicates.EqualTo(PhotoColumn::PHOTO_DIRTY, to_string(static_cast<int32_t>(DirtyType::TYPE_DELETED)));
655
656 int32_t deletedRows = -1;
657 auto ret = rdbStore->Delete(deletedRows, predicates);
658 CHECK_AND_RETURN_RET_LOG((ret == E_OK && deletedRows >= 0), E_ERR,
659 "Failed to ClearDeletedDbData, ret: %{public}d, deletedRows: %{public}d", ret, deletedRows);
660 MEDIA_INFO_LOG("ClearDeletedDbData successfully. ret: %{public}d, deletedRows: %{public}d", ret, deletedRows);
661 return E_OK;
662 }
663
UpdateBothLocalAndCloudAssets(CloudMediaRetainType retainType)664 int32_t CloudMediaAssetManager::UpdateBothLocalAndCloudAssets(CloudMediaRetainType retainType)
665 {
666 MEDIA_INFO_LOG("start UpdateBothLocalAndCloudAssets.");
667 MediaLibraryTracer tracer;
668 tracer.Start("UpdateBothLocalAndCloudAssets");
669
670 int32_t deleteRet = ClearDeletedDbData();
671 CHECK_AND_PRINT_LOG(deleteRet == E_OK, "ClearDeletedDbData failed. ret %{public}d.", deleteRet);
672
673 int32_t cycleNumber = 0;
674 std::string lastFileId = START_QUERY_ZERO;
675 std::vector<std::string> updateFileIds;
676 while (HasLocalAndCloudAssets(retainType, updateFileIds, lastFileId) && cycleNumber <= CYCLE_NUMBER) {
677 int32_t ret = UpdateLocalAndCloudAssets(updateFileIds);
678 CHECK_AND_BREAK_ERR_LOG(ret == E_OK, "UpdateBothLocalAndCloudAssets failed, ret: %{public}d", ret);
679 lastFileId = updateFileIds.back();
680 cycleNumber++;
681 }
682 MEDIA_INFO_LOG("end UpdateBothLocalAndCloudAssets.");
683 return E_OK;
684 }
685
UpdateLocalAlbums()686 int32_t CloudMediaAssetManager::UpdateLocalAlbums()
687 {
688 MEDIA_INFO_LOG("start UpdateLocalAlbums.");
689 MediaLibraryTracer tracer;
690 tracer.Start("UpdateLocalAlbums");
691 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
692 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "UpdateLocalAlbums failed. rdbStore is null");
693
694 AbsRdbPredicates predicates = AbsRdbPredicates(PhotoAlbumColumns::TABLE);
695 ValuesBucket values;
696 values.PutInt(PhotoAlbumColumns::ALBUM_DIRTY, static_cast<int32_t>(DirtyType::TYPE_NEW));
697 values.PutNull(PhotoAlbumColumns::ALBUM_CLOUD_ID);
698
699 int32_t changedRows = E_HAS_DB_ERROR;
700 int32_t ret = rdbStore->Update(changedRows, values, predicates);
701 CHECK_AND_RETURN_RET_LOG((ret == E_OK && changedRows >= 0), E_ERR,
702 "Failed to UpdateLocalAlbums, ret: %{public}d, changedRows: %{public}d", ret, changedRows);
703 MEDIA_INFO_LOG("UpdateLocalAlbums successfully. ret %{public}d. changedRows %{public}d", ret, changedRows);
704 return E_OK;
705 }
706
ForceRetainDownloadCloudMedia(CloudMediaRetainType retainType,bool needAvoidRepeatedDoing)707 int32_t CloudMediaAssetManager::ForceRetainDownloadCloudMedia(CloudMediaRetainType retainType,
708 bool needAvoidRepeatedDoing)
709 {
710 MediaLibraryTracer tracer;
711 auto retainTypeInt = static_cast<int32_t>(retainType);
712 tracer.Start(std::string("ForceRetainDownloadCloudMedia") + std::to_string(retainTypeInt));
713 MEDIA_INFO_LOG("enter. retainType: %{public}d", retainTypeInt);
714
715 if (needAvoidRepeatedDoing && IsSouthDeviceSyncCleaning(retainType)) {
716 MEDIA_INFO_LOG("this south device is cleaning, retainType: %{public}d", retainTypeInt);
717 return E_OK;
718 }
719
720 // 判断是不是已经有个南向设备端在cleaning, 如果有也直接返回
721 bool isCloudCleaning = IsSouthDeviceSyncCleaning(CloudMediaRetainType::RETAIN_FORCE);
722 bool isHdcCleaning = IsSouthDeviceSyncCleaning(CloudMediaRetainType::HDC_RETAIN_FORCE);
723 SetSouthDeviceCleanStatus(retainType, CloudSyncStatus::CLOUD_CLEANING);
724 if (needAvoidRepeatedDoing && (isCloudCleaning || isHdcCleaning)) {
725 MEDIA_INFO_LOG("some south device is cleaning. cloud: %{public}d, hdc: %{public}d",
726 isCloudCleaning, isHdcCleaning);
727 return E_OK;
728 }
729 SetSouthDeviceSyncSwitchStatus(CloudSyncStatus::CLOUD_CLEANING);
730
731 // 主动停止端云同步
732 MEDIA_INFO_LOG("ForceRetainDownloadCloudMedia StopSync bundleName:%{public}s", BUNDLE_NAME.c_str());
733 CloudSyncManager::GetInstance().StopSync(BUNDLE_NAME);
734
735 // 备份/恢复需要特殊处理,等待备份和恢复完成再清除;
736 WaitIfBackUpingOrRestoring();
737
738 auto ret = ForceRetainDownloadCloudMediaEx(retainType);
739 MEDIA_INFO_LOG("ForceRetainDownloadCloudMediaEx ret: %{public}d", ret);
740 SetSouthDeviceCleanStatus(retainType, CloudSyncStatus::SYNC_SWITCHED_OFF);
741 isCloudCleaning = IsSouthDeviceSyncCleaning(CloudMediaRetainType::RETAIN_FORCE);
742 isHdcCleaning = IsSouthDeviceSyncCleaning(CloudMediaRetainType::HDC_RETAIN_FORCE);
743
744 if (isCloudCleaning) {
745 ret |= ForceRetainDownloadCloudMediaEx(CloudMediaRetainType::RETAIN_FORCE);
746 SetSouthDeviceCleanStatus(CloudMediaRetainType::RETAIN_FORCE, CloudSyncStatus::SYNC_SWITCHED_OFF);
747 CHECK_AND_PRINT_LOG(ret == E_OK, "cloud force retain. ret %{public}d.", ret);
748 }
749
750 if (isHdcCleaning) {
751 ret |= ForceRetainDownloadCloudMediaEx(CloudMediaRetainType::HDC_RETAIN_FORCE);
752 SetSouthDeviceCleanStatus(CloudMediaRetainType::HDC_RETAIN_FORCE, CloudSyncStatus::SYNC_SWITCHED_OFF);
753 CHECK_AND_PRINT_LOG(ret == E_OK, "hdc force retain. ret %{public}d.", ret);
754 }
755 SetSouthDeviceSyncSwitchStatus(CloudSyncStatus::SYNC_SWITCHED_OFF);
756
757 TryToStartSync();
758
759 MEDIA_INFO_LOG("exit. retainType: %{public}d", retainTypeInt);
760 return ret;
761 }
762
ForceRetainDownloadCloudMediaEx(CloudMediaRetainType retainType)763 int32_t CloudMediaAssetManager::ForceRetainDownloadCloudMediaEx(CloudMediaRetainType retainType)
764 {
765 auto retainTypeInt = static_cast<int32_t>(retainType);
766 MEDIA_INFO_LOG("enter ForceRetainDownloadCloudMediaEx. retainType: %{public}d", retainTypeInt);
767
768 std::unique_lock<std::mutex> lock(updateMutex_, std::defer_lock);
769 CHECK_AND_RETURN_RET_WARN_LOG(lock.try_lock(), E_ERR, // 此处的作用貌似和避免重复的逻辑一致
770 "retainType: %{public}d, data is cleaning, skipping this operation", retainTypeInt);
771
772 MediaLibraryTracer tracer;
773 tracer.Start(std::string("ForceRetainDownloadCloudMediaEx, retainType:") + std::to_string(retainTypeInt));
774 // 停止后台异步清理云图任务,待本次云上信息标记完后重新开启
775 doDeleteTask_.store(TaskDeleteState::IDLE);
776
777 int32_t updateRet = UpdateCloudMediaAssets(retainType);
778 CHECK_AND_PRINT_LOG(updateRet == E_OK, "UpdateCloudMediaAssets failed. ret %{public}d.", updateRet);
779 int32_t ret = DeleteEmptyCloudAlbums();
780 CHECK_AND_PRINT_LOG(ret == E_OK, "DeleteEmptyCloudAlbums failed. ret %{public}d.", ret);
781 auto watch = MediaLibraryNotify::GetInstance();
782 if (watch != nullptr) {
783 MEDIA_INFO_LOG("begin to notify album update.");
784 watch->Notify(PhotoAlbumColumns::ALBUM_URI_PREFIX, NotifyType::NOTIFY_UPDATE);
785 }
786
787 ret = UpdateBothLocalAndCloudAssets(retainType);
788 CHECK_AND_PRINT_LOG(ret == E_OK, "UpdateBothLocalAndCloudAssets failed. ret %{public}d.", ret);
789 ret = UpdateLocalAlbums();
790 CHECK_AND_PRINT_LOG(ret == E_OK, "UpdateLocalAlbums failed. ret %{public}d.", ret);
791
792 MEDIA_INFO_LOG("start delete cloud media assets task.");
793 doDeleteTask_.store(TaskDeleteState::ACTIVE_DELETE);
794 DeleteAllCloudMediaAssetsAsync();
795
796 CHECK_AND_RETURN_RET_WARN_LOG(updateRet == E_OK, updateRet,
797 "exit ForceRetainDownloadCloudMediaEx, Type: %{public}d, updateRet: %{public}d.", retainTypeInt, updateRet);
798 MEDIA_INFO_LOG("exit ForceRetainDownloadCloudMediaEx, retainType: %{public}d", retainTypeInt);
799 return ret;
800 }
801
GetCloudMediaAssetTaskStatus()802 std::string CloudMediaAssetManager::GetCloudMediaAssetTaskStatus()
803 {
804 if (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE) {
805 MEDIA_ERR_LOG("cloud media download task not exit.");
806 return to_string(static_cast<int32_t>(CloudMediaAssetTaskStatus::IDLE)) + ",0,0,0,0,0";
807 }
808 return to_string(static_cast<int32_t>(operation_->GetTaskStatus())) + "," + operation_->GetTaskInfo() + "," +
809 to_string(static_cast<int32_t>(operation_->GetTaskPauseCause()));
810 }
811
HandleCloudMediaAssetUpdateOperations(MediaLibraryCommand & cmd)812 int32_t CloudMediaAssetManager::HandleCloudMediaAssetUpdateOperations(MediaLibraryCommand &cmd)
813 {
814 switch (cmd.GetOprnType()) {
815 case OperationType::CLOUD_MEDIA_ASSET_TASK_START_FORCE: {
816 return StartDownloadCloudAsset(CloudMediaDownloadType::DOWNLOAD_FORCE);
817 }
818 case OperationType::CLOUD_MEDIA_ASSET_TASK_START_GENTLE: {
819 return StartDownloadCloudAsset(CloudMediaDownloadType::DOWNLOAD_GENTLE);
820 }
821 case OperationType::CLOUD_MEDIA_ASSET_TASK_PAUSE: {
822 return PauseDownloadCloudAsset(CloudMediaTaskPauseCause::USER_PAUSED);
823 }
824 case OperationType::CLOUD_MEDIA_ASSET_TASK_CANCEL: {
825 return CancelDownloadCloudAsset();
826 }
827 case OperationType::CLOUD_MEDIA_ASSET_TASK_RETAIN_FORCE: {
828 return ForceRetainDownloadCloudMedia(CloudMediaRetainType::RETAIN_FORCE);
829 }
830 default: {
831 MEDIA_ERR_LOG("OprnType is not exit.");
832 return E_ERR;
833 }
834 }
835 }
836
HandleCloudMediaAssetGetTypeOperations(MediaLibraryCommand & cmd)837 string CloudMediaAssetManager::HandleCloudMediaAssetGetTypeOperations(MediaLibraryCommand &cmd)
838 {
839 switch (cmd.GetOprnType()) {
840 case OperationType::CLOUD_MEDIA_ASSET_TASK_STATUS_QUERY: {
841 return GetCloudMediaAssetTaskStatus();
842 }
843 default: {
844 MEDIA_ERR_LOG("OprnType is not exit.");
845 return "";
846 }
847 }
848 }
849
SetIsThumbnailUpdate()850 bool CloudMediaAssetManager::SetIsThumbnailUpdate()
851 {
852 if (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE) {
853 return false;
854 }
855 if (!operation_->isThumbnailUpdate_) {
856 MEDIA_INFO_LOG("Success set isThumbnailUpdate.");
857 operation_->isThumbnailUpdate_ = true;
858 }
859 MEDIA_INFO_LOG("Update count and size of download cloud media asset.");
860 if (operation_->InitDownloadTaskInfo() != E_OK) {
861 MEDIA_INFO_LOG("remainCount of download cloud media assets is 0.");
862 operation_->CancelDownloadTask();
863 }
864 return true;
865 }
866
GetTaskStatus()867 int32_t CloudMediaAssetManager::GetTaskStatus()
868 {
869 CHECK_AND_RETURN_RET(operation_ != nullptr, static_cast<int32_t>(CloudMediaAssetTaskStatus::IDLE));
870 return static_cast<int32_t>(operation_->GetTaskStatus());
871 }
872
GetDownloadType()873 int32_t CloudMediaAssetManager::GetDownloadType()
874 {
875 if (operation_ == nullptr) {
876 MEDIA_INFO_LOG("cloud media download task not exit.");
877 return E_ERR;
878 }
879 return static_cast<int32_t>(operation_->GetDownloadType());
880 }
881
SetBgDownloadPermission(const bool & flag)882 bool CloudMediaAssetManager::SetBgDownloadPermission(const bool &flag)
883 {
884 bool cond = (operation_ == nullptr || operation_->GetTaskStatus() == CloudMediaAssetTaskStatus::IDLE);
885 CHECK_AND_RETURN_RET(!cond, false);
886 MEDIA_INFO_LOG("Success set isBgDownloadPermission, flag: %{public}d.", static_cast<int32_t>(flag));
887 operation_->isBgDownloadPermission_ = flag;
888 return true;
889 }
890
RestartForceRetainCloudAssets()891 void CloudMediaAssetManager::RestartForceRetainCloudAssets()
892 {
893 std::thread([&] {
894 MEDIA_INFO_LOG("enter RestartForceRetainCloudAssets.");
895 auto isCleaning = IsSouthDeviceSyncCleaning(CloudMediaRetainType::RETAIN_FORCE, false);
896 isCleaning = isCleaning || IsSouthDeviceSyncCleaning(CloudMediaRetainType::HDC_RETAIN_FORCE, false);
897 if (isCleaning) {
898 MEDIA_WARN_LOG("restart continue retain force, given the current design, any of hdc/cloud can be chosen");
899 ForceRetainDownloadCloudMedia(CloudMediaRetainType::RETAIN_FORCE, false);
900 }
901 }).detach();
902 }
903
TryToStartSync()904 void CloudMediaAssetManager::TryToStartSync()
905 {
906 if (!CloudSyncHelper::GetInstance()->IsSyncSwitchOpen()) {
907 MEDIA_INFO_LOG("syncSwitch is not open");
908 return;
909 }
910 MEDIA_INFO_LOG("cloud sync manager start sync");
911 int32_t ret = CloudSyncManager::GetInstance().StartSync(BUNDLE_NAME);
912 CHECK_AND_PRINT_LOG(ret == E_OK, "cloud sync manager start sync err %{public}d", ret);
913 MEDIA_INFO_LOG("cloud sync manager end sync");
914 }
915 } // namespace Media
916 } // namespace OHOS