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