diff --git a/frameworks/ans/src/notification_helper.cpp b/frameworks/ans/src/notification_helper.cpp index d208602e06d56bc70b19273cbee88a825cad6d10..0fc8750b92458c85c5304903416072212451d28c 100644 --- a/frameworks/ans/src/notification_helper.cpp +++ b/frameworks/ans/src/notification_helper.cpp @@ -198,6 +198,11 @@ ErrCode NotificationHelper::RemoveAllNotifications(const NotificationBundleOptio return DelayedSingleton::GetInstance()->RemoveAllNotifications(bundleOption); } +ErrCode NotificationHelper::RemoveNotifications(const std::vector hashcodes, int32_t removeReason) +{ + return DelayedSingleton::GetInstance()->RemoveNotifications(hashcodes, removeReason); +} + ErrCode NotificationHelper::RemoveNotificationsByBundle(const NotificationBundleOption &bundleOption) { return DelayedSingleton::GetInstance()->RemoveNotificationsByBundle(bundleOption); diff --git a/frameworks/ans/src/notification_subscriber.cpp b/frameworks/ans/src/notification_subscriber.cpp index 5a01a737f51b764046b4cd17faf03f7665a86d9c..848b6fb1c2a86069ac8543bf6a58eb86b1953be4 100644 --- a/frameworks/ans/src/notification_subscriber.cpp +++ b/frameworks/ans/src/notification_subscriber.cpp @@ -71,9 +71,23 @@ void NotificationSubscriber::SubscriberImpl::OnCanceled( const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); - subscriber_.OnCanceled(std::make_shared(*notification), - std::make_shared(*notificationMap), - deleteReason); + if (notificationMap == nullptr) { + subscriber_.OnCanceled(std::make_shared(*notification), + std::make_shared(), deleteReason); + } else { + subscriber_.OnCanceled(std::make_shared(*notification), + std::make_shared(*notificationMap), deleteReason); + } +} + + +void NotificationSubscriber::SubscriberImpl::OnCanceledList(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason) +{ + HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + for (auto notification : notifications) { + OnCanceled(notification, notificationMap, deleteReason); + } } void NotificationSubscriber::SubscriberImpl::OnUpdated(const sptr ¬ificationMap) diff --git a/frameworks/core/common/include/ans_const_define.h b/frameworks/core/common/include/ans_const_define.h index f1654f1062b926c753f12d961e2dd823402e0639..82c4900ac90743f8660d4cfcb972e74d7cdcc9d8 100644 --- a/frameworks/core/common/include/ans_const_define.h +++ b/frameworks/core/common/include/ans_const_define.h @@ -37,6 +37,7 @@ constexpr uint32_t MAX_CONVERSATIONAL_NUM = 10000; constexpr uint32_t MAX_PERMIT_MIME_TYPE_NUM = 10000; constexpr uint32_t MAX_ACTION_BUTTON_NUM = 3; constexpr int32_t MAX_PARCELABLE_VECTOR_NUM = 10000; +constexpr uint32_t MAX_CANCELED_PARCELABLE_VECTOR_NUM = 200; constexpr int32_t SUBSCRIBE_USER_INIT = -1; diff --git a/frameworks/core/include/ans_manager_interface.h b/frameworks/core/include/ans_manager_interface.h index 6041aae154e4532873fbf47a2a9e6d90032f8a81..ccccdcd2fc88d613189b2ad55c99925cf285ad6c 100644 --- a/frameworks/core/include/ans_manager_interface.h +++ b/frameworks/core/include/ans_manager_interface.h @@ -275,6 +275,8 @@ public: */ virtual ErrCode RemoveAllNotifications(const sptr &bundleOption) = 0; + virtual ErrCode RemoveNotifications(const std::vector &hashcodes, int32_t removeReason) = 0; + /** * @brief Remove notifications based on bundle. * diff --git a/frameworks/core/include/ans_manager_proxy.h b/frameworks/core/include/ans_manager_proxy.h index 73eb6b88ced1a1e0faa872150105919434daf607..a73751a9e52168c87f7beb403baf02ef1a2eda66 100644 --- a/frameworks/core/include/ans_manager_proxy.h +++ b/frameworks/core/include/ans_manager_proxy.h @@ -255,6 +255,8 @@ public: */ ErrCode RemoveAllNotifications(const sptr &bundleOption) override; + ErrCode RemoveNotifications(const std::vector &hashcodes, int32_t removeReason) override; + /** * @brief Delete notification based on key. * diff --git a/frameworks/core/include/ans_manager_stub.h b/frameworks/core/include/ans_manager_stub.h index dcd90008dcc2bc30bfdccbfdaf2c9f3272ead59b..553150a59a63e0e5131d3861e3da7ac9efda4a1d 100644 --- a/frameworks/core/include/ans_manager_stub.h +++ b/frameworks/core/include/ans_manager_stub.h @@ -270,6 +270,8 @@ public: */ virtual ErrCode RemoveAllNotifications(const sptr &bundleOption) override; + virtual ErrCode RemoveNotifications(const std::vector &keys, int32_t removeReason) override; + /** * @brief Delete notification based on key. * @@ -709,6 +711,7 @@ private: ErrCode HandleIsNotificationPolicyAccessGranted(MessageParcel &data, MessageParcel &reply); ErrCode HandleRemoveNotification(MessageParcel &data, MessageParcel &reply); ErrCode HandleRemoveAllNotifications(MessageParcel &data, MessageParcel &reply); + ErrCode HandleRemoveNotifications(MessageParcel &data, MessageParcel &reply); ErrCode HandleDelete(MessageParcel &data, MessageParcel &reply); ErrCode HandleDeleteByBundle(MessageParcel &data, MessageParcel &reply); ErrCode HandleDeleteAll(MessageParcel &data, MessageParcel &reply); diff --git a/frameworks/core/include/ans_notification.h b/frameworks/core/include/ans_notification.h index f7d7af22265b38e9d83861c51df2b5555ec21af9..0794a5c4cd974e24faf77d792cc805da9750202a 100644 --- a/frameworks/core/include/ans_notification.h +++ b/frameworks/core/include/ans_notification.h @@ -379,6 +379,8 @@ public: */ ErrCode RemoveAllNotifications(const NotificationBundleOption &bundleOption); + ErrCode RemoveNotifications(const std::vector hashcodes, int32_t removeReason); + /** * @brief Removes all removable notifications of a specified bundle. * @note Your application must have platform signature to use this method. diff --git a/frameworks/core/include/ans_subscriber_interface.h b/frameworks/core/include/ans_subscriber_interface.h index 3d3fba0c000ab8bdd2ed8e1224194f69d891e290..91e868f79580e76e3f6bfe1d7abe696e5d43d2b2 100644 --- a/frameworks/core/include/ans_subscriber_interface.h +++ b/frameworks/core/include/ans_subscriber_interface.h @@ -66,6 +66,9 @@ public: virtual void OnCanceled(const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason) = 0; + virtual void OnCanceledList(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason) = 0; + /** * @brief The callback function on the notifications updated. * diff --git a/frameworks/core/include/ans_subscriber_proxy.h b/frameworks/core/include/ans_subscriber_proxy.h index 18ff83ee6c8bf08c51dc1a4ee8b7cdb7921565ba..2c2d883243f931c729aad561abbbf91f323bf481 100644 --- a/frameworks/core/include/ans_subscriber_proxy.h +++ b/frameworks/core/include/ans_subscriber_proxy.h @@ -52,12 +52,14 @@ public: * @brief The callback function on a notification canceled. * * @param notification Indicates the canceled notification. - * @param notificationMap Indicates the NotificationSortingMap object. * @param deleteReason Indicates the delete reason. */ void OnCanceled(const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason) override; + void OnCanceledList(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason) override; + /** * @brief The callback function on the notifications updated. * @@ -89,6 +91,8 @@ public: private: ErrCode InnerTransact(NotificationInterfaceCode code, MessageOption &flags, MessageParcel &data, MessageParcel &reply); static inline BrokerDelegator delegator_; + template + bool WriteParcelableVector(const std::vector> &parcelableVector, MessageParcel &data); }; } // namespace Notification } // namespace OHOS diff --git a/frameworks/core/include/ans_subscriber_stub.h b/frameworks/core/include/ans_subscriber_stub.h index a04b2773c187f6bea2208275ffc69c47b217bf8a..5e03e1e10cd31fa73af6b9c5e86941a7706bd705 100644 --- a/frameworks/core/include/ans_subscriber_stub.h +++ b/frameworks/core/include/ans_subscriber_stub.h @@ -68,6 +68,9 @@ public: void OnCanceled(const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason) override; + void OnCanceledList(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason) override; + /** * @brief The callback function on the notifications updated. * @@ -103,10 +106,13 @@ private: ErrCode HandleOnDisconnected(MessageParcel &data, MessageParcel &reply); ErrCode HandleOnConsumedMap(MessageParcel &data, MessageParcel &reply); ErrCode HandleOnCanceledMap(MessageParcel &data, MessageParcel &reply); + ErrCode HandleOnCanceledListMap(MessageParcel &data, MessageParcel &reply); ErrCode HandleOnUpdated(MessageParcel &data, MessageParcel &reply); ErrCode HandleOnDoNotDisturbDateChange(MessageParcel &data, MessageParcel &reply); ErrCode HandleOnEnabledNotificationChanged(MessageParcel &data, MessageParcel &reply); ErrCode HandleOnBadgeChanged(MessageParcel &data, MessageParcel &reply); + template + bool ReadParcelableVector(std::vector> &parcelableInfos, MessageParcel &data); }; } // namespace Notification } // namespace OHOS diff --git a/frameworks/core/include/distributed_notification_service_ipc_interface_code.h b/frameworks/core/include/distributed_notification_service_ipc_interface_code.h index fbd1d6d5fc05cf028c69760232b4d369d7c95a41..959baaa8dee18a1778e8c36b3d114a71c78e6648 100644 --- a/frameworks/core/include/distributed_notification_service_ipc_interface_code.h +++ b/frameworks/core/include/distributed_notification_service_ipc_interface_code.h @@ -52,6 +52,7 @@ namespace Notification { IS_NOTIFICATION_POLICY_ACCESS_GRANTED, REMOVE_NOTIFICATION, REMOVE_ALL_NOTIFICATIONS, + REMOVE_NOTIFICATIONS_BY_KEYS, DELETE_NOTIFICATION, DELETE_NOTIFICATION_BY_BUNDLE, DELETE_ALL_NOTIFICATIONS, @@ -109,6 +110,7 @@ namespace Notification { ON_CONSUMED, // Obsolete ON_CONSUMED_MAP, ON_CANCELED_MAP, + ON_CANCELED_LIST_MAP, ON_UPDATED, ON_DND_DATE_CHANGED, ON_ENABLED_NOTIFICATION_CHANGED, diff --git a/frameworks/core/src/ans_manager_proxy.cpp b/frameworks/core/src/ans_manager_proxy.cpp index 5bad741bfe83441c41975e271eac82da1fd238e8..57efd7ab3abe5d66535cbab862b8312b79f39f09 100644 --- a/frameworks/core/src/ans_manager_proxy.cpp +++ b/frameworks/core/src/ans_manager_proxy.cpp @@ -823,6 +823,50 @@ ErrCode AnsManagerProxy::RemoveAllNotifications(const sptr &keys, int32_t removeReason) +{ + if (keys.empty()) { + ANS_LOGE("[RemoveAllNotifications] fail: keys is empty."); + return ERR_ANS_INVALID_PARAM; + } + + MessageParcel data; + if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { + ANS_LOGE("[RemoveAllNotifications] fail:, write interface token failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!data.WriteInt32(keys.size())) { + ANS_LOGE("write keys size failed"); + return false; + } + + if (!data.WriteStringVector(keys)) { + ANS_LOGE("[RemoveAllNotifications] fail: write keys failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!data.WriteInt32(removeReason)) { + ANS_LOGE("[Delete] fail: write removeReason failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + MessageParcel reply; + MessageOption option = {MessageOption::TF_SYNC}; + ErrCode result = InnerTransact(NotificationInterfaceCode::REMOVE_NOTIFICATIONS_BY_KEYS, option, data, reply); + if (result != ERR_OK) { + ANS_LOGE("[RemoveNotification] fail: transact ErrCode=%{public}d", result); + return ERR_ANS_TRANSACT_FAILED; + } + + if (!reply.ReadInt32(result)) { + ANS_LOGE("[RemoveNotification] fail: read result failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + return result; +} + ErrCode AnsManagerProxy::Delete(const std::string &key, int32_t removeReason) { if (key.empty()) { diff --git a/frameworks/core/src/ans_manager_stub.cpp b/frameworks/core/src/ans_manager_stub.cpp index 526531b8e7de2d43fb64cec30b21672e9a49f101..d163eee607e1b17c5b4ebbd3eec7dd29d69b383f 100644 --- a/frameworks/core/src/ans_manager_stub.cpp +++ b/frameworks/core/src/ans_manager_stub.cpp @@ -100,6 +100,9 @@ const std::map keys; + if (!data.ReadStringVector(&keys)) { + ANS_LOGE("read keys failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + int32_t removeReason = 0; + if (!data.ReadInt32(removeReason)) { + ANS_LOGE("read removeReason failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + ErrCode result = RemoveNotifications(keys, removeReason); + if (!reply.WriteInt32(result)) { + ANS_LOGE("write result failed, ErrCode=%{public}d", result); + return ERR_ANS_PARCELABLE_FAILED; + } + return ERR_OK; +} + + ErrCode AnsManagerStub::HandleDelete(MessageParcel &data, MessageParcel &reply) { std::string key; @@ -1899,6 +1932,12 @@ ErrCode AnsManagerStub::RemoveAllNotifications(const sptr &keys, int32_t removeReason) +{ + ANS_LOGE("called!"); + return ERR_INVALID_OPERATION; +} + ErrCode AnsManagerStub::Delete(const std::string &key, int32_t removeReason) { ANS_LOGE("AnsManagerStub::Delete called!"); diff --git a/frameworks/core/src/ans_notification.cpp b/frameworks/core/src/ans_notification.cpp index 3a099b3567e0b5e2e1be9fee6130ac04c8836807..feea0bbbc85b875c735827cbc7143ba7a517d0f5 100644 --- a/frameworks/core/src/ans_notification.cpp +++ b/frameworks/core/src/ans_notification.cpp @@ -488,6 +488,21 @@ ErrCode AnsNotification::RemoveAllNotifications(const NotificationBundleOption & return ansManagerProxy_->RemoveAllNotifications(bo); } +ErrCode AnsNotification::RemoveNotifications(const std::vector hashcodes, int32_t removeReason) +{ + if (hashcodes.empty()) { + ANS_LOGE("Hashcodes is empty"); + return ERR_ANS_INVALID_PARAM; + } + + if (!GetAnsManagerProxy()) { + ANS_LOGE("GetAnsManagerProxy fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + return ansManagerProxy_->RemoveNotifications(hashcodes, removeReason); +} + ErrCode AnsNotification::RemoveNotificationsByBundle(const NotificationBundleOption &bundleOption) { if (bundleOption.GetBundleName().empty()) { diff --git a/frameworks/core/src/ans_subscriber_proxy.cpp b/frameworks/core/src/ans_subscriber_proxy.cpp index 834dd66b6ab03752f4d4768c03e10fb49c31b1e2..96f7b9fa37e03e08f3819dc10a03102f06ec8b91 100644 --- a/frameworks/core/src/ans_subscriber_proxy.cpp +++ b/frameworks/core/src/ans_subscriber_proxy.cpp @@ -172,6 +172,68 @@ void AnsSubscriberProxy::OnCanceled( } } +void AnsSubscriberProxy::OnCanceledList(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason) +{ + if (notifications.empty()) { + ANS_LOGE("Notifications is empty."); + return; + } + + MessageParcel data; + if (!data.WriteInterfaceToken(AnsSubscriberProxy::GetDescriptor())) { + ANS_LOGE("Write interface token failed."); + return; + } + + if (!WriteParcelableVector(notifications, data)) { + ANS_LOGE("Write notifications failed"); + return; + } + + if (!data.WriteBool(notificationMap != nullptr)) { + ANS_LOGE("Write existMap failed"); + return; + } + + if (notificationMap != nullptr) { + if (!data.WriteParcelable(notificationMap)) { + ANS_LOGE("Write notificationMap failed"); + return; + } + } + + if (!data.WriteInt32(deleteReason)) { + ANS_LOGE("Write deleteReason failed."); + return; + } + + MessageParcel reply; + MessageOption option = {MessageOption::TF_ASYNC}; + ErrCode result = InnerTransact(NotificationInterfaceCode::ON_CANCELED_LIST_MAP, option, data, reply); + if (result != ERR_OK) { + ANS_LOGE("Transact ErrCode=ERR_ANS_TRANSACT_FAILED"); + return; + } +} + +template +bool AnsSubscriberProxy::WriteParcelableVector(const std::vector> &parcelableVector, MessageParcel &data) +{ + if (!data.WriteInt32(parcelableVector.size())) { + ANS_LOGE("write ParcelableVector size failed"); + return false; + } + + for (auto &parcelable : parcelableVector) { + if (!data.WriteStrongParcelable(parcelable)) { + ANS_LOGE("write ParcelableVector failed"); + return false; + } + } + return true; +} + void AnsSubscriberProxy::OnUpdated(const sptr ¬ificationMap) { if (notificationMap == nullptr) { diff --git a/frameworks/core/src/ans_subscriber_stub.cpp b/frameworks/core/src/ans_subscriber_stub.cpp index b8dff16b3d0a22949968bb82c0ec70c5360ebec3..066e363602b9c134d07bf463c0158704b47d558a 100644 --- a/frameworks/core/src/ans_subscriber_stub.cpp +++ b/frameworks/core/src/ans_subscriber_stub.cpp @@ -34,6 +34,8 @@ AnsSubscriberStub::AnsSubscriberStub() std::bind(&AnsSubscriberStub::HandleOnConsumedMap, this, std::placeholders::_1, std::placeholders::_2)); interfaces_.emplace(NotificationInterfaceCode::ON_CANCELED_MAP, std::bind(&AnsSubscriberStub::HandleOnCanceledMap, this, std::placeholders::_1, std::placeholders::_2)); + interfaces_.emplace(NotificationInterfaceCode::ON_CANCELED_LIST_MAP, + std::bind(&AnsSubscriberStub::HandleOnCanceledListMap, this, std::placeholders::_1, std::placeholders::_2)); interfaces_.emplace(NotificationInterfaceCode::ON_UPDATED, std::bind(&AnsSubscriberStub::HandleOnUpdated, this, std::placeholders::_1, std::placeholders::_2)); interfaces_.emplace(NotificationInterfaceCode::ON_DND_DATE_CHANGED, @@ -147,6 +149,64 @@ ErrCode AnsSubscriberStub::HandleOnCanceledMap(MessageParcel &data, MessageParce return ERR_OK; } + +ErrCode AnsSubscriberStub::HandleOnCanceledListMap(MessageParcel &data, MessageParcel &reply) +{ + std::vector> notifications; + if (!ReadParcelableVector(notifications, data)) { + ANS_LOGE("Read notifications failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + bool existMap = false; + if (!data.ReadBool(existMap)) { + ANS_LOGW("Read existMap failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + sptr notificationMap = nullptr; + if (existMap) { + notificationMap = data.ReadParcelable(); + if (notificationMap == nullptr) { + ANS_LOGW("Read NotificationSortingMap failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + } + + int32_t reason = 0; + if (!data.ReadInt32(reason)) { + ANS_LOGW("Read reason failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + OnCanceledList(notifications, notificationMap, reason); + return ERR_OK; +} + + +template +bool AnsSubscriberStub::ReadParcelableVector(std::vector> &parcelableInfos, MessageParcel &data) +{ + int32_t infoSize = 0; + if (!data.ReadInt32(infoSize)) { + ANS_LOGE("read Parcelable size failed."); + return false; + } + + parcelableInfos.clear(); + infoSize = (infoSize < MAX_PARCELABLE_VECTOR_NUM) ? infoSize : MAX_PARCELABLE_VECTOR_NUM; + for (int32_t index = 0; index < infoSize; index++) { + sptr info = data.ReadStrongParcelable(); + if (info == nullptr) { + ANS_LOGE("read Parcelable infos failed."); + return false; + } + parcelableInfos.emplace_back(info); + } + + return true; +} + ErrCode AnsSubscriberStub::HandleOnUpdated(MessageParcel &data, MessageParcel &reply) { sptr notificationMap = data.ReadParcelable(); @@ -206,6 +266,10 @@ void AnsSubscriberStub::OnCanceled( const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason) {} +void AnsSubscriberStub::OnCanceledList(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason) +{} + void AnsSubscriberStub::OnUpdated(const sptr ¬ificationMap) {} diff --git a/frameworks/js/napi/include/common.h b/frameworks/js/napi/include/common.h index 06a546dff6f0c04916f09b3b5fb090a0c95b2838..1c8f831e8ac9979852e54efebf15b1bc4431a56c 100644 --- a/frameworks/js/napi/include/common.h +++ b/frameworks/js/napi/include/common.h @@ -1369,6 +1369,8 @@ public: */ static napi_value GetBundleOption(const napi_env &env, const napi_value &value, NotificationBundleOption &option); + static napi_value GetHashCodes(const napi_env &env, const napi_value &value, std::vector &hashCodes); + /** * @brief Gets a NotificationKey object from specified js object * diff --git a/frameworks/js/napi/include/remove.h b/frameworks/js/napi/include/remove.h index bcab40bd4648e44fc72691f43dc8899d2aba3d99..a6ceefe530b4f59688cf85da8a7fffd7510e52e1 100644 --- a/frameworks/js/napi/include/remove.h +++ b/frameworks/js/napi/include/remove.h @@ -30,6 +30,7 @@ struct BundleAndKeyInfo { struct RemoveParams { std::optional hashcode {}; std::optional bundleAndKeyInfo {}; + std::vector hashcodes; int32_t userId = SUBSCRIBE_USER_INIT; int32_t removeReason = NotificationConstant::CANCEL_REASON_DELETE; bool hasUserId = false; diff --git a/frameworks/js/napi/src/common.cpp b/frameworks/js/napi/src/common.cpp index 57dcde2e275e2e05a2d872682e9ccbab805a524a..4e47a5a6dc4af80291ea90953a4c54e4b9c06215 100644 --- a/frameworks/js/napi/src/common.cpp +++ b/frameworks/js/napi/src/common.cpp @@ -4242,6 +4242,33 @@ napi_value Common::GetBundleOption(const napi_env &env, const napi_value &value, return NapiGetNull(env); } +napi_value Common::GetHashCodes(const napi_env &env, const napi_value &value, std::vector &hashCodes) +{ + ANS_LOGD("enter"); + uint32_t length = 0; + napi_get_array_length(env, value, &length); + if (length == 0) { + ANS_LOGE("The array is empty."); + return nullptr; + } + napi_valuetype valuetype = napi_undefined; + for (size_t i = 0; i < length; i++) { + napi_value hashCode = nullptr; + napi_get_element(env, value, i, &hashCode); + NAPI_CALL(env, napi_typeof(env, hashCode, &valuetype)); + if (valuetype != napi_string) { + ANS_LOGE("Wrong argument type. Object expected."); + return nullptr; + } + char str[STR_MAX_SIZE] = {0}; + size_t strLen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, hashCode, str, STR_MAX_SIZE - 1, &strLen)); + hashCodes.emplace_back(str); + } + + return NapiGetNull(env); +} + napi_value Common::GetNotificationKey(const napi_env &env, const napi_value &value, NotificationKey &key) { ANS_LOGI("enter"); diff --git a/frameworks/js/napi/src/remove.cpp b/frameworks/js/napi/src/remove.cpp index 95fcbb7395c63eb050d2250ef7ce6208955b1037..b2f5bede20062c37759a6e23d6e9d39a925b534b 100644 --- a/frameworks/js/napi/src/remove.cpp +++ b/frameworks/js/napi/src/remove.cpp @@ -64,7 +64,17 @@ bool ParseHashcodeTypeParams( const napi_env &env, napi_value* argv, size_t argc, napi_valuetype valueType, RemoveParams ¶ms) { // argv[0]: hashCode - if (valueType == napi_string) { + bool isArray = false; + napi_is_array(env, argv[PARAM0], &isArray); + if (isArray) { + std::vector hashcodes; + auto retValue = Common::GetHashCodes(env, argv[PARAM0], hashcodes); + if (retValue == nullptr) { + ANS_LOGW("GetHashCodes failed."); + return false; + } + params.hashcodes = hashcodes; + } else if (valueType == napi_string) { size_t strLen = 0; char str[STR_MAX_SIZE] = {0}; NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, argv[PARAM0], str, STR_MAX_SIZE - 1, &strLen), false); @@ -129,14 +139,16 @@ bool ParseParameters(const napi_env &env, const napi_callback_info &info, Remove ANS_LOGW("Wrong number of arguments."); return false; } + bool isArray = false; + napi_is_array(env, argv[PARAM0], &isArray); napi_valuetype valueType = napi_undefined; NAPI_CALL_BASE(env, napi_typeof(env, argv[PARAM0], &valueType), false); if ((valueType != napi_string) && (valueType != napi_object) && - (valueType != napi_number) && (valueType != napi_boolean)) { + (valueType != napi_number) && (valueType != napi_boolean) && !isArray) { ANS_LOGW("Wrong argument type. String or object expected."); return false; } - if ((valueType == napi_string) || (valueType == napi_number) || (valueType == napi_boolean)) { + if ((valueType == napi_string) || (valueType == napi_number) || (valueType == napi_boolean) || isArray) { return ParseHashcodeTypeParams(env, argv, argc, valueType, params); } return ParseBundleOptionTypeParams(env, argv, argc, params); diff --git a/frameworks/js/napi/src/subscribe/napi_remove.cpp b/frameworks/js/napi/src/subscribe/napi_remove.cpp index 94877913b7487bd2c7f03df6c608cdff74b23590..6c04130eb881cf262036aecb8b5a2edb7b0f41fa 100644 --- a/frameworks/js/napi/src/subscribe/napi_remove.cpp +++ b/frameworks/js/napi/src/subscribe/napi_remove.cpp @@ -29,7 +29,10 @@ void NapiRemoveExecuteCallback(napi_env env, void *data) } auto removeInfo = static_cast(data); if (removeInfo) { - if (removeInfo->params.hashcode.has_value()) { + if (!removeInfo->params.hashcodes.empty()) { + removeInfo->info.errorCode = NotificationHelper::RemoveNotifications(removeInfo->params.hashcodes, + removeInfo->params.removeReason); + } else if (removeInfo->params.hashcode.has_value()) { removeInfo->info.errorCode = NotificationHelper::RemoveNotification(removeInfo->params.hashcode.value(), removeInfo->params.removeReason); } else if (removeInfo->params.bundleAndKeyInfo.has_value()) { @@ -76,6 +79,7 @@ napi_value NapiRemove(napi_env env, napi_callback_info info) napi_value resourceName = nullptr; napi_create_string_latin1(env, "remove", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call napi_create_async_work(env, nullptr, resourceName, NapiRemoveExecuteCallback, NapiRemoveCompleteCallback, (void *)removeInfo, &removeInfo->asyncWork); diff --git a/interfaces/inner_api/notification_helper.h b/interfaces/inner_api/notification_helper.h index 0d88b7b358721963c513b78e646db4414c2b4988..6956d1b8d9a052f6e1de2a546f5f93f842dd7d11 100644 --- a/interfaces/inner_api/notification_helper.h +++ b/interfaces/inner_api/notification_helper.h @@ -381,6 +381,8 @@ public: */ static ErrCode RemoveAllNotifications(const NotificationBundleOption &bundleOption); + static ErrCode RemoveNotifications(const std::vector hashcodes, int32_t removeReason); + /** * @brief Removes all removable notifications of a specified bundle. * @note Your application must have platform signature to use this method. diff --git a/interfaces/inner_api/notification_subscriber.h b/interfaces/inner_api/notification_subscriber.h index 8081375505cbd77c5445bfa84d5999c457fa6700..eec196e3ce36fb05c53793048f94caef3d0c7877 100644 --- a/interfaces/inner_api/notification_subscriber.h +++ b/interfaces/inner_api/notification_subscriber.h @@ -123,6 +123,9 @@ private: void OnCanceled(const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason) override; + void OnCanceledList(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason) override; + void OnUpdated(const sptr ¬ificationMap) override; void OnDoNotDisturbDateChange(const sptr &date) override; diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index 6446116cbe7c758d42be9f17401388ff61961315..c5e3f0aafde0ffafe71938742fdaec8e45172e7e 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -281,6 +281,8 @@ public: */ ErrCode RemoveAllNotifications(const sptr &bundleOption) override; + ErrCode RemoveNotifications(const std::vector &keys, int32_t removeReason) override; + /** * @brief Delete notification based on key. * @@ -826,6 +828,8 @@ private: ErrCode PushCheck(const sptr &request); void StartAutoDelete(const std::shared_ptr &record); void TriggerAutoDelete(std::string hashCode); + void SendNotificationsOnCanceled(std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason); void SetAgentNotification(sptr& notificationRequest, std::string& bundleName); private: static sptr instance_; diff --git a/services/ans/include/notification_subscriber_manager.h b/services/ans/include/notification_subscriber_manager.h index 53bae6aa4b2dabbbb3c8b9f54b69938c29f63e9b..1316ed8c98fd5056baf55ad178de66a5afbfd743 100644 --- a/services/ans/include/notification_subscriber_manager.h +++ b/services/ans/include/notification_subscriber_manager.h @@ -77,6 +77,8 @@ public: void NotifyCanceled(const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason); + void BatchNotifyCanceled(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason); /** * @brief Notify all subscribers on updated. * @@ -128,6 +130,8 @@ private: const sptr ¬ification, const sptr ¬ificationMap); void NotifyCanceledInner(const sptr ¬ification, const sptr ¬ificationMap, int32_t deleteReason); + void BatchNotifyCanceledInner(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason); void NotifyUpdatedInner(const sptr ¬ificationMap); void NotifyDoNotDisturbDateChangedInner(const sptr &date); void NotifyEnabledNotificationChangedInner(const sptr &callbackData); diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 3f01e8cb14b2b4949c3a27c3821347b1ab8b5ced..1052a2339280c3f4fa162e4fe86050b3e75f0373 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -405,8 +405,7 @@ ErrCode AdvancedNotificationService::CancelPreparedNotification( if (notification != nullptr) { int32_t reason = NotificationConstant::APP_CANCEL_REASON_DELETE; UpdateRecentNotification(notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); + NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, nullptr, reason); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete("", "", notification); #endif @@ -683,6 +682,7 @@ ErrCode AdvancedNotificationService::CancelAll() sptr notification = nullptr; std::vector keys = GetNotificationKeys(bundleOption); + std::vector> notifications; for (auto key : keys) { #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED std::string deviceId; @@ -698,14 +698,26 @@ ErrCode AdvancedNotificationService::CancelAll() if (notification != nullptr) { int32_t reason = NotificationConstant::APP_CANCEL_ALL_REASON_DELETE; UpdateRecentNotification(notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); + notifications.emplace_back(notification); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete(deviceId, bundleName, notification); #endif } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + std::vector> currNotificationList; + for (auto item : notifications) { + currNotificationList.emplace_back(item); + } + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + currNotificationList, nullptr, NotificationConstant::APP_CANCEL_ALL_REASON_DELETE); + notifications.clear(); + } } + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + notifications, nullptr, NotificationConstant::APP_CANCEL_ALL_REASON_DELETE); + } result = ERR_OK; })); notificationSvrQueue_->wait(handler); @@ -950,8 +962,7 @@ ErrCode AdvancedNotificationService::Delete(const std::string &key, int32_t remo if (notification != nullptr) { UpdateRecentNotification(notification, true, removeReason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, removeReason); + NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, nullptr, removeReason); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete(deviceId, bundleName, notification); #endif @@ -1000,8 +1011,7 @@ ErrCode AdvancedNotificationService::DeleteByBundle(const sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); + NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, nullptr, reason); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete(deviceId, bundleName, notification); #endif @@ -1034,6 +1044,7 @@ ErrCode AdvancedNotificationService::DeleteAll() int32_t activeUserId = SUBSCRIBE_USER_INIT; (void)GetActiveUserId(activeUserId); std::vector keys = GetNotificationKeys(nullptr); + std::vector> notifications; for (auto key : keys) { #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED std::string deviceId; @@ -1050,12 +1061,18 @@ ErrCode AdvancedNotificationService::DeleteAll() if (notification->GetUserId() == activeUserId) { int32_t reason = NotificationConstant::CANCEL_ALL_REASON_DELETE; UpdateRecentNotification(notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); + notifications.emplace_back(notification); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete(deviceId, bundleName, notification); #endif } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + SendNotificationsOnCanceled(notifications, nullptr, NotificationConstant::CANCEL_ALL_REASON_DELETE); + } + } + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + notifications, nullptr, NotificationConstant::CANCEL_REASON_DELETE); } result = ERR_OK; @@ -1824,8 +1841,7 @@ ErrCode AdvancedNotificationService::CancelContinuousTaskNotification(const std: if (notification != nullptr) { int32_t reason = NotificationConstant::APP_CANCEL_REASON_DELETE; UpdateRecentNotification(notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); + NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, nullptr, reason); } })); notificationSvrQueue_->wait(handler); @@ -2205,6 +2221,7 @@ void AdvancedNotificationService::OnBundleRemoved(const sptr keys = GetNotificationKeys(bundleOption); #endif + std::vector> notifications; for (auto key : keys) { sptr notification = nullptr; result = RemoveFromNotificationList(key, notification, true, @@ -2216,13 +2233,25 @@ void AdvancedNotificationService::OnBundleRemoved(const sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); + notifications.emplace_back(notification); + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + std::vector> currNotificationList; + for (auto item : notifications) { + currNotificationList.emplace_back(item); + } + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + currNotificationList, nullptr, reason); + notifications.clear(); + } #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete("", "", notification); #endif } } + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + notifications, nullptr, NotificationConstant::PACKAGE_CHANGED_REASON_DELETE); + } NotificationPreferences::GetInstance().RemoveAnsBundleDbInfo(bundleOption); })); @@ -2360,8 +2389,7 @@ ErrCode AdvancedNotificationService::RemoveNotification(const sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, removeReason); + NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, nullptr, removeReason); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete(deviceId, bundleName, notification); #endif @@ -2398,6 +2426,7 @@ ErrCode AdvancedNotificationService::RemoveAllNotifications(const sptrsubmit_h(std::bind([&]() { ANS_LOGD("ffrt enter!"); std::vector> removeList; + int32_t reason = NotificationConstant::CANCEL_REASON_DELETE; for (auto record : notificationList_) { if (!record->notification->IsRemoveAllowed()) { continue; @@ -2413,20 +2442,80 @@ ErrCode AdvancedNotificationService::RemoveAllNotifications(const sptr> notifications; for (auto record : removeList) { notificationList_.remove(record); if (record->notification != nullptr) { - int32_t reason = NotificationConstant::CANCEL_REASON_DELETE; UpdateRecentNotification(record->notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(record->notification, sortingMap, reason); + notifications.emplace_back(record->notification); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete(record->deviceId, record->bundleName, record->notification); #endif } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + SendNotificationsOnCanceled(notifications, nullptr, reason); + } TriggerRemoveWantAgent(record->request); } + + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(notifications, nullptr, reason); + } + })); + + return ERR_OK; +} + +ErrCode AdvancedNotificationService::RemoveNotifications( + const std::vector &keys, int32_t removeReason) +{ + HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + ANS_LOGD("enter"); + + bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID()); + if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) { + return ERR_ANS_NON_SYSTEM_APP; + } + + if (!CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) { + return ERR_ANS_PERMISSION_DENIED; + } + + handler_->PostSyncTask(std::bind([&]() { + std::vector> notifications; + for (auto key : keys) { + sptr notification = nullptr; +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + std::string deviceId; + std::string bundleName; + GetDistributedInfo(key, deviceId, bundleName); +#endif + ErrCode result = RemoveFromNotificationList(key, notification, false, removeReason); + if (result != ERR_OK) { + continue; + } + if (notification != nullptr) { + UpdateRecentNotification(notification, true, removeReason); + notifications.emplace_back(notification); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete(deviceId, bundleName, notification); +#endif + } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + std::vector> currNotificationList; + for (auto item : notifications) { + currNotificationList.emplace_back(item); + } + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + currNotificationList, nullptr, removeReason); + notifications.clear(); + } + } + + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(notifications, nullptr, removeReason); + } })); notificationSvrQueue_->wait(handler); @@ -2494,18 +2583,32 @@ ErrCode AdvancedNotificationService::CancelGroup(const std::string &groupName) } } + std::vector> notifications; for (auto record : removeList) { notificationList_.remove(record); if (record->notification != nullptr) { int32_t reason = NotificationConstant::APP_CANCEL_REASON_DELETE; UpdateRecentNotification(record->notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(record->notification, sortingMap, reason); + notifications.emplace_back(record->notification); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete(record->deviceId, record->bundleName, record->notification); #endif } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + std::vector> currNotificationList; + for (auto item : notifications) { + currNotificationList.emplace_back(item); + } + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + currNotificationList, nullptr, NotificationConstant::APP_CANCEL_REASON_DELETE); + notifications.clear(); + } + } + + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + notifications, nullptr, NotificationConstant::APP_CANCEL_REASON_DELETE); } })); notificationSvrQueue_->wait(handler); @@ -2539,6 +2642,7 @@ ErrCode AdvancedNotificationService::RemoveGroupByBundle( ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { ANS_LOGD("ffrt enter!"); std::vector> removeList; + int32_t reason = NotificationConstant::CANCEL_REASON_DELETE; for (auto record : notificationList_) { if (!record->notification->IsRemoveAllowed()) { continue; @@ -2553,18 +2657,24 @@ ErrCode AdvancedNotificationService::RemoveGroupByBundle( } } + std::vector> notifications; for (auto record : removeList) { notificationList_.remove(record); if (record->notification != nullptr) { - int32_t reason = NotificationConstant::CANCEL_REASON_DELETE; UpdateRecentNotification(record->notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(record->notification, sortingMap, reason); + notifications.emplace_back(record->notification); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete(record->deviceId, record->bundleName, record->notification); #endif } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + SendNotificationsOnCanceled(notifications, nullptr, reason); + } + } + + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(notifications, nullptr, reason); } })); notificationSvrQueue_->wait(handler); @@ -3207,8 +3317,7 @@ void AdvancedNotificationService::OnDistributedDelete( if (notification != nullptr) { int32_t reason = NotificationConstant::APP_CANCEL_REASON_OTHER; UpdateRecentNotification(notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); + NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, nullptr, reason); } })); } @@ -3369,6 +3478,7 @@ ErrCode AdvancedNotificationService::DeleteAllByUser(const int32_t &userId) ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { ANS_LOGD("ffrt enter!"); std::vector keys = GetNotificationKeys(nullptr); + std::vector> notifications; for (auto key : keys) { #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED std::string deviceId; @@ -3385,12 +3495,19 @@ ErrCode AdvancedNotificationService::DeleteAllByUser(const int32_t &userId) if (notification->GetUserId() == userId) { int32_t reason = NotificationConstant::CANCEL_ALL_REASON_DELETE; UpdateRecentNotification(notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); + notifications.emplace_back(notification); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete(deviceId, bundleName, notification); #endif } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + SendNotificationsOnCanceled(notifications, nullptr, NotificationConstant::CANCEL_ALL_REASON_DELETE); + } + } + + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + notifications, nullptr, NotificationConstant::CANCEL_ALL_REASON_DELETE); } result = ERR_OK; @@ -3585,6 +3702,7 @@ void AdvancedNotificationService::OnBundleDataCleared(const sptrsubmit_h(std::bind([&]() { ANS_LOGD("ffrt enter!"); std::vector keys = GetNotificationKeys(bundleOption); + std::vector> notifications; for (auto key : keys) { #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED std::string deviceId; @@ -3602,12 +3720,25 @@ void AdvancedNotificationService::OnBundleDataCleared(const sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); + notifications.emplace_back(notification); #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED DoDistributedDelete(deviceId, bundleName, notification); #endif } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + std::vector> currNotificationList; + for (auto item : notifications) { + currNotificationList.emplace_back(item); + } + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + currNotificationList, nullptr, NotificationConstant::PACKAGE_CHANGED_REASON_DELETE); + notifications.clear(); + } + } + + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + notifications, nullptr, NotificationConstant::PACKAGE_CHANGED_REASON_DELETE); } })); notificationSvrQueue_->wait(handler); @@ -4261,14 +4392,24 @@ void AdvancedNotificationService::TriggerAutoDelete(std::string hashCode) if (record->notification->GetKey() == hashCode) { int32_t reason = NotificationConstant::APP_CANCEL_REASON_DELETE; UpdateRecentNotification(record->notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(record->notification, sortingMap, reason); + NotificationSubscriberManager::GetInstance()->NotifyCanceled(record->notification, nullptr, reason); notificationList_.remove(record); break; } } } +void AdvancedNotificationService::SendNotificationsOnCanceled(std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason) +{ + std::vector> currNotifications; + for (auto notification : notifications) { + currNotifications.emplace_back(notification); + } + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + currNotifications, nullptr, deleteReason); + notifications.clear(); +} void PushCallbackRecipient::OnRemoteDied(const wptr &remote) { ANS_LOGE("Push Callback died, remove the proxy object"); diff --git a/services/ans/src/notification_subscriber_manager.cpp b/services/ans/src/notification_subscriber_manager.cpp index 111a094ae8736306c3c141dba09ab23f139e9677..5908f6d3e89654551bec841229370b0dfae2214f 100644 --- a/services/ans/src/notification_subscriber_manager.cpp +++ b/services/ans/src/notification_subscriber_manager.cpp @@ -152,6 +152,21 @@ void NotificationSubscriberManager::NotifyCanceled( ANS_LOGE("ffrt end!"); } +void NotificationSubscriberManager::BatchNotifyCanceled(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason) +{ + HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + if (handler_ == nullptr) { + ANS_LOGE("handler is nullptr"); + return; + } + + AppExecFwk::EventHandler::Callback NotifyCanceledFunc = std::bind( + &NotificationSubscriberManager::BatchNotifyCanceledInner, this, notifications, notificationMap, deleteReason); + + handler_->PostTask(NotifyCanceledFunc); +} + void NotificationSubscriberManager::NotifyUpdated(const sptr ¬ificationMap) { if (notificationSubQueue_ == nullptr) { @@ -382,6 +397,37 @@ void NotificationSubscriberManager::NotifyCanceledInner( } } +void NotificationSubscriberManager::BatchNotifyCanceledInner(const std::vector> ¬ifications, + const sptr ¬ificationMap, int32_t deleteReason) +{ + HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + + ANS_LOGD("notifications size = <%{public}d>", notifications.size()); + for (auto record : subscriberRecordList_) { + ANS_LOGD("record->userId = <%{public}d>", record->userId); + std::vector> currNotifications; + for (int i = 0; i < notifications.size(); i ++) { + sptr notification = notifications[i]; + auto BundleNames = notification->GetBundleName(); + auto iter = std::find(record->bundleList_.begin(), record->bundleList_.end(), BundleNames); + int32_t recvUserId = notification->GetNotificationRequest().GetReceiverUserId(); + int32_t sendUserId = notification->GetUserId(); + if (!record->subscribedAll == (iter != record->bundleList_.end()) && + ((record->userId == sendUserId) || + (record->userId == SUBSCRIBE_USER_ALL) || + (record->userId == recvUserId) || + IsSystemUser(record->userId) || // Delete this, When the systemui subscribe carry the user ID. + IsSystemUser(sendUserId))) { + currNotifications.emplace_back(notification); + } + } + if (!currNotifications.empty()) { + ANS_LOGD("onCanceledList currNotifications size = <%{public}d>", currNotifications.size()); + record->subscriber->OnCanceledList(currNotifications, notificationMap, deleteReason); + } + } +} + void NotificationSubscriberManager::NotifyUpdatedInner(const sptr ¬ificationMap) { ANS_LOGE("ffrt enter!");