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
17 #include "notification_distribution.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 "notification_merging.h"
29 #include "media_notification_utils.h"
30
31 #include <map>
32 #include <unordered_set>
33 #include <securec.h>
34
35 using namespace std;
36
37 namespace OHOS {
38 namespace Media {
39 namespace Notification {
NotificationDistribution()40 NotificationDistribution::NotificationDistribution() {}
41
~NotificationDistribution()42 NotificationDistribution::~NotificationDistribution() {}
43
FilterNotifyInfoByPermission(const MediaChangeInfo & changeInfo,NotifyUriType notifyUriType)44 MediaChangeInfo NotificationDistribution::FilterNotifyInfoByPermission(
45 const MediaChangeInfo& changeInfo, NotifyUriType notifyUriType)
46 {
47 const NotifyUriType changeUri = changeInfo.notifyUri;
48
49 if ((notifyUriType == NotifyUriType::PHOTO_URI || notifyUriType == NotifyUriType::PHOTO_ALBUM_URI) &&
50 changeUri == notifyUriType) {
51 return changeInfo;
52 }
53
54 if (notifyUriType == NotifyUriType::HIDDEN_PHOTO_URI ||
55 notifyUriType == NotifyUriType::HIDDEN_ALBUM_URI) {
56 return changeInfo;
57 }
58
59 if ((notifyUriType == NotifyUriType::TRASH_PHOTO_URI ||
60 notifyUriType == NotifyUriType::TRASH_ALBUM_URI) &&
61 (changeUri == NotifyUriType::PHOTO_URI ||
62 changeUri == NotifyUriType::TRASH_PHOTO_URI ||
63 changeUri == NotifyUriType::PHOTO_ALBUM_URI ||
64 changeUri == NotifyUriType::TRASH_ALBUM_URI)) {
65 return changeInfo;
66 }
67
68 return MediaChangeInfo{};
69 }
70
SendNotificationWithRecheckChangeInfo(const MediaChangeInfo & changeInfo,const ObserverInfo & observerInfo)71 int32_t NotificationDistribution::SendNotificationWithRecheckChangeInfo(
72 const MediaChangeInfo& changeInfo, const ObserverInfo& observerInfo)
73 {
74 MediaChangeInfo recheckChangeInfo = changeInfo;
75 recheckChangeInfo.changeInfos.clear();
76 recheckChangeInfo.isForRecheck = true;
77 recheckChangeInfo.isSystem = observerInfo.isSystem;
78 if (changeInfo.notifyType == NotifyType::NOTIFY_ASSET_ADD ||
79 changeInfo.notifyType == NotifyType::NOTIFY_ASSET_UPDATE ||
80 changeInfo.notifyType == NotifyType::NOTIFY_ASSET_REMOVE) {
81 recheckChangeInfo.notifyType = NotifyType::NOTIFY_ASSET_ADD;
82 } else {
83 recheckChangeInfo.notifyType = NotifyType::NOTIFY_ALBUM_ADD;
84 }
85 shared_ptr<MediaChangeInfo> sharedChangeInfo = make_shared<MediaChangeInfo>(recheckChangeInfo);
86 return NotificationUtils::SendNotification(observerInfo.observer, sharedChangeInfo);
87 }
88
ProcessMediaChangeInfos(const std::vector<Notification::MediaChangeInfo> & mediaChangeInfos,Notification::NotifyUriType notifyUriType,const ObserverInfo & observerInfo)89 int32_t NotificationDistribution::ProcessMediaChangeInfos(
90 const std::vector<Notification::MediaChangeInfo>& mediaChangeInfos,
91 Notification::NotifyUriType notifyUriType,
92 const ObserverInfo& observerInfo)
93 {
94 for (const auto& mediaChangeInfo : mediaChangeInfos) {
95 // 如果存在一个isForRecheck为true,只需要发送一个add通知
96 if (mediaChangeInfo.isForRecheck) {
97 return SendNotificationWithRecheckChangeInfo(mediaChangeInfo, observerInfo);
98 }
99 }
100 for (const auto& mediaChangeInfo : mediaChangeInfos) {
101 MEDIA_INFO_LOG("mediaChangeInfo:%{public}s", mediaChangeInfo.ToString().c_str());
102 if (mediaChangeInfo.changeInfos.empty()) {
103 MEDIA_INFO_LOG("mediaChangeInfo changeInfos is null");
104 continue;
105 }
106 MediaChangeInfo filteredInfo = FilterNotifyInfoByPermission(mediaChangeInfo, notifyUriType);
107 if (filteredInfo.changeInfos.empty()) {
108 MEDIA_INFO_LOG("After filtering mediaChangeInfo changeInfos is null");
109 continue;
110 }
111 filteredInfo.isSystem = observerInfo.isSystem;
112 shared_ptr<MediaChangeInfo> sharedChangeInfo = make_shared<MediaChangeInfo>(filteredInfo);
113 int32_t ret = NotificationUtils::SendNotification(observerInfo.observer, sharedChangeInfo);
114 CHECK_AND_RETURN_RET_LOG(ret != E_OK, ret, "CallbackProcessing fail err:%{public}d", ret);
115 MEDIA_INFO_LOG("CallbackProcessing ret:%{public}d", ret);
116 }
117 return E_OK;
118 }
119
ProcessNotifyInfo(const NotifyInfo & notifyInfo)120 int32_t NotificationDistribution::ProcessNotifyInfo(const NotifyInfo& notifyInfo)
121 {
122 for (const auto& observerInfo : notifyInfo.observerInfos) {
123 for (const auto& [notifyUriType, mediaChangeInfos] : notifyInfo.changeInfosMap) {
124 if (!mediaChangeInfos.empty()) {
125 ProcessMediaChangeInfos(mediaChangeInfos, notifyUriType, observerInfo);
126 }
127 }
128 }
129 return E_OK;
130 }
131
DistributeNotifyInfo(const std::vector<NotifyInfo> & notifyInfos)132 int32_t NotificationDistribution::DistributeNotifyInfo(const std::vector<NotifyInfo>& notifyInfos)
133 {
134 CHECK_AND_RETURN_RET_LOG(!notifyInfos.empty(), E_OK, "notifyInfos is null");
135
136 MEDIA_INFO_LOG("enter distributeNotifyInfo, notifyInfos size:%{public}d", static_cast<int32_t>(notifyInfos.size()));
137
138 for (const auto& notifyInfo : notifyInfos) {
139 if (notifyInfo.observerInfos.empty() || notifyInfo.changeInfosMap.empty()) {
140 MEDIA_INFO_LOG("notifyInfo has empty observerInfos or changeInfosMap");
141 continue;
142 }
143
144 ProcessNotifyInfo(notifyInfo);
145 }
146 return E_OK;
147 }
148
149 } // Notification
150 } // Media
151 } // OHOS