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 "NotificationMerging"
16
17 #include "notification_merging.h"
18
19 #include "media_log.h"
20 #include "notify_info.h"
21 #include "media_observer_manager.h"
22 #include "notify_register_permission.h"
23 #include "media_column.h"
24 #include "photo_album_column.h"
25 #include "media_change_info.h"
26 #include "medialibrary_errno.h"
27 #include "observer_info.h"
28 #include "media_datashare_stub_impl.h"
29
30 #include <map>
31 #include <unordered_set>
32 #include <set>
33
34 using namespace std;
35 using namespace OHOS::Media::AccurateRefresh;
36 using namespace OHOS::DataShare;
37
38 namespace OHOS {
39 namespace Media {
40 namespace Notification {
41
NotificationMerging()42 NotificationMerging::NotificationMerging() {}
43
~NotificationMerging()44 NotificationMerging::~NotificationMerging() {}
45
findObservers(NotifyUriType notifyUriType)46 std::vector<ObserverInfo> NotificationMerging::findObservers(NotifyUriType notifyUriType)
47 {
48 MEDIA_INFO_LOG("enter findObservers,notifyUriType:%{public}d", static_cast<int32_t>(notifyUriType));
49 static auto manager = MediaObserverManager::GetObserverManager();
50 if (manager == nullptr) {
51 manager = MediaObserverManager::GetObserverManager();
52 if (manager == nullptr) {
53 MEDIA_ERR_LOG("Failed to get ObserverManager!");
54 return {};
55 }
56 }
57 return manager->FindObserver(notifyUriType);
58 }
59
ProcessNotifyInfos(const std::vector<MediaChangeInfo> & mediaChangeInfos)60 std::vector<NotifyInfo> NotificationMerging::ProcessNotifyInfos(const std::vector<MediaChangeInfo> &mediaChangeInfos)
61 {
62 MEDIA_INFO_LOG("Enter ProcessNotifyInfos");
63 CHECK_AND_RETURN_RET_LOG(!mediaChangeInfos.empty(), {}, "mediaChangeInfos is empty");
64
65 auto manager = MediaObserverManager::GetObserverManager();
66 CHECK_AND_RETURN_RET_LOG(manager != nullptr, {}, "manager is null");
67
68 std::map<std::pair<NotifyUriType, NotifyType>, MediaChangeInfo> mergedChanges;
69 std::vector<NotifyInfo> notifyInfos;
70 // 对notifyUri和notifyType相同的进行合并
71 for (const auto &info : mediaChangeInfos) {
72 MEDIA_INFO_LOG("processing info: %{public}s", info.ToString().c_str());
73 auto key = std::make_pair(info.notifyUri, info.notifyType);
74 if (mergedChanges.find(key) == mergedChanges.end()) {
75 mergedChanges[key] = info;
76 } else {
77 auto& existing = mergedChanges[key];
78 existing.changeInfos.insert(
79 existing.changeInfos.end(),
80 info.changeInfos.begin(),
81 info.changeInfos.end()
82 );
83 }
84 }
85
86 // 将NotifyUriType相同的合并在同一个NotifyInfo中
87 std::map<NotifyUriType, NotifyInfo> uriToNotifyInfoMap;
88 for (const auto &[key, mergedInfo] : mergedChanges) {
89 auto [notifyUri, notifyType] = key;
90 if (uriToNotifyInfoMap.find(notifyUri) == uriToNotifyInfoMap.end()) {
91 NotifyInfo notifyInfo;
92 const std::vector<ObserverInfo> observerInfos = findObservers(notifyUri);
93 if (!observerInfos.empty()) {
94 notifyInfo.observerInfos.insert(notifyInfo.observerInfos.end(),
95 observerInfos.begin(), observerInfos.end());
96 }
97 uriToNotifyInfoMap[notifyUri] = notifyInfo;
98 }
99 uriToNotifyInfoMap[notifyUri].changeInfosMap[notifyUri].push_back(mergedInfo);
100 }
101
102 // 将分组后的结果转移到notifyInfos中
103 for (auto &[notifyUri, notifyInfo] : uriToNotifyInfoMap) {
104 MEDIA_INFO_LOG("notifyUri is:%{public}d", static_cast<int32_t>(notifyUri));
105 notifyInfos.push_back(std::move(notifyInfo));
106 }
107
108 MEDIA_INFO_LOG("ProcessNotifyInfos completed");
109 return notifyInfos;
110 }
111
MergeNotifyInfo(std::vector<MediaChangeInfo> changeInfos)112 std::vector<NotifyInfo> NotificationMerging::MergeNotifyInfo(std::vector<MediaChangeInfo> changeInfos)
113 {
114 MEDIA_INFO_LOG("Merging notification information");
115 CHECK_AND_RETURN_RET_LOG(!changeInfos.empty(), {}, "changeInfos is null");
116 return ProcessNotifyInfos(changeInfos);
117 }
118 } // namespace Notification
119 } // namespace Media
120 } // namespace OHOS