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_manager.h"
17 
18 #include <algorithm>
19 #include <memory>
20 #include <set>
21 
22 #include "ans_const_define.h"
23 #include "ans_inner_errors.h"
24 #include "ans_log_wrapper.h"
25 #include "hitrace_meter_adapter.h"
26 #include "ipc_skeleton.h"
27 #include "notification_flags.h"
28 #include "notification_constant.h"
29 #include "notification_config_parse.h"
30 #include "notification_extension_wrapper.h"
31 #include "os_account_manager_helper.h"
32 #include "remote_death_recipient.h"
33 #include "advanced_notification_service.h"
34 #include "notification_analytics_util.h"
35 
36 #include "advanced_notification_inline.cpp"
37 
38 namespace OHOS {
39 namespace Notification {
40 struct NotificationSubscriberManager::SubscriberRecord {
41     sptr<AnsSubscriberInterface> subscriber {nullptr};
42     std::set<std::string> bundleList_ {};
43     bool subscribedAll {false};
44     int32_t userId {SUBSCRIBE_USER_INIT};
45     std::string deviceType {CURRENT_DEVICE_TYPE};
46     int32_t subscriberUid {DEFAULT_UID};
47 };
48 
NotificationSubscriberManager()49 NotificationSubscriberManager::NotificationSubscriberManager()
50 {
51     ANS_LOGI("constructor");
52     notificationSubQueue_ = std::make_shared<ffrt::queue>("NotificationSubscriberMgr");
53     recipient_ = new (std::nothrow)
54         RemoteDeathRecipient(std::bind(&NotificationSubscriberManager::OnRemoteDied, this, std::placeholders::_1));
55     if (recipient_ == nullptr) {
56         ANS_LOGE("Failed to create RemoteDeathRecipient instance");
57     }
58 }
59 
~NotificationSubscriberManager()60 NotificationSubscriberManager::~NotificationSubscriberManager()
61 {
62     ANS_LOGI("deconstructor");
63     subscriberRecordList_.clear();
64 }
65 
ResetFfrtQueue()66 void NotificationSubscriberManager::ResetFfrtQueue()
67 {
68     if (notificationSubQueue_ != nullptr) {
69         notificationSubQueue_.reset();
70     }
71 }
72 
AddSubscriber( const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)73 ErrCode NotificationSubscriberManager::AddSubscriber(
74     const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
75 {
76     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
77     if (subscriber == nullptr) {
78         ANS_LOGE("subscriber is null.");
79         return ERR_ANS_INVALID_PARAM;
80     }
81 
82     sptr<NotificationSubscribeInfo> subInfo = subscribeInfo;
83     if (subInfo == nullptr) {
84         subInfo = new (std::nothrow) NotificationSubscribeInfo();
85         if (subInfo == nullptr) {
86             ANS_LOGE("Failed to create NotificationSubscribeInfo ptr.");
87             return ERR_ANS_NO_MEMORY;
88         }
89     }
90 
91     if (subInfo->GetAppUserId() == SUBSCRIBE_USER_INIT) {
92         int32_t userId = SUBSCRIBE_USER_INIT;
93         ErrCode ret = OsAccountManagerHelper::GetInstance().GetCurrentCallingUserId(userId);
94         if (ret != ERR_OK) {
95             return ret;
96         }
97         subInfo->AddAppUserId(userId);
98     }
99 
100     ErrCode result = ERR_ANS_TASK_ERR;
101     if (notificationSubQueue_ == nullptr) {
102         ANS_LOGE("queue is nullptr");
103         return result;
104     }
105     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_6, EventBranchId::BRANCH_2);
106     ffrt::task_handle handler = notificationSubQueue_->submit_h(std::bind([this, &subscriber, &subInfo, &result]() {
107         result = this->AddSubscriberInner(subscriber, subInfo);
108     }));
109     notificationSubQueue_->wait(handler);
110     message.Message("Subscribe notification: " + GetClientBundleName() + " user " +
111         std::to_string(subInfo->GetAppUserId()) + " " + std::to_string(result));
112     NotificationAnalyticsUtil::ReportModifyEvent(message);
113     return result;
114 }
115 
RemoveSubscriber( const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)116 ErrCode NotificationSubscriberManager::RemoveSubscriber(
117     const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
118 {
119     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
120     if (subscriber == nullptr) {
121         ANS_LOGE("subscriber is null.");
122         return ERR_ANS_INVALID_PARAM;
123     }
124 
125     ErrCode result = ERR_ANS_TASK_ERR;
126     if (notificationSubQueue_ == nullptr) {
127         ANS_LOGE("queue is nullptr");
128         return result;
129     }
130     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_6, EventBranchId::BRANCH_3);
131     ffrt::task_handle handler = notificationSubQueue_->submit_h(std::bind([this, &subscriber,
132         &subscribeInfo, &result]() {
133         ANS_LOGE("ffrt enter!");
134         result = this->RemoveSubscriberInner(subscriber, subscribeInfo);
135     }));
136     notificationSubQueue_->wait(handler);
137     std::string appUserId = (subscribeInfo == nullptr) ? "all" : std::to_string(subscribeInfo->GetAppUserId());
138     message.Message("Remove subscriber: " + GetClientBundleName() + " user " +
139         appUserId + " " + std::to_string(result));
140     NotificationAnalyticsUtil::ReportModifyEvent(message);
141     return result;
142 }
143 
NotifyConsumed( const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap)144 void NotificationSubscriberManager::NotifyConsumed(
145     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap)
146 {
147     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
148     if (notificationSubQueue_ == nullptr) {
149         ANS_LOGE("queue is nullptr");
150         return;
151     }
152     AppExecFwk::EventHandler::Callback NotifyConsumedFunc =
153         std::bind(&NotificationSubscriberManager::NotifyConsumedInner, this, notification, notificationMap);
154 
155     notificationSubQueue_->submit(NotifyConsumedFunc);
156 }
157 
BatchNotifyConsumed(const std::vector<sptr<Notification>> &notifications, const sptr<NotificationSortingMap> &notificationMap, const std::shared_ptr<SubscriberRecord> &record)158 void NotificationSubscriberManager::BatchNotifyConsumed(const std::vector<sptr<Notification>> &notifications,
159     const sptr<NotificationSortingMap> &notificationMap, const std::shared_ptr<SubscriberRecord> &record)
160 {
161     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
162     ANS_LOGI("Start batch notifyConsumed.");
163     if (notifications.empty() || notificationMap == nullptr || record == nullptr) {
164         ANS_LOGE("Invalid input.");
165         return;
166     }
167 
168     if (notificationSubQueue_ == nullptr) {
169         ANS_LOGE("Queue is nullptr");
170         return;
171     }
172 
173     AppExecFwk::EventHandler::Callback batchNotifyConsumedFunc = std::bind(
174         &NotificationSubscriberManager::BatchNotifyConsumedInner, this, notifications, notificationMap, record);
175 
176     notificationSubQueue_->submit(batchNotifyConsumedFunc);
177 }
178 
NotifyCanceled( const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)179 void NotificationSubscriberManager::NotifyCanceled(
180     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
181 {
182     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
183 #ifdef ENABLE_ANS_EXT_WRAPPER
184     std::vector<sptr<Notification>> notifications;
185     notifications.emplace_back(notification);
186     EXTENTION_WRAPPER->UpdateByCancel(notifications, deleteReason);
187 #endif
188 
189     if (notificationSubQueue_ == nullptr) {
190         ANS_LOGE("queue is nullptr");
191         return;
192     }
193     AppExecFwk::EventHandler::Callback NotifyCanceledFunc = std::bind(
194         &NotificationSubscriberManager::NotifyCanceledInner, this, notification, notificationMap, deleteReason);
195 
196     notificationSubQueue_->submit(NotifyCanceledFunc);
197 }
198 
BatchNotifyCanceled(const std::vector<sptr<Notification>> &notifications, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)199 void NotificationSubscriberManager::BatchNotifyCanceled(const std::vector<sptr<Notification>> &notifications,
200     const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
201 {
202     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
203 #ifdef ENABLE_ANS_EXT_WRAPPER
204     EXTENTION_WRAPPER->UpdateByCancel(notifications, deleteReason);
205 #endif
206 
207     if (notificationSubQueue_ == nullptr) {
208         ANS_LOGD("queue is nullptr");
209         return;
210     }
211 
212     AppExecFwk::EventHandler::Callback NotifyCanceledFunc = std::bind(
213         &NotificationSubscriberManager::BatchNotifyCanceledInner, this, notifications, notificationMap, deleteReason);
214 
215     notificationSubQueue_->submit(NotifyCanceledFunc);
216 }
217 
NotifyUpdated(const sptr<NotificationSortingMap> &notificationMap)218 void NotificationSubscriberManager::NotifyUpdated(const sptr<NotificationSortingMap> &notificationMap)
219 {
220     if (notificationSubQueue_ == nullptr) {
221         ANS_LOGE("queue is nullptr");
222         return;
223     }
224     AppExecFwk::EventHandler::Callback NotifyUpdatedFunc =
225         std::bind(&NotificationSubscriberManager::NotifyUpdatedInner, this, notificationMap);
226 
227     notificationSubQueue_->submit(NotifyUpdatedFunc);
228 }
229 
NotifyDoNotDisturbDateChanged(const int32_t &userId, const sptr<NotificationDoNotDisturbDate> &date)230 void NotificationSubscriberManager::NotifyDoNotDisturbDateChanged(const int32_t &userId,
231     const sptr<NotificationDoNotDisturbDate> &date)
232 {
233     if (notificationSubQueue_ == nullptr) {
234         ANS_LOGE("queue is nullptr");
235         return;
236     }
237     AppExecFwk::EventHandler::Callback func =
238         std::bind(&NotificationSubscriberManager::NotifyDoNotDisturbDateChangedInner, this, userId, date);
239 
240     notificationSubQueue_->submit(func);
241 }
242 
NotifyEnabledNotificationChanged( const sptr<EnabledNotificationCallbackData> &callbackData)243 void NotificationSubscriberManager::NotifyEnabledNotificationChanged(
244     const sptr<EnabledNotificationCallbackData> &callbackData)
245 {
246     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
247     if (notificationSubQueue_ == nullptr) {
248         ANS_LOGE("queue is nullptr");
249         return;
250     }
251     AppExecFwk::EventHandler::Callback func =
252         std::bind(&NotificationSubscriberManager::NotifyEnabledNotificationChangedInner, this, callbackData);
253 
254     notificationSubQueue_->submit(func);
255 }
256 
NotifyBadgeEnabledChanged(const sptr<EnabledNotificationCallbackData> &callbackData)257 void NotificationSubscriberManager::NotifyBadgeEnabledChanged(const sptr<EnabledNotificationCallbackData> &callbackData)
258 {
259     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
260     if (notificationSubQueue_ == nullptr) {
261         ANS_LOGE("Queue is nullptr.");
262         return;
263     }
264     AppExecFwk::EventHandler::Callback func =
265         std::bind(&NotificationSubscriberManager::NotifyBadgeEnabledChangedInner, this, callbackData);
266 
267     notificationSubQueue_->submit(func);
268 }
269 
OnRemoteDied(const wptr<IRemoteObject> &object)270 void NotificationSubscriberManager::OnRemoteDied(const wptr<IRemoteObject> &object)
271 {
272     ANS_LOGI("OnRemoteDied");
273     if (notificationSubQueue_ == nullptr) {
274         ANS_LOGE("queue is nullptr");
275         return;
276     }
277     ffrt::task_handle handler = notificationSubQueue_->submit_h(std::bind([this, object]() {
278         ANS_LOGE("ffrt enter!");
279         std::shared_ptr<SubscriberRecord> record = FindSubscriberRecord(object);
280         if (record != nullptr) {
281             auto subscriberUid = record->subscriberUid;
282             ANS_LOGI("subscriber removed . subscriberUid = %{public}d", record->subscriberUid);
283             subscriberRecordList_.remove(record);
284             AdvancedNotificationService::GetInstance()->RemoveSystemLiveViewNotificationsOfSa(record->subscriberUid);
285         }
286     }));
287     notificationSubQueue_->wait(handler);
288 }
289 
FindSubscriberRecord( const wptr<IRemoteObject> &object)290 std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> NotificationSubscriberManager::FindSubscriberRecord(
291     const wptr<IRemoteObject> &object)
292 {
293     auto iter = subscriberRecordList_.begin();
294 
295     for (; iter != subscriberRecordList_.end(); iter++) {
296         if ((*iter)->subscriber->AsObject() == object) {
297             return (*iter);
298         }
299     }
300     return nullptr;
301 }
302 
FindSubscriberRecord( const sptr<AnsSubscriberInterface> &subscriber)303 std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> NotificationSubscriberManager::FindSubscriberRecord(
304     const sptr<AnsSubscriberInterface> &subscriber)
305 {
306     auto iter = subscriberRecordList_.begin();
307 
308     for (; iter != subscriberRecordList_.end(); iter++) {
309         if ((*iter)->subscriber->AsObject() == subscriber->AsObject()) {
310             return (*iter);
311         }
312     }
313     return nullptr;
314 }
315 
CreateSubscriberRecord( const sptr<AnsSubscriberInterface> &subscriber)316 std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> NotificationSubscriberManager::CreateSubscriberRecord(
317     const sptr<AnsSubscriberInterface> &subscriber)
318 {
319     std::shared_ptr<SubscriberRecord> record = std::make_shared<SubscriberRecord>();
320     if (record != nullptr) {
321         record->subscriber = subscriber;
322     }
323     return record;
324 }
325 
AddRecordInfo( std::shared_ptr<SubscriberRecord> &record, const sptr<NotificationSubscribeInfo> &subscribeInfo)326 void NotificationSubscriberManager::AddRecordInfo(
327     std::shared_ptr<SubscriberRecord> &record, const sptr<NotificationSubscribeInfo> &subscribeInfo)
328 {
329     if (subscribeInfo != nullptr) {
330         record->bundleList_.clear();
331         record->subscribedAll = true;
332         for (auto bundle : subscribeInfo->GetAppNames()) {
333             record->bundleList_.insert(bundle);
334             record->subscribedAll = false;
335         }
336         record->userId = subscribeInfo->GetAppUserId();
337         // deviceType is empty, use default
338         if (!subscribeInfo->GetDeviceType().empty()) {
339             record->deviceType = subscribeInfo->GetDeviceType();
340         }
341         record->subscriberUid = subscribeInfo->GetSubscriberUid();
342     } else {
343         record->bundleList_.clear();
344         record->subscribedAll = true;
345     }
346 }
347 
RemoveRecordInfo( std::shared_ptr<SubscriberRecord> &record, const sptr<NotificationSubscribeInfo> &subscribeInfo)348 void NotificationSubscriberManager::RemoveRecordInfo(
349     std::shared_ptr<SubscriberRecord> &record, const sptr<NotificationSubscribeInfo> &subscribeInfo)
350 {
351     if (subscribeInfo != nullptr) {
352         for (auto bundle : subscribeInfo->GetAppNames()) {
353             if (record->subscribedAll) {
354                 record->bundleList_.insert(bundle);
355             } else {
356                 record->bundleList_.erase(bundle);
357             }
358         }
359     } else {
360         record->bundleList_.clear();
361         record->subscribedAll = false;
362     }
363 }
364 
AddSubscriberInner( const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)365 ErrCode NotificationSubscriberManager::AddSubscriberInner(
366     const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
367 {
368     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
369     std::shared_ptr<SubscriberRecord> record = FindSubscriberRecord(subscriber);
370     if (record == nullptr) {
371         record = CreateSubscriberRecord(subscriber);
372         if (record == nullptr) {
373             ANS_LOGE("CreateSubscriberRecord failed.");
374             return ERR_ANS_NO_MEMORY;
375         }
376         subscriberRecordList_.push_back(record);
377 
378         record->subscriber->AsObject()->AddDeathRecipient(recipient_);
379 
380         record->subscriber->OnConnected();
381         ANS_LOGI("subscriber is connected.");
382     }
383 
384     AddRecordInfo(record, subscribeInfo);
385     if (onSubscriberAddCallback_ != nullptr) {
386         onSubscriberAddCallback_(record);
387     }
388 
389     return ERR_OK;
390 }
391 
RemoveSubscriberInner( const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)392 ErrCode NotificationSubscriberManager::RemoveSubscriberInner(
393     const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
394 {
395     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
396     std::shared_ptr<SubscriberRecord> record = FindSubscriberRecord(subscriber);
397 
398     if (record == nullptr) {
399         ANS_LOGE("subscriber not found.");
400         return ERR_ANS_INVALID_PARAM;
401     }
402 
403     RemoveRecordInfo(record, subscribeInfo);
404 
405     if (!record->subscribedAll && record->bundleList_.empty()) {
406         record->subscriber->AsObject()->RemoveDeathRecipient(recipient_);
407 
408         subscriberRecordList_.remove(record);
409         record->subscriber->OnDisconnected();
410         ANS_LOGI("subscriber is disconnected.");
411     }
412 
413     return ERR_OK;
414 }
415 
NotifyConsumedInner( const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap)416 void NotificationSubscriberManager::NotifyConsumedInner(
417     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap)
418 {
419     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
420     ANS_LOGD("%{public}s notification->GetUserId <%{public}d>", __FUNCTION__, notification->GetUserId());
421 
422     for (auto record : subscriberRecordList_) {
423         ANS_LOGD("%{public}s record->userId = <%{public}d> BundleName  = <%{public}s deviceType = %{public}s",
424             __FUNCTION__, record->userId, notification->GetBundleName().c_str(), record->deviceType.c_str());
425         if (IsSubscribedBysubscriber(record, notification)) {
426             if (!record->subscriber->AsObject()->IsProxyObject()) {
427                 MessageParcel data;
428                 if (!data.WriteParcelable(notification)) {
429                     ANS_LOGE("WriteParcelable failed.");
430                     continue;
431                 }
432                 sptr<Notification> notificationStub = data.ReadParcelable<Notification>();
433                 if (notificationStub == nullptr) {
434                     ANS_LOGE("ReadParcelable failed.");
435                     continue;
436                 }
437                 record->subscriber->OnConsumed(notificationStub, notificationMap);
438                 continue;
439             }
440             record->subscriber->OnConsumed(notification, notificationMap);
441         }
442     }
443 }
444 
445 #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED
GetIsEnableEffectedRemind()446 bool NotificationSubscriberManager::GetIsEnableEffectedRemind()
447 {
448     // Ignore the impact of the bundleName and userId for smart reminder switch now.
449     for (auto record : subscriberRecordList_) {
450         if (record->deviceType.compare(NotificationConstant::CURRENT_DEVICE_TYPE) != 0) {
451             return true;
452         }
453     }
454     return false;
455 }
456 #endif
457 
BatchNotifyConsumedInner(const std::vector<sptr<Notification>> &notifications, const sptr<NotificationSortingMap> &notificationMap, const std::shared_ptr<SubscriberRecord> &record)458 void NotificationSubscriberManager::BatchNotifyConsumedInner(const std::vector<sptr<Notification>> &notifications,
459     const sptr<NotificationSortingMap> &notificationMap, const std::shared_ptr<SubscriberRecord> &record)
460 {
461     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
462     if (notifications.empty() || notificationMap == nullptr || record == nullptr) {
463         ANS_LOGE("Invalid input.");
464         return;
465     }
466 
467     ANS_LOGD("Record->userId = <%{public}d>", record->userId);
468     std::vector<sptr<Notification>> currNotifications;
469     for (size_t i = 0; i < notifications.size(); i ++) {
470         sptr<Notification> notification = notifications[i];
471         if (notification == nullptr) {
472             continue;
473         }
474         if (IsSubscribedBysubscriber(record, notification)) {
475             currNotifications.emplace_back(notification);
476         }
477     }
478     if (!currNotifications.empty()) {
479         ANS_LOGD("OnConsumedList currNotifications size = <%{public}zu>", currNotifications.size());
480         if (record->subscriber != nullptr) {
481             record->subscriber->OnConsumedList(currNotifications, notificationMap);
482         }
483     }
484 }
485 
NotifyCanceledInner( const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)486 void NotificationSubscriberManager::NotifyCanceledInner(
487     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
488 {
489     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
490     ANS_LOGD("%{public}s notification->GetUserId <%{public}d>", __FUNCTION__, notification->GetUserId());
491     bool isCommonLiveView = notification->GetNotificationRequest().IsCommonLiveView();
492     std::shared_ptr<NotificationLiveViewContent> liveViewContent = nullptr;
493     if (isCommonLiveView) {
494         liveViewContent = std::static_pointer_cast<NotificationLiveViewContent>(
495             notification->GetNotificationRequest().GetContent()->GetNotificationContent());
496         liveViewContent->FillPictureMarshallingMap();
497     }
498 
499     ANS_LOGI("CancelNotification key = %{public}s", notification->GetKey().c_str());
500     for (auto record : subscriberRecordList_) {
501         ANS_LOGD("%{public}s record->userId = <%{public}d>", __FUNCTION__, record->userId);
502         if (IsSubscribedBysubscriber(record, notification)) {
503             record->subscriber->OnCanceled(notification, notificationMap, deleteReason);
504         }
505     }
506 
507     if (isCommonLiveView && liveViewContent != nullptr) {
508         liveViewContent->ClearPictureMarshallingMap();
509     }
510 }
511 
IsSubscribedBysubscriber( const std::shared_ptr<SubscriberRecord> &record, const sptr<Notification> &notification)512 bool NotificationSubscriberManager::IsSubscribedBysubscriber(
513     const std::shared_ptr<SubscriberRecord> &record, const sptr<Notification> &notification)
514 {
515     auto BundleNames = notification->GetBundleName();
516     auto iter = std::find(record->bundleList_.begin(), record->bundleList_.end(), BundleNames);
517     bool isSubscribedTheNotification = record->subscribedAll || (iter != record->bundleList_.end()) ||
518         (notification->GetNotificationRequest().GetCreatorUid() == record->subscriberUid);
519     if (!isSubscribedTheNotification) {
520         return false;
521     }
522 
523     if (record->userId == SUBSCRIBE_USER_ALL || IsSystemUser(record->userId)) {
524         return true;
525     }
526 
527     int32_t recvUserId = notification->GetNotificationRequest().GetReceiverUserId();
528     int32_t sendUserId = notification->GetUserId();
529     if (record->userId == recvUserId) {
530         return true;
531     }
532 
533     if (IsSystemUser(sendUserId)) {
534         return true;
535     }
536 
537     return false;
538 }
539 
BatchNotifyCanceledInner(const std::vector<sptr<Notification>> &notifications, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)540 void NotificationSubscriberManager::BatchNotifyCanceledInner(const std::vector<sptr<Notification>> &notifications,
541     const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
542 {
543     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
544 
545     ANS_LOGD("notifications size = <%{public}zu>", notifications.size());
546     std::string message = "BatchNotifyCanceledInner.size:" +
547         std::to_string(notifications.size()) + ".";
548     OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(1, 9)
549         .ErrorCode(ERR_OK);
550     ReportDeleteFailedEventPush(haMetaMessage, deleteReason, message);
551 
552     std::string notificationKeys = "";
553     for (auto notification : notifications) {
554         notificationKeys.append(notification->GetKey()).append("-");
555     }
556     ANS_LOGI("CancelNotification key = %{public}s", notificationKeys.c_str());
557 
558     for (auto record : subscriberRecordList_) {
559         if (record == nullptr) {
560             continue;
561         }
562         ANS_LOGD("record->userId = <%{public}d>", record->userId);
563         std::vector<sptr<Notification>> currNotifications;
564         for (size_t i = 0; i < notifications.size(); i ++) {
565             sptr<Notification> notification = notifications[i];
566             if (notification == nullptr) {
567                 continue;
568             }
569             auto requestContent = notification->GetNotificationRequest().GetContent();
570             if (notification->GetNotificationRequest().IsCommonLiveView() &&
571                 requestContent->GetNotificationContent() != nullptr) {
572                 auto liveViewContent = std::static_pointer_cast<NotificationLiveViewContent>(
573                     requestContent->GetNotificationContent());
574                 liveViewContent->ClearPictureMap();
575                 liveViewContent->ClearPictureMarshallingMap();
576                 ANS_LOGD("live view batch delete clear picture");
577             }
578             if (notification->GetNotificationRequest().IsSystemLiveView() &&
579                 requestContent->GetNotificationContent() != nullptr) {
580                 auto localLiveViewContent = std::static_pointer_cast<NotificationLocalLiveViewContent>(
581                     requestContent->GetNotificationContent());
582                 localLiveViewContent->ClearButton();
583                 localLiveViewContent->ClearCapsuleIcon();
584                 ANS_LOGD("local live view batch delete clear picture");
585             }
586             if (IsSubscribedBysubscriber(record, notification)) {
587                 currNotifications.emplace_back(notification);
588             }
589         }
590         if (!currNotifications.empty()) {
591             ANS_LOGD("onCanceledList currNotifications size = <%{public}zu>", currNotifications.size());
592             if (record->subscriber != nullptr) {
593                 record->subscriber->OnCanceledList(currNotifications, notificationMap, deleteReason);
594             }
595         }
596     }
597 }
598 
NotifyUpdatedInner(const sptr<NotificationSortingMap> &notificationMap)599 void NotificationSubscriberManager::NotifyUpdatedInner(const sptr<NotificationSortingMap> &notificationMap)
600 {
601     for (auto record : subscriberRecordList_) {
602         record->subscriber->OnUpdated(notificationMap);
603     }
604 }
605 
NotifyDoNotDisturbDateChangedInner(const int32_t &userId, const sptr<NotificationDoNotDisturbDate> &date)606 void NotificationSubscriberManager::NotifyDoNotDisturbDateChangedInner(const int32_t &userId,
607     const sptr<NotificationDoNotDisturbDate> &date)
608 {
609     for (auto record : subscriberRecordList_) {
610         if (record->userId == SUBSCRIBE_USER_ALL || IsSystemUser(record->userId) ||
611             IsSystemUser(userId) || record->userId == userId) {
612             record->subscriber->OnDoNotDisturbDateChange(date);
613         }
614     }
615 }
616 
NotifyBadgeEnabledChangedInner( const sptr<EnabledNotificationCallbackData> &callbackData)617 void NotificationSubscriberManager::NotifyBadgeEnabledChangedInner(
618     const sptr<EnabledNotificationCallbackData> &callbackData)
619 {
620     int32_t userId = SUBSCRIBE_USER_INIT;
621     OsAccountManagerHelper::GetInstance().GetOsAccountLocalIdFromUid(callbackData->GetUid(), userId);
622     for (auto record : subscriberRecordList_) {
623         if (record->userId == SUBSCRIBE_USER_ALL || IsSystemUser(record->userId) ||
624             IsSystemUser(userId) || record->userId == userId) {
625             record->subscriber->OnBadgeEnabledChanged(callbackData);
626         }
627     }
628 }
629 
IsSystemUser(int32_t userId)630 bool NotificationSubscriberManager::IsSystemUser(int32_t userId)
631 {
632     return ((userId >= SUBSCRIBE_USER_SYSTEM_BEGIN) && (userId <= SUBSCRIBE_USER_SYSTEM_END));
633 }
634 
NotifyEnabledNotificationChangedInner( const sptr<EnabledNotificationCallbackData> &callbackData)635 void NotificationSubscriberManager::NotifyEnabledNotificationChangedInner(
636     const sptr<EnabledNotificationCallbackData> &callbackData)
637 {
638     int32_t userId = SUBSCRIBE_USER_INIT;
639     OsAccountManagerHelper::GetInstance().GetOsAccountLocalIdFromUid(callbackData->GetUid(), userId);
640     for (auto record : subscriberRecordList_) {
641         if (record->userId == SUBSCRIBE_USER_ALL || IsSystemUser(record->userId) ||
642                 IsSystemUser(userId) || record->userId == userId) {
643             record->subscriber->OnEnabledNotificationChanged(callbackData);
644         }
645     }
646 }
647 
SetBadgeNumber(const sptr<BadgeNumberCallbackData> &badgeData)648 void NotificationSubscriberManager::SetBadgeNumber(const sptr<BadgeNumberCallbackData> &badgeData)
649 {
650     if (notificationSubQueue_ == nullptr) {
651         ANS_LOGE("queue is nullptr");
652         return;
653     }
654     std::function<void()> setBadgeNumberFunc = [this, badgeData] () {
655         int32_t userId = SUBSCRIBE_USER_INIT;
656         OsAccountManagerHelper::GetInstance().GetOsAccountLocalIdFromUid(badgeData->GetUid(), userId);
657         for (auto record : subscriberRecordList_) {
658             if (record->userId == SUBSCRIBE_USER_ALL || IsSystemUser(record->userId) ||
659                 IsSystemUser(userId) || record->userId == userId) {
660                 record->subscriber->OnBadgeChanged(badgeData);
661             }
662         }
663     };
664     notificationSubQueue_->submit(setBadgeNumberFunc);
665 }
666 
RegisterOnSubscriberAddCallback( std::function<void(const std::shared_ptr<SubscriberRecord> &)> callback)667 void NotificationSubscriberManager::RegisterOnSubscriberAddCallback(
668     std::function<void(const std::shared_ptr<SubscriberRecord> &)> callback)
669 {
670     if (callback == nullptr) {
671         ANS_LOGE("Callback is nullptr");
672         return;
673     }
674 
675     onSubscriberAddCallback_ = callback;
676 }
677 
UnRegisterOnSubscriberAddCallback()678 void NotificationSubscriberManager::UnRegisterOnSubscriberAddCallback()
679 {
680     onSubscriberAddCallback_ = nullptr;
681 }
682 
683 using SubscriberRecordPtr = std::shared_ptr<NotificationSubscriberManager::SubscriberRecord>;
GetSubscriberRecords()684 std::list<SubscriberRecordPtr> NotificationSubscriberManager::GetSubscriberRecords()
685 {
686     return subscriberRecordList_;
687 }
688 
689 }  // namespace Notification
690 }  // namespace OHOS
691