From 8f0daa2bd778bb0c6e7636bf37c5024482b58414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A1=91=E7=87=83?= Date: Mon, 15 Apr 2024 07:17:52 +0000 Subject: [PATCH] swingDecision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 桑燃 Change-Id: Ib027f418737d3d3d483a31a3cc8745f9bb2dd93e --- frameworks/ans/BUILD.gn | 4 + notification.gni | 1 + services/ans/BUILD.gn | 1 - .../include/advanced_notification_service.h | 14 ++ .../ans/include/distributed_device_status.h | 3 + services/ans/include/interface_system_event.h | 2 + .../include/notification_subscriber_manager.h | 1 + .../include/reminder_swing_decision_center.h | 27 +++- services/ans/include/smart_reminder_center.h | 3 +- services/ans/include/system_event_observer.h | 2 + .../advanced_notification_publish_service.cpp | 4 +- .../ans/src/advanced_notification_service.cpp | 2 + .../ans/src/advanced_notification_utils.cpp | 11 ++ .../src/notification_subscriber_manager.cpp | 23 +++ .../src/reminder_swing_decision_center.cpp | 152 +++++++++++++++++- services/ans/src/system_event_observer.cpp | 20 +++ 16 files changed, 259 insertions(+), 11 deletions(-) diff --git a/frameworks/ans/BUILD.gn b/frameworks/ans/BUILD.gn index 0ab517193..8d19a0a74 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 e9ac9895c..7b373c548 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 49a5d0da6..17aee2a04 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 0454b238c..3dfcfe98b 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 f54ab3d20..efb6a4340 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 71cf783da..34331980d 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 6973b65ed..b1ae7cc12 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 e397d07fb..23395e246 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 0b0e3b612..6073e6904 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 7be639803..bccd944e2 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 270a070b9..04ec32c42 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 074f0315f..ed0ce7c47 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 ffc540e1e..22b9b8030 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 5c972d382..512f8292d 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 ba353680b..e846cba30 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 2cc27feed..04a07b454 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 -- Gitee