diff --git a/frameworks/ans/BUILD.gn b/frameworks/ans/BUILD.gn index 0ab517193f1a084b4cf0cd9d388bf2b1b90fccef..8d19a0a7484e7939ce7eaf34e0928dd0872f8208 100644 --- a/frameworks/ans/BUILD.gn +++ b/frameworks/ans/BUILD.gn @@ -160,6 +160,10 @@ ohos_shared_library("ans_innerkits") { defines += [ "NOTIFICATION_SMART_REMINDER_SUPPORTED" ] } + if (notification_smart_reminder_supported) { + defines += [ "NOTIFICATION_SMART_REMINDER_SUPPORTED" ] + } + innerapi_tags = [ "platformsdk" ] subsystem_name = "${subsystem_name}" part_name = "${component_name}" diff --git a/notification.gni b/notification.gni index e9ac9895c92eeda358d7e941675c8b2a940ed8e2..7b373c5485099c4d7d3bd0e74af9ec59b11382b4 100644 --- a/notification.gni +++ b/notification.gni @@ -58,6 +58,7 @@ declare_args() { notification_smart_reminder_supported = true ans_config_policy_enable = true screenlock_mgr_enable = true + notification_smart_reminder_supported = true if (defined(global_parts_info) && !defined(global_parts_info.resourceschedule_device_usage_statistics)) { diff --git a/services/ans/BUILD.gn b/services/ans/BUILD.gn index 49a5d0da6a3677df363d595f87e90e4c9936cb3d..17aee2a04f1f53ea65a0dc45f3bb0f3e94262ffb 100644 --- a/services/ans/BUILD.gn +++ b/services/ans/BUILD.gn @@ -90,7 +90,6 @@ ohos_shared_library("libans") { defines = [] cflags = [] - deps = [ "${frameworks_module_ans_path}:ans_innerkits", "../ans:ans.para", diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index 0454b238c85655009b499598994a388bb9fddcbf..3dfcfe98bd6c2c0bb22302208ab4a71545977a7d 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -1069,6 +1069,16 @@ public: * @return Returns register swing Callback result. */ ErrCode RegisterSwingCallback(const sptr& swingCallback) override; + + /** + * @brief screen lock event callback. + */ + void OnScreenLock(); + + /** + * @brief screen unlock event callback. + */ + void OnScreenUnlock(); #endif protected: @@ -1287,6 +1297,10 @@ private: std::shared_ptr notificationSlotFilter_ = nullptr; std::shared_ptr dialogManager_ = nullptr; std::list> uniqueKeyList_; +<<<<<<< HEAD +======= + OHOS::Notification::DistributedDeviceStatus DistributedDeviceStatus_ = DistributedDeviceStatus::GetInstance(); +>>>>>>> 623f0cf6 (swingDecision) }; /** diff --git a/services/ans/include/distributed_device_status.h b/services/ans/include/distributed_device_status.h index f54ab3d20e039acb68dac83d84d5ca3d57dde76d..efb6a4340a96330a720462e9101de86b1382a78a 100644 --- a/services/ans/include/distributed_device_status.h +++ b/services/ans/include/distributed_device_status.h @@ -23,11 +23,14 @@ #include "errors.h" #include "ans_log_wrapper.h" #include "safe_map.h" +#include "refbase.h" +#include "singleton.h" namespace OHOS { namespace Notification { class DistributedDeviceStatus : public DelayedSingleton { public: + static DistributedDeviceStatus &GetInstance(); DistributedDeviceStatus(); ~DistributedDeviceStatus(); ErrCode SetDeviceStatus(const std::string &deviceType, const uint32_t status); diff --git a/services/ans/include/interface_system_event.h b/services/ans/include/interface_system_event.h index 71cf783dae1271b5a32e863e70e4dabe93a19889..34331980d5dd1ee455417d357ded68a0fd466317 100644 --- a/services/ans/include/interface_system_event.h +++ b/services/ans/include/interface_system_event.h @@ -29,6 +29,8 @@ struct ISystemEvent { std::function onScreenOn; std::function onScreenOff; #endif + std::function onScreenLock; + std::function onScreenUnlock; std::function onResourceRemove; std::function &)> onBundleDataCleared; std::function &)> onBundleAdd; diff --git a/services/ans/include/notification_subscriber_manager.h b/services/ans/include/notification_subscriber_manager.h index 6973b65ed4b78a8b092b8bf15ec490a8a645b9e8..b1ae7cc127feea62991d99c12f34d6e27e6f81eb 100644 --- a/services/ans/include/notification_subscriber_manager.h +++ b/services/ans/include/notification_subscriber_manager.h @@ -162,6 +162,7 @@ private: void NotifyEnabledNotificationChangedInner(const sptr &callbackData); void NotifyBadgeEnabledChangedInner(const sptr &callbackData); bool IsSystemUser(int32_t userId); + void UpdateCrossDeviceNotificationStatus(); private: bool ProcessSyncDecision( diff --git a/services/ans/include/reminder_swing_decision_center.h b/services/ans/include/reminder_swing_decision_center.h index e397d07fbbc3a2fd54ff56920a8e9405ddc6332a..23395e24614f8c7b5ad331bcafafc16be93e4592 100644 --- a/services/ans/include/reminder_swing_decision_center.h +++ b/services/ans/include/reminder_swing_decision_center.h @@ -26,23 +26,44 @@ #include "common_event_subscriber.h" #include "common_event_manager.h" #include "common_event_support.h" +#include "nlohmann/json.hpp" +#include "notification_config_parse.h" #include "swing_callback_proxy.h" #include "system_event_subscriber.h" namespace OHOS { namespace Notification { +using namespace std; class ReminderSwingDecisionCenter { public: ReminderSwingDecisionCenter(); ~ReminderSwingDecisionCenter(); static ReminderSwingDecisionCenter &GetInstance(); + static sptr swingCallback_; void ResetSwingCallbackProxy(); ErrCode RegisterSwingCallback(const sptr &swingCallback); - static sptr swingCallback_; - + void UpdateCrossDeviceNotificationStatus(bool isEnable); + string GetSwingDeviceType(); + void OnScreenLock(); + void OnScreenUnlock(); + void OnUpdateDeviceStatus(); + void OnSmartReminderStatusChanged(); private: - static std::mutex swingMutex_; + void GetCcmSwingRemind(); + void SwingExecuteDecision(bool isScreenUnlockTrigger = false); + bool IsStatifySwingCrossDeviceStatus(); +private: + static mutex swingMutex_; + string enableSwingDeviceType_; + string enableSwingDeviceStatus_; + bool isCrossDeviceNotificationEnable_; + bool isSupportSwingSmartRemind_; + bool isSwingExecuting_; + bool isScreenUnlock_; sptr swingRecipient_ = nullptr; + + constexpr static inline const char* AFFTECED_BY = "affectedBy"; + constexpr static inline const char* SWING_FILTER = "swingEnableFilter"; }; class SwingCallbackRecipient : public IRemoteObject::DeathRecipient { diff --git a/services/ans/include/smart_reminder_center.h b/services/ans/include/smart_reminder_center.h index 0b0e3b612db8d0068aa5be959c612c5e21b8747b..6073e6904d79fb2af95ebb8f5ac5cae31035b817 100644 --- a/services/ans/include/smart_reminder_center.h +++ b/services/ans/include/smart_reminder_center.h @@ -44,7 +44,7 @@ public: ~SmartReminderCenter() = default; void ReminderDecisionProcess(const sptr &request) const; - + bool CompareStatus(const string &status, const bitset &bitStatus) const; private: void GetMultiDeviceReminder(); void ParseReminderFilterDevice(const nlohmann::json &root, const string &deviceType); @@ -69,7 +69,6 @@ private: const string &deviceType, const shared_ptr &reminderAffected, shared_ptr>> notificationFlagsOfDevices) const; - bool CompareStatus(const string &status, const bitset &bitStatus) const; void GetReminderAffecteds( const map>> &reminderFilterDevice, const sptr &request, diff --git a/services/ans/include/system_event_observer.h b/services/ans/include/system_event_observer.h index 7be63980395cab062d9e59bc968b6275808b23e6..bccd944e2e7d16facca8e2ff70646ccad062c059 100644 --- a/services/ans/include/system_event_observer.h +++ b/services/ans/include/system_event_observer.h @@ -50,6 +50,8 @@ private: void OnBundleUpdateEventInner(const EventFwk::CommonEventData &data); void OnBundleAddEventInner(const EventFwk::CommonEventData &data); void OnBootSystemCompletedEventInner(const EventFwk::CommonEventData &data); + void OnScreenLock(const EventFwk::CommonEventData &data); + void OnScreenUnlock(const EventFwk::CommonEventData &data); private: std::shared_ptr subscriber_ = nullptr; ISystemEvent callbacks_; diff --git a/services/ans/src/advanced_notification_publish_service.cpp b/services/ans/src/advanced_notification_publish_service.cpp index 270a070b9ff528922e14d55d904d55988a9ac9f5..04ec32c42e7ba3d37b38068f4fe33bf121b701f5 100644 --- a/services/ans/src/advanced_notification_publish_service.cpp +++ b/services/ans/src/advanced_notification_publish_service.cpp @@ -38,6 +38,7 @@ #include "common_event_publish_info.h" #include "want_params_wrapper.h" #include "ans_convert_enum.h" +#include "reminder_swing_decision_center.h" #include "advanced_notification_inline.cpp" @@ -2057,7 +2058,7 @@ ErrCode AdvancedNotificationService::IsSmartReminderEnabled(const std::string &d ANS_LOGE("no permission"); return ERR_ANS_PERMISSION_DENIED; } - + ReminderSwingDecisionCenter::GetInstance().OnSmartReminderStatusChanged(); return NotificationPreferences::GetInstance().IsSmartReminderEnabled(deviceType, enabled); } @@ -2075,6 +2076,7 @@ ErrCode AdvancedNotificationService::SetTargetDeviceStatus(const std::string &de } int ret = DelayedSingleton::GetInstance()->SetDeviceStatus(deviceType, status_); + ReminderSwingDecisionCenter::GetInstance().OnUpdateDeviceStatus(); ANS_LOGI("%{public}s device status update with %{public}u", deviceType.c_str(), DelayedSingleton::GetInstance()->GetDeviceStatus(deviceType)); return ret; diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 074f0315fa7b9201d8a601ba464e8ceba1a86c22..ed0ce7c471e0c5c3151fec624ba1e91f9c6214e4 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -273,6 +273,8 @@ AdvancedNotificationService::AdvancedNotificationService() std::bind(&AdvancedNotificationService::OnScreenOn, this), std::bind(&AdvancedNotificationService::OnScreenOff, this), #endif + std::bind(&AdvancedNotificationService::OnScreenLock, this), + std::bind(&AdvancedNotificationService::OnScreenUnlock, this), std::bind(&AdvancedNotificationService::OnResourceRemove, this, std::placeholders::_1), std::bind(&AdvancedNotificationService::OnBundleDataCleared, this, std::placeholders::_1), std::bind(&AdvancedNotificationService::OnBundleDataAdd, this, std::placeholders::_1), diff --git a/services/ans/src/advanced_notification_utils.cpp b/services/ans/src/advanced_notification_utils.cpp index ffc540e1e636bd59941c37139e7847f449528a63..22b9b8030bad6cfe6fdc015b55cb6937c2498590 100644 --- a/services/ans/src/advanced_notification_utils.cpp +++ b/services/ans/src/advanced_notification_utils.cpp @@ -32,6 +32,7 @@ #include "want_agent_helper.h" #include "hitrace_meter.h" #include "notification_timer_info.h" +#include "reminder_swing_decision_center.h" #include "time_service_client.h" #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED @@ -1844,5 +1845,15 @@ std::vector AdvancedNotificationService::GetBundlesOfAct return bundleInfos; } + +void AdvancedNotificationService::OnScreenLock() +{ + ReminderSwingDecisionCenter::GetInstance().OnScreenLock(); +} + +void AdvancedNotificationService::OnScreenUnlock() +{ + ReminderSwingDecisionCenter::GetInstance().OnScreenUnlock(); +} } // namespace Notification } // namespace OHOS diff --git a/services/ans/src/notification_subscriber_manager.cpp b/services/ans/src/notification_subscriber_manager.cpp index 5c972d382635b95a2923dd07fbbf9d2959ee0504..512f8292db8f1f47ea86f6ffea4a76a6a43732d1 100644 --- a/services/ans/src/notification_subscriber_manager.cpp +++ b/services/ans/src/notification_subscriber_manager.cpp @@ -31,6 +31,7 @@ #include "notification_extension_wrapper.h" #include "os_account_manager.h" #include "remote_death_recipient.h" +#include "reminder_swing_decision_center.h" namespace OHOS { namespace Notification { @@ -270,6 +271,7 @@ void NotificationSubscriberManager::OnRemoteDied(const wptr &obje if (record != nullptr) { ANS_LOGW("subscriber removed."); subscriberRecordList_.remove(record); + UpdateCrossDeviceNotificationStatus(); } })); notificationSubQueue_->wait(handler); @@ -361,6 +363,7 @@ ErrCode NotificationSubscriberManager::AddSubscriberInner( return ERR_ANS_NO_MEMORY; } subscriberRecordList_.push_back(record); + UpdateCrossDeviceNotificationStatus(); record->subscriber->AsObject()->AddDeathRecipient(recipient_); @@ -393,6 +396,7 @@ ErrCode NotificationSubscriberManager::RemoveSubscriberInner( record->subscriber->AsObject()->RemoveDeathRecipient(recipient_); subscriberRecordList_.remove(record); + UpdateCrossDeviceNotificationStatus(); record->subscriber->OnDisconnected(); ANS_LOGI("subscriber is disconnected."); @@ -437,6 +441,25 @@ bool NotificationSubscriberManager::GetIsEnableEffectedRemind() return false; } +void NotificationSubscriberManager::UpdateCrossDeviceNotificationStatus() +{ + bool isEnable = false; + std::string deviceType = ReminderSwingDecisionCenter::GetInstance().GetSwingDeviceType(); + if (deviceType.empty()) { + ANS_LOGE("GetIsEnableSwingEffectedRemind deviceType is empty"); + return; + } + + for (auto record : subscriberRecordList_) { + if (record->deviceType.compare(deviceType) == 0) { + isEnable = true; + break; + } + } + + ReminderSwingDecisionCenter::GetInstance().UpdateCrossDeviceNotificationStatus(isEnable); +} + bool NotificationSubscriberManager::ProcessSyncDecision( const std::string &deviceType, const sptr ¬ification) const { diff --git a/services/ans/src/reminder_swing_decision_center.cpp b/services/ans/src/reminder_swing_decision_center.cpp index ba353680bbda9aad6e43b1cd4981cc255a930943..e846cba30a2774f5f4d259da572a05f8256ae2d6 100644 --- a/services/ans/src/reminder_swing_decision_center.cpp +++ b/services/ans/src/reminder_swing_decision_center.cpp @@ -15,13 +15,18 @@ #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED #include "reminder_swing_decision_center.h" #include "notification_preferences.h" +#include "smart_reminder_center.h" namespace OHOS { namespace Notification { -std::mutex ReminderSwingDecisionCenter::swingMutex_; +using namespace std; +mutex ReminderSwingDecisionCenter::swingMutex_; sptr ReminderSwingDecisionCenter::swingCallback_; -ReminderSwingDecisionCenter::ReminderSwingDecisionCenter() {} +ReminderSwingDecisionCenter::ReminderSwingDecisionCenter() +{ + GetCcmSwingRemind(); +} ReminderSwingDecisionCenter::~ReminderSwingDecisionCenter() {} @@ -36,7 +41,7 @@ ErrCode ReminderSwingDecisionCenter::RegisterSwingCallback(const sptr lock(swingMutex_); + lock_guard lock(swingMutex_); if (swingCallback_ == nullptr || swingCallback_->AsObject() == nullptr) { ANS_LOGE("invalid proxy state"); return; @@ -58,6 +63,145 @@ void ReminderSwingDecisionCenter::ResetSwingCallbackProxy() swingCallback_->AsObject()->RemoveDeathRecipient(swingRecipient_); } +void ReminderSwingDecisionCenter::GetCcmSwingRemind() +{ + nlohmann::json root; + string swingJsonPoint = "/"; + swingJsonPoint.append(NotificationConfigParse::NOTIFICATION_SERVICE); + swingJsonPoint.append("/"); + swingJsonPoint.append(SWING_FILTER); + swingJsonPoint.append("/"); + swingJsonPoint.append(AFFTECED_BY); + isSupportSwingSmartRemind_ = false; + if (!NotificationConfigParse::GetInstance()->GetConfigJson(swingJsonPoint, root)) { + ANS_LOGI("Failed to get swingJsonPoint CCM config file."); + return; + } + + nlohmann::json affects = root[NotificationConfigParse::NOTIFICATION_SERVICE][SWING_FILTER][AFFTECED_BY]; + + if (affects.is_null() || !affects.is_array() || affects.empty()) { + ANS_LOGI("GetCcmSwingRemind failed as invalid ccmSwingRemind json."); + return; + } + + for (auto &affect : affects) { + if (affect.is_null() || !affect.is_object()) { + continue; + } + if (affect[NotificationConfigParse::DEVICE_TYPE].is_null() || + !affect[NotificationConfigParse::DEVICE_TYPE].is_string() || + affect[NotificationConfigParse::STATUS].is_null() || + !affect[NotificationConfigParse::STATUS].is_string()) { + continue; + } + enableSwingDeviceType_ = affect[NotificationConfigParse::DEVICE_TYPE].get(); + enableSwingDeviceStatus_ = affect[NotificationConfigParse::STATUS].get(); + ANS_LOGI("deviceType: %{public}s status: %{public}s", enableSwingDeviceType_.c_str(), + enableSwingDeviceStatus_.c_str()); + isSupportSwingSmartRemind_ = true; + } + } +} + +string ReminderSwingDecisionCenter::GetSwingDeviceType() +{ + return enableSwingDeviceType_; +} + +void ReminderSwingDecisionCenter::UpdateCrossDeviceNotificationStatus(bool isEnable) +{ + isCrossDeviceNotificationEnable_ = isEnable; + ANS_LOGI("UpdateCrossDeviceNotificationStatus %{public}d", isEnable); + SwingExecuteDecision(false); +} + +void ReminderSwingDecisionCenter::OnSmartReminderStatusChanged() +{ + SwingExecuteDecision(false); +} + +void ReminderSwingDecisionCenter::SwingExecuteDecision(bool isScreenUnlockTrigger) +{ + if (!isSupportSwingSmartRemind_) { + ANS_LOGI("is not SupportSwingSmartRemind"); + return; + } + + if (!isCrossDeviceNotificationEnable_) { + ANS_LOGI("crossDeviceNotification disable"); + return; + } + + bool isSmartReminderEnable = false; + if (ERR_OK != NotificationPreferences::GetInstance().IsSmartReminderEnabled(enableSwingDeviceType_, + isSmartReminderEnable)) { + ANS_LOGI("IsSmartReminderEnable error"); + return; + } + if (!isSmartReminderEnable) { + ANS_LOGI("IsSmartReminderEnable false"); + return; + } + + if (!swingCallback_) { + ANS_LOGI("swingCallback_ is null"); + return; + } + + int triggerMode = isScreenUnlockTrigger ? 0 : 1; + bool isSwingCrossDeviceStatusStatified = IsStatifySwingCrossDeviceStatus(); + if (isScreenUnlock_ && isSwingCrossDeviceStatusStatified) { + if (!isSwingExecuting_) { + swingCallback_->OnUpdateStatus(true, triggerMode); + isSwingExecuting_ = true; + ANS_LOGI("swing OnUpdateStatus enable triggerMode %{public}d", triggerMode); + } else { + ANS_LOGE("SwingExecuteDecision error isSwingExecuting_ %{public}d", isSwingExecuting_); + } + } else { + if (isSwingExecuting_) { + swingCallback_->OnUpdateStatus(false, triggerMode); + isSwingExecuting_ = false; + ANS_LOGI("swing OnUpdateStatus disable triggerMode %{public}d", triggerMode); + } else { + ANS_LOGE("SwingExecuteDecision error isSwingExecuting_ %{public}d", isSwingExecuting_); + ANS_LOGE("isScreenUnlock_ %{public}d isSwingCrossDeviceStatusStatified %{public}d ", + isSwingExecuting_, isSwingCrossDeviceStatusStatified); + } + } +} + +bool ReminderSwingDecisionCenter::IsStatifySwingCrossDeviceStatus() +{ + uint32_t status = DistributedDeviceStatus::GetInstance().getDeviceStatus(enableSwingDeviceType_); + ANS_LOGI("IsStatifySwingCrossDeviceStatus status %{public}d, enableSwingDeviceStatus_ %{public}s", + status, enableSwingDeviceStatus_.c_str()); + bool isSatisfied = SmartReminderCenter::GetInstance()->CompareStatus(enableSwingDeviceStatus_, bitset<4>(status)); + ANS_LOGI("IsStatifySwingCrossDeviceStatus isSatisfied %{public}d", isSatisfied); + return isSatisfied; + //return true; +} + +void ReminderSwingDecisionCenter::OnUpdateDeviceStatus() +{ + SwingExecuteDecision(false); +} + +void ReminderSwingDecisionCenter::OnScreenLock() +{ + isScreenUnlock_ = false; + SwingExecuteDecision(true); + ANS_LOGI("OnScreenLock"); +} + +void ReminderSwingDecisionCenter::OnScreenUnlock() +{ + isScreenUnlock_ = true; + SwingExecuteDecision(true); + ANS_LOGI("OnScreenUnlock"); +} + void SwingCallbackRecipient::OnRemoteDied(const wptr &remote) { ANS_LOGI("Swing Callback died, remove the proxy object"); diff --git a/services/ans/src/system_event_observer.cpp b/services/ans/src/system_event_observer.cpp index 2cc27feedf3e416b13679ea0f48e2890875f5973..04a07b45434fc7988cb103f1412905b2e18c212c 100644 --- a/services/ans/src/system_event_observer.cpp +++ b/services/ans/src/system_event_observer.cpp @@ -32,6 +32,8 @@ SystemEventObserver::SystemEventObserver(const ISystemEvent &callbacks) : callba matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF); #endif + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED); @@ -119,6 +121,10 @@ void SystemEventObserver::InitEventList() &SystemEventObserver::OnBundleUpdateEventInner; memberFuncMap_[EventFwk::CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED] = &SystemEventObserver::OnBootSystemCompletedEventInner; + memberFuncMap_[EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED] = + &SystemEventObserver::OnScreenLock; + memberFuncMap_[EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED] = + &SystemEventObserver::OnScreenUnlock; } void SystemEventObserver::OnReceiveEventInner(const EventFwk::CommonEventData &data) @@ -164,5 +170,19 @@ void SystemEventObserver::OnBootSystemCompletedEventInner(const EventFwk::Common callbacks_.onBootSystemCompleted(); } } + +void SystemEventObserver::OnScreenLock(const EventFwk::CommonEventData &data) +{ + if (callbacks_.onScreenLock != nullptr) { + callbacks_.onScreenLock(); + } +} + +void SystemEventObserver::OnScreenUnlock(const EventFwk::CommonEventData &data) +{ + if (callbacks_.onScreenUnlock != nullptr) { + callbacks_.onScreenUnlock(); + } +} } // namespace Notification } // namespace OHOS