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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap)
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>> ¬ifications,
171 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap, 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>> ¬ifications,
212 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ificationMap)
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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap)
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>> ¬ifications,
471 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ification)
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>> ¬ifications,
553 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ificationMap)
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