diff --git a/frameworks/core/include/ans_manager_proxy.h b/frameworks/core/include/ans_manager_proxy.h index dbde7e50021c9661243e8ca9de9216115e4388bf..6eb87db2aad1580f685736429c73ea0491c759a5 100644 --- a/frameworks/core/include/ans_manager_proxy.h +++ b/frameworks/core/include/ans_manager_proxy.h @@ -695,8 +695,9 @@ private: static inline BrokerDelegator delegator_; ErrCode ReadReminders(uint8_t &count, MessageParcel &reply, std::vector> &reminders); + + ErrCode RegisterMonitorCallback(const sptr ¬ification); }; } // namespace Notification } // namespace OHOS - #endif // BASE_NOTIFICATION_ANS_STANDARD_FRAMEWORKS_ANS_CORE_INCLUDE_ANS_MANAGER_PROXY_H diff --git a/frameworks/core/include/ans_manager_stub.h b/frameworks/core/include/ans_manager_stub.h index 8aac73af536fe192835256a1ab38ef00178f691e..a5a4fbebe37fcbec2a25863ccd8d0ea2fe88e1d0 100644 --- a/frameworks/core/include/ans_manager_stub.h +++ b/frameworks/core/include/ans_manager_stub.h @@ -685,6 +685,14 @@ public: */ virtual ErrCode SetBadgeNumber(int32_t badgeNumber) override; + /** + * @brief Register live Application Exiting Monitring. + * + * @param monitorStub The Monitor object. + * @return Returns register callback result. + */ + virtual ErrCode RegisterMonitorCallBack(const sptr& monitorStub); + /** * @brief Register Push Callback. * @@ -699,11 +707,9 @@ public: * @return Returns unregister push Callback result. */ ErrCode UnregisterPushCallback() override; - private: static const std::map> interfaces_; - ErrCode HandlePublish(MessageParcel &data, MessageParcel &reply); ErrCode HandleCancel(MessageParcel &data, MessageParcel &reply); ErrCode HandleCancelAll(MessageParcel &data, MessageParcel &reply); @@ -779,6 +785,7 @@ private: ErrCode HandleUnregisterPushCallback(MessageParcel &data, MessageParcel &reply); ErrCode HandleSubscribeLocalLiveView(MessageParcel &data, MessageParcel &reply); ErrCode HandleTriggerLocalLiveView(MessageParcel &data, MessageParcel &reply); + ErrCode HandleRegisterMonitorCallBack(MessageParcel &data, MessageParcel &reply); template bool WriteParcelableVector(const std::vector> &parcelableVector, MessageParcel &reply, ErrCode &result) 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 78f24ac5deb76ac191d1ecb0961967d5584d4087..60a6108d33d1bd3df8e97fd0754ed0e26e09893d 100644 --- a/frameworks/core/include/distributed_notification_service_ipc_interface_code.h +++ b/frameworks/core/include/distributed_notification_service_ipc_interface_code.h @@ -104,6 +104,7 @@ namespace Notification { SET_BADGE_NUMBER, REGISTER_PUSH_CALLBACK, UNREGISTER_PUSH_CALLBACK, + REGISTER_MONITOR_CALLBACK, // ans_subscriber_interface ON_CONNECTED, ON_DISCONNECTED, @@ -124,4 +125,4 @@ namespace Notification { } } -#endif \ No newline at end of file +#endif diff --git a/frameworks/core/src/ans_manager_proxy.cpp b/frameworks/core/src/ans_manager_proxy.cpp index 0fd30ceb2d9ed7687249d5c4c832036c2f977b2e..5c8217ea5637e0fbbf01165a9b74df8fb0454de7 100644 --- a/frameworks/core/src/ans_manager_proxy.cpp +++ b/frameworks/core/src/ans_manager_proxy.cpp @@ -27,6 +27,7 @@ #include "reminder_request_calendar.h" #include "reminder_request_timer.h" #include "ans_manager_proxy.h" +#include "ans_manager_stub.h" namespace OHOS { namespace Notification { @@ -43,6 +44,11 @@ ErrCode AnsManagerProxy::Publish(const std::string &label, const sptrGetSlotType() == NotificationConstant::SlotType::LIVE_VIEW && + notification->GetNotificationType() == NotificationContent::Type::LOCAL_LIVE_VIEW) { + RegisterMonitorCallback(notification); + } + MessageParcel data; if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { ANS_LOGE("[Publish] fail: write interface token failed."); @@ -75,6 +81,41 @@ ErrCode AnsManagerProxy::Publish(const std::string &label, const sptr ¬ification) +{ + ANS_LOGI("%{public}s", __FUNCTION__); + if (notification == nullptr) { + ANS_LOGE("[RegisterMonitorCallback] fail: notification is empty."); + return ERR_ANS_INVALID_PARAM; + } + + MessageParcel data; + if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { + ANS_LOGE("[RegisterMonitorCallback] fail: write interface token failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + sptr monitorStub = new (std::nothrow) AnsManagerStub(); + if (!data.WriteRemoteObject(monitorStub)) { + ANS_LOGE("[RegisterMonitorCallback] fail: write label failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + MessageParcel reply; + MessageOption option = { MessageOption::TF_SYNC }; + ErrCode result = InnerTransact(NotificationInterfaceCode::REGISTER_MONITOR_CALLBACK, option, data, reply); + if (result != ERR_OK) { + ANS_LOGE("transact ErrCode=%{public}d", result); + return ERR_ANS_TRANSACT_FAILED; + } + + if (!reply.ReadInt32(result)) { + ANS_LOGE("fail: read result failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + return result; +} + ErrCode AnsManagerProxy::Cancel(int32_t notificationId, const std::string &label) { MessageParcel data; diff --git a/frameworks/core/src/ans_manager_stub.cpp b/frameworks/core/src/ans_manager_stub.cpp index 777f68b99e30a73a357e534569ddeebd9557d067..12e1a7f6cc03704d868ae02f05583cf6ddeffeec 100644 --- a/frameworks/core/src/ans_manager_stub.cpp +++ b/frameworks/core/src/ans_manager_stub.cpp @@ -259,6 +259,9 @@ const std::map monitorStub = data.ReadRemoteObject(); + if (monitorStub == nullptr) { + ANS_LOGE("fail: read JSPushCallBack failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + ErrCode result = RegisterMonitorCallBack(monitorStub); + if (!reply.WriteInt32(result)) { + ANS_LOGE("fail: write result failed, ErrCode=%{public}d", result); + return ERR_ANS_PARCELABLE_FAILED; + } + return result; +} + ErrCode AnsManagerStub::HandleCancelAll(MessageParcel &data, MessageParcel &reply) { ErrCode result = CancelAll(); @@ -2276,6 +2295,12 @@ ErrCode AnsManagerStub::RegisterPushCallback(const sptr& pushCall return ERR_INVALID_OPERATION; } +ErrCode AnsManagerStub::RegisterMonitorCallBack(const sptr& monitorStub) +{ + ANS_LOGE("RegisterMonitorCallBack called!"); + return ERR_INVALID_OPERATION; +} + ErrCode AnsManagerStub::UnregisterPushCallback() { ANS_LOGE("UnregisterPushCallback called!"); diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index 70511cfe79960c7e239a64af06e6180e863293dc..d7479a4dba340786955825fa0c68006aef6c9e7b 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "event_handler.h" #include "event_runner.h" @@ -42,6 +43,7 @@ namespace OHOS { namespace Notification { +class LiveNotificationRecipient; class AdvancedNotificationService final : public AnsManagerStub { public: ~AdvancedNotificationService() override; @@ -769,6 +771,21 @@ public: */ ErrCode UnregisterPushCallback() override; + /** + * @brief Registe Monitor CallBack. + * + * @return Returns Registe Monitor Callback result. + */ + ErrCode RegisterMonitorCallBack(const sptr& monitorStub) override; + + /** + * @brief Remove specified Live notification. + * + * @return Returns Remove result. + */ + ErrCode RemoveLiveNotification(const std::string& bundleName, NotificationConstant::SlotType slotType, + NotificationContent::Type contentType); + /** * @brief Reset pushcallback proxy */ @@ -779,6 +796,11 @@ public: */ void InitNotificationEnableList(); + /** + * @brief Reset monitorcallback proxy + */ + void ResetMonitorCallBackProxy(const std::string& bundleName); + private: struct RecentInfo; AdvancedNotificationService(); @@ -884,6 +906,9 @@ private: const sptr &bundleOption, bool enabled); ErrCode CheckNotificationEnableStatus(bool ¬ificationEnable); ErrCode PublishPreparedNotificationInner(const sptr &request); + ErrCode GetTargetRecordList(const std::string& bundleName, NotificationConstant::SlotType slotType, + NotificationContent::Type contentType, std::vector>& recordList); + // Might fail if ces subscribe failed, if failed, dialogManager_ will be set nullptr bool CreateDialogManager(); @@ -893,6 +918,7 @@ private: static sptr instance_; static std::mutex instanceMutex_; static std::mutex pushMutex_; + static std::mutex monitorMutex_; static sptr pushCallBack_; std::shared_ptr runner_ = nullptr; @@ -902,6 +928,7 @@ private: std::shared_ptr recentInfo_ = nullptr; std::shared_ptr distributedKvStoreDeathRecipient_ = nullptr; std::shared_ptr systemEventObserver_ = nullptr; + std::map, sptr>> liveObjectMap_; DistributedKv::DistributedKvDataManager dataManager_; sptr pushRecipient_ = nullptr; std::shared_ptr notificationSvrQueue_ = nullptr; @@ -924,7 +951,21 @@ public: virtual ~PushCallbackRecipient(); void OnRemoteDied(const wptr &remote); }; + +/** +* @class LiveNotificationRecipient +* LiveNotificationRecipient notices IRemoteBroker died. +*/ +class LiveNotificationRecipient : public IRemoteObject::DeathRecipient { +public: + LiveNotificationRecipient(); + virtual ~LiveNotificationRecipient(); + void OnRemoteDied(const wptr &remote); + void SetBundleName(const std::string& bundleName); + std::string GetBundleName(); +private: + std::string bundleName_; +}; } // namespace Notification } // namespace OHOS - #endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_SERVICES_ANS_INCLUDE_ADVANCED_NOTIFICATION_SERVICE_H diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 49a8faf87f6ab104eafbdb52451bb31c044d9bf2..d2aadcf209df8715559c5e182b6fb33a0f40ad16 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -95,6 +95,9 @@ constexpr int32_t WINDOW_DEFAULT_WIDTH = 720; constexpr int32_t WINDOW_DEFAULT_HEIGHT = 1280; constexpr int32_t UI_HALF = 2; constexpr int32_t MAIN_USER_ID = 100; +constexpr NotificationConstant::SlotType REMOVE_SLOT_TYPE = NotificationConstant::SlotType::LIVE_VIEW; +constexpr NotificationContent::Type REMOVE_CONTENT_TYPE = NotificationContent::Type::LOCAL_LIVE_VIEW; + constexpr char HIDUMPER_HELP_MSG[] = "Usage:dump [options]\n" @@ -130,6 +133,7 @@ struct AdvancedNotificationService::RecentInfo { sptr AdvancedNotificationService::instance_; std::mutex AdvancedNotificationService::instanceMutex_; std::mutex AdvancedNotificationService::pushMutex_; +std::mutex AdvancedNotificationService::monitorMutex_; sptr AdvancedNotificationService::pushCallBack_; inline std::string GetClientBundleName() @@ -5008,6 +5012,109 @@ ErrCode AdvancedNotificationService::PublishPreparedNotificationInner(const sptr return PublishPreparedNotification(request, bundleOption); } +void AdvancedNotificationService::ResetMonitorCallBackProxy(const std::string& bundleName) +{ + std::lock_guard lock(monitorMutex_); + if (liveObjectMap_.empty()) { + ANS_LOGE("invalid liveObjectMap_ state"); + return; + } + auto it = liveObjectMap_.find(bundleName); + if (it != liveObjectMap_.end() && it->second.first != nullptr && it->second.second != nullptr) { + (it->second.first)->RemoveDeathRecipient(it->second.second); + liveObjectMap_.erase(it); + } +} + +ErrCode AdvancedNotificationService::GetTargetRecordList(const std::string& bundleName, + NotificationConstant::SlotType slotType, NotificationContent::Type contentType, + std::vector>& recordList) +{ + for (auto& notification : notificationList_) { + if (notification->request != nullptr && notification->request->GetOwnerBundleName() == bundleName && + notification->request->GetSlotType()== slotType && + notification->request->GetNotificationType() == contentType) { + recordList.emplace_back(notification); + } + } + if (recordList.empty()) { + return ERR_ANS_NOTIFICATION_NOT_EXISTS; + } + return ERR_OK; +} + +ErrCode AdvancedNotificationService::RemoveLiveNotification(const std::string& bundleName, + NotificationConstant::SlotType slotType, NotificationContent::Type contentType) +{ + std::vector> recordList; + if (GetTargetRecordList(bundleName, slotType, contentType, recordList) != ERR_OK) { + ANS_LOGE("Get Target record list fail."); + return ERR_ANS_NOTIFICATION_NOT_EXISTS; + } + if (notificationSvrQueue_ == nullptr) { + ANS_LOGE("NotificationSvrQueue is nullptr"); + return ERR_ANS_INVALID_PARAM; + } + ErrCode result = ERR_OK; + ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { + std::vector> notifications; + for (auto& record : recordList) { + std::string key = record->notification->GetKey(); + sptr notification = nullptr; +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + std::string deviceId; + std::string bundleName; + GetDistributedInfo(key, deviceId, bundleName); +#endif + result = RemoveFromNotificationList(key, notification, true, + NotificationConstant::USER_STOPPED_REASON_DELETE); + if (result != ERR_OK) { + continue; + } + if (notification != nullptr) { + int32_t reason = NotificationConstant::USER_STOPPED_REASON_DELETE; + UpdateRecentNotification(notification, true, 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 = notifications; + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + currNotificationList, nullptr, NotificationConstant::USER_STOPPED_REASON_DELETE); + notifications.clear(); + } + } + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + notifications, nullptr, NotificationConstant::USER_STOPPED_REASON_DELETE); + } + result = ERR_OK; + })); + notificationSvrQueue_->wait(handler); + return result; +} + +ErrCode AdvancedNotificationService::RegisterMonitorCallBack(const sptr &monitorStub) +{ + ANS_LOGI("%{public}s", __FUNCTION__); + + if (monitorStub == nullptr) { + ANS_LOGW("monitorStub is null."); + return ERR_INVALID_VALUE; + } + sptr liveNotificationRecipient = new (std::nothrow) LiveNotificationRecipient(); + if (!liveNotificationRecipient) { + ANS_LOGE("Failed to create death Recipient ptr PushCallbackRecipient!"); + return ERR_NO_INIT; + } + monitorStub->AddDeathRecipient(liveNotificationRecipient); + std::string bundle = GetClientBundleName(); + liveNotificationRecipient->SetBundleName(bundle); + liveObjectMap_.insert({bundle, {monitorStub, liveNotificationRecipient}}); + return ERR_OK; +} bool AdvancedNotificationService::CreateDialogManager() { @@ -5049,5 +5156,27 @@ void PushCallbackRecipient::OnRemoteDied(const wptr &remote) PushCallbackRecipient::PushCallbackRecipient() {} PushCallbackRecipient::~PushCallbackRecipient() {} + +LiveNotificationRecipient::LiveNotificationRecipient() {} + +LiveNotificationRecipient::~LiveNotificationRecipient() {} + +void LiveNotificationRecipient::OnRemoteDied(const wptr &remote) +{ + std::string bundleName = GetBundleName(); + AdvancedNotificationService::GetInstance()->RemoveLiveNotification(bundleName, + REMOVE_SLOT_TYPE, REMOVE_CONTENT_TYPE); + AdvancedNotificationService::GetInstance()->ResetMonitorCallBackProxy(bundleName); +} + +void LiveNotificationRecipient::SetBundleName(const std::string& bundleName) +{ + bundleName_ = bundleName; +} + +std::string LiveNotificationRecipient::GetBundleName() +{ + return bundleName_; +} } // namespace Notification } // namespace OHOS