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