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 "Media_Cloud_Utils"
16
17 #include "media_gallery_sync_notify.h"
18
19 #include <string>
20 #include <vector>
21
22 #include "medialibrary_errno.h"
23 #include "media_log.h"
24 #include "cloud_media_sync_const.h"
25 #include "media_column.h"
26 #include "photo_album_column.h"
27
28 namespace OHOS::Media::CloudSync {
29 using namespace std;
30 using ChangeType = AAFwk::ChangeInfo::ChangeType;
31 using NotifyDataMap = unordered_map<ChangeType, list<Uri>>;
32 unordered_map<ChangeType, list<Uri>> MediaGallerySyncNotify::notifyListMap_ = {};
33 int32_t MediaGallerySyncNotify::recordAdded_ = 0;
34 std::mutex MediaGallerySyncNotify::mtx_{};
35 constexpr int NOTIFY_INTERVALS = 50;
36 const std::string GALLERY_PROGRESS_URI = PhotoAlbumColumns::PHOTO_GALLERY_CLOUD_SYNC_INFO_URI_PREFIX;
37
GetInstance()38 MediaGallerySyncNotify &MediaGallerySyncNotify::GetInstance()
39 {
40 static MediaGallerySyncNotify instance;
41 return instance;
42 }
43
PrintUriList(ChangeType changeType,const list<Uri> & uris)44 static void PrintUriList(ChangeType changeType, const list<Uri> &uris)
45 {
46 if (uris.size() > 0) {
47 MEDIA_INFO_LOG("NotifyChange notify changeType = %{public}d, size = %{public}zu, uri = %{public}s",
48 changeType,
49 uris.size(),
50 uris.front().ToString().c_str());
51 } else {
52 MEDIA_INFO_LOG("NotifyChange notify changeType = %{public}d, size = %{public}zu", changeType, uris.size());
53 }
54 }
55
TryNotifyChange()56 static int32_t TryNotifyChange()
57 {
58 MediaGallerySyncNotify::recordAdded_++;
59 if (MediaGallerySyncNotify::recordAdded_ % NOTIFY_INTERVALS == 0) {
60 auto obsMgrClient = AAFwk::DataObsMgrClient::GetInstance();
61 if (obsMgrClient == nullptr) {
62 MEDIA_ERR_LOG("TryNotifyChange %{public}s obsMgrClient is nullptr", __func__);
63 return E_SA_LOAD_FAILED;
64 }
65 for (auto it = MediaGallerySyncNotify::notifyListMap_.begin();
66 it != MediaGallerySyncNotify::notifyListMap_.end(); ++it) {
67 obsMgrClient->NotifyChangeExt({it->first, it->second});
68 PrintUriList(it->first, it->second);
69 }
70 MediaGallerySyncNotify::notifyListMap_.clear();
71 MediaGallerySyncNotify::recordAdded_ = 0;
72 }
73 return E_OK;
74 }
75
NotifyFileAssetChange(bool notify,const std::string & uri,const ChangeType changeType)76 static int32_t NotifyFileAssetChange(bool notify, const std::string &uri, const ChangeType changeType)
77 {
78 std::lock_guard<mutex> lock(MediaGallerySyncNotify::mtx_);
79 auto iterator = MediaGallerySyncNotify::notifyListMap_.find(changeType);
80 if (iterator != MediaGallerySyncNotify::notifyListMap_.end()) {
81 iterator->second.emplace_back(Uri(uri));
82 } else {
83 list<Uri> newList;
84 newList.emplace_back(Uri(uri));
85 MediaGallerySyncNotify::notifyListMap_.insert(make_pair(changeType, newList));
86 }
87 if (!notify) {
88 return E_OK;
89 }
90 return TryNotifyChange();
91 }
92
NotifyAlbumChange(const bool notify,const std::string & uri,const ChangeType changeType)93 static int32_t NotifyAlbumChange(const bool notify, const std::string &uri, const ChangeType changeType)
94 {
95 return NotifyFileAssetChange(notify, uri, changeType);
96 }
97
NotifyAlbumMapChange(const std::string & uri,const ChangeType changeType,const std::string & fileAssetId)98 static int32_t NotifyAlbumMapChange(const std::string &uri, const ChangeType changeType, const std::string &fileAssetId)
99 {
100 return E_OK;
101 }
102
AddAndNotify(const bool notify,const std::string & uri,const ChangeType changeType,const std::string & fileAssetId)103 static int32_t AddAndNotify(
104 const bool notify, const std::string &uri, const ChangeType changeType, const std::string &fileAssetId)
105 {
106 int ret = E_NOTIFY;
107 if (uri.find(PhotoColumn::PHOTO_CLOUD_URI_PREFIX) != std::string::npos) {
108 ret = NotifyFileAssetChange(notify, uri, changeType);
109 } else if (uri.find(PhotoColumn::PHOTO_GALLERY_CLOUD_URI_PREFIX) != std::string::npos) {
110 ret = NotifyFileAssetChange(notify, uri, changeType);
111 } else if ((uri.find(PhotoAlbumColumns::ALBUM_GALLERY_CLOUD_URI_PREFIX) != std::string::npos) &&
112 (fileAssetId == "0")) {
113 ret = NotifyAlbumChange(notify, uri, changeType);
114 } else if ((uri.find(PhotoAlbumColumns::ALBUM_GALLERY_CLOUD_URI_PREFIX) != std::string::npos) ||
115 (uri.find(PhotoColumn::PHOTO_CLOUD_GALLERY_REBUILD_URI_PREFIX) != std::string::npos)) {
116 ret = NotifyAlbumChange(notify, uri + fileAssetId, changeType);
117 } else if (uri.find(PhotoAlbumColumns::PHOTO_GALLERY_DOWNLOAD_URI_PREFIX) != std::string::npos) {
118 ret = NotifyFileAssetChange(notify, uri + fileAssetId, changeType);
119 } else {
120 ret = NotifyAlbumMapChange(uri, changeType, fileAssetId);
121 }
122 return ret;
123 }
124
AddNotify(const std::string & uri,const ChangeType changeType,const std::string & fileAssetId)125 int32_t MediaGallerySyncNotify::AddNotify(
126 const std::string &uri, const ChangeType changeType, const std::string &fileAssetId)
127 {
128 MEDIA_INFO_LOG(
129 "AddNotify uri:%{public}s, type:%{public}d, fileId:%{public}s", uri.c_str(), changeType, fileAssetId.c_str());
130 return AddAndNotify(false, uri, changeType, fileAssetId);
131 }
132
TryNotify(const std::string & uri,const ChangeType changeType,const std::string & fileAssetId)133 int32_t MediaGallerySyncNotify::TryNotify(
134 const std::string &uri, const ChangeType changeType, const std::string &fileAssetId)
135 {
136 MEDIA_INFO_LOG(
137 "TryNotify uri:%{public}s, type:%{public}d, fileId:%{public}s", uri.c_str(), changeType, fileAssetId.c_str());
138 return AddAndNotify(true, uri, changeType, fileAssetId);
139 }
140
FinalNotify()141 int32_t MediaGallerySyncNotify::FinalNotify()
142 {
143 auto obsMgrClient = AAFwk::DataObsMgrClient::GetInstance();
144 if (obsMgrClient == nullptr) {
145 MEDIA_ERR_LOG("FinalNotify %{public}s obsMgrClient is nullptr", __func__);
146 return E_SA_LOAD_FAILED;
147 }
148 std::lock_guard<mutex> lock(MediaGallerySyncNotify::mtx_);
149 for (auto it = MediaGallerySyncNotify::notifyListMap_.begin(); it != MediaGallerySyncNotify::notifyListMap_.end();
150 ++it) {
151 obsMgrClient->NotifyChangeExt({it->first, it->second});
152 PrintUriList(it->first, it->second);
153 }
154 MediaGallerySyncNotify::notifyListMap_.clear();
155 MediaGallerySyncNotify::recordAdded_ = 0;
156 return E_OK;
157 }
158
NotifyProgress(NotifyTaskType taskType,const std::string & syncId,NotifySyncType syncType,uint32_t totalAlbums,uint32_t totalAssets)159 int32_t MediaGallerySyncNotify::NotifyProgress(NotifyTaskType taskType, const std::string &syncId,
160 NotifySyncType syncType, uint32_t totalAlbums, uint32_t totalAssets)
161 {
162 std::string params = "{\"syncId\":\"" + syncId + "\",";
163 params += "\"syncType\":" + to_string(syncType) + ",";
164 params += "\"taskType\":" + to_string(taskType) + ",";
165 params += "\"totalAlbums\":" + to_string(totalAlbums) + ",";
166 params += "\"totalAssets\":" + to_string(totalAssets) + "}";
167
168 auto obsMgrClient = AAFwk::DataObsMgrClient::GetInstance();
169 if (obsMgrClient == nullptr) {
170 MEDIA_ERR_LOG("NotifyProgress %{public}s obsMgrClient is nullptr", __func__);
171 return E_SA_LOAD_FAILED;
172 }
173 AAFwk::ChangeInfo changeInfo;
174 changeInfo.uris_.push_back(Uri(GALLERY_PROGRESS_URI));
175 changeInfo.data_ = (void *)params.c_str();
176 changeInfo.size_ = params.length();
177 MEDIA_INFO_LOG("NotifyProgress params = %{public}s, size is %{public}zu", params.c_str(), params.length());
178 obsMgrClient->NotifyChangeExt(changeInfo);
179
180 return E_OK;
181 }
182
NotifyProgressBegin()183 void MediaGallerySyncNotify::NotifyProgressBegin()
184 {
185 if (!syncId_.empty()) {
186 return;
187 }
188 std::time_t timeStamp = std::time(nullptr);
189 syncId_ = std::to_string(timeStamp);
190 NotifyProgress(NotifyTaskType::NOTIFY_BEGIN, syncId_, NotifySyncType::NOTIFY_INCREMENTAL_SYNC, 0, 0);
191 }
192
NotifyProgressEnd()193 void MediaGallerySyncNotify::NotifyProgressEnd()
194 {
195 NotifyProgress(NotifyTaskType::NOTIFY_END, syncId_, NotifySyncType::NOTIFY_INCREMENTAL_SYNC, 0, 0);
196 syncId_ = "";
197 }
198 } // namespace OHOS::Media::CloudSync
199