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
16 #define MLOG_TAG "AccurateRefresh::AssetAccurateRefresh"
17
18 #ifndef MEDIA_REFRESH_TEST
19 #include "cloud_sync_helper.h"
20 #endif
21 #include <cstdint>
22 #include "medialibrary_errno.h"
23 #include "media_file_utils.h"
24 #include "asset_accurate_refresh.h"
25 #include "medialibrary_notify_new.h"
26 #include "accurate_debug_log.h"
27 #include "medialibrary_tracer.h"
28 #include "dfx_refresh_manager.h"
29 #include "dfx_refresh_hander.h"
30
31 using namespace std;
32 using namespace OHOS::NativeRdb;
33
34 namespace OHOS {
35 namespace Media::AccurateRefresh {
36
37 mutex AssetAccurateRefresh::assetQueryMutex_;
38
AssetAccurateRefresh(std::shared_ptr<TransactionOperations> trans)39 AssetAccurateRefresh::AssetAccurateRefresh(std::shared_ptr<TransactionOperations> trans) : AccurateRefreshBase(trans)
40 {
41 dataManager_.SetTransaction(trans);
42 }
43
AssetAccurateRefresh(const std::string & targetBusiness,std::shared_ptr<TransactionOperations> trans)44 AssetAccurateRefresh::AssetAccurateRefresh(const std::string &targetBusiness,
45 std::shared_ptr<TransactionOperations> trans) : AccurateRefreshBase(targetBusiness, trans)
46 {
47 dataManager_.SetTransaction(trans);
48 }
49
Init()50 int32_t AssetAccurateRefresh::Init()
51 {
52 return ACCURATE_REFRESH_RET_OK;
53 }
54
Init(const AbsRdbPredicates & predicates)55 int32_t AssetAccurateRefresh::Init(const AbsRdbPredicates &predicates)
56 {
57 if (!IsValidTable(predicates.GetTableName())) {
58 return ACCURATE_REFRESH_RDB_INVALITD_TABLE;
59 }
60
61 std::lock_guard<std::mutex> lock(assetQueryMutex_);
62 return dataManager_.Init(predicates);
63 }
64
Init(const string & sql,const vector<ValueObject> bindArgs)65 int32_t AssetAccurateRefresh::Init(const string &sql, const vector<ValueObject> bindArgs)
66 {
67 std::lock_guard<std::mutex> lock(assetQueryMutex_);
68 return dataManager_.Init(sql, bindArgs);
69 }
70
71 // 增删场景下初始化数据
Init(const vector<int32_t> & fileIds)72 int32_t AssetAccurateRefresh::Init(const vector<int32_t> &fileIds)
73 {
74 std::lock_guard<std::mutex> lock(assetQueryMutex_);
75 return dataManager_.Init(fileIds);
76 }
77
78 // refresh album based on init datas and modified datas.
RefreshAlbum(NotifyAlbumType notifyAlbumType,bool isRefreshWithDateModified)79 int32_t AssetAccurateRefresh::RefreshAlbum(NotifyAlbumType notifyAlbumType, bool isRefreshWithDateModified)
80 {
81 if (dfxRefreshManager_ != nullptr) {
82 albumRefreshExe_.SetDfxRefreshManager(dfxRefreshManager_);
83 }
84 MediaLibraryTracer tracer;
85 tracer.Start("AssetAccurateRefresh::RefreshAlbum");
86 if (dataManager_.CheckIsForRecheck()) {
87 dataManager_.ClearMultiThreadChangeDatas();
88 int32_t ret = RefreshAllAlbum(notifyAlbumType, isRefreshWithDateModified);
89 DfxRefreshHander::SetEndTimeHander(dfxRefreshManager_);
90 return ret;
91 }
92 auto assetChangeDatas = dataManager_.GetChangeDatas(true);
93 if (assetChangeDatas.empty()) {
94 MEDIA_WARN_LOG("change data empty.");
95 dataManager_.ClearMultiThreadChangeDatas();
96 DfxRefreshHander::SetEndTimeHander(dfxRefreshManager_);
97 return ACCURATE_REFRESH_CHANGE_DATA_EMPTY;
98 }
99 auto ret = RefreshAlbum(assetChangeDatas, notifyAlbumType, isRefreshWithDateModified);
100 dataManager_.ClearMultiThreadChangeDatas();
101 return ret;
102 }
103
104 // 根据传递的assetChangeDatas更新相册,不需要dataManager_处理
RefreshAlbum(const vector<PhotoAssetChangeData> & assetChangeDatas,NotifyAlbumType notifyAlbumType,bool isRefreshWithDateModified)105 int32_t AssetAccurateRefresh::RefreshAlbum(const vector<PhotoAssetChangeData> &assetChangeDatas,
106 NotifyAlbumType notifyAlbumType, bool isRefreshWithDateModified)
107 {
108 if (assetChangeDatas.empty()) {
109 MEDIA_WARN_LOG("input asset change datas empty.");
110 DfxRefreshHander::SetEndTimeHander(dfxRefreshManager_);
111 return ACCURATE_REFRESH_INPUT_PARA_ERR;
112 }
113 auto diffCount = assetChangeDatas.size();
114 for (const auto &assetChangeData : assetChangeDatas) {
115 if (assetChangeData.infoBeforeChange_ != assetChangeData.infoAfterChange_) {
116 break;
117 }
118 diffCount--;
119 }
120 if (diffCount == 0) {
121 MEDIA_WARN_LOG("asset change datas are same, no need refresh album.");
122 DfxRefreshHander::SetEndTimeHander(dfxRefreshManager_);
123 return ACCURATE_REFRESH_RET_OK;
124 }
125 int32_t ret = albumRefreshExe_.RefreshAlbum(assetChangeDatas, notifyAlbumType, isRefreshWithDateModified);
126 return ret;
127 }
128
RefreshAlbumNoDateModified(NotifyAlbumType notifyAlbumType)129 int32_t AssetAccurateRefresh::RefreshAlbumNoDateModified(NotifyAlbumType notifyAlbumType)
130 {
131 return RefreshAlbum(notifyAlbumType, false);
132 }
133
134 // notify assest change infos based on init datas and modified datas.
Notify()135 int32_t AssetAccurateRefresh::Notify()
136 {
137 MediaLibraryTracer tracer;
138 tracer.Start("AssetAccurateRefresh::RefreshAlbum");
139 if (dataManager_.CheckIsForRecheck()) {
140 DfxRefreshHander::SetEndTimeHander(dfxRefreshManager_);
141 return NotifyForReCheck();
142 }
143 // 相册通知
144 albumRefreshExe_.Notify();
145
146 // 资产通知
147 return Notify(dataManager_.GetChangeDatas());
148 }
149
150 // 根据传递的assetChangeDatas进行通知,不需要dataManager_处理
Notify(const std::vector<PhotoAssetChangeData> & assetChangeDatas)151 int32_t AssetAccurateRefresh::Notify(const std::vector<PhotoAssetChangeData> &assetChangeDatas)
152 {
153 if (assetChangeDatas.empty()) {
154 MEDIA_WARN_LOG("assetChangeDatas empty.");
155 DfxRefreshHander::SetEndTimeHander(dfxRefreshManager_);
156 return ACCURATE_REFRESH_INPUT_PARA_ERR;
157 }
158
159 notifyExe_.Notify(assetChangeDatas);
160 DfxRefreshHander::SetEndTimeHander(dfxRefreshManager_);
161 return ACCURATE_REFRESH_RET_OK;
162 }
163
UpdateModifiedDatasInner(const std::vector<int> & fileIds,RdbOperation operation,PendingInfo pendingInfo)164 int32_t AssetAccurateRefresh::UpdateModifiedDatasInner(const std::vector<int> &fileIds, RdbOperation operation,
165 PendingInfo pendingInfo)
166 {
167 auto modifiedFileIds = fileIds;
168 if (modifiedFileIds.empty()) {
169 MEDIA_WARN_LOG("input modifiedFileIds empty.");
170 return ACCURATE_REFRESH_INPUT_PARA_ERR;
171 }
172
173 int32_t err = ACCURATE_REFRESH_RET_OK;
174 {
175 std::lock_guard<std::mutex> lock(assetQueryMutex_);
176 err = dataManager_.UpdateModifiedDatasInner(modifiedFileIds, operation, pendingInfo);
177 }
178 CHECK_AND_RETURN_RET_WARN_LOG(err == ACCURATE_REFRESH_RET_OK, err,
179 "UpdateModifiedDatasInner failed, err:%{public}d", err);
180 err = dataManager_.PostProcessModifiedDatas(modifiedFileIds);
181 CHECK_AND_RETURN_RET_WARN_LOG(err == ACCURATE_REFRESH_RET_OK, err,
182 "PostProcessModifiedDatas failed, err:%{public}d", err);
183 return ACCURATE_REFRESH_RET_OK;
184 }
185
UpdateModifiedDatas()186 int32_t AssetAccurateRefresh::UpdateModifiedDatas()
187 {
188 return dataManager_.UpdateModifiedDatas();
189 }
190
GetReturningKeyName()191 string AssetAccurateRefresh::GetReturningKeyName()
192 {
193 return PhotoColumn::MEDIA_ID;
194 }
195
LogicalDeleteReplaceByUpdate(MediaLibraryCommand & cmd,int32_t & deletedRows)196 int32_t AssetAccurateRefresh::LogicalDeleteReplaceByUpdate(MediaLibraryCommand &cmd, int32_t &deletedRows)
197 {
198 if (!IsValidTable(cmd.GetTableName())) {
199 return ACCURATE_REFRESH_RDB_INVALITD_TABLE;
200 }
201 return DeleteCommon([&](ValuesBucket &values) {
202 return Update(deletedRows, values, *(cmd.GetAbsRdbPredicates()), RDB_OPERATION_REMOVE);
203 });
204 }
205
LogicalDeleteReplaceByUpdate(const AbsRdbPredicates & predicates,int32_t & deletedRows)206 int32_t AssetAccurateRefresh::LogicalDeleteReplaceByUpdate(const AbsRdbPredicates &predicates, int32_t &deletedRows)
207 {
208 DfxRefreshHander::SetOperationStartTimeHander(dfxRefreshManager_);
209 if (!IsValidTable(predicates.GetTableName())) {
210 return ACCURATE_REFRESH_RDB_INVALITD_TABLE;
211 }
212 int32_t ret = DeleteCommon(
213 [&](ValuesBucket &values) { return Update(deletedRows, values, predicates, RDB_OPERATION_REMOVE); });
214 DfxRefreshHander::SetOptEndTimeHander(predicates, dfxRefreshManager_);
215 return ret;
216 }
217
DeleteCommon(function<int32_t (ValuesBucket &)> updateExe)218 int32_t AssetAccurateRefresh::DeleteCommon(function<int32_t(ValuesBucket &)> updateExe)
219 {
220 MediaLibraryTracer tracer;
221 tracer.Start("AssetAccurateRefresh::DeleteCommon");
222 ValuesBucket valuesBucket;
223 valuesBucket.PutInt(MEDIA_DATA_DB_DIRTY, static_cast<int32_t>(DirtyType::TYPE_DELETED));
224 valuesBucket.PutInt(MEDIA_DATA_DB_SYNC_STATUS, static_cast<int32_t>(SyncStatusType::TYPE_UPLOAD));
225 valuesBucket.PutLong(PhotoColumn::PHOTO_META_DATE_MODIFIED, MediaFileUtils::UTCTimeMilliSeconds());
226 auto ret = updateExe(valuesBucket);
227 if (ret != NativeRdb::E_OK) {
228 MEDIA_ERR_LOG("rdbStore_->Delete failed, ret = %{public}d", ret);
229 return E_HAS_DB_ERROR;
230 }
231
232 #ifndef MEDIA_REFRESH_TEST
233 if (!trans_) {
234 CloudSyncHelper::GetInstance()->StartSync();
235 ACCURATE_DEBUG("Delete update done, start sync.");
236 }
237 #endif
238
239 return ACCURATE_REFRESH_RET_OK;
240 }
241
IsValidTable(std::string tableName)242 bool AssetAccurateRefresh::IsValidTable(std::string tableName)
243 {
244 return PhotoColumn::PHOTOS_TABLE == tableName;
245 }
246
SetContentChanged(int32_t fileId,bool isChanged)247 int32_t AssetAccurateRefresh::SetContentChanged(int32_t fileId, bool isChanged)
248 {
249 return dataManager_.SetContentChanged(fileId, isChanged);
250 }
251
SetThumbnailStatus(int32_t fileId,int32_t status)252 int32_t AssetAccurateRefresh::SetThumbnailStatus(int32_t fileId, int32_t status)
253 {
254 // 函数调用错误
255 return dataManager_.SetThumbnailStatus(fileId, status);
256 }
257
NotifyForReCheck()258 int32_t AssetAccurateRefresh::NotifyForReCheck()
259 {
260 Notification::NotifyInfoInner notifyInfo;
261 notifyInfo.tableType = Notification::NotifyTableType::PHOTOS;
262 notifyInfo.operationType = Notification::ASSET_OPERATION_RECHECK;
263 Notification::MediaLibraryNotifyNew::AddItem(notifyInfo);
264 ACCURATE_DEBUG("asset recheck");
265 return ACCURATE_REFRESH_RET_OK;
266 }
267
RefreshAllAlbum(NotifyAlbumType notifyAlbumType,bool isRefreshWithDateModified)268 int32_t AssetAccurateRefresh::RefreshAllAlbum(NotifyAlbumType notifyAlbumType, bool isRefreshWithDateModified)
269 {
270 return albumRefreshExe_.RefreshAllAlbum(notifyAlbumType, isRefreshWithDateModified);
271 }
272 } // namespace Media::AccurateRefresh
273 } // namespace OHOS