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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap)
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>> ¬ifications,
203 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap, 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>> ¬ifications,
244 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ificationMap)
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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap)
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>> ¬ifications,
535 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ification)
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> ¬ification)
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>> ¬ifications,
648 const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ificationMap)
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> ¬ification, 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> ¬ification, 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