• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #define MLOG_TAG "PhotosDataHandler"
16 
17 #include "photos_data_handler.h"
18 
19 #include <sstream>
20 
21 #include "backup_database_utils.h"
22 #include "backup_file_utils.h"
23 #include "ffrt.h"
24 #include "ffrt_inner.h"
25 #include "media_file_utils.h"
26 #include "upgrade_restore_task_report.h"
27 
28 namespace OHOS::Media {
OnStart(int32_t sceneCode,const std::string & taskId,std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb)29 void PhotosDataHandler::OnStart(int32_t sceneCode, const std::string &taskId,
30     std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb)
31 {
32     SetSceneCode(sceneCode).SetTaskId(taskId).SetMediaLibraryRdb(mediaLibraryRdb);
33 }
34 
SetSceneCode(int32_t sceneCode)35 PhotosDataHandler &PhotosDataHandler::SetSceneCode(int32_t sceneCode)
36 {
37     sceneCode_ = sceneCode;
38     return *this;
39 }
40 
SetTaskId(const std::string & taskId)41 PhotosDataHandler &PhotosDataHandler::SetTaskId(const std::string &taskId)
42 {
43     taskId_ = taskId;
44     return *this;
45 }
46 
SetMediaLibraryRdb(std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb)47 PhotosDataHandler &PhotosDataHandler::SetMediaLibraryRdb(std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb)
48 {
49     mediaLibraryRdb_ = mediaLibraryRdb;
50     photosDao_.SetMediaLibraryRdb(mediaLibraryRdb);
51     return *this;
52 }
53 
HandleDirtyFiles()54 void PhotosDataHandler::HandleDirtyFiles()
55 {
56     int64_t startQuery = MediaFileUtils::UTCTimeMilliSeconds();
57     int32_t totalNumber = photosDao_.GetDirtyFilesCount();
58     MEDIA_INFO_LOG("totalNumber = %{public}d", totalNumber);
59     ffrt_set_cpu_worker_max_num(ffrt::qos_utility, MAX_THREAD_NUM);
60     int64_t startClean = MediaFileUtils::UTCTimeMilliSeconds();
61     for (int32_t offset = 0; offset < totalNumber; offset += QUERY_COUNT) {
62         ffrt::submit([this, offset]() { HandleDirtyFilesBatch(offset); }, { &offset }, {},
63             ffrt::task_attr().qos(static_cast<int32_t>(ffrt::qos_utility)));
64     }
65     ffrt::wait();
66     int64_t startDelete = MediaFileUtils::UTCTimeMilliSeconds();
67     int32_t deleteCount = PhotosDataHandler::DeleteDirtyFilesInDb();
68     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
69     UpgradeRestoreTaskReport().SetSceneCode(sceneCode_).SetTaskId(taskId_)
70         .Report("HANDLE_DIRTY_FILES", "",
71             "total dirty count: " + std::to_string(totalNumber) +
72             ", query total cost: " + std::to_string(startClean - startQuery) +
73             "; clean files count: " + std::to_string(dirtyFileCleanNumber_) +
74             ", clean files cost: " + std::to_string(startDelete - startClean) +
75             ", failed clean files count: " + std::to_string(failedDirtyFileCleanNumber_) +
76             "; clean db count: " + std::to_string(deleteCount) +
77             ", delete in db cost: " + std::to_string(end - startDelete));
78 }
79 
HandleDirtyFilesBatch(int32_t offset)80 void PhotosDataHandler::HandleDirtyFilesBatch(int32_t offset)
81 {
82     MEDIA_INFO_LOG("start clean dirty files offset: %{public}d", offset);
83     int64_t startQuery = MediaFileUtils::UTCTimeMilliSeconds();
84     std::vector<PhotosDao::PhotosRowData> dirtyFiles = photosDao_.GetDirtyFiles(offset);
85     int64_t startClean = MediaFileUtils::UTCTimeMilliSeconds();
86     int32_t count = CleanDirtyFiles(dirtyFiles);
87     dirtyFileCleanNumber_ += count;
88     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
89     MEDIA_INFO_LOG("query %{public}zu dirty files cost %{public}" PRId64", clean cost %{public}" PRId64,
90         dirtyFiles.size(), startClean - startQuery, end - startClean);
91 }
92 
CleanDirtyFiles(const std::vector<PhotosDao::PhotosRowData> & dirtyFiles)93 int32_t PhotosDataHandler::CleanDirtyFiles(const std::vector<PhotosDao::PhotosRowData> &dirtyFiles)
94 {
95     int32_t count = 0;
96     CHECK_AND_RETURN_RET(!dirtyFiles.empty(), count);
97     for (const auto &dirtyFile : dirtyFiles) {
98         // clean cloud path
99         bool deleteFileRet = MediaFileUtils::DeleteFileOrFolder(dirtyFile.data, true);
100         // clean thumbs folder
101         std::string thumbsFolder =
102             BackupFileUtils::GetReplacedPathByPrefixType(PrefixType::CLOUD, PrefixType::CLOUD_THUMB, dirtyFile.data);
103         bool deleteThumbsRet = MediaFileUtils::DeleteFileOrFolder(thumbsFolder, false);
104         if (!deleteFileRet || !deleteThumbsRet) {
105             std::lock_guard<mutex> lock(cleanFailedFilesMutex_);
106             MEDIA_ERR_LOG("Clean file failed, path: %{public}s, ret: %{public}d, errno: %{public}d",
107                 BackupFileUtils::GarbleFilePath(dirtyFile.data, sceneCode_).c_str(),
108                 static_cast<int32_t>(deleteFileRet), static_cast<int32_t>(deleteThumbsRet), errno);
109             cleanFailedFiles_.push_back(to_string(dirtyFile.fileId));
110             failedDirtyFileCleanNumber_++;
111             continue;
112         }
113         count++;
114     }
115     return count;
116 }
117 
DeleteDirtyFilesInDb()118 int32_t PhotosDataHandler::DeleteDirtyFilesInDb()
119 {
120     // clean database
121     NativeRdb::AbsRdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
122     predicates.EqualTo(PhotoColumn::PHOTO_SYNC_STATUS, static_cast<int32_t>(SyncStatusType::TYPE_BACKUP));
123     predicates.NotIn(MediaColumn::MEDIA_ID, cleanFailedFiles_);
124     int32_t changedRows = 0;
125     int32_t deleteDbRet = BackupDatabaseUtils::Delete(predicates, changedRows, mediaLibraryRdb_);
126     MEDIA_INFO_LOG("changedRows: %{public}d, deleteRet: %{public}d", changedRows, deleteDbRet);
127     return changedRows;
128 }
129 }  // namespace OHOS::Media
130