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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap)
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>> ¬ifications,
222 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap, 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>> ¬ifications,
271 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ificationMap)
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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap)
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>> ¬ifications,
593 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ification)
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> ¬ification)
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>> ¬ifications,
720 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ificationMap)
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> ¬ification)
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