diff --git a/bundle.json b/bundle.json index 9a6f3ee2e6062989551b44a2b0a7c4540ccd73ad..7c191896c4d94a5d467de3c4e68a5e73876c390a 100644 --- a/bundle.json +++ b/bundle.json @@ -130,6 +130,7 @@ ], "fwk_group": [ "//base/notification/distributed_notification_service/frameworks/ans:ans_client", + "//base/notification/distributed_notification_service/frameworks/js/napi:napi_extension_subscription", "//base/notification/distributed_notification_service/frameworks/js/napi:napi_notification", "//base/notification/distributed_notification_service/frameworks/js/napi:napi_reminder", "//base/notification/distributed_notification_service/interfaces/ndk:ohnotification", diff --git a/frameworks/ans/IAnsManager.idl b/frameworks/ans/IAnsManager.idl index 48812d68095b3f0bf836dc6d943efc5ffc2edbf5..3b9a4c57b819e4ab1e099d84d7b6d88844420bc1 100644 --- a/frameworks/ans/IAnsManager.idl +++ b/frameworks/ans/IAnsManager.idl @@ -331,5 +331,11 @@ interface OHOS.Notification.IAnsManager { void GetTargetDeviceBundleList([in] String deviceType, [in] String deviceId, [out] String[] bundleList, [out] String[] labelList); + void IsUserGranted([out] boolean enabled); + + void GetUserGrantedState([in] sptr targetBundle, [out] boolean enabled); + + void SetUserGrantedState([in] sptr targetBundle, [in] boolean enabled); + [macrodef NOTIFICATION_SMART_REMINDER_SUPPORTED] void RegisterSwingCallback([in] IRemoteObject swingCallback); } diff --git a/frameworks/ans/src/notification_helper.cpp b/frameworks/ans/src/notification_helper.cpp index bcdcab6c6449a23b80d78973e50c96d1ef1967f7..d3c3acdb3873a46d9d770c957a1b23d3693b6976 100644 --- a/frameworks/ans/src/notification_helper.cpp +++ b/frameworks/ans/src/notification_helper.cpp @@ -789,5 +789,20 @@ ErrCode NotificationHelper::GetLiveViewConfig(const std::vector& bu { return DelayedSingleton::GetInstance()->GetLiveViewConfig(bundleList); } + +ErrCode NotificationHelper::IsUserGranted(bool& enabled) +{ + return DelayedSingleton::GetInstance()->IsUserGranted(enabled); +} + +ErrCode NotificationHelper::GetUserGrantedState(const NotificationBundleOption& targetBundle, bool& enabled) +{ + return DelayedSingleton::GetInstance()->GetUserGrantedState(targetBundle, enabled); +} + +ErrCode NotificationHelper::SetUserGrantedState(const NotificationBundleOption& targetBundle, bool enabled) +{ + return DelayedSingleton::GetInstance()->SetUserGrantedState(targetBundle, enabled); +} } // namespace Notification } // namespace OHOS diff --git a/frameworks/core/common/include/ans_permission_def.h b/frameworks/core/common/include/ans_permission_def.h index bd6d9347b44ce968c283408a163f50c38b3c3522..fc0997dcddd9b4842852b4d36b3b5e132c24b00a 100644 --- a/frameworks/core/common/include/ans_permission_def.h +++ b/frameworks/core/common/include/ans_permission_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -26,6 +26,7 @@ constexpr char OHOS_PERMISSION_SET_UNREMOVABLE_NOTIFICATION[] = "ohos.permission constexpr char OHOS_PERMISSION_NOTIFICATION_AGENT_CONTROLLER[] = "ohos.permission.NOTIFICATION_AGENT_CONTROLLER"; constexpr char OHOS_PERMISSION_SEND_NOTIFICATION_CROSS_USER[] = "ohos.permission.SEND_NOTIFICATION_CROSS_USER"; constexpr char OHOS_PERMISSION_MANAGE_EDM_POLICY[] = "ohos.permission.MANAGE_EDM_POLICY"; +constexpr char OHOS_PERMISSION_SUBSCRIBE_NOTIFICATION[] = "ohos.permission.SUBSCRIBE_NOTIFICATION"; } // namespace Notification } // namespace OHOS diff --git a/frameworks/core/include/ans_notification.h b/frameworks/core/include/ans_notification.h index 0f54553b2288ee5249d82c801e21970c6a3a55c8..ea7875959fbf9dca1d5ea5a56df788d03ac7f2fa 100644 --- a/frameworks/core/include/ans_notification.h +++ b/frameworks/core/include/ans_notification.h @@ -1435,6 +1435,29 @@ public: */ ErrCode GetLiveViewConfig(const std::vector& bundleList); + /** + * @brief Obtains whether the notification extension subscription is enabled. + * @param enabled True if the subscription is enabled. + * @return Returns get result. + */ + ErrCode IsUserGranted(bool& enabled); + + /** + * @brief Obtains whether the notification extension subscription is enabled. + * @param targetBundle The bundle option to be queried. + * @param enabled True if the subscription is enabled. + * @return Returns get result. + */ + ErrCode GetUserGrantedState(const NotificationBundleOption& targetBundle, bool& enabled); + + /** + * @brief Set the notification extension subscription state. + * @param targetBundle The bundle option to be set. + * @param enabled True if the subscription is enabled. + * @return Returns set result. + */ + ErrCode SetUserGrantedState(const NotificationBundleOption& targetBundle, bool enabled); + private: /** * @brief Gets Ans Manager proxy. diff --git a/frameworks/core/src/ans_notification.cpp b/frameworks/core/src/ans_notification.cpp index 704f8734e61a35b6af51aac1bda88417cb34f280..c206a93e1f3446f44938fdabe367fb7f7949658e 100644 --- a/frameworks/core/src/ans_notification.cpp +++ b/frameworks/core/src/ans_notification.cpp @@ -2593,5 +2593,62 @@ ErrCode AnsNotification::GetDistributedDevicelist(std::vector &devi } return proxy->GetDistributedDevicelist(deviceTypes); } + +ErrCode AnsNotification::IsUserGranted(bool& enabled) +{ + ANS_LOGD("AnsNotification::IsUserGranted called"); + + sptr proxy = GetAnsManagerProxy(); + if (!proxy) { + ANS_LOGE("Get ans manager proxy fail"); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + return proxy->IsUserGranted(enabled); +} + +ErrCode AnsNotification::GetUserGrantedState(const NotificationBundleOption& targetBundle, bool& enabled) +{ + ANS_LOGD("called"); + if (targetBundle.GetBundleName().empty()) { + ANS_LOGE("Invalid bundle name."); + return ERR_ANS_INVALID_PARAM; + } + + sptr proxy = GetAnsManagerProxy(); + if (!proxy) { + ANS_LOGE("Get ans manager proxy fail"); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + sptr bo(new (std::nothrow) NotificationBundleOption(targetBundle)); + if (bo == nullptr) { + ANS_LOGE("null bundleOption"); + return ERR_ANS_INVALID_PARAM; + } + return proxy->GetUserGrantedState(bo, enabled); +} + +ErrCode AnsNotification::SetUserGrantedState(const NotificationBundleOption& targetBundle, bool enabled) +{ + ANS_LOGD("called"); + if (targetBundle.GetBundleName().empty()) { + ANS_LOGE("Invalid bundle name."); + return ERR_ANS_INVALID_PARAM; + } + + sptr proxy = GetAnsManagerProxy(); + if (!proxy) { + ANS_LOGE("Get ans manager proxy fail"); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + sptr bo(new (std::nothrow) NotificationBundleOption(targetBundle)); + if (bo == nullptr) { + ANS_LOGE("null bundleOption"); + return ERR_ANS_INVALID_PARAM; + } + return proxy->SetUserGrantedState(bo, enabled); +} } // namespace Notification } // namespace OHOS diff --git a/frameworks/js/napi/BUILD.gn b/frameworks/js/napi/BUILD.gn index ac0505b7841a38f8f784120ab7559e7bc100501f..b015fdc68e46a4aff2184e732b5e2d824240f556 100644 --- a/frameworks/js/napi/BUILD.gn +++ b/frameworks/js/napi/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2023 Huawei Device Co., Ltd. +# Copyright (c) 2021-2025 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -29,6 +29,12 @@ group("napi_notification") { ] } +group("napi_extension_subscription") { + deps = [ + "src/extension_subscription:notificationextensionsubscription", + ] +} + cflags = [ "-fno-math-errno", "-fno-unroll-loops", diff --git a/frameworks/js/napi/include/extension_subscription/init_module.h b/frameworks/js/napi/include/extension_subscription/init_module.h new file mode 100644 index 0000000000000000000000000000000000000000..fecde4b5095424e7c0e88e2ac365907265f4fbca --- /dev/null +++ b/frameworks/js/napi/include/extension_subscription/init_module.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_INCLUDE_EXTENSION_SUBSCRIPTION_INIT_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_INCLUDE_EXTENSION_SUBSCRIPTION_INIT_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace NotificationNapi { +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((constructor)) void RegisterModule(void); +napi_value NotificationSubscribeInit(napi_env env, napi_value exports); +static napi_value Init(napi_env env, napi_value exports); + +#ifdef __cplusplus +} +#endif + +/* + * Module define + */ +napi_module _module_subscribe = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "notificationExtensionSubscription", + .nm_priv = ((void *)0), + .reserved = {0} + +}; +} // namespace NotificationNapi +} // namespace OHOS +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_INCLUDE_EXTENSION_SUBSCRIPTION_INIT_H diff --git a/frameworks/js/napi/include/extension_subscription/napi_notification_extension.h b/frameworks/js/napi/include/extension_subscription/napi_notification_extension.h new file mode 100644 index 0000000000000000000000000000000000000000..b3410760c87ceab8583a96d80291d5b7b69a1a41 --- /dev/null +++ b/frameworks/js/napi/include/extension_subscription/napi_notification_extension.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_NOTIFICATION_EXTENSION_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_NOTIFICATION_EXTENSION_H + +#include "common.h" + +namespace OHOS { +namespace NotificationNapi { +using namespace OHOS::Notification; + +struct NotificationExtensionUserGrantedParams { + NotificationBundleOption targetBundle; + bool enabled = false; + std::vector> bundles; +}; + +struct AsyncCallbackInfoNotificationExtensionUserGranted { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + CallbackPromiseInfo info; + NotificationExtensionUserGrantedParams params; +}; + +napi_value NapiIsUserGranted(napi_env env, napi_callback_info info); +napi_value NapiGetUserGrantedState(napi_env env, napi_callback_info info); +napi_value NapiSetUserGrantedState(napi_env env, napi_callback_info info); +} // namespace NotificationNapi +} // namespace OHOS +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_NOTIFICATION_EXTENSION_H \ No newline at end of file diff --git a/frameworks/js/napi/src/extension_subscription/BUILD.gn b/frameworks/js/napi/src/extension_subscription/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..8d3c4c015224c34919a9c8daf27c538028346025 --- /dev/null +++ b/frameworks/js/napi/src/extension_subscription/BUILD.gn @@ -0,0 +1,94 @@ +# Copyright (c) 2022-2023 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. + +import("//base/notification/distributed_notification_service/notification.gni") +import("//build/ohos.gni") + +cflags = [ + "-fno-math-errno", + "-fno-unroll-loops", + "-fmerge-all-constants", + "-fno-ident", + "-Oz", + "-flto", + "-ffunction-sections", + "-fdata-sections", +] + +config("native_module_config") { + visibility = [ ":*" ] + + include_dirs = [] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } +} + +ohos_shared_library("notificationextensionsubscription") { + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + branch_protector_ret = "pac_ret" + + include_dirs = [ + "../../include", + "../../include/extension_subscription", + ] + + configs = [ ":native_module_config" ] + + sources = [ + "../common.cpp", + "../common_utils.cpp", + "../constant.cpp", + "init_module.cpp", + "napi_notification_extension.cpp", + ] + + deps = [ "${frameworks_module_ans_path}:ans_innerkits" ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_context_native", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:app_context", + "ability_runtime:napi_base_context", + "ability_runtime:napi_common", + "ability_runtime:napi_wantagent_common", + "ability_runtime:runtime", + "ability_runtime:ui_extension", + "ability_runtime:wantagent_innerkits", + "access_token:libtokenid_sdk", + "ace_engine:ace_uicontent", + "c_utils:utils", + "ffrt:libffrt", + "hilog:libhilog", + "hitrace:libhitracechain", + "image_framework:image", + "ipc:ipc_single", + "napi:ace_napi", + "relational_store:native_rdb", + ] + + relative_install_dir = "module" + subsystem_name = "${subsystem_name}" + part_name = "${component_name}" +} diff --git a/frameworks/js/napi/src/extension_subscription/init_module.cpp b/frameworks/js/napi/src/extension_subscription/init_module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49ffcc9b10dffc304782eba6fbfae39d98de2468 --- /dev/null +++ b/frameworks/js/napi/src/extension_subscription/init_module.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "constant.h" +#include "init_module.h" +#include "napi_notification_extension.h" + +namespace OHOS { +namespace NotificationNapi { +using namespace OHOS::Notification; + +EXTERN_C_START + +napi_value NotificationSubscribeInit(napi_env env, napi_value exports) +{ + ANS_LOGD("called"); + + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("isUserGranted", NapiIsUserGranted), + DECLARE_NAPI_FUNCTION("getUserGrantedState", NapiGetUserGrantedState), + DECLARE_NAPI_FUNCTION("setUserGrantedState", NapiSetUserGrantedState), + }; + + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + + return exports; +} +/* + * Module export function + */ +static napi_value Init(napi_env env, napi_value exports) +{ + /* + * Propertise define + */ + NotificationSubscribeInit(env, exports); + ConstantInit(env, exports); + + return exports; +} + +/* + * Module register function + */ +__attribute__((constructor)) void RegisterModule(void) +{ + napi_module_register(&_module_subscribe); +} +EXTERN_C_END +} // namespace NotificationNapi +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/src/extension_subscription/napi_notification_extension.cpp b/frameworks/js/napi/src/extension_subscription/napi_notification_extension.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c027fed2a8fef9590f1342f744deb2b4652091be --- /dev/null +++ b/frameworks/js/napi/src/extension_subscription/napi_notification_extension.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi_notification_extension.h" + +#include "ans_inner_errors.h" +#include "js_native_api.h" +#include "js_native_api_types.h" + +namespace OHOS { +namespace NotificationNapi { +namespace { +const int SUBSCRIBE_MAX_PARA = 1; +const int NAPI_GET_USER_GRANTED_STATE_MAX_PARA = 1; +const int NAPI_SET_USER_GRANTED_STATE_MAX_PARA = 2; +const int NAPI_GET_USER_GRANTED_ENABLE_BUNDLES_MAX_PARA = 1; +const int NAPI_SET_USER_GRANTED_BUNDLE_STATE_MAX_PARA = 3; +} + +napi_value ParseParametersForGetUserGrantedState(const napi_env& env, const napi_callback_info& info, + NotificationExtensionUserGrantedParams& params) +{ + size_t argc = NAPI_GET_USER_GRANTED_STATE_MAX_PARA; + napi_value argv[NAPI_GET_USER_GRANTED_STATE_MAX_PARA] = { nullptr }; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL)); + if (argc < NAPI_GET_USER_GRANTED_STATE_MAX_PARA) { + ANS_LOGE("Wrong number of arguments."); + Common::NapiThrow(env, ERROR_PARAM_INVALID, MANDATORY_PARAMETER_ARE_LEFT_UNSPECIFIED); + return nullptr; + } + + napi_valuetype valuetype = napi_undefined; + // argv[0]: targetBundle + NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype)); + if (valuetype != napi_object) { + ANS_LOGE("Argument type is incorrect. Object expected."); + std::string msg = "Incorrect parameter types.The type of param must be object."; + Common::NapiThrow(env, ERROR_PARAM_INVALID, msg); + return nullptr; + } + auto retValue = Common::GetBundleOption(env, argv[PARAM0], params.targetBundle); + if (retValue == nullptr) { + ANS_LOGE("GetBundleOption failed."); + Common::NapiThrow(env, ERROR_PARAM_INVALID, PARAMETER_VERIFICATION_FAILED); + return nullptr; + } + + return Common::NapiGetNull(env); +} + +napi_value ParseParametersForSetUserGrantedState(const napi_env& env, const napi_callback_info& info, + NotificationExtensionUserGrantedParams& params) +{ + size_t argc = NAPI_SET_USER_GRANTED_STATE_MAX_PARA; + napi_value argv[NAPI_SET_USER_GRANTED_STATE_MAX_PARA] = { nullptr, nullptr }; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL)); + if (argc < NAPI_SET_USER_GRANTED_STATE_MAX_PARA) { + ANS_LOGE("Wrong number of arguments."); + Common::NapiThrow(env, ERROR_PARAM_INVALID, MANDATORY_PARAMETER_ARE_LEFT_UNSPECIFIED); + return nullptr; + } + + napi_valuetype valuetype = napi_undefined; + // argv[0]: targetBundle + NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype)); + if (valuetype != napi_object) { + ANS_LOGE("Argument type is incorrect. Object expected."); + std::string msg = "Incorrect parameter types.The type of param must be object."; + Common::NapiThrow(env, ERROR_PARAM_INVALID, msg); + return nullptr; + } + auto retValue = Common::GetBundleOption(env, argv[PARAM0], params.targetBundle); + if (retValue == nullptr) { + ANS_LOGE("GetBundleOption failed."); + Common::NapiThrow(env, ERROR_PARAM_INVALID, PARAMETER_VERIFICATION_FAILED); + return nullptr; + } + + // argv[1]: enabled + NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype)); + if (valuetype != napi_boolean) { + ANS_LOGE("Wrong argument type. Bool expected."); + std::string msg = "Incorrect parameter types.The type of param must be boolean."; + Common::NapiThrow(env, ERROR_PARAM_INVALID, msg); + return nullptr; + } + napi_get_value_bool(env, argv[PARAM1], ¶ms.enabled); + + return Common::NapiGetNull(env); +} + +void AsyncCompleteCallbackUserGrantedReturnVoid(napi_env env, napi_status status, void *data) +{ + ANS_LOGD("called"); + if (!data) { + ANS_LOGE("Invalid async callback data"); + return; + } + AsyncCallbackInfoNotificationExtensionUserGranted* asynccallbackinfo = + static_cast(data); + if (asynccallbackinfo) { + Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env)); + if (asynccallbackinfo->info.callback != nullptr) { + napi_delete_reference(env, asynccallbackinfo->info.callback); + } + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } +} + +void AsyncCompleteCallbackReturnBoolean(napi_env env, napi_status status, void *data) +{ + ANS_LOGD("called"); + if (!data) { + ANS_LOGE("Invalid async callback data"); + return; + } + AsyncCallbackInfoNotificationExtensionUserGranted* asynccallbackinfo = + static_cast(data); + if (asynccallbackinfo) { + napi_value result = nullptr; + napi_get_boolean(env, asynccallbackinfo->params.enabled, &result); + Common::CreateReturnValue(env, asynccallbackinfo->info, result); + if (asynccallbackinfo->info.callback != nullptr) { + napi_delete_reference(env, asynccallbackinfo->info.callback); + } + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } +} + +napi_value NapiIsUserGranted(napi_env env, napi_callback_info info) +{ + ANS_LOGD("NapiIsUserGranted called"); + + AsyncCallbackInfoNotificationExtensionUserGranted* asynccallbackinfo = new (std::nothrow) + AsyncCallbackInfoNotificationExtensionUserGranted { .env = env, .asyncWork = nullptr }; + if (!asynccallbackinfo) { + Common::NapiThrow(env, ERROR_INTERNAL_ERROR); + return Common::JSParaError(env, nullptr); + } + napi_value promise = nullptr; + Common::PaddingCallbackPromiseInfo(env, nullptr, asynccallbackinfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "isUserGranted", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + ANS_LOGD("isUserGranted work excute."); + AsyncCallbackInfoNotificationExtensionUserGranted *asynccallbackinfo = + static_cast(data); + if (asynccallbackinfo) { + asynccallbackinfo->info.errorCode = + NotificationHelper::IsUserGranted(asynccallbackinfo->params.enabled); + ANS_LOGI("errorCode = %{public}d", asynccallbackinfo->info.errorCode); + } + }, + AsyncCompleteCallbackReturnBoolean, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated); + + return promise; +} + +napi_value NapiGetUserGrantedState(napi_env env, napi_callback_info info) +{ + ANS_LOGD("called"); + + AsyncCallbackInfoNotificationExtensionUserGranted* asynccallbackinfo = new (std::nothrow) + AsyncCallbackInfoNotificationExtensionUserGranted { .env = env, .asyncWork = nullptr }; + if (!asynccallbackinfo) { + Common::NapiThrow(env, ERROR_INTERNAL_ERROR); + return Common::JSParaError(env, nullptr); + } + + if (ParseParametersForGetUserGrantedState(env, info, asynccallbackinfo->params) == nullptr) { + Common::NapiThrow(env, ERROR_PARAM_INVALID); + return Common::NapiGetUndefined(env); + } + + napi_value promise = nullptr; + Common::PaddingCallbackPromiseInfo(env, nullptr, asynccallbackinfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "getUserGrantedState", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + ANS_LOGD("getUserGrantedState work excute."); + AsyncCallbackInfoNotificationExtensionUserGranted *asynccallbackinfo = + static_cast(data); + if (asynccallbackinfo) { + asynccallbackinfo->info.errorCode = NotificationHelper::GetUserGrantedState( + asynccallbackinfo->params.targetBundle, asynccallbackinfo->params.enabled); + ANS_LOGI("errorCode = %{public}d", asynccallbackinfo->info.errorCode); + } + }, + AsyncCompleteCallbackReturnBoolean, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated); + + return promise; +} + +napi_value NapiSetUserGrantedState(napi_env env, napi_callback_info info) +{ + ANS_LOGD("called"); + + AsyncCallbackInfoNotificationExtensionUserGranted* asynccallbackinfo = new (std::nothrow) + AsyncCallbackInfoNotificationExtensionUserGranted { .env = env, .asyncWork = nullptr }; + if (!asynccallbackinfo) { + Common::NapiThrow(env, ERROR_INTERNAL_ERROR); + return Common::JSParaError(env, nullptr); + } + + if (ParseParametersForSetUserGrantedState(env, info, asynccallbackinfo->params) == nullptr) { + Common::NapiThrow(env, ERROR_PARAM_INVALID); + return Common::NapiGetUndefined(env); + } + + napi_value promise = nullptr; + Common::PaddingCallbackPromiseInfo(env, nullptr, asynccallbackinfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "setUserGrantedState", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + ANS_LOGD("setUserGrantedState work excute."); + AsyncCallbackInfoNotificationExtensionUserGranted *asynccallbackinfo = + static_cast(data); + if (asynccallbackinfo) { + asynccallbackinfo->info.errorCode = NotificationHelper::SetUserGrantedState( + asynccallbackinfo->params.targetBundle, asynccallbackinfo->params.enabled); + ANS_LOGI("errorCode = %{public}d", asynccallbackinfo->info.errorCode); + } + }, + AsyncCompleteCallbackUserGrantedReturnVoid, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated); + + return promise; +} +} // namespace NotificationNapi +} // namespace OHOS diff --git a/interfaces/inner_api/notification_helper.h b/interfaces/inner_api/notification_helper.h index 9344b108c445723b809bda1036d3ab30feb8193e..3fd298c42a5b51ccbab428a2c5fd06cee9286827 100644 --- a/interfaces/inner_api/notification_helper.h +++ b/interfaces/inner_api/notification_helper.h @@ -1435,6 +1435,29 @@ public: * @return Returns set result. */ static ErrCode GetLiveViewConfig(const std::vector& bundleList); + + /** + * @brief Obtains whether the notification extension subscription is enabled. + * @param enabled True if the subscription is enabled. + * @return Returns get result. + */ + static ErrCode IsUserGranted(bool& enabled); + + /** + * @brief Obtains whether the notification extension subscription is enabled. + * @param targetBundle The bundle option to be queried. + * @param enabled True if the subscription is enabled. + * @return Returns get result. + */ + static ErrCode GetUserGrantedState(const NotificationBundleOption& targetBundle, bool& enabled); + + /** + * @brief Set the notification extension subscription state. + * @param targetBundle The bundle option to be set. + * @param enabled True if the subscription is enabled. + * @return Returns set result. + */ + static ErrCode SetUserGrantedState(const NotificationBundleOption& targetBundle, bool enabled); }; } // namespace Notification } // namespace OHOS diff --git a/services/ans/BUILD.gn b/services/ans/BUILD.gn index 754e060d5b45459f872f372982d8463f8994e351..f44b4974a2e0eeea19697d38ccb2d6ce7280a6af 100644 --- a/services/ans/BUILD.gn +++ b/services/ans/BUILD.gn @@ -68,6 +68,7 @@ ohos_source_set("ans_service_sources") { "src/advanced_notification_manager/advanced_notification_cancel.cpp", "src/advanced_notification_clone_service.cpp", "src/advanced_notification_event_service.cpp", + "src/advanced_notification_extension_subscription.cpp", "src/advanced_notification_flow_control_service.cpp", "src/advanced_notification_inline.cpp", "src/advanced_notification_live_view_service.cpp", diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index ed0e690f262838a045adb77f25d7c771df1e9bf7..10c854a3ec87bb1c0231a8914e01a74d103890a3 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -1446,6 +1446,13 @@ public: const std::string& value) override; ErrCode GetLiveViewConfig(const std::vector& bundleList) override; + + ErrCode IsUserGranted(bool& isEnabled) override; + + ErrCode GetUserGrantedState(const sptr& targetBundle, bool& enabled) override; + + ErrCode SetUserGrantedState(const sptr& targetBundle, bool enabled) override; + protected: /** * @brief Query whether there is a agent relationship between the two apps. diff --git a/services/ans/include/notification_clone_bundle_info.h b/services/ans/include/notification_clone_bundle_info.h index a400e46f54b2098971a186da02a069caf7d00cb3..a9161b96e36d8576849398df29331bc69ddf495d 100644 --- a/services/ans/include/notification_clone_bundle_info.h +++ b/services/ans/include/notification_clone_bundle_info.h @@ -61,6 +61,9 @@ public: void SetSilentReminderEnabled(const NotificationConstant::SWITCH_STATE &silentReminderEnabled); NotificationConstant::SWITCH_STATE GetSilentReminderEnabled() const; + void SetEnabledExtensionSubscription(const bool &enabled); + bool GetEnabledExtensionSubscription() const; + void AddSlotInfo(const SlotInfo &slotInfo); std::vector GetSlotInfo() const; @@ -78,6 +81,7 @@ private: NotificationConstant::SWITCH_STATE isEnabledNotification_ = NotificationConstant::SWITCH_STATE::SYSTEM_DEFAULT_OFF; std::vector slotsInfo_; NotificationConstant::SWITCH_STATE silentReminderEnabled_; + bool enabledExtensionSubscription_ = false; }; } // namespace Notification } // namespace OHOS diff --git a/services/ans/include/notification_preferences.h b/services/ans/include/notification_preferences.h index b7b6b0c175a84c8b8b15865acb53e1a38029c58c..53f1d272da83d9e946d5ef37f87a1a8bf6804757 100644 --- a/services/ans/include/notification_preferences.h +++ b/services/ans/include/notification_preferences.h @@ -574,6 +574,8 @@ public: bool SetLiveViewRebuildFlag(int32_t userId); ErrCode InitBundlesInfo(int32_t userId, std::unordered_map& bundlesMap); void GetAllLiveViewBundles(std::vector>& bundleOption); + ErrCode GetExtensionSubscriptionEnabled(const sptr &bundleOption, bool &enabled); + ErrCode SetExtensionSubscriptionEnabled(const sptr &bundleOption, bool enabled); 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 fe92e48d8c4fd10123f325026c10835cd793b304..8f0d3fb82329c8585a971c352ac215770ac25fc3 100644 --- a/services/ans/include/notification_preferences_database.h +++ b/services/ans/include/notification_preferences_database.h @@ -339,6 +339,7 @@ public: int32_t SetKvToDb(const std::string &key, const std::string &value, const int32_t &userId); int32_t SetByteToDb(const std::string &key, const std::vector &value, const int32_t &userId); int32_t GetKvFromDb(const std::string &key, std::string &value, const int32_t &userId); + bool PutExtensionSubscriptionEnabled(const NotificationPreferencesInfo::BundleInfo& bundleInfo); #ifdef ENABLE_ANS_PRIVILEGED_MESSAGE_EXT_WRAPPER int32_t GetKvFromDb(const std::string &key, std::string &value, const int32_t &userId, int32_t &retCode); #endif @@ -504,6 +505,8 @@ private: void ParseSlotAuthorizedStatus(sptr &slot, const std::string &value) const; void ParseSlotAuthHitnCnt(sptr &slot, const std::string &value) const; void ParseSlotReminderMode(sptr &slot, const std::string &value) const; + void ParseBundleExtensionSubscriptionEnabled( + NotificationPreferencesInfo::BundleInfo& bundleInfo, const std::string& value) const; bool UpdateCloneToDisturbeDB(const int32_t &userId, const std::unordered_map values); diff --git a/services/ans/include/notification_preferences_info.h b/services/ans/include/notification_preferences_info.h index 158441557c3eb766be7eea3fcc163d8cc6a19e13..9b96ff3f82f0f5eb4bb3e4dd96e11e12dea6b9cf 100644 --- a/services/ans/include/notification_preferences_info.h +++ b/services/ans/include/notification_preferences_info.h @@ -226,6 +226,8 @@ public: int32_t GetBundleUid() const; void SetSlotEnabled(NotificationConstant::SlotType slotType, bool enabled); bool GetSlotEnabled(NotificationConstant::SlotType slotType, bool &enabled) const; + bool GetExtensionSubscriptionEnabled() const; + void SetExtensionSubscriptionEnabled(bool enabled); private: std::string bundleName_; @@ -239,6 +241,7 @@ public: bool hasPoppedDialog_ = BUNDLE_POPPED_DIALOG; std::map> slots_; std::map slotFlagsMap_; + bool enabledExtensionSubscription_ = false; }; /* diff --git a/services/ans/include/preferences_constant.h b/services/ans/include/preferences_constant.h index 21e8728a400822dd208b27b15355b4fb2346b9ed..1c4fbc681af15e1911cba354e682f0c1808df984 100644 --- a/services/ans/include/preferences_constant.h +++ b/services/ans/include/preferences_constant.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -61,6 +61,7 @@ enum class BundleType { BUNDLE_ENABLE_NOTIFICATION_USER_OPTION, BUNDLE_POPPED_DIALOG_TYPE, BUNDLE_SLOTFLGS_TYPE, + BUNDLE_EXTENSION_SUBSCRIPTION_ENABLED_TYPE, }; } // namespace Notification } // namespace OHOS diff --git a/services/ans/src/advanced_notification_extension_subscription.cpp b/services/ans/src/advanced_notification_extension_subscription.cpp new file mode 100644 index 0000000000000000000000000000000000000000..808b1569f1a9fde56f4f8158837dd610f6fa083d --- /dev/null +++ b/services/ans/src/advanced_notification_extension_subscription.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "access_token_helper.h" +#include "advanced_notification_service.h" +#include "ans_inner_errors.h" +#include "ans_log_wrapper.h" +#include "ans_trace_wrapper.h" +#include "ans_permission_def.h" +#include "bundle_manager_helper.h" +#include "common_event_manager.h" +#include "common_event_support.h" +#include "errors.h" +#include "ipc_skeleton.h" +#include "notification_preferences.h" +#include "os_account_manager_helper.h" + +namespace OHOS { +namespace Notification { +namespace { +constexpr const char* ANS_EXTENSION_SERVICE_MODULE_NAME = "libans_extension_service.z.so"; +} + +ErrCode AdvancedNotificationService::IsUserGranted(bool& isEnabled) +{ + ANS_LOGD("AdvancedNotificationService::IsUserGranted"); + if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_SUBSCRIBE_NOTIFICATION)) { + return ERR_ANS_PERMISSION_DENIED; + } + + ANS_LOGE("AdvancedNotificationService::IsUserGranted"); + + sptr bundleOption = GenerateBundleOption(); + if (bundleOption == nullptr) { + ANS_LOGE("Failed to create NotificationBundleOption"); + return ERR_ANS_NO_MEMORY; + } + + if (notificationSvrQueue_ == nullptr) { + ANS_LOGE("NotificationSvrQueue_ is nullptr."); + return ERR_ANS_INVALID_PARAM; + } + ErrCode result = ERR_OK; + ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { + ANS_LOGD("ffrt enter!"); + result = NotificationPreferences::GetInstance()->GetExtensionSubscriptionEnabled(bundleOption, isEnabled); + if (result != ERR_OK) { + ANS_LOGE("Failed to insert subscription info into db, ret: %{public}d", result); + return; + } + })); + notificationSvrQueue_->wait(handler); + + return result; +} + +ErrCode AdvancedNotificationService::GetUserGrantedState( + const sptr& targetBundle, bool& enabled) +{ + ANS_LOGD("AdvancedNotificationService::GetUserGrantedState"); + bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID()); + if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) { + return ERR_ANS_NON_SYSTEM_APP; + } + + if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) { + return ERR_ANS_PERMISSION_DENIED; + } + + sptr bundle = GenerateValidBundleOption(targetBundle); + if (bundle == nullptr) { + ANS_LOGE("Bundle is null."); + return ERR_ANS_INVALID_BUNDLE; + } + + if (notificationSvrQueue_ == nullptr) { + ANS_LOGE("NotificationSvrQueue_ is nullptr."); + return ERR_ANS_INVALID_PARAM; + } + ErrCode result = ERR_OK; + ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { + ANS_LOGD("ffrt enter!"); + result = NotificationPreferences::GetInstance()->GetExtensionSubscriptionEnabled(bundle, enabled); + if (result != ERR_OK) { + ANS_LOGE("Failed to get user granted state for bundle: %{public}s, ret: %{public}d", + targetBundle->GetBundleName().c_str(),result); + return; + } + })); + notificationSvrQueue_->wait(handler); + + return result; +} + +ErrCode AdvancedNotificationService::SetUserGrantedState( + const sptr& targetBundle, bool enabled) +{ + bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID()); + if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) { + return ERR_ANS_NON_SYSTEM_APP; + } + + if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) { + return ERR_ANS_PERMISSION_DENIED; + } + + sptr bundle = GenerateValidBundleOption(targetBundle); + if (bundle == nullptr) { + ANS_LOGE("Bundle is null."); + return ERR_ANS_INVALID_BUNDLE; + } + + if (notificationSvrQueue_ == nullptr) { + ANS_LOGE("NotificationSvrQueue_ is nullptr."); + return ERR_ANS_INVALID_PARAM; + } + ErrCode result = ERR_OK; + ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { + ANS_LOGD("ffrt enter!"); + result = NotificationPreferences::GetInstance()->SetExtensionSubscriptionEnabled(bundle, enabled); + if (result != ERR_OK) { + ANS_LOGE("Failed to set user granted state for bundle: %{public}s, ret: %{public}d", + targetBundle->GetBundleName().c_str(), result); + } + })); + notificationSvrQueue_->wait(handler); + + return result; +} +} // namespace Notification +} // namespace OHOS diff --git a/services/ans/src/advanced_notification_utils.cpp b/services/ans/src/advanced_notification_utils.cpp index bcae685ddfb09b9d6301e63c5ccbb3914a3bc2c1..5f1d24cab47269ed094da2f9eff8c7a095827bc6 100644 --- a/services/ans/src/advanced_notification_utils.cpp +++ b/services/ans/src/advanced_notification_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -1982,6 +1982,12 @@ void AdvancedNotificationService::UpdateCloneBundleInfo(const NotificationCloneB } else { ANS_LOGW("Set notification badge failed."); } + if (NotificationPreferences::GetInstance()->SetExtensionSubscriptionEnabled( + bundle, cloneBundleInfo.GetEnabledExtensionSubscription()) == ERR_OK) { + // handle bundle extension enabled changed + } else { + ANS_LOGW("Set subscription enabled failed."); + } UpdateCloneBundleInfoFoSilentReminder(cloneBundleInfo, bundle); })); diff --git a/services/ans/src/clone/notification_clone_bundle_info.cpp b/services/ans/src/clone/notification_clone_bundle_info.cpp index a189acbbd8a0bc8a8844c6c8b506fa596202f790..8d7fac6dce975b646bcfd9fe9d39afdf518f872f 100644 --- a/services/ans/src/clone/notification_clone_bundle_info.cpp +++ b/services/ans/src/clone/notification_clone_bundle_info.cpp @@ -33,6 +33,7 @@ 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 const char *BUNDLE_INFO_SUBSCRIPTION_ENABLED = "enableExtensionSubscription"; constexpr int32_t CONST_ENABLE_INT = 1; } void NotificationCloneBundleInfo::SetBundleName(const std::string &name) @@ -106,6 +107,16 @@ NotificationConstant::SWITCH_STATE NotificationCloneBundleInfo::GetSilentReminde return silentReminderEnabled_; } +void NotificationCloneBundleInfo::SetEnabledExtensionSubscription(const bool &enabled) +{ + enabledExtensionSubscription_ = enabled; +} + +bool NotificationCloneBundleInfo::GetEnabledExtensionSubscription() const +{ + return enabledExtensionSubscription_; +} + void NotificationCloneBundleInfo::AddSlotInfo(const SlotInfo &slotInfo) { for (auto& item : slotsInfo_) { @@ -145,6 +156,7 @@ void NotificationCloneBundleInfo::ToJson(nlohmann::json &jsonObject) const jsonObject[BUNDLE_INFO_SHOW_BADGE] = isShowBadge_ ? 1 : 0; jsonObject[BUNDLE_INFO_ENABLE_NOTIFICATION] = static_cast(isEnabledNotification_); jsonObject[BUNDLE_INFO_SILENT_REMINDER] = static_cast(silentReminderEnabled_); + jsonObject[BUNDLE_INFO_SUBSCRIPTION_ENABLED] = enabledExtensionSubscription_ ? 1 : 0; } void NotificationCloneBundleInfo::SlotsFromJson(const nlohmann::json &jsonObject) @@ -214,6 +226,11 @@ void NotificationCloneBundleInfo::FromJson(const nlohmann::json &jsonObject) silentReminderEnabled_ = static_cast(silentReminderEnabled); } } + if (jsonObject.contains(BUNDLE_INFO_SUBSCRIPTION_ENABLED) && + jsonObject[BUNDLE_INFO_SUBSCRIPTION_ENABLED].is_number()) { + int32_t enabledExtensionSubscription = jsonObject.at(BUNDLE_INFO_SUBSCRIPTION_ENABLED).get(); + enabledExtensionSubscription_ = (enabledExtensionSubscription == CONST_ENABLE_INT); + } SlotsFromJson(jsonObject); } std::string NotificationCloneBundleInfo::SlotInfo::Dump() const diff --git a/services/ans/src/notification_preferences.cpp b/services/ans/src/notification_preferences.cpp index 38b662af96056ffed4442982c593c90c7a5ab4dc..03cc3ad7adf0ae68817717e2d6031439db0a9702 100644 --- a/services/ans/src/notification_preferences.cpp +++ b/services/ans/src/notification_preferences.cpp @@ -1048,6 +1048,10 @@ ErrCode NotificationPreferences::SaveBundleProperty(NotificationPreferencesInfo: bundleInfo.SetSlotFlags(value); storeDBResult = preferncesDB_->PutSlotFlags(bundleInfo, value); break; + case BundleType::BUNDLE_EXTENSION_SUBSCRIPTION_ENABLED_TYPE: + bundleInfo.SetExtensionSubscriptionEnabled(value); + storeDBResult = preferncesDB_->PutExtensionSubscriptionEnabled(bundleInfo); + break; default: break; } @@ -1083,6 +1087,9 @@ ErrCode NotificationPreferences::GetBundleProperty( value = bundleInfo.GetSlotFlags(); ANS_LOGD("Into BUNDLE_SLOTFLGS_TYPE:GetSlotFlags."); break; + case BundleType::BUNDLE_EXTENSION_SUBSCRIPTION_ENABLED_TYPE: + value = bundleInfo.GetExtensionSubscriptionEnabled(); + break; default: result = ERR_ANS_INVALID_PARAM; break; @@ -1727,6 +1734,38 @@ ErrCode NotificationPreferences::GetDistributedDevicelist(std::vector& bundleOption, bool& enabled) +{ + ANS_LOGD("called"); + if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) { + return ERR_ANS_INVALID_PARAM; + } + auto result = GetBundleProperty(bundleOption, BundleType::BUNDLE_EXTENSION_SUBSCRIPTION_ENABLED_TYPE, enabled); + if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) { + enabled = false; + result = ERR_OK; + } + return result; +} + +ErrCode NotificationPreferences::SetExtensionSubscriptionEnabled( + const sptr& bundleOption, bool enabled) +{ + ANS_LOGD("called"); + if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) { + return ERR_ANS_INVALID_PARAM; + } + std::lock_guard lock(preferenceMutex_); + NotificationPreferencesInfo preferencesInfo = preferencesInfo_; + ErrCode result = SetBundleProperty( + preferencesInfo, bundleOption, BundleType::BUNDLE_EXTENSION_SUBSCRIPTION_ENABLED_TYPE, enabled); + if (result == ERR_OK) { + preferencesInfo_ = preferencesInfo; + } + return result; +} + ErrCode NotificationPreferences::SetSubscriberExistFlag(const std::string& deviceType, bool existFlag) { ANS_LOGD("%{public}s", __FUNCTION__); diff --git a/services/ans/src/notification_preferences_database.cpp b/services/ans/src/notification_preferences_database.cpp index e95c31de17e9f2ea332e6f5975b1560c028acab1..a94a14cc99ab5287762f36c3b3461cbd265ba304 100644 --- a/services/ans/src/notification_preferences_database.cpp +++ b/services/ans/src/notification_preferences_database.cpp @@ -233,6 +233,7 @@ const static std::string KEY_SLOT_AUTH_HINT_CNT = "authHintCnt"; */ const static std::string KEY_REMINDER_MODE = "reminderMode"; +const static std::string KEY_EXTENSION_SUBSCRIPTION_ENABLED = "enableExtensionSubscription"; constexpr char RELATIONSHIP_JSON_KEY_SERVICE[] = "service"; constexpr char RELATIONSHIP_JSON_KEY_APP[] = "app"; @@ -729,6 +730,8 @@ bool NotificationPreferencesDatabase::PutBundlePropertyValueToDisturbeDB( std::to_string(bundleInfo.GetHasPoppedDialog()), values); GenerateEntry(GenerateBundleKey(bundleKey, KEY_BUNDLE_UID), std::to_string(bundleInfo.GetBundleUid()), values); + GenerateEntry(GenerateBundleKey(bundleKey, KEY_EXTENSION_SUBSCRIPTION_ENABLED), + std::to_string(bundleInfo.GetExtensionSubscriptionEnabled()), values); if (!CheckRdbStore()) { ANS_LOGE("null RdbStore"); return false; @@ -1066,6 +1069,9 @@ int32_t NotificationPreferencesDatabase::PutBundlePropertyToDisturbeDB( ANS_LOGD("Into BUNDLE_SLOTFLGS_TYPE:GenerateBundleKey."); keyStr = GenerateBundleKey(bundleKey, KEY_BUNDLE_SLOTFLGS_TYPE); break; + case BundleType::BUNDLE_EXTENSION_SUBSCRIPTION_ENABLED_TYPE: + keyStr = GenerateBundleKey(bundleKey, KEY_EXTENSION_SUBSCRIPTION_ENABLED); + break; default: break; } @@ -1259,6 +1265,9 @@ void NotificationPreferencesDatabase::ParseBundlePropertyFromDisturbeDB( if (typeStr.compare(KEY_BUNDLE_SLOTFLGS_TYPE) == 0) { return ParseBundleSlotFlags(bundleInfo, valueStr); } + if (typeStr.compare(KEY_EXTENSION_SUBSCRIPTION_ENABLED) == 0) { + return ParseBundleExtensionSubscriptionEnabled(bundleInfo, valueStr); + } } void NotificationPreferencesDatabase::ParseSlot(const std::string &findString, sptr &slot, @@ -1646,6 +1655,13 @@ void NotificationPreferencesDatabase::ParseSlotReminderMode( slot->SetReminderMode(reminderMode); } +void NotificationPreferencesDatabase::ParseBundleExtensionSubscriptionEnabled( + NotificationPreferencesInfo::BundleInfo &bundleInfo, const std::string &value) const +{ + ANS_LOGD("ParseBundleExtensionSubscriptionEnabled bundle enabled is %{public}s.", value.c_str()); + bundleInfo.SetExtensionSubscriptionEnabled(static_cast(StringToInt(value))); +} + std::string NotificationPreferencesDatabase::GenerateBundleLablel( const NotificationPreferencesInfo::BundleInfo &bundleInfo) const { @@ -2596,6 +2612,24 @@ bool NotificationPreferencesDatabase::IsSmartReminderEnabled(const std::string d return result; } +bool NotificationPreferencesDatabase::PutExtensionSubscriptionEnabled( + const NotificationPreferencesInfo::BundleInfo& bundleInfo) +{ + if (bundleInfo.GetBundleName().empty()) { + ANS_LOGE("Bundle name is null."); + return false; + } + + if (!CheckBundle(bundleInfo.GetBundleName(), bundleInfo.GetBundleUid())) { + return false; + } + + std::string bundleKey = GenerateBundleLablel(bundleInfo); + int32_t result = PutBundlePropertyToDisturbeDB(bundleKey, BundleType::BUNDLE_EXTENSION_SUBSCRIPTION_ENABLED_TYPE, + bundleInfo.GetExtensionSubscriptionEnabled(), bundleInfo.GetBundleUid()); + return (result == NativeRdb::E_OK); +} + bool NotificationPreferencesDatabase::SetDistributedEnabledBySlot( const NotificationConstant::SlotType &slotType, const std::string &deviceType, const bool enabled) { diff --git a/services/ans/src/notification_preferences_info.cpp b/services/ans/src/notification_preferences_info.cpp index 9eb121215945cb4ee078977fdf57df3bcca545db..cedcde7df7ac9d8ec0882ed73c5e239cc38ccedc 100644 --- a/services/ans/src/notification_preferences_info.cpp +++ b/services/ans/src/notification_preferences_info.cpp @@ -222,6 +222,15 @@ int32_t NotificationPreferencesInfo::BundleInfo::GetBundleUid() const return uid_; } +bool NotificationPreferencesInfo::BundleInfo::GetExtensionSubscriptionEnabled() const +{ + return enabledExtensionSubscription_; +} + +void NotificationPreferencesInfo::BundleInfo::SetExtensionSubscriptionEnabled(bool enabled) +{ + enabledExtensionSubscription_ = enabled; +} void NotificationPreferencesInfo::SetBundleInfo(BundleInfo &info) { std::string bundleKey = info.GetBundleName().append(std::to_string(info.GetBundleUid())); @@ -383,6 +392,7 @@ void NotificationPreferencesInfo::GetAllCLoneBundlesInfo(const int32_t &userId, cloneBundleInfo.SetSlotFlags(iter->second.GetSlotFlags()); cloneBundleInfo.SetIsShowBadge(iter->second.GetIsShowBadge()); cloneBundleInfo.SetEnableNotification(iter->second.GetEnableNotification()); + cloneBundleInfo.SetEnabledExtensionSubscription(iter->second.GetExtensionSubscriptionEnabled()); iter->second.GetAllSlots(slots); for (auto& slot : slots) { NotificationCloneBundleInfo::SlotInfo slotInfo;