1 /*
2  * Copyright (c) 2021-2024 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 #include "notification_subscriber.h"
17 
18 #include "notification_constant.h"
19 #include "hitrace_meter_adapter.h"
20 #include "iservice_registry.h"
21 #include "system_ability_definition.h"
22 
23 namespace OHOS {
24 namespace Notification {
NotificationSubscriber()25 NotificationSubscriber::NotificationSubscriber()
26 {
27     impl_ = new (std::nothrow) SubscriberImpl(*this);
28     deviceType_ = NotificationConstant::CURRENT_DEVICE_TYPE;
29 };
30 
~NotificationSubscriber()31 NotificationSubscriber::~NotificationSubscriber()
32 {
33     if (impl_ != nullptr) {
34         impl_->OnSubscriberDestory();
35     }
36 }
37 
SetDeviceType(const std::string & deviceType)38 void NotificationSubscriber::SetDeviceType(const std::string &deviceType)
39 {
40     deviceType_ = deviceType;
41 }
42 
GetDeviceType() const43 std::string NotificationSubscriber::GetDeviceType() const
44 {
45     return deviceType_;
46 }
47 
48 #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED
ProcessSyncDecision(const std::string & deviceType,std::shared_ptr<Notification> & notification) const49 bool NotificationSubscriber::ProcessSyncDecision(
50     const std::string &deviceType, std::shared_ptr<Notification> &notification) const
51 {
52     sptr<NotificationRequest> request = notification->GetNotificationRequestPoint();
53     if (request == nullptr) {
54         ANS_LOGE("No need to consume cause invalid reqeuest.");
55         return false;
56     }
57     auto flagsMap = request->GetDeviceFlags();
58     if (flagsMap == nullptr || flagsMap->size() <= 0) {
59         return true;
60     }
61     auto flagIter = flagsMap->find(deviceType);
62     if (flagIter != flagsMap->end() && flagIter->second != nullptr) {
63         ANS_LOGI("SetFlags-before filte, notificationKey = %{public}s flagIter \
64             flags = %{public}d, deviceType:%{public}s",
65             request->GetKey().c_str(), flagIter->second->GetReminderFlags(), deviceType.c_str());
66         std::shared_ptr<NotificationFlags> tempFlags = request->GetFlags();
67         tempFlags->SetSoundEnabled(DowngradeReminder(tempFlags->IsSoundEnabled(), flagIter->second->IsSoundEnabled()));
68         tempFlags->SetVibrationEnabled(
69             DowngradeReminder(tempFlags->IsVibrationEnabled(), flagIter->second->IsVibrationEnabled()));
70         tempFlags->SetLockScreenVisblenessEnabled(
71             tempFlags->IsLockScreenVisblenessEnabled() && flagIter->second->IsLockScreenVisblenessEnabled());
72         tempFlags->SetBannerEnabled(
73             tempFlags->IsBannerEnabled() && flagIter->second->IsBannerEnabled());
74         tempFlags->SetLightScreenEnabled(
75             tempFlags->IsLightScreenEnabled() && flagIter->second->IsLightScreenEnabled());
76         request->SetFlags(tempFlags);
77         ANS_LOGI("SetFlags-after filte, notificationKey = %{public}s flags = %{public}d",
78             request->GetKey().c_str(), tempFlags->GetReminderFlags());
79         return true;
80     }
81     if (deviceType.size() <= 0 || deviceType.compare(NotificationConstant::CURRENT_DEVICE_TYPE) == 0) {
82         return true;
83     }
84     ANS_LOGD("No need to consume cause cannot find deviceFlags. deviceType: %{public}s.", deviceType.c_str());
85     return false;
86 }
87 
DowngradeReminder(const NotificationConstant::FlagStatus & oldFlags,const NotificationConstant::FlagStatus & judgeFlags) const88 NotificationConstant::FlagStatus NotificationSubscriber::DowngradeReminder(
89     const NotificationConstant::FlagStatus &oldFlags, const NotificationConstant::FlagStatus &judgeFlags) const
90 {
91     if (judgeFlags == NotificationConstant::FlagStatus::NONE || oldFlags == NotificationConstant::FlagStatus::NONE) {
92         return NotificationConstant::FlagStatus::NONE;
93     }
94     if (judgeFlags > oldFlags) {
95         return judgeFlags;
96     } else {
97         return oldFlags;
98     }
99 }
100 #endif
101 
GetImpl() const102 const sptr<NotificationSubscriber::SubscriberImpl> NotificationSubscriber::GetImpl() const
103 {
104     return impl_;
105 }
106 
SubscriberImpl(NotificationSubscriber & subscriber)107 NotificationSubscriber::SubscriberImpl::SubscriberImpl(NotificationSubscriber &subscriber) : subscriber_(subscriber)
108 {
109     recipient_ = new (std::nothrow) DeathRecipient(*this);
110 };
111 
OnSubscriberDestory()112 void NotificationSubscriber::SubscriberImpl::OnSubscriberDestory()
113 {
114     isSubscriberDestory_.store(true);
115 }
116 
OnConnected()117 void NotificationSubscriber::SubscriberImpl::OnConnected()
118 {
119     if (isSubscriberDestory_.load()) {
120         return;
121     }
122     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
123     sptr<AnsManagerInterface> proxy = GetAnsManagerProxy();
124     if (proxy != nullptr) {
125         proxy->AsObject()->AddDeathRecipient(recipient_);
126         ANS_LOGD("%s, Add death recipient.", __func__);
127     }
128     subscriber_.OnConnected();
129 }
130 
OnDisconnected()131 void NotificationSubscriber::SubscriberImpl::OnDisconnected()
132 {
133     if (isSubscriberDestory_.load()) {
134         return;
135     }
136     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
137     sptr<AnsManagerInterface> proxy = GetAnsManagerProxy();
138     if (proxy != nullptr) {
139         proxy->AsObject()->RemoveDeathRecipient(recipient_);
140         ANS_LOGD("%s, Remove death recipient.", __func__);
141     }
142     subscriber_.OnDisconnected();
143 }
144 
OnConsumed(const sptr<Notification> & notification,const sptr<NotificationSortingMap> & notificationMap)145 void NotificationSubscriber::SubscriberImpl::OnConsumed(
146     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap)
147 {
148     if (isSubscriberDestory_.load()) {
149         return;
150     }
151     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
152     std::shared_ptr<Notification> sharedNotification = std::make_shared<Notification>(*notification);
153 #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED
154     if (!subscriber_.ProcessSyncDecision(subscriber_.GetDeviceType(), sharedNotification)) {
155         return;
156     }
157 #endif
158     subscriber_.OnConsumed(
159         sharedNotification, std::make_shared<NotificationSortingMap>(*notificationMap));
160 }
161 
OnConsumedList(const std::vector<sptr<Notification>> & notifications,const sptr<NotificationSortingMap> & notificationMap)162 void NotificationSubscriber::SubscriberImpl::OnConsumedList(const std::vector<sptr<Notification>> &notifications,
163     const sptr<NotificationSortingMap> &notificationMap)
164 {
165     if (isSubscriberDestory_.load()) {
166         return;
167     }
168     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
169     for (auto notification : notifications) {
170         OnConsumed(notification, notificationMap);
171     }
172 }
173 
OnCanceled(const sptr<Notification> & notification,const sptr<NotificationSortingMap> & notificationMap,int32_t deleteReason)174 void NotificationSubscriber::SubscriberImpl::OnCanceled(
175     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
176 {
177     if (isSubscriberDestory_.load()) {
178         return;
179     }
180     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
181     if (notificationMap == nullptr) {
182         subscriber_.OnCanceled(std::make_shared<Notification>(*notification),
183             std::make_shared<NotificationSortingMap>(), deleteReason);
184     } else {
185         subscriber_.OnCanceled(std::make_shared<Notification>(*notification),
186             std::make_shared<NotificationSortingMap>(*notificationMap), deleteReason);
187     }
188 }
189 
OnBatchCanceled(const std::vector<sptr<Notification>> & notifications,const sptr<NotificationSortingMap> & notificationMap,int32_t deleteReason)190 void NotificationSubscriber::SubscriberImpl::OnBatchCanceled(const std::vector<sptr<Notification>> &notifications,
191     const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
192 {
193     if (isSubscriberDestory_.load()) {
194         return;
195     }
196     std::vector<std::shared_ptr<Notification>> notificationList;
197     for (auto notification : notifications) {
198         notificationList.emplace_back(std::make_shared<Notification>(*notification));
199     }
200     if (notificationMap == nullptr) {
201         subscriber_.OnBatchCanceled(notificationList,
202             std::make_shared<NotificationSortingMap>(), deleteReason);
203     } else {
204         subscriber_.OnBatchCanceled(notificationList,
205             std::make_shared<NotificationSortingMap>(*notificationMap), deleteReason);
206     }
207 }
208 
OnCanceledList(const std::vector<sptr<Notification>> & notifications,const sptr<NotificationSortingMap> & notificationMap,int32_t deleteReason)209 void NotificationSubscriber::SubscriberImpl::OnCanceledList(const std::vector<sptr<Notification>> &notifications,
210     const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
211 {
212     if (isSubscriberDestory_.load()) {
213         return;
214     }
215     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
216     if (subscriber_.HasOnBatchCancelCallback()) {
217         OnBatchCanceled(notifications, notificationMap, deleteReason);
218         return;
219     }
220     for (auto notification : notifications) {
221         OnCanceled(notification, notificationMap, deleteReason);
222     }
223 }
224 
OnUpdated(const sptr<NotificationSortingMap> & notificationMap)225 void NotificationSubscriber::SubscriberImpl::OnUpdated(const sptr<NotificationSortingMap> &notificationMap)
226 {
227     if (isSubscriberDestory_.load()) {
228         return;
229     }
230     subscriber_.OnUpdate(std::make_shared<NotificationSortingMap>(*notificationMap));
231 }
232 
OnDoNotDisturbDateChange(const sptr<NotificationDoNotDisturbDate> & date)233 void NotificationSubscriber::SubscriberImpl::OnDoNotDisturbDateChange(const sptr<NotificationDoNotDisturbDate> &date)
234 {
235     if (isSubscriberDestory_.load()) {
236         return;
237     }
238     subscriber_.OnDoNotDisturbDateChange(std::make_shared<NotificationDoNotDisturbDate>(*date));
239 }
240 
OnEnabledNotificationChanged(const sptr<EnabledNotificationCallbackData> & callbackData)241 void NotificationSubscriber::SubscriberImpl::OnEnabledNotificationChanged(
242     const sptr<EnabledNotificationCallbackData> &callbackData)
243 {
244     if (isSubscriberDestory_.load()) {
245         return;
246     }
247     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
248     subscriber_.OnEnabledNotificationChanged(std::make_shared<EnabledNotificationCallbackData>(*callbackData));
249 }
250 
OnBadgeChanged(const sptr<BadgeNumberCallbackData> & badgeData)251 void NotificationSubscriber::SubscriberImpl::OnBadgeChanged(const sptr<BadgeNumberCallbackData> &badgeData)
252 {
253     if (isSubscriberDestory_.load()) {
254         return;
255     }
256     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
257     subscriber_.OnBadgeChanged(std::make_shared<BadgeNumberCallbackData>(*badgeData));
258 }
259 
OnBadgeEnabledChanged(const sptr<EnabledNotificationCallbackData> & callbackData)260 void NotificationSubscriber::SubscriberImpl::OnBadgeEnabledChanged(
261     const sptr<EnabledNotificationCallbackData> &callbackData)
262 {
263     if (isSubscriberDestory_.load()) {
264         return;
265     }
266     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
267     subscriber_.OnBadgeEnabledChanged(callbackData);
268 }
269 
GetAnsManagerProxy()270 sptr<AnsManagerInterface> NotificationSubscriber::SubscriberImpl::GetAnsManagerProxy()
271 {
272     sptr<ISystemAbilityManager> systemAbilityManager =
273         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
274     if (!systemAbilityManager) {
275         return nullptr;
276     }
277 
278     sptr<IRemoteObject> remoteObject =
279         systemAbilityManager->GetSystemAbility(ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID);
280     if (!remoteObject) {
281         return nullptr;
282     }
283 
284     sptr<AnsManagerInterface> proxy = iface_cast<AnsManagerInterface>(remoteObject);
285     if ((proxy == nullptr) || (proxy->AsObject() == nullptr)) {
286         return nullptr;
287     }
288 
289     return proxy;
290 }
291 
DeathRecipient(SubscriberImpl & subscriberImpl)292 NotificationSubscriber::SubscriberImpl::DeathRecipient::DeathRecipient(SubscriberImpl &subscriberImpl)
293     : subscriberImpl_(subscriberImpl) {};
294 
~DeathRecipient()295 NotificationSubscriber::SubscriberImpl::DeathRecipient::~DeathRecipient() {};
296 
OnRemoteDied(const wptr<IRemoteObject> & object)297 void NotificationSubscriber::SubscriberImpl::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
298 {
299     subscriberImpl_.subscriber_.OnDied();
300 }
301 }  // namespace Notification
302 }  // namespace OHOS
303