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::AlbumChangeInfo"
17
18 #include <sstream>
19
20 #include "album_change_info.h"
21 #include "result_set_utils.h"
22 #include "media_file_utils.h"
23 #include "accurate_debug_log.h"
24
25 using namespace std;
26 using namespace OHOS::NativeRdb;
27
28 namespace OHOS {
29 namespace Media::AccurateRefresh {
30
31 const map<std::string, ResultSetDataType> AlbumChangeInfo::albumInfoCloumnTypes_ = {
32 { PhotoAlbumColumns::ALBUM_LPATH, TYPE_STRING },
33 { PhotoAlbumColumns::ALBUM_IMAGE_COUNT, TYPE_INT32 },
34 { PhotoAlbumColumns::ALBUM_VIDEO_COUNT, TYPE_INT32 },
35 { PhotoAlbumColumns::ALBUM_TYPE, TYPE_INT32 },
36 { PhotoAlbumColumns::ALBUM_SUBTYPE, TYPE_INT32 },
37 { PhotoAlbumColumns::ALBUM_NAME, TYPE_STRING },
38 { PhotoAlbumColumns::ALBUM_COUNT, TYPE_INT32 },
39 { PhotoAlbumColumns::ALBUM_COVER_URI, TYPE_STRING },
40 { PhotoAlbumColumns::HIDDEN_COUNT, TYPE_INT32 },
41 { PhotoAlbumColumns::HIDDEN_COVER, TYPE_STRING },
42 { PhotoAlbumColumns::ALBUM_ID, TYPE_INT32 },
43 { PhotoAlbumColumns::COVER_DATE_TIME, TYPE_INT64 },
44 { PhotoAlbumColumns::HIDDEN_COVER_DATE_TIME, TYPE_INT64 },
45 { PhotoAlbumColumns::ALBUM_DIRTY, TYPE_INT32 },
46 { PhotoAlbumColumns::COVER_URI_SOURCE, TYPE_INT32 },
47 { PhotoAlbumColumns::ALBUM_ORDER, TYPE_INT32 },
48 { PhotoAlbumColumns::ORDER_SECTION, TYPE_INT32},
49 };
50
__anon91bceb070102() 51 const vector<std::string> AlbumChangeInfo::albumInfoColumns_ = []() {
52 vector<string> result;
53 for (const auto &item : albumInfoCloumnTypes_) {
54 result.push_back(item.first);
55 }
56 return result;
57 }();
58
GetAlbumInfoColumns()59 const std::vector<std::string>& AlbumChangeInfo::GetAlbumInfoColumns()
60 {
61 return albumInfoColumns_;
62 }
63
GetInfoFromResult(const shared_ptr<NativeRdb::ResultSet> & resultSet,const std::vector<std::string> & columns)64 vector<AlbumChangeInfo> AlbumChangeInfo::GetInfoFromResult(
65 const shared_ptr<NativeRdb::ResultSet> &resultSet, const std::vector<std::string> &columns)
66 {
67 vector<AlbumChangeInfo> albumChangeInfos;
68 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
69 AlbumChangeInfo albumChangeInfo;
70 albumChangeInfo.lpath_ = get<string>(ResultSetUtils::GetValFromColumn(
71 PhotoAlbumColumns::ALBUM_LPATH, resultSet, GetDataType(PhotoAlbumColumns::ALBUM_LPATH)));
72 albumChangeInfo.imageCount_ = get<int32_t>(ResultSetUtils::GetValFromColumn(
73 PhotoAlbumColumns::ALBUM_IMAGE_COUNT, resultSet, GetDataType(PhotoAlbumColumns::ALBUM_IMAGE_COUNT)));
74 albumChangeInfo.videoCount_ = get<int32_t>(ResultSetUtils::GetValFromColumn(
75 PhotoAlbumColumns::ALBUM_VIDEO_COUNT, resultSet, GetDataType(PhotoAlbumColumns::ALBUM_VIDEO_COUNT)));
76 albumChangeInfo.albumType_ = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_TYPE,
77 resultSet, GetDataType(PhotoAlbumColumns::ALBUM_TYPE)));
78 albumChangeInfo.albumSubType_ = get<int32_t>(ResultSetUtils::GetValFromColumn(
79 PhotoAlbumColumns::ALBUM_SUBTYPE, resultSet, GetDataType(PhotoAlbumColumns::ALBUM_SUBTYPE)));
80 albumChangeInfo.albumName_ = get<string>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_NAME,
81 resultSet, GetDataType(PhotoAlbumColumns::ALBUM_NAME)));
82 albumChangeInfo.count_ = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_COUNT,
83 resultSet, GetDataType(PhotoAlbumColumns::ALBUM_COUNT)));
84 albumChangeInfo.coverUri_ = get<string>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_COVER_URI,
85 resultSet, GetDataType(PhotoAlbumColumns::ALBUM_COVER_URI)));
86 albumChangeInfo.hiddenCount_ = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::HIDDEN_COUNT,
87 resultSet, GetDataType(PhotoAlbumColumns::HIDDEN_COUNT)));
88 albumChangeInfo.hiddenCoverUri_ = get<string>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::HIDDEN_COVER,
89 resultSet, GetDataType(PhotoAlbumColumns::HIDDEN_COVER)));
90 albumChangeInfo.albumId_ = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_ID,
91 resultSet, GetDataType(PhotoAlbumColumns::ALBUM_ID)));
92 albumChangeInfo.albumUri_ = MediaFileUtils::GetUriByExtrConditions(PhotoAlbumColumns::ALBUM_URI_PREFIX,
93 to_string(albumChangeInfo.albumId_));
94 albumChangeInfo.coverDateTime_ = get<int64_t>(ResultSetUtils::GetValFromColumn(
95 PhotoAlbumColumns::COVER_DATE_TIME, resultSet, GetDataType(PhotoAlbumColumns::COVER_DATE_TIME)));
96 albumChangeInfo.hiddenCoverDateTime_ = get<int64_t>(ResultSetUtils::GetValFromColumn(
97 PhotoAlbumColumns::HIDDEN_COVER_DATE_TIME, resultSet,
98 GetDataType(PhotoAlbumColumns::HIDDEN_COVER_DATE_TIME)));
99 albumChangeInfo.dirty_ = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_DIRTY,
100 resultSet, GetDataType(PhotoAlbumColumns::ALBUM_DIRTY)));
101 albumChangeInfo.coverUriSource_ = get<int32_t>(ResultSetUtils::GetValFromColumn(
102 PhotoAlbumColumns::COVER_URI_SOURCE, resultSet, GetDataType(PhotoAlbumColumns::COVER_URI_SOURCE)));
103 albumChangeInfo.orderSection_ = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_ORDER,
104 resultSet, GetDataType(PhotoAlbumColumns::ALBUMS_ORDER)));
105 albumChangeInfo.albumOrder_ = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ORDER_SECTION,
106 resultSet, GetDataType(PhotoAlbumColumns::ORDER_SECTION)));
107 albumChangeInfos.push_back(albumChangeInfo);
108 }
109
110 return albumChangeInfos;
111 }
112
ToString(bool isDetail) const113 string AlbumChangeInfo::ToString(bool isDetail) const
114 {
115 stringstream ss;
116 if (isDetail) {
117 ss << "albumId_: " << albumId_ << ", albumSubType_: "<< albumSubType_ << ", count_: " << count_;
118 ss << ", imageCount_: " << imageCount_ << ", videoCount_: " << videoCount_;
119 ss << ", hiddenCount_: " << hiddenCount_ << ", albumType_: " << albumType_ << ", albumName_: " << albumName_;
120 ss << ", albumUri_: " << albumUri_ << ", coverUri_: " << MediaFileUtils::DesensitizeUri(coverUri_);
121 ss << ", hiddenCoverUri_: " << MediaFileUtils::DesensitizeUri(hiddenCoverUri_);
122 ss << ", isCoverChange_: " << isCoverChange_ << ", isHiddenCoverChange_: " << isHiddenCoverChange_;
123 ss << ", coverDateTime_: " << coverDateTime_ << ", hiddenCoverDateTime_: " << hiddenCoverDateTime_;
124 ss << ", dirty_: " << dirty_ << ", coverUriSource_: " << coverUriSource_;
125 ss << ", albumOrder_: " << albumOrder_ << ", orderSection_ " << orderSection_;
126 if (isCoverChange_) {
127 ss << ", cover info: " << coverInfo_.ToString().c_str();
128 }
129 if (isHiddenCoverChange_) {
130 ss << ", hidden cover info: " << hiddenCoverInfo_.ToString().c_str();
131 }
132 } else {
133 ss << "albumId_: " << albumId_ << ", albumSubType_: "<< albumSubType_;
134 }
135
136 return ss.str();
137 }
138
GetDataType(const std::string & column)139 ResultSetDataType AlbumChangeInfo::GetDataType(const std::string &column)
140 {
141 auto const &item = albumInfoCloumnTypes_.find(column);
142 if (item == albumInfoCloumnTypes_.end()) {
143 return TYPE_NULL;
144 }
145 return item->second;
146 }
147
GetUpdateValues(const AlbumChangeInfo & oldAlbumInfo,NotifyType & type)148 ValuesBucket AlbumChangeInfo::GetUpdateValues(const AlbumChangeInfo &oldAlbumInfo, NotifyType &type)
149 {
150 stringstream ss;
151 ValuesBucket values;
152 if (imageCount_ != oldAlbumInfo.imageCount_ && imageCount_ != INVALID_INT32_VALUE) {
153 values.PutInt(PhotoAlbumColumns::ALBUM_IMAGE_COUNT, imageCount_);
154 ss << "imageCount_: " << oldAlbumInfo.imageCount_ << " -> " << imageCount_ << ", ";
155 }
156 if (videoCount_ != oldAlbumInfo.videoCount_ && videoCount_ != INVALID_INT32_VALUE) {
157 values.PutInt(PhotoAlbumColumns::ALBUM_VIDEO_COUNT, videoCount_);
158 ss << "videoCount_: " << oldAlbumInfo.videoCount_ << " -> " << videoCount_ << ", ";
159 }
160 if (count_ != oldAlbumInfo.count_ && count_ != INVALID_INT32_VALUE) {
161 values.PutInt(PhotoAlbumColumns::ALBUM_COUNT, count_);
162 ss << "count_: " << oldAlbumInfo.count_ << " -> " << count_ << ", ";
163 }
164 if (hiddenCount_ != oldAlbumInfo.hiddenCount_ && hiddenCount_ != INVALID_INT32_VALUE) {
165 values.PutInt(PhotoAlbumColumns::HIDDEN_COUNT, hiddenCount_);
166 ss << "hiddenCount_: " << oldAlbumInfo.hiddenCount_ << " -> " << hiddenCount_ << ", ";
167 values.PutInt(PhotoAlbumColumns::CONTAINS_HIDDEN, hiddenCount_ != 0);
168 ss << "contains_hidden: true, ";
169 }
170 if (coverUri_ != oldAlbumInfo.coverUri_ && coverUri_ != EMPTY_STR) {
171 values.PutString(PhotoAlbumColumns::ALBUM_COVER_URI, coverUri_);
172 ss << "coverUri_: " << MediaFileUtils::DesensitizeUri(oldAlbumInfo.coverUri_) << " -> ";
173 ss << MediaFileUtils::DesensitizeUri(coverUri_) << ", ";
174 }
175 if (hiddenCoverUri_ != oldAlbumInfo.hiddenCoverUri_ && hiddenCoverUri_ != EMPTY_STR) {
176 values.PutString(PhotoAlbumColumns::HIDDEN_COVER, hiddenCoverUri_);
177 ss << "hiddenCoverUri_: " << MediaFileUtils::DesensitizeUri(oldAlbumInfo.hiddenCoverUri_) << " -> ";
178 ss << MediaFileUtils::DesensitizeUri(hiddenCoverUri_) << ", ";
179 }
180 if (coverDateTime_ != oldAlbumInfo.coverDateTime_ && coverDateTime_ != INVALID_INT64_VALUE) {
181 values.PutLong(PhotoAlbumColumns::COVER_DATE_TIME, coverDateTime_);
182 ss << "coverDateTime_: " << oldAlbumInfo.coverDateTime_ << " -> " << coverDateTime_ << ", ";
183 }
184 if (hiddenCoverDateTime_ != oldAlbumInfo.hiddenCoverDateTime_ && hiddenCoverDateTime_ != INVALID_INT64_VALUE) {
185 values.PutLong(PhotoAlbumColumns::HIDDEN_COVER_DATE_TIME, hiddenCoverDateTime_);
186 ss << "hiddenCoverDateTime_: " << oldAlbumInfo.hiddenCoverDateTime_ << " -> " << hiddenCoverDateTime_;
187 }
188
189 type = oldAlbumInfo.count_ < count_ ? NOTIFY_ALBUM_ADD_ASSET :
190 (oldAlbumInfo.count_ > count_ ? NOTIFY_ALBUM_REMOVE_ASSET : NOTIFY_UPDATE);
191 ACCURATE_INFO("Update albumInfo[%{public}d], notifyType[%{public}d]: %{public}s", oldAlbumInfo.albumId_,
192 static_cast<int32_t>(type), ss.str().c_str());
193 return values;
194 }
195
Marshalling(Parcel & parcel) const196 bool AlbumChangeInfo::Marshalling(Parcel &parcel) const
197 {
198 return Marshalling(parcel, false);
199 }
200
Marshalling(Parcel & parcel,bool isSystem) const201 bool AlbumChangeInfo::Marshalling(Parcel &parcel, bool isSystem) const
202 {
203 bool isValid = albumId_ != INVALID_INT32_VALUE;
204 bool ret = parcel.WriteBool(isValid);
205 if (ret && !isValid) {
206 return ret;
207 }
208 ret = ret && parcel.WriteInt32(imageCount_);
209 ret = ret && parcel.WriteInt32(videoCount_);
210 ret = ret && parcel.WriteInt32(albumType_);
211 ret = ret && parcel.WriteInt32(albumSubType_);
212 ret = ret && parcel.WriteString(albumName_);
213 ret = ret && parcel.WriteString(albumUri_);
214 ret = ret && parcel.WriteInt32(count_);
215 ret = ret && parcel.WriteString(coverUri_);
216 ret = ret && parcel.WriteBool(isSystem);
217 if (isSystem) {
218 ret = ret && parcel.WriteInt32(hiddenCount_);
219 ret = ret && parcel.WriteString(hiddenCoverUri_);
220 ret = ret && parcel.WriteBool(isCoverChange_);
221 if (isCoverChange_) {
222 ret = ret && coverInfo_.Marshalling(parcel, isSystem);
223 }
224
225 ret = ret && parcel.WriteBool(isHiddenCoverChange_);
226 if (isHiddenCoverChange_) {
227 ret = ret && hiddenCoverInfo_.Marshalling(parcel, isSystem);
228 }
229 ret = ret && parcel.WriteInt32(orderSection_);
230 ret = ret && parcel.WriteInt32(albumOrder_);
231 }
232 ret = ret && parcel.WriteInt32(albumId_);
233 return ret;
234 }
235
ReadFromParcel(Parcel & parcel)236 bool AlbumChangeInfo::ReadFromParcel(Parcel &parcel)
237 {
238 bool isValid = false;
239 bool ret = parcel.ReadBool(isValid);
240 if (ret && !isValid) {
241 return ret;
242 }
243 ret = ret && parcel.ReadInt32(imageCount_);
244 ret = ret && parcel.ReadInt32(videoCount_);
245 ret = ret && parcel.ReadInt32(albumType_);
246 ret = ret && parcel.ReadInt32(albumSubType_);
247 ret = ret && parcel.ReadString(albumName_);
248 ret = ret && parcel.ReadString(albumUri_);
249 ret = ret && parcel.ReadInt32(count_);
250 ret = ret && parcel.ReadString(coverUri_);
251 ret = ret && parcel.ReadBool(isSystem_);
252 if (isSystem_) {
253 ret = ret && parcel.ReadInt32(hiddenCount_);
254 ret = ret && parcel.ReadString(hiddenCoverUri_);
255 ret = ret && parcel.ReadBool(isCoverChange_);
256 if (ret && isCoverChange_) {
257 ret = ret && coverInfo_.ReadFromParcel(parcel);
258 }
259 ret = ret && parcel.ReadBool(isHiddenCoverChange_);
260 if (ret && isHiddenCoverChange_) {
261 ret = ret && hiddenCoverInfo_.ReadFromParcel(parcel);
262 }
263 ret = ret && parcel.ReadInt32(orderSection_);
264 ret = ret && parcel.ReadInt32(albumOrder_);
265 }
266 ret = ret && parcel.ReadInt32(albumId_);
267 return ret;
268 }
269
Unmarshalling(Parcel & parcel)270 shared_ptr<AlbumChangeInfo> AlbumChangeInfo::Unmarshalling(Parcel &parcel)
271 {
272 shared_ptr<AlbumChangeInfo> albumChangeInfo = make_shared<AlbumChangeInfo>();
273 if (albumChangeInfo->ReadFromParcel(parcel)) {
274 return albumChangeInfo;
275 }
276 return nullptr;
277 }
278
279 template <typename T>
GetDiff(const T & value,const T & compareValue,const std::string & name,std::stringstream & ss)280 void GetDiff(const T &value, const T &compareValue, const std::string &name, std::stringstream &ss)
281 {
282 if (value != compareValue) {
283 ss << name << ": " << value << " -> " << compareValue << ", ";
284 }
285 }
286 #define GET_ALBUM_DIFF(member) GetDiff(album.member, compare.member, #member, ss)
GetAlbumDiff(const AlbumChangeInfo & album,const AlbumChangeInfo & compare)287 string AlbumChangeInfo::GetAlbumDiff(const AlbumChangeInfo &album, const AlbumChangeInfo &compare)
288 {
289 stringstream ss;
290 if (album.albumId_ != compare.albumId_) {
291 ss << "diff album info albumId: " << album.albumId_ << ", compare albumId: " << compare.albumId_;
292 return ss.str();
293 }
294 ss << "albumId[" << album.albumId_ << "]: ";
295 GET_ALBUM_DIFF(lpath_);
296 GET_ALBUM_DIFF(imageCount_);
297 GET_ALBUM_DIFF(videoCount_);
298 GET_ALBUM_DIFF(albumType_);
299 GET_ALBUM_DIFF(albumSubType_);
300 GET_ALBUM_DIFF(albumName_);
301 GET_ALBUM_DIFF(albumUri_);
302 GET_ALBUM_DIFF(count_);
303 GET_ALBUM_DIFF(hiddenCount_);
304 GET_ALBUM_DIFF(isCoverChange_);
305 GET_ALBUM_DIFF(isHiddenCoverChange_);
306 GET_ALBUM_DIFF(coverDateTime_);
307 GET_ALBUM_DIFF(hiddenCoverDateTime_);
308 GET_ALBUM_DIFF(dirty_);
309 GET_ALBUM_DIFF(coverUriSource_);
310 GET_ALBUM_DIFF(albumOrder_);
311 GET_ALBUM_DIFF(orderSection_);
312
313 if (album.coverUri_ != compare.coverUri_) {
314 ss << "coverUri_: " << MediaFileUtils::DesensitizeUri(album.coverUri_) << " -> ";
315 ss << MediaFileUtils::DesensitizeUri(compare.coverUri_) << ", ";
316 }
317
318 if (album.hiddenCoverUri_ != compare.hiddenCoverUri_) {
319 ss << "hiddenCoverUri_: " << MediaFileUtils::DesensitizeUri(album.hiddenCoverUri_) << " -> ";
320 ss << MediaFileUtils::DesensitizeUri(compare.hiddenCoverUri_);
321 }
322 return ss.str();
323 }
GetDataDiff(const AlbumChangeInfo & compare)324 string AlbumChangeInfo::GetDataDiff(const AlbumChangeInfo &compare)
325 {
326 return GetAlbumDiff(*this, compare);
327 }
328
Unmarshalling(Parcel & parcel)329 shared_ptr<AlbumChangeData> AlbumChangeData::Unmarshalling(Parcel &parcel)
330 {
331 shared_ptr<AlbumChangeData> albumChangeData = make_shared<AlbumChangeData>();
332 if (albumChangeData->ReadFromParcel(parcel)) {
333 return albumChangeData;
334 }
335 return nullptr;
336 }
337
IsAlbumInfoChange()338 bool AlbumChangeData::IsAlbumInfoChange()
339 {
340 return infoAfterChange_.isCoverChange_ || (!IsAlbumHiddenInfoChange()) ||
341 (infoBeforeChange_.imageCount_ != infoAfterChange_.imageCount_) ||
342 (infoBeforeChange_.videoCount_ != infoAfterChange_.videoCount_) ||
343 (infoBeforeChange_.count_ != infoAfterChange_.count_) ||
344 (infoBeforeChange_.lpath_ != infoAfterChange_.lpath_) ||
345 (infoBeforeChange_.albumName_ != infoAfterChange_.albumName_) ||
346 (infoBeforeChange_.dirty_ != infoAfterChange_.dirty_) ||
347 (infoBeforeChange_.albumOrder_ != infoAfterChange_.albumOrder_) ||
348 (infoBeforeChange_.orderSection_ != infoAfterChange_.orderSection_);
349 }
350
IsAlbumHiddenInfoChange()351 bool AlbumChangeData::IsAlbumHiddenInfoChange()
352 {
353 return infoAfterChange_.isHiddenCoverChange_ || (infoBeforeChange_.hiddenCount_ != infoAfterChange_.hiddenCount_);
354 }
355
ToString() const356 string AlbumRefreshInfo::ToString() const
357 {
358 stringstream ss;
359 if (IsAlbumInfoRefresh()) {
360 ss << "deltaCount_: " << deltaCount_ << ", deltaVideoCount_: " << deltaVideoCount_;
361 ss << ", deltaAddCover_ fileId: " << deltaAddCover_.fileId_ << ", remove asset size: " << removeFileIds.size();
362 ss << ", assetModifiedCnt_: " << assetModifiedCnt_;
363 ss << ", album timestamp: " << albumRefreshTimestamp_.ToString();
364 }
365 if (IsAlbumHiddenInfoRefresh()) {
366 ss << ", deltaHiddenCount_: " << deltaHiddenCount_ << ", deltaAddHiddenCover_ fileId: ";
367 ss << deltaAddHiddenCover_.fileId_ << ", remove hidden asset size: " << removeHiddenFileIds.size();
368 ss << ", hiddenAssetModifiedCnt_: " << hiddenAssetModifiedCnt_;
369 ss << ", album hidden timestamp: " << albumHiddenRefreshTimestamp_.ToString();
370 }
371 if (isForceRefresh_) {
372 ss << ", isForceRefresh_: " << isForceRefresh_;
373 }
374 if (isHiddenForceRefresh_) {
375 ss << ", isHiddenForceRefresh_: " << isHiddenForceRefresh_;
376 }
377
378 return ss.str();
379 }
380
381 } // namespace Media
382 } // namespace OHOS
383