From 886a98e558ea8306ccde345437dd2d0757f891f6 Mon Sep 17 00:00:00 2001 From: "baozeyu1@huawei.com" Date: Fri, 20 Jun 2025 11:30:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=8F=E5=90=8C=E5=88=A0=E9=99=A41?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: baozeyu1@huawei.com --- frameworks/ans/IAnsManager.idl | 2 + frameworks/ans/src/notification_helper.cpp | 9 + .../core/common/include/ans_convert_enum.h | 2 + .../common/include/distributed_data_define.h | 2 + .../core/common/src/ans_convert_enum.cpp | 6 + frameworks/core/include/ans_notification.h | 10 + frameworks/core/src/ans_notification.cpp | 14 ++ .../ans_notification_branch_test.cpp | 7 + .../unittest/mock/mock_ans_manager_proxy.h | 3 +- interfaces/inner_api/notification_constant.h | 17 ++ interfaces/inner_api/notification_helper.h | 10 + .../include/advanced_notification_service.h | 18 ++ .../ans/include/notification_config_parse.h | 11 + .../distributed_extension_service.h | 3 + .../advanced_notification_cancel.cpp | 196 ++++++++++++++++++ .../src/common/notification_config_parse.cpp | 79 +++++++ .../ans/src/distributed_device_status.cpp | 7 +- ...tification_distributed_manager_service.cpp | 15 +- .../distributed_extension_service.cpp | 80 ++++--- .../notification_config_parse_mock.cpp | 6 + services/distributed/BUILD.gn | 1 + .../include/base/distributed_local_config.h | 2 + .../soft_bus/distributed_device_service.h | 1 + .../soft_bus/distributed_publish_service.h | 14 ++ .../include/soft_bus/distributed_service.h | 4 + .../include/soft_bus/distributed_subscriber.h | 3 + .../include/tlv_box/batch_remove_box.h | 8 +- .../tlv_box/remove_all_distributed_box.h | 34 +++ .../distributed/include/tlv_box/remove_box.h | 8 +- .../distributed/include/tlv_box/tlv_box.h | 1 + .../src/base/distributed_local_config.cpp | 5 + .../soft_bus/distributed_device_service.cpp | 19 +- .../distributed_publish_service_v2.cpp | 195 +++++++++++++++-- .../src/soft_bus/distributed_service.cpp | 24 +++ .../src/soft_bus/distributed_subscriber.cpp | 72 ++++++- .../src/tlv_box/batch_remove_box.cpp | 36 +++- .../tlv_box/remove_all_distributed_box.cpp | 37 ++++ .../distributed/src/tlv_box/remove_box.cpp | 34 ++- tools/test/mock/mock_ans_manager_stub.h | 6 + 39 files changed, 931 insertions(+), 70 deletions(-) create mode 100644 services/distributed/include/tlv_box/remove_all_distributed_box.h create mode 100644 services/distributed/src/tlv_box/remove_all_distributed_box.cpp diff --git a/frameworks/ans/IAnsManager.idl b/frameworks/ans/IAnsManager.idl index fbdcb4d8f..44ccca632 100644 --- a/frameworks/ans/IAnsManager.idl +++ b/frameworks/ans/IAnsManager.idl @@ -105,6 +105,8 @@ interface OHOS.Notification.IAnsManager { void RemoveNotifications([in] String[] hashcodes, [in] int removeReason); + void RemoveDistributedNotifications([in] String[] hashcodes, [in] int slotTypeInt, [in] int deleteTypeInt, [in] int removeReason); + void Delete([in] String key, [in] int removeReason); void DeleteByBundle([in] sptr bundleOption); diff --git a/frameworks/ans/src/notification_helper.cpp b/frameworks/ans/src/notification_helper.cpp index b605205ec..2bd4e6516 100644 --- a/frameworks/ans/src/notification_helper.cpp +++ b/frameworks/ans/src/notification_helper.cpp @@ -308,6 +308,15 @@ ErrCode NotificationHelper::RemoveNotifications() return DelayedSingleton::GetInstance()->RemoveNotifications(); } +ErrCode NotificationHelper::RemoveDistributedNotifications(const std::vector& hashcodes, + const NotificationConstant::SlotType& slotType, + const NotificationConstant::DistributedDeleteType& deleteType, + const int32_t removeReason) +{ + return DelayedSingleton::GetInstance()->RemoveDistributedNotifications( + hashcodes, slotType, deleteType, removeReason); +} + ErrCode NotificationHelper::GetNotificationSlotsForBundle( const NotificationBundleOption &bundleOption, std::vector> &slots) { diff --git a/frameworks/core/common/include/ans_convert_enum.h b/frameworks/core/common/include/ans_convert_enum.h index eb1a5961a..a771515c4 100644 --- a/frameworks/core/common/include/ans_convert_enum.h +++ b/frameworks/core/common/include/ans_convert_enum.h @@ -88,6 +88,8 @@ enum class RemoveReason { DISABLE_NOTIFICATION_FEATURE_REASON_DELETE = 31, DISTRIBUTED_COLLABORATIVE_DELETE = 32, USER_LOGOUT_REASON_DELETE = 33, + DISTRIBUTED_ENABLE_CLOSE_DELETE = 34, + DISTRIBUTED_RELEASE_DELETE = 35, APP_CANCEL_REASON_OTHER = 100, }; diff --git a/frameworks/core/common/include/distributed_data_define.h b/frameworks/core/common/include/distributed_data_define.h index d03734511..9f3f50d85 100644 --- a/frameworks/core/common/include/distributed_data_define.h +++ b/frameworks/core/common/include/distributed_data_define.h @@ -41,6 +41,7 @@ enum DeviceStatueChangeType { DEVICE_USING_CHANGE = 0, NOTIFICATION_ENABLE_CHANGE = 1, ALL_CONNECT_STATUS_CHANGE = 2, + DEVICE_USING_CLOSE = 3, }; struct DeviceStatueChangeInfo { @@ -58,6 +59,7 @@ struct DistributedDeviceConfig { std::string localType; std::set supportPeerDevice; std::unordered_set collaborativeDeleteTypes; + std::map>> collaborativeDeleteTypesByDevice; }; static std::string StringAnonymous(const std::string& data) diff --git a/frameworks/core/common/src/ans_convert_enum.cpp b/frameworks/core/common/src/ans_convert_enum.cpp index 8bde20522..fbb9db75f 100644 --- a/frameworks/core/common/src/ans_convert_enum.cpp +++ b/frameworks/core/common/src/ans_convert_enum.cpp @@ -285,6 +285,12 @@ bool AnsEnumUtil::ReasonCToJS(const int &inType, int &outType) case NotificationConstant::USER_LOGOUT_REASON_DELETE: outType = static_cast(RemoveReason::USER_LOGOUT_REASON_DELETE); break; + case NotificationConstant::DISTRIBUTED_ENABLE_CLOSE_DELETE: + outType = static_cast(RemoveReason::DISTRIBUTED_ENABLE_CLOSE_DELETE); + break; + case NotificationConstant::DISTRIBUTED_RELEASE_DELETE: + outType = static_cast(RemoveReason::DISTRIBUTED_RELEASE_DELETE); + break; default: ReasonCToJSExt(inType, outType); break; diff --git a/frameworks/core/include/ans_notification.h b/frameworks/core/include/ans_notification.h index c44995742..bdac614a0 100644 --- a/frameworks/core/include/ans_notification.h +++ b/frameworks/core/include/ans_notification.h @@ -590,6 +590,16 @@ public: */ ErrCode RemoveNotifications(); + /** + * @brief Removes Distributed notifications in the system. + * @note Your application must have platform signature to use this method. + * @return Returns remove notifications result. + */ + ErrCode RemoveDistributedNotifications(const std::vector& hashcodes, + const NotificationConstant::SlotType& slotType, + const NotificationConstant::DistributedDeleteType& deleteType, + const int32_t removeReason); + /** * @brief Obtains all notification slots belonging to the specified bundle. * diff --git a/frameworks/core/src/ans_notification.cpp b/frameworks/core/src/ans_notification.cpp index f00768a4f..4346f0bfb 100644 --- a/frameworks/core/src/ans_notification.cpp +++ b/frameworks/core/src/ans_notification.cpp @@ -927,6 +927,20 @@ ErrCode AnsNotification::RemoveNotifications(const std::vector hash return proxy->RemoveNotifications(hashcodes, removeReason); } +ErrCode AnsNotification::RemoveDistributedNotifications(const std::vector& hashcodes, + const NotificationConstant::SlotType& slotType, + const NotificationConstant::DistributedDeleteType& deleteType, + const int32_t removeReason) +{ + sptr proxy = GetAnsManagerProxy(); + if (!proxy) { + ANS_LOGE("GetAnsManagerProxy fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + return proxy->RemoveDistributedNotifications(hashcodes, slotType, deleteType, removeReason); +} + ErrCode AnsNotification::RemoveNotificationsByBundle(const NotificationBundleOption &bundleOption) { ANS_LOGI("enter RemoveNotificationsByBundle,bundleName:%{public}s", bundleOption.GetBundleName().c_str()); diff --git a/frameworks/core/test/unittest/ans_notification_branch_test/ans_notification_branch_test.cpp b/frameworks/core/test/unittest/ans_notification_branch_test/ans_notification_branch_test.cpp index 8a02c297e..6b707dd2b 100644 --- a/frameworks/core/test/unittest/ans_notification_branch_test/ans_notification_branch_test.cpp +++ b/frameworks/core/test/unittest/ans_notification_branch_test/ans_notification_branch_test.cpp @@ -192,6 +192,13 @@ public: return ERR_ANS_INVALID_PARAM; } + ErrCode RemoveDistributedNotifications(const std::vector& hashcodes, + const int32_t slotTypeInt, const int32_t deleteTypeInt, + const int32_t removeReason) override + { + return ERR_ANS_INVALID_PARAM; + } + ErrCode DeleteByBundle(const sptr &bundleOption) override { return ERR_ANS_INVALID_PARAM; diff --git a/frameworks/core/test/unittest/mock/mock_ans_manager_proxy.h b/frameworks/core/test/unittest/mock/mock_ans_manager_proxy.h index bd331a01b..19e597870 100644 --- a/frameworks/core/test/unittest/mock/mock_ans_manager_proxy.h +++ b/frameworks/core/test/unittest/mock/mock_ans_manager_proxy.h @@ -182,7 +182,8 @@ public: ErrCode(const std::string&, const std::string&, int32_t, const std::vector&)); MOCK_METHOD4(SetTargetDeviceSwitch, ErrCode(const std::string&, const std::string&, bool, bool)); MOCK_METHOD1(SetHashCodeRule, ErrCode(uint32_t)); - + MOCK_METHOD4(RemoveDistributedNotifications, ErrCode(const std::vector& hashcodes, + const int32_t, const int32_t, const int32_t)); #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED MOCK_METHOD1(RegisterSwingCallback, ErrCode(const sptr&)); #endif diff --git a/interfaces/inner_api/notification_constant.h b/interfaces/inner_api/notification_constant.h index b1c478578..e0520e328 100644 --- a/interfaces/inner_api/notification_constant.h +++ b/interfaces/inner_api/notification_constant.h @@ -78,6 +78,13 @@ public: SA_SELF_BANNER_FLAG = 1 << 9, }; + enum DistributedDeleteType { + ALL, + SLOT, + EXCLUDE_ONE_SLOT, + HASHCODES, + }; + enum class VisiblenessType { /** * the notification display effect has not been set by NotificationRequest::setVisibleness(). @@ -341,6 +348,16 @@ public: */ static const int32_t USER_LOGOUT_REASON_DELETE = 33; + /** + * Indicates that a notification is deleted because distributed enable close removed. + */ + static const int32_t DISTRIBUTED_ENABLE_CLOSE_DELETE = 34; + + /** + * Indicates that a notification is deleted because distributed release removed. + */ + static const int32_t DISTRIBUTED_RELEASE_DELETE = 35; + /** * Indicates that a notification is deleted for other reasons. */ diff --git a/interfaces/inner_api/notification_helper.h b/interfaces/inner_api/notification_helper.h index 2559b18f2..1f35fd1b0 100644 --- a/interfaces/inner_api/notification_helper.h +++ b/interfaces/inner_api/notification_helper.h @@ -658,6 +658,16 @@ public: */ static ErrCode RemoveNotifications(); + /** + * @brief Removes Distributed notifications in the system. + * @note Your application must have platform signature to use this method. + * @return Returns remove notifications result. + */ + static ErrCode RemoveDistributedNotifications(const std::vector& hashcodes, + const NotificationConstant::SlotType& slotType, + const NotificationConstant::DistributedDeleteType& deleteType, + const int32_t removeReason); + /** * @brief Obtains all active notifications in the current system. The caller must have system permissions to * call this method. diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index dcd725510..dcdf55619 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -391,6 +391,15 @@ public: ErrCode RemoveNotifications(const std::vector &keys, int32_t removeReason) override; + /** + * @brief Removes Distributed notifications in the system. + * @note Your application must have platform signature to use this method. + * @return Returns remove notifications result. + */ + ErrCode RemoveDistributedNotifications(const std::vector& hashcodes, + const int32_t slotTypeInt, const int32_t deleteTypeInt, + const int32_t removeReason) override; + ErrCode GetUnifiedGroupInfoFromDb(std::string &enable); /** @@ -1651,6 +1660,15 @@ private: const bool easyAbroad); void ClearSlotTypeData(const sptr &request, int32_t callingUid, int32_t sourceType); ErrCode RegisterPushCallbackTokenCheck(); + ErrCode RemoveDistributedNotifications(const std::vector& hashcodes, + const int32_t removeReason); + ErrCode RemoveDistributedNotifications(const NotificationConstant::SlotType& slotType, + const int32_t removeReason, + const NotificationConstant::DistributedDeleteType& deleteType); + ErrCode RemoveAllDistributedNotifications(const int32_t removeReason); + bool ExecuteDeleteDistributedNotification(std::shared_ptr& record, + std::vector>& notifications, const int32_t removeReason); + bool IsDistributedNotification(sptr request); template bool WriteParcelableVector(const std::vector> &parcelableVector, MessageParcel &data) diff --git a/services/ans/include/notification_config_parse.h b/services/ans/include/notification_config_parse.h index 77b9f7745..cb3923f82 100644 --- a/services/ans/include/notification_config_parse.h +++ b/services/ans/include/notification_config_parse.h @@ -57,12 +57,18 @@ public: bool GetMirrorNotificationEnabledStatus(std::vector& deviceTypes); bool GetAppAndDeviceRelationMap(std::map& relationMap); std::unordered_set GetCollaborativeDeleteType() const; + bool GetCollaborativeDeleteTypeByDevice(std::map>>& map) const; bool GetFilterUidAndBundleName(const std::string &key); void GetCollaborationFilter(); bool IsInCollaborationFilter(const std::string &bundleName, int32_t uid) const; uint32_t GetStartAbilityTimeout(); private: + bool ParseCollaborativeDeleteTypesDevices(std::map>>& map, nlohmann::json& collaborativeDeleteTypes) const; + bool ParseDeviceSlotType(const nlohmann::json& device, + std::map>& peerDeviceTypeMap) const; std::map defaultCurrentSlotReminder_; std::vector notificationConfigJsons_; std::mutex mutex_; @@ -95,6 +101,11 @@ public: #endif constexpr static const char* CFG_KEY_COLLABORATIVE_DELETE_TYPES = "collaborativeDeleteTypes"; constexpr static const char* CFG_KEY_START_ABILITY_TIMEOUT = "startAbilityTimeout"; + constexpr static const char* CFG_KEY_COLLABORATIVE_DELETE_TYPES_DEVICES = "collaborativeDeleteTypesDevices"; + constexpr static const char* LOCAL_DEVICE_TYPE = "localDeviceType"; + constexpr static const char* PEER_DELETE_FILTER_DEVICE = "peerDeleteFilterDevice"; + constexpr static const char* PEER_DEVICE_TYPE = "peerDeviceType"; + constexpr static const char* DELETE_SLOT_TYPE = "deleteSlotTypes"; }; } // namespace Notification } // namespace OHOS diff --git a/services/ans/include/notification_extension/distributed_extension_service.h b/services/ans/include/notification_extension/distributed_extension_service.h index bc1550c39..31189099b 100644 --- a/services/ans/include/notification_extension/distributed_extension_service.h +++ b/services/ans/include/notification_extension/distributed_extension_service.h @@ -67,6 +67,9 @@ private: ~DistributedExtensionService(); void SetMaxContentLength(nlohmann::json &configJson); void SetOperationReplyTimeout(nlohmann::json &configJson); + bool SetLocalType(nlohmann::json &configJson); + bool SetSupportPeerDevice(nlohmann::json &configJson); + bool SetMaxTitleLength(nlohmann::json &configJson); std::mutex mapLock_; std::atomic dansRunning_ = false; diff --git a/services/ans/src/advanced_notification_manager/advanced_notification_cancel.cpp b/services/ans/src/advanced_notification_manager/advanced_notification_cancel.cpp index 4e2d2db3d..861990ead 100644 --- a/services/ans/src/advanced_notification_manager/advanced_notification_cancel.cpp +++ b/services/ans/src/advanced_notification_manager/advanced_notification_cancel.cpp @@ -912,5 +912,201 @@ void AdvancedNotificationService::ExcuteDeleteAll(ErrCode &result, const int32_t BatchCancelTimer(timerIds); result = ERR_OK; } + +ErrCode AdvancedNotificationService::RemoveDistributedNotifications( + const std::vector& hashcodes, const int32_t slotTypeInt, + const int32_t deleteTypeInt, const int32_t removeReason) +{ + bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID()); + if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) { + ANS_LOGE("IsSystemApp is false."); + return ERR_ANS_NON_SYSTEM_APP; + } + + if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) { + ANS_LOGE("app no controller"); + return ERR_ANS_PERMISSION_DENIED; + } + + NotificationConstant::SlotType slotType = static_cast(slotTypeInt); + NotificationConstant::DistributedDeleteType deleteType = + static_cast(deleteTypeInt); + + switch (deleteType) { + case NotificationConstant::DistributedDeleteType::ALL: + return RemoveAllDistributedNotifications(removeReason); + case NotificationConstant::DistributedDeleteType::SLOT: + case NotificationConstant::DistributedDeleteType::EXCLUDE_ONE_SLOT: + return RemoveDistributedNotifications(slotType, removeReason, deleteType); + case NotificationConstant::DistributedDeleteType::HASHCODES: + return RemoveDistributedNotifications(hashcodes, removeReason); + default: + ANS_LOGW("no deleteType"); + break; + } + return ERR_OK; +} + +ErrCode AdvancedNotificationService::RemoveDistributedNotifications( + const std::vector& hashcodes, const int32_t removeReason) +{ + ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([=]() { + std::vector> notifications; + std::list> deleteRecords; + for (auto record : notificationList_) { + auto notification = record->notification; + if (notification == nullptr) { + continue; + } + + auto key = notification->GetKey(); + if (std::find(hashcodes.begin(), hashcodes.end(), key) == hashcodes.end()) { + continue; + } + if (ExecuteDeleteDistributedNotification(record, notifications, removeReason)) { + deleteRecords.push_back(record); + } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + std::vector> currNotificationList = notifications; + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + currNotificationList, nullptr, removeReason); + notifications.clear(); + } + } + + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + notifications, nullptr, removeReason); + } + for (auto deleteRecord : deleteRecords) { + notificationList_.remove(deleteRecord); + } + })); + return ERR_OK; +} + +ErrCode AdvancedNotificationService::RemoveDistributedNotifications( + const NotificationConstant::SlotType& slotType, const int32_t removeReason, + const NotificationConstant::DistributedDeleteType& deleteType) +{ + ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([=]() { + std::vector> notifications; + std::list> deleteRecords; + for (auto record : notificationList_) { + auto notification = record->notification; + if (notification == nullptr) { + continue; + } + auto request = notification->GetNotificationRequestPoint(); + if (request == nullptr) { + continue; + } + if (deleteType == NotificationConstant::DistributedDeleteType::EXCLUDE_ONE_SLOT && + request->GetSlotType() == slotType) { + ANS_LOGD("key:%{public}s,ty:%{public}d", request->GetKey().c_str(), request->GetSlotType()); + continue; + } + if (deleteType == NotificationConstant::DistributedDeleteType::SLOT && + request->GetSlotType() != slotType) { + ANS_LOGD("key:%{public}s,ty:%{public}d", request->GetKey().c_str(), request->GetSlotType()); + continue; + } + + if (ExecuteDeleteDistributedNotification(record, notifications, removeReason)) { + deleteRecords.push_back(record); + } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + std::vector> currNotificationList = notifications; + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + currNotificationList, nullptr, removeReason); + notifications.clear(); + } + } + + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + notifications, nullptr, removeReason); + } + for (auto deleteRecord : deleteRecords) { + notificationList_.remove(deleteRecord); + } + })); + return ERR_OK; +} + +ErrCode AdvancedNotificationService::RemoveAllDistributedNotifications( + const int32_t removeReason) +{ + ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([=]() { + std::vector> notifications; + std::list> deleteRecords; + for (auto record : notificationList_) { + if (ExecuteDeleteDistributedNotification(record, notifications, removeReason)) { + deleteRecords.push_back(record); + } + if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) { + std::vector> currNotificationList = notifications; + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + currNotificationList, nullptr, removeReason); + notifications.clear(); + } + } + + if (!notifications.empty()) { + NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled( + notifications, nullptr, removeReason); + } + + for (auto deleteRecord : deleteRecords) { + notificationList_.remove(deleteRecord); + } + })); + return ERR_OK; +} + +bool AdvancedNotificationService::ExecuteDeleteDistributedNotification( + std::shared_ptr& record, + std::vector>& notifications, + const int32_t removeReason) +{ + if (record == nullptr) { + ANS_LOGE("delete record is null"); + return false; + } + + auto notification = record->notification; + if (notification == nullptr) { + ANS_LOGE("delete notification is null"); + return false; + } + + auto request = notification->GetNotificationRequestPoint(); + if (request == nullptr) { + ANS_LOGE("delete request is null"); + return false; + } + if (IsDistributedNotification(request)) { + notifications.emplace_back(notification); + CancelTimer(notification->GetAutoDeletedTimer()); + ProcForDeleteLiveView(record); + TriggerRemoveWantAgent(request, removeReason, record->isThirdparty); + CancelWantAgent(notification); + return true; + } + ANS_LOGD("delete not distributed, key:%{public}s", request->GetKey().c_str()); + return false; +} + +bool AdvancedNotificationService::IsDistributedNotification(sptr request) +{ + if (request == nullptr) { + return false; + } + + if (request->GetDistributedCollaborate()) { + return true; + } + return false; +} } // namespace Notification } // namespace OHOS \ No newline at end of file diff --git a/services/ans/src/common/notification_config_parse.cpp b/services/ans/src/common/notification_config_parse.cpp index e7a444355..288528a50 100644 --- a/services/ans/src/common/notification_config_parse.cpp +++ b/services/ans/src/common/notification_config_parse.cpp @@ -482,5 +482,84 @@ bool NotificationConfigParse::IsReportTrustList(const std::string& bundleName) c return reporteTrustSet_.count(bundleName); } +bool NotificationConfigParse::GetCollaborativeDeleteTypeByDevice(std::map>>& resultMap) const +{ + nlohmann::json root; + std::string JsonPoint = "/"; + JsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE); + JsonPoint.append("/"); + JsonPoint.append(CFG_KEY_COLLABORATIVE_DELETE_TYPES_DEVICES); + if (!GetConfigJson(JsonPoint, root)) { + ANS_LOGE("GetConfigJson faild"); + return false; + } + + if (root.find(CFG_KEY_NOTIFICATION_SERVICE) == root.end()) { + ANS_LOGE("appPrivileges null"); + return false; + } + + nlohmann::json collaborativeDeleteTypes = + root[CFG_KEY_NOTIFICATION_SERVICE][CFG_KEY_COLLABORATIVE_DELETE_TYPES_DEVICES]; + + if (collaborativeDeleteTypes.is_null() || collaborativeDeleteTypes.empty() || + !collaborativeDeleteTypes.is_array()) { + ANS_LOGE("get collaborativeDeleteTypes failed."); + return false; + } + std::map>> tempMap; + if (!ParseCollaborativeDeleteTypesDevices(tempMap, collaborativeDeleteTypes)) { + return false; + } + resultMap = tempMap; + return true; +} + +bool NotificationConfigParse::ParseCollaborativeDeleteTypesDevices(std::map>>& resultMap, + nlohmann::json& collaborativeDeleteTypes) const +{ + for (const auto& device : collaborativeDeleteTypes) { + if (!device.contains(LOCAL_DEVICE_TYPE) || !device[LOCAL_DEVICE_TYPE].is_string()) { + continue; + } + std::string localDeviceType = device[LOCAL_DEVICE_TYPE]; + + if (!device.contains(PEER_DELETE_FILTER_DEVICE) || !device[PEER_DELETE_FILTER_DEVICE].is_array()) { + continue; + } + + std::map> peerDeviceTypeMap; + ParseDeviceSlotType(device, peerDeviceTypeMap); + resultMap[localDeviceType] = peerDeviceTypeMap; + } + return true; +} + +bool NotificationConfigParse::ParseDeviceSlotType(const nlohmann::json& device, + std::map>& peerDeviceTypeMap) const +{ + for (const auto& peerDevice : device[PEER_DELETE_FILTER_DEVICE]) { + if (!peerDevice.contains(PEER_DEVICE_TYPE) || !peerDevice[PEER_DEVICE_TYPE].is_string()) { + continue; + } + std::string peerDeviceType = peerDevice[PEER_DEVICE_TYPE]; + + if (!peerDevice.contains(DELETE_SLOT_TYPE) || !peerDevice[DELETE_SLOT_TYPE].is_array()) { + continue; + } + + std::unordered_set deleteSlotTypes; + for (const auto& slotType : peerDevice[DELETE_SLOT_TYPE]) { + if (slotType.is_string()) { + deleteSlotTypes.insert(slotType); + } + } + + peerDeviceTypeMap[peerDeviceType] = std::move(deleteSlotTypes); + } + return true; +} } // namespace Notification } // namespace OHOS diff --git a/services/ans/src/distributed_device_status.cpp b/services/ans/src/distributed_device_status.cpp index b647057c1..e17815684 100644 --- a/services/ans/src/distributed_device_status.cpp +++ b/services/ans/src/distributed_device_status.cpp @@ -76,16 +76,19 @@ void ChangeStatus(DeviceStatus& device, const std::string &deviceType, const uin device.status &= ~(1 << i); } } + DeviceStatueChangeInfo changeInfo; + changeInfo.deviceId = device.deviceId; if (deviceType == NotificationConstant::PAD_DEVICE_TYPE || deviceType == NotificationConstant::PC_DEVICE_TYPE) { if (((1 << DistributedDeviceStatus::USING_FLAG) & controlFlag) && ((1 << DistributedDeviceStatus::USING_FLAG) & device.status)) { - DeviceStatueChangeInfo changeInfo; - changeInfo.deviceId = device.deviceId; changeInfo.changeType = DeviceStatueChangeType::DEVICE_USING_CHANGE; DistributedExtensionService::GetInstance().DeviceStatusChange(changeInfo); ANS_LOGI("notify %{public}s %{public}s using change.", device.deviceType.c_str(), StringAnonymous(device.deviceId).c_str()); + } else if (((1 << DistributedDeviceStatus::USING_FLAG) & device.status) == 0) { + changeInfo.changeType = DeviceStatueChangeType::DEVICE_USING_CLOSE; + DistributedExtensionService::GetInstance().DeviceStatusChange(changeInfo); } } diff --git a/services/ans/src/distributed_manager/advanced_notification_distributed_manager_service.cpp b/services/ans/src/distributed_manager/advanced_notification_distributed_manager_service.cpp index dac1a91b8..dd5412e28 100644 --- a/services/ans/src/distributed_manager/advanced_notification_distributed_manager_service.cpp +++ b/services/ans/src/distributed_manager/advanced_notification_distributed_manager_service.cpp @@ -106,6 +106,12 @@ ErrCode AdvancedNotificationService::SetDistributedEnabledBySlot( changeInfo.changeType = DeviceStatueChangeType::NOTIFICATION_ENABLE_CHANGE; DistributedExtensionService::GetInstance().DeviceStatusChange(changeInfo); } + + if (result == ERR_OK && !enabled) { + RemoveDistributedNotifications(slotType, + NotificationConstant::DISTRIBUTED_ENABLE_CLOSE_DELETE, + NotificationConstant::DistributedDeleteType::SLOT); + } ANS_LOGI("SetDistributedEnabledBySlot %{public}d, deviceType: %{public}s, enabled: %{public}s, " "SetDistributedEnabledBySlot result: %{public}d", slotType, deviceType.c_str(), std::to_string(enabled).c_str(), result); @@ -598,9 +604,10 @@ ErrCode AdvancedNotificationService::SetDistributedEnabledByBundle(const sptrSetDistributedEnabledByBundle(bundle, deviceType, enabled); - + ANS_LOGI("%{public}s_%{public}d, deviceType: %{public}s, enabled: %{public}s, " "SetDistributedEnabledByBundle result: %{public}d", bundleOption->GetBundleName().c_str(), bundleOption->GetUid(), deviceType.c_str(), std::to_string(enabled).c_str(), result); @@ -656,6 +663,12 @@ ErrCode AdvancedNotificationService::SetDistributedEnabled(const std::string &de changeInfo.changeType = DeviceStatueChangeType::NOTIFICATION_ENABLE_CHANGE; DistributedExtensionService::GetInstance().DeviceStatusChange(changeInfo); } + + if (result == ERR_OK && !enabled) { + RemoveDistributedNotifications(NotificationConstant::SlotType::LIVE_VIEW, + NotificationConstant::DISTRIBUTED_ENABLE_CLOSE_DELETE, + NotificationConstant::DistributedDeleteType::EXCLUDE_ONE_SLOT); + } return result; } diff --git a/services/ans/src/notification_extension/distributed_extension_service.cpp b/services/ans/src/notification_extension/distributed_extension_service.cpp index 9e1a7a150..f3cf0a9f5 100644 --- a/services/ans/src/notification_extension/distributed_extension_service.cpp +++ b/services/ans/src/notification_extension/distributed_extension_service.cpp @@ -157,38 +157,21 @@ bool DistributedExtensionService::initConfig() return false; } - nlohmann::json localTypeJson = configJson[CFG_KEY_LOCAL_TYPE]; - if (localTypeJson.is_null() || localTypeJson.empty()) { - ANS_LOGE("Dans initConfig local type as invalid json."); - } else { - deviceConfig_.localType = localTypeJson.get(); - ANS_LOGI("Dans initConfig local type %{public}s.", deviceConfig_.localType.c_str()); - } - - nlohmann::json supportJson = configJson[CFG_KEY_SUPPORT_DEVICES]; - if (supportJson.is_null() || supportJson.empty() || !supportJson.is_array()) { - ANS_LOGE("Dans initConfig support type as invalid json."); + SetLocalType(configJson); + if (!SetSupportPeerDevice(configJson)) { return false; } - - for (auto &deviceJson : supportJson) { - ANS_LOGI("Dans initConfig support type %{public}s.", deviceJson.get().c_str()); - deviceConfig_.supportPeerDevice.insert(deviceJson.get()); - } - - nlohmann::json titleJson = configJson[CFG_KEY_TITLE_LENGTH]; - if (titleJson.is_null() || titleJson.empty() || !titleJson.is_number_integer()) { - deviceConfig_.maxTitleLength = DEFAULT_TITLE_LENGTH; - } else { - deviceConfig_.maxTitleLength = titleJson.get(); - ANS_LOGI("Dans initConfig title length %{public}d.", deviceConfig_.maxTitleLength); - } - + SetMaxTitleLength(configJson); SetMaxContentLength(configJson); SetOperationReplyTimeout(configJson); deviceConfig_.collaborativeDeleteTypes = NotificationConfigParse::GetInstance()->GetCollaborativeDeleteType(); deviceConfig_.startAbilityTimeout = NotificationConfigParse::GetInstance()->GetStartAbilityTimeout(); + std::map>> map; + auto res = NotificationConfigParse::GetInstance()->GetCollaborativeDeleteTypeByDevice(map); + if (res && !map.empty()) { + deviceConfig_.collaborativeDeleteTypesByDevice = map; + } return true; } @@ -484,5 +467,52 @@ void DistributedExtensionService::SetMaxContentLength(nlohmann::json &configJson ANS_LOGI("Dans initConfig content length %{public}d.", deviceConfig_.maxContentLength); } } + +bool DistributedExtensionService::SetLocalType(nlohmann::json &configJson) +{ + nlohmann::json localTypeJson = configJson[CFG_KEY_LOCAL_TYPE]; + if (localTypeJson.is_null() || localTypeJson.empty()) { + ANS_LOGE("Dans initConfig local type as invalid json."); + return false; + } + + if (!localTypeJson.is_string()) { + ANS_LOGE("Dans initConfig local type not string"); + return false; + } + + deviceConfig_.localType = localTypeJson.get(); + ANS_LOGI("Dans initConfig local type %{public}s.", deviceConfig_.localType.c_str()); + return true; +} + +bool DistributedExtensionService::SetSupportPeerDevice(nlohmann::json &configJson) +{ + nlohmann::json supportJson = configJson[CFG_KEY_SUPPORT_DEVICES]; + if (supportJson.is_null() || supportJson.empty() || !supportJson.is_array()) { + ANS_LOGE("Dans initConfig support type as invalid json."); + return false; + } + + for (auto &deviceJson : supportJson) { + if (deviceJson.is_string()) { + deviceConfig_.supportPeerDevice.insert(deviceJson.get()); + ANS_LOGI("Dans initConfig support type %{public}s.", deviceJson.get().c_str()); + } + } + return true; +} + +bool DistributedExtensionService::SetMaxTitleLength(nlohmann::json &configJson) +{ + nlohmann::json titleJson = configJson[CFG_KEY_TITLE_LENGTH]; + if (titleJson.is_null() || titleJson.empty() || !titleJson.is_number_integer()) { + deviceConfig_.maxTitleLength = DEFAULT_TITLE_LENGTH; + } else { + deviceConfig_.maxTitleLength = titleJson.get(); + ANS_LOGI("Dans initConfig title length %{public}d.", deviceConfig_.maxTitleLength); + } + return true; +} } } diff --git a/services/ans/test/unittest/notification_extension/notification_config_parse_mock.cpp b/services/ans/test/unittest/notification_extension/notification_config_parse_mock.cpp index 12ce89cb1..1d0e6cd38 100644 --- a/services/ans/test/unittest/notification_extension/notification_config_parse_mock.cpp +++ b/services/ans/test/unittest/notification_extension/notification_config_parse_mock.cpp @@ -184,6 +184,12 @@ bool NotificationConfigParse::IsReportTrustList(const std::string& bundleName) c { return true; } + +bool NotificationConfigParse::GetCollaborativeDeleteTypeByDevice(std::map>>& resultMap) const +{ + return true; +} } // namespace Notification } // namespace OHOS diff --git a/services/distributed/BUILD.gn b/services/distributed/BUILD.gn index 87ab3b7c8..2b1def176 100644 --- a/services/distributed/BUILD.gn +++ b/services/distributed/BUILD.gn @@ -122,6 +122,7 @@ ohos_shared_library("libdans") { "src/tlv_box/bundle_icon_box.cpp", "src/tlv_box/match_box.cpp", "src/tlv_box/notification_sync_box.cpp", + "src/tlv_box/remove_all_distributed_box.cpp", "src/tlv_box/remove_box.cpp", "src/tlv_box/request_box.cpp", "src/tlv_box/response_box.cpp", diff --git a/services/distributed/include/base/distributed_local_config.h b/services/distributed/include/base/distributed_local_config.h index 27f93038c..5c0dc2213 100644 --- a/services/distributed/include/base/distributed_local_config.h +++ b/services/distributed/include/base/distributed_local_config.h @@ -34,6 +34,8 @@ public: int32_t GetContentLength() const; uint32_t GetStartAbilityTimeout() const; std::unordered_set GetCollaborativeDeleteTypes() const; + void GetCollaborativeDeleteTypesByDevices( + std::map>>& config) const; private: DistributedDeviceConfig localConfig_; }; diff --git a/services/distributed/include/soft_bus/distributed_device_service.h b/services/distributed/include/soft_bus/distributed_device_service.h index 5b72b9890..6e0f03753 100644 --- a/services/distributed/include/soft_bus/distributed_device_service.h +++ b/services/distributed/include/soft_bus/distributed_device_service.h @@ -55,6 +55,7 @@ public: void AddDeviceInfo(DistributedDeviceInfo deviceItem); void DeleteDeviceInfo(const std::string& deviceId); std::map& GetDeviceList(); + void GetDeviceList(std::map& peerDevices); int32_t SyncDeviceMatch(const DistributedDeviceInfo peerDevice, MatchType type); #ifdef DISTRIBUTED_FEATURE_MASTER void SetDeviceStatus(const std::shared_ptr& boxMessage); diff --git a/services/distributed/include/soft_bus/distributed_publish_service.h b/services/distributed/include/soft_bus/distributed_publish_service.h index 44edf6a7a..c6bb75800 100644 --- a/services/distributed/include/soft_bus/distributed_publish_service.h +++ b/services/distributed/include/soft_bus/distributed_publish_service.h @@ -21,6 +21,12 @@ #include "request_box.h" #include "notification_request.h" #include "distributed_device_data.h" +#ifdef DISTRIBUTED_FEATURE_MASTER +#include "remove_box.h" +#include "batch_remove_box.h" +#else +#endif + namespace OHOS { namespace Notification { @@ -29,12 +35,15 @@ public: static DistributedPublishService& GetInstance(); void RemoveNotification(const std::shared_ptr& boxMessage); void RemoveNotifications(const std::shared_ptr& boxMessage); + void BatchRemoveReport(const std::string &slotTypesString, const int result); + int RemoveDistributedNotifications(const std::vector& hashcodes); void OnRemoveNotification(const DistributedDeviceInfo& peerDevice, std::string hashCode, int32_t slotTypes); void OnRemoveNotifications(const DistributedDeviceInfo& peerDevice, std::string hashCodes, std::string slotTypes); #ifdef DISTRIBUTED_FEATURE_MASTER + void RemoveAllDistributedNotificaions(DistributedDeviceInfo& deviceInfo); void SyncLiveViewNotification(const DistributedDeviceInfo peerDevice, bool isForce); void SendNotifictionRequest(const std::shared_ptr request, const DistributedDeviceInfo& peerDevice, bool isSyncNotification = false); @@ -47,9 +56,14 @@ private: NotificationConstant::SlotType slotType, std::shared_ptr& requestBox); void SetNotificationContent(const std::shared_ptr &content, NotificationContent::Type type, std::shared_ptr& requestBox); + bool ForWardRemove(const std::shared_ptr& boxMessage, std::string& deviceId); + std::shared_ptr MakeRemvoeBox(std::string &hashCode, int32_t &slotTypes); + std::shared_ptr MakeBatchRemvoeBox(std::vector& hashCodes, + std::string &slotTypes); #else void PublishNotification(const std::shared_ptr& boxMessage); void PublishSynchronousLiveView(const std::shared_ptr& boxMessage); + void RemoveAllDistributedNotifications(); private: void MakeExtendInfo(const NotificationRequestBox& box, sptr& request); void MakeNotificationButtons(const NotificationRequestBox& box, diff --git a/services/distributed/include/soft_bus/distributed_service.h b/services/distributed/include/soft_bus/distributed_service.h index 5961e672b..1b17aa3a1 100644 --- a/services/distributed/include/soft_bus/distributed_service.h +++ b/services/distributed/include/soft_bus/distributed_service.h @@ -58,6 +58,10 @@ public: void SyncInstalledBundle(const std::string& bundleName, bool isAdd); #endif std::string GetNotificationKey(const std::shared_ptr& notification); + constexpr static const char* WEARABLE_DEVICE_TYPE = "wearable"; + constexpr static const char* PAD_DEVICE_TYPE = "pad"; + constexpr static const char* PC_DEVICE_TYPE = "pc"; + constexpr static const char* PHONE_DEVICE_TYPE = "phone"; private: void OnHandleMsg(std::shared_ptr& box); void ConnectPeerDevice(DistributedDeviceInfo device); diff --git a/services/distributed/include/soft_bus/distributed_subscriber.h b/services/distributed/include/soft_bus/distributed_subscriber.h index be4aa3e19..1514c2158 100644 --- a/services/distributed/include/soft_bus/distributed_subscriber.h +++ b/services/distributed/include/soft_bus/distributed_subscriber.h @@ -47,6 +47,9 @@ public: void SetPeerDevice(DistributedDeviceInfo localDevice); bool CheckNeedCollaboration(const std::shared_ptr ¬ification); bool CheckCollaborativeRemoveType(const NotificationConstant::SlotType& slotType); + bool CheckTypeByCcmRule(const std::string& slotType, + const std::string& localDeviceType, const std::string& peerDeviceType); + std::string SlotEnumToSring(const NotificationConstant::SlotType& slotType); bool HasOnBatchCancelCallback() override { return true; diff --git a/services/distributed/include/tlv_box/batch_remove_box.h b/services/distributed/include/tlv_box/batch_remove_box.h index 54fc1dc37..1045e51f8 100644 --- a/services/distributed/include/tlv_box/batch_remove_box.h +++ b/services/distributed/include/tlv_box/batch_remove_box.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -28,8 +28,12 @@ public: BatchRemoveNotificationBox(); ~BatchRemoveNotificationBox(); BatchRemoveNotificationBox(std::shared_ptr box); - bool SetNotificationHashCode(const std::string& hashCode); + bool SetNotificationHashCodes(const std::string& hashCodes); bool SetNotificationSlotTypes(const std::string &slotTypes); + bool SetLocalDeviceId(const std::string &deviceId); + bool GetNotificationHashCodes(std::string &hashCodes) const; + bool GetNotificationSlotTypes(std::string &slotType) const; + bool GetLocalDeviceId(std::string &deviceId) const; }; } // namespace Notification } // namespace OHOS diff --git a/services/distributed/include/tlv_box/remove_all_distributed_box.h b/services/distributed/include/tlv_box/remove_all_distributed_box.h new file mode 100644 index 000000000..64ceaef0f --- /dev/null +++ b/services/distributed/include/tlv_box/remove_all_distributed_box.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_NOTIFICATION_DISTRIBUTED_REMOVEALL_DISTRIBUTED_NOTIFICATIONS_BOX_H +#define BASE_NOTIFICATION_DISTRIBUTED_REMOVEALL_DISTRIBUTED_NOTIFICATIONS_BOX_H + +#include + +#include "box_base.h" +#include "tlv_box.h" + +namespace OHOS { +namespace Notification { +class RemoveAllDistributedNotificationsBox : public BoxBase { +public: + RemoveAllDistributedNotificationsBox(); + ~RemoveAllDistributedNotificationsBox(); + RemoveAllDistributedNotificationsBox(std::shared_ptr box); +}; +} // namespace Notification +} // namespace OHOS +#endif // BASE_NOTIFICATION_DISTRIBUTED_REMOVEALL_DISTRIBUTED_NOTIFICATIONS_BOX_H diff --git a/services/distributed/include/tlv_box/remove_box.h b/services/distributed/include/tlv_box/remove_box.h index d34c03429..6d05de125 100644 --- a/services/distributed/include/tlv_box/remove_box.h +++ b/services/distributed/include/tlv_box/remove_box.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -28,7 +28,11 @@ public: ~NotificationRemoveBox(); NotificationRemoveBox(std::shared_ptr box); bool SetNotificationHashCode(const std::string& hashCode); - bool setNotificationSlotType(int32_t slotType); + bool SetNotificationSlotType(int32_t slotType); + bool SetLocalDeviceId(const std::string &deviceId); + bool GetNotificationHashCode(std::string &hashCode) const; + bool GetNotificationSlotType(int32_t &slotType) const; + bool GetLocalDeviceId(std::string &deviceId) const; }; } // namespace Notification } // namespace OHOS diff --git a/services/distributed/include/tlv_box/tlv_box.h b/services/distributed/include/tlv_box/tlv_box.h index fbb17f29a..c0596064c 100644 --- a/services/distributed/include/tlv_box/tlv_box.h +++ b/services/distributed/include/tlv_box/tlv_box.h @@ -37,6 +37,7 @@ enum NotificationEventType : int32_t { SYNC_NOTIFICATION = 10, NOTIFICATION_RESPONSE_REPLY_SYNC = 11, INSTALLED_BUNDLE_SYNC = 12, + REMOVE_ALL_DISTRIBUTED_NOTIFICATIONS = 13, }; enum TlvType : int32_t { diff --git a/services/distributed/src/base/distributed_local_config.cpp b/services/distributed/src/base/distributed_local_config.cpp index e9c279ad1..5ee8d248c 100644 --- a/services/distributed/src/base/distributed_local_config.cpp +++ b/services/distributed/src/base/distributed_local_config.cpp @@ -50,5 +50,10 @@ std::unordered_set DistributedLocalConfig::GetCollaborativeDeleteTy return localConfig_.collaborativeDeleteTypes; } +void DistributedLocalConfig::GetCollaborativeDeleteTypesByDevices( + std::map>>& config) const +{ + config = localConfig_.collaborativeDeleteTypesByDevice; +} } } diff --git a/services/distributed/src/soft_bus/distributed_device_service.cpp b/services/distributed/src/soft_bus/distributed_device_service.cpp index 3d801de4b..c580a5540 100644 --- a/services/distributed/src/soft_bus/distributed_device_service.cpp +++ b/services/distributed/src/soft_bus/distributed_device_service.cpp @@ -22,6 +22,7 @@ #include "distributed_device_data.h" #include "notification_helper.h" #include "distributed_observer_service.h" +#include "distributed_service.h" namespace OHOS { namespace Notification { @@ -39,19 +40,19 @@ std::string DistributedDeviceService::DeviceTypeToTypeString(uint16_t deviceType { switch (deviceType) { case DistributedHardware::DmDeviceType::DEVICE_TYPE_WATCH: { - return "wearable"; + return DistributedService::WEARABLE_DEVICE_TYPE; } case DistributedHardware::DmDeviceType::DEVICE_TYPE_PAD: { - return "pad"; + return DistributedService::PAD_DEVICE_TYPE; } case DistributedHardware::DmDeviceType::DEVICE_TYPE_PC: { - return "pc"; + return DistributedService::PC_DEVICE_TYPE; } case DistributedHardware::DmDeviceType::DEVICE_TYPE_2IN1: { - return "pc"; + return DistributedService::PC_DEVICE_TYPE; } case DistributedHardware::DmDeviceType::DEVICE_TYPE_PHONE: { - return "phone"; + return DistributedService::PHONE_DEVICE_TYPE; } default: return ""; @@ -285,6 +286,14 @@ std::map& DistributedDeviceService::GetDevic return peerDevice_; } +void DistributedDeviceService::GetDeviceList(std::map& peerDevices) +{ + std::lock_guard lock(mapLock_); + for (auto deviceItem : peerDevice_) { + peerDevices[deviceItem.first] = deviceItem.second; + } +} + int32_t DistributedDeviceService::SyncDeviceMatch(const DistributedDeviceInfo peerDevice, MatchType type) { std::shared_ptr matchBox = std::make_shared(); diff --git a/services/distributed/src/soft_bus/distributed_publish_service_v2.cpp b/services/distributed/src/soft_bus/distributed_publish_service_v2.cpp index f38eb26af..8933a155e 100644 --- a/services/distributed/src/soft_bus/distributed_publish_service_v2.cpp +++ b/services/distributed/src/soft_bus/distributed_publish_service_v2.cpp @@ -36,6 +36,7 @@ #include "int_wrapper.h" #include "string_wrapper.h" #include "distributed_subscribe_service.h" +#include "remove_all_distributed_box.h" namespace OHOS { namespace Notification { @@ -64,15 +65,27 @@ void DistributedPublishService::RemoveNotification(const std::shared_ptr { std::string hashCode; int32_t slotType; - if (boxMessage == nullptr) { - ANS_LOGE("boxMessage is nullptr"); + NotificationRemoveBox removeBox = NotificationRemoveBox(boxMessage); + removeBox.GetNotificationHashCode(hashCode); + removeBox.GetNotificationSlotType(slotType); + + if (hashCode.empty()) { + ANS_LOGW("dans remove hashCode empty"); return; } - boxMessage->GetStringValue(NOTIFICATION_HASHCODE, hashCode); - boxMessage->GetInt32Value(NOTIFICATION_SLOT_TYPE, slotType); +#ifdef DISTRIBUTED_FEATURE_MASTER + std::string deviceId; + removeBox.GetLocalDeviceId(deviceId); + std::shared_ptr forwardBox = MakeRemvoeBox(hashCode, slotType); + if (forwardBox != nullptr) { + ForWardRemove(forwardBox, deviceId); + } +#else +#endif + std::vector hashCodes; + hashCodes.push_back(hashCode); - int result = IN_PROCESS_CALL(NotificationHelper::RemoveNotification( - hashCode, NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE)); + int result = RemoveDistributedNotifications(hashCodes); std::string errorReason = "delete message failed"; if (result == 0) { errorReason = "delete message success"; @@ -86,16 +99,16 @@ void DistributedPublishService::RemoveNotification(const std::shared_ptr void DistributedPublishService::RemoveNotifications(const std::shared_ptr& boxMessage) { + BatchRemoveNotificationBox removeBox = BatchRemoveNotificationBox(boxMessage); std::vector hashCodes; std::string hashCodesString; - if (boxMessage == nullptr) { - ANS_LOGE("boxMessage is nullptr"); - return; - } - if (!boxMessage->GetStringValue(NOTIFICATION_HASHCODE, hashCodesString)) { - ANS_LOGE("failed GetStringValue from boxMessage"); + removeBox.GetNotificationHashCodes(hashCodesString); + if (hashCodesString.empty()) { + ANS_LOGW("dans remove hashCodesString empty"); return; } + std::string slotTypesString; + removeBox.GetNotificationSlotTypes(slotTypesString); std::istringstream hashCodesStream(hashCodesString); std::string hashCode; while (hashCodesStream >> hashCode) { @@ -104,17 +117,42 @@ void DistributedPublishService::RemoveNotifications(const std::shared_ptr forwardBox = MakeBatchRemvoeBox(hashCodes, slotTypesString); + if (forwardBox != nullptr) { + ForWardRemove(forwardBox, deviceId); + } +#else +#endif + + int result = RemoveDistributedNotifications(hashCodes); + BatchRemoveReport(slotTypesString, result); + ANS_LOGI("dans br re:%{public}d., hs:%{public}s", result, hashCodesString.c_str()); +} + +int DistributedPublishService::RemoveDistributedNotifications(const std::vector& hashcodes) +{ + int res = 0; + auto local = DistributedDeviceService::GetInstance().GetLocalDevice(); + if (local.deviceType_ == DistributedHardware::DmDeviceType::DEVICE_TYPE_PHONE) { + res = IN_PROCESS_CALL(NotificationHelper::RemoveNotifications( + hashcodes, NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE)); + } else { + res = IN_PROCESS_CALL(NotificationHelper::RemoveDistributedNotifications(hashcodes, + NotificationConstant::SlotType::SOCIAL_COMMUNICATION, + NotificationConstant::DistributedDeleteType::HASHCODES, + NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE)); + } + return res; +} + +void DistributedPublishService::BatchRemoveReport(const std::string &slotTypesString, const int result) +{ if (result == 0) { AnalyticsUtil::GetInstance().AbnormalReporting(DELETE_ERROR_EVENT_CODE, result, BRANCH4_ID, "delete message success"); - std::string slotTypesString; - if (!boxMessage->GetStringValue(BATCH_REMOVE_SLOT_TYPE, slotTypesString)) { - ANS_LOGE("failed GetStringValue from boxMessage"); - return; - } std::istringstream slotTypesStream(slotTypesString); std::string slotTypeString; while (slotTypesStream >> slotTypeString) { @@ -133,9 +171,17 @@ void DistributedPublishService::OnRemoveNotification(const DistributedDeviceInfo std::string hashCode, int32_t slotTypes) { std::shared_ptr removeBox = std::make_shared(); + if (removeBox == nullptr) { + ANS_LOGE("create batchRemoveBox err"); + return; + } + ANS_LOGI("dans OnCanceled %{public}s", hashCode.c_str()); removeBox->SetNotificationHashCode(hashCode); - removeBox->setNotificationSlotType(slotTypes); + removeBox->SetNotificationSlotType(slotTypes); + auto local = DistributedDeviceService::GetInstance().GetLocalDevice(); + removeBox->SetLocalDeviceId(local.deviceId_); + if (!removeBox->Serialize()) { ANS_LOGW("dans OnCanceled serialize failed"); return; @@ -148,10 +194,14 @@ void DistributedPublishService::OnRemoveNotifications(const DistributedDeviceInf std::string hashCodes, std::string slotTypes) { std::shared_ptr batchRemoveBox = std::make_shared(); - if (!hashCodes.empty()) { - batchRemoveBox->SetNotificationHashCode(hashCodes); + if (batchRemoveBox == nullptr) { + ANS_LOGE("create batchRemoveBox err"); + return; } + batchRemoveBox->SetNotificationHashCodes(hashCodes); batchRemoveBox->SetNotificationSlotTypes(slotTypes); + auto local = DistributedDeviceService::GetInstance().GetLocalDevice(); + batchRemoveBox->SetLocalDeviceId(local.deviceId_); if (!batchRemoveBox->Serialize()) { ANS_LOGW("dans OnCanceled serialize failed"); @@ -162,6 +212,96 @@ void DistributedPublishService::OnRemoveNotifications(const DistributedDeviceInf } #ifdef DISTRIBUTED_FEATURE_MASTER +void DistributedPublishService::RemoveAllDistributedNotificaions(DistributedDeviceInfo& deviceInfo) +{ + std::shared_ptr removeBox = + std::make_shared(); + if (removeBox == nullptr) { + ANS_LOGW("create box error"); + return; + } + + if (!removeBox->Serialize()) { + ANS_LOGW("dans OnCanceled serialize failed"); + return; + } + ANS_LOGI("RemoveAllDistributedNotificaions ID:%{public}s", + StringAnonymous(deviceInfo.deviceId_).c_str()); + DistributedClient::GetInstance().SendMessage(removeBox, TransDataType::DATA_TYPE_MESSAGE, + deviceInfo.deviceId_, DELETE_ERROR_EVENT_CODE); +} + +bool DistributedPublishService::ForWardRemove(const std::shared_ptr& boxMessage, + std::string& deviceId) +{ + auto local = DistributedDeviceService::GetInstance().GetLocalDevice(); + if (local.deviceType_ != DistributedHardware::DmDeviceType::DEVICE_TYPE_PHONE) { + ANS_LOGD("no need forward"); + return false; + } + std::map peerDevices; + DistributedDeviceService::GetInstance().GetDeviceList(peerDevices); + if (peerDevices.empty()) { + ANS_LOGW("no peerDevices"); + return false; + } + + for (auto peerDevice : peerDevices) { + auto peerDeviceInfo = peerDevice.second; + if (peerDeviceInfo.deviceId_ == deviceId) { + ANS_LOGD("no need ForWardRemove"); + continue; + } + DistributedClient::GetInstance().SendMessage(boxMessage, TransDataType::DATA_TYPE_MESSAGE, + peerDeviceInfo.deviceId_, DELETE_ERROR_EVENT_CODE); + ANS_LOGI("ForWardRemove,deviceId:%{public}s", StringAnonymous(peerDeviceInfo.deviceId_).c_str()); + } + return true; +} + +std::shared_ptr DistributedPublishService::MakeRemvoeBox( + std::string &hashCode, int32_t &slotTypes) +{ + std::shared_ptr removeBox = std::make_shared(); + if (removeBox == nullptr) { + ANS_LOGE("MakeRemvoeBox ERR"); + return nullptr; + } + removeBox->SetNotificationHashCode(DISTRIBUTED_LABEL + hashCode); + removeBox->SetNotificationSlotType(slotTypes); + + if (!removeBox->Serialize()) { + ANS_LOGW("dans OnCanceled serialize failed"); + return nullptr; + } + + return removeBox; +} + +std::shared_ptr DistributedPublishService::MakeBatchRemvoeBox( + std::vector& hashCodes, std::string &slotTypes) +{ + std::shared_ptr batchRemoveBox = std::make_shared(); + if (batchRemoveBox == nullptr) { + ANS_LOGE("MakeBatchRemvoeBox ERR"); + return nullptr; + } + std::ostringstream keysStream; + for (auto hashCode : hashCodes) { + auto key = DISTRIBUTED_LABEL + hashCode; + keysStream << key << ' '; + } + std::string hashCodeStrings = keysStream.str(); + batchRemoveBox->SetNotificationHashCodes(hashCodeStrings); + batchRemoveBox->SetNotificationSlotTypes(slotTypes); + + if (!batchRemoveBox->Serialize()) { + ANS_LOGW("dans OnCanceled serialize failed"); + return nullptr; + } + return batchRemoveBox; +} + void DistributedPublishService::SyncLiveViewNotification(const DistributedDeviceInfo peerDevice, bool isForce) { if (!DistributedDeviceService::GetInstance().IsSyncLiveView(peerDevice.deviceId_, isForce)) { @@ -390,6 +530,15 @@ void DistributedPublishService::SetNotificationExtendInfo(const sptr hashcodes; + IN_PROCESS_CALL(NotificationHelper::RemoveDistributedNotifications(hashcodes, + NotificationConstant::SlotType::SOCIAL_COMMUNICATION, + NotificationConstant::DistributedDeleteType::ALL, + NotificationConstant::DISTRIBUTED_RELEASE_DELETE)); +} + void DistributedPublishService::PublishNotification(const std::shared_ptr& boxMessage) { sptr request = new (std::nothrow) NotificationRequest(); diff --git a/services/distributed/src/soft_bus/distributed_service.cpp b/services/distributed/src/soft_bus/distributed_service.cpp index b0f6e9bdb..1a7fb7e1b 100644 --- a/services/distributed/src/soft_bus/distributed_service.cpp +++ b/services/distributed/src/soft_bus/distributed_service.cpp @@ -152,6 +152,18 @@ void DistributedService::ReleaseDevice(const std::string &deviceId, uint16_t dev } std::function subscribeTask = std::bind([deviceId, deviceType]() { DistributedSubscribeService::GetInstance().UnSubscribeNotification(deviceId, deviceType); + auto localDevice = DistributedDeviceService::GetInstance().GetLocalDevice(); + if (localDevice.deviceType_ == DistributedHardware::DmDeviceType::DEVICE_TYPE_WATCH) { + ANS_LOGD("watch not delete notifications"); + return; + } + if (deviceType == DistributedHardware::DmDeviceType::DEVICE_TYPE_PHONE) { + std::vector hashcodes; + NotificationHelper::RemoveDistributedNotifications(hashcodes, + NotificationConstant::SlotType::SOCIAL_COMMUNICATION, + NotificationConstant::DistributedDeleteType::ALL, + NotificationConstant::DISTRIBUTED_RELEASE_DELETE); + } }); serviceQueue_->submit(subscribeTask); } @@ -176,6 +188,15 @@ void DistributedService::DeviceStatusChange(const DeviceStatueChangeInfo& change DistributedDeviceService::GetInstance().SetSubscribeAllConnect(true); } } + + if (changeInfo.changeType == DeviceStatueChangeType::DEVICE_USING_CLOSE) { + DistributedDeviceInfo device; + if (!DistributedDeviceService::GetInstance().GetDeviceInfoByUdid(changeInfo.deviceId, device)) { + ANS_LOGW("get deviceId err"); + return; + } + DistributedPublishService::GetInstance().RemoveAllDistributedNotificaions(device); + } #else if (changeInfo.changeType == DeviceStatueChangeType::NOTIFICATION_ENABLE_CHANGE) { DistributedDeviceService::GetInstance().SyncDeviceStatus(DistributedDeviceService::STATE_TYPE_SWITCH, @@ -447,6 +468,9 @@ void DistributedService::OnHandleMsg(std::shared_ptr& box) case NotificationEventType::SYNC_NOTIFICATION: DistributedPublishService::GetInstance().PublishSynchronousLiveView(box); break; + case NotificationEventType::REMOVE_ALL_DISTRIBUTED_NOTIFICATIONS: + DistributedPublishService::GetInstance().RemoveAllDistributedNotifications(); + break; #endif default: break; diff --git a/services/distributed/src/soft_bus/distributed_subscriber.cpp b/services/distributed/src/soft_bus/distributed_subscriber.cpp index 824970230..7bd3218f8 100644 --- a/services/distributed/src/soft_bus/distributed_subscriber.cpp +++ b/services/distributed/src/soft_bus/distributed_subscriber.cpp @@ -56,7 +56,9 @@ void DistribuedSubscriber::OnCanceled(const std::shared_ptr &reque ANS_LOGI("Subscriber on canceled %{public}d %{public}s %{public}d %{public}s.", peerDevice_.deviceType_, StringAnonymous(peerDevice_.deviceId_).c_str(), localDevice_.deviceType_, StringAnonymous(localDevice_.deviceId_).c_str()); - if (deleteReason == NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE) { + if (deleteReason == NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE || + deleteReason == NotificationConstant::DISTRIBUTED_ENABLE_CLOSE_DELETE || + deleteReason == NotificationConstant::DISTRIBUTED_RELEASE_DELETE) { ANS_LOGD("is cross device deletion"); return; } @@ -128,7 +130,9 @@ void DistribuedSubscriber::OnBatchCanceled(const std::vector>> deleteConfigDevice; + DistributedLocalConfig::GetInstance().GetCollaborativeDeleteTypesByDevices(deleteConfigDevice); + if (deleteConfigDevice.empty()) { + ANS_LOGW("distributed delete ccm is undefined"); + return false; + } + + auto peerdeleteConfigDeviceIt = deleteConfigDevice.find(localDeviceType); + if (peerdeleteConfigDeviceIt == deleteConfigDevice.end()) { + ANS_LOGW("peerdeleteConfigDevice err, local:%{public}s, per:%{public}s", + localDeviceType.c_str(), peerDeviceType.c_str()); + return false; + } + + auto peerdeleteConfigDevice = peerdeleteConfigDeviceIt->second; + auto deleteSlotTypeListIt = peerdeleteConfigDevice.find(peerDeviceType); + if (deleteSlotTypeListIt == peerdeleteConfigDevice.end()) { + ANS_LOGW("deleteSlotTypeList err, local:%{public}s, per:%{public}s", + localDeviceType.c_str(), peerDeviceType.c_str()); + return false; + } + + auto deleteSlotTypeList = deleteSlotTypeListIt->second; + if (deleteSlotTypeList.find(slotType) == deleteSlotTypeList.end()) { + ANS_LOGD("deleteSlotTypeList no slottype:%{public}s, local:%{public}s, per:%{public}s", + slotType.c_str(), localDeviceType.c_str(), peerDeviceType.c_str()); + return false; + } + + return true; +} + + +std::string DistribuedSubscriber::SlotEnumToSring(const NotificationConstant::SlotType& slotType) { std::string type; switch (slotType) { @@ -215,11 +277,9 @@ bool DistribuedSubscriber::CheckCollaborativeRemoveType(const NotificationConsta type = "ILLEGAL_TYPE"; break; default: - return false; + break; } - auto collaborativeDeleteTypes = DistributedLocalConfig::GetInstance().GetCollaborativeDeleteTypes(); - return collaborativeDeleteTypes.find(type) != collaborativeDeleteTypes.end(); + return type; } - } } diff --git a/services/distributed/src/tlv_box/batch_remove_box.cpp b/services/distributed/src/tlv_box/batch_remove_box.cpp index aba7d7531..4315b371a 100644 --- a/services/distributed/src/tlv_box/batch_remove_box.cpp +++ b/services/distributed/src/tlv_box/batch_remove_box.cpp @@ -32,12 +32,12 @@ BatchRemoveNotificationBox::~BatchRemoveNotificationBox() BatchRemoveNotificationBox::BatchRemoveNotificationBox(std::shared_ptr box) : BoxBase(box) {} -bool BatchRemoveNotificationBox::SetNotificationHashCode(const std::string& hashCode) +bool BatchRemoveNotificationBox::SetNotificationHashCodes(const std::string& hashCodes) { if (box_ == nullptr) { return false; } - return box_->PutValue(std::make_shared(NOTIFICATION_HASHCODE, hashCode)); + return box_->PutValue(std::make_shared(NOTIFICATION_HASHCODE, hashCodes)); } bool BatchRemoveNotificationBox::SetNotificationSlotTypes(const std::string &slotTypes) @@ -47,5 +47,37 @@ bool BatchRemoveNotificationBox::SetNotificationSlotTypes(const std::string &slo } return box_->PutValue(std::make_shared(BATCH_REMOVE_SLOT_TYPE, slotTypes)); } + +bool BatchRemoveNotificationBox::SetLocalDeviceId(const std::string &deviceId) +{ + if (box_ == nullptr) { + return false; + } + return box_->PutValue(std::make_shared(LOCAL_DEVICE_ID, deviceId)); +} + +bool BatchRemoveNotificationBox::GetNotificationHashCodes(std::string& hashCodes) const +{ + if (box_ == nullptr) { + return false; + } + return box_->GetStringValue(NOTIFICATION_HASHCODE, hashCodes); +} + +bool BatchRemoveNotificationBox::GetNotificationSlotTypes(std::string& slotTypes) const +{ + if (box_ == nullptr) { + return false; + } + return box_->GetStringValue(BATCH_REMOVE_SLOT_TYPE, slotTypes); +} + +bool BatchRemoveNotificationBox::GetLocalDeviceId(std::string& deviceId) const +{ + if (box_ == nullptr) { + return false; + } + return box_->GetStringValue(LOCAL_DEVICE_ID, deviceId); +} } } diff --git a/services/distributed/src/tlv_box/remove_all_distributed_box.cpp b/services/distributed/src/tlv_box/remove_all_distributed_box.cpp new file mode 100644 index 000000000..bfb04ca71 --- /dev/null +++ b/services/distributed/src/tlv_box/remove_all_distributed_box.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "remove_all_distributed_box.h" + +namespace OHOS { +namespace Notification { + +RemoveAllDistributedNotificationsBox::RemoveAllDistributedNotificationsBox() +{ + if (box_ == nullptr) { + return; + } + box_->SetMessageType(REMOVE_ALL_DISTRIBUTED_NOTIFICATIONS); +} + +RemoveAllDistributedNotificationsBox::~RemoveAllDistributedNotificationsBox() +{} + +RemoveAllDistributedNotificationsBox::RemoveAllDistributedNotificationsBox( + std::shared_ptr box) : BoxBase(box) +{ +} +} +} \ No newline at end of file diff --git a/services/distributed/src/tlv_box/remove_box.cpp b/services/distributed/src/tlv_box/remove_box.cpp index 7920e2ca7..de81fb340 100644 --- a/services/distributed/src/tlv_box/remove_box.cpp +++ b/services/distributed/src/tlv_box/remove_box.cpp @@ -41,7 +41,7 @@ bool NotificationRemoveBox::SetNotificationHashCode(const std::string& hashCode) return box_->PutValue(std::make_shared(NOTIFICATION_HASHCODE, hashCode)); } -bool NotificationRemoveBox::setNotificationSlotType(int32_t slotType) +bool NotificationRemoveBox::SetNotificationSlotType(int32_t slotType) { if (box_ == nullptr) { return false; @@ -49,5 +49,37 @@ bool NotificationRemoveBox::setNotificationSlotType(int32_t slotType) return box_->PutValue(std::make_shared(NOTIFICATION_SLOT_TYPE, slotType)); } + +bool NotificationRemoveBox::SetLocalDeviceId(const std::string &deviceId) +{ + if (box_ == nullptr) { + return false; + } + return box_->PutValue(std::make_shared(LOCAL_DEVICE_ID, deviceId)); +} + +bool NotificationRemoveBox::GetNotificationHashCode(std::string& hashCode) const +{ + if (box_ == nullptr) { + return false; + } + return box_->GetStringValue(NOTIFICATION_HASHCODE, hashCode); +} + +bool NotificationRemoveBox::GetNotificationSlotType(int32_t &slotType) const +{ + if (box_ == nullptr) { + return false; + } + return box_->GetInt32Value(NOTIFICATION_SLOT_TYPE, slotType); +} + +bool NotificationRemoveBox::GetLocalDeviceId(std::string& deviceId) const +{ + if (box_ == nullptr) { + return false; + } + return box_->GetStringValue(LOCAL_DEVICE_ID, deviceId); +} } } \ No newline at end of file diff --git a/tools/test/mock/mock_ans_manager_stub.h b/tools/test/mock/mock_ans_manager_stub.h index a3e883664..4a51b657e 100644 --- a/tools/test/mock/mock_ans_manager_stub.h +++ b/tools/test/mock/mock_ans_manager_stub.h @@ -178,6 +178,12 @@ public: return ERR_ANS_INVALID_PARAM; } + ErrCode RemoveDistributedNotifications(const std::vector& hashcodes, + const int32_t slotTypeInt, const int32_t deleteTypeInt, const int32_t removeReason) override + { + return ERR_ANS_INVALID_PARAM; + } + ErrCode RemoveNotifications(const std::vector& hashcodes, int32_t removeReason) override { return ERR_ANS_INVALID_PARAM; -- Gitee