• 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 
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