• 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 
16 #define MLOG_TAG "AccurateRefresh::AlbumAccurateRefresh"
17 #include <cstdint>
18 
19 #ifndef MEDIA_REFRESH_TEST
20     #include "cloud_sync_helper.h"
21 #endif
22 
23 #include "medialibrary_errno.h"
24 #include "album_accurate_refresh.h"
25 #include "medialibrary_notify_new.h"
26 #include "accurate_debug_log.h"
27 #include "medialibrary_tracer.h"
28 #include "dfx_refresh_hander.h"
29 #include "result_set_utils.h"
30 #include "medialibrary_type_const.h"
31 #include "medialibrary_unistore_manager.h"
32 
33 using namespace std;
34 using namespace OHOS::NativeRdb;
35 
36 namespace OHOS {
37 namespace Media::AccurateRefresh {
38 
AlbumAccurateRefresh(const std::string & targetBusiness,std::shared_ptr<TransactionOperations> trans)39 AlbumAccurateRefresh::AlbumAccurateRefresh(const std::string &targetBusiness,
40     std::shared_ptr<TransactionOperations> trans) : AccurateRefreshBase(targetBusiness, trans)
41 {
42     dataManager_.SetTransaction(trans);
43 }
44 
AlbumAccurateRefresh(std::shared_ptr<TransactionOperations> trans)45 AlbumAccurateRefresh::AlbumAccurateRefresh(std::shared_ptr<TransactionOperations> trans) : AccurateRefreshBase(trans)
46 {
47     dataManager_.SetTransaction(trans);
48 }
49 
Init()50 int32_t AlbumAccurateRefresh::Init()
51 {
52     return ACCURATE_REFRESH_RET_OK;
53 }
54 
Init(const AbsRdbPredicates & predicates)55 int32_t AlbumAccurateRefresh::Init(const AbsRdbPredicates &predicates)
56 {
57     if (!IsValidTable(predicates.GetTableName())) {
58         return ACCURATE_REFRESH_RDB_INVALITD_TABLE;
59     }
60 
61     return dataManager_.Init(predicates);
62 }
63 
Init(const string & sql,const vector<ValueObject> bindArgs)64 int32_t AlbumAccurateRefresh::Init(const string &sql, const vector<ValueObject> bindArgs)
65 {
66     return dataManager_.Init(sql, bindArgs);
67 }
68 
Init(const std::vector<int32_t> & albumIds)69 int32_t AlbumAccurateRefresh::Init(const std::vector<int32_t> &albumIds)
70 {
71     return dataManager_.InitAlbumInfos(albumIds);
72 }
73 
Notify(std::shared_ptr<DfxRefreshManager> dfxRefreshManager)74 int32_t AlbumAccurateRefresh::Notify(std::shared_ptr<DfxRefreshManager> dfxRefreshManager)
75 {
76     if (dataManager_.CheckIsForRecheck()) {
77         return NotifyForReCheck();
78     }
79     return Notify(dataManager_.GetChangeDatas(), dfxRefreshManager);
80 }
81 
Notify(vector<AlbumChangeData> albumChangeDatas,std::shared_ptr<DfxRefreshManager> dfxRefreshManager)82 int32_t AlbumAccurateRefresh::Notify(vector<AlbumChangeData> albumChangeDatas,
83     std::shared_ptr<DfxRefreshManager> dfxRefreshManager)
84 {
85     if (albumChangeDatas.empty()) {
86         MEDIA_WARN_LOG("albumChangeDatas empty.");
87         return ACCURATE_REFRESH_INPUT_PARA_ERR;
88     }
89     notifyExe_.Notify(albumChangeDatas);
90     if (dfxRefreshManager != nullptr) {
91         dfxRefreshManager->SetEndTime();
92     } else if (dfxRefreshManager_ != nullptr) {
93         dfxRefreshManager_->SetEndTime();
94     }
95 
96     return ACCURATE_REFRESH_RET_OK;
97 }
98 
NotifyAddAlbums(const vector<string> & albumIdsStr)99 int32_t AlbumAccurateRefresh::NotifyAddAlbums(const vector<string> &albumIdsStr)
100 {
101     return Notify(dataManager_.GetAlbumDatasFromAddAlbum(albumIdsStr));
102 }
103 
UpdateModifiedDatasInner(const std::vector<int> & albumIds,RdbOperation operation,PendingInfo pendingInfo)104 int32_t AlbumAccurateRefresh::UpdateModifiedDatasInner(const std::vector<int> &albumIds, RdbOperation operation,
105     PendingInfo pendingInfo)
106 {
107     auto modifiedAlbumIds = albumIds;
108     if (modifiedAlbumIds.empty()) {
109         MEDIA_WARN_LOG("modifiedAlbumIds empty.");
110         return ACCURATE_REFRESH_INPUT_PARA_ERR;
111     }
112     DfxRefreshHander::SetAlbumIdHander(albumIds, dfxRefreshManager_);
113     int32_t err = dataManager_.UpdateModifiedDatasInner(modifiedAlbumIds, operation, pendingInfo);
114     CHECK_AND_RETURN_RET_WARN_LOG(err == ACCURATE_REFRESH_RET_OK, err,
115         "UpdateModifiedDatasInner failed, err:%{public}d", err);
116     err = dataManager_.PostProcessModifiedDatas(modifiedAlbumIds);
117     CHECK_AND_RETURN_RET_WARN_LOG(err == ACCURATE_REFRESH_RET_OK, err,
118         "PostProcessModifiedDatas failed, err:%{public}d", err);
119     return ACCURATE_REFRESH_RET_OK;
120 }
121 
UpdateModifiedDatas()122 int32_t AlbumAccurateRefresh::UpdateModifiedDatas()
123 {
124     return dataManager_.UpdateModifiedDatas();
125 }
126 
GetInitAlbumInfos()127 unordered_map<int32_t, AlbumChangeInfo> AlbumAccurateRefresh::GetInitAlbumInfos()
128 {
129     return dataManager_.GetInitAlbumInfos();
130 }
131 
GetReturningKeyName()132 string AlbumAccurateRefresh::GetReturningKeyName()
133 {
134     return PhotoAlbumColumns::ALBUM_ID;
135 }
136 
LogicalDeleteReplaceByUpdate(MediaLibraryCommand & cmd,int32_t & deletedRows)137 int32_t AlbumAccurateRefresh::LogicalDeleteReplaceByUpdate(MediaLibraryCommand &cmd, int32_t &deletedRows)
138 {
139     if (!IsValidTable(cmd.GetTableName())) {
140         return ACCURATE_REFRESH_RDB_INVALITD_TABLE;
141     }
142     return DeleteCommon([&](ValuesBucket &values) {
143         return Update(deletedRows, values, *(cmd.GetAbsRdbPredicates()), RDB_OPERATION_REMOVE);
144     });
145 }
146 
LogicalDeleteReplaceByUpdate(const AbsRdbPredicates & predicates,int & deletedRows)147 int32_t AlbumAccurateRefresh::LogicalDeleteReplaceByUpdate(const AbsRdbPredicates &predicates, int &deletedRows)
148 {
149     DfxRefreshHander::SetOperationStartTimeHander(dfxRefreshManager_);
150     if (!IsValidTable(predicates.GetTableName())) {
151         return ACCURATE_REFRESH_RDB_INVALITD_TABLE;
152     }
153     int32_t ret = DeleteCommon([&](ValuesBucket& values) {
154         return Update(deletedRows, values, predicates, RDB_OPERATION_REMOVE);
155     });
156     DfxRefreshHander::SetOptEndTimeHander(predicates, dfxRefreshManager_);
157     return ret;
158 }
159 
DeleteCommon(function<int32_t (ValuesBucket &)> updateExe)160 int32_t AlbumAccurateRefresh::DeleteCommon(function<int32_t(ValuesBucket&)> updateExe)
161 {
162     MEDIA_INFO_LOG("DeleteCommon enter");
163     MediaLibraryTracer tracer;
164     tracer.Start("AlbumAccurateRefresh::DeleteCommon");
165     ValuesBucket valuesBucket;
166     valuesBucket.PutInt(PhotoAlbumColumns::ALBUM_DIRTY, static_cast<int32_t>(DirtyType::TYPE_DELETED));
167     auto ret = updateExe(valuesBucket);
168     if (ret != NativeRdb::E_OK) {
169         MEDIA_ERR_LOG("rdbStore_->Delete failed, ret = %{public}d", ret);
170         return E_HAS_DB_ERROR;
171     }
172 
173     #ifndef MEDIA_REFRESH_TEST
174         if (!trans_) {
175             CloudSyncHelper::GetInstance()->StartSync(); // 事务场景不需要执行
176             ACCURATE_DEBUG("Delete update done, start sync.");
177         }
178     #endif
179 
180     return ACCURATE_REFRESH_RET_OK;
181 }
182 
IsValidTable(std::string tableName)183 bool AlbumAccurateRefresh::IsValidTable(std::string tableName)
184 {
185     return PhotoAlbumColumns::TABLE == tableName;
186 }
187 
NotifyForReCheck()188 int32_t AlbumAccurateRefresh::NotifyForReCheck()
189 {
190     Notification::NotifyInfoInner notifyInfo;
191     notifyInfo.tableType = Notification::NotifyTableType::PHOTO_ALBUM;
192     notifyInfo.operationType = Notification::ALBUM_OPERATION_RECHECK;
193     Notification::MediaLibraryNotifyNew::AddItem(notifyInfo);
194     ACCURATE_DEBUG("album recheck");
195     return ACCURATE_REFRESH_RET_OK;
196 }
197 
IsCoverContentChange(string & fileId)198 bool AlbumAccurateRefresh::IsCoverContentChange(string &fileId)
199 {
200     CHECK_AND_RETURN_RET_LOG(MediaFileUtils::IsValidInteger(fileId), false, "invalid input param");
201     CHECK_AND_RETURN_RET_LOG(stoi(fileId) > 0, false, "fileId is invalid");
202     MEDIA_INFO_LOG("IsCoverContentChange in, fileId: %{public}s", fileId.c_str());
203 
204     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
205     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
206     vector<string> columns = {PhotoAlbumColumns::ALBUM_ID, PhotoAlbumColumns::ALBUM_COVER_URI,
207         PhotoAlbumColumns::HIDDEN_COVER};
208     shared_ptr<ResultSet> resultSet = rdbStore->Query(predicates, columns);
209     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, false, "resultSet is null!");
210     int32_t rowCount = 0;
211     resultSet->GetRowCount(rowCount);
212     CHECK_AND_RETURN_RET_LOG(rowCount > 0, false, "result rowCount is: %{public}d", rowCount);
213 
214     vector<int32_t> albumIds;
215     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
216         int32_t albumId = get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_ID,
217             resultSet, TYPE_INT32));
218         string coverUri = get<string>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::ALBUM_COVER_URI,
219             resultSet, TYPE_STRING));
220         string hiddenCover = get<string>(ResultSetUtils::GetValFromColumn(PhotoAlbumColumns::HIDDEN_COVER,
221             resultSet, TYPE_STRING));
222         if ((coverUri != "" && MediaFileUtils::GetIdFromUri(coverUri) == fileId)
223             || (hiddenCover != "" && MediaFileUtils::GetIdFromUri(hiddenCover) == fileId)) {
224             albumIds.push_back(albumId);
225         }
226     }
227     resultSet->Close();
228 
229     if (!albumIds.empty()) {
230         NotifyAlbumsCoverChange(fileId, albumIds);
231         return true;
232     }
233     return false;
234 }
235 
NotifyAlbumsCoverChange(string & fileId,vector<int32_t> & albumIds)236 void AlbumAccurateRefresh::NotifyAlbumsCoverChange(string &fileId, vector<int32_t> &albumIds)
237 {
238     CHECK_AND_RETURN_LOG(MediaFileUtils::IsValidInteger(fileId), "invalid input param");
239     CHECK_AND_RETURN_LOG(stoi(fileId) > 0, "fileId is invalid");
240     CHECK_AND_RETURN_LOG(!albumIds.empty(), "no album cover has changed");
241     Init(albumIds);
242     UpdateModifiedDatasInner(albumIds, RDB_OPERATION_UPDATE);
243     vector<AlbumChangeData> albumChangeDatas = dataManager_.GetChangeDatas();
244     for (auto &albumChangeData : albumChangeDatas) {
245         if (MediaFileUtils::GetIdFromUri(albumChangeData.infoAfterChange_.coverUri_) == fileId) {
246             albumChangeData.infoAfterChange_.isCoverChange_ = true;
247             continue;
248         }
249         if (MediaFileUtils::GetIdFromUri(albumChangeData.infoAfterChange_.hiddenCoverUri_) == fileId) {
250             albumChangeData.infoAfterChange_.isHiddenCoverChange_ = true;
251             continue;
252         }
253     }
254     Notify(albumChangeDatas);
255 }
256 
257 } // namespace Media
258 } // namespace OHOS