• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #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_trace_wrapper.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 "bool_wrapper.h"
37 #include "advanced_notification_inline.h"
38 #include "liveview_all_scenarios_extension_wrapper.h"
39 #ifdef ALL_SCENARIO_COLLABORATION
40 #include "distributed_collaboration_service.h"
41 #endif
42 
43 namespace OHOS {
44 namespace Notification {
45 struct NotificationSubscriberManager::SubscriberRecord {
46     sptr<IAnsSubscriber> subscriber {nullptr};
47     std::set<std::string> bundleList_ {};
48     bool subscribedAll {false};
49     int32_t userId {SUBSCRIBE_USER_INIT};
50     std::string deviceType {CURRENT_DEVICE_TYPE};
51     int32_t subscriberUid {DEFAULT_UID};
52     bool needNotifyApplicationChanged = false;
53     bool needNotifyResponse = false;
54     uint32_t filterType {0};
55     std::set<NotificationConstant::SlotType> slotTypes {};
56     bool isSubscribeSelf = false;
57 };
58 
59 const uint32_t FILTETYPE_IM = 1 << 0;
60 const uint32_t FILTETYPE_QUICK_REPLY_IM = 2 << 0;
61 static const std::string EXTENDINFO_INFO_PRE = "notification_collaboration_";
62 static const std::string EXTENDINFO_DEVICE_ID = "deviceId";
63 
NotificationSubscriberManager()64 NotificationSubscriberManager::NotificationSubscriberManager()
65 {
66     ANS_LOGD("called");
67     notificationSubQueue_ = std::make_shared<ffrt::queue>("NotificationSubscriberMgr");
68     recipient_ = new (std::nothrow)
69         RemoteDeathRecipient(std::bind(&NotificationSubscriberManager::OnRemoteDied, this, std::placeholders::_1));
70     if (recipient_ == nullptr) {
71         ANS_LOGE("Failed to create RemoteDeathRecipient instance");
72     }
73 }
74 
~NotificationSubscriberManager()75 NotificationSubscriberManager::~NotificationSubscriberManager()
76 {
77     ANS_LOGD("called");
78     subscriberRecordList_.clear();
79 }
80 
ResetFfrtQueue()81 void NotificationSubscriberManager::ResetFfrtQueue()
82 {
83     if (notificationSubQueue_ != nullptr) {
84         notificationSubQueue_.reset();
85     }
86 }
87 
AddSubscriber(const sptr<IAnsSubscriber> & subscriber,const sptr<NotificationSubscribeInfo> & subscribeInfo)88 ErrCode NotificationSubscriberManager::AddSubscriber(
89     const sptr<IAnsSubscriber> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
90 {
91     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
92     if (subscriber == nullptr) {
93         ANS_LOGE("null subscriber");
94         return ERR_ANS_INVALID_PARAM;
95     }
96 
97     sptr<NotificationSubscribeInfo> subInfo = subscribeInfo;
98     if (subInfo == nullptr) {
99         subInfo = new (std::nothrow) NotificationSubscribeInfo();
100         if (subInfo == nullptr) {
101             ANS_LOGE("null subInfo");
102             return ERR_ANS_NO_MEMORY;
103         }
104     }
105 
106     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_9, EventBranchId::BRANCH_2);
107     message.Message(GetClientBundleName() + "_" +
108         " user:" + std::to_string(subInfo->GetAppUserId()));
109     if (subInfo->GetAppUserId() == SUBSCRIBE_USER_INIT) {
110         int32_t userId = SUBSCRIBE_USER_INIT;
111         ErrCode ret = OsAccountManagerHelper::GetInstance().GetCurrentCallingUserId(userId);
112         if (ret != ERR_OK) {
113             ANS_LOGE("Get current calling userId failed.");
114             message.ErrorCode(ret).Append(" Get userId Failed");
115             NotificationAnalyticsUtil::ReportModifyEvent(message);
116             return ret;
117         }
118         subInfo->AddAppUserId(userId);
119     }
120 
121     ErrCode result = ERR_ANS_TASK_ERR;
122     if (notificationSubQueue_ == nullptr) {
123         ANS_LOGE("null queue");
124         return result;
125     }
126 
127     ffrt::task_handle handler = notificationSubQueue_->submit_h(std::bind([this, &subscriber, &subInfo, &result]() {
128         result = this->AddSubscriberInner(subscriber, subInfo);
129     }));
130     notificationSubQueue_->wait(handler);
131 
132     std::string bundleNames;
133     for (auto bundleName : subInfo->GetAppNames()) {
134         bundleNames += bundleName;
135         bundleNames += " ";
136     }
137     std::string slotTypes;
138     for (auto slotType : subInfo->GetSlotTypes()) {
139         slotTypes += std::to_string(slotType);
140         slotTypes += " ";
141     }
142     ANS_LOGI("%{public}s_, user: %{public}s, bundleNames: %{public}s, deviceType: %{public}s, slotTypes: %{public}s, "
143         "Add subscriber result: %{public}d", GetClientBundleName().c_str(),
144         std::to_string(subInfo->GetAppUserId()).c_str(), bundleNames.c_str(), subInfo->GetDeviceType().c_str(),
145         slotTypes.c_str(), result);
146     message.ErrorCode(result).Append(bundleNames + "," + subInfo->GetDeviceType() + "," + slotTypes);
147     NotificationAnalyticsUtil::ReportModifyEvent(message);
148     return result;
149 }
150 
RemoveSubscriber(const sptr<IAnsSubscriber> & subscriber,const sptr<NotificationSubscribeInfo> & subscribeInfo)151 ErrCode NotificationSubscriberManager::RemoveSubscriber(
152     const sptr<IAnsSubscriber> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
153 {
154     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
155     if (subscriber == nullptr) {
156         ANS_LOGE("null subscriber");
157         return ERR_ANS_INVALID_PARAM;
158     }
159 
160     ErrCode result = ERR_ANS_TASK_ERR;
161     if (notificationSubQueue_ == nullptr) {
162         ANS_LOGE("null queue");
163         return result;
164     }
165     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_9, EventBranchId::BRANCH_1);
166     ffrt::task_handle handler = notificationSubQueue_->submit_h(std::bind([this, &subscriber,
167         &subscribeInfo, &result]() {
168         ANS_LOGE("ffrt enter!");
169         result = this->RemoveSubscriberInner(subscriber, subscribeInfo);
170     }));
171     notificationSubQueue_->wait(handler);
172     std::string appUserId = (subscribeInfo == nullptr) ? "all" : std::to_string(subscribeInfo->GetAppUserId());
173 
174     ANS_LOGI("%{public}s_, user: %{public}s, Remove subscriber result: %{public}d", GetClientBundleName().c_str(),
175         appUserId.c_str(), result);
176     message.Message(GetClientBundleName() + "_" + "  user:" + appUserId);
177     message.ErrorCode(result);
178     NotificationAnalyticsUtil::ReportModifyEvent(message);
179     return result;
180 }
181 
NotifyConsumed(const sptr<Notification> & notification,const sptr<NotificationSortingMap> & notificationMap)182 void NotificationSubscriberManager::NotifyConsumed(
183     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap)
184 {
185     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
186     if (notificationSubQueue_ == nullptr) {
187         ANS_LOGE("null queue");
188         return;
189     }
190     AppExecFwk::EventHandler::Callback NotifyConsumedFunc =
191         std::bind(&NotificationSubscriberManager::NotifyConsumedInner, this, notification, notificationMap);
192 
193     notificationSubQueue_->submit(NotifyConsumedFunc);
194 }
195 
NotifyApplicationInfoNeedChanged(const std::string & bundleName)196 void NotificationSubscriberManager::NotifyApplicationInfoNeedChanged(const std::string& bundleName)
197 {
198     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
199     if (notificationSubQueue_ == nullptr || bundleName.empty()) {
200         ANS_LOGE("null queue");
201         return;
202     }
203     AppExecFwk::EventHandler::Callback NotifyConsumedFunc =
204         std::bind(&NotificationSubscriberManager::NotifyApplicationInfochangedInner, this, bundleName);
205 
206     notificationSubQueue_->submit(NotifyConsumedFunc);
207 }
208 
209 
NotifyApplicationInfochangedInner(const std::string & bundleName)210 void NotificationSubscriberManager::NotifyApplicationInfochangedInner(const std::string& bundleName)
211 {
212     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
213     ANS_LOGD("bundleName: %{public}s", bundleName.c_str());
214     for (auto record : subscriberRecordList_) {
215         if (record->needNotifyApplicationChanged) {
216             record->subscriber->OnApplicationInfoNeedChanged(bundleName);
217         }
218     }
219 }
220 
BatchNotifyConsumed(const std::vector<sptr<Notification>> & notifications,const sptr<NotificationSortingMap> & notificationMap,const std::shared_ptr<SubscriberRecord> & record)221 void NotificationSubscriberManager::BatchNotifyConsumed(const std::vector<sptr<Notification>> &notifications,
222     const sptr<NotificationSortingMap> &notificationMap, const std::shared_ptr<SubscriberRecord> &record)
223 {
224     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
225     ANS_LOGI("Start batch notifyConsumed.");
226     if (notifications.empty() || notificationMap == nullptr || record == nullptr) {
227         ANS_LOGE("Invalid input.");
228         return;
229     }
230 
231     if (notificationSubQueue_ == nullptr) {
232         ANS_LOGE("null queue");
233         return;
234     }
235 
236 #ifdef ALL_SCENARIO_COLLABORATION
237     for (auto item : notifications) {
238         DistributedCollaborationService::GetInstance().AddCollaborativeDeleteItem(item);
239     }
240 #endif
241     AppExecFwk::EventHandler::Callback batchNotifyConsumedFunc = std::bind(
242         &NotificationSubscriberManager::BatchNotifyConsumedInner, this, notifications, notificationMap, record);
243 
244     notificationSubQueue_->submit(batchNotifyConsumedFunc);
245 }
246 
NotifyCanceled(const sptr<Notification> & notification,const sptr<NotificationSortingMap> & notificationMap,int32_t deleteReason)247 void NotificationSubscriberManager::NotifyCanceled(
248     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
249 {
250     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
251 #ifdef ENABLE_ANS_AGGREGATION
252     std::vector<sptr<Notification>> notifications;
253     notifications.emplace_back(notification);
254     EXTENTION_WRAPPER->UpdateByCancel(notifications, deleteReason);
255 #endif
256 
257     if (notificationSubQueue_ == nullptr) {
258         ANS_LOGE("null queue");
259         return;
260     }
261 #ifdef ALL_SCENARIO_COLLABORATION
262     DistributedCollaborationService::GetInstance().AddCollaborativeDeleteItem(notification);
263 #endif
264     AppExecFwk::EventHandler::Callback NotifyCanceledFunc = std::bind(
265         &NotificationSubscriberManager::NotifyCanceledInner, this, notification, notificationMap, deleteReason);
266 
267     notificationSubQueue_->submit(NotifyCanceledFunc);
268 }
269 
BatchNotifyCanceled(const std::vector<sptr<Notification>> & notifications,const sptr<NotificationSortingMap> & notificationMap,int32_t deleteReason)270 void NotificationSubscriberManager::BatchNotifyCanceled(const std::vector<sptr<Notification>> &notifications,
271     const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
272 {
273     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
274 #ifdef ENABLE_ANS_AGGREGATION
275     EXTENTION_WRAPPER->UpdateByCancel(notifications, deleteReason);
276 #endif
277 
278     if (notificationSubQueue_ == nullptr) {
279         ANS_LOGD("queue is nullptr");
280         return;
281     }
282     AppExecFwk::EventHandler::Callback NotifyCanceledFunc = std::bind(
283         &NotificationSubscriberManager::BatchNotifyCanceledInner, this, notifications, notificationMap, deleteReason);
284 
285     notificationSubQueue_->submit(NotifyCanceledFunc);
286 }
287 
NotifyUpdated(const sptr<NotificationSortingMap> & notificationMap)288 void NotificationSubscriberManager::NotifyUpdated(const sptr<NotificationSortingMap> &notificationMap)
289 {
290     if (notificationSubQueue_ == nullptr) {
291         ANS_LOGE("null queue");
292         return;
293     }
294     AppExecFwk::EventHandler::Callback NotifyUpdatedFunc =
295         std::bind(&NotificationSubscriberManager::NotifyUpdatedInner, this, notificationMap);
296 
297     notificationSubQueue_->submit(NotifyUpdatedFunc);
298 }
299 
NotifyDoNotDisturbDateChanged(const int32_t & userId,const sptr<NotificationDoNotDisturbDate> & date,const std::string & bundle)300 void NotificationSubscriberManager::NotifyDoNotDisturbDateChanged(const int32_t &userId,
301     const sptr<NotificationDoNotDisturbDate> &date, const std::string &bundle)
302 {
303     if (notificationSubQueue_ == nullptr) {
304         ANS_LOGE("null queue");
305         return;
306     }
307     AppExecFwk::EventHandler::Callback func =
308         std::bind(&NotificationSubscriberManager::NotifyDoNotDisturbDateChangedInner, this, userId, date, bundle);
309 
310     notificationSubQueue_->submit(func);
311 }
312 
NotifyEnabledNotificationChanged(const sptr<EnabledNotificationCallbackData> & callbackData)313 void NotificationSubscriberManager::NotifyEnabledNotificationChanged(
314     const sptr<EnabledNotificationCallbackData> &callbackData)
315 {
316     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
317     if (notificationSubQueue_ == nullptr) {
318         ANS_LOGE("null queue");
319         return;
320     }
321     AppExecFwk::EventHandler::Callback func =
322         std::bind(&NotificationSubscriberManager::NotifyEnabledNotificationChangedInner, this, callbackData);
323 
324     notificationSubQueue_->submit(func);
325 }
326 
NotifyBadgeEnabledChanged(const sptr<EnabledNotificationCallbackData> & callbackData)327 void NotificationSubscriberManager::NotifyBadgeEnabledChanged(const sptr<EnabledNotificationCallbackData> &callbackData)
328 {
329     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
330     if (notificationSubQueue_ == nullptr) {
331         ANS_LOGE("null queue");
332         return;
333     }
334     AppExecFwk::EventHandler::Callback func =
335         std::bind(&NotificationSubscriberManager::NotifyBadgeEnabledChangedInner, this, callbackData);
336 
337     notificationSubQueue_->submit(func);
338 }
339 
OnRemoteDied(const wptr<IRemoteObject> & object)340 void NotificationSubscriberManager::OnRemoteDied(const wptr<IRemoteObject> &object)
341 {
342     ANS_LOGD("called");
343     if (notificationSubQueue_ == nullptr) {
344         ANS_LOGE("null queue");
345         return;
346     }
347     ffrt::task_handle handler = notificationSubQueue_->submit_h(std::bind([this, object]() {
348         ANS_LOGD("ffrt enter!");
349         std::shared_ptr<SubscriberRecord> record = FindSubscriberRecord(object);
350         if (record != nullptr) {
351             auto subscriberUid = record->subscriberUid;
352             ANS_LOGI("subscriber removed . subscriberUid = %{public}d", record->subscriberUid);
353             subscriberRecordList_.remove(record);
354             AdvancedNotificationService::GetInstance()->RemoveSystemLiveViewNotificationsOfSa(record->subscriberUid);
355         }
356     }));
357     notificationSubQueue_->wait(handler);
358 }
359 
FindSubscriberRecord(const wptr<IRemoteObject> & object)360 std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> NotificationSubscriberManager::FindSubscriberRecord(
361     const wptr<IRemoteObject> &object)
362 {
363     auto iter = subscriberRecordList_.begin();
364 
365     for (; iter != subscriberRecordList_.end(); iter++) {
366         if ((*iter)->subscriber->AsObject() == object) {
367             return (*iter);
368         }
369     }
370     return nullptr;
371 }
372 
FindSubscriberRecord(const sptr<IAnsSubscriber> & subscriber)373 std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> NotificationSubscriberManager::FindSubscriberRecord(
374     const sptr<IAnsSubscriber> &subscriber)
375 {
376     auto iter = subscriberRecordList_.begin();
377 
378     for (; iter != subscriberRecordList_.end(); iter++) {
379         if ((*iter)->subscriber->AsObject() == subscriber->AsObject()) {
380             return (*iter);
381         }
382     }
383     return nullptr;
384 }
385 
CreateSubscriberRecord(const sptr<IAnsSubscriber> & subscriber)386 std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> NotificationSubscriberManager::CreateSubscriberRecord(
387     const sptr<IAnsSubscriber> &subscriber)
388 {
389     std::shared_ptr<SubscriberRecord> record = std::make_shared<SubscriberRecord>();
390     if (record != nullptr) {
391         record->subscriber = subscriber;
392     }
393     return record;
394 }
395 
AddRecordInfo(std::shared_ptr<SubscriberRecord> & record,const sptr<NotificationSubscribeInfo> & subscribeInfo)396 void NotificationSubscriberManager::AddRecordInfo(
397     std::shared_ptr<SubscriberRecord> &record, const sptr<NotificationSubscribeInfo> &subscribeInfo)
398 {
399     if (subscribeInfo != nullptr) {
400         record->bundleList_.clear();
401         record->subscribedAll = true;
402         for (auto bundle : subscribeInfo->GetAppNames()) {
403             record->bundleList_.insert(bundle);
404             record->subscribedAll = false;
405         }
406         record->slotTypes.clear();
407         for (auto slotType : subscribeInfo->GetSlotTypes()) {
408             record->slotTypes.insert(slotType);
409         }
410         record->userId = subscribeInfo->GetAppUserId();
411         // deviceType is empty, use default
412         if (!subscribeInfo->GetDeviceType().empty()) {
413             record->deviceType = subscribeInfo->GetDeviceType();
414         }
415         record->subscriberUid = subscribeInfo->GetSubscriberUid();
416         record->filterType = subscribeInfo->GetFilterType();
417         record->needNotifyApplicationChanged = subscribeInfo->GetNeedNotifyApplication();
418         record->needNotifyResponse = subscribeInfo->GetNeedNotifyResponse();
419         record->isSubscribeSelf = subscribeInfo->GetIsSubscribeSelf();
420     } else {
421         record->bundleList_.clear();
422         record->subscribedAll = true;
423         record->slotTypes.clear();
424     }
425 }
426 
RemoveRecordInfo(std::shared_ptr<SubscriberRecord> & record,const sptr<NotificationSubscribeInfo> & subscribeInfo)427 void NotificationSubscriberManager::RemoveRecordInfo(
428     std::shared_ptr<SubscriberRecord> &record, const sptr<NotificationSubscribeInfo> &subscribeInfo)
429 {
430     if (subscribeInfo != nullptr) {
431         for (auto bundle : subscribeInfo->GetAppNames()) {
432             if (record->subscribedAll) {
433                 record->bundleList_.insert(bundle);
434             } else {
435                 record->bundleList_.erase(bundle);
436             }
437         }
438     } else {
439         record->bundleList_.clear();
440         record->subscribedAll = false;
441     }
442 }
443 
AddSubscriberInner(const sptr<IAnsSubscriber> & subscriber,const sptr<NotificationSubscribeInfo> & subscribeInfo)444 ErrCode NotificationSubscriberManager::AddSubscriberInner(
445     const sptr<IAnsSubscriber> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
446 {
447     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
448     std::shared_ptr<SubscriberRecord> record = FindSubscriberRecord(subscriber);
449     if (record == nullptr) {
450         record = CreateSubscriberRecord(subscriber);
451         if (record == nullptr) {
452             ANS_LOGE("null record");
453             return ERR_ANS_NO_MEMORY;
454         }
455         subscriberRecordList_.push_back(record);
456 
457         record->subscriber->AsObject()->AddDeathRecipient(recipient_);
458 
459         record->subscriber->OnConnected();
460         ANS_LOGD("subscriber connected");
461     }
462 
463     AddRecordInfo(record, subscribeInfo);
464     if (onSubscriberAddCallback_ != nullptr) {
465         onSubscriberAddCallback_(record);
466     }
467 
468     if (subscribeInfo->GetDeviceType() == DEVICE_TYPE_WEARABLE ||
469         subscribeInfo->GetDeviceType() == DEVICE_TYPE_LITE_WEARABLE) {
470         AdvancedNotificationService::GetInstance()->SetAndPublishSubscriberExistFlag(DEVICE_TYPE_WEARABLE, true);
471     }
472     if (subscribeInfo->GetDeviceType() == DEVICE_TYPE_HEADSET) {
473         AdvancedNotificationService::GetInstance()->SetAndPublishSubscriberExistFlag(DEVICE_TYPE_HEADSET, true);
474     }
475     return ERR_OK;
476 }
477 
RemoveSubscriberInner(const sptr<IAnsSubscriber> & subscriber,const sptr<NotificationSubscribeInfo> & subscribeInfo)478 ErrCode NotificationSubscriberManager::RemoveSubscriberInner(
479     const sptr<IAnsSubscriber> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
480 {
481     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
482     std::shared_ptr<SubscriberRecord> record = FindSubscriberRecord(subscriber);
483 
484     if (record == nullptr) {
485         ANS_LOGE("null record");
486         return ERR_ANS_INVALID_PARAM;
487     }
488 
489     RemoveRecordInfo(record, subscribeInfo);
490 
491     if (!record->subscribedAll && record->bundleList_.empty()) {
492         record->subscriber->AsObject()->RemoveDeathRecipient(recipient_);
493 
494         subscriberRecordList_.remove(record);
495         record->subscriber->OnDisconnected();
496         ANS_LOGI("subscriber is disconnected.");
497     }
498 
499     return ERR_OK;
500 }
501 
NotifyConsumedInner(const sptr<Notification> & notification,const sptr<NotificationSortingMap> & notificationMap)502 void NotificationSubscriberManager::NotifyConsumedInner(
503     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap)
504 {
505     if (notification == nullptr) {
506         ANS_LOGE("null notification");
507         return;
508     }
509     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
510     ANS_LOGD("%{public}s notification->GetUserId <%{public}d>", __FUNCTION__, notification->GetUserId());
511 
512     for (auto record : subscriberRecordList_) {
513         ANS_LOGD("%{public}s record->userId = <%{public}d> BundleName  = <%{public}s deviceType = %{public}s",
514             __FUNCTION__, record->userId, notification->GetBundleName().c_str(), record->deviceType.c_str());
515         if (IsSubscribedBysubscriber(record, notification) && ConsumeRecordFilter(record, notification)) {
516             if (!record->subscriber->AsObject()->IsProxyObject()) {
517                 MessageParcel data;
518                 if (!data.WriteParcelable(notification)) {
519                     ANS_LOGE("WriteParcelable failed.");
520                     continue;
521                 }
522                 sptr<Notification> notificationStub = data.ReadParcelable<Notification>();
523                 if (notificationStub == nullptr) {
524                     ANS_LOGE("null notificationStub");
525                     continue;
526                 }
527                 record->subscriber->OnConsumed(notificationStub, notificationMap);
528                 continue;
529             }
530 
531         if (notificationMap != nullptr && notification->GetNotificationRequestPoint()->IsCommonLiveView()) {
532             record->subscriber->OnConsumedWithMaxCapacity(notification, notificationMap);
533         } else if (notificationMap != nullptr && !notification->GetNotificationRequestPoint()->IsCommonLiveView()) {
534             record->subscriber->OnConsumed(notification, notificationMap);
535         } else if (notificationMap == nullptr && notification->GetNotificationRequestPoint()->IsCommonLiveView()) {
536             record->subscriber->OnConsumedWithMaxCapacity(notification);
537         } else {
538             record->subscriber->OnConsumed(notification);
539         }
540         }
541     }
542     NotificationSubscriberManager::TrackCodeLog(notification);
543 }
544 
545 #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED
GetIsEnableEffectedRemind()546 bool NotificationSubscriberManager::GetIsEnableEffectedRemind()
547 {
548     // Ignore the impact of the bundleName and userId for smart reminder switch now.
549     for (auto record : subscriberRecordList_) {
550         if (record->deviceType.compare(NotificationConstant::CURRENT_DEVICE_TYPE) != 0) {
551             return true;
552         }
553     }
554     return false;
555 }
556 
IsDeviceTypeSubscriberd(const std::string deviceType)557 bool NotificationSubscriberManager::IsDeviceTypeSubscriberd(const std::string deviceType)
558 {
559     for (auto record : subscriberRecordList_) {
560         if (record->deviceType.compare(deviceType) == 0) {
561             return true;
562         }
563     }
564     ANS_LOGE("device = %{public}s", deviceType.c_str());
565     return false;
566 }
567 
IsDeviceTypeAffordConsume(const std::string deviceType,const sptr<NotificationRequest> & request,bool & result)568 ErrCode NotificationSubscriberManager::IsDeviceTypeAffordConsume(
569     const std::string deviceType,
570     const sptr<NotificationRequest> &request,
571     bool &result)
572 {
573     for (auto record : subscriberRecordList_) {
574         if (record->deviceType.compare(deviceType) != 0) {
575             continue;
576         }
577         sptr<Notification> notification = new (std::nothrow) Notification(request);
578         if (notification == nullptr) {
579             ANS_LOGE("null notification");
580             return ERR_ANS_NO_MEMORY;
581         }
582         if (IsSubscribedBysubscriber(record, notification) && ConsumeRecordFilter(record, notification)) {
583             result = true;
584             return ERR_OK;
585         }
586     }
587     result = false;
588     return ERR_OK;
589 }
590 #endif
591 
BatchNotifyConsumedInner(const std::vector<sptr<Notification>> & notifications,const sptr<NotificationSortingMap> & notificationMap,const std::shared_ptr<SubscriberRecord> & record)592 void NotificationSubscriberManager::BatchNotifyConsumedInner(const std::vector<sptr<Notification>> &notifications,
593     const sptr<NotificationSortingMap> &notificationMap, const std::shared_ptr<SubscriberRecord> &record)
594 {
595     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
596     if (notifications.empty() || notificationMap == nullptr || record == nullptr) {
597         ANS_LOGE("Invalid input.");
598         return;
599     }
600 
601     ANS_LOGD("Record->userId = <%{public}d>", record->userId);
602     std::vector<sptr<Notification>> currNotifications;
603     for (size_t i = 0; i < notifications.size(); i ++) {
604         sptr<Notification> notification = notifications[i];
605         if (notification == nullptr) {
606             continue;
607         }
608         bool wearableFlag = false;
609         bool headsetFlag = false;
610         bool keyNodeFlag = false;
611         if (IsSubscribedBysubscriber(record, notification) && ConsumeRecordFilter(record, notification)) {
612             currNotifications.emplace_back(notification);
613             if (record->subscriber != nullptr) {
614                 NotificationSubscriberManager::TrackCodeLog(notification);
615             }
616         }
617     }
618     if (!currNotifications.empty()) {
619         ANS_LOGD("OnConsumedList currNotifications size = <%{public}zu>", currNotifications.size());
620         if (record->subscriber != nullptr) {
621             if (notificationMap != nullptr) {
622                 record->subscriber->OnConsumedList(currNotifications, notificationMap);
623             } else {
624                 record->subscriber->OnConsumedList(currNotifications);
625             }
626         }
627     }
628 }
629 
NotifyCanceledInner(const sptr<Notification> & notification,const sptr<NotificationSortingMap> & notificationMap,int32_t deleteReason)630 void NotificationSubscriberManager::NotifyCanceledInner(
631     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
632 {
633     if (notification == nullptr) {
634         ANS_LOGE("null notification");
635         return;
636     }
637     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
638     ANS_LOGD("%{public}s notification->GetUserId <%{public}d>", __FUNCTION__, notification->GetUserId());
639     std::shared_ptr<NotificationLiveViewContent> liveViewContent = nullptr;
640 
641     ANS_LOGI("CancelNotification key = %{public}s", notification->GetKey().c_str());
642     for (auto record : subscriberRecordList_) {
643         ANS_LOGD("%{public}s record->userId = <%{public}d>", __FUNCTION__, record->userId);
644         if (IsSubscribedBysubscriber(record, notification)) {
645             if (notificationMap != nullptr && notification->GetNotificationRequestPoint()->IsCommonLiveView()) {
646                 record->subscriber->OnCanceledWithMaxCapacity(notification, notificationMap, deleteReason);
647             } else if (notificationMap != nullptr && !notification->GetNotificationRequestPoint()->IsCommonLiveView()) {
648                 record->subscriber->OnCanceled(notification, notificationMap, deleteReason);
649             } else if (notificationMap == nullptr && notification->GetNotificationRequestPoint()->IsCommonLiveView()) {
650                 record->subscriber->OnCanceledWithMaxCapacity(notification, deleteReason);
651             } else {
652                 record->subscriber->OnCanceled(notification, deleteReason);
653             }
654         }
655     }
656 }
657 
IsSubscribedBysubscriber(const std::shared_ptr<SubscriberRecord> & record,const sptr<Notification> & notification)658 bool NotificationSubscriberManager::IsSubscribedBysubscriber(
659     const std::shared_ptr<SubscriberRecord> &record, const sptr<Notification> &notification)
660 {
661     auto BundleNames = notification->GetBundleName();
662     auto iter = std::find(record->bundleList_.begin(), record->bundleList_.end(), BundleNames);
663     bool isSubscribedTheNotification = record->subscribedAll || (iter != record->bundleList_.end()) ||
664         (notification->GetNotificationRequestPoint()->GetCreatorUid() == record->subscriberUid);
665     if (!isSubscribedTheNotification) {
666         return false;
667     }
668     auto soltType = notification->GetNotificationRequestPoint()->GetSlotType();
669     auto slotIter = std::find(record->slotTypes.begin(), record->slotTypes.end(), soltType);
670     bool isSubscribedSlotType = (record->slotTypes.size() == 0) || (slotIter != record->slotTypes.end());
671     if (!isSubscribedSlotType) {
672         return false;
673     }
674 
675     if (record->userId == SUBSCRIBE_USER_ALL || IsSystemUser(record->userId)) {
676         return true;
677     }
678 
679     int32_t recvUserId = notification->GetNotificationRequestPoint()->GetReceiverUserId();
680     int32_t sendUserId = notification->GetUserId();
681     if (record->userId == recvUserId) {
682         return true;
683     }
684 
685     if (IsSystemUser(sendUserId)) {
686         return true;
687     }
688 
689     return false;
690 }
691 
ConsumeRecordFilter(const std::shared_ptr<SubscriberRecord> & record,const sptr<Notification> & notification)692 bool NotificationSubscriberManager::ConsumeRecordFilter(
693     const std::shared_ptr<SubscriberRecord> &record, const sptr<Notification> &notification)
694 {
695     NotificationRequest request = notification->GetNotificationRequest();
696     // filterType
697     ANS_LOGD("filterType = %{public}u", record->filterType);
698     if (NotificationConstant::SlotType::SOCIAL_COMMUNICATION == request.GetSlotType()) {
699         bool isQuickReply = request.HasUserInputButton();
700         if (isQuickReply && (record->filterType & FILTETYPE_QUICK_REPLY_IM) > 0) {
701             ANS_LOGI("ConsumeRecordFilter-filterType-quickReply");
702             return false;
703         }
704         if (!isQuickReply && (record->filterType & FILTETYPE_IM) > 0) {
705             ANS_LOGI("ConsumeRecordFilter-filterType-im");
706             return false;
707         }
708         std::string bundleName = notification->GetBundleName();
709         if (isQuickReply && record->deviceType == DEVICE_TYPE_WEARABLE &&
710             !DelayedSingleton<NotificationConfigParse>::GetInstance()->IsDistributedReplyEnabled(bundleName)) {
711             ANS_LOGI("ConsumeRecordFilter-filterType-im bundle %{public}s", bundleName.c_str());
712             return false;
713         }
714     }
715 
716     return true;
717 }
718 
BatchNotifyCanceledInner(const std::vector<sptr<Notification>> & notifications,const sptr<NotificationSortingMap> & notificationMap,int32_t deleteReason)719 void NotificationSubscriberManager::BatchNotifyCanceledInner(const std::vector<sptr<Notification>> &notifications,
720     const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
721 {
722     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
723 
724     ANS_LOGD("notifications size = <%{public}zu>", notifications.size());
725 
726     std::string notificationKeys = "";
727     for (auto notification : notifications) {
728         notificationKeys.append(notification->GetKey()).append("-");
729     }
730     ANS_LOGI("CancelNotification key = %{public}s", notificationKeys.c_str());
731 
732     for (auto record : subscriberRecordList_) {
733         if (record == nullptr) {
734             continue;
735         }
736         ANS_LOGD("record->userId = <%{public}d>", record->userId);
737         std::vector<sptr<Notification>> currNotifications;
738         for (size_t i = 0; i < notifications.size(); i ++) {
739             sptr<Notification> notification = notifications[i];
740             if (notification == nullptr) {
741                 continue;
742             }
743             auto requestContent = notification->GetNotificationRequest().GetContent();
744             if (notification->GetNotificationRequest().IsCommonLiveView() &&
745                 requestContent->GetNotificationContent() != nullptr) {
746                 auto liveViewContent = std::static_pointer_cast<NotificationLiveViewContent>(
747                     requestContent->GetNotificationContent());
748                 liveViewContent->ClearPictureMap();
749                 ANS_LOGD("live view batch delete clear picture");
750             }
751             if (notification->GetNotificationRequest().IsSystemLiveView() &&
752                 requestContent->GetNotificationContent() != nullptr) {
753                 auto localLiveViewContent = std::static_pointer_cast<NotificationLocalLiveViewContent>(
754                     requestContent->GetNotificationContent());
755                 localLiveViewContent->ClearButton();
756                 localLiveViewContent->ClearCapsuleIcon();
757                 ANS_LOGD("local live view batch delete clear picture");
758             }
759             if (IsSubscribedBysubscriber(record, notification)) {
760                 currNotifications.emplace_back(notification);
761             }
762         }
763         if (!currNotifications.empty()) {
764             ANS_LOGD("onCanceledList currNotifications size = <%{public}zu>", currNotifications.size());
765             if (record->subscriber == nullptr) {
766                 return;
767             }
768             if (notificationMap != nullptr) {
769                 record->subscriber->OnCanceledList(currNotifications, notificationMap, deleteReason);
770             } else {
771                 record->subscriber->OnCanceledList(currNotifications, deleteReason);
772             }
773         }
774     }
775 }
776 
NotifyUpdatedInner(const sptr<NotificationSortingMap> & notificationMap)777 void NotificationSubscriberManager::NotifyUpdatedInner(const sptr<NotificationSortingMap> &notificationMap)
778 {
779     if (notificationMap == nullptr) {
780         ANS_LOGE("null notificationMap");
781         return;
782     }
783     for (auto record : subscriberRecordList_) {
784         record->subscriber->OnUpdated(notificationMap);
785     }
786 }
787 
788 template <typename... Args>
NotifySubscribers(int32_t userId,const std::string & bundle,ErrCode (IAnsSubscriber::* func)(Args...),Args &&...args)789 void NotificationSubscriberManager::NotifySubscribers(int32_t userId, const std::string& bundle,
790     ErrCode (IAnsSubscriber::*func)(Args...), Args&& ... args)
791 {
792     for (auto& record : subscriberRecordList_) {
793         if (IsNeedNotifySubscribers(record, userId, bundle)) {
794             (record->subscriber->*func)(std::forward<Args>(args)...);
795         }
796     }
797 }
798 
IsNeedNotifySubscribers(const std::shared_ptr<SubscriberRecord> & record,const int32_t & userId,const std::string & bundle)799 bool NotificationSubscriberManager::IsNeedNotifySubscribers(const std::shared_ptr<SubscriberRecord> &record,
800     const int32_t &userId, const std::string &bundle)
801 {
802     if (record->userId == SUBSCRIBE_USER_ALL || IsSystemUser(record->userId) || IsSystemUser(userId)) {
803         return true;
804     }
805 
806     if (record->userId == userId) {
807         if (record->isSubscribeSelf) {
808             auto iter = std::find(record->bundleList_.begin(), record->bundleList_.end(), bundle);
809             if (iter != record->bundleList_.end()) {
810                 return true;
811             }
812         } else {
813             return true;
814         }
815     }
816     return false;
817 }
818 
NotifyDoNotDisturbDateChangedInner(const int32_t & userId,const sptr<NotificationDoNotDisturbDate> & date,const std::string & bundle)819 void NotificationSubscriberManager::NotifyDoNotDisturbDateChangedInner(const int32_t &userId,
820     const sptr<NotificationDoNotDisturbDate> &date, const std::string &bundle)
821 {
822     if (date == nullptr) {
823         ANS_LOGE("null date");
824         return;
825     }
826     NotifySubscribers(userId, bundle, &IAnsSubscriber::OnDoNotDisturbDateChange, date);
827 }
828 
NotifyBadgeEnabledChangedInner(const sptr<EnabledNotificationCallbackData> & callbackData)829 void NotificationSubscriberManager::NotifyBadgeEnabledChangedInner(
830     const sptr<EnabledNotificationCallbackData> &callbackData)
831 {
832     if (callbackData == nullptr) {
833         ANS_LOGE("null callbackData");
834         return;
835     }
836     int32_t userId = SUBSCRIBE_USER_INIT;
837     OsAccountManagerHelper::GetInstance().GetOsAccountLocalIdFromUid(callbackData->GetUid(), userId);
838     std::string bundle = callbackData->GetBundle();
839     NotifySubscribers(userId, bundle, &IAnsSubscriber::OnBadgeEnabledChanged, callbackData);
840 }
841 
IsSystemUser(int32_t userId)842 bool NotificationSubscriberManager::IsSystemUser(int32_t userId)
843 {
844     return ((userId >= SUBSCRIBE_USER_SYSTEM_BEGIN) && (userId <= SUBSCRIBE_USER_SYSTEM_END));
845 }
846 
NotifyEnabledNotificationChangedInner(const sptr<EnabledNotificationCallbackData> & callbackData)847 void NotificationSubscriberManager::NotifyEnabledNotificationChangedInner(
848     const sptr<EnabledNotificationCallbackData> &callbackData)
849 {
850     if (callbackData == nullptr) {
851         ANS_LOGE("null callbackData");
852         return;
853     }
854     int32_t userId = SUBSCRIBE_USER_INIT;
855     OsAccountManagerHelper::GetInstance().GetOsAccountLocalIdFromUid(callbackData->GetUid(), userId);
856     std::string bundle = callbackData->GetBundle();
857     NotifySubscribers(userId, bundle, &IAnsSubscriber::OnEnabledNotificationChanged, callbackData);
858 }
859 
SetBadgeNumber(const sptr<BadgeNumberCallbackData> & badgeData)860 void NotificationSubscriberManager::SetBadgeNumber(const sptr<BadgeNumberCallbackData> &badgeData)
861 {
862     if (notificationSubQueue_ == nullptr || badgeData == nullptr) {
863         ANS_LOGE("null queue or badgeData");
864         return;
865     }
866     std::function<void()> setBadgeNumberFunc = [this, badgeData] () {
867         int32_t userId = SUBSCRIBE_USER_INIT;
868         OsAccountManagerHelper::GetInstance().GetOsAccountLocalIdFromUid(badgeData->GetUid(), userId);
869         std::string bundle = badgeData->GetBundle();
870         NotifySubscribers(userId, bundle, &IAnsSubscriber::OnBadgeChanged, badgeData);
871         NotificationAnalyticsUtil::ReportBadgeChange(badgeData);
872     };
873     notificationSubQueue_->submit(setBadgeNumberFunc);
874 }
875 
RegisterOnSubscriberAddCallback(std::function<void (const std::shared_ptr<SubscriberRecord> &)> callback)876 void NotificationSubscriberManager::RegisterOnSubscriberAddCallback(
877     std::function<void(const std::shared_ptr<SubscriberRecord> &)> callback)
878 {
879     if (callback == nullptr) {
880         ANS_LOGE("null callback");
881         return;
882     }
883 
884     onSubscriberAddCallback_ = callback;
885 }
886 
UnRegisterOnSubscriberAddCallback()887 void NotificationSubscriberManager::UnRegisterOnSubscriberAddCallback()
888 {
889     onSubscriberAddCallback_ = nullptr;
890 }
891 
892 using SubscriberRecordPtr = std::shared_ptr<NotificationSubscriberManager::SubscriberRecord>;
GetSubscriberRecords()893 std::list<SubscriberRecordPtr> NotificationSubscriberManager::GetSubscriberRecords()
894 {
895     return subscriberRecordList_;
896 }
897 
TrackCodeLog(const sptr<Notification> & notification)898 void NotificationSubscriberManager::TrackCodeLog(const sptr<Notification> &notification)
899 {
900     if (notification == nullptr) {
901         ANS_LOGE("null record or notification");
902         return;
903     }
904     sptr<NotificationRequest> request = notification->GetNotificationRequestPoint();
905     if (request == nullptr) {
906         ANS_LOGE("null request");
907         return;
908     }
909     auto flagsMap = request->GetDeviceFlags();
910     if (flagsMap == nullptr || flagsMap->size() <= 0) {
911         ANS_LOGE("null flagsMap or empty flagsMap");
912         return;
913     }
914 
915     bool keyNode = false;
916     bool commonLiveView = request->IsCommonLiveView();
917     std::shared_ptr<AAFwk::WantParams> extendInfo = request->GetExtendInfo();
918     if (extendInfo != nullptr) {
919         auto value = extendInfo->GetParam("collaboration_node");
920         AAFwk::IBoolean* ao = AAFwk::IBoolean::Query(value);
921         if (ao != nullptr) {
922             keyNode = AAFwk::Boolean::Unbox(ao);
923         }
924     }
925 
926     std::vector<std::string> deviceTypes;
927     for (auto& flag : *flagsMap) {
928         deviceTypes.push_back(flag.first);
929     }
930     HaOperationMessage operation = HaOperationMessage(commonLiveView).KeyNode(keyNode)
931         .SyncPublish(deviceTypes);
932     NotificationAnalyticsUtil::ReportOperationsDotEvent(operation);
933 }
934 
DistributeOperation(const sptr<NotificationOperationInfo> & operationInfo,const sptr<NotificationRequest> & request)935 ErrCode NotificationSubscriberManager::DistributeOperation(
936     const sptr<NotificationOperationInfo>& operationInfo, const sptr<NotificationRequest>& request)
937 {
938     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
939     if (notificationSubQueue_ == nullptr || operationInfo == nullptr) {
940         ANS_LOGE("null queue");
941         return ERR_ANS_TASK_ERR;
942     }
943 
944     ErrCode result = ERR_OK;
945     int32_t funcResult = -1;
946     ffrt::task_handle handler = notificationSubQueue_->submit_h(std::bind([&]() {
947         result = DistributeOperationTask(operationInfo, request, funcResult);
948     }));
949     notificationSubQueue_->wait(handler);
950     ANS_LOGI("Subscriber manager operation %{public}s %{public}d", operationInfo->GetHashCode().c_str(), result);
951     return result;
952 }
953 
DistributeOperationTask(const sptr<NotificationOperationInfo> & operationInfo,const sptr<NotificationRequest> & request,int32_t & funcResult)954 ErrCode NotificationSubscriberManager::DistributeOperationTask(const sptr<NotificationOperationInfo>& operationInfo,
955     const sptr<NotificationRequest>& request, int32_t &funcResult)
956 {
957     ErrCode result = ERR_OK;
958     for (const auto& record : subscriberRecordList_) {
959         if (record == nullptr) {
960             continue;
961         }
962         std::string notificationUdid = "";
963         if (request != nullptr && request->GetExtendInfo() != nullptr) {
964             notificationUdid = request->GetExtendInfo()->GetStringParam(EXTENDINFO_INFO_PRE + EXTENDINFO_DEVICE_ID);
965         }
966         if (record->needNotifyResponse && record->subscriber != nullptr) {
967             operationInfo->SetNotificationUdid(notificationUdid);
968             result = record->subscriber->OnOperationResponse(operationInfo, funcResult);
969             if (result == ERR_OK) {
970                 return result;
971             }
972         }
973         result = ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
974     }
975     return result;
976 }
977 }  // namespace Notification
978 }  // namespace OHOS
979