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::AssetDataManager"
17
18 #include <sstream>
19
20 #include "asset_data_manager.h"
21 #include "medialibrary_unistore_manager.h"
22 #include "accurate_debug_log.h"
23 #include "medialibrary_tracer.h"
24 #include "media_file_utils.h"
25
26 using namespace std;
27 using namespace OHOS::NativeRdb;
28
29 namespace OHOS {
30 namespace Media::AccurateRefresh {
31
~AssetDataManager()32 AssetDataManager::~AssetDataManager()
33 {
34 ClearMultiThreadChangeDatas();
35 }
36
UpdateModifiedDatas()37 int32_t AssetDataManager::UpdateModifiedDatas()
38 {
39 return ACCURATE_REFRESH_RET_OK;
40 }
41
PostProcessModifiedDatas(const std::vector<int32_t> & keys)42 int32_t AssetDataManager::PostProcessModifiedDatas(const std::vector<int32_t> &keys)
43 {
44 ACCURATE_DEBUG("keys size: %{public}zu", keys.size());
45 for (auto key : keys) {
46 auto iter = changeDatas_.find(key);
47 if (iter == changeDatas_.end()) {
48 MEDIA_WARN_LOG("not init info for update common modified data.");
49 continue;
50 }
51 PhotoAssetChangeData &assetChangeData = iter->second;
52 assetChangeData.thumbnailChangeStatus_ = UpdateThumbnailChangeStatus(assetChangeData);
53 assetChangeData.isContentChanged_ =
54 assetChangeData.thumbnailChangeStatus_ == ThumbnailChangeStatus::THUMBNAIL_UPDATE;
55 }
56 return ACCURATE_REFRESH_RET_OK;
57 }
58
UpdateThumbnailChangeStatus(PhotoAssetChangeData & assetChangeData)59 int32_t AssetDataManager::UpdateThumbnailChangeStatus(PhotoAssetChangeData &assetChangeData)
60 {
61 int32_t visibleAfter = assetChangeData.infoAfterChange_.thumbnailVisible_;
62 int32_t visibleBefore = assetChangeData.infoBeforeChange_.thumbnailVisible_;
63 int64_t readyBefore = assetChangeData.infoBeforeChange_.thumbnailReady_;
64 int64_t readyAfter = assetChangeData.infoAfterChange_.thumbnailReady_;
65 MEDIA_DEBUG_LOG("UpdateThumbnailChangeStatus visibleBefore: %{public}d, visibleAfter: %{public}d, "
66 "readyBefore: %{public}" PRId64 ", readyAfter: %{public}" PRId64,
67 visibleBefore, visibleAfter, readyBefore, readyAfter);
68 if (visibleAfter == 0 || visibleAfter == INVALID_INT32_VALUE) {
69 return ThumbnailChangeStatus::THUMBNAIL_NOT_EXISTS;
70 }
71 if (visibleBefore != visibleAfter) {
72 return ThumbnailChangeStatus::THUMBNAIL_ADD;
73 }
74 if (readyBefore == readyAfter) {
75 return ThumbnailChangeStatus::THUMBNAIL_NOT_CHANGE;
76 } else {
77 return ThumbnailChangeStatus::THUMBNAIL_UPDATE;
78 }
79 }
80
GetChangeInfoKey(const PhotoAssetChangeInfo & changeInfo)81 int32_t AssetDataManager::GetChangeInfoKey(const PhotoAssetChangeInfo &changeInfo)
82 {
83 return changeInfo.fileId_;
84 }
85
GetInfoByKeys(const std::vector<int32_t> & fileIds)86 std::vector<PhotoAssetChangeInfo> AssetDataManager::GetInfoByKeys(const std::vector<int32_t> &fileIds)
87 {
88 AbsRdbPredicates rbdPredicates(PhotoColumn::PHOTOS_TABLE);
89 vector<string> fileIdStrs;
90 for (const auto &fileId : fileIds) {
91 fileIdStrs.push_back(to_string(fileId));
92 }
93 rbdPredicates.In(PhotoColumn::MEDIA_ID, fileIdStrs);
94 return GetInfosByPredicates(rbdPredicates);
95 }
96
GetInfosByPredicates(const AbsRdbPredicates & predicates)97 vector<PhotoAssetChangeInfo> AssetDataManager::GetInfosByPredicates(const AbsRdbPredicates &predicates)
98 {
99 MediaLibraryTracer tracer;
100 tracer.Start("AssetDataManager::GetInfosByPredicates");
101 shared_ptr<ResultSet> resultSet;
102 if (CanTransOperate()) {
103 resultSet = trans_->QueryByStep(predicates, PhotoAssetChangeInfo::GetPhotoAssetColumns());
104 } else {
105 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
106 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, vector<PhotoAssetChangeInfo>(), "rdbStore null");
107 resultSet = rdbStore->QueryByStep(predicates, PhotoAssetChangeInfo::GetPhotoAssetColumns());
108 }
109 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, vector<PhotoAssetChangeInfo>(), "resultSet null");
110 auto ret = GetInfosByResult(resultSet);
111 resultSet->Close();
112 return ret;
113 }
114
GetInfosByResult(const shared_ptr<ResultSet> & resultSet)115 vector<PhotoAssetChangeInfo> AssetDataManager::GetInfosByResult(const shared_ptr<ResultSet> &resultSet)
116 {
117 // 根据resultSet转PhotoAssetChangeInfo
118 return PhotoAssetChangeInfo::GetInfoFromResult(resultSet, PhotoAssetChangeInfo::GetPhotoAssetColumns());
119 }
120
GetInitKeys()121 vector<int32_t> AssetDataManager::GetInitKeys()
122 {
123 stringstream ss;
124 ss << "GetInitKeys:";
125 vector<int32_t> fileIds;
126 for (auto &changeData : changeDatas_) {
127 fileIds.push_back(changeData.first);
128 ss << " " << changeData.first;
129 }
130
131 ACCURATE_DEBUG("%{public}s", ss.str().c_str());
132 return fileIds;
133 }
134
SetContentChanged(int32_t fileId,bool isChanged)135 int32_t AssetDataManager::SetContentChanged(int32_t fileId, bool isChanged)
136 {
137 auto iter = contentInfos.find(fileId);
138 if (iter == contentInfos.end()) {
139 PhotoAssetContentInfo contentInfo;
140 contentInfo.isContentChanged_ = isChanged;
141 contentInfos.emplace(fileId, contentInfo);
142 ACCURATE_DEBUG("add fileId: %{public}d, isChanged %{public}d", fileId, isChanged);
143 } else {
144 iter->second.isContentChanged_ = isChanged;
145 ACCURATE_DEBUG("update fileId: %{public}d, isChanged %{public}d", fileId, isChanged);
146 }
147 return ACCURATE_REFRESH_RET_OK;
148 }
149
SetThumbnailStatus(int32_t fileId,int32_t status)150 int32_t AssetDataManager::SetThumbnailStatus(int32_t fileId, int32_t status)
151 {
152 auto iter = contentInfos.find(fileId);
153 if (iter == contentInfos.end()) {
154 PhotoAssetContentInfo contentInfo;
155 contentInfo.thumbnailChangeStatus_ = status;
156 contentInfos.emplace(fileId, contentInfo);
157 ACCURATE_DEBUG("add fileId: %{public}d, status: %{public}d", fileId, status);
158 } else {
159 iter->second.thumbnailChangeStatus_ = status;
160 ACCURATE_DEBUG("update fileId: %{public}d, status: %{public}d", fileId, status);
161 }
162 return ACCURATE_REFRESH_RET_OK;
163 }
164
UpdateNotifyInfo()165 int32_t AssetDataManager::UpdateNotifyInfo()
166 {
167 for (auto const &contentInfo : contentInfos) {
168 auto fileId = contentInfo.first;
169 const PhotoAssetContentInfo &content = contentInfo.second;
170 auto iter = changeDatas_.find(fileId);
171 if (iter == changeDatas_.end()) {
172 MEDIA_ERR_LOG("no changeDatas: %{public}d.", fileId);
173 continue;
174 }
175 iter->second.isContentChanged_ = content.isContentChanged_;
176 iter->second.thumbnailChangeStatus_ = content.thumbnailChangeStatus_;
177 ACCURATE_DEBUG("update fileId:%{public}d, content(%{public}d, %{public}d)", fileId, content.isContentChanged_,
178 content.thumbnailChangeStatus_);
179 }
180 return ACCURATE_REFRESH_RET_OK;
181 }
182
PostInsertBeforeData(PhotoAssetChangeData & changeData,PendingInfo & pendingInfo)183 void AssetDataManager::PostInsertBeforeData(PhotoAssetChangeData &changeData, PendingInfo &pendingInfo)
184 {
185 UpdatePendingInfo(changeData, pendingInfo);
186 if (changeData.infoBeforeChange_.fileId_ == INVALID_INT32_VALUE) {
187 MEDIA_ERR_LOG("invalid fileId");
188 return;
189 }
190
191 MultiThreadAssetChangeInfoMgr::GetInstance().CheckInsertBeforeInfo(changeData.infoBeforeChange_);
192 }
193
PostInsertAfterData(PhotoAssetChangeData & changeData,PendingInfo & pendingInfo,bool isAdd)194 void AssetDataManager::PostInsertAfterData(PhotoAssetChangeData &changeData, PendingInfo &pendingInfo, bool isAdd)
195 {
196 UpdatePendingInfo(changeData, pendingInfo);
197 if (changeData.infoAfterChange_.fileId_ == INVALID_INT32_VALUE) {
198 MEDIA_ERR_LOG("invalid fileId");
199 return;
200 }
201 if (MultiThreadAssetChangeInfoMgr::GetInstance().CheckInsertAfterInfo(changeData.infoAfterChange_, isAdd)) {
202 multiThreadAssetIds_.insert(changeData.infoAfterChange_.fileId_);
203 changeData.isMultiOperation_ = true;
204 }
205 }
206
CheckUpdateDataForMultiThread(PhotoAssetChangeData & changeData)207 bool AssetDataManager::CheckUpdateDataForMultiThread(PhotoAssetChangeData &changeData)
208 {
209 if (!changeData.isMultiOperation_) {
210 return false;
211 }
212 auto infos = MultiThreadAssetChangeInfoMgr::GetInstance().GetAndUpdateAssetChangeData(changeData.GetFileId());
213 changeData.infoBeforeChange_ = infos.first;
214 changeData.infoAfterChange_ = infos.second;
215 changeData.isMultiOperation_ = false;
216 ClearMultiThreadChangeData(changeData.GetFileId());
217 return true;
218 }
219
ClearMultiThreadChangeData(int32_t fileId)220 void AssetDataManager::ClearMultiThreadChangeData(int32_t fileId)
221 {
222 MultiThreadAssetChangeInfoMgr::GetInstance().ClearMultiThreadChangeData(fileId);
223 multiThreadAssetIds_.erase(fileId);
224 }
225
ClearMultiThreadChangeDatas()226 void AssetDataManager::ClearMultiThreadChangeDatas()
227 {
228 if (multiThreadAssetIds_.empty()) {
229 return;
230 }
231 for (auto fileId : multiThreadAssetIds_) {
232 MultiThreadAssetChangeInfoMgr::GetInstance().ClearMultiThreadChangeData(fileId);
233 }
234 multiThreadAssetIds_.clear();
235 }
236
UpdatePendingInfo(PhotoAssetChangeData & changeData,PendingInfo & pendingInfo)237 void AssetDataManager::UpdatePendingInfo(PhotoAssetChangeData &changeData, PendingInfo &pendingInfo)
238 {
239 if (pendingInfo.start_ != INVALID_INT64_VALUE && changeData.infoBeforeChange_.timestamp_ == INVALID_INT64_VALUE) {
240 changeData.infoBeforeChange_.timestamp_ = pendingInfo.start_;
241 }
242 if (pendingInfo.end_ != INVALID_INT64_VALUE && changeData.infoAfterChange_.timestamp_ == INVALID_INT64_VALUE) {
243 changeData.infoAfterChange_.timestamp_ = pendingInfo.end_;
244 }
245 ACCURATE_DEBUG("start[%{public}" PRId64 "], end[%{public}" PRId64 "], pendingInfo[%{public}" PRId64 \
246 ", %{public}" PRId64 "]", changeData.infoBeforeChange_.timestamp_, changeData.infoAfterChange_.timestamp_,
247 pendingInfo.start_, pendingInfo.end_);
248 }
249
250 } // namespace Media
251 } // namespace OHOS
252