diff --git a/frameworks/ans/IAnsManager.idl b/frameworks/ans/IAnsManager.idl index 3b12836df3f5ac4ea6d42a2f50ddf1649dc79221..48812d68095b3f0bf836dc6d943efc5ffc2edbf5 100644 --- a/frameworks/ans/IAnsManager.idl +++ b/frameworks/ans/IAnsManager.idl @@ -319,6 +319,12 @@ interface OHOS.Notification.IAnsManager { void SetTargetDeviceSwitch([in] String deviceType, [in] String deviceId, [in] boolean notificaitonEnable, [in] boolean liveViewEnable); + void SetCheckConfig([in] int response, [in] String requestId, [in] String key, [in] String value); + + void GetLiveViewConfig([in] String[] bundleList); + + void SetDefaultSlotForBundle([in] sptr bundleOption, [in] int slotTypeInt, [in] boolean enabled, [in] boolean isForceControl); + void SetHashCodeRule([in] unsigned int type); void GetMutilDeviceStatus([in] String deviceType, [in] unsigned int status, [out] String deviceId, [out] int userId); diff --git a/frameworks/ans/src/notification_helper.cpp b/frameworks/ans/src/notification_helper.cpp index e0f9664131b1635ada64f0b0c02bff1ee3846001..bcdcab6c6449a23b80d78973e50c96d1ef1967f7 100644 --- a/frameworks/ans/src/notification_helper.cpp +++ b/frameworks/ans/src/notification_helper.cpp @@ -771,5 +771,23 @@ ErrCode NotificationHelper::GetTargetDeviceBundleList(const std::string& deviceT return DelayedSingleton::GetInstance()->GetTargetDeviceBundleList(deviceType, deviceId, bundleList, labelList); } + +ErrCode NotificationHelper::SetDefaultSlotForBundle(const NotificationBundleOption& bundleOption, + const NotificationConstant::SlotType &slotType, bool enabled, bool isForceControl) +{ + return DelayedSingleton::GetInstance()->SetDefaultSlotForBundle(bundleOption, + slotType, enabled, isForceControl); +} + +ErrCode NotificationHelper::SetCheckConfig(int32_t response, const std::string& requestId, + const std::string& key, const std::string& value) +{ + return DelayedSingleton::GetInstance()->SetCheckConfig(response, requestId, key, value); +} + +ErrCode NotificationHelper::GetLiveViewConfig(const std::vector& bundleList) +{ + return DelayedSingleton::GetInstance()->GetLiveViewConfig(bundleList); +} } // namespace Notification } // namespace OHOS diff --git a/frameworks/ans/src/push_callback_stub.cpp b/frameworks/ans/src/push_callback_stub.cpp index c2fa3db03fe8b29c00fdc9226085d380a2b5e57f..7e52eaaddb78b308c884f2bfa18f8795699fef00 100644 --- a/frameworks/ans/src/push_callback_stub.cpp +++ b/frameworks/ans/src/push_callback_stub.cpp @@ -39,6 +39,7 @@ enum PushCheckErrCode : int32_t { SYSTEM_ERROR = 4, OPTIONAL_PARAMETER_INVALID = 5 }; +constexpr int32_t MAX_LIVEVIEW_CONFIG_SIZE = 60; ErrCode PushCallBackStub::ConvertPushCheckCodeToErrCode(int32_t pushCheckCode) { @@ -99,7 +100,23 @@ int PushCallBackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Messag } return NO_ERROR; } - + case static_cast(NotificationInterfaceCode::ON_CHECK_LIVEVIEW): { + std::string requestId = data.ReadString(); + auto vsize = data.ReadUint64(); + vsize = (vsize < MAX_LIVEVIEW_CONFIG_SIZE) ? vsize : MAX_LIVEVIEW_CONFIG_SIZE; + std::vector bundlesName; + for (uint64_t it = 0; it < vsize; ++it) { + std::string bundle = data.ReadString(); + bundlesName.emplace_back(bundle); + } + int32_t checkResult = this->OnCheckLiveView(requestId, bundlesName); + ANS_LOGI("Push check liveview: %{public}zu %{public}d.", bundlesName.size(), checkResult); + if (!reply.WriteInt32(checkResult)) { + ANS_LOGE("Failed to write reply "); + return ERR_INVALID_REPLY; + } + return NO_ERROR; + } default: { return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } @@ -144,6 +161,51 @@ int32_t PushCallBackProxy::OnCheckNotification( return result; } +int32_t PushCallBackProxy::OnCheckLiveView(const std::string& requestId, const std::vector& bundles) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(PushCallBackProxy::GetDescriptor())) { + ANS_LOGE("Write interface token failed."); + return ERROR_IPC_ERROR; + } + + if (!data.WriteString(requestId)) { + ANS_LOGE("Connect done element error."); + return ERROR_IPC_ERROR; + } + + if (!data.WriteUint64(bundles.size())) { + ANS_LOGE("Failed to write the size of bundles"); + return ERROR_IPC_ERROR; + } + + for (auto item : bundles) { + if (!data.WriteString(item)) { + ANS_LOGE("Failed to write bundle name"); + return ERROR_IPC_ERROR; + } + } + + auto remote = Remote(); + if (remote == nullptr) { + ANS_LOGE("null remote"); + return ERROR_IPC_ERROR; + } + + int error = remote->SendRequest(static_cast(NotificationInterfaceCode::ON_CHECK_LIVEVIEW), + data, reply, option); + if (error != NO_ERROR) { + ANS_LOGE("error: %{public}d", error); + return ERROR_IPC_ERROR; + } + + int result = reply.ReadInt32(); + return result; +} + void PushCallBackProxy::HandleEventControl( std::string eventControl, const std::shared_ptr &pushCallBackParam) { diff --git a/frameworks/core/common/include/ans_inner_errors.h b/frameworks/core/common/include/ans_inner_errors.h index 4f03ced902d13b9d40709369488b74a2aeb6fa68..73b138f556424265c549709c8c2bc8cc4194ffae 100644 --- a/frameworks/core/common/include/ans_inner_errors.h +++ b/frameworks/core/common/include/ans_inner_errors.h @@ -97,6 +97,7 @@ enum ErrorCode : uint32_t { ERR_ANS_REJECTED_WITH_DISABLE_NOTIFICATION, ERR_ANS_OPERATION_TIMEOUT, ERR_ANS_LOCAL_SUBSCRIBE_CHECK_FAILED, + ERR_ANS_BUNDLE_SLOT_EXIST, }; enum ReminderErrorCode : uint32_t { diff --git a/frameworks/core/include/ans_notification.h b/frameworks/core/include/ans_notification.h index 18037bbaa8bdaf4c35fb711aacfb7d0cafa74fd5..0f54553b2288ee5249d82c801e21970c6a3a55c8 100644 --- a/frameworks/core/include/ans_notification.h +++ b/frameworks/core/include/ans_notification.h @@ -1403,6 +1403,38 @@ public: */ ErrCode GetDistributedDevicelist(std::vector &deviceTypes); + /** + * Set whether the application slot is enabled. + * + * @param bundleOption Indicates the bundle name and uid of the application. + * @param slotType Indicates type of slot. + * @param enable the type of slot enabled. + * @param isForceControl Indicates whether the slot is affected by the notification switch. + * @return Returns get slot number by bundle result. + */ + ErrCode SetDefaultSlotForBundle(const NotificationBundleOption& bundleOption, + const NotificationConstant::SlotType &slotType, bool enabled, bool isForceControl); + + /** + * @brief Set check config. + * + * @param response Indicates the result of check. + * @param requestId Indicates the request. + * @param key Indicates live view config if the value is "APP_LIVEVIEW_CONFIG". + * @param value Indicates key-value pair of live view. + * @return Returns set result. + */ + ErrCode SetCheckConfig(int32_t response, const std::string& requestId, const std::string& key, + const std::string& value); + + /** + * @brief get live view config. + * + * @param bundleList Indicates bundle name. + * @return Returns set result. + */ + ErrCode GetLiveViewConfig(const std::vector& bundleList); + private: /** * @brief Gets Ans Manager proxy. diff --git a/frameworks/core/include/distributed_notification_service_ipc_interface_code.h b/frameworks/core/include/distributed_notification_service_ipc_interface_code.h index 1738c062cb69c5e410a8cf32299fb418ce5d8b22..3b9d9a59ef4cd2d0c655ec3c6ec6c5baf8245677 100644 --- a/frameworks/core/include/distributed_notification_service_ipc_interface_code.h +++ b/frameworks/core/include/distributed_notification_service_ipc_interface_code.h @@ -163,6 +163,7 @@ namespace Notification { REQUEST_ENABLE_NOTIFICATION_BY_BUNDLE, REPLY_DISTRIBUTE_OPERATION, GET_NOTIFICATION_SETTING, + ON_CHECK_LIVEVIEW, }; } } diff --git a/frameworks/core/src/ans_notification.cpp b/frameworks/core/src/ans_notification.cpp index a84f3e388be684b9c11c1d73ed1d8b68e40486f9..704f8734e61a35b6af51aac1bda88417cb34f280 100644 --- a/frameworks/core/src/ans_notification.cpp +++ b/frameworks/core/src/ans_notification.cpp @@ -2401,6 +2401,52 @@ ErrCode AnsNotification::AllowUseReminder(const std::string& bundleName, bool& i return proxy->AllowUseReminder(bundleName, isAllowUseReminder); } +ErrCode AnsNotification::SetDefaultSlotForBundle(const NotificationBundleOption& bundleOption, + const NotificationConstant::SlotType &slotType, bool enabled, bool isForceControl) +{ + NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); + if (bundleOption.GetBundleName().empty()) { + ANS_LOGE("Invalid bundle name."); + return ERR_ANS_INVALID_PARAM; + } + + sptr proxy = GetAnsManagerProxy(); + if (!proxy) { + ANS_LOGE("SetDefaultSlotForBundle fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + sptr bo(new (std::nothrow) NotificationBundleOption(bundleOption)); + if (bo == nullptr) { + ANS_LOGE("null bundleOption"); + return ERR_ANS_INVALID_PARAM; + } + return proxy->SetDefaultSlotForBundle(bo, slotType, enabled, isForceControl); +} + +ErrCode AnsNotification::SetCheckConfig(int32_t response, const std::string& requestId, + const std::string& key, const std::string& value) +{ + sptr proxy = GetAnsManagerProxy(); + if (!proxy) { + ANS_LOGE("Get ans manager proxy fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + return proxy->SetCheckConfig(response, requestId, key, value); +} + +ErrCode AnsNotification::GetLiveViewConfig(const std::vector& bundleList) +{ + sptr proxy = GetAnsManagerProxy(); + if (!proxy) { + ANS_LOGE("Get ans manager proxy fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + return proxy->GetLiveViewConfig(bundleList); +} + void AnsNotification::CreateSubscribeListener(const std::shared_ptr &subscriber, sptr &listener) { 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 a85dd39252caa3182ada2d91dd0ddeb302c8373c..0c58571e0595ae6f4cdac4f7d89589a617902fb5 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 @@ -763,6 +763,23 @@ public: { return ERR_ANS_INVALID_PARAM; } + + ErrCode SetCheckConfig(int32_t response, const std::string& requestId, const std::string& key, + const std::string& value) override + { + return ERR_ANS_INVALID_PARAM; + } + + ErrCode GetLiveViewConfig(const std::vector& bundleList) override + { + return ERR_ANS_INVALID_PARAM; + } + + ErrCode SetDefaultSlotForBundle(const sptr &bundleOption, + int32_t slotTypeInt, bool enabled, bool isForceControl) override + { + return ERR_ANS_INVALID_PARAM; + } }; class AnsNotificationBranchTest : public testing::Test { 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 d38fdd038db24c0f4d7fc98b7ffcc89d52d1a04b..8f0d53903abc8c18e1da117fe03d210113e58420 100644 --- a/frameworks/core/test/unittest/mock/mock_ans_manager_proxy.h +++ b/frameworks/core/test/unittest/mock/mock_ans_manager_proxy.h @@ -195,6 +195,9 @@ public: MOCK_METHOD4(GetMutilDeviceStatus, ErrCode(const std::string&, const uint32_t, std::string&, int32_t&)); MOCK_METHOD4(GetTargetDeviceBundleList, ErrCode(const std::string&, const std::string&, std::vector&, std::vector&)); + MOCK_METHOD4(SetCheckConfig, ErrCode(int32_t, const std::string&, const std::string&, const std::string&)); + MOCK_METHOD1(GetLiveViewConfig, ErrCode(const std::vector&)); + MOCK_METHOD4(SetDefaultSlotForBundle, ErrCode(const sptr &, int32_t, bool, bool)); #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED MOCK_METHOD1(RegisterSwingCallback, ErrCode(const sptr&)); #endif diff --git a/interfaces/inner_api/notification_helper.h b/interfaces/inner_api/notification_helper.h index 1aa83aa179d00f8efe9c5c84ce0772bbe8b758cb..9344b108c445723b809bda1036d3ab30feb8193e 100644 --- a/interfaces/inner_api/notification_helper.h +++ b/interfaces/inner_api/notification_helper.h @@ -1403,6 +1403,38 @@ public: * @return Returns ERR_OK on success, others on failure. */ static ErrCode GetDistributedDevicelist(std::vector &deviceTypes); + + /** + * Set the application default slot is enabled. + * + * @param bundleOption Indicates the bundle name and uid of the application. + * @param slotType Indicates type of slot. + * @param enabled the type of slot enabled. + * @param isForceControl Indicates whether the slot is affected by the notification switch. + * @return Returns get slot number by bundle result. + */ + static ErrCode SetDefaultSlotForBundle(const NotificationBundleOption& bundleOption, + const NotificationConstant::SlotType &slotType, bool enabled, bool isForceControl); + + /** + * @brief Set check config. + * + * @param response Indicates the result of check. + * @param requestId Indicates the request. + * @param key Indicates live view config if the value is "APP_LIVEVIEW_CONFIG". + * @param value Indicates key-value pair of live view. + * @return Returns set result. + */ + static ErrCode SetCheckConfig(int32_t response, const std::string& requestId, const std::string& key, + const std::string& value); + + /** + * @brief get live view config. + * + * @param bundleList Indicates bundle name. + * @return Returns set result. + */ + static ErrCode GetLiveViewConfig(const std::vector& bundleList); }; } // namespace Notification } // namespace OHOS diff --git a/interfaces/inner_api/push_callback_interface.h b/interfaces/inner_api/push_callback_interface.h index dc35d92fdf201c8bd07f5c69b487139cb03fd442..8b16a2258c234888159a92f8579a661a52c48d6f 100644 --- a/interfaces/inner_api/push_callback_interface.h +++ b/interfaces/inner_api/push_callback_interface.h @@ -36,6 +36,15 @@ public: */ virtual int32_t OnCheckNotification( const std::string ¬ificationData, const std::shared_ptr &pushCallBackParam) = 0; + + /** + * OnCheckLiveView + * + * @param requestId, Identifies a unique request. + * @param bundles, Identifies the bundle name. + * @return Returns push check result. + */ + virtual int32_t OnCheckLiveView(const std::string& requestId, const std::vector& bundles) = 0; }; } // namespace Notification } // namespace OHOS diff --git a/interfaces/inner_api/push_callback_proxy.h b/interfaces/inner_api/push_callback_proxy.h index 4f009a155d49355c783166d6c3a473bb4f1c3fa8..c66c28fcd96f7a430f2840f593c98962b80480e5 100644 --- a/interfaces/inner_api/push_callback_proxy.h +++ b/interfaces/inner_api/push_callback_proxy.h @@ -42,6 +42,8 @@ public: int32_t OnCheckNotification( const std::string ¬ificationData, const std::shared_ptr &pushCallBackParam) override; + int32_t OnCheckLiveView(const std::string& requestId, const std::vector& bundles) override; + void HandleEventControl(std::string eventControl, const std::shared_ptr &pushCallBackParam); private: static inline BrokerDelegator delegator_; diff --git a/interfaces/inner_api/push_callback_stub.h b/interfaces/inner_api/push_callback_stub.h index fcbc5c939ebc3ec10c4b95fe18088eff138bb97d..9fe46010dad446b0a0018863f047eaac731240dc 100644 --- a/interfaces/inner_api/push_callback_stub.h +++ b/interfaces/inner_api/push_callback_stub.h @@ -36,6 +36,7 @@ public: int OnRemoteRequest( uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + int OnCheckLiveView(const std::string& requestId, const std::vector& bundles) override { return 0; } ErrCode ConvertPushCheckCodeToErrCode(int32_t pushCheckCode); private: diff --git a/services/ans/BUILD.gn b/services/ans/BUILD.gn index 3917f307fd616a398482d41abfbef02b1883a073..c5389eda92d5a276b376e020fda7a27229dedca2 100644 --- a/services/ans/BUILD.gn +++ b/services/ans/BUILD.gn @@ -127,6 +127,7 @@ ohos_source_set("ans_service_sources") { "src/system_event_observer.cpp", "src/system_live_view/advanced_notification_system_live_view_service.cpp", "src/telephony_extension_wrapper.cpp", + "src/utils/notification_liveview_utils.cpp", "src/utils/notifictaion_load_utils.cpp", ] diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index 312bd712c2212a37b6d3dc84f87942471f0b2487..14b44a5cbdb239d15aa304255d3f3468a6d9f0cd 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -1439,6 +1439,13 @@ public: ErrCode AtomicServicePublish(const sptr &request); + ErrCode SetDefaultSlotForBundle(const sptr &bundleOption, + int32_t slotTypeInt, bool enabled, bool isForceControl) override; + + ErrCode SetCheckConfig(int32_t response, const std::string& requestId, const std::string& key, + const std::string& value) override; + + ErrCode GetLiveViewConfig(const std::vector& bundleList) override; protected: /** * @brief Query whether there is a agent relationship between the two apps. @@ -1450,6 +1457,7 @@ protected: bool IsAgentRelationship(const std::string &agentBundleName, const std::string &sourceBundleName); public: + void TriggerLiveViewSwitchCheck(int32_t userId); bool CheckApiCompatibility(const sptr &bundleOption); ErrCode SetDefaultNotificationEnabled( const sptr &bundleOption, bool enabled); @@ -1741,7 +1749,7 @@ private: ErrCode AddSlotThenPublishEvent( const sptr &slot, const sptr &bundle, - bool enabled, bool isForceControl); + bool enabled, bool isForceControl, int32_t authStatus = NotificationSlot::AuthorizedStatus::AUTHORIZED); ErrCode OnRecoverLiveView(const std::vector &keys); ErrCode CollaborateFilter(const sptr &request); void HandleUpdateLiveViewNotificationTimer(const int32_t uid, const bool isPaused); @@ -1774,6 +1782,10 @@ private: std::vector>& notifications, const int32_t removeReason); bool IsDistributedNotification(sptr request); bool IsEnableNotificationByKioskAppTrustList(const std::string &bundleName); + void InvockLiveViewSwitchCheck(const std::vector>& bundles, + int32_t userId, uint32_t index); + void InvokeCheckConfig(const std::string& requestId); + ErrCode HandlePushCheckFailed(const sptr &request, int32_t result); template bool WriteParcelableVector(const std::vector> &parcelableVector, MessageParcel &data) diff --git a/services/ans/include/bundle_manager_helper.h b/services/ans/include/bundle_manager_helper.h index 3f45cbba4c16c560931eb0ba5af3412ee5931be0..fcb727e22f3aeb39ca9ec150a25e6a89d1777617 100644 --- a/services/ans/include/bundle_manager_helper.h +++ b/services/ans/include/bundle_manager_helper.h @@ -175,6 +175,8 @@ public: ErrCode GetBundleResourceInfo(const std::string &bundleName, AppExecFwk::BundleResourceInfo &bundleResourceInfo, const int32_t appIndex); + ErrCode GetAllBundleInfo(std::map>& bundleOptions, + int32_t userId); private: void Connect(); void Disconnect(); diff --git a/services/ans/include/liveview_all_scenarios_extension_wrapper.h b/services/ans/include/liveview_all_scenarios_extension_wrapper.h index 8e9fddffe6bbc3b21519c6e296b52477e239a620..6e42f92d0378e706bdce3b3ff8d51a28d41098f8 100644 --- a/services/ans/include/liveview_all_scenarios_extension_wrapper.h +++ b/services/ans/include/liveview_all_scenarios_extension_wrapper.h @@ -33,8 +33,23 @@ public: typedef ErrCode (*UPDATE_LIVEVIEW_VOICE_CONTENT)(const sptr &request); ErrCode UpdateLiveviewVoiceContent(const sptr &request); + typedef ErrCode (*UPDATE_LIVEVIEW_CONFIG)(const std::string& config); + ErrCode UpdateLiveViewConfig(const std::string& config); + typedef ErrCode (*CHECK_LIVEVIEW_CONFIG)(const std::string& bundleName, const std::string& event, + int32_t userId, bool& enable); + ErrCode CheckLiveViewConfig(const std::string& bundleName, const std::string& event, + int32_t userId, bool& enable); + typedef ErrCode (*GET_LIVEVIEW_CONFIG_VERSION)(int32_t& version); + ErrCode GetLiveViewConfigVersion(int32_t& version); + typedef ErrCode (*NOTIFY_LIVEVIEW_EVENT)(const std::string& event, + const sptr& bundleInfo); + ErrCode NotifyLiveViewEvent(const std::string& event, const sptr& bundleInfo); private: void* ExtensionHandle_ = nullptr; + CHECK_LIVEVIEW_CONFIG checkLiveViewConfig_ = nullptr; + NOTIFY_LIVEVIEW_EVENT notifyLiveViewEvent_ = nullptr; + UPDATE_LIVEVIEW_CONFIG updateLiveViewConfig_ = nullptr; + GET_LIVEVIEW_CONFIG_VERSION getLiveViewConfigVersion_ = nullptr; UPDATE_LIVEVIEW_REMINDER_FLAGS updateLiveviewReminderFlags_ = nullptr; UPDATE_LIVEVIEW_VOICE_CONTENT updateLiveviewVoiceContent_ = nullptr; }; @@ -42,4 +57,4 @@ private: #define LIVEVIEW_ALL_SCENARIOS_EXTENTION_WRAPPER \ ::OHOS::DelayedSingleton::GetInstance() } // namespace OHOS::Notification -#endif // BASE_NOTIFICATION_ANS_SERVICES_LIVEVIEW_ALL_SCENARIOS_EXTENSION_WRAPPER_H \ No newline at end of file +#endif // BASE_NOTIFICATION_ANS_SERVICES_LIVEVIEW_ALL_SCENARIOS_EXTENSION_WRAPPER_H diff --git a/services/ans/include/notification_analytics_util.h b/services/ans/include/notification_analytics_util.h index abbeb5a4a4bc8365faf94831a2dd589469bce281..8801f9a78863a6e668ca96a113460e51073d31d0 100644 --- a/services/ans/include/notification_analytics_util.h +++ b/services/ans/include/notification_analytics_util.h @@ -234,6 +234,8 @@ public: static bool ReportAllBundlesSlotEnabled(); static void ReportLiveViewNumber(const sptr& request, const int32_t reportType); + + static void ReportTriggerLiveView(const std::vector& bundles); private: static void ReportNotificationEvent(const sptr& request, EventFwk::Want want, int32_t eventCode, const std::string& reason); diff --git a/services/ans/include/notification_clone_bundle_info.h b/services/ans/include/notification_clone_bundle_info.h index 98825eb15c9e3e30b0a93441dfd293293dfb680c..a400e46f54b2098971a186da02a069caf7d00cb3 100644 --- a/services/ans/include/notification_clone_bundle_info.h +++ b/services/ans/include/notification_clone_bundle_info.h @@ -31,9 +31,11 @@ public: class SlotInfo { public: std::string Dump() const; + int32_t GetAuthStaus() const; NotificationConstant::SlotType slotType_; bool enable_; bool isForceControl_; + bool authorizedStatus_ = true; }; NotificationCloneBundleInfo() = default; ~NotificationCloneBundleInfo() = default; diff --git a/services/ans/include/notification_preferences.h b/services/ans/include/notification_preferences.h index c9ba6ca2e5139619f584a72ebd845cbb66ce4a34..b7b6b0c175a84c8b8b15865acb53e1a38029c58c 100644 --- a/services/ans/include/notification_preferences.h +++ b/services/ans/include/notification_preferences.h @@ -568,6 +568,12 @@ public: */ ErrCode GetDistributedDevicelist(std::vector &deviceTypes); + ErrCode GetLiveViewConfigVersion(int32_t &version); + bool SetLiveViewConfigVersion(const int32_t& version); + ErrCode GetLiveViewRebuildFlag(std::string& flag, int32_t userId); + bool SetLiveViewRebuildFlag(int32_t userId); + ErrCode InitBundlesInfo(int32_t userId, std::unordered_map& bundlesMap); + void GetAllLiveViewBundles(std::vector>& bundleOption); private: bool GetBundleInfo(NotificationPreferencesInfo &preferencesInfo, const sptr &bundleOption, NotificationPreferencesInfo::BundleInfo &info) const; diff --git a/services/ans/include/notification_preferences_database.h b/services/ans/include/notification_preferences_database.h index e6cb4e000aec2dc740c2cc4ade84d413cc05d083..fe92e48d8c4fd10123f325026c10835cd793b304 100644 --- a/services/ans/include/notification_preferences_database.h +++ b/services/ans/include/notification_preferences_database.h @@ -426,6 +426,10 @@ public: */ bool GetDistributedDevicelist(std::string &deviceTypes); + bool GetLiveViewConfigVersion(int32_t& version); + bool SetLiveViewConfigVersion(const int32_t& version); + bool GetLiveViewRebuildFlag(std::string& flag, int32_t userId); + bool SetLiveViewRebuildFlag(int32_t userId); private: bool CheckRdbStore(); diff --git a/services/ans/include/utils/notification_liveview_utils.h b/services/ans/include/utils/notification_liveview_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..6e0fc30a560488b20b0e246e21d563b68193e027 --- /dev/null +++ b/services/ans/include/utils/notification_liveview_utils.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 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 NOTIFICATION_LIVEVIEW_UTILS_H +#define NOTIFICATION_LIVEVIEW_UTILS_H + +#include +#include +#include +#include "ffrt.h" +#include "notification_request.h" +#include "notification_bundle_option.h" + +namespace OHOS { +namespace Notification { + +struct LiveViewCheckParam { +public: + LiveViewCheckParam() = default; + LiveViewCheckParam(const std::vector bundles) + { + bundlesName = bundles; + } + int32_t retryTime = 0; + std::vector bundlesName; +}; + + +class NotificationLiveViewUtils { +public: + static NotificationLiveViewUtils& GetInstance(); + + std::string AddLiveViewCheckData(std::shared_ptr& param); + void EraseLiveViewCheckData(const std::string& requestId); + bool GetLiveViewCheckData(const std::string& requestId, std::shared_ptr& data); + bool CheckLiveViewConfigByBundle(const std::string& bundleName, const std::string& event); + bool CheckLiveViewForBundle(const sptr& request); + + bool CheckLiveViewVersion(); + void NotifyLiveViewEvent(const std::string& event); + void NotifyLiveViewEvent(const std::string& event, const sptr& bundleInfo); + bool CheckLiveViewRebuild(int32_t userId); + void SetLiveViewRebuild(int32_t userId, int32_t data); + + static const int32_t ERASE_FLAG_INIT = 0; + static const int32_t ERASE_FLAG_RUNNING = 1; + static const int32_t ERASE_FLAG_FINISHED = 2; + static constexpr char ALL_EVENT[] = "ALL"; +private: + NotificationLiveViewUtils() = default; + ~NotificationLiveViewUtils() = default; + + ffrt::mutex eraseMutex; + std::map eraseFlag; + + ffrt::mutex dataMutex; + std::map> checkData; +}; + +} +} +#endif // NOTIFICATION_LIVEVIEW_UTILS_H diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 9a7625dd78ac4e14226b4c4a9b1ed11e84c4fd91..07c0aaefd00b8227d32bb74420247adefb9c33d5 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -83,6 +83,7 @@ #include "liveview_all_scenarios_extension_wrapper.h" #include "notification_operation_service.h" #include "string_wrapper.h" +#include "notification_liveview_utils.h" namespace OHOS { namespace Notification { @@ -102,6 +103,7 @@ constexpr int32_t TYPE_CODE_VOIP = 0; constexpr int32_t CONTROL_BY_DO_NOT_DISTURB_MODE = 1 << 14; constexpr int32_t CONTROL_BY_INTELLIGENT_EXPERIENCE = 1 << 31; constexpr int32_t FIRST_USERID = 0; +constexpr int32_t PUSH_CHECK_WEAK_NETWORK = 7788; const std::string DO_NOT_DISTURB_MODE = "1"; const std::string INTELLIGENT_EXPERIENCE = "1"; @@ -1791,6 +1793,26 @@ void AdvancedNotificationService::CreatePushCheckJson( } } +ErrCode AdvancedNotificationService::HandlePushCheckFailed(const sptr &request, int32_t result) +{ + HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_2, EventBranchId::BRANCH_5) + .ErrorCode(result).Message("Push OnCheckNotification failed."); + if (AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER) && + AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_AGENT_CONTROLLER)) { + if (!request->IsAtomicServiceNotification()) { + NotificationAnalyticsUtil::ReportTipsEvent(request, message); + } + return ERR_OK; + } + if (result == PUSH_CHECK_WEAK_NETWORK) { + if (NotificationLiveViewUtils::GetInstance().CheckLiveViewForBundle(request)) { + return ERR_OK; + } + } + NotificationAnalyticsUtil::ReportPublishFailedEvent(request, message); + return result; +} + ErrCode AdvancedNotificationService::PushCheck(const sptr &request) { ANS_LOGD("start."); @@ -1823,18 +1845,10 @@ ErrCode AdvancedNotificationService::PushCheck(const sptr & } ErrCode result = pushCallBack->OnCheckNotification(jsonObject.dump(), pushCallBackParam); if (result != ERR_OK) { - HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_2, EventBranchId::BRANCH_5) - .ErrorCode(result).Message("Push OnCheckNotification failed."); - if (AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER) && - AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_AGENT_CONTROLLER)) { - if (!request->IsAtomicServiceNotification()) { - NotificationAnalyticsUtil::ReportTipsEvent(request, message); - } - result = ERR_OK; - } else { - NotificationAnalyticsUtil::ReportPublishFailedEvent(request, message); + if (HandlePushCheckFailed(request, result) != ERR_OK) { return result; } + result = ERR_OK; } if (pushCallBackParam != nullptr && !pushCallBackParam->eventControl.empty() && extroInfo != nullptr) { extroInfo->SetParam("eventControl", AAFwk::String::Box(pushCallBackParam->eventControl)); diff --git a/services/ans/src/advanced_notification_slot_service.cpp b/services/ans/src/advanced_notification_slot_service.cpp index 04c8033daac89eeb83c9a01c987f0fca30d74434..03b41b6eb2b915e240d586d2b0234d712a469131 100644 --- a/services/ans/src/advanced_notification_slot_service.cpp +++ b/services/ans/src/advanced_notification_slot_service.cpp @@ -33,6 +33,8 @@ #include "smart_reminder_center.h" #endif +#include "notification_liveview_utils.h" +#include "os_account_manager_helper.h" #include "advanced_notification_inline.h" #include "notification_config_parse.h" #include "notification_extension_wrapper.h" @@ -45,7 +47,17 @@ namespace { constexpr char KEY_NAME[] = "AGGREGATE_CONFIG"; constexpr char CTRL_LIST_KEY_NAME[] = "NOTIFICATION_CTL_LIST_PKG"; constexpr char CALL_UI_BUNDLE[] = "com.ohos.callui"; + constexpr char LIVEVIEW_CONFIG_KEY[] = "APP_LIVEVIEW_CONFIG"; constexpr uint32_t NOTIFICATION_SETTING_FLAG_BASE = 0x11; + constexpr int32_t MAX_LIVEVIEW_CONFIG_SIZE = 60; + constexpr int32_t MAX_CHECK_RETRY_TIME = 3; + constexpr int32_t PUSH_CHECK_ERR_DEVICE = 6; + constexpr int32_t PUSH_CHECK_ERR_EXPIRED = 10; + constexpr int32_t PUSH_CHECK_ERR_AUTH = 11; + constexpr int32_t MAX_CHECK_NUM = 20; + constexpr uint64_t DELAY_TIME_CHECK_LIVEVIEW = 10 * 1000 * 1000; + constexpr uint64_t DELAY_TIME_TRIGGER_LIVEVIEW = 10 * 60 * 1000 * 1000; + constexpr uint64_t INTERVAL_CHECK_LIVEVIEW = 1000 * 1000; const std::set unAffectDevices = { NotificationConstant::LITEWEARABLE_DEVICE_TYPE, NotificationConstant::WEARABLE_DEVICE_TYPE @@ -870,7 +882,7 @@ ErrCode AdvancedNotificationService::GetSlotNumAsBundle( ErrCode AdvancedNotificationService::AddSlotThenPublishEvent( const sptr &slot, const sptr &bundle, - bool enabled, bool isForceControl) + bool enabled, bool isForceControl, int32_t authStatus) { bool allowed = false; NotificationConstant::SWITCH_STATE state = NotificationConstant::SWITCH_STATE::SYSTEM_DEFAULT_OFF; @@ -887,7 +899,7 @@ ErrCode AdvancedNotificationService::AddSlotThenPublishEvent( slot->SetEnable(enabled); slot->SetForceControl(isForceControl); - slot->SetAuthorizedStatus(NotificationSlot::AuthorizedStatus::AUTHORIZED); + slot->SetAuthorizedStatus(authStatus); std::vector> slots; slots.push_back(slot); result = NotificationPreferences::GetInstance()->AddNotificationSlots(bundle, slots); @@ -1019,6 +1031,289 @@ ErrCode AdvancedNotificationService::GetEnabledForBundleSlot( return result; } +ErrCode AdvancedNotificationService::SetDefaultSlotForBundle(const sptr &bundleOption, + int32_t slotTypeInt, bool enabled, bool isForceControl) +{ + NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION); + NotificationConstant::SlotType slotType = static_cast(slotTypeInt); + ANS_LOGD("slotType: %{public}d, enabled: %{public}d, isForceControl: %{public}d", + slotType, enabled, isForceControl); + ErrCode result = CheckCommonParams(); + if (result != ERR_OK) { + return result; + } + + if (bundleOption == nullptr || bundleOption->GetBundleName().empty() || bundleOption->GetUid() <= 0) { + return ERR_ANS_INVALID_BUNDLE; + } + + HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_5, EventBranchId::BRANCH_5); + message.Message(bundleOption->GetBundleName() + "_" +std::to_string(bundleOption->GetUid()) + + " slotType: " + std::to_string(static_cast(slotType)) + + " enabled: " +std::to_string(enabled) + "isForceControl" + std::to_string(isForceControl)); + ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { + sptr slot; + result = NotificationPreferences::GetInstance()->GetNotificationSlot(bundleOption, slotType, slot); + if (result == ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST || + result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) { + slot = new (std::nothrow) NotificationSlot(slotType); + if (slot == nullptr) { + ANS_LOGE("Failed to create NotificationSlot ptr."); + result = ERR_ANS_NO_MEMORY; + return; + } + GenerateSlotReminderMode(slot, bundleOption); + result = AddSlotThenPublishEvent(slot, bundleOption, enabled, isForceControl, + NotificationSlot::AuthorizedStatus::NOT_AUTHORIZED); + return; + } + })); + notificationSvrQueue_->wait(handler); + + SendEnableNotificationSlotHiSysEvent(bundleOption, slotType, enabled, result); + message.ErrorCode(result); + NotificationAnalyticsUtil::ReportModifyEvent(message); + ANS_LOGI("%{public}s_%{public}d, SetDefaultSlotForBundle successful.", + bundleOption->GetBundleName().c_str(), bundleOption->GetUid()); + return result; +} + + +void AdvancedNotificationService::InvokeCheckConfig(const std::string& requestId) +{ + std::shared_ptr checkParam = nullptr; + if (!NotificationLiveViewUtils::GetInstance().GetLiveViewCheckData(requestId, checkParam)) { + ANS_LOGW("Unknow request %{public}s.", requestId.c_str()); + return; + } + if (checkParam == nullptr) { + ANS_LOGW("Invalid data request %{public}s.", requestId.c_str()); + return; + } + + sptr pushCallBack = nullptr; + { + std::lock_guard lock(pushMutex_); + if (pushCallBacks_.find(NotificationConstant::SlotType::LIVE_VIEW) == pushCallBacks_.end()) { + ANS_LOGW("No push check function."); + NotificationLiveViewUtils::GetInstance().EraseLiveViewCheckData(requestId); + return; + } + pushCallBack = pushCallBacks_[NotificationConstant::SlotType::LIVE_VIEW]; + } + if (pushCallBack == nullptr) { + ANS_LOGW("Invalid push check function."); + NotificationLiveViewUtils::GetInstance().EraseLiveViewCheckData(requestId); + return; + } + + int32_t res = pushCallBack->OnCheckLiveView(requestId, checkParam->bundlesName); + if (res != ERR_OK) { + ANS_LOGW("Push check failed %{public}d %{public}zu.", res, checkParam->bundlesName.size()); + NotificationLiveViewUtils::GetInstance().EraseLiveViewCheckData(requestId); + } +} + +void AdvancedNotificationService::InvockLiveViewSwitchCheck( + const std::vector>& bundles, int32_t userId, uint32_t index) +{ + ANS_LOGI("Invock switch start %{public}zu %{public}u %{public}d.", bundles.size(), index, userId); + int count = 0; + std::vector handleBundles; + for (; index < bundles.size() && count < MAX_CHECK_NUM; index++) { + count++; + if (DelayedSingleton::GetInstance()->IsLiveViewEnabled( + bundles[index]->GetBundleName())) { + continue; + } + + if (NotificationLiveViewUtils::GetInstance().CheckLiveViewConfigByBundle( + bundles[index]->GetBundleName(), NotificationLiveViewUtils::ALL_EVENT)) { + continue; + } + + sptr slot; + if (NotificationPreferences::GetInstance()->GetNotificationSlot(bundles[index], + NotificationConstant::SlotType::LIVE_VIEW, slot) != ERR_OK) { + continue; + } + + NotificationPreferences::GetInstance()->RemoveNotificationSlot(bundles[index], + NotificationConstant::SlotType::LIVE_VIEW); + handleBundles.push_back(bundles[index]->GetBundleName()); + } + + ANS_LOGI("Invock switch %{public}zu %{public}u %{public}zu.", bundles.size(), index, handleBundles.size()); + if (!handleBundles.empty()) { + NotificationAnalyticsUtil::ReportTriggerLiveView(handleBundles); + } + + if (index >= bundles.size()) { + NotificationLiveViewUtils::GetInstance().SetLiveViewRebuild(userId, + NotificationLiveViewUtils::ERASE_FLAG_FINISHED); + return; + } + + if (notificationSvrQueue_ == nullptr) { + ANS_LOGE("Serial queue is invalid."); + NotificationLiveViewUtils::GetInstance().SetLiveViewRebuild(userId, + NotificationLiveViewUtils::ERASE_FLAG_INIT); + return; + } + + notificationSvrQueue_->submit_h(std::bind([&, bundles, userId, index]() { + InvockLiveViewSwitchCheck(bundles, userId, index); + }), + ffrt::task_attr().delay(INTERVAL_CHECK_LIVEVIEW).name("doTriggerLiveView")); +} + +void AdvancedNotificationService::TriggerLiveViewSwitchCheck(int32_t userId) +{ + if (notificationSvrQueue_ == nullptr) { + ANS_LOGE("Serial queue is invalid."); + return; + } + + if (!NotificationLiveViewUtils::GetInstance().CheckLiveViewRebuild(userId)) { + return; + } + + ANS_LOGE("Trigger live view start."); + notificationSvrQueue_->submit_h(std::bind([&, userId]() { + std::map> bundleOptions; + if (BundleManagerHelper::GetInstance()->GetAllBundleInfo(bundleOptions, userId) != ERR_OK) { + NotificationLiveViewUtils::GetInstance().SetLiveViewRebuild(userId, + NotificationLiveViewUtils::ERASE_FLAG_INIT); + NotificationLiveViewUtils::GetInstance().SetLiveViewRebuild(userId, + NotificationLiveViewUtils::ERASE_FLAG_INIT); + return; + } + std::vector> checkBundles; + std::unordered_map bundlesMap; + if (NotificationPreferences::GetInstance()->InitBundlesInfo(userId, bundlesMap) != ERR_OK) { + NotificationLiveViewUtils::GetInstance().SetLiveViewRebuild(userId, + NotificationLiveViewUtils::ERASE_FLAG_INIT); + return; + } + + for (auto item : bundlesMap) { + if (bundleOptions.count(item.second)) { + checkBundles.push_back(bundleOptions[item.second]); + } + } + ANS_LOGI("Get data %{public}zu %{public}zu %{public}zu.", bundleOptions.size(), checkBundles.size(), + bundlesMap.size()); + InvockLiveViewSwitchCheck(checkBundles, userId, 0); + }), + ffrt::task_attr().name("triggerLiveView").delay(DELAY_TIME_TRIGGER_LIVEVIEW)); +} + +ErrCode AdvancedNotificationService::SetCheckConfig(int32_t response, const std::string& requestId, + const std::string& key, const std::string& value) +{ + if (key != LIVEVIEW_CONFIG_KEY) { + ANS_LOGE("Invalid key %{public}s.", key.c_str()); + return ERR_ANS_INVALID_PARAM; + } + + if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_AGENT_CONTROLLER)) { + ANS_LOGE("Permission denied."); + return ERR_ANS_PERMISSION_DENIED; + } + + if (notificationSvrQueue_ == nullptr) { + ANS_LOGE("Serial queue is invalid."); + return ERR_ANS_INVALID_PARAM; + } + + notificationSvrQueue_->submit_h(std::bind([&]() { + if (response == ERR_OK) { + LIVEVIEW_ALL_SCENARIOS_EXTENTION_WRAPPER->UpdateLiveViewConfig(value); + return; + } + + ANS_LOGW("Push request failed %{public}s %{public}d.", requestId.c_str(), response); + if (response == PUSH_CHECK_ERR_DEVICE || response == PUSH_CHECK_ERR_EXPIRED || + response == PUSH_CHECK_ERR_AUTH) { + NotificationLiveViewUtils::GetInstance().EraseLiveViewCheckData(requestId); + return; + } + + std::shared_ptr checkParam = nullptr; + if (!NotificationLiveViewUtils::GetInstance().GetLiveViewCheckData(requestId, checkParam)) { + ANS_LOGE("Unknow request %{public}s.", requestId.c_str()); + return; + } + if (checkParam == nullptr) { + ANS_LOGE("Invalid data request %{public}s.", requestId.c_str()); + return; + } + + checkParam->retryTime++; + if (checkParam->retryTime >= MAX_CHECK_RETRY_TIME) { + NotificationLiveViewUtils::GetInstance().EraseLiveViewCheckData(requestId); + ANS_LOGE("Check failed request %{public}s.", requestId.c_str()); + return; + } + + if (notificationSvrQueue_ == nullptr) { + ANS_LOGE("Check handler is null."); + return; + } + notificationSvrQueue_->submit_h([&, requestId]() { InvokeCheckConfig(requestId); }, + ffrt::task_attr().name("checkLiveView").delay(DELAY_TIME_CHECK_LIVEVIEW)); + })); + + return ERR_OK; +} + +ErrCode AdvancedNotificationService::GetLiveViewConfig(const std::vector& bundleList) +{ + if (bundleList.empty() || bundleList.size() > MAX_LIVEVIEW_CONFIG_SIZE) { + ANS_LOGE("Invalid param %{public}zu.", bundleList.size()); + return ERR_ANS_INVALID_PARAM; + } + + if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) { + ANS_LOGE("Permission denied."); + return ERR_ANS_PERMISSION_DENIED; + } + + if (notificationSvrQueue_ == nullptr) { + ANS_LOGE("Serial queue is invalid."); + return ERR_ANS_INVALID_PARAM; + } + + int32_t result = ERR_OK; + ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { + sptr pushCallBack = nullptr; + { + std::lock_guard lock(pushMutex_); + if (pushCallBacks_.find(NotificationConstant::SlotType::LIVE_VIEW) == pushCallBacks_.end()) { + ANS_LOGE("No push check."); + result = ERR_ANS_PUSH_CHECK_UNREGISTERED; + return; + } + pushCallBack = pushCallBacks_[NotificationConstant::SlotType::LIVE_VIEW]; + } + if (pushCallBack == nullptr) { + ANS_LOGE("Invalid push check function."); + result = ERR_ANS_PUSH_CHECK_UNREGISTERED; + return; + } + auto param = std::make_shared(bundleList); + auto requestId = NotificationLiveViewUtils::GetInstance().AddLiveViewCheckData(param); + int32_t res = pushCallBack->OnCheckLiveView(requestId, bundleList); + if (res != ERR_OK) { + result = ERR_ANS_PUSH_CHECK_FAILED; + ANS_LOGE("Push check failed %{public}d %{public}zu.", res, bundleList.size()); + NotificationLiveViewUtils::GetInstance().EraseLiveViewCheckData(requestId); + } + })); + notificationSvrQueue_->wait(handler); + return result; +} + ErrCode AdvancedNotificationService::GetAllLiveViewEnabledBundles( std::vector &bundleOption) { diff --git a/services/ans/src/bundle_manager_helper.cpp b/services/ans/src/bundle_manager_helper.cpp index 02b697c7356e67357ac8c36a8da5a662c646ee99..c2fa1a38e7ba6878ddacd32af1c6bb2d68bb9c71 100644 --- a/services/ans/src/bundle_manager_helper.cpp +++ b/services/ans/src/bundle_manager_helper.cpp @@ -27,6 +27,8 @@ namespace OHOS { namespace Notification { +constexpr int32_t APP_TYPE_ONE = 1; +constexpr int32_t APP_TYPE_TWO = 2; BundleManagerHelper::BundleManagerHelper() { deathRecipient_ = new (std::nothrow) @@ -79,6 +81,51 @@ bool BundleManagerHelper::IsSystemApp(int32_t uid) return isSystemApp; } +ErrCode BundleManagerHelper::GetAllBundleInfo(std::map>& bundleOptions, + int32_t userId) +{ + std::vector bundleInfos; + { + std::lock_guard lock(connectionMutex_); + Connect(); + if (bundleMgr_ == nullptr) { + ANS_LOGE("GetBundleInfo bundle proxy failed."); + return -1; + } + + int32_t flags = static_cast(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION); + std::string identity = IPCSkeleton::ResetCallingIdentity(); + ErrCode result = bundleMgr_->GetBundleInfosV9(flags, bundleInfos, userId); + IPCSkeleton::SetCallingIdentity(identity); + if (result != ERR_OK) { + ANS_LOGE("Get installed bundle failed %{public}d.", result); + return result; + } + } + for (auto& bundle : bundleInfos) { + if (bundle.applicationInfo.bundleType != AppExecFwk::BundleType::APP || + bundle.applicationInfo.codePath == std::to_string(APP_TYPE_ONE) || + bundle.applicationInfo.codePath == std::to_string(APP_TYPE_TWO)) { + ANS_LOGD("Get not app %{public}s", bundle.applicationInfo.bundleName.c_str()); + continue; + } + + ANS_LOGI("Get bundle %{public}d %{public}s.", bundle.applicationInfo.uid, + bundle.applicationInfo.bundleName.c_str()); + sptr option = new (std::nothrow) NotificationBundleOption( + bundle.applicationInfo.bundleName, bundle.applicationInfo.uid); + if (option == nullptr) { + ANS_LOGE("Get bundle failed."); + continue; + } + std::string key = bundle.applicationInfo.bundleName + std::to_string(bundle.applicationInfo.uid); + bundleOptions[key] = option; + } + + ANS_LOGI("Get installed bundle size %{public}zu.", bundleOptions.size()); + return ERR_OK; +} + bool BundleManagerHelper::CheckApiCompatibility(const sptr &bundleOption) { if (bundleOption == nullptr) { diff --git a/services/ans/src/clone/notification_clone_bundle_info.cpp b/services/ans/src/clone/notification_clone_bundle_info.cpp index 5167ce3d611eb188673ffa2018576e7c80e0f152..a189acbbd8a0bc8a8844c6c8b506fa596202f790 100644 --- a/services/ans/src/clone/notification_clone_bundle_info.cpp +++ b/services/ans/src/clone/notification_clone_bundle_info.cpp @@ -16,6 +16,7 @@ #include "notification_clone_bundle_info.h" #include "ans_log_wrapper.h" +#include "notification_slot.h" namespace OHOS { namespace Notification { @@ -31,6 +32,7 @@ constexpr const char *BUNDLE_INFO_SLOT_TYPE = "slotType"; constexpr const char *BUNDLE_INFO_SLOT_ENABLE = "slotEnable"; constexpr const char *BUNDLE_INFO_SLOT_CONTROL = "slotControl"; constexpr const char *BUNDLE_INFO_SILENT_REMINDER = "enabledSilentReminder"; +constexpr const char *BUNDLE_INFO_SLOT_AUTHSTATUS = "slotAuthorized"; constexpr int32_t CONST_ENABLE_INT = 1; } void NotificationCloneBundleInfo::SetBundleName(const std::string &name) @@ -110,6 +112,7 @@ void NotificationCloneBundleInfo::AddSlotInfo(const SlotInfo &slotInfo) if (item.slotType_ == slotInfo.slotType_) { item.enable_ = slotInfo.enable_; item.isForceControl_ = slotInfo.isForceControl_; + item.authorizedStatus_ = slotInfo.authorizedStatus_; return; } } @@ -130,6 +133,7 @@ void NotificationCloneBundleInfo::ToJson(nlohmann::json &jsonObject) const jsonNode[BUNDLE_INFO_SLOT_TYPE] = static_cast(slotsInfo_[index].slotType_); jsonNode[BUNDLE_INFO_SLOT_ENABLE] = slotsInfo_[index].enable_ ? 1 : 0; jsonNode[BUNDLE_INFO_SLOT_CONTROL] = slotsInfo_[index].isForceControl_ ? 1 : 0; + jsonNode[BUNDLE_INFO_SLOT_AUTHSTATUS] = slotsInfo_[index].authorizedStatus_ ? 1 : 0; jsonNodes.emplace_back(jsonNode); } jsonObject[BUNDLE_INFO_SLOT_LIST] = jsonNodes; @@ -163,6 +167,10 @@ void NotificationCloneBundleInfo::SlotsFromJson(const nlohmann::json &jsonObject int32_t forceControl = slotJson.at(BUNDLE_INFO_SLOT_CONTROL).get(); slotInfo.isForceControl_ = (forceControl == CONST_ENABLE_INT); } + if (slotJson.contains(BUNDLE_INFO_SLOT_AUTHSTATUS) && slotJson[BUNDLE_INFO_SLOT_AUTHSTATUS].is_number()) { + int32_t auth = slotJson.at(BUNDLE_INFO_SLOT_AUTHSTATUS).get(); + slotInfo.authorizedStatus_ = (auth == CONST_ENABLE_INT); + } slotsInfo_.emplace_back(slotInfo); } } @@ -214,6 +222,12 @@ std::string NotificationCloneBundleInfo::SlotInfo::Dump() const + std::to_string(isForceControl_); } +int32_t NotificationCloneBundleInfo::SlotInfo::GetAuthStaus() const +{ + return authorizedStatus_ ? NotificationSlot::AuthorizedStatus::AUTHORIZED : + NotificationSlot::AuthorizedStatus::NOT_AUTHORIZED; +} + std::string NotificationCloneBundleInfo::Dump() const { std::string slotDump = "{"; diff --git a/services/ans/src/clone/notification_clone_manager.cpp b/services/ans/src/clone/notification_clone_manager.cpp index e961cf5c84243d12c5ef8b3eab012cdc6760d009..9084693168e5d089d66603a337d6bf03697c2fd1 100644 --- a/services/ans/src/clone/notification_clone_manager.cpp +++ b/services/ans/src/clone/notification_clone_manager.cpp @@ -30,6 +30,8 @@ #include "dh_notification_clone_bundle_service.h" #include "common_event_manager.h" #include "notification_analytics_util.h" +#include "notification_liveview_utils.h" +#include "common_event_support.h" namespace OHOS { namespace Notification { @@ -302,6 +304,12 @@ void NotificationCloneManager::OnRestoreStart(EventFwk::Want want) iter->second->OnRestoreStart(bundleName, appIndex, userId, uid); } } + + sptr bundleOption = new (std::nothrow) NotificationBundleOption(bundleName, uid); + if (bundleOption != nullptr) { + NotificationLiveViewUtils::GetInstance().NotifyLiveViewEvent( + EventFwk::CommonEventSupport::COMMON_EVENT_RESTORE_START, bundleOption); + } } void NotificationCloneManager::OnDhRestoreStart(const std::string bundleName, const int32_t uid) diff --git a/services/ans/src/common/notification_analytics_util.cpp b/services/ans/src/common/notification_analytics_util.cpp index 7c96b535828ec0417c421073b005122bb9f903a3..0f7f81d97a23355514e2f759d54ee7b79c9c5a30 100644 --- a/services/ans/src/common/notification_analytics_util.cpp +++ b/services/ans/src/common/notification_analytics_util.cpp @@ -44,6 +44,7 @@ constexpr const int32_t DELETE_ERROR_EVENT_CODE = 5; constexpr const int32_t MODIFY_ERROR_EVENT_CODE = 6; constexpr const int32_t ANS_CUSTOMIZE_CODE = 7; constexpr const int32_t BADGE_CHANGE_CODE = 201; +static int32_t LIVEVIEW_TRIGGER_SUB_CODE = 103; constexpr const int32_t DEFAULT_ERROR_EVENT_COUNT = 5; constexpr const int32_t DEFAULT_ERROR_EVENT_TIME = 60; @@ -1423,6 +1424,27 @@ void NotificationAnalyticsUtil::ExecuteCacheList() g_reportFlag = true; } +void NotificationAnalyticsUtil::ReportTriggerLiveView(const std::vector& bundles) +{ + nlohmann::json ansData; + ansData["subCode"] = std::to_string(LIVEVIEW_TRIGGER_SUB_CODE); + nlohmann::json dataArray = nlohmann::json::array(); + for (auto bundle : bundles) { + dataArray.push_back(bundle); + } + ansData["data"] = dataArray; + std::string message = ansData.dump(-1, ' ', false, + nlohmann::json::error_handler_t::replace); + + EventFwk::Want want; + want.SetAction(NOTIFICATION_EVENT_PUSH_AGENT); + want.SetParam("ansData", message); + ReportCache reportCache; + reportCache.want = want; + reportCache.eventCode = ANS_CUSTOMIZE_CODE; + ReportCommonEvent(reportCache); +} + void NotificationAnalyticsUtil::ReportCommonEvent(const ReportCache& reportCache) { EventFwk::CommonEventPublishInfo publishInfo; diff --git a/services/ans/src/liveview_all_scenarios_extension_wrapper.cpp b/services/ans/src/liveview_all_scenarios_extension_wrapper.cpp index 392d5335cf1af13116c7261ee633de4a9c503e4c..92f77eed8abac09282ecda46e8308eb28e50b5ea 100644 --- a/services/ans/src/liveview_all_scenarios_extension_wrapper.cpp +++ b/services/ans/src/liveview_all_scenarios_extension_wrapper.cpp @@ -53,6 +53,30 @@ void LiveviewAllScenariosExtensionWrapper::InitExtentionWrapper() return; } + updateLiveViewConfig_ = (UPDATE_LIVEVIEW_CONFIG)dlsym(ExtensionHandle_, "UpdateLiveViewConfig"); + if (updateLiveViewConfig_ == nullptr) { + ANS_LOGE("liveview update config %{public}s.", dlerror()); + return; + } + + checkLiveViewConfig_ = (CHECK_LIVEVIEW_CONFIG)dlsym(ExtensionHandle_, "CheckLiveViewConfig"); + if (checkLiveViewConfig_ == nullptr) { + ANS_LOGE("liveview check config %{public}s.", dlerror()); + return; + } + + getLiveViewConfigVersion_ = (GET_LIVEVIEW_CONFIG_VERSION)dlsym(ExtensionHandle_, + "GetLiveViewConfigVersion"); + if (getLiveViewConfigVersion_ == nullptr) { + ANS_LOGE("liveview get version %{public}s.", dlerror()); + return; + } + + notifyLiveViewEvent_ = (NOTIFY_LIVEVIEW_EVENT)dlsym(ExtensionHandle_, "NotifyLiveViewEvent"); + if (notifyLiveViewEvent_ == nullptr) { + ANS_LOGE("liveview notify config %{public}s.", dlerror()); + return; + } ANS_LOGI("liveview all scenarios extension wrapper init success"); } @@ -63,6 +87,10 @@ void LiveviewAllScenariosExtensionWrapper::CloseExtentionWrapper() ExtensionHandle_ = nullptr; updateLiveviewReminderFlags_ = nullptr; updateLiveviewVoiceContent_ = nullptr; + updateLiveViewConfig_ = nullptr; + checkLiveViewConfig_ = nullptr; + getLiveViewConfigVersion_ = nullptr; + notifyLiveViewEvent_ = nullptr; } ANS_LOGI("liveview all scenarios extension wrapper close success"); } @@ -84,4 +112,46 @@ ErrCode LiveviewAllScenariosExtensionWrapper::UpdateLiveviewVoiceContent(const s } return updateLiveviewVoiceContent_(request); } -} \ No newline at end of file + +ErrCode LiveviewAllScenariosExtensionWrapper::UpdateLiveViewConfig(const std::string& config) +{ + if (updateLiveViewConfig_ == nullptr) { + ANS_LOGE("Liveview update config failed"); + return -1; + } + + return updateLiveViewConfig_(config); +} + +ErrCode LiveviewAllScenariosExtensionWrapper::CheckLiveViewConfig(const std::string& bundleName, + const std::string& event, int32_t userId, bool& enable) +{ + if (checkLiveViewConfig_ == nullptr) { + ANS_LOGE("Liveview check config failed"); + return -1; + } + + return checkLiveViewConfig_(bundleName, event, userId, enable); +} + +ErrCode LiveviewAllScenariosExtensionWrapper::GetLiveViewConfigVersion(int32_t& version) +{ + if (getLiveViewConfigVersion_ == nullptr) { + ANS_LOGE("Liveview get version"); + return -1; + } + + return getLiveViewConfigVersion_(version); +} + +ErrCode LiveviewAllScenariosExtensionWrapper::NotifyLiveViewEvent(const std::string& event, + const sptr& bundleInfo) +{ + if (notifyLiveViewEvent_ == nullptr) { + ANS_LOGE("Liveview notify config failed"); + return -1; + } + + return notifyLiveViewEvent_(event, bundleInfo); +} +} diff --git a/services/ans/src/notification_preferences.cpp b/services/ans/src/notification_preferences.cpp index 1f6323f9c519c5ad88bc08eb01890fa0ae314379..38b662af96056ffed4442982c593c90c7a5ab4dc 100644 --- a/services/ans/src/notification_preferences.cpp +++ b/services/ans/src/notification_preferences.cpp @@ -725,7 +725,7 @@ void NotificationPreferences::UpdateCloneBundleInfo(int32_t userId, slotInfo->SetReminderMode(configSlotReminderMode & slotFlags); slotInfo->SetEnable(cloneSlot.enable_); slotInfo->SetForceControl(cloneSlot.isForceControl_); - slotInfo->SetAuthorizedStatus(NotificationSlot::AuthorizedStatus::AUTHORIZED); + slotInfo->SetAuthorizedStatus(cloneSlot.GetAuthStaus()); slots.push_back(slotInfo); bundleInfo.SetSlot(slotInfo); } @@ -755,6 +755,59 @@ void NotificationPreferences::GetAllCLoneBundlesInfo(int32_t userId, preferencesInfo_ = preferencesInfo; } +ErrCode NotificationPreferences::InitBundlesInfo(int32_t userId, + std::unordered_map& bundlesMap) +{ + std::lock_guard lock(preferenceMutex_); + return GetBatchKvsFromDb(KEY_BUNDLE_LABEL, bundlesMap, userId); +} + +ErrCode NotificationPreferences::GetLiveViewConfigVersion(int32_t& version) +{ + std::lock_guard lock(preferenceMutex_); + if (preferncesDB_ == nullptr) { + ANS_LOGE("the prefernces db is nullptr"); + return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED; + } + if (preferncesDB_->GetLiveViewConfigVersion(version)) { + return ERR_OK; + } + return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED; +} + +bool NotificationPreferences::SetLiveViewConfigVersion(const int32_t& version) +{ + std::lock_guard lock(preferenceMutex_); + if (preferncesDB_ == nullptr) { + ANS_LOGE("the prefernces db is nullptr"); + return false; + } + return preferncesDB_->SetLiveViewConfigVersion(version); +} + +ErrCode NotificationPreferences::GetLiveViewRebuildFlag(std::string& flag, int32_t userId) +{ + std::lock_guard lock(preferenceMutex_); + if (preferncesDB_ == nullptr) { + ANS_LOGE("the prefernces db is nullptr"); + return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED; + } + if (preferncesDB_->GetLiveViewRebuildFlag(flag, userId)) { + return ERR_OK; + } + return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED; +} + +bool NotificationPreferences::SetLiveViewRebuildFlag(int32_t userId) +{ + std::lock_guard lock(preferenceMutex_); + if (preferncesDB_ == nullptr) { + ANS_LOGE("the prefernces db is nullptr"); + return false; + } + return preferncesDB_->SetLiveViewRebuildFlag(userId); +} + void NotificationPreferences::GetDoNotDisturbProfileListByUserId(int32_t userId, std::vector> &profiles) { @@ -1110,7 +1163,7 @@ ErrCode NotificationPreferences::SetDistributedBundleOption( int32_t userId = -1; OsAccountManagerHelper::GetInstance().GetCurrentCallingUserId(userId); - + std::lock_guard lock(preferenceMutex_); bool storeDBResult = true; storeDBResult = preferncesDB_->PutDistributedBundleOption(bundles, deviceType, userId); @@ -1145,7 +1198,7 @@ ErrCode NotificationPreferences::SetSilentReminderEnabled(const sptrGetBundleName().empty()) { return ERR_ANS_INVALID_PARAM; } - + std::lock_guard lock(preferenceMutex_); NotificationPreferencesInfo::SilentReminderInfo silentReminderInfo; silentReminderInfo.bundleName = bundleOption->GetBundleName(); @@ -1160,14 +1213,14 @@ ErrCode NotificationPreferences::SetSilentReminderEnabled(const sptr &bundleOption, NotificationConstant::SWITCH_STATE &enableStatus) { if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) { return ERR_ANS_INVALID_PARAM; } - + std::lock_guard lock(preferenceMutex_); NotificationPreferencesInfo::SilentReminderInfo silentReminderInfo; if (preferencesInfo_.GetSilentReminderInfo(bundleOption, silentReminderInfo)) { diff --git a/services/ans/src/notification_preferences_database.cpp b/services/ans/src/notification_preferences_database.cpp index fd3a048f1d55225f9df477357297dcd24b9b5f43..e95c31de17e9f2ea332e6f5975b1560c028acab1 100644 --- a/services/ans/src/notification_preferences_database.cpp +++ b/services/ans/src/notification_preferences_database.cpp @@ -259,6 +259,8 @@ const static std::string KEY_SUBSCRIBER_EXISTED_FLAG = "existFlag"; const static int32_t DISTRIBUTED_KEY_NUM = 4; const static int32_t DISTRIBUTED_KEY_BUNDLE_INDEX = 1; const static int32_t DISTRIBUTED_KEY_UID_INDEX = 2; +static const char* const LIVE_VIEW_CCM_VERSION = "liveview_ccm_version"; +static const char* const LIVE_VIEW_REBUILD_FLAG = "liveview_rebuild_flag"; /** * Indicates that distributed notification switch. @@ -2336,7 +2338,71 @@ bool NotificationPreferencesDatabase::SetSilentReminderEnabled( result, key.c_str(), silentReminderInfo.enableStatus); return (result == NativeRdb::E_OK); } - + +bool NotificationPreferencesDatabase::GetLiveViewConfigVersion(int32_t& version) +{ + bool result = false; + GetValueFromDisturbeDB(LIVE_VIEW_CCM_VERSION, ZERO_USERID, [&](const int32_t &status, std::string &value) { + switch (status) { + case NativeRdb::E_EMPTY_VALUES_BUCKET: { + result = true; + break; + } + case NativeRdb::E_OK: { + result = true; + version = StringToInt(value); + break; + } + default: + ANS_LOGE("Get data from db failed %{public}d", status); + result = false; + break; + } + }); + return result; +} + +bool NotificationPreferencesDatabase::GetLiveViewRebuildFlag(std::string& flag, int32_t userId) +{ + bool result = false; + GetValueFromDisturbeDB(LIVE_VIEW_REBUILD_FLAG, userId, [&](const int32_t &status, std::string &value) { + switch (status) { + case NativeRdb::E_EMPTY_VALUES_BUCKET: { + result = true; + break; + } + case NativeRdb::E_OK: { + flag = value; + result = true; + break; + } + default: + ANS_LOGE("Get data from db failed %{public}d", status); + result = false; + break; + } + }); + return result; +} + +bool NotificationPreferencesDatabase::SetLiveViewConfigVersion(const int32_t& version) +{ + int32_t result = PutDataToDB(LIVE_VIEW_CCM_VERSION, version, ZERO_USERID); + ANS_LOGE("Set version failed %{public}d %{public}d", version, result); + return (result == NativeRdb::E_OK); +} + +bool NotificationPreferencesDatabase::SetLiveViewRebuildFlag(int32_t userId) +{ + if (!CheckRdbStore()) { + ANS_LOGE("null RdbStore"); + return false; + } + int32_t result = rdbDataManager_->InsertData(LIVE_VIEW_REBUILD_FLAG, KEY_REMOVED_FLAG, userId); + ANS_LOGI("Set flag failed %{public}d", result); + return (result == NativeRdb::E_OK); +} + bool NotificationPreferencesDatabase::IsSilentReminderEnabled( NotificationPreferencesInfo::SilentReminderInfo &silentReminderInfo) { diff --git a/services/ans/src/notification_preferences_info.cpp b/services/ans/src/notification_preferences_info.cpp index c9eafda9950fd76f550230ef5ba4e2ce329bfb2e..9eb121215945cb4ee078977fdf57df3bcca545db 100644 --- a/services/ans/src/notification_preferences_info.cpp +++ b/services/ans/src/notification_preferences_info.cpp @@ -389,6 +389,8 @@ void NotificationPreferencesInfo::GetAllCLoneBundlesInfo(const int32_t &userId, slotInfo.slotType_ = slot->GetType(); slotInfo.enable_ = slot->GetEnable(); slotInfo.isForceControl_ = slot->GetForceControl(); + slotInfo.authorizedStatus_ = + (slot->GetAuthorizedStatus() ==NotificationSlot::AuthorizedStatus::AUTHORIZED); cloneBundleInfo.AddSlotInfo(slotInfo); } auto silentReminderIter = silentReminderInfos_.find(bundleItem.second); diff --git a/services/ans/src/system_event_observer.cpp b/services/ans/src/system_event_observer.cpp index 29eee9c0177f07c8bc76e9f85a25e5c41d61dbd1..ed18c9486103494c9228914fe0823dbc6e52f8b9 100644 --- a/services/ans/src/system_event_observer.cpp +++ b/services/ans/src/system_event_observer.cpp @@ -25,6 +25,7 @@ #ifdef ALL_SCENARIO_COLLABORATION #include "distributed_device_manager.h" #endif +#include "notification_liveview_utils.h" namespace OHOS { namespace Notification { @@ -50,6 +51,8 @@ SystemEventObserver::SystemEventObserver(const ISystemEvent &callbacks) : callba matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_RESTORE_START); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_KIOSK_MODE_ON); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_KIOSK_MODE_OFF); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_STARTED); EventFwk::CommonEventSubscribeInfo commonEventSubscribeInfo(matchingSkills); commonEventSubscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON); @@ -101,11 +104,12 @@ void SystemEventObserver::OnReceiveEvent(const EventFwk::CommonEventData &data) std::string action = want.GetAction(); ANS_LOGD("OnReceiveEvent action is %{public}s.", action.c_str()); if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) { - if (callbacks_.onBundleRemoved != nullptr) { - sptr bundleOption = GetBundleOption(want); - if (bundleOption != nullptr) { - callbacks_.onBundleRemoved(bundleOption); - } + sptr bundleOption = GetBundleOption(want); + if (bundleOption != nullptr && callbacks_.onBundleRemoved != nullptr) { + callbacks_.onBundleRemoved(bundleOption); + } + if (bundleOption != nullptr) { + NotificationLiveViewUtils::GetInstance().NotifyLiveViewEvent(action, bundleOption); } #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON) { @@ -127,6 +131,7 @@ void SystemEventObserver::OnReceiveEvent(const EventFwk::CommonEventData &data) NotificationPreferences::GetInstance()->InitSettingFromDisturbDB(userId); AdvancedNotificationService::GetInstance()->RecoverLiveViewFromDb(userId); NotificationCloneManager::GetInstance().OnUserSwitch(userId); + AdvancedNotificationService::GetInstance()->TriggerLiveViewSwitchCheck(userId); #ifdef ALL_SCENARIO_COLLABORATION DistributedDeviceManager::GetInstance().InitTrustList(); #endif @@ -162,6 +167,9 @@ void SystemEventObserver::OnReceiveEvent(const EventFwk::CommonEventData &data) NotificationPreferences::GetInstance()->SetKioskModeStatus(true); } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_KIOSK_MODE_OFF) { NotificationPreferences::GetInstance()->SetKioskModeStatus(false); + } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED || + action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_STARTED) { + NotificationLiveViewUtils::GetInstance().NotifyLiveViewEvent(action); } else { OnReceiveEventInner(data); } @@ -183,21 +191,27 @@ void SystemEventObserver::OnReceiveEventInner(const EventFwk::CommonEventData &d void SystemEventObserver::OnBundleAddEventInner(const EventFwk::CommonEventData &data) { - if (callbacks_.onBundleAdd != nullptr) { - sptr bundleOption = GetBundleOption(data.GetWant()); - if (bundleOption != nullptr) { - callbacks_.onBundleAdd(bundleOption); - } + sptr bundleOption = GetBundleOption(data.GetWant()); + if (bundleOption != nullptr && callbacks_.onBundleAdd != nullptr) { + callbacks_.onBundleAdd(bundleOption); + } + if (bundleOption != nullptr) { + NotificationLiveViewUtils::GetInstance().NotifyLiveViewEvent( + EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED, bundleOption); } } void SystemEventObserver::OnBundleUpdateEventInner(const EventFwk::CommonEventData &data) { - if (callbacks_.onBundleUpdate != nullptr) { - sptr bundleOption = GetBundleOption(data.GetWant()); - if (bundleOption != nullptr) { - callbacks_.onBundleUpdate(bundleOption); - } + sptr bundleOption = GetBundleOption(data.GetWant()); + if (bundleOption != nullptr && callbacks_.onBundleUpdate != nullptr) { + callbacks_.onBundleUpdate(bundleOption); + } + + AAFwk::Want want = data.GetWant(); + if (bundleOption != nullptr && want.GetBoolParam("isAppUpdate", false)) { + NotificationLiveViewUtils::GetInstance().NotifyLiveViewEvent( + EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED, bundleOption); } } diff --git a/services/ans/src/utils/notification_liveview_utils.cpp b/services/ans/src/utils/notification_liveview_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b594a4870e758a713ddacc2f81495cfcd9608d7a --- /dev/null +++ b/services/ans/src/utils/notification_liveview_utils.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2024 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 "notification_liveview_utils.h" + +#include +#include "ans_log_wrapper.h" +#include "advanced_notification_inline.h" +#include "notification_preferences.h" +#include "liveview_all_scenarios_extension_wrapper.h" + +namespace OHOS { +namespace Notification { + +NotificationLiveViewUtils& NotificationLiveViewUtils::GetInstance() +{ + static NotificationLiveViewUtils notificationLiveViewUtils; + return notificationLiveViewUtils; +} + +std::string NotificationLiveViewUtils::AddLiveViewCheckData(std::shared_ptr& param) +{ + std::string requestId = std::to_string(GetCurrentTime()) + std::to_string(param->bundlesName.size()); + std::lock_guard lock(dataMutex); + checkData[requestId] = param; + return requestId; +} + +void NotificationLiveViewUtils::EraseLiveViewCheckData(const std::string& requestId) +{ + std::lock_guard lock(dataMutex); + checkData.erase(requestId); +} + +bool NotificationLiveViewUtils::GetLiveViewCheckData(const std::string& requestId, + std::shared_ptr& data) +{ + std::lock_guard lock(dataMutex); + if (checkData.find(requestId) == checkData.end()) { + return false; + } + data = checkData[requestId]; + return true; +} + +bool NotificationLiveViewUtils::CheckLiveViewConfigByBundle(const std::string& bundleName, + const std::string& event) +{ + int32_t userId = SUBSCRIBE_USER_INIT; + if (OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(userId) != ERR_OK) { + ANS_LOGE("Current user acquisition failed"); + userId = DEFAULT_USER_ID; + } + + bool configEnable = false; + if (LIVEVIEW_ALL_SCENARIOS_EXTENTION_WRAPPER->CheckLiveViewConfig(bundleName, event, + userId, configEnable) != ERR_OK) { + return false; + } + return configEnable; +} + +bool NotificationLiveViewUtils::CheckLiveViewForBundle(const sptr& request) +{ + if (request == nullptr || !request->IsCommonLiveView()) { + return false; + } + + std::string bundleName; + if (request->IsAgentNotification()) { + bundleName = request->GetOwnerBundleName(); + } else { + bundleName = request->GetCreatorBundleName(); + } + + std::string event; + auto content = request->GetContent()->GetNotificationContent(); + auto liveViewContent = std::static_pointer_cast(content); + std::shared_ptr extroInfo = liveViewContent->GetExtraInfo(); + if (extroInfo != nullptr && extroInfo->HasParam("event")) { + event = extroInfo->GetStringParam("event"); + } + + bool enable = false; + if (LIVEVIEW_ALL_SCENARIOS_EXTENTION_WRAPPER->CheckLiveViewConfig(bundleName, event, + DEFAULT_USER_ID, enable) != ERR_OK) { + return false; + } + return enable; +} + +bool NotificationLiveViewUtils::CheckLiveViewVersion() +{ + int32_t ccmVersion = 0; + if (LIVEVIEW_ALL_SCENARIOS_EXTENTION_WRAPPER->GetLiveViewConfigVersion(ccmVersion) != ERR_OK) { + ANS_LOGW("Live view util get ccm failed"); + return false; + } + + int32_t version = 0; + if (NotificationPreferences::GetInstance()->GetLiveViewConfigVersion(version) != ERR_OK) { + ANS_LOGW("Live view util get db failed"); + return false; + } + + if (version == 0 || version < ccmVersion) { + NotificationPreferences::GetInstance()->SetLiveViewConfigVersion(ccmVersion); + return true; + } + return false; +} + +void NotificationLiveViewUtils::NotifyLiveViewEvent(const std::string& event) +{ + ANS_LOGI("notify event %{public}s", event.c_str()); + if (CheckLiveViewVersion()) { + LIVEVIEW_ALL_SCENARIOS_EXTENTION_WRAPPER->NotifyLiveViewEvent(event, nullptr); + } +} + +void NotificationLiveViewUtils::NotifyLiveViewEvent(const std::string& event, + const sptr& bundleInfo) +{ + ANS_LOGI("notify event %{public}s", event.c_str()); + LIVEVIEW_ALL_SCENARIOS_EXTENTION_WRAPPER->NotifyLiveViewEvent(event, bundleInfo); +} + +bool NotificationLiveViewUtils::CheckLiveViewRebuild(int32_t userId) +{ + std::lock_guard lock(eraseMutex); + if (eraseFlag.find(userId) == eraseFlag.end()) { + eraseFlag[userId] = ERASE_FLAG_INIT; + } else { + if (eraseFlag[userId] == ERASE_FLAG_RUNNING || eraseFlag[userId] == ERASE_FLAG_FINISHED) { + return false; + } + } + + std::string rebuildFlag; + if (NotificationPreferences::GetInstance()->GetLiveViewRebuildFlag(rebuildFlag, userId) != ERR_OK) { + ANS_LOGW("Live view util get db failed"); + eraseFlag[userId] = ERASE_FLAG_INIT; + return false; + } + + if (rebuildFlag.empty()) { + eraseFlag[userId] = ERASE_FLAG_RUNNING; + ANS_LOGI("Live view start config."); + return true; + } + eraseFlag[userId] = ERASE_FLAG_FINISHED; + return false; +} + +void NotificationLiveViewUtils::SetLiveViewRebuild(int32_t userId, int32_t data) +{ + std::lock_guard lock(eraseMutex); + if (data == ERASE_FLAG_INIT || data == ERASE_FLAG_FINISHED) { + eraseFlag[userId] = data; + } + if (data == ERASE_FLAG_FINISHED) { + NotificationPreferences::GetInstance()->SetLiveViewRebuildFlag(userId); + } +} +} +} diff --git a/services/ans/test/unittest/BUILD.gn b/services/ans/test/unittest/BUILD.gn index 9f3f1a30dc8e743e5a64ece753892c4ce802f455..352c85c04befa78002b2b4ab90b644a51f8b1067 100644 --- a/services/ans/test/unittest/BUILD.gn +++ b/services/ans/test/unittest/BUILD.gn @@ -1614,6 +1614,7 @@ ohos_unittest("notification_extension_test") { "notification_extension/distributed_device_status_test.cpp", "notification_extension/distributed_extension_service_test.cpp", "notification_extension/mock_distributed_operation_callback.cpp", + "notification_extension/notification_liveview_utils_test.cpp", "notification_extension/notification_config_parse_mock.cpp", "notification_extension/notification_load_utils_mock.cpp", "notification_extension/notification_operation_service_test.cpp", @@ -1688,6 +1689,7 @@ ohos_unittest("notification_extension_test") { "${services_path}/ans/src/system_event_observer.cpp", "${services_path}/ans/src/system_live_view/advanced_notification_system_live_view_service.cpp", "${services_path}/ans/src/telephony_extension_wrapper.cpp", + "${services_path}/ans/src/utils/notification_liveview_utils.cpp", ] defines = [] diff --git a/services/ans/test/unittest/advanced_notification_service_branch_test.cpp b/services/ans/test/unittest/advanced_notification_service_branch_test.cpp index c8a5dbb2d540415eb774b5e316424b41296f56de..559a68f857fca191cbe7509678378f28c73032a6 100644 --- a/services/ans/test/unittest/advanced_notification_service_branch_test.cpp +++ b/services/ans/test/unittest/advanced_notification_service_branch_test.cpp @@ -1323,5 +1323,73 @@ HWTEST_F(AnsBranchTest, AnsBranchTest_286000, Function | SmallTest | Level1) ASSERT_EQ(advancedNotificationService_->IsNeedSilentInDoNotDisturbMode( phoneNumber, callerType), ERR_ANS_PERMISSION_DENIED); } + +/** + * @tc.number : AnsBranchTest_286001 + * @tc.name : SetCheckConfig + * @tc.desc : Test SetCheckConfig function return ERR_ANS_INVALID_PARAM. + */ +HWTEST_F(AnsBranchTest, AnsBranchTest_286001, Function | SmallTest | Level1) +{ + int32_t response = 0; + std::string requestId = "id"; + std::string key = "key"; + std::string value = "value"; + MockIsVerfyPermisson(false); + int32_t result = advancedNotificationService_->SetCheckConfig(response, requestId, key, value); + ASSERT_EQ(result, ERR_ANS_INVALID_PARAM); + + key = "APP_LIVEVIEW_CONFIG"; + result = advancedNotificationService_->SetCheckConfig(response, requestId, key, value); + ASSERT_EQ(result, ERR_ANS_PERMISSION_DENIED); + + MockIsVerfyPermisson(true); + result = advancedNotificationService_->SetCheckConfig(response, requestId, key, value); + ASSERT_EQ(result, ERR_OK); + result = advancedNotificationService_->SetCheckConfig(6, requestId, key, value); + ASSERT_EQ(result, ERR_OK); + result = advancedNotificationService_->SetCheckConfig(10, requestId, key, value); + ASSERT_EQ(result, ERR_OK); + result = advancedNotificationService_->SetCheckConfig(11, requestId, key, value); + ASSERT_EQ(result, ERR_OK); + result = advancedNotificationService_->SetCheckConfig(7, requestId, key, value); + ASSERT_EQ(result, ERR_OK); +} + +/** + * @tc.number : AnsBranchTest_286002 + * @tc.name : SetCheckConfig + * @tc.desc : Test SetCheckConfig function return ERR_ANS_INVALID_PARAM. + */ +HWTEST_F(AnsBranchTest, AnsBranchTest_286002, Function | SmallTest | Level1) +{ + sptr bundle = new NotificationBundleOption(); + MockGetTokenTypeFlag(Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL); + int32_t result = advancedNotificationService_->SetDefaultSlotForBundle(bundle, 5, true, true); + ASSERT_EQ(result, ERR_ANS_NON_SYSTEM_APP); + + MockIsVerfyPermisson(false); + MockGetTokenTypeFlag(Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE); + result = advancedNotificationService_->SetDefaultSlotForBundle(bundle, 5, true, true); + ASSERT_EQ(result, ERR_ANS_PERMISSION_DENIED); + + MockGetTokenTypeFlag(Security::AccessToken::ATokenTypeEnum::TOKEN_HAP); + result = advancedNotificationService_->SetDefaultSlotForBundle(bundle, 5, true, true); + ASSERT_EQ(result, ERR_ANS_PERMISSION_DENIED); + + MockIsVerfyPermisson(true); + result = advancedNotificationService_->SetDefaultSlotForBundle(bundle, 5, true, true); + ASSERT_EQ(result, ERR_ANS_INVALID_BUNDLE); + + bundle->SetBundleName(TEST_DEFUALT_BUNDLE); + result = advancedNotificationService_->SetDefaultSlotForBundle(bundle, 5, true, true); + ASSERT_EQ(result, ERR_ANS_INVALID_BUNDLE); + + bundle->SetUid(NON_SYSTEM_APP_UID); + result = advancedNotificationService_->SetDefaultSlotForBundle(bundle, 5, true, true); + ASSERT_EQ(result, ERR_OK); + result = advancedNotificationService_->SetDefaultSlotForBundle(bundle, 5, true, true); + ASSERT_EQ(result, ERR_ANS_BUNDLE_SLOT_EXIST); +} } // namespace Notification } // namespace OHOS diff --git a/services/ans/test/unittest/mock/include/mock_push_callback_stub.h b/services/ans/test/unittest/mock/include/mock_push_callback_stub.h index af15e463acaf8b128d124b97e14cdaa310580b98..e37cb5f8120624212ce15d35e56afdac18dca6b9 100644 --- a/services/ans/test/unittest/mock/include/mock_push_callback_stub.h +++ b/services/ans/test/unittest/mock/include/mock_push_callback_stub.h @@ -28,8 +28,11 @@ public: virtual ~MockPushCallBackStub(); virtual int32_t OnCheckNotification(const std::string ¬ificationData, const std::shared_ptr &pushCallBackParam) override; + virtual int32_t OnCheckLiveView(const std::string& requestId, + const std::vector& bundles) override; }; namespace Notification { +void MockOnCheckLiveView(const int32_t retOnCheckLiveView); void MockOnCheckNotification(const int32_t retOnCheckNotification); } // namespace Notification } // namespace OHOS diff --git a/services/ans/test/unittest/mock/mock_push_callback_stub.cpp b/services/ans/test/unittest/mock/mock_push_callback_stub.cpp index 2768e389fda99f5683dea700b8f925efe66e71cb..9801119c7e5a98b4abbb9f12e493e2ac77078bda 100644 --- a/services/ans/test/unittest/mock/mock_push_callback_stub.cpp +++ b/services/ans/test/unittest/mock/mock_push_callback_stub.cpp @@ -19,6 +19,7 @@ namespace OHOS { namespace Notification { namespace { int32_t g_retOnCheckNotification = 0; +int32_t g_retOnCheckLiveView = 0; } void MockOnCheckNotification(const int32_t retOnCheckNotification) @@ -26,6 +27,10 @@ void MockOnCheckNotification(const int32_t retOnCheckNotification) g_retOnCheckNotification = retOnCheckNotification; } +void MockOnCheckLiveView(const int32_t retOnCheckLiveView) +{ + g_retOnCheckLiveView = retOnCheckLiveView; +} } // namespace Notification MockPushCallBackStub::MockPushCallBackStub() {} MockPushCallBackStub::~MockPushCallBackStub() {} @@ -34,4 +39,10 @@ int32_t MockPushCallBackStub::OnCheckNotification(const std::string ¬ificatio { return Notification::g_retOnCheckNotification; } + +int32_t MockPushCallBackStub::OnCheckLiveView(const std::string& requestId, + const std::vector& bundles) +{ + return Notification::g_retOnCheckLiveView; +} } // namespace OHOS diff --git a/services/ans/test/unittest/notification_extension/notification_liveview_utils_test.cpp b/services/ans/test/unittest/notification_extension/notification_liveview_utils_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e946f18a37c78337d9b23e8668f041a648bd811c --- /dev/null +++ b/services/ans/test/unittest/notification_extension/notification_liveview_utils_test.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021-2024 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 "gtest/gtest.h" + +#define private public + +#include "notification_liveview_utils.h" + +using namespace testing::ext; + +namespace OHOS { +namespace Notification { + +class NotificationLiveViewUtilTest : public testing::Test { +public: + static void SetUpTestCase() {}; + static void TearDownTestCase() {}; + void SetUp() {}; + void TearDown() {}; +}; + +/** + * @tc.name: CheckData_100 + * @tc.desc: Test live view check data. + * @tc.type: FUNC + */ +HWTEST_F(NotificationLiveViewUtilTest, CheckData_100, Function | SmallTest | Level1) +{ + std::vector data; + data.emplace_back("bundle_1"); + auto check = std::make_shared(data); + std::string id = NotificationLiveViewUtils::GetInstance().AddLiveViewCheckData(check); + ASSERT_EQ(id.empty(), false); + + std::shared_ptr checkData; + bool exist = NotificationLiveViewUtils::GetInstance().GetLiveViewCheckData("id", checkData); + ASSERT_EQ(exist, false); + + exist = NotificationLiveViewUtils::GetInstance().GetLiveViewCheckData(id, checkData); + ASSERT_EQ(exist, true); + + NotificationLiveViewUtils::GetInstance().EraseLiveViewCheckData(id); +} + +/** + * @tc.name: CheckData_200 + * @tc.desc: Test live view check data. + * @tc.type: FUNC + */ +HWTEST_F(NotificationLiveViewUtilTest, CheckData_200, Function | SmallTest | Level1) +{ + bool check = NotificationLiveViewUtils::GetInstance().CheckLiveViewRebuild(100); + ASSERT_EQ(check, true); + // invoke again + check = NotificationLiveViewUtils::GetInstance().CheckLiveViewRebuild(100); + ASSERT_EQ(check, false); + NotificationLiveViewUtils::GetInstance().SetLiveViewRebuild(100, + NotificationLiveViewUtils::ERASE_FLAG_INIT); + check = NotificationLiveViewUtils::GetInstance().CheckLiveViewRebuild(100); + ASSERT_EQ(check, true); +} +} +} diff --git a/tools/test/mock/mock_ans_manager_stub.h b/tools/test/mock/mock_ans_manager_stub.h index cd5d64d8f2f18c8c0ed036487a3614c2008633ec..0a19a6a327bd450a39e840f378785baccf72b0f7 100644 --- a/tools/test/mock/mock_ans_manager_stub.h +++ b/tools/test/mock/mock_ans_manager_stub.h @@ -745,6 +745,22 @@ public: return ERR_ANS_INVALID_PARAM; } + ErrCode SetCheckConfig(int32_t response, const std::string& requestId, const std::string& key, + const std::string& value) override + { + return ERR_ANS_INVALID_PARAM; + } + + ErrCode GetLiveViewConfig(const std::vector& bundleList) override + { + return ERR_ANS_INVALID_PARAM; + } + + ErrCode SetDefaultSlotForBundle(const sptr &bundleOption, + int32_t slotTypeInt, bool enabled, bool isForceControl) override + { + return ERR_ANS_INVALID_PARAM; + } private: std::string cmd_; std::string bundle_;