diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index 08f56f6f892de7750ef318acd7376a2af5572404..40879919dea922de506e55d6476aa2087cc92ddd 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -1406,6 +1406,8 @@ public: */ ErrCode SetHashCodeRule(const uint32_t type) override; + bool IsNotificationOnceForcedEnable(sptr &bundleOption); + ErrCode AtomicServicePublish(const sptr &request); protected: diff --git a/services/ans/include/notification_app_privileges.h b/services/ans/include/notification_app_privileges.h index e22e9401b4e62a9edf7e3e9c1c1452224106dbdf..6cff4c768f81c45011f55bb62cd8327e2e50ea8d 100644 --- a/services/ans/include/notification_app_privileges.h +++ b/services/ans/include/notification_app_privileges.h @@ -31,14 +31,23 @@ public: bool IsReminderEnabled() const; bool IsDistributedReplyEnabled() const; bool IsNotificationForcedEnable() const; + bool IsNotificationOnceForcedEnable() const; private: - static constexpr int32_t NOTIFICATION_FORCED_ENABLE = 5; + static constexpr int32_t NOTIFICATION_ONCE_FORCED_ENABLE_SEQ = 6; + static constexpr int32_t NOTIFICATION_FORCED_ENABLE_SEQ = 5; static constexpr int32_t DISTRIBUTED_REPLY_SEQ = 4; static constexpr int32_t REMINDER_ENABLED_SEQ = 2; static constexpr int32_t BANNER_ENABLED_SEQ = 1; static constexpr int32_t LIVE_VIEW_ENABLED_SEQ = 0; + static constexpr char NOTIFICATION_ONCE_FORCED_ENABLE = '1'; + static constexpr char NOTIFICATION_FORCED_ENABLE = '1'; + static constexpr char DISTRIBUTED_REPLY_ENABLE = '1'; + static constexpr char REMINDER_ENABLE = '1'; + static constexpr char BANNER_ENABLE = '1'; + static constexpr char LIVE_VIEW_ENABLE = '1'; + uint32_t privileges_ = 0; }; } // namespace Notification diff --git a/services/ans/include/notification_config_parse.h b/services/ans/include/notification_config_parse.h index b5229c1fb0d999234ad61a3d07c0ce5c969b9251..cb0528cf1974417066d0c19a8aa4c2c4ab26631c 100644 --- a/services/ans/include/notification_config_parse.h +++ b/services/ans/include/notification_config_parse.h @@ -53,6 +53,7 @@ public: bool IsReminderEnabled(const std::string& bundleName) const; bool IsDistributedReplyEnabled(const std::string& bundleName) const; bool IsNotificationForcedEnable(const std::string& bundleName) const; + bool IsNotificationOnceForcedEnable(const std::string& bundleName) const; void GetFlowCtrlConfigFromCCM(FlowControlThreshold &threshold); bool GetSmartReminderEnableList(std::vector& deviceTypes); bool GetMirrorNotificationEnabledStatus(std::vector& deviceTypes); diff --git a/services/ans/include/notification_preferences.h b/services/ans/include/notification_preferences.h index fd9c38dc9cabaf7fc557b1c2e4be1f985459ca2d..38f7ab21603e83c44a8146bde0c2a07ee5bf137a 100644 --- a/services/ans/include/notification_preferences.h +++ b/services/ans/include/notification_preferences.h @@ -530,6 +530,10 @@ public: bool SetBundleRemoveFlag(const sptr &bundleOption, const NotificationConstant::SlotType &slotType, int32_t sourceType); + bool GetOnceForcedEnableFlag(const sptr &bundleOption); + + bool SetOnceForcedEnableFlag(const sptr &bundleOption); + void SetKioskModeStatus(bool isKioskMode); bool IsKioskMode(); diff --git a/services/ans/include/notification_preferences_database.h b/services/ans/include/notification_preferences_database.h index df6a250c5b9dbd01b9455451da39735f82c47265..fb3ef65b025af6f670b3efb91ee6ee69ebb74dd6 100644 --- a/services/ans/include/notification_preferences_database.h +++ b/services/ans/include/notification_preferences_database.h @@ -383,6 +383,11 @@ public: bool GetBundleRemoveFlag(const sptr &bundleOption, const NotificationConstant::SlotType &slotType, int32_t sourceType); + + bool GetOnceForcedEnableFlag(const sptr &bundleOption); + + bool SetOnceForcedEnableFlag(const sptr &bundleOption); + /** * @brief ParseBundleFromDistureDB * @param info bundle info. diff --git a/services/ans/src/common/notification_app_privileges.cpp b/services/ans/src/common/notification_app_privileges.cpp index f61994d685a041c4cbd1d28f7f2f7ca11a2a7ebf..485b0b2ca96847873b30ff338def7d92a40c146b 100644 --- a/services/ans/src/common/notification_app_privileges.cpp +++ b/services/ans/src/common/notification_app_privileges.cpp @@ -19,22 +19,32 @@ namespace OHOS { namespace Notification { NotificationAppPrivileges::NotificationAppPrivileges(const std::string &flagStr) { - if (flagStr.size() > LIVE_VIEW_ENABLED_SEQ && flagStr[LIVE_VIEW_ENABLED_SEQ] == '1') { + if (flagStr.size() > LIVE_VIEW_ENABLED_SEQ && + flagStr[LIVE_VIEW_ENABLED_SEQ] == LIVE_VIEW_ENABLE) { privileges_ |= 1 << LIVE_VIEW_ENABLED_SEQ; } - if (flagStr.size() > BANNER_ENABLED_SEQ && flagStr[BANNER_ENABLED_SEQ] == '1') { + if (flagStr.size() > BANNER_ENABLED_SEQ && + flagStr[BANNER_ENABLED_SEQ] == BANNER_ENABLE) { privileges_ |= 1 << BANNER_ENABLED_SEQ; } - if (flagStr.size() > REMINDER_ENABLED_SEQ && flagStr[REMINDER_ENABLED_SEQ] == '1') { + if (flagStr.size() > REMINDER_ENABLED_SEQ && + flagStr[REMINDER_ENABLED_SEQ] == REMINDER_ENABLE) { privileges_ |= 1 << REMINDER_ENABLED_SEQ; } - if (flagStr.size() > DISTRIBUTED_REPLY_SEQ && flagStr[DISTRIBUTED_REPLY_SEQ] == '1') { + if (flagStr.size() > DISTRIBUTED_REPLY_SEQ && + flagStr[DISTRIBUTED_REPLY_SEQ] == DISTRIBUTED_REPLY_ENABLE) { privileges_ |= 1 << DISTRIBUTED_REPLY_SEQ; } - if (flagStr.size() >= NOTIFICATION_FORCED_ENABLE && flagStr[NOTIFICATION_FORCED_ENABLE] == '1') { - privileges_ |= 1 << NOTIFICATION_FORCED_ENABLE; + if (flagStr.size() > NOTIFICATION_FORCED_ENABLE_SEQ && + flagStr[NOTIFICATION_FORCED_ENABLE_SEQ] == NOTIFICATION_FORCED_ENABLE) { + privileges_ |= 1 << NOTIFICATION_FORCED_ENABLE_SEQ; + } + if (flagStr.size() > NOTIFICATION_ONCE_FORCED_ENABLE_SEQ && + flagStr[NOTIFICATION_ONCE_FORCED_ENABLE_SEQ] == NOTIFICATION_ONCE_FORCED_ENABLE) { + privileges_ |= 1 << NOTIFICATION_ONCE_FORCED_ENABLE_SEQ; } } + bool NotificationAppPrivileges::IsLiveViewEnabled() const { if ((privileges_ & (1 << LIVE_VIEW_ENABLED_SEQ)) != 0) { @@ -66,7 +76,14 @@ bool NotificationAppPrivileges::IsDistributedReplyEnabled() const bool NotificationAppPrivileges::IsNotificationForcedEnable() const { - if ((privileges_ & (1 << NOTIFICATION_FORCED_ENABLE)) != 0) { + if ((privileges_ & (1 << NOTIFICATION_FORCED_ENABLE_SEQ)) != 0) { + return true; + } + return false; +} +bool NotificationAppPrivileges::IsNotificationOnceForcedEnable() const +{ + if ((privileges_ & (1 << NOTIFICATION_ONCE_FORCED_ENABLE_SEQ)) != 0) { return true; } return false; diff --git a/services/ans/src/common/notification_config_parse.cpp b/services/ans/src/common/notification_config_parse.cpp index 971829f6309e0e0109547e2b2c1b75c5e586997e..6db1d91e8d645db8ddc5709d735bcced13974b05 100644 --- a/services/ans/src/common/notification_config_parse.cpp +++ b/services/ans/src/common/notification_config_parse.cpp @@ -216,6 +216,15 @@ bool NotificationConfigParse::IsNotificationForcedEnable(const std::string& bund return appPrivileges->IsNotificationForcedEnable(); } +bool NotificationConfigParse::IsNotificationOnceForcedEnable(const std::string& bundleName) const +{ + std::shared_ptr appPrivileges = GetAppPrivileges(bundleName); + if (appPrivileges == nullptr) { + return false; + } + return appPrivileges->IsNotificationOnceForcedEnable(); +} + void NotificationConfigParse::GetFlowCtrlConfigFromCCM(FlowControlThreshold &threshold) { nlohmann::json root; diff --git a/services/ans/src/enable_manager/enable_manager.cpp b/services/ans/src/enable_manager/enable_manager.cpp index a5d5280535d6f9fcd0a0e0d0636e9d617f4e158a..8af82c18ed78937b151ce5d3eaa5270cd674428c 100644 --- a/services/ans/src/enable_manager/enable_manager.cpp +++ b/services/ans/src/enable_manager/enable_manager.cpp @@ -31,6 +31,7 @@ #include "notification_analytics_util.h" #include "os_account_manager_helper.h" #include "notification_extension_wrapper.h" +#include "notification_config_parse.h" namespace OHOS { namespace Notification { @@ -446,6 +447,19 @@ ErrCode AdvancedNotificationService::GetAllNotificationEnabledBundles( return result; } +bool AdvancedNotificationService::IsNotificationOnceForcedEnable(sptr &bundleOption) +{ + if (DelayedSingleton::GetInstance()-> + IsNotificationOnceForcedEnable(bundleOption->GetBundleName()) && + !NotificationPreferences::GetInstance()->GetOnceForcedEnableFlag(bundleOption)) { + NotificationPreferences::GetInstance()->SetOnceForcedEnableFlag(bundleOption); + ANS_LOGI("bundle %{public}s_%{public}d once forced enable.", + bundleOption->GetBundleName().c_str(), bundleOption->GetUid()); + return true; + } + return false; +} + ErrCode AdvancedNotificationService::SetNotificationsEnabledByUser(int32_t userId, bool enabled) { ANS_LOGD("%{public}s", __FUNCTION__); diff --git a/services/ans/src/notification_preferences.cpp b/services/ans/src/notification_preferences.cpp index 34c2705e80e506c7f1491f7914dd3b438c5d00c2..dbdb1ecdfa4cb7f948096dc0508cd962f484e7d6 100644 --- a/services/ans/src/notification_preferences.cpp +++ b/services/ans/src/notification_preferences.cpp @@ -346,6 +346,22 @@ ErrCode NotificationPreferences::SetNotificationSlotFlagsForBundle( return result; } +bool NotificationPreferences::GetOnceForcedEnableFlag(const sptr &bundleOption) +{ + if (preferncesDB_ == nullptr) { + return true; + } + return preferncesDB_->GetOnceForcedEnableFlag(bundleOption); +} + +bool NotificationPreferences::SetOnceForcedEnableFlag(const sptr &bundleOption) +{ + if (preferncesDB_ == nullptr) { + return false; + } + return preferncesDB_->SetOnceForcedEnableFlag(bundleOption); +} + ErrCode NotificationPreferences::IsShowBadge(const sptr &bundleOption, bool &enable) { if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) { diff --git a/services/ans/src/notification_preferences_database.cpp b/services/ans/src/notification_preferences_database.cpp index d57653161879a8de9876865bc338e3e442f3a5ea..ccef752631c5000418c9a0ae8440907b616ea560 100644 --- a/services/ans/src/notification_preferences_database.cpp +++ b/services/ans/src/notification_preferences_database.cpp @@ -244,6 +244,16 @@ const static std::string KEY_REMOVED_FLAG = "1"; const static std::string KEY_SECOND_REMOVED_FLAG = "2"; constexpr int32_t CLEAR_SLOT_FROM_AVSEESAION = 1; + +/** + * Force to turn on the notification switch once. + */ +const static std::string KEY_ONCE_FORCED_ENABLE_FLAG = "label_ans_once_forced_enable"; + +const static std::string KEY_NOT_FORCED_ENABLE = "1"; + +const static std::string KEY_FORCED_ENABLE_DONE = "2"; + /** * Indicates hashCode rule. */ @@ -3061,6 +3071,75 @@ bool NotificationPreferencesDatabase::GetBundleRemoveFlag(const sptr &bundleOption) +{ + std::string key = KEY_ONCE_FORCED_ENABLE_FLAG + KEY_UNDER_LINE + bundleOption->GetBundleName() + + std::to_string(bundleOption->GetUid()); + return key; +} + +bool NotificationPreferencesDatabase::SetOnceForcedEnableFlag(const sptr &bundleOption) +{ + if (bundleOption == nullptr) { + ANS_LOGE("null bundleOption"); + return false; + } + + int32_t userId = SUBSCRIBE_USER_INIT; + OHOS::AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId); + if (userId == SUBSCRIBE_USER_INIT) { + ANS_LOGE("Current user acquisition failed"); + return false; + } + + if (!CheckRdbStore()) { + ANS_LOGE("null RdbStore"); + return false; + } + std::string key = GetOnceForcedEnableFlagKey(bundleOption); + int32_t result = rdbDataManager_->InsertData(key, KEY_FORCED_ENABLE_DONE, userId); + return (result == NativeRdb::E_OK); +} + +bool NotificationPreferencesDatabase::GetOnceForcedEnableFlag(const sptr &bundleOption) +{ + if (bundleOption == nullptr) { + ANS_LOGE("null bundleOption"); + return true; + } + + int32_t userId = SUBSCRIBE_USER_INIT; + OHOS::AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId); + if (userId == SUBSCRIBE_USER_INIT) { + ANS_LOGW("Current user acquisition failed"); + return true; + } + + std::string key = GetOnceForcedEnableFlagKey(bundleOption); + bool existFlag = true; + std::string result; + GetValueFromDisturbeDB(key, userId, [&](const int32_t& status, std::string& value) { + switch (status) { + case NativeRdb::E_EMPTY_VALUES_BUCKET: { + existFlag = false; + break; + } + case NativeRdb::E_OK: { + result = value; + break; + } + default: + break; + } + }); + + ANS_LOGI("once forced enable flag %{public}s,%{public}s,%{public}d", key.c_str(), result.c_str(), existFlag); + if (!existFlag || result == KEY_NOT_FORCED_ENABLE) { + return false; + } + return true; +} + std::string NotificationPreferencesDatabase::GenerateHashCodeGenerate(const int32_t uid) { return std::string(KEY_HASH_CODE_RULE).append(KEY_MIDDLE_LINE).append(std::to_string(uid)); diff --git a/services/ans/src/permission_filter.cpp b/services/ans/src/permission_filter.cpp index e49836e9d4bb384cd9f2586045bcf7647c833d9d..0948176a6d5cfb013f7c68fd54731e095c847fe9 100644 --- a/services/ans/src/permission_filter.cpp +++ b/services/ans/src/permission_filter.cpp @@ -73,8 +73,9 @@ ErrCode PermissionFilter::OnPublish(const std::shared_ptr &r } if (result == ERR_OK) { - if (!enable && DelayedSingleton::GetInstance()-> - IsNotificationForcedEnable(record->bundleOption->GetBundleName())) { + if (!enable && (DelayedSingleton::GetInstance()-> + IsNotificationForcedEnable(record->bundleOption->GetBundleName()) || + AdvancedNotificationService::GetInstance()->IsNotificationOnceForcedEnable(record->bundleOption))) { AdvancedNotificationService::GetInstance()-> SetNotificationsEnabledForSpecialBundle("", record->bundleOption, true); return result; diff --git a/services/ans/test/unittest/notification_extension/notification_config_parse_mock.cpp b/services/ans/test/unittest/notification_extension/notification_config_parse_mock.cpp index b34baaacb51cb4f7fbef350c49130feea21facf1..48bbe3ada73991daf8e058f4f9694575eac2fa33 100644 --- a/services/ans/test/unittest/notification_extension/notification_config_parse_mock.cpp +++ b/services/ans/test/unittest/notification_extension/notification_config_parse_mock.cpp @@ -134,6 +134,11 @@ bool NotificationConfigParse::IsNotificationForcedEnable(const std::string& bund return false; } +bool NotificationConfigParse::IsNotificationOnceForcedEnable(const std::string& bundleName) const +{ + return false; +} + void NotificationConfigParse::GetFlowCtrlConfigFromCCM(FlowControlThreshold &threshold) { }