diff --git a/frameworks/ans/BUILD.gn b/frameworks/ans/BUILD.gn index f194290d4c0f03c3851555b27ae34b30805108d0..71e5df5385b020d1c56ff3d24f110a2508f42548 100644 --- a/frameworks/ans/BUILD.gn +++ b/frameworks/ans/BUILD.gn @@ -84,6 +84,7 @@ ohos_shared_library("ans_innerkits") { "${frameworks_module_ans_path}/src/notification_content.cpp", "${frameworks_module_ans_path}/src/notification_conversational_content.cpp", "${frameworks_module_ans_path}/src/notification_conversational_message.cpp", + "${frameworks_module_ans_path}/src/notification_disable.cpp", "${frameworks_module_ans_path}/src/notification_distributed_options.cpp", "${frameworks_module_ans_path}/src/notification_do_not_disturb_date.cpp", "${frameworks_module_ans_path}/src/notification_do_not_disturb_profile.cpp", diff --git a/frameworks/ans/src/notification_disable.cpp b/frameworks/ans/src/notification_disable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1fc36611b57f93979e873dfa169fd6a9cd133740 --- /dev/null +++ b/frameworks/ans/src/notification_disable.cpp @@ -0,0 +1,132 @@ +/* + * 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_disable.h" + +#include "ans_const_define.h" +#include "ans_log_wrapper.h" +#include "nlohmann/json.hpp" +#include "parcel.h" + +namespace OHOS { +namespace Notification { +namespace { +constexpr const char *DISABLED = "disabled"; +constexpr const char *BUNDLELIST = "bundleList"; +} // namespace +void NotificationDisable::SetDisabled(bool disabled) +{ + disabled_ = disabled; +} + +void NotificationDisable::SetBundleList(const std::vector &bundleList) +{ + bundleList_ = bundleList; +} + +bool NotificationDisable::GetDisabled() const +{ + return disabled_; +} + +std::vector NotificationDisable::GetBundleList() const +{ + return bundleList_; +} + +bool NotificationDisable::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteBool(disabled_)) { + ANS_LOGE("Failed to write disabled"); + return false; + } + auto size = bundleList_.size(); + if (size > MAX_PARCELABLE_VECTOR_NUM) { + ANS_LOGE("Size exceeds the range"); + return false; + } + if (!parcel.WriteInt32(size)) { + ANS_LOGE("Failed to write bundle list size"); + return false; + } + for (uint32_t index = 0; index < size; ++index) { + if (!parcel.WriteString(bundleList_[index])) { + ANS_LOGE("Failed to write bundle list"); + return false; + } + } + return true; +} + +bool NotificationDisable::ReadFromParcel(Parcel &parcel) +{ + disabled_ = parcel.ReadBool(); + auto size = parcel.ReadUint32(); + if (size > MAX_PARCELABLE_VECTOR_NUM) { + ANS_LOGE("Size exceeds the range"); + return false; + } + bundleList_.resize(size); + for (uint32_t index = 0; index < size; ++index) { + if (!parcel.ReadString(bundleList_[index])) { + ANS_LOGE("Failed to read bundle list"); + return false; + } + } + return true; +} + +NotificationDisable *NotificationDisable::Unmarshalling(Parcel &parcel) +{ + auto objptr = new (std::nothrow) NotificationDisable(); + if ((objptr != nullptr) && !objptr->ReadFromParcel(parcel)) { + delete objptr; + objptr = nullptr; + } + return objptr; +} + +std::string NotificationDisable::ToJson() +{ + nlohmann::json jsonObject; + jsonObject[DISABLED] = disabled_; + jsonObject[BUNDLELIST] = nlohmann::json(bundleList_); + return jsonObject.dump(); +} + +void NotificationDisable::FromJson(const std::string &jsonObj) +{ + if (jsonObj.empty() || !nlohmann::json::accept(jsonObj)) { + ANS_LOGE("Invalid json string"); + return; + } + nlohmann::json jsonObject = nlohmann::json::parse(jsonObj, nullptr, false); + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return; + } + if (jsonObject.is_discarded()) { + ANS_LOGE("Failed to parse json string"); + return; + } + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find(DISABLED) != jsonEnd && jsonObject.at(DISABLED).is_boolean()) { + disabled_ = jsonObject.at(DISABLED).get(); + } + if (jsonObject.find(BUNDLELIST) != jsonEnd && jsonObject.at(BUNDLELIST).is_array()) { + bundleList_ = jsonObject.at(BUNDLELIST).get>(); + } +} +} +} \ No newline at end of file diff --git a/frameworks/ans/src/notification_helper.cpp b/frameworks/ans/src/notification_helper.cpp index a98e65bd36c8ed41daf79345c03ecccffb53fb8e..18587c965304869aa7d6e4703a63f7e338d4f23a 100644 --- a/frameworks/ans/src/notification_helper.cpp +++ b/frameworks/ans/src/notification_helper.cpp @@ -592,5 +592,10 @@ ErrCode NotificationHelper::AllowUseReminder(const std::string& bundleName, bool { return DelayedSingleton::GetInstance()->AllowUseReminder(bundleName, isAllowUseReminder); } + +ErrCode NotificationHelper::DisableNotificationFeature(const NotificationDisable ¬ificationDisable) +{ + return DelayedSingleton::GetInstance()->DisableNotificationFeature(notificationDisable); +} } // namespace Notification } // namespace OHOS diff --git a/frameworks/cj/ffi/include/inner_errors.h b/frameworks/cj/ffi/include/inner_errors.h index c613aa83afdc4fb23669b806f6cd3f8573f74723..99af3298e284113ae838d830d74b5c286a377a42 100644 --- a/frameworks/cj/ffi/include/inner_errors.h +++ b/frameworks/cj/ffi/include/inner_errors.h @@ -108,6 +108,7 @@ enum ErrorCode : uint32_t { ERR_ANS_PUSH_CHECK_NETWORK_UNREACHABLE, ERR_ANS_PUSH_CHECK_EXTRAINFO_INVALID, ERR_ANS_NO_PROFILE_TEMPLATE, + ERR_ANS_REJECTED_WITH_DISABLE_NOTIFICATION, }; // Common error code const uint32_t ERROR_PERMISSION_DENIED = 201; // No permission to call the interface. @@ -135,6 +136,8 @@ const int32_t ERROR_REPEAT_SET = 1600015; // Repeat create const int32_t ERROR_EXPIRED_NOTIFICATION = 1600016; // Low update version. const int32_t ERROR_SETTING_WINDOW_EXIST = 1600018; // The notification settings window is already displayed. const int32_t ERROR_NO_PROFILE_TEMPLATE = 1600019; // Not exit noNotDisturb profile template. +const int32_t ERROR_REJECTED_WITH_DISABLE_NOTIFICATION = + 1600020; // Failed to release the blocklist application notification. const int32_t ERROR_NETWORK_UNREACHABLE = 2300007; // Network unreachable. const int32_t ERROR_BUNDLE_NOT_FOUND = 17700001; // The specified bundle name was not found. diff --git a/frameworks/core/common/include/ans_convert_enum.h b/frameworks/core/common/include/ans_convert_enum.h index a2cdad089bde56ac8fbcdab06ecd46b9efde0bf1..85a9bb14bf74e29e356baf90a8824bf01e9b2c0a 100644 --- a/frameworks/core/common/include/ans_convert_enum.h +++ b/frameworks/core/common/include/ans_convert_enum.h @@ -85,6 +85,7 @@ enum class RemoveReason { PACKAGE_REMOVE_REASON_DELETE = 28, SLOT_ENABLED_REASON_DELETE = 29, RECOVER_LIVE_VIEW_DELETE = 30, + DISABLE_NOTIFICATION_FEATURE_REASON_DELETE = 31, APP_CANCEL_REASON_OTHER = 100, }; diff --git a/frameworks/core/common/include/ans_inner_errors.h b/frameworks/core/common/include/ans_inner_errors.h index a7aa88d48b314ca20349a9a96f6439cbd550ae21..18adb9c0794ad57f1d79d6a15d8b3c9a2b12077e 100644 --- a/frameworks/core/common/include/ans_inner_errors.h +++ b/frameworks/core/common/include/ans_inner_errors.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * 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 @@ -93,7 +93,8 @@ enum ErrorCode : uint32_t { ERR_ANS_NO_AGENT_SETTING, ERR_ANS_NO_PROFILE_TEMPLATE, ERR_ANS_ENCRYPT_FAIL, - ERR_ANS_DECRYPT_FAIL + ERR_ANS_DECRYPT_FAIL, + ERR_ANS_REJECTED_WITH_DISABLE_NOTIFICATION, }; enum ReminderErrorCode : uint32_t { @@ -150,6 +151,8 @@ const int32_t ERROR_EXPIRED_NOTIFICATION = 1600016; // Low update ver const int32_t ERROR_NO_AGENT_SETTING = 1600017; // No corresponding agent relationship configuration. const int32_t ERROR_SETTING_WINDOW_EXIST = 1600018; // The notification settings window is already displayed. const int32_t ERROR_NO_PROFILE_TEMPLATE = 1600019; // Not exit noNotDisturb profile template. +const int32_t ERROR_REJECTED_WITH_DISABLE_NOTIFICATION = + 1600020; // Failed to release the blocklist application notification. const int32_t ERROR_NETWORK_UNREACHABLE = 2300007; // Network unreachable. const int32_t ERROR_BUNDLE_NOT_FOUND = 17700001; // The specified bundle name was not found. } // namespace Notification diff --git a/frameworks/core/common/src/ans_convert_enum.cpp b/frameworks/core/common/src/ans_convert_enum.cpp index b191906b1a1be4aa353f9baa380e0a1245295c3f..4026f5335358ce4b703d15a5fe3a0858309a02b1 100644 --- a/frameworks/core/common/src/ans_convert_enum.cpp +++ b/frameworks/core/common/src/ans_convert_enum.cpp @@ -337,6 +337,9 @@ void AnsEnumUtil::ReasonCToJSSecondExt(const int &inType, int &outType) case NotificationConstant::RECOVER_LIVE_VIEW_DELETE: outType = static_cast(RemoveReason::RECOVER_LIVE_VIEW_DELETE); break; + case NotificationConstant::DISABLE_NOTIFICATION_FEATURE_REASON_DELETE: + outType = static_cast(RemoveReason::DISABLE_NOTIFICATION_FEATURE_REASON_DELETE); + break; default: outType = static_cast(RemoveReason::APP_CANCEL_REASON_OTHER); ANS_LOGW("Reason %{public}d is an invalid value", inType); diff --git a/frameworks/core/include/ans_manager_interface.h b/frameworks/core/include/ans_manager_interface.h index d50562a4fb55a6728c837410acdcf0c7a53e39fb..7ce1f2a573b6cce9f0a3a0ff3eb6a74be7124d86 100644 --- a/frameworks/core/include/ans_manager_interface.h +++ b/frameworks/core/include/ans_manager_interface.h @@ -25,6 +25,7 @@ #include "iremote_broker.h" #include "notification_bundle_option.h" #include "notification_constant.h" +#include "notification_disable.h" #include "notification_do_not_disturb_date.h" #include "notification_do_not_disturb_profile.h" #include "notification_request.h" @@ -917,6 +918,14 @@ public: * @return Returns Update result. */ virtual ErrCode UpdateNotificationTimerByUid(const int32_t uid, const bool isPaused) = 0; + + /** + * @brief Set switch and bundle list of disable notification feature. + * + * @param notificationDisable Switch and bundle list of disable notification feature. + * @return Returns set result. + */ + virtual ErrCode DisableNotificationFeature(const sptr ¬ificationDisable) = 0; }; } // namespace Notification } // namespace OHOS diff --git a/frameworks/core/include/ans_manager_proxy.h b/frameworks/core/include/ans_manager_proxy.h index 53529e5c9ec0e00239b3eec342459d6a2607b63a..dd311a9793976a8502a5c03005e7ec7151db3d14 100644 --- a/frameworks/core/include/ans_manager_proxy.h +++ b/frameworks/core/include/ans_manager_proxy.h @@ -908,6 +908,14 @@ public: */ ErrCode UpdateNotificationTimerByUid(const int32_t uid, const bool isPaused) override; + /** + * @brief Set switch and bundle list of disable notification feature. + * + * @param notificationDisable Switch and bundle list of disable notification feature. + * @return Returns set result. + */ + ErrCode DisableNotificationFeature(const sptr ¬ificationDisable) override; + private: ErrCode InnerTransact(NotificationInterfaceCode code, MessageOption &flags, MessageParcel &data, MessageParcel &reply); diff --git a/frameworks/core/include/ans_manager_stub.h b/frameworks/core/include/ans_manager_stub.h index 8b310ea2d275a58b33a4064e0d6671daf267c332..6b23b2f012aef9cdfa59d6b9c8f328120206773b 100644 --- a/frameworks/core/include/ans_manager_stub.h +++ b/frameworks/core/include/ans_manager_stub.h @@ -908,6 +908,14 @@ public: * @return Returns Update result. */ virtual ErrCode UpdateNotificationTimerByUid(const int32_t uid, const bool isPaused) override; + + /** + * @brief Set switch and bundle list of disable notification feature. + * + * @param notificationDisable Switch and bundle list of disable notification feature. + * @return Returns set result. + */ + virtual ErrCode DisableNotificationFeature(const sptr ¬ificationDisable) override; private: ErrCode HandlePublish(MessageParcel &data, MessageParcel &reply); @@ -1008,6 +1016,7 @@ private: ErrCode HandleRegisterSwingCallback(MessageParcel &data, MessageParcel &reply); #endif ErrCode HandleUpdateNotificationTimerByUid(MessageParcel &data, MessageParcel &reply); + ErrCode HandleDisableNotificationFeature(MessageParcel &data, MessageParcel &reply); template bool WriteParcelableVector(const std::vector> &parcelableVector, MessageParcel &reply, ErrCode &result) { diff --git a/frameworks/core/include/ans_notification.h b/frameworks/core/include/ans_notification.h index 75a9f9c83b20388340d76a3ccb8623168809ef42..0a52d41be6d4cb70f9fbcc43b01c8ac63ae61c94 100644 --- a/frameworks/core/include/ans_notification.h +++ b/frameworks/core/include/ans_notification.h @@ -1148,6 +1148,14 @@ public: * @return Returns Update result. */ ErrCode UpdateNotificationTimerByUid(const int32_t uid, const bool isPaused); + + /** + * @brief Set switch and bundle list of disable notification feature. + * + * @param notificationDisable Switch and bundle list of disable notification feature. + * @return Returns set result. + */ + ErrCode DisableNotificationFeature(const NotificationDisable ¬ificationDisable); 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 186f116760efcf29c72452cd83d3d981a35cbaf2..a9bbcdb335797aa3c1ca634fea89309cbfebadf9 100644 --- a/frameworks/core/include/distributed_notification_service_ipc_interface_code.h +++ b/frameworks/core/include/distributed_notification_service_ipc_interface_code.h @@ -146,6 +146,7 @@ namespace Notification { GET_DONOTDISTURB_PROFILE, UPDATE_NOTIFICATION_TIMER, ALLOW_USE_REMINDER, + DISABLE_NOTIFICATION_FEATURE, }; } } diff --git a/frameworks/core/src/ans_notification.cpp b/frameworks/core/src/ans_notification.cpp index b8c730d5f065ffce295a0c5cfed798ae4baebc2b..e97b21e7dd06c91ef4fe1e6af99f711e062b2c30 100644 --- a/frameworks/core/src/ans_notification.cpp +++ b/frameworks/core/src/ans_notification.cpp @@ -1963,5 +1963,20 @@ std::string AnsNotification::GetAppInstanceKey() const return ""; } } + +ErrCode AnsNotification::DisableNotificationFeature(const NotificationDisable ¬ificationDisable) +{ + sptr proxy = GetAnsManagerProxy(); + if (!proxy) { + ANS_LOGE("DisableNotificationFeature fail"); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + sptr reqPtr = new (std::nothrow) NotificationDisable(notificationDisable); + if (reqPtr == nullptr) { + ANS_LOGE("failed to create NotificationDisable ptr"); + return ERR_ANS_NO_MEMORY; + } + return proxy->DisableNotificationFeature(reqPtr); +} } // namespace Notification } // namespace OHOS diff --git a/frameworks/core/src/manager/ans_manager_proxy.cpp b/frameworks/core/src/manager/ans_manager_proxy.cpp index 3f9188ccd1930d96ac23cfeec0949b040de694be..03bcf59be4bdea3f5a26caa29584b66c5a296d39 100644 --- a/frameworks/core/src/manager/ans_manager_proxy.cpp +++ b/frameworks/core/src/manager/ans_manager_proxy.cpp @@ -985,5 +985,34 @@ ErrCode AnsManagerProxy::UpdateNotificationTimerByUid(const int32_t uid, const b return result; } + +ErrCode AnsManagerProxy::DisableNotificationFeature(const sptr ¬ificationDisable) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { + ANS_LOGE("write interface token failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!data.WriteParcelable(notificationDisable)) { + ANS_LOGE("write notificationDisable failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + MessageParcel reply; + MessageOption option = { MessageOption::TF_SYNC }; + ErrCode result = InnerTransact(NotificationInterfaceCode::DISABLE_NOTIFICATION_FEATURE, option, data, reply); + if (result != ERR_OK) { + ANS_LOGE("transact ErrCode=%{public}d", result); + return ERR_ANS_TRANSACT_FAILED; + } + + if (!reply.ReadInt32(result)) { + ANS_LOGE("fail: read result failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + return result; +} } // namespace Notification } // namespace OHOS diff --git a/frameworks/core/src/manager/ans_manager_stub.cpp b/frameworks/core/src/manager/ans_manager_stub.cpp index b581a5060db292e53fa3c60dc05da8ea9c328706..48368d8732eda74e202cbecfb9488b5c468424a5 100644 --- a/frameworks/core/src/manager/ans_manager_stub.cpp +++ b/frameworks/core/src/manager/ans_manager_stub.cpp @@ -429,6 +429,10 @@ int32_t AnsManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Mess result = HandleAllowUseReminder(data, reply); break; } + case static_cast(NotificationInterfaceCode::DISABLE_NOTIFICATION_FEATURE): { + result = HandleDisableNotificationFeature(data, reply); + break; + } default: { ANS_LOGE("[OnRemoteRequest] fail: unknown code!"); return IPCObjectStub::OnRemoteRequest(code, data, reply, flags); @@ -2496,5 +2500,16 @@ ErrCode AnsManagerStub::HandleAllowUseReminder(MessageParcel &data, MessageParce } return ERR_OK; } + +ErrCode AnsManagerStub::HandleDisableNotificationFeature(MessageParcel &data, MessageParcel &reply) +{ + sptr notificationDisable = data.ReadParcelable(); + ErrCode result = DisableNotificationFeature(notificationDisable); + if (!reply.WriteInt32(result)) { + ANS_LOGE("[HandleDisableNotificationFeature] fail: write result failed, ErrCode=%{public}d", result); + return ERR_ANS_PARCELABLE_FAILED; + } + return ERR_OK; +} } // namespace Notification } // namespace OHOS diff --git a/frameworks/core/src/manager/ans_manager_stub_invalid.cpp b/frameworks/core/src/manager/ans_manager_stub_invalid.cpp index ce3db3ebbcf962cfa7e7d448f37e54d161073038..53ce9c0b3e375409dbc30d1eb97b1363a75750a1 100644 --- a/frameworks/core/src/manager/ans_manager_stub_invalid.cpp +++ b/frameworks/core/src/manager/ans_manager_stub_invalid.cpp @@ -629,5 +629,11 @@ ErrCode AnsManagerStub::UpdateNotificationTimerByUid(const int32_t uid, const bo ANS_LOGE("UpdateNotificationTimerByUid called!"); return ERR_INVALID_OPERATION; } + +ErrCode AnsManagerStub::DisableNotificationFeature(const sptr ¬ificationDisable) +{ + ANS_LOGE("DisableNotificationFeature called!"); + return ERR_INVALID_OPERATION; +} } // namespace Notification } // namespace OHOS 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 0f4b0ef3e9c9dc20f33b7e27d61b56f77a0cac2b..317d1828c32c2be667c124f91cabfa2e2563c35e 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 @@ -559,6 +559,11 @@ public: { return ERR_ANS_INVALID_PARAM; } + + ErrCode DisableNotificationFeature(const sptr ¬ificationDisable) override + { + return ERR_ANS_INVALID_PARAM; + } }; class AnsNotificationBranchTest : public testing::Test { diff --git a/frameworks/js/napi/BUILD.gn b/frameworks/js/napi/BUILD.gn index 5ef45ad7c6410a4878c059d788e75c9af61295e1..6bad2cc4dd4eeac1974992d24702385deb8c7d2c 100644 --- a/frameworks/js/napi/BUILD.gn +++ b/frameworks/js/napi/BUILD.gn @@ -82,6 +82,7 @@ ohos_shared_library("notification") { "src/common_convert_request.cpp", "src/common_utils.cpp", "src/constant.cpp", + "src/disable_notification.cpp", "src/display_badge.cpp", "src/distributed.cpp", "src/disturb_mode.cpp", diff --git a/frameworks/js/napi/include/disable_notification.h b/frameworks/js/napi/include/disable_notification.h new file mode 100644 index 0000000000000000000000000000000000000000..ab04eb5d48a2789e749a7a018a4102fc9e843f97 --- /dev/null +++ b/frameworks/js/napi/include/disable_notification.h @@ -0,0 +1,40 @@ +/* + * 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 BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_DISABLE_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_DISABLE_H + +#include "common.h" + +namespace OHOS { +namespace NotificationNapi { +using namespace OHOS::Notification; + +struct AsyncCallbackInfoDisableNotification { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + NotificationDisable disableNotification; + CallbackPromiseInfo info; +}; + +bool ParseDisableNotificationDisabled(const napi_env &env, const napi_value &value, bool &disabled); +bool ParseDisableNotificationBundleList( + const napi_env &env, const napi_value &value, std::vector &bundleList); +bool ParseDisableNotificationParameters( + const napi_env &env, const napi_callback_info &info, NotificationDisable ¶s); +} // namespace NotificationNapi +} // namespace OHOS + +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_DISABLE_H \ No newline at end of file diff --git a/frameworks/js/napi/include/manager/napi_disable_notification.h b/frameworks/js/napi/include/manager/napi_disable_notification.h new file mode 100644 index 0000000000000000000000000000000000000000..0d5124abd7c78893e03099a2179213e4225c1e68 --- /dev/null +++ b/frameworks/js/napi/include/manager/napi_disable_notification.h @@ -0,0 +1,29 @@ +/* + * 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 BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_INCLUDE_DISABLE_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_INCLUDE_DISABLE_H + +#include "common.h" + +namespace OHOS { +namespace NotificationNapi { +using namespace OHOS::Notification; + +napi_value NapiDisableNotificationFeature(napi_env env, napi_callback_info info); +} // namespace NotificationNapi +} // namespace OHOS + +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_JS_NAPI_INCLUDE_DISABLE_H \ No newline at end of file diff --git a/frameworks/js/napi/src/common_utils.cpp b/frameworks/js/napi/src/common_utils.cpp index e03e13438f1c0e8060f46eeb1168ea077e0e2f54..744d55ee72d519a74e6d476369ef45f1e12b135e 100644 --- a/frameworks/js/napi/src/common_utils.cpp +++ b/frameworks/js/napi/src/common_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * 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 @@ -56,6 +56,7 @@ static const std::unordered_map ERROR_CODE_MESSAGE { {ERROR_NO_RIGHT, "No permission"}, {ERROR_EXPIRED_NOTIFICATION, "Low update version"}, {ERROR_NETWORK_UNREACHABLE, "Network unreachable"}, + {ERROR_REJECTED_WITH_DISABLE_NOTIFICATION, "Failed to release the blocklist application notification"}, }; } @@ -334,7 +335,8 @@ int32_t Common::ErrorToExternal(uint32_t errCode) {ERR_ANS_PUSH_CHECK_NETWORK_UNREACHABLE, ERROR_NETWORK_UNREACHABLE}, {ERR_ANS_NO_AGENT_SETTING, ERROR_NO_AGENT_SETTING}, {ERR_ANS_DIALOG_IS_POPPING, ERROR_DIALOG_IS_POPPING}, - {ERR_ANS_NO_PROFILE_TEMPLATE, ERROR_NO_PROFILE_TEMPLATE} + {ERR_ANS_NO_PROFILE_TEMPLATE, ERROR_NO_PROFILE_TEMPLATE}, + {ERR_ANS_REJECTED_WITH_DISABLE_NOTIFICATION, ERROR_REJECTED_WITH_DISABLE_NOTIFICATION} }; int32_t ExternalCode = ERROR_INTERNAL_ERROR; diff --git a/frameworks/js/napi/src/disable_notification.cpp b/frameworks/js/napi/src/disable_notification.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0b4e15aa136ef5b722cb0a099c69e597e3301b21 --- /dev/null +++ b/frameworks/js/napi/src/disable_notification.cpp @@ -0,0 +1,109 @@ +/* + * 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 "disable_notification.h" +#include "ans_inner_errors.h" + +namespace OHOS { +namespace NotificationNapi { +constexpr int8_t DISABLE_MAX_PARA = 2; + +bool ParseDisableNotificationDisabled(const napi_env &env, const napi_value &value, bool &disabled) +{ + ANS_LOGD("parse disabled"); + napi_valuetype valuetype = napi_undefined; + NAPI_CALL_BASE(env, napi_typeof(env, value, &valuetype), false); + if (valuetype != napi_boolean) { + ANS_LOGW("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 false; + } + napi_get_value_bool(env, value, &disabled); + return true; +} + +bool ParseDisableNotificationBundleList( + const napi_env &env, const napi_value &value, std::vector &bundleList) +{ + ANS_LOGD("parse bundle list"); + bool isArray = false; + napi_is_array(env, value, &isArray); + if (!isArray) { + ANS_LOGE("wrong argument type. Array expected"); + std::string msg = "Incorrect parameter types.The type of param must be array."; + Common::NapiThrow(env, ERROR_PARAM_INVALID, msg); + return false; + } + uint32_t length = 0; + napi_get_array_length(env, value, &length); + if (length == 0) { + ANS_LOGD("the array is empty"); + std::string msg = "Mandatory parameters are left unspecified. The array is empty."; + Common::NapiThrow(env, ERROR_PARAM_INVALID, msg); + return false; + } + napi_valuetype valuetype = napi_undefined; + for (size_t index = 0; index < length; index++) { + napi_value nBundle = nullptr; + napi_get_element(env, value, index, &nBundle); + NAPI_CALL_BASE(env, napi_typeof(env, nBundle, &valuetype), false); + if (valuetype != napi_string) { + ANS_LOGE("wrong argument type. Object expected"); + std::string msg = "Incorrect parameter types.The type of param must be string."; + Common::NapiThrow(env, ERROR_PARAM_INVALID, msg); + return false; + } + char str[STR_MAX_SIZE] = {0}; + size_t strLen = 0; + napi_get_value_string_utf8(env, nBundle, str, STR_MAX_SIZE - 1, &strLen); + if (std::strlen(str) == 0) { + ANS_LOGE("property deviceType is empty"); + Common::NapiThrow(env, ERROR_PARAM_INVALID, MANDATORY_PARAMETER_ARE_LEFT_UNSPECIFIED); + return false; + } + bundleList.emplace_back(str); + } + return true; +} + +bool ParseDisableNotificationParameters( + const napi_env &env, const napi_callback_info &info, NotificationDisable ¶m) +{ + ANS_LOGD("enter"); + size_t argc = DISABLE_MAX_PARA; + napi_value argv[DISABLE_MAX_PARA] = {nullptr}; + napi_value thisVar = nullptr; + NAPI_CALL_BASE(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL), false); + if (argc != DISABLE_MAX_PARA) { + ANS_LOGE("wrong number of arguments"); + Common::NapiThrow(env, ERROR_PARAM_INVALID, MANDATORY_PARAMETER_ARE_LEFT_UNSPECIFIED); + return false; + } + // argv[0]: disabled + bool disabled = false; + if (!ParseDisableNotificationDisabled(env, argv[PARAM0], disabled)) { + return false; + } + param.SetDisabled(disabled); + std::vector bundleList; + if (!ParseDisableNotificationBundleList(env, argv[PARAM1], bundleList)) { + return false; + } + param.SetBundleList(bundleList); + return true; +} +} +} \ No newline at end of file diff --git a/frameworks/js/napi/src/manager/BUILD.gn b/frameworks/js/napi/src/manager/BUILD.gn index 0081f8b8bc2625be13ec34093f544fbcb4c90831..68484ba645ad18ecd0b43913e75ff6039962b407 100644 --- a/frameworks/js/napi/src/manager/BUILD.gn +++ b/frameworks/js/napi/src/manager/BUILD.gn @@ -66,6 +66,7 @@ ohos_shared_library("notificationmanager") { "../common_convert_request.cpp", "../common_utils.cpp", "../constant.cpp", + "../disable_notification.cpp", "../display_badge.cpp", "../distributed.cpp", "../disturb_mode.cpp", @@ -77,6 +78,7 @@ ohos_shared_library("notificationmanager") { "init_module.cpp", "local_live_view_subscribe.cpp", "napi_cancel.cpp", + "napi_disable_notification.cpp", "napi_display_badge.cpp", "napi_distributed.cpp", "napi_distributed_enable.cpp", diff --git a/frameworks/js/napi/src/manager/init_module.cpp b/frameworks/js/napi/src/manager/init_module.cpp index 0468d5b6995c9c0b4278cbe6e57caab803c2a510..9f9cac32a9834637ce54cbd599b99011b3251ac3 100644 --- a/frameworks/js/napi/src/manager/init_module.cpp +++ b/frameworks/js/napi/src/manager/init_module.cpp @@ -20,6 +20,7 @@ #include "js_runtime_utils.h" #include "napi/native_api.h" #include "napi_cancel.h" +#include "napi_disable_notification.h" #include "napi_display_badge.h" #include "napi_distributed.h" #include "napi_disturb_mode.h" @@ -123,6 +124,7 @@ napi_value NotificationManagerInit(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("isNotificationEnabledSync", NapiIsNotificationEnabledSync), DECLARE_NAPI_FUNCTION("openNotificationSettings", NapiOpenNotificationSettings), DECLARE_NAPI_FUNCTION("getDoNotDisturbProfile", NapiGetDoNotDisturbProfile), + DECLARE_NAPI_FUNCTION("disableNotificationFeature", NapiDisableNotificationFeature), }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); diff --git a/frameworks/js/napi/src/manager/napi_disable_notification.cpp b/frameworks/js/napi/src/manager/napi_disable_notification.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a2b90043cb396d0746b6edef344f7d82b63b95f0 --- /dev/null +++ b/frameworks/js/napi/src/manager/napi_disable_notification.cpp @@ -0,0 +1,72 @@ +/* + * 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 "napi_disable_notification.h" + +#include "ans_inner_errors.h" +#include "disable_notification.h" + +namespace OHOS { +namespace NotificationNapi { +napi_value NapiDisableNotificationFeature(napi_env env, napi_callback_info info) +{ + ANS_LOGI("enter"); + NotificationDisable paras; + if (!ParseDisableNotificationParameters(env, info, paras)) { + Common::NapiThrow(env, ERROR_PARAM_INVALID); + return Common::NapiGetUndefined(env); + } + + AsyncCallbackInfoDisableNotification *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoDisableNotification { + .env = env, .asyncWork = nullptr, .disableNotification = paras + }; + 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, "disableNotificationFeature", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work(env, + nullptr, resourceName, [](napi_env env, void *data) { + ANS_LOGD("Napi disable notification Feature work excute."); + AsyncCallbackInfoDisableNotification *asynccallbackinfo = + static_cast(data); + if (asynccallbackinfo) { + asynccallbackinfo->info.errorCode = + NotificationHelper::DisableNotificationFeature(asynccallbackinfo->disableNotification); + } + }, + [](napi_env env, napi_status status, void *data) { + ANS_LOGD("Napi disable notification Feature work complete."); + AsyncCallbackInfoDisableNotification *asynccallbackinfo = + static_cast(data); + if (asynccallbackinfo) { + Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env)); + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } + }, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated); + return promise; +} +} +} \ No newline at end of file diff --git a/interfaces/inner_api/notification_constant.h b/interfaces/inner_api/notification_constant.h index 6f4de3f91f3326b0fa2eba7e628c9634781e8cde..364c2ba76b752b18b38863432258cadd3fbf904e 100644 --- a/interfaces/inner_api/notification_constant.h +++ b/interfaces/inner_api/notification_constant.h @@ -297,6 +297,11 @@ public: */ static const int32_t RECOVER_LIVE_VIEW_DELETE = 30; + /** + * Indicates that a notification is deleted because disable. + */ + static const int32_t DISABLE_NOTIFICATION_FEATURE_REASON_DELETE = 31; + /** * Indicates that a notification is deleted for other reasons. */ diff --git a/interfaces/inner_api/notification_disable.h b/interfaces/inner_api/notification_disable.h new file mode 100644 index 0000000000000000000000000000000000000000..d89d1909792d720172f47851b1a2ebad50c0b295 --- /dev/null +++ b/interfaces/inner_api/notification_disable.h @@ -0,0 +1,47 @@ +/* + * 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 BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_DISABLE_PROFILE_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_DISABLE_PROFILE_H + +#include "nlohmann/json.hpp" +#include "parcel.h" + +namespace OHOS { +namespace Notification { +class NotificationDisable : public Parcelable { +public: + NotificationDisable() = default; + ~NotificationDisable() = default; + + void SetDisabled(bool disabled); + void SetBundleList(const std::vector &bundleList); + bool GetDisabled() const; + std::vector GetBundleList() const; + bool Marshalling(Parcel &parcel) const override; + bool ReadFromParcel(Parcel &parcel); + + static NotificationDisable *Unmarshalling(Parcel &parcel); + std::string ToJson(); + void FromJson(const std::string &jsonObj); + +private: + bool disabled_ = false; + std::vector bundleList_; +}; +} +} + +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_DISABLE_PROFILE_H \ No newline at end of file diff --git a/interfaces/inner_api/notification_helper.h b/interfaces/inner_api/notification_helper.h index 5817ea3203ab5bb4817a43d9dfb7a065c3cecadd..c846f999d193031a24fd546cec701a8bc2e9f264 100644 --- a/interfaces/inner_api/notification_helper.h +++ b/interfaces/inner_api/notification_helper.h @@ -1118,6 +1118,14 @@ public: * @return Returns ERR_OK on success, others on failure. */ static ErrCode AllowUseReminder(const std::string& bundleName, bool& isAllowUseReminder); + + /** + * @brief Set switch and bundle list of disable notification feature. + * + * @param notificationDisable Switch and bundle list of disable notification feature. + * @return Returns set result. + */ + static ErrCode DisableNotificationFeature(const NotificationDisable ¬ificationDisable); }; } // namespace Notification } // namespace OHOS diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index 061ba3b3e2a949080898ced1d452ccd84260a1bd..3f2bf81ea9b05df3ac98e966efce7052d3a4e89b 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -1106,6 +1106,10 @@ public: void UpdateCloneBundleInfo(const NotificationCloneBundleInfo cloneBundleInfo); void TryStartReminderAgentService(); + + ErrCode DisableNotificationFeature(const sptr ¬ificationDisable) override; + + bool IsDisableNotification(const std::string &bundleName); protected: /** * @brief Query whether there is a agent relationship between the two apps. diff --git a/services/ans/include/notification_preferences.h b/services/ans/include/notification_preferences.h index 793a500306dab478965ea0be78f7279a7dafd6e8..a497fbe14d1e80b31bb565e4230de8955b3b6d5b 100644 --- a/services/ans/include/notification_preferences.h +++ b/services/ans/include/notification_preferences.h @@ -399,6 +399,8 @@ public: const std::vector& cloneBundleInfo); bool DelBatchCloneProfileInfo(const int32_t &userId, const std::vector>& profileInfo); + ErrCode SetDisableNotificationInfo(const sptr ¬ificationDisable); + bool GetDisableNotificationInfo(NotificationDisable ¬ificationDisable); private: bool GetBundleInfo(NotificationPreferencesInfo &preferencesInfo, diff --git a/services/ans/include/notification_preferences_database.h b/services/ans/include/notification_preferences_database.h index b6c6eeca1ceb3692b73a433ab9633c62b79f3c95..53edaa2d9ced4f0f6dfec06ea07993d49bae6054 100644 --- a/services/ans/include/notification_preferences_database.h +++ b/services/ans/include/notification_preferences_database.h @@ -260,7 +260,8 @@ public: const std::vector>& profileInfo); bool DelBatchCloneBundleInfo(const int32_t &userId, const std::vector& cloneBundleInfo); - + bool SetDisableNotificationInfo(const sptr ¬ificationDisable); + bool GetDisableNotificationInfo(NotificationDisable ¬ificationDisable); private: bool CheckRdbStore(); @@ -345,6 +346,7 @@ private: void GetDoNotDisturbEndDate(NotificationPreferencesInfo &info, int32_t userId); void GetEnableAllNotification(NotificationPreferencesInfo &info, int32_t userId); void GetDoNotDisturbProfile(NotificationPreferencesInfo &info, int32_t userId); + void GetDisableNotificationInfo(NotificationPreferencesInfo &info); void SetSoltProperty(sptr &slot, std::string &typeStr, std::string &valueStr, const std::string &findString, const int32_t &userId); void ExecuteDisturbeDB(sptr &slot, std::string &typeStr, std::string &valueStr, diff --git a/services/ans/include/notification_preferences_info.h b/services/ans/include/notification_preferences_info.h index 18c9e5ca1da4f82cde05e50184aeeb1e5e485515..7d1bc8220156fec42f807cc9cd5da343ee35be9f 100644 --- a/services/ans/include/notification_preferences_info.h +++ b/services/ans/include/notification_preferences_info.h @@ -26,6 +26,7 @@ #include "preferences_constant.h" #include "advanced_notification_service.h" #include "notification_clone_bundle_info.h" +#include "notification_disable.h" namespace OHOS { namespace Notification { @@ -319,12 +320,21 @@ public: void GetAllDoNotDisturbProfiles(int32_t userId, std::vector> &profiles); void GetAllCLoneBundlesInfo(const int32_t &userId, const std::unordered_map &bunlesMap, std::vector &cloneBundles); + void SetDisableNotificationInfo(const sptr ¬ificationDisable); + bool GetDisableNotificationInfo(NotificationDisable ¬ificationDisable); + void AddDisableNotificationInfo(const std::string &value); private: std::map isEnabledAllNotification_; std::map> doNotDisturbDate_; std::map> doNotDisturbProfiles_; std::map infos_; + + struct DisableNotificationInfo { + int32_t disabled = -1; + std::vector bundleList; + }; + DisableNotificationInfo disableNotificationInfo_; }; } // namespace Notification } // namespace OHOS diff --git a/services/ans/src/advanced_notification_publish_service.cpp b/services/ans/src/advanced_notification_publish_service.cpp index 432ab960fdac9b54499d19bcfd62b985e686e2e5..086bac360ff0a01dc5788714ee341bce964d5481 100644 --- a/services/ans/src/advanced_notification_publish_service.cpp +++ b/services/ans/src/advanced_notification_publish_service.cpp @@ -194,6 +194,10 @@ ErrCode AdvancedNotificationService::PublishNotificationForIndirectProxy(const s request->SetSound(""); } std::string bundle = request->GetCreatorBundleName(); + if (IsDisableNotification(bundle)) { + ANS_LOGI("failed to release the blocklist application notification, bundleName=%{public}s", bundle.c_str()); + return ERR_ANS_REJECTED_WITH_DISABLE_NOTIFICATION; + } int32_t uid = request->GetCreatorUid(); request->SetOwnerUid(uid); request->SetOwnerBundleName(bundle); @@ -2270,6 +2274,10 @@ ErrCode AdvancedNotificationService::PublishNotificationBySa(const sptrIsAgentNotification()) { record->bundleOption = new (std::nothrow) NotificationBundleOption("", request->GetCreatorUid()); } else { + if (!bundle.empty() && IsDisableNotification(bundle)) { + ANS_LOGI("failed to release the blocklist application notification, bundleName=%{public}s", bundle.c_str()); + return ERR_ANS_REJECTED_WITH_DISABLE_NOTIFICATION; + } record->bundleOption = new (std::nothrow) NotificationBundleOption(bundle, uid); } record->bundleOption->SetAppInstanceKey(request->GetAppInstanceKey()); @@ -2732,5 +2740,24 @@ void AdvancedNotificationService::ClearAllNotificationGroupInfo(std::string loca aggregateLocalSwitch_ = status; }); } + +bool AdvancedNotificationService::IsDisableNotification(const std::string &bundleName) +{ + NotificationDisable notificationDisable; + if (NotificationPreferences::GetInstance()->GetDisableNotificationInfo(notificationDisable)) { + if (notificationDisable.GetDisabled()) { + ANSR_LOGI("set disabled to open"); + std::vector bundleList = notificationDisable.GetBundleList(); + auto it = std::find(bundleList.begin(), bundleList.end(), bundleName); + if (it != bundleList.end()) { + ANS_LOGD("failed to release the blocklist application notification"); + return true; + } + } + } else { + ANS_LOGI("no disabled has been set up or set disabled to close"); + } + return false; +} } // namespace Notification } // namespace OHOS diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 9fcb968adad29267f1b1482aa0b19b67cf5198cd..646ad438b3a959648744459a12b7ecee3cbf040b 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -429,6 +429,7 @@ ErrCode AdvancedNotificationService::PrepareNotificationInfo( const sptr &request, sptr &bundleOption) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + bool controller = true; if (request == nullptr) { ANS_LOGE("request is invalid."); return ERR_ANS_INVALID_PARAM; @@ -459,6 +460,16 @@ ErrCode AdvancedNotificationService::PrepareNotificationInfo( bundleOption = new (std::nothrow) NotificationBundleOption(request->GetCreatorBundleName(), request->GetCreatorUid()); } + if (NotificationPreferences::GetInstance()->IsAgentRelationship(GetClientBundleName(), sourceBundleName) && + AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_AGENT_CONTROLLER)) { + controller = false; + } + } + + if (controller && IsDisableNotification(request->GetOwnerBundleName())) { + ANS_LOGI("failed to release the blocklist application notification, bundleName=%{public}s", + (request->GetOwnerBundleName()).c_str()); + return ERR_ANS_REJECTED_WITH_DISABLE_NOTIFICATION; } if (bundleOption == nullptr) { @@ -2566,5 +2577,41 @@ void AdvancedNotificationService::GetFlowCtrlConfigFromCCM() ANS_LOGI("GetFlowCtrlConfigFromCCM success"); } + +ErrCode AdvancedNotificationService::DisableNotificationFeature(const sptr ¬ificationDisable) +{ + ANS_LOGD("called"); + if (notificationDisable == nullptr) { + ANS_LOGE("notificationDisable is nullptr"); + return ERR_ANS_INVALID_PARAM; + } + bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID()); + if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) { + ANS_LOGE("notificationDisable is no system app"); + return ERR_ANS_NON_SYSTEM_APP; + } + if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) { + ANS_LOGE("notificationDisable is permission denied"); + return ERR_ANS_PERMISSION_DENIED; + } + if (notificationSvrQueue_ == nullptr) { + ANS_LOGE("serial queue is invalid"); + return ERR_ANS_INVALID_PARAM; + } + ffrt::task_handle handler = + notificationSvrQueue_->submit_h(std::bind([copyNotificationDisable = notificationDisable]() { + ANS_LOGD("the ffrt enter"); + NotificationPreferences::GetInstance()->SetDisableNotificationInfo(copyNotificationDisable); + })); + notificationSvrQueue_->wait(handler); + if (notificationDisable->GetDisabled()) { + std::vector bundleList = notificationDisable->GetBundleList(); + for (auto bundle : bundleList) { + sptr bo(new (std::nothrow) NotificationBundleOption(bundle, DEFAULT_UID)); + RemoveAllNotificationsInner(bo, NotificationConstant::DISABLE_NOTIFICATION_FEATURE_REASON_DELETE); + } + } + return ERR_OK; +} } // namespace Notification } // namespace OHOS diff --git a/services/ans/src/notification_preferences.cpp b/services/ans/src/notification_preferences.cpp index bd637fa821622579536dda1cba12c57dc2fc8543..9f9dd5e8d23c46dbce11071f3bf1b3b44c361745 100644 --- a/services/ans/src/notification_preferences.cpp +++ b/services/ans/src/notification_preferences.cpp @@ -1334,5 +1334,43 @@ bool NotificationPreferences::DelBatchCloneBundleInfo(const int32_t &userId, } return preferncesDB_->DelBatchCloneBundleInfo(userId, cloneBundleInfo); } + +ErrCode NotificationPreferences::SetDisableNotificationInfo(const sptr ¬ificationDisable) +{ + ANS_LOGD("called"); + std::lock_guard lock(preferenceMutex_); + preferencesInfo_.SetDisableNotificationInfo(notificationDisable); + if (preferncesDB_ == nullptr) { + ANS_LOGE("the prefernces db is nullptr"); + return ERR_ANS_SERVICE_NOT_READY; + } + if (!preferncesDB_->SetDisableNotificationInfo(notificationDisable)) { + ANS_LOGE("db set disable notification info fail"); + return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED; + } + + return ERR_OK; +} + +bool NotificationPreferences::GetDisableNotificationInfo(NotificationDisable ¬ificationDisable) +{ + std::lock_guard lock(preferenceMutex_); + if (preferencesInfo_.GetDisableNotificationInfo(notificationDisable)) { + return true; + } + if (preferncesDB_ == nullptr) { + ANS_LOGE("the prefernces db is nullptr"); + return false; + } + if (preferncesDB_->GetDisableNotificationInfo(notificationDisable)) { + ANS_LOGD("db get disable notification success"); + sptr notificationDisablePtr = new (std::nothrow) NotificationDisable(notificationDisable); + preferencesInfo_.SetDisableNotificationInfo(notificationDisablePtr); + } else { + ANS_LOGI("db get disable notification fail"); + return false; + } + return true; +} } // namespace Notification } // namespace OHOS diff --git a/services/ans/src/notification_preferences_database.cpp b/services/ans/src/notification_preferences_database.cpp index 5a48a2ec4a7cc9284230d09cbcb08b605856c6d8..5b1a3a58809fe09c42f1fd70d5d1e1ca83f8fa76 100644 --- a/services/ans/src/notification_preferences_database.cpp +++ b/services/ans/src/notification_preferences_database.cpp @@ -226,6 +226,7 @@ constexpr char RELATIONSHIP_JSON_KEY_APP[] = "app"; const static std::string KEY_CLONE_LABEL = "label_ans_clone_"; const static std::string CLONE_BUNDLE = "bundle_"; const static std::string CLONE_PROFILE = "profile_"; +const static std::string KEY_DISABLE_NOTIFICATION = "disableNotificationFeature"; NotificationPreferencesDatabase::NotificationPreferencesDatabase() { @@ -696,6 +697,7 @@ bool NotificationPreferencesDatabase::ParseFromDisturbeDB(NotificationPreference GetEnableAllNotification(info, iter); GetDoNotDisturbProfile(info, iter); } + GetDisableNotificationInfo(info); return true; } @@ -2296,5 +2298,57 @@ bool NotificationPreferencesDatabase::UpdateCloneToDisturbeDB(const int32_t &use int32_t result = rdbDataManager_->InsertBatchData(values, userId); return (result == NativeRdb::E_OK); } + +bool NotificationPreferencesDatabase::SetDisableNotificationInfo(const sptr ¬ificationDisable) +{ + if (notificationDisable == nullptr || !CheckRdbStore()) { + ANS_LOGE("notificationDisable or rdbStore is nullptr"); + return false; + } + if (notificationDisable->GetBundleList().empty()) { + ANS_LOGE("the bundle list is empty"); + return false; + } + std::string key = KEY_DISABLE_NOTIFICATION; + std::string value = notificationDisable->ToJson(); + int32_t userId = 0; + int32_t result = rdbDataManager_->InsertData(key, value, userId); + return (result == NativeRdb::E_OK); +} + +bool NotificationPreferencesDatabase::GetDisableNotificationInfo(NotificationDisable ¬ificationDisable) +{ + if (!CheckRdbStore()) { + ANS_LOGE("rdbStore is nullptr"); + return false; + } + std::string key = KEY_DISABLE_NOTIFICATION; + std::string value; + int32_t userId = 0; + int32_t result = rdbDataManager_->QueryData(key, value, userId); + if (result != NativeRdb::E_OK) { + ANS_LOGE("query disable data fail"); + return false; + } + notificationDisable.FromJson(value); + return true; +} + +void NotificationPreferencesDatabase::GetDisableNotificationInfo(NotificationPreferencesInfo &info) +{ + if (!CheckRdbStore()) { + ANS_LOGE("rdbStore is nullptr"); + return; + } + std::string key = KEY_DISABLE_NOTIFICATION; + std::string value; + int32_t userId = 0; + int32_t result = rdbDataManager_->QueryData(key, value, userId); + if (result != NativeRdb::E_OK) { + ANS_LOGE("query disable data failed"); + return; + } + info.AddDisableNotificationInfo(value); +} } // namespace Notification } // namespace OHOS diff --git a/services/ans/src/notification_preferences_info.cpp b/services/ans/src/notification_preferences_info.cpp index e77bc6e85e75d1a85b54919f425b2de78a542038..9e33aa3d20e31d1a4c627a243dc69fa3eba22f0b 100644 --- a/services/ans/src/notification_preferences_info.cpp +++ b/services/ans/src/notification_preferences_info.cpp @@ -408,5 +408,52 @@ void NotificationPreferencesInfo::SetBundleInfoFromDb(BundleInfo &info, std::str { infos_.insert_or_assign(bundleKey, info); } + +void NotificationPreferencesInfo::SetDisableNotificationInfo(const sptr ¬ificationDisable) +{ + if (notificationDisable == nullptr) { + ANS_LOGE("the notificationDisable is nullptr"); + return; + } + if (notificationDisable->GetBundleList().empty()) { + ANS_LOGE("the bundle list is empty"); + return; + } + DisableNotificationInfo disableNotificationInfo; + if (notificationDisable->GetDisabled()) { + disableNotificationInfo_.disabled = 1; + } else { + disableNotificationInfo_.disabled = 0; + } + disableNotificationInfo_.bundleList = notificationDisable->GetBundleList(); +} + +bool NotificationPreferencesInfo::GetDisableNotificationInfo(NotificationDisable ¬ificationDisable) +{ + if (disableNotificationInfo_.disabled == -1) { + ANS_LOGI("notificationDisable is invalid"); + return false; + } + if (disableNotificationInfo_.bundleList.empty()) { + ANS_LOGE("notificationDisable bundleList is empty"); + return false; + } + notificationDisable.SetDisabled(disableNotificationInfo_.disabled); + notificationDisable.SetBundleList(disableNotificationInfo_.bundleList); + return true; +} + +void NotificationPreferencesInfo::AddDisableNotificationInfo(const std::string &value) +{ + NotificationDisable notificationDisable; + notificationDisable.FromJson(value); + DisableNotificationInfo disableNotificationInfo; + if (notificationDisable.GetDisabled()) { + disableNotificationInfo_.disabled = 1; + } else { + disableNotificationInfo_.disabled = 0; + } + disableNotificationInfo_.bundleList = notificationDisable.GetBundleList(); +} } // namespace Notification } // namespace OHOS