From bc85388cfbc7e76e1516c6ed65f602b875c8620a Mon Sep 17 00:00:00 2001 From: zero-cyc Date: Mon, 15 Aug 2022 16:10:08 +0800 Subject: [PATCH 1/2] =?UTF-8?q?kvstore=E6=8E=A5=E5=8F=A3=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zero-cyc Change-Id: I0d0234eed6c70470ca05fced10c754495bbf765a --- services/ans/include/preferences_constant.h | 2 +- .../src/notification_preferences_database.cpp | 23 ++++++++- .../include/distributed_database.h | 2 + .../distributed_preferences_database.h | 1 + .../distributed/src/distributed_database.cpp | 48 ++++++++++++------- .../src/distributed_notification_manager.cpp | 11 ++++- .../src/distributed_preferences_database.cpp | 45 +++++++++-------- .../src/distributed_screen_status_manager.cpp | 28 ++++++----- .../unittest/distributed_database_test.cpp | 2 + .../distributed_notification_manager_test.cpp | 3 +- ...distributed_screen_status_manager_test.cpp | 13 ++--- 11 files changed, 117 insertions(+), 61 deletions(-) diff --git a/services/ans/include/preferences_constant.h b/services/ans/include/preferences_constant.h index c99d818fd..fae1fd77e 100644 --- a/services/ans/include/preferences_constant.h +++ b/services/ans/include/preferences_constant.h @@ -21,7 +21,7 @@ namespace Notification { /** * Indicates distributed database app id. */ -constexpr char APP_ID[] = "advanced_notification_service"; +constexpr char APP_ID[] = "notification_service"; /** * Indicates distributed database store id. diff --git a/services/ans/src/notification_preferences_database.cpp b/services/ans/src/notification_preferences_database.cpp index 842216dbb..0d18ef611 100644 --- a/services/ans/src/notification_preferences_database.cpp +++ b/services/ans/src/notification_preferences_database.cpp @@ -203,6 +203,8 @@ const static std::string KEY_SLOT_ENABLE_BYPASS_DND = "enableBypassDnd"; */ const static std::string KEY_SLOT_ENABLED = "enabled"; +constexpr char KV_STORE_PATH[] = "/data/service/el1/public/database/notification_service"; + const std::map &, std::string &)>> NotificationPreferencesDatabase::slotMap_ = { @@ -338,7 +340,9 @@ DistributedKv::Status NotificationPreferencesDatabase::GetKvStore() .createIfMissing = true, .encrypt = false, .autoSync = false, + .area = DistributedKv::EL1, .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION, + .baseDir = KV_STORE_PATH }; auto status = dataManager_.GetSingleKvStore(options, appId_, storeId_, kvStorePtr_); if (status != DistributedKv::Status::SUCCESS) { @@ -392,6 +396,7 @@ bool NotificationPreferencesDatabase::PutSlotsToDisturbeDB( return false; } DistributedKv::Status status = kvStorePtr_->PutBatch(entries); + CloseKvStore(); return (status == DistributedKv::Status::SUCCESS); } @@ -423,6 +428,7 @@ bool NotificationPreferencesDatabase::PutGroupsToDisturbeDB( return false; } DistributedKv::Status status = kvStorePtr_->PutBatch(entries); + CloseKvStore(); return (status == DistributedKv::Status::SUCCESS); } @@ -455,6 +461,7 @@ bool NotificationPreferencesDatabase::PutBundlePropertyToDisturbeDB( break; } }); + CloseKvStore(); return result; } @@ -559,6 +566,7 @@ bool NotificationPreferencesDatabase::PutNotificationsEnabled(const int32_t &use DistributedKv::Key enableKey(typeKey); DistributedKv::Value enableValue(std::to_string(enabled)); DistributedKv::Status status = kvStorePtr_->Put(enableKey, enableValue); + CloseKvStore(); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("Store enable notification failed. %{public}d", status); return false; @@ -622,6 +630,7 @@ bool NotificationPreferencesDatabase::PutDoNotDisturbDate( }; DistributedKv::Status status = kvStorePtr_->PutBatch(entries); + CloseKvStore(); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("Store DoNotDisturbDate failed. %{public}d", status); return false; @@ -750,6 +759,7 @@ bool NotificationPreferencesDatabase::ParseFromDisturbeDB(NotificationPreference return false; } ParseBundleFromDistureDB(info, entries); + CloseKvStore(); return true; } @@ -760,7 +770,7 @@ bool NotificationPreferencesDatabase::RemoveAllDataFromDisturbeDB() ANS_LOGE("KvStore is nullptr."); return false; } - DistributedKv::Status status = dataManager_.DeleteKvStore(appId_, storeId_); + DistributedKv::Status status = dataManager_.DeleteKvStore(appId_, storeId_, KV_STORE_PATH); return (status == DistributedKv::Status::SUCCESS); } @@ -779,6 +789,7 @@ bool NotificationPreferencesDatabase::RemoveBundleFromDisturbeDB(const std::stri if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("Get Bundle Info failed."); + CloseKvStore(); return false; } @@ -790,6 +801,7 @@ bool NotificationPreferencesDatabase::RemoveBundleFromDisturbeDB(const std::stri DistributedKv::Key bundleDBKey(KEY_BUNDLE_LABEL + KEY_BUNDLE_NAME + KEY_UNDER_LINE + bundleKey); keys.push_back(bundleDBKey); status = kvStorePtr_->DeleteBatch(keys); + CloseKvStore(); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("delete bundle Info failed."); return false; @@ -818,6 +830,7 @@ bool NotificationPreferencesDatabase::RemoveSlotFromDisturbeDB( status = kvStorePtr_->GetEntries(DistributedKv::Key(GenerateSlotKey(bundleKey, slotType) + KEY_UNDER_LINE), slotentries); if (status != DistributedKv::Status::SUCCESS) { + CloseKvStore(); return false; } std::vector keys; @@ -826,6 +839,7 @@ bool NotificationPreferencesDatabase::RemoveSlotFromDisturbeDB( } status = kvStorePtr_->DeleteBatch(keys); + CloseKvStore(); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("delete bundle Info failed."); return false; @@ -852,6 +866,7 @@ bool NotificationPreferencesDatabase::RemoveAllSlotsFromDisturbeDB(const std::st std::vector slotsEntries; status = kvStorePtr_->GetEntries(DistributedKv::Key(GenerateSlotKey(bundleKey) + KEY_UNDER_LINE), slotsEntries); if (status != DistributedKv::Status::SUCCESS) { + CloseKvStore(); return false; } std::vector keys; @@ -860,6 +875,7 @@ bool NotificationPreferencesDatabase::RemoveAllSlotsFromDisturbeDB(const std::st } status = kvStorePtr_->DeleteBatch(keys); + CloseKvStore(); ANS_LOGD("%{public}s remove all slots status %{public}d", __FUNCTION__, status); return (status == DistributedKv::Status::SUCCESS); } @@ -887,11 +903,13 @@ bool NotificationPreferencesDatabase::RemoveGroupsFromDisturbeDB( for (auto iter : groupIds) { result = GetRemoveGroupKeysFromDisturbeDB(bundleKey, iter, keys); if (!result) { + CloseKvStore(); return result; } } DistributedKv::Status status = kvStorePtr_->DeleteBatch(keys); + CloseKvStore(); ANS_LOGD("%{public}s remove groups status %{public}d", __FUNCTION__, status); return (status == DistributedKv::Status::SUCCESS); } @@ -961,6 +979,7 @@ DistributedKv::Status NotificationPreferencesDatabase::PutBundlePropertyToDistur return DistributedKv::Status::ERROR; } DistributedKv::Status status = kvStorePtr_->Put(key, value); + CloseKvStore(); return status; } @@ -1650,6 +1669,7 @@ bool NotificationPreferencesDatabase::RemoveNotificationEnable(const int32_t use std::string(KEY_ENABLE_ALL_NOTIFICATION).append(KEY_UNDER_LINE).append(std::to_string(userId)); DistributedKv::Key enableKey(key); DistributedKv::Status status = kvStorePtr_->Delete(enableKey); + CloseKvStore(); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("delete bundle Info failed."); return false; @@ -1681,6 +1701,7 @@ bool NotificationPreferencesDatabase::RemoveDoNotDisturbDate(const int32_t userI }; DistributedKv::Status status = kvStorePtr_->DeleteBatch(keys); + CloseKvStore(); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("delete DoNotDisturb date failed."); return false; diff --git a/services/distributed/include/distributed_database.h b/services/distributed/include/distributed_database.h index 4bde7adab..dca37c7b1 100644 --- a/services/distributed/include/distributed_database.h +++ b/services/distributed/include/distributed_database.h @@ -123,6 +123,8 @@ public: */ bool RecreateDistributedDB(); + bool OnDeviceConnected(); + private: void GetKvDataManager(void); bool CheckKvDataManager(void); diff --git a/services/distributed/include/distributed_preferences_database.h b/services/distributed/include/distributed_preferences_database.h index 6248c6d0f..1fc06ba15 100644 --- a/services/distributed/include/distributed_preferences_database.h +++ b/services/distributed/include/distributed_preferences_database.h @@ -83,6 +83,7 @@ private: bool CheckKvDataManager(void); void GetKvStore(void); bool CheckKvStore(void); + void CloseKvStore(); private: std::mutex mutex_; diff --git a/services/distributed/src/distributed_database.cpp b/services/distributed/src/distributed_database.cpp index 8dccefc9b..23f3f80a5 100644 --- a/services/distributed/src/distributed_database.cpp +++ b/services/distributed/src/distributed_database.cpp @@ -20,8 +20,9 @@ namespace OHOS { namespace Notification { namespace { -const std::string APP_ID = "advanced_notification_service"; +const std::string APP_ID = "notification_service"; const std::string STORE_ID = "distributed_notification"; +constexpr char KV_STORE_PATH[] = "/data/service/el1/public/database/notification_service"; } // namespace DistributedDatabase::DistributedDatabase( @@ -29,7 +30,6 @@ DistributedDatabase::DistributedDatabase( : DistributedFlowControl(), databaseCb_(databaseCb), deviceCb_(deviceCb) { GetKvDataManager(); - GetKvStore(); } DistributedDatabase::~DistributedDatabase() @@ -66,12 +66,15 @@ void DistributedDatabase::GetKvStore(void) if (!CheckKvDataManager()) { return; } - - DistributedKv::Options options; - options.createIfMissing = true; - options.securityLevel = DistributedKv::SecurityLevel::S1; - options.autoSync = true; - options.kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION; + DistributedKv::Options options { + .createIfMissing = true, + .securityLevel = DistributedKv::SecurityLevel::S1, + .autoSync = true, + .encrypt = false, + .area = DistributedKv::EL1, + .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION, + .baseDir = KV_STORE_PATH + }; DistributedKv::AppId appId = {.appId = APP_ID}; DistributedKv::StoreId storeId = {.storeId = STORE_ID}; DistributedKv::Status status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_); @@ -106,11 +109,21 @@ bool DistributedDatabase::CheckKvStore(void) return true; } +bool DistributedDatabase::OnDeviceConnected() +{ + std::lock_guard lock(mutex_); + if (!CheckKvStore()) { + return false; + } + return true; +} + bool DistributedDatabase::PutToDistributedDB(const std::string &key, const std::string &value) { std::lock_guard lock(mutex_); - if (!CheckKvStore()) { + if (kvStore_ == nullptr) { + ANS_LOGE("kvStore is nullptr."); return false; } @@ -134,7 +147,8 @@ bool DistributedDatabase::GetFromDistributedDB(const std::string &key, std::stri { std::lock_guard lock(mutex_); - if (!CheckKvStore()) { + if (kvStore_ == nullptr) { + ANS_LOGE("kvStore is nullptr."); return false; } @@ -160,7 +174,8 @@ bool DistributedDatabase::GetEntriesFromDistributedDB(const std::string &prefixK { std::lock_guard lock(mutex_); - if (!CheckKvStore()) { + if (kvStore_ == nullptr) { + ANS_LOGE("kvStore is nullptr."); return false; } @@ -183,7 +198,8 @@ bool DistributedDatabase::DeleteToDistributedDB(const std::string &key) { std::lock_guard lock(mutex_); - if (!CheckKvStore()) { + if (kvStore_ == nullptr) { + ANS_LOGE("kvStore is nullptr."); return false; } @@ -206,7 +222,8 @@ bool DistributedDatabase::ClearDataByDevice(const std::string &deviceId) { std::lock_guard lock(mutex_); - if (!CheckKvStore()) { + if (kvStore_ == nullptr) { + ANS_LOGE("kvStore is nullptr."); return false; } @@ -305,18 +322,15 @@ bool DistributedDatabase::RecreateDistributedDB() ANS_LOGE("KvManager flow control."); return false; } - kvStore_.reset(); - DistributedKv::AppId appId = {.appId = APP_ID}; DistributedKv::StoreId storeId = {.storeId = STORE_ID}; - DistributedKv::Status status = kvDataManager_->DeleteKvStore(appId, storeId); + DistributedKv::Status status = kvDataManager_->DeleteKvStore(appId, storeId, KV_STORE_PATH); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvDataManager DeleteKvStore() failed ret = 0x%{public}x", status); return false; } - GetKvStore(); return true; } } // namespace Notification diff --git a/services/distributed/src/distributed_notification_manager.cpp b/services/distributed/src/distributed_notification_manager.cpp index 5aa3e53ad..460405aab 100644 --- a/services/distributed/src/distributed_notification_manager.cpp +++ b/services/distributed/src/distributed_notification_manager.cpp @@ -202,8 +202,15 @@ void DistributedNotificationManager::OnDatabaseDelete( void DistributedNotificationManager::OnDeviceConnected(const std::string &deviceId) { ANS_LOGD("%{public}s", __FUNCTION__); - handler_->PostTask(std::bind([=]() {})); - return; + handler_->PostTask(std::bind([=]() { + if (database_ == nullptr) { + ANS_LOGE("OnDeviceConnected failed: database is null"); + return; + } + if (!database_->OnDeviceConnected()) { + ANS_LOGE("OnDeviceConnected failed."); + } + })); } void DistributedNotificationManager::OnDeviceDisconnected(const std::string &deviceId) diff --git a/services/distributed/src/distributed_preferences_database.cpp b/services/distributed/src/distributed_preferences_database.cpp index 535bcda40..4ee3a39c5 100644 --- a/services/distributed/src/distributed_preferences_database.cpp +++ b/services/distributed/src/distributed_preferences_database.cpp @@ -20,14 +20,14 @@ namespace OHOS { namespace Notification { namespace { -const std::string APP_ID = "advanced_notification_service"; +const std::string APP_ID = "notification_service"; const std::string STORE_ID = "distributed_preferences"; +constexpr char KV_STORE_PATH[] = "/data/service/el1/public/database/notification_service"; } // namespace DistributedPreferencesDatabase::DistributedPreferencesDatabase() : DistributedFlowControl() { GetKvDataManager(); - GetKvStore(); } DistributedPreferencesDatabase::~DistributedPreferencesDatabase() @@ -57,15 +57,16 @@ void DistributedPreferencesDatabase::GetKvStore(void) return; } - DistributedKv::Status status; - DistributedKv::Options options; - options.createIfMissing = true; - options.autoSync = false; - options.kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION; - + DistributedKv::Options options = { + .createIfMissing = true, + .autoSync = false, + .area = DistributedKv::EL1, + .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION, + .baseDir = KV_STORE_PATH + }; DistributedKv::AppId appId = {.appId = APP_ID}; DistributedKv::StoreId storeId = {.storeId = STORE_ID}; - status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_); + DistributedKv::Status status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvDataManager GetSingleKvStore failed ret = 0x%{public}x", status); kvStore_.reset(); @@ -96,12 +97,14 @@ bool DistributedPreferencesDatabase::PutToDistributedDB(const std::string &key, if (!KvStoreFlowControl()) { ANS_LOGE("kvStore flow control."); + CloseKvStore(); return false; } DistributedKv::Key kvStoreKey(key); DistributedKv::Value kvStoreValue(value); DistributedKv::Status status = kvStore_->Put(kvStoreKey, kvStoreValue); + CloseKvStore(); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvStore Put() failed ret = 0x%{public}x", status); return false; @@ -113,26 +116,24 @@ bool DistributedPreferencesDatabase::PutToDistributedDB(const std::string &key, bool DistributedPreferencesDatabase::GetFromDistributedDB(const std::string &key, std::string &value) { std::lock_guard lock(mutex_); - if (!CheckKvStore()) { return false; } if (!KvStoreFlowControl()) { ANS_LOGE("kvStore flow control."); + CloseKvStore(); return false; } - DistributedKv::Key kvStoreKey(key); DistributedKv::Value kvStoreValue; DistributedKv::Status status = kvStore_->Get(kvStoreKey, kvStoreValue); + CloseKvStore(); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvStore Get() failed ret = 0x%{public}x", status); return false; } - value = kvStoreValue.ToString(); - return true; } @@ -140,23 +141,21 @@ bool DistributedPreferencesDatabase::GetEntriesFromDistributedDB( const std::string &prefixKey, std::vector &entries) { std::lock_guard lock(mutex_); - if (!CheckKvStore()) { return false; } - if (!KvStoreFlowControl()) { ANS_LOGE("kvStore flow control."); + CloseKvStore(); return false; } - DistributedKv::Key kvStoreKey(prefixKey); DistributedKv::Status status = kvStore_->GetEntries(kvStoreKey, entries); + CloseKvStore(); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvStore GetEntries() failed ret = 0x%{public}x", status); return false; } - return true; } @@ -167,15 +166,15 @@ bool DistributedPreferencesDatabase::DeleteToDistributedDB(const std::string &ke if (!CheckKvStore()) { return false; } - if (!KvStoreFlowControl()) { ANS_LOGE("kvStore flow control."); + CloseKvStore(); return false; } - DistributedKv::Key kvStoreKey(key); DistributedKv::Value kvStoreValue; DistributedKv::Status status = kvStore_->Delete(kvStoreKey); + CloseKvStore(); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvStore Delete() failed ret = 0x%{public}x", status); return false; @@ -204,12 +203,18 @@ bool DistributedPreferencesDatabase::ClearDatabase(void) return false; } - status = kvDataManager_->DeleteKvStore(appId, storeId); + status = kvDataManager_->DeleteKvStore(appId, storeId, KV_STORE_PATH); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvDataManager DeleteKvStore() failed ret = 0x%{public}x", status); return false; } return true; } + +void DistributedPreferencesDatabase::CloseKvStore() +{ + DistributedKv::AppId appId = {.appId = APP_ID}; + kvDataManager_->CloseKvStore(appId, kvStore_); +} } // namespace Notification } // namespace OHOS \ No newline at end of file diff --git a/services/distributed/src/distributed_screen_status_manager.cpp b/services/distributed/src/distributed_screen_status_manager.cpp index dfd721e41..d8b0bd5bc 100644 --- a/services/distributed/src/distributed_screen_status_manager.cpp +++ b/services/distributed/src/distributed_screen_status_manager.cpp @@ -21,12 +21,13 @@ namespace OHOS { namespace Notification { namespace { -const std::string APP_ID = "advanced_notification_service"; +const std::string APP_ID = "notification_service"; const std::string STORE_ID = "distributed_screen_status"; const std::string DELIMITER = "|"; const std::string SCREEN_STATUS_LABEL = "screen_status"; const std::string SCREEN_STATUS_VALUE_ON = "on"; const std::string SCREEN_STATUS_VALUE_OFF = "off"; +constexpr char KV_STORE_PATH[] = "/data/service/el1/public/database/notification_service"; } // namespace DistributedScreenStatusManager::DistributedScreenStatusManager() : DistributedFlowControl() @@ -37,7 +38,6 @@ DistributedScreenStatusManager::DistributedScreenStatusManager() : DistributedFl }; deviceCb_ = std::make_shared(callback); GetKvDataManager(); - GetKvStore(); } DistributedScreenStatusManager::~DistributedScreenStatusManager() @@ -46,6 +46,8 @@ DistributedScreenStatusManager::~DistributedScreenStatusManager() void DistributedScreenStatusManager::OnDeviceConnected(const std::string &deviceId) { ANS_LOGI("deviceId:%{public}s", deviceId.c_str()); + std::lock_guard lock(mutex_); + CheckKvStore(); } void DistributedScreenStatusManager::OnDeviceDisconnected(const std::string &deviceId) @@ -72,7 +74,7 @@ void DistributedScreenStatusManager::OnDeviceDisconnected(const std::string &dev DistributedKv::AppId appId = {.appId = APP_ID}; DistributedKv::StoreId storeId = {.storeId = STORE_ID}; - kvDataManager_->DeleteKvStore(appId, storeId); + kvDataManager_->DeleteKvStore(appId, storeId, KV_STORE_PATH); if (!CheckKvStore()) { return; @@ -112,16 +114,16 @@ void DistributedScreenStatusManager::GetKvStore(void) if (!CheckKvDataManager()) { return; } - - DistributedKv::Status status; - DistributedKv::Options options; - options.createIfMissing = true; - options.autoSync = true; - options.kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION; - + DistributedKv::Options options = { + .createIfMissing = true, + .autoSync = true, + .area = DistributedKv::EL1, + .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION, + .baseDir = KV_STORE_PATH + }; DistributedKv::AppId appId = {.appId = APP_ID}; DistributedKv::StoreId storeId = {.storeId = STORE_ID}; - status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_); + DistributedKv::Status status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvDataManager GetSingleKvStore failed ret = 0x%{public}x", status); kvStore_.reset(); @@ -153,7 +155,7 @@ std::string DistributedScreenStatusManager::GenerateDistributedKey(const std::st ErrCode DistributedScreenStatusManager::CheckRemoteDevicesIsUsing(bool &isUsing) { std::lock_guard lock(mutex_); - if (!CheckKvDataManager() || !CheckKvStore()) { + if (!CheckKvDataManager() || kvStore_ == nullptr) { return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; } @@ -204,7 +206,7 @@ ErrCode DistributedScreenStatusManager::SetLocalScreenStatus(bool screenOn) std::lock_guard lock(mutex_); ANS_LOGI("%{public}s, screenOn:%{public}s", __FUNCTION__, screenOn ? "true" : "false"); localScreenOn_ = screenOn; - if (!CheckKvStore()) { + if (kvStore_ == nullptr) { return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; } diff --git a/services/distributed/test/unittest/distributed_database_test.cpp b/services/distributed/test/unittest/distributed_database_test.cpp index 329297a73..c6c6dcfcb 100644 --- a/services/distributed/test/unittest/distributed_database_test.cpp +++ b/services/distributed/test/unittest/distributed_database_test.cpp @@ -17,6 +17,7 @@ #include "gtest/gtest.h" +#define private public #include "distributed_database.h" using namespace testing::ext; @@ -67,6 +68,7 @@ void DistributedDatabaseTest::SetUp() databaseCallback_ = std::make_shared(databaseCallback); deviceCallback_ = std::make_shared(deviceCallback); database_ = std::make_shared(databaseCallback_, deviceCallback_); + database_->OnDeviceConnected(); } void DistributedDatabaseTest::TearDown() diff --git a/services/distributed/test/unittest/distributed_notification_manager_test.cpp b/services/distributed/test/unittest/distributed_notification_manager_test.cpp index e4ab49cf0..70d832fb1 100644 --- a/services/distributed/test/unittest/distributed_notification_manager_test.cpp +++ b/services/distributed/test/unittest/distributed_notification_manager_test.cpp @@ -16,7 +16,7 @@ #include #include "gtest/gtest.h" - +#define private public #include "distributed_notification_manager.h" using namespace testing::ext; @@ -42,6 +42,7 @@ protected: void DistributedNotificationManagerTest::SetUp() { distributedManager_ = DistributedNotificationManager::GetInstance(); + distributedManager_->OnDeviceConnected("test"); } void DistributedNotificationManagerTest::TearDown() diff --git a/services/distributed/test/unittest/distributed_screen_status_manager_test.cpp b/services/distributed/test/unittest/distributed_screen_status_manager_test.cpp index e1b68b00b..5c4b85d63 100644 --- a/services/distributed/test/unittest/distributed_screen_status_manager_test.cpp +++ b/services/distributed/test/unittest/distributed_screen_status_manager_test.cpp @@ -16,7 +16,7 @@ #include #include "gtest/gtest.h" - +#define private public #include "distributed_screen_status_manager.h" using namespace testing::ext; @@ -27,17 +27,18 @@ public: void SetUp() override; void TearDown() override; protected: - std::shared_ptr DistributedScreenStatusManager_; + std::shared_ptr distributedScreenStatusManager_; }; void DistributedScreenStatusManagerTest::SetUp() { - DistributedScreenStatusManager_ = DistributedScreenStatusManager::GetInstance(); + distributedScreenStatusManager_ = DistributedScreenStatusManager::GetInstance(); + distributedScreenStatusManager_->OnDeviceConnected("test"); } void DistributedScreenStatusManagerTest::TearDown() { - DistributedScreenStatusManager_ = nullptr; + distributedScreenStatusManager_ = nullptr; DistributedScreenStatusManager::DestroyInstance(); } @@ -50,7 +51,7 @@ HWTEST_F(DistributedScreenStatusManagerTest, CheckRemoteDevicesIsUsing_00100, Fu { bool isUsing = true; - EXPECT_EQ(DistributedScreenStatusManager_->CheckRemoteDevicesIsUsing(isUsing), ERR_OK); + EXPECT_EQ(distributedScreenStatusManager_->CheckRemoteDevicesIsUsing(isUsing), ERR_OK); } /** @@ -62,7 +63,7 @@ HWTEST_F(DistributedScreenStatusManagerTest, SetLocalScreenStatus_00100, Functio { bool screenOn = false; - EXPECT_EQ(DistributedScreenStatusManager_->SetLocalScreenStatus(screenOn), ERR_OK); + EXPECT_EQ(distributedScreenStatusManager_->SetLocalScreenStatus(screenOn), ERR_OK); } } // namespace Notification } // namespace OHOS \ No newline at end of file -- Gitee From 41fbc3b9131b40f32456fc2c49005fd1740c8ceb Mon Sep 17 00:00:00 2001 From: zero-cyc Date: Mon, 15 Aug 2022 21:21:04 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=88=A0=E9=99=A4slotgroup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zero-cyc Change-Id: I843d8089640cd4cea8d68fdee725d5226eaaebfb --- frameworks/ans/BUILD.gn | 1 - frameworks/ans/src/notification_helper.cpp | 31 -- frameworks/ans/src/notification_slot.cpp | 17 - .../ans/src/notification_slot_group.cpp | 174 --------- frameworks/core/BUILD.gn | 1 - .../core/common/include/ans_const_define.h | 1 - .../core/include/ans_manager_interface.h | 47 --- frameworks/core/include/ans_manager_proxy.h | 46 --- frameworks/core/include/ans_manager_stub.h | 51 --- frameworks/core/include/ans_notification.h | 60 --- frameworks/core/src/ans_manager_proxy.cpp | 191 ---------- frameworks/core/src/ans_manager_stub.cpp | 134 ------- frameworks/core/src/ans_notification.cpp | 73 ---- .../test/moduletest/ans_fw_module_test.cpp | 5 - .../ans_innerkits_module_slot_test.cpp | 112 ------ interfaces/inner_api/notification_helper.h | 61 --- interfaces/inner_api/notification_slot.h | 20 - .../inner_api/notification_slot_group.h | 145 -------- .../include/advanced_notification_service.h | 46 --- .../ans/include/notification_preferences.h | 67 ---- .../notification_preferences_database.h | 33 -- .../include/notification_preferences_info.h | 48 --- .../ans/src/advanced_notification_service.cpp | 99 ----- services/ans/src/notification_preferences.cpp | 208 ----------- .../src/notification_preferences_database.cpp | 236 +----------- .../ans/src/notification_preferences_info.cpp | 82 ---- .../advanced_notification_service_test.cpp | 169 --------- ...notification_preferences_database_test.cpp | 92 ----- .../notification_preferences_test.cpp | 351 ------------------ .../distributed/src/distributed_database.cpp | 7 +- services/test/moduletest/ans_module_test.cpp | 34 -- .../notification_service_test.cpp | 46 --- test/fuzztest/BUILD.gn | 3 - .../addnotificationslotgroups_fuzzer/BUILD.gn | 53 --- .../addnotificationslotgroups_fuzzer.cpp | 46 --- .../addnotificationslotgroups_fuzzer.h | 29 -- .../corpus/init | 13 - .../project.xml | 25 -- .../addnotificationslots_fuzzer.cpp | 2 - .../getnotificationslotgroup_fuzzer/BUILD.gn | 53 --- .../corpus/init | 13 - .../getnotificationslotgroup_fuzzer.cpp | 35 -- .../getnotificationslotgroup_fuzzer.h | 21 -- .../project.xml | 25 -- .../BUILD.gn | 53 --- .../corpus/init | 13 - .../project.xml | 25 -- .../removenotificationslotgroup_fuzzer.cpp | 34 -- .../removenotificationslotgroup_fuzzer.h | 21 -- test/resource/ansSTSlotGroupTest/BUILD.gn | 59 --- test/resource/ansSTSlotGroupTest/config.json | 41 -- .../include/ans_slotgroup_test.h | 49 --- .../src/ans_slotgroup_test.cpp | 163 -------- .../ansSlotGroupHap/AnsSTSlotGroupTest.hap | Bin 110986 -> 0 bytes .../include/notificationgetparam.h | 3 - .../notificationfuzzconfig/config.json | 6 - .../src/notificationfuzztestmanager.cpp | 25 -- .../src/notificationgetparam.cpp | 26 -- 58 files changed, 4 insertions(+), 3520 deletions(-) delete mode 100644 frameworks/ans/src/notification_slot_group.cpp delete mode 100644 interfaces/inner_api/notification_slot_group.h delete mode 100644 test/fuzztest/addnotificationslotgroups_fuzzer/BUILD.gn delete mode 100644 test/fuzztest/addnotificationslotgroups_fuzzer/addnotificationslotgroups_fuzzer.cpp delete mode 100644 test/fuzztest/addnotificationslotgroups_fuzzer/addnotificationslotgroups_fuzzer.h delete mode 100644 test/fuzztest/addnotificationslotgroups_fuzzer/corpus/init delete mode 100644 test/fuzztest/addnotificationslotgroups_fuzzer/project.xml delete mode 100644 test/fuzztest/getnotificationslotgroup_fuzzer/BUILD.gn delete mode 100644 test/fuzztest/getnotificationslotgroup_fuzzer/corpus/init delete mode 100644 test/fuzztest/getnotificationslotgroup_fuzzer/getnotificationslotgroup_fuzzer.cpp delete mode 100644 test/fuzztest/getnotificationslotgroup_fuzzer/getnotificationslotgroup_fuzzer.h delete mode 100644 test/fuzztest/getnotificationslotgroup_fuzzer/project.xml delete mode 100644 test/fuzztest/removenotificationslotgroup_fuzzer/BUILD.gn delete mode 100644 test/fuzztest/removenotificationslotgroup_fuzzer/corpus/init delete mode 100644 test/fuzztest/removenotificationslotgroup_fuzzer/project.xml delete mode 100644 test/fuzztest/removenotificationslotgroup_fuzzer/removenotificationslotgroup_fuzzer.cpp delete mode 100644 test/fuzztest/removenotificationslotgroup_fuzzer/removenotificationslotgroup_fuzzer.h delete mode 100644 test/resource/ansSTSlotGroupTest/BUILD.gn delete mode 100644 test/resource/ansSTSlotGroupTest/config.json delete mode 100644 test/resource/ansSTSlotGroupTest/include/ans_slotgroup_test.h delete mode 100644 test/resource/ansSTSlotGroupTest/src/ans_slotgroup_test.cpp delete mode 100644 test/resource/ansSlotGroupHap/AnsSTSlotGroupTest.hap diff --git a/frameworks/ans/BUILD.gn b/frameworks/ans/BUILD.gn index 3e07cf3f5..8f04ffc13 100644 --- a/frameworks/ans/BUILD.gn +++ b/frameworks/ans/BUILD.gn @@ -62,7 +62,6 @@ ohos_shared_library("ans_innerkits") { "src/notification_picture_content.cpp", "src/notification_request.cpp", "src/notification_slot.cpp", - "src/notification_slot_group.cpp", "src/notification_sorting.cpp", "src/notification_sorting_map.cpp", "src/notification_subscribe_info.cpp", diff --git a/frameworks/ans/src/notification_helper.cpp b/frameworks/ans/src/notification_helper.cpp index 330879179..fb3053653 100644 --- a/frameworks/ans/src/notification_helper.cpp +++ b/frameworks/ans/src/notification_helper.cpp @@ -55,31 +55,6 @@ ErrCode NotificationHelper::GetNotificationSlots(std::vector::GetInstance()->GetNotificationSlots(slots); } -ErrCode NotificationHelper::AddNotificationSlotGroup(const NotificationSlotGroup &slotGroup) -{ - return DelayedSingleton::GetInstance()->AddNotificationSlotGroup(slotGroup); -} - -ErrCode NotificationHelper::AddNotificationSlotGroups(const std::vector &slotGroups) -{ - return DelayedSingleton::GetInstance()->AddNotificationSlotGroups(slotGroups); -} - -ErrCode NotificationHelper::RemoveNotificationSlotGroup(const std::string &slotGroupId) -{ - return DelayedSingleton::GetInstance()->RemoveNotificationSlotGroup(slotGroupId); -} - -ErrCode NotificationHelper::GetNotificationSlotGroup(const std::string &groupId, sptr &group) -{ - return DelayedSingleton::GetInstance()->GetNotificationSlotGroup(groupId, group); -} - -ErrCode NotificationHelper::GetNotificationSlotGroups(std::vector> &groups) -{ - return DelayedSingleton::GetInstance()->GetNotificationSlotGroups(groups); -} - ErrCode NotificationHelper::GetNotificationSlotNumAsBundle(const NotificationBundleOption &bundleOption, uint64_t &num) { return DelayedSingleton::GetInstance()->GetNotificationSlotNumAsBundle(bundleOption, num); @@ -259,12 +234,6 @@ ErrCode NotificationHelper::UpdateNotificationSlots( return DelayedSingleton::GetInstance()->UpdateNotificationSlots(bundleOption, slots); } -ErrCode NotificationHelper::UpdateNotificationSlotGroups( - const NotificationBundleOption &bundleOption, const std::vector> &groups) -{ - return DelayedSingleton::GetInstance()->UpdateNotificationSlotGroups(bundleOption, groups); -} - ErrCode NotificationHelper::GetAllActiveNotifications(std::vector> ¬ification) { return DelayedSingleton::GetInstance()->GetAllActiveNotifications(notification); diff --git a/frameworks/ans/src/notification_slot.cpp b/frameworks/ans/src/notification_slot.cpp index e41616918..3bef9e5d4 100644 --- a/frameworks/ans/src/notification_slot.cpp +++ b/frameworks/ans/src/notification_slot.cpp @@ -149,16 +149,6 @@ void NotificationSlot::SetName(const std::string &name) name_ = TruncateString(name); } -std::string NotificationSlot::GetSlotGroup() const -{ - return groupId_; -} - -void NotificationSlot::SetSlotGroup(const std::string &groupId) -{ - groupId_ = groupId; -} - Uri NotificationSlot::GetSound() const { return sound_; @@ -226,7 +216,6 @@ std::string NotificationSlot::Dump() const ", isVibrate = " + (isVibrationEnabled_ ? "true" : "false") + ", vibration = " + MergeVectorToString(vibrationValues_) + ", isShowBadge = " + (isShowBadge_ ? "true" : "false") + - ", groupId = " + groupId_ + ", enabled = " + (enabled_ ? "true" : "false") + " }"; } @@ -288,11 +277,6 @@ bool NotificationSlot::Marshalling(Parcel &parcel) const return false; } - if (!parcel.WriteString(groupId_)) { - ANS_LOGE("Failed to write groupId"); - return false; - } - if (sound_.ToString().empty()) { if (!parcel.WriteInt32(VALUE_NULL)) { ANS_LOGE("Failed to write int"); @@ -335,7 +319,6 @@ bool NotificationSlot::ReadFromParcel(Parcel &parcel) level_ = static_cast(parcel.ReadInt32()); type_ = static_cast(parcel.ReadInt32()); lockScreenVisibleness_ = static_cast(parcel.ReadInt32()); - groupId_ = parcel.ReadString(); int32_t empty = VALUE_NULL; if (!parcel.ReadInt32(empty)) { diff --git a/frameworks/ans/src/notification_slot_group.cpp b/frameworks/ans/src/notification_slot_group.cpp deleted file mode 100644 index cb63278eb..000000000 --- a/frameworks/ans/src/notification_slot_group.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2021 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_slot_group.h" -#include "ans_log_wrapper.h" -#include "string_ex.h" - -namespace OHOS { -namespace Notification { -const int32_t MAX_TEXT_LENGTH = 1000; -const std::string LINE_SEPARATOR = "\n"; - -NotificationSlotGroup::NotificationSlotGroup() -{} - -NotificationSlotGroup::NotificationSlotGroup(const std::string &id, const std::string &name) : id_(id), name_(name) -{ - id_ = TruncateString(id); - name_ = TruncateString(name); -} - -NotificationSlotGroup::~NotificationSlotGroup() -{} - -std::string NotificationSlotGroup::GetDescription() const -{ - return description_; -} - -std::string NotificationSlotGroup::GetId() const -{ - return id_; -} - -std::string NotificationSlotGroup::GetName() const -{ - return name_; -} - -void NotificationSlotGroup::SetSlots(const std::vector &slots) -{ - slots_ = slots; -} - -std::vector NotificationSlotGroup::GetSlots() const -{ - return slots_; -} - -bool NotificationSlotGroup::IsDisabled() const -{ - return isDisabled_; -} - -void NotificationSlotGroup::SetDescription(const std::string &description) -{ - description_ = TruncateString(description); -} - -std::string NotificationSlotGroup::Dump() const -{ - std::string contents; - for (auto it = slots_.begin(); it != slots_.end(); ++it) { - contents += it->Dump(); - if (it != slots_.end() - 1) { - contents += ","; - } - } - return "NotificationSlotGroup{ " - "id = " + id_ + - ", name = " + name_ + - ", description = " + description_ + - ", slots = " + contents + - ", isDisabled = " + (isDisabled_ ? "true" : "false") + - " }"; -} - -bool NotificationSlotGroup::Marshalling(Parcel &parcel) const -{ - if (!parcel.WriteString(id_)) { - ANS_LOGE("Failed to write id"); - return false; - } - - if (!parcel.WriteString(name_)) { - ANS_LOGE("Failed to write name"); - return false; - } - - if (!parcel.WriteString(description_)) { - ANS_LOGE("Failed to write description"); - return false; - } - - if (slots_.empty()) { - if (!parcel.WriteUint64(0)) { - ANS_LOGE("Failed to write the size of slots"); - return false; - } - } else { - if (!parcel.WriteUint64(slots_.size())) { - ANS_LOGE("Failed to write the size of slots"); - return false; - } - for (size_t it = 0; it < slots_.size(); ++it) { - if (!parcel.WriteParcelable(&slots_.at(it))) { - ANS_LOGE("Failed to write slots"); - return false; - } - } - } - - if (!parcel.WriteBool(isDisabled_)) { - ANS_LOGE("Failed to write isDisabled"); - return false; - } - - return true; -} - -bool NotificationSlotGroup::ReadFromParcel(Parcel &parcel) -{ - id_ = parcel.ReadString(); - name_ = parcel.ReadString(); - description_ = parcel.ReadString(); - uint64_t size = parcel.ReadUint64(); - if (size) { - for (uint64_t i = 0; i < size; ++i) { - auto slot = parcel.ReadParcelable(); - if (slot == nullptr) { - ANS_LOGE("Failed to read slot"); - return false; - } - slots_.emplace_back(*slot); - } - } - isDisabled_ = parcel.ReadBool(); - return true; -} - -NotificationSlotGroup *NotificationSlotGroup::Unmarshalling(Parcel &parcel) -{ - NotificationSlotGroup *notificationSlotGroup = new (std::nothrow) NotificationSlotGroup(); - - if (notificationSlotGroup && !notificationSlotGroup->ReadFromParcel(parcel)) { - delete notificationSlotGroup; - notificationSlotGroup = nullptr; - } - - return notificationSlotGroup; -} - -std::string NotificationSlotGroup::TruncateString(const std::string &inPutString) -{ - std::string temp = inPutString; - if (inPutString.length() > MAX_TEXT_LENGTH) { - temp = inPutString.substr(0, MAX_TEXT_LENGTH); - } - return temp; -} -} // namespace Notification -} // namespace OHOS \ No newline at end of file diff --git a/frameworks/core/BUILD.gn b/frameworks/core/BUILD.gn index 184dadf0c..77a95d3d8 100644 --- a/frameworks/core/BUILD.gn +++ b/frameworks/core/BUILD.gn @@ -60,7 +60,6 @@ ohos_shared_library("ans_core") { "${frameworks_module_ans_path}/src/notification_picture_content.cpp", "${frameworks_module_ans_path}/src/notification_request.cpp", "${frameworks_module_ans_path}/src/notification_slot.cpp", - "${frameworks_module_ans_path}/src/notification_slot_group.cpp", "${frameworks_module_ans_path}/src/notification_sorting.cpp", "${frameworks_module_ans_path}/src/notification_sorting_map.cpp", "${frameworks_module_ans_path}/src/notification_subscribe_info.cpp", diff --git a/frameworks/core/common/include/ans_const_define.h b/frameworks/core/common/include/ans_const_define.h index eb286069d..66454a4a0 100644 --- a/frameworks/core/common/include/ans_const_define.h +++ b/frameworks/core/common/include/ans_const_define.h @@ -29,7 +29,6 @@ constexpr size_t MAX_ACTIVE_NUM = 1000; constexpr uint32_t MAX_ACTIVE_NUM_PERAPP = 100; constexpr uint32_t MAX_ACTIVE_NUM_PERSECOND = 10; constexpr size_t MAX_SLOT_NUM = 5; -constexpr size_t MAX_SLOT_GROUP_NUM = 4; constexpr uint32_t MAX_ICON_SIZE = 50 * 1024; constexpr uint32_t MAX_PICTURE_SIZE = 2 * 1024 * 1024; constexpr bool SUPPORT_DO_NOT_DISTRUB = true; diff --git a/frameworks/core/include/ans_manager_interface.h b/frameworks/core/include/ans_manager_interface.h index 376489c55..afd8a3fd1 100644 --- a/frameworks/core/include/ans_manager_interface.h +++ b/frameworks/core/include/ans_manager_interface.h @@ -26,7 +26,6 @@ #include "notification_do_not_disturb_date.h" #include "notification_request.h" #include "notification_slot.h" -#include "notification_slot_group.h" #include "notification_subscribe_info.h" #include "reminder_request.h" @@ -126,16 +125,6 @@ public: */ virtual ErrCode RemoveAllSlots() = 0; - /** - * @brief Creates multiple notification slot groups. - * @note The precautions for using this method are similar to those for - * AddNotificationSlotGroup(NotificationSlotGroup). - * - * @param groups Indicates a list of NotificationSlotGroup objects to create. This parameter cannot be null. - * @return Returns ERR_OK on success, others on failure. - */ - virtual ErrCode AddSlotGroups(std::vector> groups) = 0; - /** * @brief Queries a created notification slot. * @@ -154,23 +143,6 @@ public: */ virtual ErrCode GetSlots(std::vector> &slots) = 0; - /** - * @brief Queries a created notification slot group. - * - * @param groupId Indicates the ID of the slot group. - * @param group Indicates the created NotificationSlotGroup. - * @return Returns ERR_OK on success, others on failure. - */ - virtual ErrCode GetSlotGroup(const std::string &groupId, sptr &group) = 0; - - /** - * @brief Obtains a list of created notification slot groups. - * - * @param groups Indicates a list of created notification slot groups. - * @return Returns ERR_OK on success, others on failure. - */ - virtual ErrCode GetSlotGroups(std::vector> &groups) = 0; - /** * @brief Obtains the number of slot. * @@ -180,15 +152,6 @@ public: */ virtual ErrCode GetSlotNumAsBundle(const sptr &bundleOption, uint64_t &num) = 0; - /** - * @brief Deletes multiple notification slot groups. - * - * @param groupIds Indicates the IDs of the notification slot groups, which is created by - * AddNotificationSlotGroup(NotificationSlotGroup) This parameter must be specified. - * @return Returns ERR_OK on success, others on failure. - */ - virtual ErrCode RemoveSlotGroups(const std::vector &groupIds) = 0; - /** * @brief Obtains active notifications of the current application in the system. * @@ -374,16 +337,6 @@ public: virtual ErrCode UpdateSlots( const sptr &bundleOption, const std::vector> &slots) = 0; - /** - * @brief Update slotgroup according to bundle. - * - * @param bundleOption Indicates the NotificationBundleOption object. - * @param groups Indicates the notification slots to be updated. - * @return Returns ERR_OK on success, others on failure. - */ - virtual ErrCode UpdateSlotGroups( - const sptr &bundleOption, const std::vector> &groups) = 0; - /** * @brief Allow notifications to be sent based on the deviceId. * diff --git a/frameworks/core/include/ans_manager_proxy.h b/frameworks/core/include/ans_manager_proxy.h index 696c44c56..59baba2a2 100644 --- a/frameworks/core/include/ans_manager_proxy.h +++ b/frameworks/core/include/ans_manager_proxy.h @@ -113,16 +113,6 @@ public: */ ErrCode RemoveAllSlots() override; - /** - * @brief Creates multiple notification slot groups. - * @note The precautions for using this method are similar to those for - * AddNotificationSlotGroup(NotificationSlotGroup). - * - * @param groups Indicates a list of NotificationSlotGroup objects to create. This parameter cannot be null. - * @return Returns ERR_OK on success, others on failure. - */ - ErrCode AddSlotGroups(std::vector> groups) override; - /** * @brief Queries a created notification slot. * @@ -141,23 +131,6 @@ public: */ ErrCode GetSlots(std::vector> &slots) override; - /** - * @brief Queries a created notification slot group. - * - * @param groupId Indicates the ID of the slot group. - * @param group Indicates the created NotificationSlotGroup. - * @return Returns ERR_OK on success, others on failure. - */ - ErrCode GetSlotGroup(const std::string &groupId, sptr &group) override; - - /** - * @brief Obtains a list of created notification slot groups. - * - * @param groups Indicates a list of created notification slot groups. - * @return Returns ERR_OK on success, others on failure. - */ - ErrCode GetSlotGroups(std::vector> &groups) override; - /** * @brief Obtains the number of slot. * @@ -167,15 +140,6 @@ public: */ ErrCode GetSlotNumAsBundle(const sptr &bundleOption, uint64_t &num) override; - /** - * @brief Deletes multiple notification slot groups. - * - * @param groupIds Indicates the IDs of the notification slot groups, which is created by - * AddNotificationSlotGroup(NotificationSlotGroup) This parameter must be specified. - * @return Returns ERR_OK on success, others on failure. - */ - ErrCode RemoveSlotGroups(const std::vector &groupIds) override; - /** * @brief Obtains active notifications of the current application in the system. * @@ -361,16 +325,6 @@ public: ErrCode UpdateSlots( const sptr &bundleOption, const std::vector> &slots) override; - /** - * @brief Update slotgroup according to bundle. - * - * @param bundleOption Indicates the NotificationBundleOption object. - * @param groups Indicates the notification slots to be updated. - * @return Returns ERR_OK on success, others on failure. - */ - ErrCode UpdateSlotGroups(const sptr &bundleOption, - const std::vector> &groups) override; - /** * @brief Allow notifications to be sent based on the deviceId. * diff --git a/frameworks/core/include/ans_manager_stub.h b/frameworks/core/include/ans_manager_stub.h index 2d857d6f1..ed28f92c2 100644 --- a/frameworks/core/include/ans_manager_stub.h +++ b/frameworks/core/include/ans_manager_stub.h @@ -128,16 +128,6 @@ public: */ virtual ErrCode RemoveAllSlots() override; - /** - * @brief Creates multiple notification slot groups. - * @note The precautions for using this method are similar to those for - * AddNotificationSlotGroup(NotificationSlotGroup). - * - * @param groups Indicates a list of NotificationSlotGroup objects to create. This parameter cannot be null. - * @return Returns ERR_OK on success, others on failure. - */ - virtual ErrCode AddSlotGroups(std::vector> groups) override; - /** * @brief Queries a created notification slot. * @@ -157,23 +147,6 @@ public: */ virtual ErrCode GetSlots(std::vector> &slots) override; - /** - * @brief Queries a created notification slot group. - * - * @param groupId Indicates the ID of the slot group. - * @param group Indicates the created NotificationSlotGroup. - * @return Returns ERR_OK on success, others on failure. - */ - virtual ErrCode GetSlotGroup(const std::string &groupId, sptr &group) override; - - /** - * @brief Obtains a list of created notification slot groups. - * - * @param groups Indicates a list of created notification slot groups. - * @return Returns ERR_OK on success, others on failure. - */ - virtual ErrCode GetSlotGroups(std::vector> &groups) override; - /** * @brief Obtains the number of slot. * @@ -183,15 +156,6 @@ public: */ virtual ErrCode GetSlotNumAsBundle(const sptr &bundleOption, uint64_t &num) override; - /** - * @brief Deletes multiple notification slot groups. - * - * @param groupIds Indicates the IDs of the notification slot groups, which is created by - * AddNotificationSlotGroup(NotificationSlotGroup) This parameter must be specified. - * @return Returns ERR_OK on success, others on failure. - */ - virtual ErrCode RemoveSlotGroups(const std::vector &groupIds) override; - /** * @brief Obtains active notifications of the current application in the system. * @@ -377,16 +341,6 @@ public: virtual ErrCode UpdateSlots( const sptr &bundleOption, const std::vector> &slots) override; - /** - * @brief Update slotgroup according to bundle. - * @param bundleOption Bundle as a condition. - * @param groups Groups that needs to be updated. - * - * @return Returns ERR_OK on success, others on failure. - */ - virtual ErrCode UpdateSlotGroups(const sptr &bundleOption, - const std::vector> &groups) override; - /** * @brief Allow notifications to be sent based on the deviceId. * @@ -759,13 +713,9 @@ private: ErrCode HandleAddSlots(MessageParcel &data, MessageParcel &reply); ErrCode HandleRemoveSlotByType(MessageParcel &data, MessageParcel &reply); ErrCode HandleRemoveAllSlots(MessageParcel &data, MessageParcel &reply); - ErrCode HandleAddSlotGroups(MessageParcel &data, MessageParcel &reply); ErrCode HandleGetSlots(MessageParcel &data, MessageParcel &reply); ErrCode HandleGetSlotByType(MessageParcel &data, MessageParcel &reply); - ErrCode HandleGetSlotGroup(MessageParcel &data, MessageParcel &reply); - ErrCode HandleGetSlotGroups(MessageParcel &data, MessageParcel &reply); ErrCode HandleGetSlotNumAsBundle(MessageParcel &data, MessageParcel &reply); - ErrCode HandleRemoveSlotGroups(MessageParcel &data, MessageParcel &reply); ErrCode HandleGetActiveNotifications(MessageParcel &data, MessageParcel &reply); ErrCode HandleGetActiveNotificationNums(MessageParcel &data, MessageParcel &reply); ErrCode HandleGetAllActiveNotifications(MessageParcel &data, MessageParcel &reply); @@ -786,7 +736,6 @@ private: ErrCode HandleDeleteAll(MessageParcel &data, MessageParcel &reply); ErrCode HandleGetSlotsByBundle(MessageParcel &data, MessageParcel &reply); ErrCode HandleUpdateSlots(MessageParcel &data, MessageParcel &reply); - ErrCode HandleUpdateSlotGroups(MessageParcel &data, MessageParcel &reply); ErrCode HandleRequestEnableNotification(MessageParcel &data, MessageParcel &reply); ErrCode HandleSetNotificationsEnabledForBundle(MessageParcel &data, MessageParcel &reply); ErrCode HandleSetNotificationsEnabledForAllBundles(MessageParcel &data, MessageParcel &reply); diff --git a/frameworks/core/include/ans_notification.h b/frameworks/core/include/ans_notification.h index 05bf40439..cba702560 100644 --- a/frameworks/core/include/ans_notification.h +++ b/frameworks/core/include/ans_notification.h @@ -91,56 +91,6 @@ public: */ ErrCode GetNotificationSlots(std::vector> &slots); - /** - * @brief Creates a notification slot group to which a NotificationSlot object can be bound by - * calling NotificationSlot::SetSlotGroup(string). - * @note A NotificationSlotGroup instance cannot be used directly after being initialized. - * Instead, you have to call this method to create a notification slot group so that you can bind - * NotificationSlot objects to it. - * - * @param slotGroup Indicates the notification slot group to be created, which is set by NotificationSlotGroup. - * This parameter must be specified. the notification slot to be created, which is set by - * NotificationSlot. - * @return Returns add notification slot group result. - */ - ErrCode AddNotificationSlotGroup(const NotificationSlotGroup &slotGroup); - - /** - * @brief Creates multiple notification slot groups. - * @note The precautions for using this method are similar to those for - * AddNotificationSlotGroup(NotificationSlotGroup). - * - * @param slotGroups Indicates a list of NotificationSlotGroup objects to create. This parameter cannot be null. - * @return Returns add notification slot groups result. - */ - ErrCode AddNotificationSlotGroups(const std::vector &slotGroups); - - /** - * @brief Deletes a created notification slot group based on the slot group ID. - * - * @param slotGroupId Indicates the ID of the notification slot group, which is created by - * AddNotificationSlotGroup(NotificationSlotGroup) This parameter must be specified. - * @return Returns remove notification slot group result. - */ - ErrCode RemoveNotificationSlotGroup(const std::string &slotGroupId); - - /** - * @brief Queries a created notification slot group. - * - * @param groupId Indicates the ID of the slot group. - * @param group Indicates the created NotificationSlotGroup. - * @return Returns get notification slot group result. - */ - ErrCode GetNotificationSlotGroup(const std::string &groupId, sptr &group); - - /** - * @brief Obtains a list of created notification slot groups. - * - * @param groups Indicates a list of created notification slot groups. - * @return Returns get notification slot groups result. - */ - ErrCode GetNotificationSlotGroups(std::vector> &groups); - /** * @brief Obtains number of slot. * @@ -494,16 +444,6 @@ public: ErrCode UpdateNotificationSlots( const NotificationBundleOption &bundleOption, const std::vector> &slots); - /** - * @brief Updates all notification slot groups for the specified bundle. - * - * @param bundleOption Indicates the bundle name and uid of the application. - * @param groups Indicates a list of new notification slot groups. - * @return Returns update notification slot groups for bundle result. - */ - ErrCode UpdateNotificationSlotGroups( - const NotificationBundleOption &bundleOption, const std::vector> &groups); - /** * @brief Obtains all active notifications in the current system. The caller must have system permissions to * call this method. diff --git a/frameworks/core/src/ans_manager_proxy.cpp b/frameworks/core/src/ans_manager_proxy.cpp index fb5851ff8..a5e654c05 100644 --- a/frameworks/core/src/ans_manager_proxy.cpp +++ b/frameworks/core/src/ans_manager_proxy.cpp @@ -332,46 +332,6 @@ ErrCode AnsManagerProxy::RemoveAllSlots() return result; } -ErrCode AnsManagerProxy::AddSlotGroups(std::vector> groups) -{ - if (groups.empty()) { - ANS_LOGE("[AddSlotGroups] fail: groups is empty."); - return ERR_ANS_INVALID_PARAM; - } - - size_t groupsSize = groups.size(); - if (groupsSize > MAX_SLOT_GROUP_NUM) { - ANS_LOGE("[AddSlotGroups] fail: groupsSize over max size."); - return ERR_ANS_INVALID_PARAM; - } - - MessageParcel data; - if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { - ANS_LOGE("[AddSlotGroups] fail: write interface token failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - if (!WriteParcelableVector(groups, data)) { - ANS_LOGE("[AddSlotGroups] fail: write groups failed"); - return ERR_ANS_PARCELABLE_FAILED; - } - - MessageParcel reply; - MessageOption option = {MessageOption::TF_SYNC}; - ErrCode result = InnerTransact(ADD_SLOT_GROUPS, option, data, reply); - if (result != ERR_OK) { - ANS_LOGE("[AddSlotGroups] fail: transact ErrCode=%{public}d", result); - return ERR_ANS_TRANSACT_FAILED; - } - - if (!reply.ReadInt32(result)) { - ANS_LOGE("[AddSlotGroups] fail: read result failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - return result; -} - ErrCode AnsManagerProxy::GetSlotByType(const NotificationConstant::SlotType &slotType, sptr &slot) { MessageParcel data; @@ -433,72 +393,6 @@ ErrCode AnsManagerProxy::GetSlots(std::vector> &slots) return result; } -ErrCode AnsManagerProxy::GetSlotGroup(const std::string &groupId, sptr &group) -{ - if (groupId.empty()) { - ANS_LOGE("[GetSlotGroup] fail: groupId is null."); - return ERR_ANS_INVALID_PARAM; - } - - MessageParcel data; - if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { - ANS_LOGE("[GetSlotGroup] fail: write interface token failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - if (!data.WriteString(groupId)) { - ANS_LOGE("[GetSlotGroup] fail:: write groupId failed"); - return ERR_ANS_PARCELABLE_FAILED; - } - - MessageParcel reply; - MessageOption option = {MessageOption::TF_SYNC}; - ErrCode result = InnerTransact(GET_SLOT_GROUP, option, data, reply); - if (result != ERR_OK) { - ANS_LOGE("[GetSlotGroup] fail: transact ErrCode=%{public}d", result); - return ERR_ANS_TRANSACT_FAILED; - } - - if (!reply.ReadInt32(result)) { - ANS_LOGE("[GetSlotGroup] fail: read result failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - if (result == ERR_OK) { - group = reply.ReadParcelable(); - if (group == nullptr) { - ANS_LOGE("[GetSlotGroup] fail: read group failed"); - return ERR_ANS_PARCELABLE_FAILED; - } - } - - return result; -} - -ErrCode AnsManagerProxy::GetSlotGroups(std::vector> &groups) -{ - MessageParcel data; - if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { - ANS_LOGE("[GetSlotGroups] fail: write interface token failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - MessageParcel reply; - MessageOption option = {MessageOption::TF_SYNC}; - ErrCode result = InnerTransact(GET_SLOT_GROUPS, option, data, reply); - if (result != ERR_OK) { - ANS_LOGE("[GetSlotGroups] fail: transact ErrCode=%{public}d", result); - return ERR_ANS_TRANSACT_FAILED; - } - - if (!ReadParcelableVector(groups, reply, result)) { - ANS_LOGE("[GetSlotGroups] fail: read groups failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - return result; -} - ErrCode AnsManagerProxy::GetSlotNumAsBundle(const sptr &bundleOption, uint64_t &num) { if (bundleOption == nullptr) { @@ -538,40 +432,6 @@ ErrCode AnsManagerProxy::GetSlotNumAsBundle(const sptr return result; } -ErrCode AnsManagerProxy::RemoveSlotGroups(const std::vector &groupIds) -{ - if (groupIds.empty()) { - ANS_LOGE("[RemoveSlotGroups] fail: groupIds is empty."); - return ERR_ANS_INVALID_PARAM; - } - - MessageParcel data; - if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { - ANS_LOGE("[RemoveSlotGroups] fail: write interface token failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - if (!data.WriteStringVector(groupIds)) { - ANS_LOGE("[RemoveSlotGroups] fail:: write groupIds failed"); - return ERR_ANS_PARCELABLE_FAILED; - } - - MessageParcel reply; - MessageOption option = {MessageOption::TF_SYNC}; - ErrCode result = InnerTransact(REMOVE_SLOT_GROUPS, option, data, reply); - if (result != ERR_OK) { - ANS_LOGE("[RemoveSlotGroups] fail: transact ErrCode=%{public}d", result); - return ERR_ANS_TRANSACT_FAILED; - } - - if (!reply.ReadInt32(result)) { - ANS_LOGE("[RemoveSlotGroups] fail: read result failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - return result; -} - ErrCode AnsManagerProxy::GetActiveNotifications(std::vector> ¬ifications) { MessageParcel data; @@ -1233,57 +1093,6 @@ ErrCode AnsManagerProxy::UpdateSlots( return result; } -ErrCode AnsManagerProxy::UpdateSlotGroups( - const sptr &bundleOption, const std::vector> &groups) -{ - if (bundleOption == nullptr) { - ANS_LOGE("[UpdateSlotGroups] fail: bundleOption is empty."); - return ERR_ANS_INVALID_PARAM; - } - - if (groups.empty()) { - ANS_LOGE("[UpdateSlotGroups] fail: groups is empty."); - return ERR_ANS_INVALID_PARAM; - } - - size_t groupSize = groups.size(); - if (groupSize > MAX_SLOT_GROUP_NUM) { - ANS_LOGE("[UpdateSlotGroups] fail: groupSize over max size."); - return ERR_ANS_INVALID_PARAM; - } - - MessageParcel data; - if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { - ANS_LOGE("[UpdateSlotGroups] fail: write interface token failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - if (!data.WriteParcelable(bundleOption)) { - ANS_LOGE("[UpdateSlotGroups] fail:: write bundleOption failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - if (!WriteParcelableVector(groups, data)) { - ANS_LOGE("[UpdateSlotGroups] fail: write groups failed"); - return ERR_ANS_PARCELABLE_FAILED; - } - - MessageParcel reply; - MessageOption option = {MessageOption::TF_SYNC}; - ErrCode result = InnerTransact(UPDATE_SLOT_GROUPS, option, data, reply); - if (result != ERR_OK) { - ANS_LOGE("[UpdateSlotGroups] fail: transact ErrCode=%{public}d", result); - return ERR_ANS_TRANSACT_FAILED; - } - - if (!reply.ReadInt32(result)) { - ANS_LOGE("[UpdateSlotGroups] fail: read result failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - return result; -} - ErrCode AnsManagerProxy::RequestEnableNotification(const std::string &deviceId) { MessageParcel data; diff --git a/frameworks/core/src/ans_manager_stub.cpp b/frameworks/core/src/ans_manager_stub.cpp index e72fdafc9..4305dd3ac 100644 --- a/frameworks/core/src/ans_manager_stub.cpp +++ b/frameworks/core/src/ans_manager_stub.cpp @@ -55,27 +55,15 @@ const std::map> groups; - if (!ReadParcelableVector(groups, data)) { - ANS_LOGE("[HandleAddSlotGroups] fail: read slotsSize failed"); - return ERR_ANS_PARCELABLE_FAILED; - } - - ErrCode result = AddSlotGroups(groups); - if (!reply.WriteInt32(result)) { - ANS_LOGE("[HandleAddSlotGroups] fail: write result failed, ErrCode=%{public}d", result); - return ERR_ANS_PARCELABLE_FAILED; - } - return ERR_OK; -} - ErrCode AnsManagerStub::HandleGetSlots(MessageParcel &data, MessageParcel &reply) { std::vector> slots; @@ -505,40 +474,6 @@ ErrCode AnsManagerStub::HandleGetSlotByType(MessageParcel &data, MessageParcel & return ERR_OK; } -ErrCode AnsManagerStub::HandleGetSlotGroup(MessageParcel &data, MessageParcel &reply) -{ - std::string groupId; - if (!data.ReadString(groupId)) { - ANS_LOGE("[HandleGetSlotGroup] fail: read groupId failed"); - return ERR_ANS_PARCELABLE_FAILED; - } - - sptr group; - ErrCode result = GetSlotGroup(groupId, group); - if (!reply.WriteInt32(result)) { - ANS_LOGE("[HandleGetSlotGroup] fail: write result failed, ErrCode=%{public}d", result); - return ERR_ANS_PARCELABLE_FAILED; - } - - if (!reply.WriteParcelable(group)) { - ANS_LOGE("[HandleGetSlotGroup] fail: write group failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - return ERR_OK; -} - -ErrCode AnsManagerStub::HandleGetSlotGroups(MessageParcel &data, MessageParcel &reply) -{ - std::vector> groups; - ErrCode result = GetSlotGroups(groups); - if (!WriteParcelableVector(groups, reply, result)) { - ANS_LOGE("[HandleGetSlotGroups] fail: write groups failed"); - return ERR_ANS_PARCELABLE_FAILED; - } - - return ERR_OK; -} - ErrCode AnsManagerStub::HandleGetSlotNumAsBundle(MessageParcel &data, MessageParcel &reply) { sptr bundleOption = data.ReadStrongParcelable(); @@ -561,22 +496,6 @@ ErrCode AnsManagerStub::HandleGetSlotNumAsBundle(MessageParcel &data, MessagePar return ERR_OK; } -ErrCode AnsManagerStub::HandleRemoveSlotGroups(MessageParcel &data, MessageParcel &reply) -{ - std::vector groupIds; - if (!data.ReadStringVector(&groupIds)) { - ANS_LOGE("[HandleRemoveSlotGroups] fail: read groupIds failed"); - return ERR_ANS_PARCELABLE_FAILED; - } - - ErrCode result = RemoveSlotGroups(groupIds); - if (!reply.WriteInt32(result)) { - ANS_LOGE("[HandleRemoveSlotGroups] fail: write result failed, ErrCode=%{public}d", result); - return ERR_ANS_PARCELABLE_FAILED; - } - return ERR_OK; -} - ErrCode AnsManagerStub::HandleGetActiveNotifications(MessageParcel &data, MessageParcel &reply) { std::vector> notifications; @@ -1003,28 +922,6 @@ ErrCode AnsManagerStub::HandleUpdateSlots(MessageParcel &data, MessageParcel &re return ERR_OK; } -ErrCode AnsManagerStub::HandleUpdateSlotGroups(MessageParcel &data, MessageParcel &reply) -{ - sptr bundleOption = data.ReadParcelable(); - if (bundleOption == nullptr) { - ANS_LOGE("[HandleUpdateSlotGroups] fail: read bundle failed."); - return ERR_ANS_PARCELABLE_FAILED; - } - - std::vector> groups; - if (!ReadParcelableVector(groups, data)) { - ANS_LOGE("[HandleUpdateSlotGroups] fail: read groups failed"); - return ERR_ANS_PARCELABLE_FAILED; - } - - ErrCode result = UpdateSlotGroups(bundleOption, groups); - if (!reply.WriteInt32(result)) { - ANS_LOGE("[HandleUpdateSlotGroups] fail: write result failed, ErrCode=%{public}d", result); - return ERR_ANS_PARCELABLE_FAILED; - } - return ERR_OK; -} - ErrCode AnsManagerStub::HandleRequestEnableNotification(MessageParcel &data, MessageParcel &reply) { std::string deviceId; @@ -1922,12 +1819,6 @@ ErrCode AnsManagerStub::RemoveAllSlots() return ERR_INVALID_OPERATION; } -ErrCode AnsManagerStub::AddSlotGroups(std::vector> groups) -{ - ANS_LOGE("AnsManagerStub::AddSlotGroups called!"); - return ERR_INVALID_OPERATION; -} - ErrCode AnsManagerStub::GetSlotByType(const NotificationConstant::SlotType &slotType, sptr &slot) { ANS_LOGE("AnsManagerStub::GetSlotByType called!"); @@ -1940,30 +1831,12 @@ ErrCode AnsManagerStub::GetSlots(std::vector> &slots) return ERR_INVALID_OPERATION; } -ErrCode AnsManagerStub::GetSlotGroup(const std::string &groupId, sptr &group) -{ - ANS_LOGE("AnsManagerStub::GetSlotGroup called!"); - return ERR_INVALID_OPERATION; -} - -ErrCode AnsManagerStub::GetSlotGroups(std::vector> &groups) -{ - ANS_LOGE("AnsManagerStub::GetSlotGroups called!"); - return ERR_INVALID_OPERATION; -} - ErrCode AnsManagerStub::GetSlotNumAsBundle(const sptr &bundleOption, uint64_t &num) { ANS_LOGE("AnsManagerStub::GetSlotNumAsBundle called!"); return ERR_INVALID_OPERATION; } -ErrCode AnsManagerStub::RemoveSlotGroups(const std::vector &groupIds) -{ - ANS_LOGE("AnsManagerStub::RemoveSlotGroups called!"); - return ERR_INVALID_OPERATION; -} - ErrCode AnsManagerStub::GetActiveNotifications(std::vector> ¬ifications) { ANS_LOGE("AnsManagerStub::GetActiveNotifications called!"); @@ -2089,13 +1962,6 @@ ErrCode AnsManagerStub::UpdateSlots( return ERR_INVALID_OPERATION; } -ErrCode AnsManagerStub::UpdateSlotGroups( - const sptr &bundleOption, const std::vector> &groups) -{ - ANS_LOGE("AnsManagerStub::UpdateSlotGroups called!"); - return ERR_INVALID_OPERATION; -} - ErrCode AnsManagerStub::RequestEnableNotification(const std::string &deviceId) { ANS_LOGE("AnsManagerStub::RequestEnableNotification called!"); diff --git a/frameworks/core/src/ans_notification.cpp b/frameworks/core/src/ans_notification.cpp index a88d5b6e6..2a9fd677d 100644 --- a/frameworks/core/src/ans_notification.cpp +++ b/frameworks/core/src/ans_notification.cpp @@ -103,62 +103,6 @@ ErrCode AnsNotification::GetNotificationSlots(std::vector return ansManagerProxy_->GetSlots(slots); } -ErrCode AnsNotification::AddNotificationSlotGroup(const NotificationSlotGroup &slotGroup) -{ - std::vector slotGroups; - slotGroups.emplace_back(slotGroup); - return AddNotificationSlotGroups(slotGroups); -} - -ErrCode AnsNotification::AddNotificationSlotGroups(const std::vector &slotGroups) -{ - if (!GetAnsManagerProxy()) { - ANS_LOGE("GetAnsManagerProxy fail."); - return ERR_ANS_SERVICE_NOT_CONNECTED; - } - - std::vector> slotGroupsSptr; - for (auto it = slotGroups.begin(); it != slotGroups.end(); ++it) { - sptr slotGroup = new (std::nothrow) NotificationSlotGroup(*it); - if (slotGroup == nullptr) { - ANS_LOGE("Failed to add notification slot groups with NotificationSlotGroup nullptr"); - return ERR_ANS_NO_MEMORY; - } - slotGroupsSptr.emplace_back(slotGroup); - } - - return ansManagerProxy_->AddSlotGroups(slotGroupsSptr); -} - -ErrCode AnsNotification::RemoveNotificationSlotGroup(const std::string &slotGroupId) -{ - if (!GetAnsManagerProxy()) { - ANS_LOGE("GetAnsManagerProxy fail."); - return ERR_ANS_SERVICE_NOT_CONNECTED; - } - std::vector slotGroupIds; - slotGroupIds.emplace_back(slotGroupId); - return ansManagerProxy_->RemoveSlotGroups(slotGroupIds); -} - -ErrCode AnsNotification::GetNotificationSlotGroup(const std::string &groupId, sptr &group) -{ - if (!GetAnsManagerProxy()) { - ANS_LOGE("GetAnsManagerProxy fail."); - return ERR_ANS_SERVICE_NOT_CONNECTED; - } - return ansManagerProxy_->GetSlotGroup(groupId, group); -} - -ErrCode AnsNotification::GetNotificationSlotGroups(std::vector> &groups) -{ - if (!GetAnsManagerProxy()) { - ANS_LOGE("GetAnsManagerProxy fail."); - return ERR_ANS_SERVICE_NOT_CONNECTED; - } - return ansManagerProxy_->GetSlotGroups(groups); -} - ErrCode AnsNotification::GetNotificationSlotNumAsBundle(const NotificationBundleOption &bundleOption, uint64_t &num) { if (bundleOption.GetBundleName().empty()) { @@ -659,23 +603,6 @@ ErrCode AnsNotification::UpdateNotificationSlots( return ansManagerProxy_->UpdateSlots(bo, slots); } -ErrCode AnsNotification::UpdateNotificationSlotGroups( - const NotificationBundleOption &bundleOption, const std::vector> &groups) -{ - if (bundleOption.GetBundleName().empty()) { - ANS_LOGE("Invalid bundle name."); - return ERR_ANS_INVALID_PARAM; - } - - if (!GetAnsManagerProxy()) { - ANS_LOGE("GetAnsManagerProxy fail."); - return ERR_ANS_SERVICE_NOT_CONNECTED; - } - - sptr bo(new (std::nothrow) NotificationBundleOption(bundleOption)); - return ansManagerProxy_->UpdateSlotGroups(bo, groups); -} - ErrCode AnsNotification::GetAllActiveNotifications(std::vector> ¬ification) { if (!GetAnsManagerProxy()) { diff --git a/frameworks/test/moduletest/ans_fw_module_test.cpp b/frameworks/test/moduletest/ans_fw_module_test.cpp index d108d7d6d..7ecf1d6c2 100644 --- a/frameworks/test/moduletest/ans_fw_module_test.cpp +++ b/frameworks/test/moduletest/ans_fw_module_test.cpp @@ -628,11 +628,6 @@ void AnsFWModuleTest::TearDown() NotificationHelper::CancelAllNotifications(); NotificationHelper::RemoveAllSlots(); NotificationHelper::RemoveNotifications(); - std::vector> groups; - NotificationHelper::GetNotificationSlotGroups(groups); - for (auto group : groups) { - NotificationHelper::RemoveNotificationSlotGroup(group->GetId().c_str()); - } SleepForFC(); } diff --git a/frameworks/test/moduletest/ans_innerkits_module_slot_test.cpp b/frameworks/test/moduletest/ans_innerkits_module_slot_test.cpp index 41d4d2367..82e87976d 100644 --- a/frameworks/test/moduletest/ans_innerkits_module_slot_test.cpp +++ b/frameworks/test/moduletest/ans_innerkits_module_slot_test.cpp @@ -69,7 +69,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00100, Fu slot.SetDescription("description"); slot.SetLedLightColor(0); slot.SetLevel(NotificationSlot::NotificationLevel::LEVEL_LOW); - slot.SetSlotGroup("group"); slot.SetSound(Uri(".")); std::vector style; style.push_back(0); @@ -93,7 +92,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00100, Fu EXPECT_EQ(NotificationConstant::SOCIAL_COMMUNICATION, spSlot->GetType()); EXPECT_EQ(NotificationConstant::VisiblenessType::PUBLIC, spSlot->GetLockScreenVisibleness()); EXPECT_EQ("SOCIAL_COMMUNICATION", spSlot->GetName()); - EXPECT_EQ("group", spSlot->GetSlotGroup()); EXPECT_EQ(Uri("."), spSlot->GetSound()); for (auto it : spSlot->GetVibrationStyle()) { EXPECT_EQ(0, it); @@ -120,7 +118,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00200, Fu slot.SetDescription("description"); slot.SetLedLightColor(0); slot.SetLevel(NotificationSlot::NotificationLevel::LEVEL_LOW); - slot.SetSlotGroup("group"); slot.SetSound(Uri(".")); std::vector style; style.push_back(0); @@ -143,7 +140,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00200, Fu EXPECT_EQ(NotificationConstant::SERVICE_REMINDER, spSlot->GetType()); EXPECT_EQ(NotificationConstant::VisiblenessType::PUBLIC, spSlot->GetLockScreenVisibleness()); EXPECT_EQ("SERVICE_REMINDER", spSlot->GetName()); - EXPECT_EQ("group", spSlot->GetSlotGroup()); EXPECT_EQ(Uri("."), spSlot->GetSound()); for (auto it : spSlot->GetVibrationStyle()) { EXPECT_EQ(0, it); @@ -171,7 +167,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00300, Fu slot.SetDescription("description"); slot.SetLedLightColor(0); slot.SetLevel(NotificationSlot::NotificationLevel::LEVEL_LOW); - slot.SetSlotGroup("group"); slot.SetSound(Uri(".")); std::vector style; style.push_back(0); @@ -194,7 +189,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00300, Fu EXPECT_EQ(NotificationConstant::CONTENT_INFORMATION, spSlot->GetType()); EXPECT_EQ(NotificationConstant::VisiblenessType::SECRET, spSlot->GetLockScreenVisibleness()); EXPECT_EQ("CONTENT_INFORMATION", spSlot->GetName()); - EXPECT_EQ("group", spSlot->GetSlotGroup()); EXPECT_EQ(Uri("."), spSlot->GetSound()); for (auto it : spSlot->GetVibrationStyle()) { EXPECT_EQ(0, it); @@ -221,7 +215,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00400, Fu slot.SetDescription("description"); slot.SetLedLightColor(0); slot.SetLevel(NotificationSlot::NotificationLevel::LEVEL_LOW); - slot.SetSlotGroup("group"); slot.SetSound(Uri(".")); std::vector style; style.push_back(0); @@ -244,7 +237,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00400, Fu EXPECT_EQ(NotificationConstant::OTHER, spSlot->GetType()); EXPECT_EQ(NotificationConstant::VisiblenessType::SECRET, spSlot->GetLockScreenVisibleness()); EXPECT_EQ("OTHER", spSlot->GetName()); - EXPECT_EQ("group", spSlot->GetSlotGroup()); EXPECT_EQ(Uri("."), spSlot->GetSound()); for (auto it : spSlot->GetVibrationStyle()) { EXPECT_EQ(0, it); @@ -273,7 +265,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00500, Fu slot.SetDescription(description); slot.SetLedLightColor(0); slot.SetLevel(NotificationSlot::NotificationLevel::LEVEL_LOW); - slot.SetSlotGroup("group"); slot.SetSound(Uri(".")); std::vector style; style.push_back(0); @@ -298,7 +289,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00500, Fu EXPECT_EQ(NotificationConstant::OTHER, spSlot->GetType()); EXPECT_EQ(NotificationConstant::VisiblenessType::SECRET, spSlot->GetLockScreenVisibleness()); EXPECT_EQ("OTHER", spSlot->GetName()); - EXPECT_EQ("group", spSlot->GetSlotGroup()); EXPECT_EQ(Uri("."), spSlot->GetSound()); for (auto it : spSlot->GetVibrationStyle()) { EXPECT_EQ(0, it); @@ -380,107 +370,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlot_00900, Fu EXPECT_EQ(NotificationSlot::NotificationLevel::LEVEL_MIN, slot.GetLevel()); } -/** - * @tc.number : ANS_Interface_MT_NotificationSlotGroup_00100 - * @tc.name : NotificationSlotGroup_00100 - * @tc.desc : Add notification slot group, get notification slot group and remove notification slot group. - * @tc.expected : Add notification slot group success, get notification slot group correctly and remove notification - * slot group success. - */ -HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlotGroup_00100, Function | MediumTest | Level1) -{ - NotificationSlotGroup slotGroup("id", "name"); - slotGroup.SetDescription("description"); - EXPECT_EQ(0, NotificationHelper::AddNotificationSlotGroup(slotGroup)); - sptr spSlotGroup; - EXPECT_EQ(0, NotificationHelper::GetNotificationSlotGroup("id", spSlotGroup)); - - if (spSlotGroup == nullptr) { - GTEST_LOG_(INFO) << "get slot group is empty"; - } else { - GTEST_LOG_(INFO) << "get slot group is:" << spSlotGroup->Dump(); - EXPECT_EQ("description", spSlotGroup->GetDescription()); - EXPECT_EQ("id", spSlotGroup->GetId()); - EXPECT_EQ("name", spSlotGroup->GetName()); - EXPECT_EQ(false, spSlotGroup->IsDisabled()); - } - EXPECT_EQ(0, NotificationHelper::RemoveNotificationSlotGroup("id")); - EXPECT_EQ((int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST, - NotificationHelper::GetNotificationSlotGroup("id", spSlotGroup)); -} - -/** - * @tc.number : ANS_Interface_MT_NotificationSlotGroup_00200 - * @tc.name : NotificationSlotGroup_00200 - * @tc.desc : Add notification slot group, slot group set description character length exceed 1000 - * characters, get notification slot group and remove notification slot group. - * @tc.expected : Add notification slot group success, get notification slot group correctly and remove notification - * slot group success. - */ -HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlotGroup_00200, Function | MediumTest | Level1) -{ - NotificationSlotGroup slotGroup("id", "name"); - std::string description(2000, 'c'); - slotGroup.SetDescription(description); - EXPECT_EQ(0, NotificationHelper::AddNotificationSlotGroup(slotGroup)); - GTEST_LOG_(INFO) << "after add group is:" << slotGroup.Dump(); - sptr spSlotGroup; - EXPECT_EQ(0, NotificationHelper::GetNotificationSlotGroup("id", spSlotGroup)); - - if (spSlotGroup == nullptr) { - GTEST_LOG_(INFO) << "get slot group is empty"; - } else { - GTEST_LOG_(INFO) << "get slot group is:" << spSlotGroup->Dump(); - std::string expectDescription(1000, 'c'); - EXPECT_EQ(expectDescription, spSlotGroup->GetDescription()); - EXPECT_EQ("id", spSlotGroup->GetId()); - EXPECT_EQ("name", spSlotGroup->GetName()); - EXPECT_EQ(false, spSlotGroup->IsDisabled()); - } - EXPECT_EQ(0, NotificationHelper::RemoveNotificationSlotGroup("id")); - EXPECT_EQ((int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST, - NotificationHelper::GetNotificationSlotGroup("id", spSlotGroup)); -} - -/** - * @tc.number : ANS_Interface_MT_NotificationSlotGroup_00300 - * @tc.name : NotificationSlotGroup_00300 - * @tc.desc : Two different slots added to the same slot group. - * @tc.expected : Add success. - */ -HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_NotificationSlotGroup_00300, Function | MediumTest | Level1) -{ - NotificationSlot slotA(NotificationConstant::OTHER); - slotA.SetSlotGroup("id"); - - NotificationSlot slotB(NotificationConstant::CUSTOM); - slotA.SetSlotGroup("id"); - - NotificationSlotGroup slotGroup("id", "name"); - EXPECT_EQ(0, NotificationHelper::AddNotificationSlotGroup(slotGroup)); - - sptr spSlotGroup; - EXPECT_EQ(0, NotificationHelper::GetNotificationSlotGroup("id", spSlotGroup)); - - if (spSlotGroup == nullptr) { - GTEST_LOG_(INFO) << "get slot group is empty"; - } else { - std::vector slots = spSlotGroup->GetSlots(); - for (auto it : slots) { - if (NotificationConstant::OTHER == it.GetType()) { - EXPECT_EQ("OTHER", it.GetId()); - } else if (NotificationConstant::CUSTOM == it.GetType()) { - EXPECT_EQ("CUSTOM", it.GetId()); - } else { - GTEST_LOG_(INFO) << "slot group has wrong slot"; - } - } - } - EXPECT_EQ(0, NotificationHelper::RemoveNotificationSlotGroup("id")); - EXPECT_EQ((int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST, - NotificationHelper::GetNotificationSlotGroup("id", spSlotGroup)); -} - /** * @tc.number : ANS_Interface_MT_SetEnabledForBundleSlot_00100 * @tc.name : SetEnabledForBundleSlot_00100 @@ -495,7 +384,6 @@ HWTEST_F(AnsInnerKitsModuleSlotTest, ANS_Interface_MT_SetEnabledForBundleSlot_00 slot.SetDescription("description"); slot.SetLedLightColor(0); slot.SetLevel(NotificationSlot::NotificationLevel::LEVEL_LOW); - slot.SetSlotGroup("group"); slot.SetSound(Uri(".")); std::vector style; style.push_back(0); diff --git a/interfaces/inner_api/notification_helper.h b/interfaces/inner_api/notification_helper.h index 9cf917e7b..13e85e02d 100644 --- a/interfaces/inner_api/notification_helper.h +++ b/interfaces/inner_api/notification_helper.h @@ -21,7 +21,6 @@ #include "enabled_notification_callback_data.h" #include "notification_request.h" #include "notification_slot.h" -#include "notification_slot_group.h" #include "notification_sorting_map.h" #include "notification_subscriber.h" @@ -93,56 +92,6 @@ public: */ static ErrCode GetNotificationSlots(std::vector> &slots); - /** - * @brief Creates a notification slot group to which a NotificationSlot object can be bound by - * calling NotificationSlot::SetSlotGroup(string). - * @note A NotificationSlotGroup instance cannot be used directly after being initialized. - * Instead, you have to call this method to create a notification slot group so that you can bind - * NotificationSlot objects to it. - * - * @param slotGroup Indicates the notification slot group to be created, which is set by NotificationSlotGroup. - * This parameter must be specified. the notification slot to be created, which is set by - * NotificationSlot. - * @return Returns add notification slot group result. - */ - static ErrCode AddNotificationSlotGroup(const NotificationSlotGroup &slotGroup); - - /** - * @brief Creates multiple notification slot groups. - * @note The precautions for using this method are similar to those for - * AddNotificationSlotGroup(NotificationSlotGroup). - * - * @param slotGroups Indicates a list of NotificationSlotGroup objects to create. This parameter cannot be null. - * @return Returns add notification slot groups result. - */ - static ErrCode AddNotificationSlotGroups(const std::vector &slotGroups); - - /** - * @brief Deletes a created notification slot group based on the slot group ID. - * - * @param slotGroupId Indicates the ID of the notification slot group, which is created by - * AddNotificationSlotGroup(NotificationSlotGroup) This parameter must be specified. - * @return Returns remove notification slot group result. - */ - static ErrCode RemoveNotificationSlotGroup(const std::string &slotGroupId); - - /** - * @brief Queries a created notification slot group. - * - * @param groupId Indicates the ID of the slot group. - * @param group Indicates the created NotificationSlotGroup. - * @return Returns get notification slot group result. - */ - static ErrCode GetNotificationSlotGroup(const std::string &groupId, sptr &group); - - /** - * @brief Obtains a list of created notification slot groups. - * - * @param groups Indicates a list of created notification slot groups. - * @return Returns get notification slot groups result. - */ - static ErrCode GetNotificationSlotGroups(std::vector> &groups); - /** * @brief Obtains number of slot. * @@ -496,16 +445,6 @@ public: static ErrCode UpdateNotificationSlots( const NotificationBundleOption &bundleOption, const std::vector> &slots); - /** - * @brief Update all notification slot groups for the specified bundle. - * - * @param bundleOption Indicates the bundle name and uid of the application. - * @param groups Indicates a list of new notification slot groups. - * @return Returns update notification slot groups for bundle result. - */ - static ErrCode UpdateNotificationSlotGroups( - const NotificationBundleOption &bundleOption, const std::vector> &groups); - /** * @brief Obtains all active notifications in the current system. The caller must have system permissions to * call this method. diff --git a/interfaces/inner_api/notification_slot.h b/interfaces/inner_api/notification_slot.h index 903e877b0..354938d85 100644 --- a/interfaces/inner_api/notification_slot.h +++ b/interfaces/inner_api/notification_slot.h @@ -189,25 +189,6 @@ public: */ std::string GetName() const; - /** - * @brief Obtains the ID of the NotificationSlotGroup object to which this NotificationSlot object belongs, - * which is set by SetSlotGroup(string). - * - * @return Returns the ID of the NotificationSlotGroup to which this NotificationSlot object belongs. - */ - std::string GetSlotGroup() const; - - /** - * @brief Binds a NotificationSlot object to a specified NotificationSlotGroup. - * @note SetSlotGroup must be called before the NotificationHelper::AddNotificationSlot(NotificationSlot) method is - * called. Otherwise, this method will not take effect. - * - * @param groupId Indicates the ID of the NotificationSlotGroup object to bind, - * which must have been created by calling - * NotificationHelper::AddNotificationSlotGroup(NotificationSlotGroup). - */ - void SetSlotGroup(const std::string &groupId); - /** * @brief Obtains the prompt tone of a NotificationSlot object, which is set by SetSound(Uri). * @@ -368,7 +349,6 @@ private: NotificationLevel level_ {LEVEL_DEFAULT}; NotificationConstant::SlotType type_ {}; NotificationConstant::VisiblenessType lockScreenVisibleness_ {NotificationConstant::VisiblenessType::NO_OVERRIDE}; - std::string groupId_ {}; Uri sound_; std::vector vibrationValues_ {}; bool enabled_ {true}; diff --git a/interfaces/inner_api/notification_slot_group.h b/interfaces/inner_api/notification_slot_group.h deleted file mode 100644 index 09c341334..000000000 --- a/interfaces/inner_api/notification_slot_group.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2021 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_NOTIFICATION_SLOT_GROUP_H -#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_NOTIFICATION_SLOT_GROUP_H - -#include "notification_slot.h" - -namespace OHOS { -namespace Notification { -class NotificationSlotGroup : public Parcelable { -public: - - /** - * @brief A constructor used to create a NotificationSlotGroup instance with the group ID and name initialized. - * - * @param id Indicates the ID of the NotificationSlotGroup. - * The ID must be unique and its length must not exceed 1000 characters (the excess part is automatically - * truncated). - * @param name Indicates the name of the NotificationSlotGroup. - * Its length must not exceed 1000 characters (the excess part is automatically truncated). - */ - NotificationSlotGroup(const std::string &id, const std::string &name); - - ~NotificationSlotGroup(); - - /** - * @brief Obtains the description of this NotificationSlotGroup object, which is set by SetDescription(string). - * - * @return Returns the description of this NotificationSlotGroup. - */ - std::string GetDescription() const; - - /** - * @brief Obtains the ID of this NotificationSlotGroup object, which is set by - * NotificationSlotGroup(string, string). - * - * @return Returns the ID of this NotificationSlotGroup. - */ - std::string GetId() const; - - /** - * @brief Obtains the name of this NotificationSlotGroup object, which is set by - * NotificationSlotGroup(string, string). - * - * @return Returns the name of this NotificationSlotGroup. - */ - std::string GetName() const; - - /** - * @brief Obtains a list of notification slots bound to this NotificationSlotGroup object. - * @note NotificationSlot::SetSlotGroup(string) is used to bind a notification slot to a notification slot group. - * - * @param slots Indicates the slots which to set to the slotgroup. - */ - void SetSlots(const std::vector &slots); - - /** - * @brief Sets a list of notification slots bound to this NotificationSlotGroup object. - * @note NotificationSlot::SetSlotGroup(string) is used to bind a notification slot to a notification slot group. - * - * @return Returns the list of notification slots bound to this NotificationSlotGroup. - */ - std::vector GetSlots() const; - - /** - * @brief Checks whether this NotificationSlotGroup is disabled. - * - * @return Returns true if this NotificationSlotGroup is disabled; returns false otherwise. - */ - bool IsDisabled() const; - - /** - * @brief Sets the description for this NotificationSlotGroup object. - * - * @param description describes this NotificationSlotGroup object. - * Its length must not exceed 1000 characters (the excess part is automatically truncated). - */ - void SetDescription(const std::string &description); - - /** - * @brief Dumps a string representation of the object. - * - * @return Returns a string representation of the object. - */ - std::string Dump() const; - - /** - * @brief Marshals NotificationSlotGroup objects and writes them into Parcel. - * - * @param parcel Indicates the Parcel object for marshalling. - * @return Returns true if the marshalling is successful; returns false otherwise. - */ - virtual bool Marshalling(Parcel &parcel) const override; - - /** - * @brief Unmarshals a NotificationSlotGroup object from a Parcel. - * - * @param parcel Indicates the Parcel object for unmarshalling. - * @return Returns the NotificationSlotGroup object. - */ - static NotificationSlotGroup *Unmarshalling(Parcel &parcel); - - /** - * @brief If string length exceed 1000 characters, the excessive part is automatically truncated. - * - * @param truncatedString Indicates the sting which will be truncated - * @return Returns the string that has been truncated. - */ - std::string TruncateString(const std::string &inPutString); - -private: - NotificationSlotGroup(); - - /** - * @brief Read NotificationSlotGroup object from a Parcel. - * - * @param parcel Indicates the parcel object. - * @return Returns true if succeed; returns false otherwise. - */ - bool ReadFromParcel(Parcel &parcel); - -private: - std::string id_ {}; - std::string name_ {}; - std::string description_ {}; - std::vector slots_ {}; - bool isDisabled_ {false}; -}; -} // namespace Notification -} // namespace OHOS - -#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_NOTIFICATION_SLOT_GROUP_H \ No newline at end of file diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index 8b349142d..7281f3a1a 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -125,16 +125,6 @@ public: */ ErrCode RemoveAllSlots() override; - /** - * @brief Creates multiple notification slot groups. - * @note The precautions for using this method are similar to those for - * AddNotificationSlotGroup(NotificationSlotGroup). - * - * @param groups Indicates a list of NotificationSlotGroup objects to create. This parameter cannot be null. - * @return Returns ERR_OK on success, others on failure. - */ - ErrCode AddSlotGroups(std::vector> groups) override; - /** * @brief Queries a created notification slot. * @@ -153,23 +143,6 @@ public: */ ErrCode GetSlots(std::vector> &slots) override; - /** - * @brief Queries a created notification slot group. - * - * @param groupId Indicates the ID of the slot group. - * @param group Indicates the created NotificationSlotGroup. - * @return Returns ERR_OK on success, others on failure. - */ - ErrCode GetSlotGroup(const std::string &groupId, sptr &group) override; - - /** - * @brief Obtains a list of created notification slot groups. - * - * @param groups Indicates a list of created notification slot groups. - * @return Returns ERR_OK on success, others on failure. - */ - ErrCode GetSlotGroups(std::vector> &groups) override; - /** * @brief Obtains the number of slot. * @@ -179,15 +152,6 @@ public: */ ErrCode GetSlotNumAsBundle(const sptr &bundleOption, uint64_t &num) override; - /** - * @brief Deletes multiple notification slot groups. - * - * @param groupIds Indicates the IDs of the notification slot groups, which is created by - * AddNotificationSlotGroup(NotificationSlotGroup) This parameter must be specified. - * @return Returns ERR_OK on success, others on failure. - */ - ErrCode RemoveSlotGroups(const std::vector &groupIds) override; - /** * @brief Obtains active notifications of the current application in the system. * @@ -373,16 +337,6 @@ public: ErrCode UpdateSlots( const sptr &bundleOption, const std::vector> &slots) override; - /** - * @brief Update slotgroup according to bundle. - * - * @param bundleOption Indicates the NotificationBundleOption object. - * @param groups Indicates the notification slots to be updated. - * @return Returns ERR_OK on success, others on failure. - */ - ErrCode UpdateSlotGroups(const sptr &bundleOption, - const std::vector> &groups) override; - /** * @brief Allow notifications to be sent based on the deviceId. * diff --git a/services/ans/include/notification_preferences.h b/services/ans/include/notification_preferences.h index 2c55af914..7548eb5f7 100644 --- a/services/ans/include/notification_preferences.h +++ b/services/ans/include/notification_preferences.h @@ -43,16 +43,6 @@ public: ErrCode AddNotificationSlots( const sptr &bundleOption, const std::vector> &slots); - /** - * @brief Add notification slot groups into DB. - * - * @param bundleOption Indicates bunlde info label. - * @param groups Indicates add notification slot groups. - * @return Return ERR_OK on success, others on failure. - */ - ErrCode AddNotificationSlotGroups( - const sptr &bundleOption, const std::vector> &groups); - /** * @brief Add notification bunle info into DB. * @@ -79,15 +69,6 @@ public: */ ErrCode RemoveNotificationAllSlots(const sptr &bundleOption); - /** - * @brief Remove notification all slot in the of bundle from DB. - * - * @param bundleOption Indicates bunlde info label. - * @return Return ERR_OK on success, others on failure. - */ - ErrCode RemoveNotificationSlotGroups( - const sptr &bundleOption, const std::vector &groupIds); - /** * @brief Remove notification bundle from DB. * @@ -106,16 +87,6 @@ public: ErrCode UpdateNotificationSlots( const sptr &bundleOption, const std::vector> &slot); - /** - * @brief Update notification slot group into DB. - * - * @param bundleOption Indicates bunlde info label. - * @param slot Indicates need to upadte slot group. - * @return Return ERR_OK on success, others on failure. - */ - ErrCode UpdateNotificationSlotGroups( - const sptr &bundleOption, const std::vector> &groups); - /** * @brief Get notification slot from DB. * @@ -146,38 +117,6 @@ public: */ ErrCode GetNotificationSlotsNumForBundle(const sptr &bundleOption, uint64_t &num); - /** - * @brief Get notification group in a bundle from DB. - * - * @param bundleOption Indicates bunlde info label. - * @param groupId Indicates to get group id. - * @param group Indicates to get slot group. - * @return Return ERR_OK on success, others on failure. - */ - ErrCode GetNotificationSlotGroup(const sptr &bundleOption, const std::string &groupId, - sptr &group); - - /** - * @brief Get notification all group in a bundle from DB. - * - * @param bundleOption Indicates bunlde info label. - * @param groups Indicates to get slot groups. - * @return Return ERR_OK on success, others on failure. - */ - ErrCode GetNotificationAllSlotGroups( - const sptr &bundleOption, std::vector> &groups); - - /** - * @brief Get notification all slot in a group in the of bunlde from DB. - * - * @param bundleOption Indicates bunlde info label. - * @param groupId Indicates to get group id. - * @param slots Indicates to get slots. - * @return Return ERR_OK on success, others on failure. - */ - ErrCode GetNotificationAllSlotInSlotGroup(const sptr &bundleOption, - const std::string &groupId, std::vector> &slots); - /** * @brief Get show badge in the of bunlde from DB. * @@ -326,16 +265,10 @@ public: private: ErrCode CheckSlotForCreateSlot(const sptr &bundleOption, const sptr &slot, NotificationPreferencesInfo &preferencesInfo) const; - ErrCode CheckGroupForCreateSlotGroup(const sptr &bundleOption, - const sptr &group, NotificationPreferencesInfo &preferencesInfo) const; ErrCode CheckSlotForRemoveSlot(const sptr &bundleOption, const NotificationConstant::SlotType &slotType, NotificationPreferencesInfo &preferencesInfo) const; - ErrCode CheckGroupForRemoveSlotGroup(const sptr &bundleOption, const std::string &groupId, - NotificationPreferencesInfo &preferencesInfo) const; ErrCode CheckSlotForUpdateSlot(const sptr &bundleOption, const sptr &slot, NotificationPreferencesInfo &preferencesInfo) const; - ErrCode CheckGroupForUpdateSlotGroup(const sptr &bundleOption, - const sptr &group, NotificationPreferencesInfo &preferencesInfo) const; template ErrCode SetBundleProperty(NotificationPreferencesInfo &preferencesInfo, const sptr &bundleOption, const BundleType &type, const T &value); diff --git a/services/ans/include/notification_preferences_database.h b/services/ans/include/notification_preferences_database.h index 4c3e3c7f1..6aee6f7c3 100644 --- a/services/ans/include/notification_preferences_database.h +++ b/services/ans/include/notification_preferences_database.h @@ -40,17 +40,6 @@ public: bool PutSlotsToDisturbeDB( const std::string &bundleName, const int32_t &bundleUid, const std::vector> &slots); - /** - * @brief Put notification slot groups into disturbe DB. - * - * @param bundleName Indicates bundle name. - * @param bundleUid Indicates bundle uid. - * @param groups Indicates notification groups. - * @return Return true on success, false on failure. - */ - bool PutGroupsToDisturbeDB(const std::string &bundleName, const int32_t &bundleUid, - const std::vector> &groups); - /** * @brief Put notification bundle into disturbe DB. * @@ -165,15 +154,6 @@ public: */ bool RemoveAllSlotsFromDisturbeDB(const std::string &bundleKey); - /** - * @brief Delete some groups in the of bundle from disturbe DB. - * - * @param bundleKey Indicates to which a bundle. - * @param groupId Indicates to group id in the of bundle. - * @return Return true on success, false on failure. - */ - bool RemoveGroupsFromDisturbeDB(const std::string &bundleKey, const std::vector &groupId); - /** * @brief Deal death recipient. * @@ -201,15 +181,9 @@ private: void GetValueFromDisturbeDB(const std::string &key, std::function function); void GetValueFromDisturbeDB(const std::string &key, std::function function); - bool GetRemoveGroupKeysFromDisturbeDB( - const std::string &bundleKey, const std::string &groupId, std::vector &keys); bool SlotToEntry(const std::string &bundleName, const int32_t &bundleUid, const sptr &slot, std::vector &entries); - bool GroupToEntry(const std::string &bundleName, const int32_t &bundleUid, const sptr &group, - std::vector &entries); - void GenerateGroupEntry(const std::string &bundleKey, const sptr &group, - std::vector &entries) const; void GenerateSlotEntry(const std::string &bundleKey, const sptr &slot, std::vector &entries) const; void GenerateEntry( @@ -222,26 +196,20 @@ private: int32_t StringToInt(const std::string &str) const; int64_t StringToInt64(const std::string &str) const; bool IsSlotKey(const std::string &bundleKey, const std::string &key) const; - bool IsGroupKey(const std::string &bundleKey, const std::string &key) const; std::string GenerateSlotKey( const std::string &bundleKey, const std::string &type = "", const std::string &subType = "") const; - std::string GenerateGroupKey(const std::string &bundleKey, const std::string &subType = "") const; std::string GenerateBundleKey(const std::string &bundleKey, const std::string &type = "") const; void ParseBundleFromDistureDB( NotificationPreferencesInfo &info, const std::vector &entries); void ParseSlotFromDisturbeDB(NotificationPreferencesInfo::BundleInfo &bundleInfo, const std::string &bundleKey, const DistributedKv::Entry &entry); - void ParseGroupFromDisturbeDB(NotificationPreferencesInfo::BundleInfo &bundleInfo, const std::string &bundleKey, - const DistributedKv::Entry &entry); void ParseBundlePropertyFromDisturbeDB(NotificationPreferencesInfo::BundleInfo &bundleInfo, const std::string &bundleKey, const DistributedKv::Entry &entry); void ParseDoNotDisturbType(NotificationPreferencesInfo &info); void ParseDoNotDisturbBeginDate(NotificationPreferencesInfo &info); void ParseDoNotDisturbEndDate(NotificationPreferencesInfo &info); void ParseEnableAllNotification(NotificationPreferencesInfo &info); - void ParseGroupDescription( - const std::string &bundleKey, sptr &group, const DistributedKv::Entry &entry); void ParseBundleName(NotificationPreferencesInfo::BundleInfo &bundleInfo, const std::string &value) const; void ParseBundleImportance(NotificationPreferencesInfo::BundleInfo &bundleInfo, const std::string &value) const; void ParseBundleShowBadge(NotificationPreferencesInfo::BundleInfo &bundleInfo, const std::string &value) const; @@ -255,7 +223,6 @@ private: void ParseBundleUid(NotificationPreferencesInfo::BundleInfo &bundleInfo, const std::string &value) const; void ParseSlot( const std::string &findString, sptr &slot, const DistributedKv::Entry &entry); - void ParseSlotGroupId(sptr &slot, const std::string &value) const; void ParseSlotDescription(sptr &slot, const std::string &value) const; void ParseSlotLevel(sptr &slot, const std::string &value) const; void ParseSlotShowBadge(sptr &slot, const std::string &value) const; diff --git a/services/ans/include/notification_preferences_info.h b/services/ans/include/notification_preferences_info.h index 5a567efcc..450655e8d 100644 --- a/services/ans/include/notification_preferences_info.h +++ b/services/ans/include/notification_preferences_info.h @@ -23,7 +23,6 @@ #include "notification_bundle_option.h" #include "notification_do_not_disturb_date.h" #include "notification_slot.h" -#include "notification_slot_group.h" #include "preferences_constant.h" namespace OHOS { @@ -170,37 +169,6 @@ public: */ bool GetAllSlotsInGroup(const std::string &groupId, std::vector &slots); - /** - * @brief Set bundle group. - * - * @param group Indicates the set group. - */ - void SetGroup(const sptr &group); - - /** - * @brief Get group from bundle. - * - * @param groupId Indicates the get group id in the of bundle. - * @param group Indicates the get group. - * @return Return true on success, false on failure. - */ - bool GetGroup(const std::string &groupId, sptr &group); - - /** - * @brief Get all group from bundle. - * - * @param group Indicates the get groups. - * @return Return true on success, false on failure. - */ - bool GetAllGroups(std::vector> &group); - - /** - * @brief Get slot group num from bundle. - * - * @return Return num is group size. - */ - size_t GetGroupSize() const; - /** * @brief Check whether to exsist slot in the of bundle. * @@ -209,14 +177,6 @@ public: */ bool IsExsitSlot(const NotificationConstant::SlotType &type) const; - /** - * @brief Check whether to exsist slot group in the of bundle. - * - * @param groupId Indicates the slot group id. - * @return Return true on success, false on failure. - */ - bool IsExsitSlotGroup(const std::string &groupId) const; - /** * @brief Rremove a slot from bundle. * @@ -232,13 +192,6 @@ public: */ void RemoveAllSlots(); - /** - * @brief remove slot group from bundle. - * - * @param groupId Indicates the slot group id. - * @return Return true on success, false on failure. - */ - bool RemoveSlotGroup(const std::string &groupId); void SetBundleUid(const int32_t &uid); int32_t GetBundleUid() const; void SetSlotEnabled(NotificationConstant::SlotType slotType, bool enabled); @@ -254,7 +207,6 @@ public: bool isEnabledNotification_ = BUNDLE_ENABLE_NOTIFICATION; bool hasPoppedDialog_ = BUNDLE_POPPED_DIALOG; std::map> slots_; - std::map> groups_; }; /* diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 1d39e77fa..11bbd96de 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -751,21 +751,6 @@ ErrCode AdvancedNotificationService::AddSlots(const std::vector> groups) -{ - ANS_LOGD("%{public}s", __FUNCTION__); - - sptr bundleOption = GenerateBundleOption(); - if (bundleOption == nullptr) { - return ERR_ANS_INVALID_BUNDLE; - } - - ErrCode result = ERR_OK; - handler_->PostSyncTask(std::bind( - [&]() { result = NotificationPreferences::GetInstance().AddNotificationSlotGroups(bundleOption, groups); })); - return result; -} - ErrCode AdvancedNotificationService::GetSlots(std::vector> &slots) { ANS_LOGD("%{public}s", __FUNCTION__); @@ -786,62 +771,6 @@ ErrCode AdvancedNotificationService::GetSlots(std::vector return result; } -ErrCode AdvancedNotificationService::GetSlotGroup(const std::string &groupId, sptr &group) -{ - ANS_LOGD("%{public}s", __FUNCTION__); - - sptr bundleOption = GenerateBundleOption(); - if (bundleOption == nullptr) { - return ERR_ANS_INVALID_BUNDLE; - } - - ErrCode result = ERR_OK; - handler_->PostSyncTask(std::bind([&]() { - result = NotificationPreferences::GetInstance().GetNotificationSlotGroup(bundleOption, groupId, group); - if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) { - result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST; - } - })); - return result; -} - -ErrCode AdvancedNotificationService::GetSlotGroups(std::vector> &groups) -{ - ANS_LOGD("%{public}s", __FUNCTION__); - - sptr bundleOption = GenerateBundleOption(); - if (bundleOption == nullptr) { - return ERR_ANS_INVALID_BUNDLE; - } - - ErrCode result = ERR_OK; - handler_->PostSyncTask(std::bind([&]() { - result = NotificationPreferences::GetInstance().GetNotificationAllSlotGroups(bundleOption, groups); - if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) { - result = ERR_OK; - groups.clear(); - } - })); - return result; -} - -ErrCode AdvancedNotificationService::RemoveSlotGroups(const std::vector &groupIds) -{ - sptr bundleOption = GenerateBundleOption(); - if (bundleOption == nullptr) { - return ERR_ANS_INVALID_BUNDLE; - } - - ErrCode result = ERR_OK; - handler_->PostSyncTask(std::bind([&]() { - result = NotificationPreferences::GetInstance().RemoveNotificationSlotGroups(bundleOption, groupIds); - if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) { - result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_ID_INVALID; - } - })); - return result; -} - ErrCode AdvancedNotificationService::GetActiveNotifications(std::vector> ¬ifications) { ANS_LOGD("%{public}s", __FUNCTION__); @@ -1194,34 +1123,6 @@ ErrCode AdvancedNotificationService::UpdateSlots( return result; } -ErrCode AdvancedNotificationService::UpdateSlotGroups( - const sptr &bundleOption, const std::vector> &groups) -{ - ANS_LOGD("%{public}s", __FUNCTION__); - - if (!IsSystemApp()) { - return ERR_ANS_NON_SYSTEM_APP; - } - - if (!CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) { - return ERR_ANS_PERMISSION_DENIED; - } - - sptr bundle = GenerateValidBundleOption(bundleOption); - if (bundle == nullptr) { - return ERR_ANS_INVALID_BUNDLE; - } - - ErrCode result = ERR_OK; - handler_->PostSyncTask(std::bind([&]() { - result = NotificationPreferences::GetInstance().UpdateNotificationSlotGroups(bundle, groups); - if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) { - result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST; - } - })); - return result; -} - ErrCode AdvancedNotificationService::SetShowBadgeEnabledForBundle( const sptr &bundleOption, bool enabled) { diff --git a/services/ans/src/notification_preferences.cpp b/services/ans/src/notification_preferences.cpp index 30bf6e192..8d12e9f2c 100644 --- a/services/ans/src/notification_preferences.cpp +++ b/services/ans/src/notification_preferences.cpp @@ -69,34 +69,6 @@ ErrCode NotificationPreferences::AddNotificationSlots( return result; } -ErrCode NotificationPreferences::AddNotificationSlotGroups( - const sptr &bundleOption, const std::vector> &groups) -{ - ANS_LOGD("%{public}s", __FUNCTION__); - if (bundleOption == nullptr || bundleOption->GetBundleName().empty() || groups.empty()) { - return ERR_ANS_INVALID_PARAM; - } - - NotificationPreferencesInfo preferencesInfo = preferencesInfo_; - ErrCode result = ERR_OK; - for (auto group : groups) { - result = CheckGroupForCreateSlotGroup(bundleOption, group, preferencesInfo); - if (result != ERR_OK) { - return result; - } - } - - if ((result == ERR_OK) && - (!preferncesDB_->PutGroupsToDisturbeDB(bundleOption->GetBundleName(), bundleOption->GetUid(), groups))) { - return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED; - } - - if (result == ERR_OK) { - preferencesInfo_ = preferencesInfo; - } - return result; -} - ErrCode NotificationPreferences::AddNotificationBundleProperty(const sptr &bundleOption) { if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) { @@ -162,31 +134,6 @@ ErrCode NotificationPreferences::RemoveNotificationAllSlots(const sptr &bundleOption, const std::vector &groupIds) -{ - ANS_LOGD("%{public}s", __FUNCTION__); - if (bundleOption == nullptr || bundleOption->GetBundleName().empty() || groupIds.empty()) { - return ERR_ANS_INVALID_PARAM; - } - NotificationPreferencesInfo preferencesInfo = preferencesInfo_; - ErrCode result = ERR_OK; - for (auto groupId : groupIds) { - result = CheckGroupForRemoveSlotGroup(bundleOption, groupId, preferencesInfo); - if (result != ERR_OK) { - return result; - } - } - if ((result == ERR_OK) && (!preferncesDB_->RemoveGroupsFromDisturbeDB(GenerateBundleKey(bundleOption), groupIds))) { - return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED; - } - - if (result == ERR_OK) { - preferencesInfo_ = preferencesInfo; - } - return result; -} - ErrCode NotificationPreferences::RemoveNotificationForBundle(const sptr &bundleOption) { ANS_LOGD("%{public}s", __FUNCTION__); @@ -242,34 +189,6 @@ ErrCode NotificationPreferences::UpdateNotificationSlots( return result; } -ErrCode NotificationPreferences::UpdateNotificationSlotGroups( - const sptr &bundleOption, const std::vector> &groups) -{ - ANS_LOGD("%{public}s", __FUNCTION__); - if (bundleOption == nullptr || bundleOption->GetBundleName().empty() || groups.empty()) { - return ERR_ANS_INVALID_PARAM; - } - - NotificationPreferencesInfo preferencesInfo = preferencesInfo_; - ErrCode result = ERR_OK; - for (auto groupIter : groups) { - result = CheckGroupForUpdateSlotGroup(bundleOption, groupIter, preferencesInfo); - if (result != ERR_OK) { - return result; - } - } - - if ((result == ERR_OK) && - (!preferncesDB_->PutGroupsToDisturbeDB(bundleOption->GetBundleName(), bundleOption->GetUid(), groups))) { - return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED; - } - - if (result == ERR_OK) { - preferencesInfo_ = preferencesInfo; - } - return result; -} - ErrCode NotificationPreferences::GetNotificationSlot(const sptr &bundleOption, const NotificationConstant::SlotType &type, sptr &slot) { @@ -327,62 +246,6 @@ ErrCode NotificationPreferences::GetNotificationSlotsNumForBundle( return result; } -ErrCode NotificationPreferences::GetNotificationSlotGroup( - const sptr &bundleOption, const std::string &groupId, sptr &group) -{ - if (bundleOption == nullptr || bundleOption->GetBundleName().empty() || groupId.empty()) { - return ERR_ANS_INVALID_PARAM; - } - - ErrCode result = ERR_OK; - NotificationPreferencesInfo::BundleInfo bundleInfo; - if (preferencesInfo_.GetBundleInfo(bundleOption, bundleInfo)) { - if (!bundleInfo.GetGroup(groupId, group)) { - result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST; - } - } else { - ANS_LOGW("Notification bundle does not exsit."); - result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST; - } - return result; -} - -ErrCode NotificationPreferences::GetNotificationAllSlotGroups( - const sptr &bundleOption, std::vector> &groups) -{ - if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) { - return ERR_ANS_INVALID_PARAM; - } - - ErrCode result = ERR_OK; - NotificationPreferencesInfo::BundleInfo bundleInfo; - if (preferencesInfo_.GetBundleInfo(bundleOption, bundleInfo)) { - bundleInfo.GetAllGroups(groups); - } else { - ANS_LOGW("Notification bundle does not exsit."); - result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST; - } - return result; -} - -ErrCode NotificationPreferences::GetNotificationAllSlotInSlotGroup(const sptr &bundleOption, - const std::string &groupId, std::vector> &slots) -{ - if (bundleOption == nullptr || bundleOption->GetBundleName().empty() || groupId.empty()) { - return ERR_ANS_INVALID_PARAM; - } - - ErrCode result = ERR_OK; - NotificationPreferencesInfo::BundleInfo bundleInfo; - if (preferencesInfo_.GetBundleInfo(bundleOption, bundleInfo)) { - bundleInfo.GetAllSlotsInGroup(groupId, slots); - } else { - ANS_LOGW("Notification bundle does not exsit."); - result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST; - } - return result; -} - ErrCode NotificationPreferences::IsShowBadge(const sptr &bundleOption, bool &enable) { if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) { @@ -625,36 +488,6 @@ ErrCode NotificationPreferences::CheckSlotForCreateSlot(const sptr &bundleOption, - const sptr &group, NotificationPreferencesInfo &preferencesInfo) const -{ - if (group == nullptr) { - ANS_LOGE("Notification slot group is nullptr."); - return ERR_ANS_INVALID_PARAM; - } - - if (group->GetId().empty()) { - ANS_LOGE("Notification slot group id is invalid."); - return ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_ID_INVALID; - } - - NotificationPreferencesInfo::BundleInfo bundleInfo; - if (!preferencesInfo.GetBundleInfo(bundleOption, bundleInfo)) { - bundleInfo.SetBundleName(bundleOption->GetBundleName()); - bundleInfo.SetBundleUid(bundleOption->GetUid()); - bundleInfo.SetEnableNotification(CheckApiCompatibility(bundleOption)); - } else { - if (bundleInfo.GetGroupSize() >= MAX_SLOT_GROUP_NUM) { - return ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_EXCEED_MAX_NUM; - } - } - - bundleInfo.SetGroup(group); - preferencesInfo.SetBundleInfo(bundleInfo); - - return ERR_OK; -} - ErrCode NotificationPreferences::CheckSlotForRemoveSlot(const sptr &bundleOption, const NotificationConstant::SlotType &slotType, NotificationPreferencesInfo &preferencesInfo) const { @@ -675,26 +508,6 @@ ErrCode NotificationPreferences::CheckSlotForRemoveSlot(const sptr &bundleOption, - const std::string &groupId, NotificationPreferencesInfo &preferencesInfo) const -{ - ErrCode result = ERR_OK; - NotificationPreferencesInfo::BundleInfo bundleInfo; - if (preferencesInfo.GetBundleInfo(bundleOption, bundleInfo)) { - if (bundleInfo.IsExsitSlotGroup(groupId)) { - bundleInfo.RemoveSlotGroup(groupId); - preferencesInfo.SetBundleInfo(bundleInfo); - } else { - ANS_LOGE("Notification slot group id is invalid."); - result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_ID_INVALID; - } - } else { - ANS_LOGW("Notification bundle does not exsit."); - result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST; - } - return result; -} - ErrCode NotificationPreferences::CheckSlotForUpdateSlot(const sptr &bundleOption, const sptr &slot, NotificationPreferencesInfo &preferencesInfo) const { @@ -723,27 +536,6 @@ ErrCode NotificationPreferences::CheckSlotForUpdateSlot(const sptr &bundleOption, - const sptr &group, NotificationPreferencesInfo &preferencesInfo) const -{ - ErrCode result = ERR_OK; - NotificationPreferencesInfo::BundleInfo bundleInfo; - if (preferencesInfo.GetBundleInfo(bundleOption, bundleInfo)) { - if (bundleInfo.IsExsitSlotGroup(group->GetId())) { - bundleInfo.SetBundleName(bundleOption->GetBundleName()); - bundleInfo.SetBundleUid(bundleOption->GetUid()); - bundleInfo.SetGroup(group); - preferencesInfo.SetBundleInfo(bundleInfo); - } else { - result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST; - } - } else { - ANS_LOGW("Notification slot is nullptr."); - result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST; - } - return result; -} - template ErrCode NotificationPreferences::SetBundleProperty(NotificationPreferencesInfo &preferencesInfo, const sptr &bundleOption, const BundleType &type, const T &value) diff --git a/services/ans/src/notification_preferences_database.cpp b/services/ans/src/notification_preferences_database.cpp index 0d18ef611..24299562a 100644 --- a/services/ans/src/notification_preferences_database.cpp +++ b/services/ans/src/notification_preferences_database.cpp @@ -98,31 +98,6 @@ const static std::string KEY_BUNDLE_POPPED_DIALOG = "poppedDialog"; */ const static std::string KEY_BUNDLE_UID = "uid"; -/** - * Indicates that disturbe key which group. - */ -const static std::string KEY_GROUP = "group"; - -/** - * Indicates that disturbe key which group id. - */ -const static std::string KEY_GROUP_ID = "id"; - -/** - * Indicates that disturbe key which group name. - */ -const static std::string KEY_GROUP_NAME = "name"; - -/** - * Indicates that disturbe key which group description. - */ -const static std::string KEY_GROUP_DESCRIPTION = "groupDescription"; - -/** - * Indicates that disturbe key which group is disable. - */ -const static std::string KEY_GROUP_DISABLE = "isDisable"; - /** * Indicates that disturbe key which slot. */ @@ -139,12 +114,7 @@ const static std::string KEY_SLOT_TYPE = "type"; const static std::string KEY_SLOT_ID = "id"; /** - * Indicates that disturbe key which slot group id. - */ -const static std::string KEY_SLOT_GROUPID = "groupId"; - -/** - * Indicates that disturbe key which slot group name. + * Indicates that disturbe key which slot name. */ const static std::string KEY_SLOT_NAME = "name"; @@ -208,11 +178,6 @@ constexpr char KV_STORE_PATH[] = "/data/service/el1/public/database/notification const std::map &, std::string &)>> NotificationPreferencesDatabase::slotMap_ = { - { - KEY_SLOT_GROUPID, - std::bind(&NotificationPreferencesDatabase::ParseSlotGroupId, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3), - }, { KEY_SLOT_DESCRIPTION, std::bind(&NotificationPreferencesDatabase::ParseSlotDescription, std::placeholders::_1, @@ -400,38 +365,6 @@ bool NotificationPreferencesDatabase::PutSlotsToDisturbeDB( return (status == DistributedKv::Status::SUCCESS); } -bool NotificationPreferencesDatabase::PutGroupsToDisturbeDB( - const std::string &bundleName, const int32_t &bundleUid, const std::vector> &groups) -{ - if (bundleName.empty()) { - ANS_LOGE("Bundle name is null."); - return false; - } - - if (groups.empty()) { - ANS_LOGE("Slot is empty."); - return false; - } - - bool result = true; - std::vector entries; - for (auto iter : groups) { - result = GroupToEntry(bundleName, bundleUid, iter, entries); - if (!result) { - ANS_LOGE("Group to entry is null."); - return result; - } - } - - if (!CheckKvStore()) { - ANS_LOGE("KvStore is nullptr."); - return false; - } - DistributedKv::Status status = kvStorePtr_->PutBatch(entries); - CloseKvStore(); - return (status == DistributedKv::Status::SUCCESS); -} - bool NotificationPreferencesDatabase::PutBundlePropertyToDisturbeDB( const NotificationPreferencesInfo::BundleInfo &bundleInfo) { @@ -880,62 +813,6 @@ bool NotificationPreferencesDatabase::RemoveAllSlotsFromDisturbeDB(const std::st return (status == DistributedKv::Status::SUCCESS); } -bool NotificationPreferencesDatabase::RemoveGroupsFromDisturbeDB( - const std::string &bundleKey, const std::vector &groupIds) -{ - if (bundleKey.empty()) { - ANS_LOGE("Bundle name is null."); - return false; - } - - if (groupIds.empty()) { - ANS_LOGE("Group id is empty."); - return false; - } - - if (!CheckKvStore()) { - ANS_LOGE("KvStore is nullptr."); - return false; - } - - std::vector keys; - bool result = true; - for (auto iter : groupIds) { - result = GetRemoveGroupKeysFromDisturbeDB(bundleKey, iter, keys); - if (!result) { - CloseKvStore(); - return result; - } - } - - DistributedKv::Status status = kvStorePtr_->DeleteBatch(keys); - CloseKvStore(); - ANS_LOGD("%{public}s remove groups status %{public}d", __FUNCTION__, status); - return (status == DistributedKv::Status::SUCCESS); -} - -bool NotificationPreferencesDatabase::GetRemoveGroupKeysFromDisturbeDB( - const std::string &bundleKey, const std::string &groupId, std::vector &keys) -{ - if (!CheckKvStore()) { - ANS_LOGE("KvStore is nullptr."); - return false; - } - - DistributedKv::Status status; - std::vector groupentries; - std::string slotKeyStr = GenerateGroupKey(bundleKey, groupId); - status = kvStorePtr_->GetEntries(DistributedKv::Key(slotKeyStr + KEY_UNDER_LINE), groupentries); - if (status != DistributedKv::Status::SUCCESS) { - return false; - } - for (auto iter : groupentries) { - keys.push_back(iter.key); - } - - return true; -} - bool NotificationPreferencesDatabase::StoreDeathRecipient() { ANS_LOGW("distribute remote died"); @@ -1021,7 +898,7 @@ bool NotificationPreferencesDatabase::SlotToEntry(const std::string &bundleName, const sptr &slot, std::vector &entries) { if (slot == nullptr) { - ANS_LOGE("Notification group is nullptr."); + ANS_LOGE("Notification slot is nullptr."); return false; } @@ -1040,7 +917,6 @@ void NotificationPreferencesDatabase::GenerateSlotEntry(const std::string &bundl std::string slotType = std::to_string(slot->GetType()); GenerateEntry(GenerateSlotKey(bundleKey, slotType, KEY_SLOT_TYPE), std::to_string(slot->GetType()), entries); GenerateEntry(GenerateSlotKey(bundleKey, slotType, KEY_SLOT_ID), slot->GetId(), entries); - GenerateEntry(GenerateSlotKey(bundleKey, slotType, KEY_SLOT_GROUPID), slot->GetSlotGroup(), entries); GenerateEntry(GenerateSlotKey(bundleKey, slotType, KEY_SLOT_NAME), slot->GetName(), entries); GenerateEntry(GenerateSlotKey(bundleKey, slotType, KEY_SLOT_DESCRIPTION), slot->GetDescription(), entries); GenerateEntry(GenerateSlotKey(bundleKey, slotType, KEY_SLOT_LEVEL), std::to_string(slot->GetLevel()), entries); @@ -1066,35 +942,6 @@ void NotificationPreferencesDatabase::GenerateSlotEntry(const std::string &bundl GenerateEntry(GenerateSlotKey(bundleKey, slotType, KEY_SLOT_ENABLED), std::to_string(slot->GetEnable()), entries); } -bool NotificationPreferencesDatabase::GroupToEntry(const std::string &bundleName, const int32_t &bundleUid, - const sptr &group, std::vector &entries) -{ - - if (group == nullptr) { - ANS_LOGE("Notification group is nullptr."); - return false; - } - - if (!CheckBundle(bundleName, bundleUid)) { - return false; - } - - std::string bundleKey = bundleName + std::to_string(bundleUid); - GenerateGroupEntry(bundleKey, group, entries); - return true; -} - -void NotificationPreferencesDatabase::GenerateGroupEntry(const std::string &bundleKey, - const sptr &group, std::vector &entries) const -{ - std::string groupLebal = group->GetId().append(KEY_UNDER_LINE); - GenerateEntry(GenerateGroupKey(bundleKey, groupLebal + KEY_GROUP_ID), group->GetId(), entries); - GenerateEntry(GenerateGroupKey(bundleKey, groupLebal + KEY_GROUP_NAME), group->GetName(), entries); - GenerateEntry(GenerateGroupKey(bundleKey, groupLebal + KEY_GROUP_DESCRIPTION), group->GetDescription(), entries); - GenerateEntry( - GenerateGroupKey(bundleKey, groupLebal + KEY_GROUP_DISABLE), std::to_string(group->IsDisabled()), entries); -} - void NotificationPreferencesDatabase::ParseBundleFromDistureDB( NotificationPreferencesInfo &info, const std::vector &entries) { @@ -1112,8 +959,6 @@ void NotificationPreferencesDatabase::ParseBundleFromDistureDB( for (auto bundleEntry : bundleEntries) { if (IsSlotKey(GenerateBundleKey(bundleKey), bundleEntry.key.ToString())) { ParseSlotFromDisturbeDB(bunldeInfo, bundleKey, bundleEntry); - } else if (IsGroupKey(GenerateBundleKey(bundleKey), bundleEntry.key.ToString())) { - ParseGroupFromDisturbeDB(bunldeInfo, bundleKey, bundleEntry); } else { ParseBundlePropertyFromDisturbeDB(bunldeInfo, bundleKey, bundleEntry); } @@ -1138,32 +983,6 @@ void NotificationPreferencesDatabase::ParseSlotFromDisturbeDB(NotificationPrefer bundleInfo.SetSlot(slot); } -void NotificationPreferencesDatabase::ParseGroupFromDisturbeDB(NotificationPreferencesInfo::BundleInfo &bundleInfo, - const std::string &bundleKey, const DistributedKv::Entry &entry) -{ - if (!CheckKvStore()) { - ANS_LOGE("KvStore is nullptr."); - return; - } - std::string groupKey = entry.key.ToString(); - std::string groupId = SubUniqueIdentifyFromString(GenerateGroupKey(bundleKey) + KEY_UNDER_LINE, groupKey); - sptr group; - if (!bundleInfo.GetGroup(groupId, group)) { - std::string groupName; - std::string groupNameKey = GenerateGroupKey(bundleKey, groupId + KEY_UNDER_LINE + KEY_GROUP_NAME); - GetValueFromDisturbeDB( - groupNameKey, [&groupName](DistributedKv::Value &value) { groupName = value.ToString(); }); - if (groupName.empty()) { - ANS_LOGE("Group name does not exsited."); - return; - } - group = new NotificationSlotGroup(groupId, groupName); - } - - ParseGroupDescription(bundleKey, group, entry); - bundleInfo.SetGroup(group); -} - void NotificationPreferencesDatabase::ParseBundlePropertyFromDisturbeDB( NotificationPreferencesInfo::BundleInfo &bundleInfo, const std::string &bundleKey, const DistributedKv::Entry &entry) @@ -1265,20 +1084,6 @@ bool NotificationPreferencesDatabase::IsSlotKey(const std::string &bundleKey, co return false; } -bool NotificationPreferencesDatabase::IsGroupKey(const std::string &bundleKey, const std::string &key) const -{ - std::string tempStr = FindLastString(bundleKey, key); - size_t pos = tempStr.find_first_of(KEY_UNDER_LINE); - std::string slotStr; - if (pos != std::string::npos) { - slotStr = tempStr.substr(0, pos); - } - if (!slotStr.compare(KEY_GROUP)) { - return true; - } - return false; -} - std::string NotificationPreferencesDatabase::GenerateSlotKey( const std::string &bundleKey, const std::string &type, const std::string &subType) const { @@ -1301,24 +1106,6 @@ std::string NotificationPreferencesDatabase::GenerateSlotKey( return key; } -std::string NotificationPreferencesDatabase::GenerateGroupKey( - const std::string &bundleKey, const std::string &type) const -{ - /* group key - * - * KEY_ANS_BUNDLE_bundlename_group_id_id0_id: - * KEY_ANS_BUNDLE_bundlename_group_id_id0_name: - * KEY_ANS_BUNDLE_bundlename_group_id_id1_name - * - */ - std::string key = GenerateBundleKey(bundleKey).append(KEY_GROUP).append(KEY_UNDER_LINE).append(KEY_GROUP_ID); - if (!type.empty()) { - key.append(KEY_UNDER_LINE).append(type); - } - ANS_LOGD("Group key is %{public}s.", key.c_str()); - return key; -} - std::string NotificationPreferencesDatabase::GenerateBundleKey( const std::string &bundleKey, const std::string &type) const { @@ -1393,18 +1180,6 @@ void NotificationPreferencesDatabase::ParseEnableAllNotification(NotificationPre } } -void NotificationPreferencesDatabase::ParseGroupDescription( - const std::string &bundleKey, sptr &group, const DistributedKv::Entry &entry) -{ - std::string findStr = GenerateGroupKey(bundleKey, group->GetId()) + KEY_UNDER_LINE; - std::string typeStr = FindLastString(findStr, entry.key.ToString()); - std::string valueStr = entry.value.ToString(); - if (!typeStr.compare(KEY_GROUP_DESCRIPTION)) { - ANS_LOGD("SetGroupDescription is %{public}s.", valueStr.c_str()); - group->SetDescription(valueStr); - } -} - void NotificationPreferencesDatabase::ParseBundleName( NotificationPreferencesInfo::BundleInfo &bundleInfo, const std::string &value) const { @@ -1461,13 +1236,6 @@ void NotificationPreferencesDatabase::ParseBundleUid( bundleInfo.SetBundleUid(StringToInt(value)); } -void NotificationPreferencesDatabase::ParseSlotGroupId(sptr &slot, const std::string &value) const -{ - ANS_LOGD("ParseSlotGroupId slot group id is %{public}s.", value.c_str()); - std::string slotGroupId = value; - slot->SetSlotGroup(slotGroupId); -} - void NotificationPreferencesDatabase::ParseSlotDescription(sptr &slot, const std::string &value) const { ANS_LOGD("ParseSlotDescription slot des is %{public}s.", value.c_str()); diff --git a/services/ans/src/notification_preferences_info.cpp b/services/ans/src/notification_preferences_info.cpp index bd2788d84..2ab4e39f8 100644 --- a/services/ans/src/notification_preferences_info.cpp +++ b/services/ans/src/notification_preferences_info.cpp @@ -124,84 +124,12 @@ uint32_t NotificationPreferencesInfo::BundleInfo::GetAllSlotsSize() return slots_.size(); } -bool NotificationPreferencesInfo::BundleInfo::GetAllSlotsInGroup( - const std::string &groupId, std::vector> &slots) -{ - std::for_each(slots_.begin(), - slots_.end(), - [&](std::map>::reference iter) { - if (!iter.second->GetSlotGroup().compare(groupId)) { - slots.emplace_back(iter.second); - } - }); - return true; -} - -bool NotificationPreferencesInfo::BundleInfo::GetAllSlotsInGroup( - const std::string &groupId, std::vector &slots) -{ - std::for_each(slots_.begin(), - slots_.end(), - [&](std::map>::reference &iter) { - if (!iter.second->GetSlotGroup().compare(groupId)) { - slots.emplace_back(*iter.second); - } - }); - return true; -} - -void NotificationPreferencesInfo::BundleInfo::SetGroup(const sptr &group) -{ - if (group) { - groups_.insert_or_assign(group->GetId(), group); - } -} - -bool NotificationPreferencesInfo::BundleInfo::GetGroup(const std::string &groupId, sptr &group) -{ - auto iter = groups_.find(groupId); - if (iter != groups_.end()) { - group = iter->second; - std::vector slots; - GetAllSlotsInGroup(groupId, slots); - group->SetSlots(slots); - return true; - } - return false; -} - -bool NotificationPreferencesInfo::BundleInfo::GetAllGroups(std::vector> &group) -{ - std::for_each( - groups_.begin(), groups_.end(), [&](std::map>::reference iter) { - std::vector slots; - GetAllSlotsInGroup(iter.second->GetId(), slots); - iter.second->SetSlots(slots); - group.emplace_back(iter.second); - }); - return true; -} - -size_t NotificationPreferencesInfo::BundleInfo::GetGroupSize() const -{ - return groups_.size(); -} - bool NotificationPreferencesInfo::BundleInfo::IsExsitSlot(const NotificationConstant::SlotType &type) const { auto iter = slots_.find(type); return (iter != slots_.end()); } -bool NotificationPreferencesInfo::BundleInfo::IsExsitSlotGroup(const std::string &groupId) const -{ - auto iter = groups_.find(groupId); - if (iter != groups_.end()) { - return true; - } - return false; -} - bool NotificationPreferencesInfo::BundleInfo::RemoveSlot(const NotificationConstant::SlotType &type) { auto iter = slots_.find(type); @@ -217,16 +145,6 @@ void NotificationPreferencesInfo::BundleInfo::RemoveAllSlots() slots_.clear(); } -bool NotificationPreferencesInfo::BundleInfo::RemoveSlotGroup(const std::string &groupId) -{ - auto iter = groups_.find(groupId); - if (iter != groups_.end()) { - groups_.erase(groupId); - return true; - } - return false; -} - void NotificationPreferencesInfo::BundleInfo::SetBundleUid(const int32_t &uid) { uid_ = uid; diff --git a/services/ans/test/unittest/advanced_notification_service_test.cpp b/services/ans/test/unittest/advanced_notification_service_test.cpp index 98af315dc..453f0c4e2 100644 --- a/services/ans/test/unittest/advanced_notification_service_test.cpp +++ b/services/ans/test/unittest/advanced_notification_service_test.cpp @@ -44,7 +44,6 @@ public: private: void TestAddSlot(NotificationConstant::SlotType type); - void TestAddSlotGroup(); private: static sptr advancedNotificationService_; @@ -114,14 +113,6 @@ void AdvancedNotificationServiceTest::TestAddSlot(NotificationConstant::SlotType EXPECT_EQ(advancedNotificationService_->AddSlots(slots), (int)ERR_OK); } -void AdvancedNotificationServiceTest::TestAddSlotGroup() -{ - std::vector> groups; - sptr group = new NotificationSlotGroup("id0", "name0"); - groups.push_back(group); - advancedNotificationService_->AddSlotGroups(groups); -} - /** * @tc.number : ANS_Publish_00100 * @tc.name : ANSPublish00100 @@ -445,19 +436,6 @@ HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_01300, SleepForFC(); } -/** - * @tc.number : ANS_Publish_01400 - * @tc.name : ANSPublish01400 - * @tc.desc : - */ -HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_01400, Function | SmallTest | Level1) -{ - TestAddSlotGroup(); - std::vector groupIds; - groupIds.push_back("id0"); - EXPECT_EQ(advancedNotificationService_->RemoveSlotGroups(groupIds), (int)ERR_OK); -} - /** * @tc.number : AdvancedNotificationServiceTest_01600 * @tc.name : ANS_GetSlot_0200 @@ -477,25 +455,6 @@ HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_01600, EXPECT_EQ((int)slotsResult.size(), 1); } -/** - * @tc.number : AdvancedNotificationServiceTest_01700 - * @tc.name : ANS_GetSlotGroup_0100 - * @tc.desc : Test GetSlotGroup function - */ -HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_01700, Function | SmallTest | Level1) -{ - std::vector> groups; - sptr group2 = new NotificationSlotGroup("id2", "name2"); - group2->SetDescription("Description"); - groups.push_back(group2); - advancedNotificationService_->AddSlotGroups(groups); - sptr group = new NotificationSlotGroup(); - EXPECT_EQ(advancedNotificationService_->GetSlotGroup("id2", group), ERR_OK); - EXPECT_EQ(group2->GetId(), group->GetId()); - EXPECT_EQ(group2->GetName(), group->GetName()); - EXPECT_EQ(group2->GetDescription(), group->GetDescription()); -} - /** * @tc.number : AdvancedNotificationServiceTest_01800 * @tc.name : ANS_SetNotificationBadgeNum_0100 @@ -576,38 +535,6 @@ HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_02300, (int)ERR_OK); } -/** - * @tc.number : AdvancedNotificationServiceTest_02400 - * @tc.name : ANS_UpdateSlotGroups_0100 - * @tc.desc : Test UpdateSlotGroups function when no group - */ -HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_02400, Function | SmallTest | Level1) -{ - TestAddSlotGroup(); - std::vector> groups; - sptr group2 = new NotificationSlotGroup("id1", "name1"); - groups.push_back(group2); - EXPECT_EQ((int)advancedNotificationService_->UpdateSlotGroups( - new NotificationBundleOption(TEST_DEFUALT_BUNDLE, SYSTEM_APP_UID), groups), - (int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST); -} - -/** - * @tc.number : AdvancedNotificationServiceTest_02500 - * @tc.name : ANS_UpdateSlotGroups_0200 - * @tc.desc : Test UpdateSlotGroups function - */ -HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_02500, Function | SmallTest | Level1) -{ - TestAddSlotGroup(); - std::vector> groups; - sptr group2 = new NotificationSlotGroup("id0", "name1"); - groups.push_back(group2); - EXPECT_EQ((int)advancedNotificationService_->UpdateSlotGroups( - new NotificationBundleOption(TEST_DEFUALT_BUNDLE, SYSTEM_APP_UID), groups), - (int)ERR_OK); -} - /** * @tc.number : AdvancedNotificationServiceTest_02700 * @tc.name : ANS_SetShowBadgeEnabledForBundle_0100 @@ -853,34 +780,6 @@ HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_05300, (int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST); } -/** - * @tc.number : AdvancedNotificationServiceTest_05400 - * @tc.name : ANS_AddSlotGroups_0100 - * @tc.desc : Test AddSlotGroups function - */ -HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_05400, Function | SmallTest | Level1) -{ - std::vector> groups; - sptr group0 = new NotificationSlotGroup("id0", "name0"); - sptr group1 = new NotificationSlotGroup("id1", "name1"); - groups.push_back(group0); - groups.push_back(group1); - EXPECT_EQ(advancedNotificationService_->AddSlotGroups(groups), ERR_OK); -} - -/** - * @tc.number : AdvancedNotificationServiceTest_05500 - * @tc.name : ANS_RemoveSlotGroups_0100 - * @tc.desc : Test RemoveSlotGroups function - */ -HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_05500, Function | SmallTest | Level1) -{ - TestAddSlotGroup(); - std::vector groupIds; - groupIds.push_back("id0"); - EXPECT_EQ(advancedNotificationService_->RemoveSlotGroups(groupIds), (int)ERR_OK); -} - /** * @tc.number : AdvancedNotificationServiceTest_05600 * @tc.name : ANS_GetSlot_0100 @@ -899,25 +798,6 @@ HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_05600, EXPECT_EQ(slot->GetLevel(), slot0->GetLevel()); } -/** - * @tc.number : AdvancedNotificationServiceTest_05800 - * @tc.name : ANS_GetSlotGroup_0100 - * @tc.desc : Test GetSlotGroup function - */ -HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_05800, Function | SmallTest | Level1) -{ - std::vector> groups; - sptr group2 = new NotificationSlotGroup("id2", "name2"); - group2->SetDescription("Description"); - groups.push_back(group2); - advancedNotificationService_->AddSlotGroups(groups); - sptr group = new NotificationSlotGroup(); - EXPECT_EQ(advancedNotificationService_->GetSlotGroup("id2", group), ERR_OK); - EXPECT_EQ(group2->GetId(), group->GetId()); - EXPECT_EQ(group2->GetName(), group->GetName()); - EXPECT_EQ(group2->GetDescription(), group->GetDescription()); -} - /** * @tc.number : AdvancedNotificationServiceTest_05900 * @tc.name : ANS_SetNotificationBadgeNum_0100 @@ -998,38 +878,6 @@ HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_06400, (int)ERR_OK); } -/** - * @tc.number : AdvancedNotificationServiceTest_06500 - * @tc.name : ANS_UpdateSlotGroups_0100 - * @tc.desc : Test UpdateSlotGroups function when no group - */ -HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_06500, Function | SmallTest | Level1) -{ - TestAddSlot(NotificationConstant::SlotType::OTHER); - std::vector> groups; - sptr group2 = new NotificationSlotGroup("id2", "name2"); - groups.push_back(group2); - EXPECT_EQ((int)advancedNotificationService_->UpdateSlotGroups( - new NotificationBundleOption(TEST_DEFUALT_BUNDLE, SYSTEM_APP_UID), groups), - (int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST); -} - -/** - * @tc.number : AdvancedNotificationServiceTest_06600 - * @tc.name : ANS_UpdateSlotGroups_0200 - * @tc.desc : Test UpdateSlotGroups function - */ -HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_06600, Function | SmallTest | Level1) -{ - TestAddSlotGroup(); - std::vector> groups; - sptr group2 = new NotificationSlotGroup("id0", "name2"); - groups.push_back(group2); - EXPECT_EQ((int)advancedNotificationService_->UpdateSlotGroups( - new NotificationBundleOption(TEST_DEFUALT_BUNDLE, SYSTEM_APP_UID), groups), - (int)ERR_OK); -} - /** * @tc.number : AdvancedNotificationServiceTest_06800 * @tc.name : ANS_SetShowBadgeEnabledForBundle_0100 @@ -1144,23 +992,6 @@ HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_08700, EXPECT_EQ(slot->GetType(), NotificationConstant::SlotType::OTHER); } -/** - * @tc.number : AdvancedNotificationServiceTest_08900 - * @tc.name : ANS_GetSlotGroups_0100 - * @tc.desc : Test GetSlotGroups function - */ -HWTEST_F(AdvancedNotificationServiceTest, AdvancedNotificationServiceTest_08900, Function | SmallTest | Level1) -{ - std::vector> groups; - sptr group2 = new NotificationSlotGroup("id2", "name2"); - group2->SetDescription("Description"); - groups.push_back(group2); - advancedNotificationService_->AddSlotGroups(groups); - std::vector> group; - EXPECT_EQ(advancedNotificationService_->GetSlotGroups(group), ERR_OK); - EXPECT_EQ(groups.size(), group.size()); -} - /** * @tc.number : AdvancedNotificationServiceTest_09000 * @tc.name : ANS_GetAllActiveNotifications_0100 diff --git a/services/ans/test/unittest/notification_preferences_database_test.cpp b/services/ans/test/unittest/notification_preferences_database_test.cpp index e4857df84..392920628 100644 --- a/services/ans/test/unittest/notification_preferences_database_test.cpp +++ b/services/ans/test/unittest/notification_preferences_database_test.cpp @@ -76,44 +76,6 @@ HWTEST_F(NotificationPreferencesDatabaseTest, PutSlotsToDisturbeDB_00300, Functi EXPECT_FALSE(preferncesDB_->PutSlotsToDisturbeDB(bundleName_, bundleUid_, slots)); } -/** - * @tc.name : PutGroupsToDisturbeDB_00100 - * @tc.number : - * @tc.desc : Put slot group into disturbe DB, return is true. - */ -HWTEST_F(NotificationPreferencesDatabaseTest, PutGroupsToDisturbeDB_00100, Function | SmallTest | Level1) -{ - sptr slotGroup = new NotificationSlotGroup("id", "name"); - std::vector> groups; - groups.push_back(slotGroup); - - EXPECT_TRUE(preferncesDB_->PutGroupsToDisturbeDB(bundleName_, bundleUid_, groups)); -} - -/** - * @tc.name : PutGroupsToDisturbeDB_00200 - * @tc.number : - * @tc.desc : Put slot group into disturbe DB when bundle name is null, return is false. - */ -HWTEST_F(NotificationPreferencesDatabaseTest, PutGroupsToDisturbeDB_00200, Function | SmallTest | Level1) -{ - sptr slotGroup = new NotificationSlotGroup("id", "name"); - std::vector> groups; - groups.push_back(slotGroup); - EXPECT_FALSE(preferncesDB_->PutGroupsToDisturbeDB(std::string(), 0, groups)); -} - -/** - * @tc.number : PutGroupsToDisturbeDB_00300 - * @tc.name : - * @tc.desc : Put slot group into disturbe DB when groups is null, return is false. - */ -HWTEST_F(NotificationPreferencesDatabaseTest, PutGroupsToDisturbeDB_00300, Function | SmallTest | Level1) -{ - std::vector> groups; - EXPECT_FALSE(preferncesDB_->PutGroupsToDisturbeDB(bundleName_, bundleUid_, groups)); -} - /** * @tc.name : PutShowBadge_00100 * @tc.number : @@ -415,47 +377,6 @@ HWTEST_F(NotificationPreferencesDatabaseTest, RemoveSlotFromDisturbeDB_00200, Fu std::string(), OHOS::Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION)); } -/** - * @tc.name : RemoveGroupsFromDisturbeDB_00100 - * @tc.number : - * @tc.desc : Remove slot froup from disturbe DB, return is true. - */ -HWTEST_F(NotificationPreferencesDatabaseTest, RemoveGroupsFromDisturbeDB_00100, Function | SmallTest | Level1) -{ - sptr slotGroup = new NotificationSlotGroup("id", "name"); - std::vector> groups; - groups.push_back(slotGroup); - EXPECT_TRUE(preferncesDB_->PutGroupsToDisturbeDB(bundleName_, bundleUid_, groups)); - std::vector groupIds; - groupIds.push_back("id"); - EXPECT_TRUE(preferncesDB_->RemoveGroupsFromDisturbeDB(bundleName_, groupIds)); -} - -/** - * @tc.number : RemoveGroupsFromDisturbeDB_00200 - * @tc.name : - * @tc.desc : Remove slot froup from disturbe DB when bundle name is null, return is false. - */ -HWTEST_F(NotificationPreferencesDatabaseTest, RemoveGroupsFromDisturbeDB_00200, Function | SmallTest | Level1) -{ - std::vector groupIds; - groupIds.push_back("group1"); - groupIds.push_back("group2"); - EXPECT_FALSE(preferncesDB_->RemoveGroupsFromDisturbeDB(std::string(), groupIds)); -} - -/** - * @tc.number : GetRemoveGroupKeys_00100 - * @tc.name : - * @tc.desc : Get remove group disturbe key, return is true. - */ -HWTEST_F(NotificationPreferencesDatabaseTest, GetRemoveGroupKeys_00100, Function | SmallTest | Level1) -{ - std::string groupId = "id"; - std::vector keys; - EXPECT_TRUE(preferncesDB_->GetRemoveGroupKeysFromDisturbeDB(bundleName_, groupId, keys)); -} - /** * @tc.name : StoreDeathRecipient_00100 * @tc.number : @@ -509,19 +430,6 @@ HWTEST_F(NotificationPreferencesDatabaseTest, ChangeSlotToEntry_00100, Function EXPECT_TRUE(preferncesDB_->SlotToEntry(bundleName_, bundleUid_, slot, entries)); } -/** - * @tc.name : ChangeGroupToEntry_00100 - * @tc.number : - * @tc.desc : Change slot group to entry. - */ -HWTEST_F(NotificationPreferencesDatabaseTest, ChangeGroupToEntry_00100, Function | SmallTest | Level1) -{ - sptr slotGroup = new NotificationSlotGroup("id", "name"); - std::vector entries; - - EXPECT_TRUE(preferncesDB_->GroupToEntry(bundleName_, bundleUid_, slotGroup, entries)); -} - /** * @tc.name : CheckBundle_00100 * @tc.number : diff --git a/services/ans/test/unittest/notification_preferences_test.cpp b/services/ans/test/unittest/notification_preferences_test.cpp index ee84ca591..0ffe922c4 100644 --- a/services/ans/test/unittest/notification_preferences_test.cpp +++ b/services/ans/test/unittest/notification_preferences_test.cpp @@ -30,7 +30,6 @@ public: void TearDown(); void TestAddNotificationSlot(); - void TestAddNotificationSlotGroup(); static sptr bundleOption_; static sptr noExsitbundleOption_; @@ -57,14 +56,6 @@ void NotificationPreferencesTest::TestAddNotificationSlot() NotificationPreferences::GetInstance().AddNotificationSlots(bundleOption_, slots); } -void NotificationPreferencesTest::TestAddNotificationSlotGroup() -{ - sptr group = new NotificationSlotGroup("id", "name"); - std::vector> groups; - groups.push_back(group); - NotificationPreferences::GetInstance().AddNotificationSlotGroups(bundleOption_, groups); -} - /** * @tc.number : AddNotificationSlots_00100 * @tc.name : @@ -136,85 +127,6 @@ HWTEST_F(NotificationPreferencesTest, AddNotificationSlots_00500, Function | Sma EXPECT_EQ((int)NotificationPreferences::GetInstance().AddNotificationSlots(bundleOption_, slots), (int)ERR_OK); } -/** - * @tc.number : AddNotificationSlotGroups_00100 - * @tc.name : - * @tc.desc : Add a notification groups into disturbe DB , return is ERR_OK - */ -HWTEST_F(NotificationPreferencesTest, AddNotificationSlotGroups_00100, Function | SmallTest | Level1) -{ - sptr group = new NotificationSlotGroup("id", "name"); - std::vector> groups; - groups.push_back(group); - EXPECT_EQ( - (int)NotificationPreferences::GetInstance().AddNotificationSlotGroups(bundleOption_, groups), (int)ERR_OK); -} - -/** - * @tc.number : AddNotificationSlotGroups_00200 - * @tc.name : - * @tc.desc : Add a notification groups into disturbe DB when bundle name is null, return is ERR_ANS_INVALID_PARAM. - */ -HWTEST_F(NotificationPreferencesTest, AddNotificationSlotGroups_00200, Function | SmallTest | Level1) -{ - sptr group = new NotificationSlotGroup("id", "name"); - std::vector> groups; - groups.push_back(group); - EXPECT_EQ((int)NotificationPreferences::GetInstance().AddNotificationSlotGroups(bundleEmptyOption_, groups), - (int)ERR_ANS_INVALID_PARAM); -} - -/** - * @tc.number : AddNotificationSlotGroups_00300 - * @tc.name : - * @tc.desc : Add a notification groups into disturbe DB when groups is null, return is ERR_ANS_INVALID_PARAM. - */ -HWTEST_F(NotificationPreferencesTest, AddNotificationSlotGroups_00300, Function | SmallTest | Level1) -{ - std::vector> groups; - EXPECT_EQ((int)NotificationPreferences::GetInstance().AddNotificationSlotGroups(bundleOption_, groups), - (int)ERR_ANS_INVALID_PARAM); -} - -/** - * @tc.number : AddNotificationSlotGroups_00400 - * @tc.name : - * @tc.desc : Add a notification groups into disturbe DB when group id is null, return is - * ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_ID_INVALID - */ -HWTEST_F(NotificationPreferencesTest, AddNotificationSlotGroups_00400, Function | SmallTest | Level1) -{ - sptr group = new NotificationSlotGroup("", "name"); - std::vector> groups; - groups.push_back(group); - EXPECT_EQ((int)NotificationPreferences::GetInstance().AddNotificationSlotGroups(bundleOption_, groups), - (int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_ID_INVALID); -} - -/** - * @tc.number : AddNotificationSlotGroups_00500 - * @tc.name : - * @tc.desc : Add a notification groups into disturbe DB when add group exceed max num, return is - * ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_EXCEED_MAX_NUM - */ -HWTEST_F(NotificationPreferencesTest, AddNotificationSlotGroups_00500, Function | SmallTest | Level1) -{ - sptr group1 = new NotificationSlotGroup("id1", "name1"); - sptr group2 = new NotificationSlotGroup("id2", "name1"); - sptr group3 = new NotificationSlotGroup("id3", "name1"); - sptr group4 = new NotificationSlotGroup("id4", "name1"); - sptr group5 = new NotificationSlotGroup("id5", "name1"); - std::vector> groups; - groups.push_back(group1); - groups.push_back(group2); - groups.push_back(group3); - groups.push_back(group4); - groups.push_back(group5); - - EXPECT_EQ((int)NotificationPreferences::GetInstance().AddNotificationSlotGroups(bundleOption_, groups), - (int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_EXCEED_MAX_NUM); -} - /** * @tc.number : RemoveNotificationSlot_00100 * @tc.name : @@ -268,79 +180,6 @@ HWTEST_F(NotificationPreferencesTest, RemoveNotificationSlot_00400, Function | S (int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST); } -/** - * @tc.number : RemoveNotificationSlotGroups_00100 - * @tc.name : - * @tc.desc : Remove a notification group from disturbe DB , return is ERR_OK - */ -HWTEST_F(NotificationPreferencesTest, RemoveNotificationSlotGroups_00100, Function | SmallTest | Level1) -{ - TestAddNotificationSlotGroup(); - std::string groupId = "id"; - std::vector groupIds; - groupIds.push_back(groupId); - EXPECT_EQ( - (int)NotificationPreferences::GetInstance().RemoveNotificationSlotGroups(bundleOption_, groupIds), (int)ERR_OK); -} - -/** - * @tc.number : RemoveNotificationSlotGroups_00200 - * @tc.name : - * @tc.desc : Remove a notification group from disturbe DB when bundleName is null, return is ERR_ANS_INVALID_PARAM - */ -HWTEST_F(NotificationPreferencesTest, RemoveNotificationSlotGroups_00200, Function | SmallTest | Level1) -{ - TestAddNotificationSlotGroup(); - std::string groupId("id"); - std::vector groupIds; - groupIds.push_back(groupId); - EXPECT_EQ((int)NotificationPreferences::GetInstance().RemoveNotificationSlotGroups(bundleEmptyOption_, groupIds), - (int)ERR_ANS_INVALID_PARAM); -} - -/** - * @tc.number : RemoveNotificationSlotGroups_00300 - * @tc.name : - * @tc.desc : Remove a notification group from disturbe DB when group id is null, return is ERR_ANS_INVALID_PARAM - */ -HWTEST_F(NotificationPreferencesTest, RemoveNotificationSlotGroups_00300, Function | SmallTest | Level1) -{ - TestAddNotificationSlotGroup(); - std::vector groupIds; - EXPECT_EQ((int)NotificationPreferences::GetInstance().RemoveNotificationSlotGroups(bundleOption_, groupIds), - (int)ERR_ANS_INVALID_PARAM); -} - -/** - * @tc.number : RemoveNotificationSlotGroups_00400 - * @tc.name : - * @tc.desc : Remove a notification group from disturbe DB when bundle name does not exsit, return is - * ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST - */ -HWTEST_F(NotificationPreferencesTest, RemoveNotificationSlotGroups_00400, Function | SmallTest | Level1) -{ - TestAddNotificationSlotGroup(); - std::vector groupIds; - groupIds.push_back("id"); - EXPECT_EQ((int)NotificationPreferences::GetInstance().RemoveNotificationSlotGroups(noExsitbundleOption_, groupIds), - (int)ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST); -} - -/** - * @tc.number : RemoveNotificationSlotGroups_00500 - * @tc.name : - * @tc.desc : Remove a notification group from disturbe DB when group id does not exsit, return is - * ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_ID_INVALID - */ -HWTEST_F(NotificationPreferencesTest, RemoveNotificationSlotGroups_00500, Function | SmallTest | Level1) -{ - TestAddNotificationSlotGroup(); - std::string groupId = "id1"; - std::vector groupIds; - groupIds.push_back(groupId); - EXPECT_EQ((int)NotificationPreferences::GetInstance().RemoveNotificationSlotGroups(bundleOption_, groupIds), - (int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_ID_INVALID); -} /** * @tc.number : RemoveNotificationForBundle_00100 * @tc.name : @@ -450,82 +289,6 @@ HWTEST_F(NotificationPreferencesTest, UpdateNotificationSlots_00500, Function | (int)ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST); } -/** - * @tc.number : UpdateNotificationSlotGroups_00100 - * @tc.name : - * @tc.desc : Update notification slot group into disturbe DB return is ERR_OK. - */ -HWTEST_F(NotificationPreferencesTest, UpdateNotificationSlotGroups_00100, Function | SmallTest | Level1) -{ - sptr group = new NotificationSlotGroup("id", "name"); - std::vector> groups; - groups.push_back(group); - EXPECT_EQ( - (int)NotificationPreferences::GetInstance().AddNotificationSlotGroups(bundleOption_, groups), (int)ERR_OK); - std::string des("This is a group description."); - group->SetDescription(des); - EXPECT_EQ( - (int)NotificationPreferences::GetInstance().UpdateNotificationSlotGroups(bundleOption_, groups), (int)ERR_OK); -} - -/** - * @tc.number : UpdateNotificationSlotGroups_00200 - * @tc.name : - * @tc.desc : Update notification slot group into disturbe DB when bundle name is null, return is - * ERR_ANS_INVALID_PARAM. - */ -HWTEST_F(NotificationPreferencesTest, UpdateNotificationSlotGroups_00200, Function | SmallTest | Level1) -{ - sptr group = new NotificationSlotGroup("id", "name"); - std::vector> groups; - groups.push_back(group); - EXPECT_EQ((int)NotificationPreferences::GetInstance().UpdateNotificationSlotGroups(bundleEmptyOption_, groups), - (int)ERR_ANS_INVALID_PARAM); -} - -/** - * @tc.number : UpdateNotificationSlotGroups_00300 - * @tc.name : - * @tc.desc : Update notification slot group into disturbe DB when groups is null, return is ERR_ANS_INVALID_PARAM. - */ -HWTEST_F(NotificationPreferencesTest, UpdateNotificationSlotGroups_00300, Function | SmallTest | Level1) -{ - std::vector> groups; - EXPECT_EQ((int)NotificationPreferences::GetInstance().UpdateNotificationSlotGroups(bundleOption_, groups), - (int)ERR_ANS_INVALID_PARAM); -} - -/** - * @tc.number : UpdateNotificationSlotGroups_00400 - * @tc.name : - * @tc.desc : Update notification slot group into disturbe DB when bundle does not exsit, return is - * ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST. - */ -HWTEST_F(NotificationPreferencesTest, UpdateNotificationSlotGroups_00400, Function | SmallTest | Level1) -{ - sptr group = new NotificationSlotGroup("id", "name"); - std::vector> groups; - groups.push_back(group); - EXPECT_EQ((int)NotificationPreferences::GetInstance().UpdateNotificationSlotGroups(noExsitbundleOption_, groups), - (int)ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST); -} - -/** - * @tc.number : UpdateNotificationSlotGroups_00500 - * @tc.name : - * @tc.desc : Update notification slot group into disturbe DB when groupid is null, return is - * ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST - */ -HWTEST_F(NotificationPreferencesTest, UpdateNotificationSlotGroups_00500, Function | SmallTest | Level1) -{ - TestAddNotificationSlotGroup(); - sptr spGroup = new NotificationSlotGroup("", "name"); - std::vector> groups; - groups.push_back(spGroup); - EXPECT_EQ((int)NotificationPreferences::GetInstance().UpdateNotificationSlotGroups(bundleOption_, groups), - (int)ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_NOT_EXIST); -} - /** * @tc.number : GetNotificationSlot_00100 * @tc.name : @@ -648,120 +411,6 @@ HWTEST_F(NotificationPreferencesTest, GetNotificationAllSlots_00400, Function | EXPECT_EQ((int)slotsResult.size(), 0); } -/** - * @tc.number : GetNotificationAllSlotGroups_00100 - * @tc.name : - * @tc.desc : Get all notification slots from disturbe DB, return is ERR_OK. - */ -HWTEST_F(NotificationPreferencesTest, GetNotificationAllSlotGroups_00100, Function | SmallTest | Level1) -{ - TestAddNotificationSlotGroup(); - std::vector> groups; - EXPECT_EQ( - (int)NotificationPreferences::GetInstance().GetNotificationAllSlotGroups(bundleOption_, groups), (int)ERR_OK); - EXPECT_EQ((int)groups.size(), 1); -} - -/** - * @tc.number : GetNotificationAllSlotGroups_00200 - * @tc.name : - * @tc.desc : Get all notification slots from disturbe DB when bundle name is null, return is - * ERR_ANS_INVALID_PARAM - */ -HWTEST_F(NotificationPreferencesTest, GetNotificationAllSlotGroups_00200, Function | SmallTest | Level1) -{ - std::vector> groups; - EXPECT_EQ((int)NotificationPreferences::GetInstance().GetNotificationAllSlotGroups(bundleEmptyOption_, groups), - (int)ERR_ANS_INVALID_PARAM); - EXPECT_EQ((int)groups.size(), 0); -} - -/** - * @tc.number : GetNotificationAllSlotGroups_00300 - * @tc.name : - * @tc.desc : Get all notification slots from disturbe DB when bundle name does not exsit, return is - * ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST - */ -HWTEST_F(NotificationPreferencesTest, GetNotificationAllSlotGroups_00300, Function | SmallTest | Level1) -{ - std::vector> groups; - EXPECT_EQ((int)NotificationPreferences::GetInstance().GetNotificationAllSlotGroups(noExsitbundleOption_, groups), - (int)ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST); - EXPECT_EQ((int)groups.size(), 0); -} - -/** - * @tc.number : GetNotificationAllSlotInSlotGroup_00100 - * @tc.name : - * @tc.desc : Get all notification slots in the same group from disturbe DB , return is ERR_OK. - */ -HWTEST_F(NotificationPreferencesTest, GetNotificationAllSlotInSlotGroup_00100, Function | SmallTest | Level1) -{ - std::string groupId = "groupId"; - sptr group = new NotificationSlotGroup("groupId", "name"); - std::vector> groups; - groups.push_back(group); - NotificationPreferences::GetInstance().AddNotificationSlotGroups(bundleOption_, groups); - - sptr slot = new NotificationSlot(NotificationConstant::SlotType::OTHER); - slot->SetSlotGroup(groupId); - std::vector> slots; - slots.push_back(slot); - NotificationPreferences::GetInstance().AddNotificationSlots(bundleOption_, slots); - std::vector> slotsReuslt; - EXPECT_EQ((int)NotificationPreferences::GetInstance().GetNotificationAllSlotInSlotGroup( - bundleOption_, groupId, slotsReuslt), - (int)ERR_OK); - EXPECT_EQ((int)slotsReuslt.size(), 1); -} - -/** - * @tc.number : GetNotificationAllSlotInSlotGroup_00200 - * @tc.name : - * @tc.desc : Get all notification slots in the same group from disturbe DB when bundle name is null, return is - * ERR_ANS_INVALID_PARAM. - */ -HWTEST_F(NotificationPreferencesTest, GetNotificationAllSlotInSlotGroup_00200, Function | SmallTest | Level1) -{ - std::string groupId = "groupId"; - std::vector> slotsReuslt; - EXPECT_EQ((int)NotificationPreferences::GetInstance().GetNotificationAllSlotInSlotGroup( - bundleEmptyOption_, groupId, slotsReuslt), - (int)ERR_ANS_INVALID_PARAM); - EXPECT_EQ((int)slotsReuslt.size(), 0); -} - -/** - * @tc.number : GetNotificationAllSlotInSlotGroup_00300 - * @tc.name : - * @tc.desc : Get all notification slots in the same group from disturbe DB when group id is null, return is - * ERR_ANS_INVALID_PARAM. - */ -HWTEST_F(NotificationPreferencesTest, GetNotificationAllSlotInSlotGroup_00300, Function | SmallTest | Level1) -{ - std::vector> slotsReuslt; - EXPECT_EQ( - (int)NotificationPreferences::GetInstance().GetNotificationAllSlotInSlotGroup(bundleOption_, "", slotsReuslt), - (int)ERR_ANS_INVALID_PARAM); - EXPECT_EQ((int)slotsReuslt.size(), 0); -} - -/** - * @tc.number : GetNotificationAllSlotInSlotGroup_00400 - * @tc.name : - * @tc.desc : Get all notification slots in the same group from disturbe DB when bundle name does not exsit, return - * is ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST. - */ -HWTEST_F(NotificationPreferencesTest, GetNotificationAllSlotInSlotGroup_00400, Function | SmallTest | Level1) -{ - std::string groupId = "groupId"; - std::vector> slotsReuslt; - EXPECT_EQ((int)NotificationPreferences::GetInstance().GetNotificationAllSlotInSlotGroup( - noExsitbundleOption_, groupId, slotsReuslt), - (int)ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST); - EXPECT_EQ((int)slotsReuslt.size(), 0); -} - /** * @tc.number : SetShowBadge_00100 * @tc.name : diff --git a/services/distributed/src/distributed_database.cpp b/services/distributed/src/distributed_database.cpp index 23f3f80a5..8beb20110 100644 --- a/services/distributed/src/distributed_database.cpp +++ b/services/distributed/src/distributed_database.cpp @@ -99,6 +99,7 @@ void DistributedDatabase::GetKvStore(void) bool DistributedDatabase::CheckKvStore(void) { + std::lock_guard lock(mutex_); if (kvStore_ == nullptr) { GetKvStore(); } @@ -111,11 +112,7 @@ bool DistributedDatabase::CheckKvStore(void) bool DistributedDatabase::OnDeviceConnected() { - std::lock_guard lock(mutex_); - if (!CheckKvStore()) { - return false; - } - return true; + return CheckKvStore(); } bool DistributedDatabase::PutToDistributedDB(const std::string &key, const std::string &value) diff --git a/services/test/moduletest/ans_module_test.cpp b/services/test/moduletest/ans_module_test.cpp index 6822d4e82..fef7b49d4 100644 --- a/services/test/moduletest/ans_module_test.cpp +++ b/services/test/moduletest/ans_module_test.cpp @@ -1151,20 +1151,10 @@ HWTEST_F(AnsModuleTest, AnsModuleTest_0054, Function | SmallTest | Level1) { // add slot std::vector> slots; - sptr group = new NotificationSlotGroup("id", "name"); sptr socialSlot = new NotificationSlot(NotificationConstant::SlotType::SOCIAL_COMMUNICATION); sptr reminderSlot = new NotificationSlot(NotificationConstant::SlotType::SERVICE_REMINDER); sptr contentSlot = new NotificationSlot(NotificationConstant::SlotType::CONTENT_INFORMATION); sptr otherSlot = new NotificationSlot(NotificationConstant::SlotType::OTHER); - socialSlot->SetSlotGroup(group->GetId()); - reminderSlot->SetSlotGroup(group->GetId()); - contentSlot->SetSlotGroup(group->GetId()); - otherSlot->SetSlotGroup(group->GetId()); - - // add slot group - std::vector> slotGroups; - slotGroups.push_back(group); - g_advancedNotificationService->AddSlotGroups(slotGroups); slots.push_back(socialSlot); slots.push_back(reminderSlot); @@ -1183,9 +1173,7 @@ HWTEST_F(AnsModuleTest, AnsModuleTest_0055, Function | SmallTest | Level1) { // add slot std::vector> slots; - sptr group = new NotificationSlotGroup("id", "name"); sptr socialSlot = new NotificationSlot(NotificationConstant::SlotType::SOCIAL_COMMUNICATION); - socialSlot->SetSlotGroup(group->GetId()); slots.push_back(socialSlot); EXPECT_EQ(g_advancedNotificationService->AddSlots(slots), 0); @@ -1201,17 +1189,9 @@ HWTEST_F(AnsModuleTest, AnsModuleTest_0056, Function | SmallTest | Level1) { // add slot std::vector> slots; - sptr group = new NotificationSlotGroup("id", "name"); sptr socialSlot = new NotificationSlot(NotificationConstant::SlotType::SOCIAL_COMMUNICATION); - socialSlot->SetSlotGroup(group->GetId()); slots.push_back(socialSlot); EXPECT_EQ(g_advancedNotificationService->AddSlots(slots), 0); - - // get slot group by groupId - group = nullptr; - g_advancedNotificationService->GetSlotGroup("id", group); - EXPECT_FALSE(group != nullptr); - // remove slot group EXPECT_EQ(g_advancedNotificationService->RemoveSlotByType(NotificationConstant::SlotType::SOCIAL_COMMUNICATION), 0); } @@ -2439,20 +2419,13 @@ HWTEST_F(AnsModuleTest, AnsModuleTest_0127, Function | SmallTest | Level1) sortingMap) { ret++; }; // add slot - sptr group = new NotificationSlotGroup("id", "name"); std::vector> slots; sptr slot = new NotificationSlot(NotificationConstant::SlotType::SOCIAL_COMMUNICATION); sptr slot1 = new NotificationSlot(NotificationConstant::SlotType::SERVICE_REMINDER); slots.push_back(slot); slots.push_back(slot1); - slot->SetSlotGroup(group->GetId()); g_advancedNotificationService->AddSlots(slots); - // add slot group - std::vector> slotGroups; - slotGroups.push_back(group); - g_advancedNotificationService->AddSlotGroups(slotGroups); - // create content std::shared_ptr contentImpl = std::make_shared(); contentImpl->SetText("1"); @@ -2500,20 +2473,13 @@ HWTEST_F(AnsModuleTest, AnsModuleTest_0128, Function | SmallTest | Level1) sortingMap) { ret++; }; // add slot - sptr group = new NotificationSlotGroup("id", "name"); std::vector> slots; sptr slot = new NotificationSlot(NotificationConstant::SlotType::CONTENT_INFORMATION); sptr slot1 = new NotificationSlot(NotificationConstant::SlotType::OTHER); slots.push_back(slot); slots.push_back(slot1); - slot->SetSlotGroup(group->GetId()); g_advancedNotificationService->AddSlots(slots); - // add slot group - std::vector> slotGroups; - slotGroups.push_back(group); - g_advancedNotificationService->AddSlotGroups(slotGroups); - // create content std::shared_ptr contentImpl = std::make_shared(); contentImpl->SetText("1"); diff --git a/test/bechmarktest/notification_services_test/notification_service_test.cpp b/test/bechmarktest/notification_services_test/notification_service_test.cpp index 4968862a2..0f3c6001e 100644 --- a/test/bechmarktest/notification_services_test/notification_service_test.cpp +++ b/test/bechmarktest/notification_services_test/notification_service_test.cpp @@ -127,52 +127,6 @@ BENCHMARK_F(BenchmarkNotificationService, RemoveSlotByTypeTestCase)(benchmark::S } } -/** - * @tc.name: AddSlotGroupTestCase - * @tc.desc: AddSlotGroup - * @tc.type: FUNC - * @tc.require: - */ -BENCHMARK_F(BenchmarkNotificationService, AddSlotGroupTestCase)(benchmark::State &state) -{ - std::vector> groups; - sptr group = new NotificationSlotGroup("id0", "name0"); - groups.push_back(group); - while (state.KeepRunning()) { - ErrCode errCode = advancedNotificationService_->AddSlotGroups(groups); - if (errCode != ERR_OK) { - state.SkipWithError("AddSlotGroupTestCase failed."); - } - } -} - -/** - * @tc.name: RemoveSlotGroupsTestCase - * @tc.desc: RemoveSlotGroups - * @tc.type: FUNC - * @tc.require: - */ -BENCHMARK_F(BenchmarkNotificationService, RemoveSlotGroupsTestCase)(benchmark::State &state) -{ - std::vector> groups; - sptr group = new NotificationSlotGroup("id0", "name0"); - groups.push_back(group); - std::vector groupIds; - groupIds.push_back("id0"); - - while (state.KeepRunning()) { - ErrCode errCode = advancedNotificationService_->AddSlotGroups(groups); - if (errCode != ERR_OK) { - state.SkipWithError("RemoveSlotGroupsTestCase add failed."); - } - - errCode = advancedNotificationService_->RemoveSlotGroups(groupIds); - if (errCode != ERR_OK) { - state.SkipWithError("RemoveSlotGroupsTestCase remove failed."); - } - } -} - /** * @tc.name: SubscribeTestCase * @tc.desc: Subscribe diff --git a/test/fuzztest/BUILD.gn b/test/fuzztest/BUILD.gn index 558518d3a..be7f24d4a 100644 --- a/test/fuzztest/BUILD.gn +++ b/test/fuzztest/BUILD.gn @@ -15,17 +15,14 @@ group("fuzztest") { testonly = true deps = [ - "addnotificationslotgroups_fuzzer:AddNotificationSlotGroupsFuzzTest", "addnotificationslots_fuzzer:AddNotificationSlotsFuzzTest", "addslotbytype_fuzzer:AddSlotByTypeFuzzTest", "cancelnotification_fuzzer:CancelNotificationFuzzTest", "getnotificationslot_fuzzer:GetNotificationSlotFuzzTest", - "getnotificationslotgroup_fuzzer:GetNotificationSlotGroupFuzzTest", "getnotificationslotnumasbundle_fuzzer:GetNotificationSlotNumAsBundleFuzzTest", "publishnotification_fuzzer:PublishNotificationFuzzTest", "removenotification_fuzzer:RemoveNotificationFuzzTest", "removenotificationslot_fuzzer:RemoveNotificationSlotFuzzTest", - "removenotificationslotgroup_fuzzer:RemoveNotificationSlotGroupFuzzTest", "setnotificationbadgenum_fuzzer:SetNotificationBadgeNumFuzzTest", ] } diff --git a/test/fuzztest/addnotificationslotgroups_fuzzer/BUILD.gn b/test/fuzztest/addnotificationslotgroups_fuzzer/BUILD.gn deleted file mode 100644 index c03d4364f..000000000 --- a/test/fuzztest/addnotificationslotgroups_fuzzer/BUILD.gn +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) 2022 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. - -#####################hydra-fuzz################### -import("//base/notification/distributed_notification_service/notification.gni") -import("//build/config/features.gni") -import("//build/test.gni") -module_output_path = "${component_name}/fuzztest" - -##############################fuzztest########################################## -ohos_fuzztest("AddNotificationSlotGroupsFuzzTest") { - module_out_path = module_output_path - fuzz_config_file = - "${component_path}/test/fuzztest/addnotificationslotgroups_fuzzer" - - include_dirs = [] - cflags = [ - "-g", - "-O0", - "-Wno-unused-variable", - "-fno-omit-frame-pointer", - ] - sources = [ "addnotificationslotgroups_fuzzer.cpp" ] - - deps = [ "${frameworks_module_ans_path}:ans_innerkits" ] - - external_deps = [ - "ability_base:want", - "ability_base:zuri", - "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", - "multimedia_image_standard:image_native", - "relational_store:native_rdb", - ] -} - -############################################################################### -group("fuzztest") { - testonly = true - deps = [] - deps += [ ":AddNotificationSlotGroupsFuzzTest" ] -} -############################################################################### diff --git a/test/fuzztest/addnotificationslotgroups_fuzzer/addnotificationslotgroups_fuzzer.cpp b/test/fuzztest/addnotificationslotgroups_fuzzer/addnotificationslotgroups_fuzzer.cpp deleted file mode 100644 index 49af1e97c..000000000 --- a/test/fuzztest/addnotificationslotgroups_fuzzer/addnotificationslotgroups_fuzzer.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2022 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 "addnotificationslotgroups_fuzzer.h" - -#define private public -#include "notification_helper.h" -#undef private - -namespace OHOS { - bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size) - { - std::string description = reinterpret_cast(data); - Notification::NotificationSlotGroup group; - group.SetDescription(description); - - Notification::NotificationSlot slot; - std::vector slots; - slots.emplace_back(slot); - group.SetSlots(slots); - - std::vector groups; - groups.emplace_back(group); - return Notification::NotificationHelper::AddNotificationSlotGroups(groups) == ERR_OK; - } -} - -/* Fuzzer entry point */ -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) -{ - /* Run your code on data */ - OHOS::DoSomethingInterestingWithMyAPI(data, size); - return 0; -} diff --git a/test/fuzztest/addnotificationslotgroups_fuzzer/addnotificationslotgroups_fuzzer.h b/test/fuzztest/addnotificationslotgroups_fuzzer/addnotificationslotgroups_fuzzer.h deleted file mode 100644 index ff2c49f89..000000000 --- a/test/fuzztest/addnotificationslotgroups_fuzzer/addnotificationslotgroups_fuzzer.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2022 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 TEST_FUZZTEST_ADDNOTIFICATIONSLOTGROUPS_FUZZER_ADDNOTIFICATIONSLOTGROUPS_FUZZER_H -#define TEST_FUZZTEST_ADDNOTIFICATIONSLOTGROUPS_FUZZER_ADDNOTIFICATIONSLOTGROUPS_FUZZER_H - -#define FUZZ_PROJECT_NAME "addnotificationslotgroups_fuzzer" - -#include - -uint32_t U32_AT(const uint8_t *ptr) -{ - // convert fuzz input data to an integer - return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]; -} - -#endif // TEST_FUZZTEST_ADDNOTIFICATIONSLOTGROUPS_FUZZER_ADDNOTIFICATIONSLOTGROUPS_FUZZER_H diff --git a/test/fuzztest/addnotificationslotgroups_fuzzer/corpus/init b/test/fuzztest/addnotificationslotgroups_fuzzer/corpus/init deleted file mode 100644 index 1b910144f..000000000 --- a/test/fuzztest/addnotificationslotgroups_fuzzer/corpus/init +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2022 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. -FUZZ \ No newline at end of file diff --git a/test/fuzztest/addnotificationslotgroups_fuzzer/project.xml b/test/fuzztest/addnotificationslotgroups_fuzzer/project.xml deleted file mode 100644 index 6e8ad2cfd..000000000 --- a/test/fuzztest/addnotificationslotgroups_fuzzer/project.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - 1000 - - 300 - - 4096 - - diff --git a/test/fuzztest/addnotificationslots_fuzzer/addnotificationslots_fuzzer.cpp b/test/fuzztest/addnotificationslots_fuzzer/addnotificationslots_fuzzer.cpp index 30aa44aad..652be8a9c 100644 --- a/test/fuzztest/addnotificationslots_fuzzer/addnotificationslots_fuzzer.cpp +++ b/test/fuzztest/addnotificationslots_fuzzer/addnotificationslots_fuzzer.cpp @@ -43,8 +43,6 @@ namespace OHOS { Notification::NotificationConstant::VisiblenessType(visibleness); slot.SetLockscreenVisibleness(visiblenessType); - slot.SetSlotGroup(stringData); - uint8_t type = *data % SLOT_TYPE_NUM; Notification::NotificationConstant::SlotType slotType = Notification::NotificationConstant::SlotType(type); slot.SetType(slotType); diff --git a/test/fuzztest/getnotificationslotgroup_fuzzer/BUILD.gn b/test/fuzztest/getnotificationslotgroup_fuzzer/BUILD.gn deleted file mode 100644 index caa0f2b1f..000000000 --- a/test/fuzztest/getnotificationslotgroup_fuzzer/BUILD.gn +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) 2022 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. - -#####################hydra-fuzz################### -import("//base/notification/distributed_notification_service/notification.gni") -import("//build/config/features.gni") -import("//build/test.gni") -module_output_path = "${component_name}/fuzztest" - -##############################fuzztest########################################## -ohos_fuzztest("GetNotificationSlotGroupFuzzTest") { - module_out_path = module_output_path - fuzz_config_file = - "${component_path}/test/fuzztest/getnotificationslotgroup_fuzzer" - - include_dirs = [] - cflags = [ - "-g", - "-O0", - "-Wno-unused-variable", - "-fno-omit-frame-pointer", - ] - sources = [ "getnotificationslotgroup_fuzzer.cpp" ] - - deps = [ "${frameworks_module_ans_path}:ans_innerkits" ] - - external_deps = [ - "ability_base:want", - "ability_base:zuri", - "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", - "multimedia_image_standard:image_native", - "relational_store:native_rdb", - ] -} - -############################################################################### -group("fuzztest") { - testonly = true - deps = [] - deps += [ ":GetNotificationSlotGroupFuzzTest" ] -} -############################################################################### diff --git a/test/fuzztest/getnotificationslotgroup_fuzzer/corpus/init b/test/fuzztest/getnotificationslotgroup_fuzzer/corpus/init deleted file mode 100644 index 1b910144f..000000000 --- a/test/fuzztest/getnotificationslotgroup_fuzzer/corpus/init +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2022 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. -FUZZ \ No newline at end of file diff --git a/test/fuzztest/getnotificationslotgroup_fuzzer/getnotificationslotgroup_fuzzer.cpp b/test/fuzztest/getnotificationslotgroup_fuzzer/getnotificationslotgroup_fuzzer.cpp deleted file mode 100644 index 8529f71dd..000000000 --- a/test/fuzztest/getnotificationslotgroup_fuzzer/getnotificationslotgroup_fuzzer.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2022 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 "getnotificationslotgroup_fuzzer.h" - -#include "notification_helper.h" - -namespace OHOS { - bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size) - { - std::string groupId = reinterpret_cast(data); - sptr group = nullptr; - return Notification::NotificationHelper::GetNotificationSlotGroup(groupId, group) == ERR_OK; - } -} - -/* Fuzzer entry point */ -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) -{ - /* Run your code on data */ - OHOS::DoSomethingInterestingWithMyAPI(data, size); - return 0; -} diff --git a/test/fuzztest/getnotificationslotgroup_fuzzer/getnotificationslotgroup_fuzzer.h b/test/fuzztest/getnotificationslotgroup_fuzzer/getnotificationslotgroup_fuzzer.h deleted file mode 100644 index 529d8be3c..000000000 --- a/test/fuzztest/getnotificationslotgroup_fuzzer/getnotificationslotgroup_fuzzer.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2022 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 TEST_FUZZTEST_GETNOTIFICATIONSLOTGROUP_FUZZER_GETNOTIFICATIONSLOTGROUP_FUZZER_H -#define TEST_FUZZTEST_GETNOTIFICATIONSLOTGROUP_FUZZER_GETNOTIFICATIONSLOTGROUP_FUZZER_H - -#define FUZZ_PROJECT_NAME "getnotificationslotgroups_fuzzer" - -#endif // TEST_FUZZTEST_GETNOTIFICATIONSLOTGROUP_FUZZER_GETNOTIFICATIONSLOTGROUP_FUZZER_H diff --git a/test/fuzztest/getnotificationslotgroup_fuzzer/project.xml b/test/fuzztest/getnotificationslotgroup_fuzzer/project.xml deleted file mode 100644 index 6e8ad2cfd..000000000 --- a/test/fuzztest/getnotificationslotgroup_fuzzer/project.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - 1000 - - 300 - - 4096 - - diff --git a/test/fuzztest/removenotificationslotgroup_fuzzer/BUILD.gn b/test/fuzztest/removenotificationslotgroup_fuzzer/BUILD.gn deleted file mode 100644 index d4b2558ff..000000000 --- a/test/fuzztest/removenotificationslotgroup_fuzzer/BUILD.gn +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) 2022 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. - -#####################hydra-fuzz################### -import("//base/notification/distributed_notification_service/notification.gni") -import("//build/config/features.gni") -import("//build/test.gni") -module_output_path = "${component_name}/fuzztest" - -##############################fuzztest########################################## -ohos_fuzztest("RemoveNotificationSlotGroupFuzzTest") { - module_out_path = module_output_path - fuzz_config_file = - "${component_path}/test/fuzztest/removenotificationslotgroup_fuzzer" - - include_dirs = [] - cflags = [ - "-g", - "-O0", - "-Wno-unused-variable", - "-fno-omit-frame-pointer", - ] - sources = [ "removenotificationslotgroup_fuzzer.cpp" ] - - deps = [ "${frameworks_module_ans_path}:ans_innerkits" ] - - external_deps = [ - "ability_base:want", - "ability_base:zuri", - "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", - "multimedia_image_standard:image_native", - "relational_store:native_rdb", - ] -} - -############################################################################### -group("fuzztest") { - testonly = true - deps = [] - deps += [ ":RemoveNotificationSlotGroupFuzzTest" ] -} -############################################################################### diff --git a/test/fuzztest/removenotificationslotgroup_fuzzer/corpus/init b/test/fuzztest/removenotificationslotgroup_fuzzer/corpus/init deleted file mode 100644 index 1b910144f..000000000 --- a/test/fuzztest/removenotificationslotgroup_fuzzer/corpus/init +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2022 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. -FUZZ \ No newline at end of file diff --git a/test/fuzztest/removenotificationslotgroup_fuzzer/project.xml b/test/fuzztest/removenotificationslotgroup_fuzzer/project.xml deleted file mode 100644 index 6e8ad2cfd..000000000 --- a/test/fuzztest/removenotificationslotgroup_fuzzer/project.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - 1000 - - 300 - - 4096 - - diff --git a/test/fuzztest/removenotificationslotgroup_fuzzer/removenotificationslotgroup_fuzzer.cpp b/test/fuzztest/removenotificationslotgroup_fuzzer/removenotificationslotgroup_fuzzer.cpp deleted file mode 100644 index 50b4ede4b..000000000 --- a/test/fuzztest/removenotificationslotgroup_fuzzer/removenotificationslotgroup_fuzzer.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2022 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 "removenotificationslotgroup_fuzzer.h" - -#include "notification_helper.h" - -namespace OHOS { - bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size) - { - std::string slotGroupId = reinterpret_cast(data); - return Notification::NotificationHelper::RemoveNotificationSlotGroup(slotGroupId) == ERR_OK; - } -} - -/* Fuzzer entry point */ -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) -{ - /* Run your code on data */ - OHOS::DoSomethingInterestingWithMyAPI(data, size); - return 0; -} diff --git a/test/fuzztest/removenotificationslotgroup_fuzzer/removenotificationslotgroup_fuzzer.h b/test/fuzztest/removenotificationslotgroup_fuzzer/removenotificationslotgroup_fuzzer.h deleted file mode 100644 index 2b1fd85bc..000000000 --- a/test/fuzztest/removenotificationslotgroup_fuzzer/removenotificationslotgroup_fuzzer.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2022 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 TEST_FUZZTEST_REMOVENOTIFICATIONSLOTGROUP_FUZZER_REMOVENOTIFICATIONSLOTGROUP_FUZZER_H -#define TEST_FUZZTEST_REMOVENOTIFICATIONSLOTGROUP_FUZZER_REMOVENOTIFICATIONSLOTGROUP_FUZZER_H - -#define FUZZ_PROJECT_NAME "removenotificationslotgroup_fuzzer" - -#endif // TEST_FUZZTEST_REMOVENOTIFICATIONSLOTGROUP_FUZZER_REMOVENOTIFICATIONSLOTGROUP_FUZZER_H diff --git a/test/resource/ansSTSlotGroupTest/BUILD.gn b/test/resource/ansSTSlotGroupTest/BUILD.gn deleted file mode 100644 index d0b5b333f..000000000 --- a/test/resource/ansSTSlotGroupTest/BUILD.gn +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2021 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") -import("//build/test.gni") - -SUBDEMOSYSTEM_DIR = "${component_path}/test/resource/ansSTSlotGroupTest" - -group("ansSTSlotGroupTest") { - deps = [ ":libraryAnsSTSlotGroupTest" ] -} - -config("ansSTSlotGroupTestConfig") { - visibility = [ ":*" ] - - include_dirs = [ - "${SUBDEMOSYSTEM_DIR}/include", - "${ability_runtime_path}/interfaces/kits/native/appkit/app", - "${ability_runtime_services_path}/abilitymgr/include", - "${inner_api_path}", - ] -} - -ohos_shared_library("libraryAnsSTSlotGroupTest") { - sources = [ "${SUBDEMOSYSTEM_DIR}/src/ans_slotgroup_test.cpp" ] - - configs = [ ":ansSTSlotGroupTestConfig" ] - - deps = [ - "${ability_runtime_path}/frameworks/native/appkit:appkit_native", - "${core_path}:ans_core", - "${frameworks_module_ans_path}:ans_innerkits", - ] - - external_deps = [ - "ability_base:want", - "ability_runtime:abilitykit_native", - "ability_runtime:wantagent_innerkits", - "bundle_framework:appexecfwk_base", - "bundle_framework:appexecfwk_core", - "c_utils:utilsbase", - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", - ] - - subsystem_name = "${subsystem_name}" - part_name = "${subsystem_name}" -} diff --git a/test/resource/ansSTSlotGroupTest/config.json b/test/resource/ansSTSlotGroupTest/config.json deleted file mode 100644 index 9228a94af..000000000 --- a/test/resource/ansSTSlotGroupTest/config.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "app":{ - "bundleName": "com.ohos.ansst.ansSTSlotGroup", - "vendor": "ix", - "version": { - "code": 1, - "name": "1.0" - }, - "apiVersion": { - "compatible": 3, - "target": 3 - } - }, - "deviceConfig": { - "default": { - } - }, - "module": { - "package":"com.hos.AnsSlotGroupSystemTest.src", - "name":"AnsSlotGroupSystemTest", - "deviceType": [ - "tv", - "car" - ], - "distro": { - "deliveryWithInstall": true, - "moduleName": "testability", - "moduleType": "entry" - }, - "abilities": [{ - "name": "AnsSlotGroupSystemTest", - "icon": "$media:snowball", - "srcLanguage": "c++", - "label": "AnsSlotGroupSystemTest Ability zofa label", - "launchType": "singletop", - "orientation": "unspecified", - "type": "page", - "visible": true - }] - } -} \ No newline at end of file diff --git a/test/resource/ansSTSlotGroupTest/include/ans_slotgroup_test.h b/test/resource/ansSTSlotGroupTest/include/ans_slotgroup_test.h deleted file mode 100644 index 4e20ffb27..000000000 --- a/test/resource/ansSTSlotGroupTest/include/ans_slotgroup_test.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2021 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 _ans_st_slotgroup_ -#define _ans_st_slotgroup_ - -#include -#include "ability_loader.h" -#include "notification_helper.h" -#ifdef PRINT_LOG -#undef PRINT_LOG -#endif -#include "app_log_wrapper.h" - -namespace OHOS { -namespace AppExecFwk { -class AnsSlotGroupSystemTest : public Ability { -protected: - virtual void OnStart(const Want &want) override; - virtual void OnStop() override; - virtual void OnActive() override; - virtual void OnInactive() override; - virtual void OnBackground() override; - virtual void OnForeground(const Want &want) override; - virtual void OnNewWant(const Want &want) override; - -private: - void Clear(); - void GetWantInfo(const Want &want); - - std::string shouldReturn; - std::string targetBundle; - std::string targetAbility; -}; -} // namespace AppExecFwk -} // namespace OHOS -#endif \ No newline at end of file diff --git a/test/resource/ansSTSlotGroupTest/src/ans_slotgroup_test.cpp b/test/resource/ansSTSlotGroupTest/src/ans_slotgroup_test.cpp deleted file mode 100644 index ac933f801..000000000 --- a/test/resource/ansSTSlotGroupTest/src/ans_slotgroup_test.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2021 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 "ans_slotgroup_test.h" -#include "notification_slot_group.h" - -namespace OHOS { -namespace AppExecFwk { -void AnsSlotGroupSystemTest::OnStart(const Want &want) -{ - APP_LOGI("====>Ans SlotGroup test start:====>"); - Notification::NotificationSlotGroup slotGroupTest("id_test", "name_test"); - if (slotGroupTest.GetId().empty()) { - ANS_LOGI("====>Notification slot group id is invalid====>"); - } else { - ANS_LOGI("====>Notification slot group id is====> %{public}s", slotGroupTest.GetId().c_str()); - } - ErrCode errAddGroupTest = Notification::NotificationHelper::AddNotificationSlotGroup(slotGroupTest); - APP_LOGI("====>add a SlotGroup with id name id_test, ErrCode is====> %{public}d", errAddGroupTest); - - Notification::NotificationSlot slotFirst(Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION); - Notification::NotificationSlot slotSecond(Notification::NotificationConstant::SlotType::SERVICE_REMINDER); - Notification::NotificationSlot slotThird(Notification::NotificationConstant::SlotType::CONTENT_INFORMATION); - Notification::NotificationSlot slotFourth(Notification::NotificationConstant::SlotType::OTHER); - Notification::NotificationSlot slotFifth(Notification::NotificationConstant::SlotType::CUSTOM); - - slotFirst.SetSlotGroup("id_test"); - slotSecond.SetSlotGroup("id_test"); - slotThird.SetSlotGroup("id_test"); - slotFourth.SetSlotGroup("id_test"); - slotFifth.SetSlotGroup("id_test"); - - ErrCode errAddSlotFirst = Notification::NotificationHelper::AddNotificationSlot(slotFirst); - ErrCode errAddSlotSecond = Notification::NotificationHelper::AddNotificationSlot(slotSecond); - ErrCode errAddSlotThird = Notification::NotificationHelper::AddNotificationSlot(slotThird); - ErrCode errAddSlotFourth = Notification::NotificationHelper::AddNotificationSlot(slotFourth); - ErrCode errAddSlotFifth = Notification::NotificationHelper::AddNotificationSlot(slotFifth); - - APP_LOGI("====>add SOCIAL_COMMUNICATION type slot, ErrCode is====> %{public}d", errAddSlotFirst); - APP_LOGI("====>add SERVICE_REMINDER type slot, ErrCode is====> %{public}d", errAddSlotSecond); - APP_LOGI("====>add CONTENT_INFORMATION type slot, ErrCode is====> %{public}d", errAddSlotThird); - APP_LOGI("====>add OTHER type slot, ErrCode is====> %{public}d", errAddSlotFourth); - APP_LOGI("====>add CUSTOM type slot, ErrCode is====> %{public}d", errAddSlotFifth); - - sptr group; - ErrCode errcodeGet = Notification::NotificationHelper::GetNotificationSlotGroup("id_test", group); - APP_LOGI("====>get SlotGroup after adding SlotGroup and slots, ErrCode is====> %{public}d", errcodeGet); - if (group != nullptr) { - std::string dumpGroupStr = group->Dump(); - APP_LOGI("====>obtained group dump====> %{public}s", dumpGroupStr.c_str()); - APP_LOGI("====>the number of slots in the obtained group====> %{public}zu", group->GetSlots().size()); - - ErrCode errcodeRem = Notification::NotificationHelper::RemoveNotificationSlotGroup("id_test"); - APP_LOGI("====>remove the group whose id is id_test, ErrCode is====> %{public}d", errcodeRem); - sptr groupTwo; - ErrCode errcodeGetTwo = Notification::NotificationHelper::GetNotificationSlotGroup("id_test", groupTwo); - APP_LOGI("====>get SlotGroup after removing SlotGroup, ErrCode is====> %{public}d", errcodeGetTwo); - - ErrCode errAddGroupTestSecond = Notification::NotificationHelper::AddNotificationSlotGroup(slotGroupTest); - APP_LOGI("====>add SlotGroup again with id name id_test, ErrCode is====> %{public}d", errAddGroupTestSecond); - sptr groupSecond; - ErrCode errcodeGetSecond = Notification::NotificationHelper::GetNotificationSlotGroup("id_test", groupSecond); - APP_LOGI("====>get SlotGroup again after adding SlotGroup again, ErrCode is: %{public}d", errcodeGetSecond); - if (groupSecond != nullptr) { - dumpGroupStr = groupSecond->Dump(); - APP_LOGI("====>the second time obtained group dump====> %{public}s", dumpGroupStr.c_str()); - APP_LOGI("====>the number of slots in second obtained group: %{public}zu", groupSecond->GetSlots().size()); - - Notification::NotificationSlotGroup slotGroupFirst("id_first", "name_first"); - ErrCode errAddGroupFirst = Notification::NotificationHelper::AddNotificationSlotGroup(slotGroupFirst); - APP_LOGI("====>add SlotGroup with id name id_first, ErrCode is====> %{public}d", errAddGroupFirst); - - Notification::NotificationSlotGroup slotGroupSecond("id_second", "name_second"); - ErrCode errAddGroupSecond = Notification::NotificationHelper::AddNotificationSlotGroup(slotGroupSecond); - APP_LOGI("====>add SlotGroup with id name id_second, ErrCode is====> %{public}d", errAddGroupSecond); - - Notification::NotificationSlotGroup slotGroupThird("id_third", "name_third"); - ErrCode errAddGroupThird = Notification::NotificationHelper::AddNotificationSlotGroup(slotGroupThird); - APP_LOGI("====>add SlotGroup with id name id_third, ErrCode is====> %{public}d", errAddGroupThird); - - Notification::NotificationSlotGroup slotGroupFourth("id_fourth", "name_fourth"); - ErrCode errAddGroupFourth = Notification::NotificationHelper::AddNotificationSlotGroup(slotGroupFourth); - APP_LOGI("====>add SlotGroup with id name id_fourth, ErrCode is====> %{public}d", errAddGroupFourth); - - Notification::NotificationSlotGroup slotGroupFifth("id_fifth", "name_fifth"); - ErrCode errAddGroupFifth = Notification::NotificationHelper::AddNotificationSlotGroup(slotGroupFifth); - APP_LOGI("====>add SlotGroup with id name id_fifth, ErrCode is====> %{public}d", errAddGroupFifth); - } else { - ANS_LOGI("====>fail to get group after adding SlotGroup for the second time====>"); - } - } else { - ANS_LOGI("====>fail to get group after adding SlotGroup and slots for the first time====>"); - } - - Ability::OnStart(want); -} - -void AnsSlotGroupSystemTest::OnNewWant(const Want &want) -{ - GetWantInfo(want); - Ability::OnNewWant(want); -} - -void AnsSlotGroupSystemTest::OnForeground(const Want &want) -{ - GetWantInfo(want); - Ability::OnForeground(want); -} - -void AnsSlotGroupSystemTest::OnStop() -{ - Ability::OnStop(); -} - -void AnsSlotGroupSystemTest::OnActive() -{ - Ability::OnActive(); - if (std::string::npos != shouldReturn.find(GetAbilityName())) { - TerminateAbility(); - } - Clear(); -} - -void AnsSlotGroupSystemTest::OnInactive() -{ - Ability::OnInactive(); -} - -void AnsSlotGroupSystemTest::OnBackground() -{ - Ability::OnBackground(); -} - -void AnsSlotGroupSystemTest::Clear() -{ - shouldReturn = ""; - targetBundle = ""; - targetAbility = ""; -} - -void AnsSlotGroupSystemTest::GetWantInfo(const Want &want) -{ - Want mWant(want); - shouldReturn = mWant.GetStringParam("shouldReturn"); - targetBundle = mWant.GetStringParam("targetBundle"); - targetAbility = mWant.GetStringParam("targetAbility"); -} - -REGISTER_AA(AnsSlotGroupSystemTest) -} // namespace AppExecFwk -} // namespace OHOS \ No newline at end of file diff --git a/test/resource/ansSlotGroupHap/AnsSTSlotGroupTest.hap b/test/resource/ansSlotGroupHap/AnsSTSlotGroupTest.hap deleted file mode 100644 index 0132daeec68f4c4e81ce4f02e6352cec88a7be96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110986 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
  • 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 DGg+=t diff --git a/test/resource/notificationfuzztest/include/notificationgetparam.h b/test/resource/notificationfuzztest/include/notificationgetparam.h index 873d64e3a..e083a2b26 100644 --- a/test/resource/notificationfuzztest/include/notificationgetparam.h +++ b/test/resource/notificationfuzztest/include/notificationgetparam.h @@ -96,9 +96,6 @@ sptr GetParamNotificationSlotSptr(); OHOS::Notification::NotificationConstant::SlotType GetParamSlotType(); std::vector> GetParamNotificationSlotSptrVector(); std::vector GetParamNotificationSlotVector(); -std::vector GetParamNotificationSlotGroupVector(); -sptr GetParamNotificationSlotGroup(); -std::vector> GetParamNotificationSlotGroupSptrVector(); std::shared_ptr GetParamNotificationBundleOption(); std::shared_ptr GetParamNotificationRequest(); std::vector> GetParamNotificationRequestVector(); diff --git a/test/resource/notificationfuzztest/notificationfuzzconfig/config.json b/test/resource/notificationfuzztest/notificationfuzzconfig/config.json index a7fc3f8c8..446dcbb6c 100644 --- a/test/resource/notificationfuzztest/notificationfuzzconfig/config.json +++ b/test/resource/notificationfuzztest/notificationfuzzconfig/config.json @@ -37,11 +37,6 @@ "RemoveAllSlots": [], "GetNotificationSlot": [], "GetNotificationSlots": [], - "AddNotificationSlotGroup": [], - "AddNotificationSlotGroups": [], - "RemoveNotificationSlotGroup": [], - "GetNotificationSlotGroup": [], - "GetNotificationSlotGroups": [], "GetNotificationSlotNumAsBundle": [], "PublishNotificationNotificationRequest": [], "PublishNotificationstringNotificationRequest": [], @@ -73,7 +68,6 @@ "RemoveNotifications": [], "GetNotificationSlotsForBundle": [], "UpdateNotificationSlots": [], - "UpdateNotificationSlotGroups": [], "GetAllActiveNotificationsNotification": [], "GetAllActiveNotificationsstringNotification": [], "IsAllowedNotify": [], diff --git a/test/resource/notificationfuzztest/src/notificationfuzztestmanager.cpp b/test/resource/notificationfuzztest/src/notificationfuzztestmanager.cpp index bb4702414..09ac94234 100644 --- a/test/resource/notificationfuzztest/src/notificationfuzztestmanager.cpp +++ b/test/resource/notificationfuzztest/src/notificationfuzztestmanager.cpp @@ -51,26 +51,6 @@ void NotificationFuzzTestManager::RegisterNotificationHelper() OHOS::Notification::NotificationHelper::GetNotificationSlots(param); }); - callFunctionMap_.emplace("NotificationHelperAddNotificationSlotGroup", - []() { OHOS::Notification::NotificationHelper::AddNotificationSlotGroup(*GetParamNotificationSlotGroup()); }); - - callFunctionMap_.emplace("NotificationHelperAddNotificationSlotGroups", []() { - OHOS::Notification::NotificationHelper::AddNotificationSlotGroups(GetParamNotificationSlotGroupVector()); - }); - - callFunctionMap_.emplace("NotificationHelperRemoveNotificationSlotGroup", - []() { OHOS::Notification::NotificationHelper::RemoveNotificationSlotGroup(GetStringParam()); }); - - callFunctionMap_.emplace("NotificationHelperGetNotificationSlotGroup", []() { - sptr param = GetParamNotificationSlotGroup(); - OHOS::Notification::NotificationHelper::GetNotificationSlotGroup(GetStringParam(), param); - }); - - callFunctionMap_.emplace("NotificationHelperGetNotificationSlotGroups", []() { - std::vector> param = GetParamNotificationSlotGroupSptrVector(); - OHOS::Notification::NotificationHelper::GetNotificationSlotGroups(param); - }); - callFunctionMap_.emplace("NotificationHelperGetNotificationSlotNumAsBundle", []() { int param = GetIntParam(); OHOS::Notification::NotificationHelper::GetNotificationSlotNumAsBundle( @@ -309,11 +289,6 @@ void NotificationFuzzTestManager::RegisterNotificationHelper() *GetParamNotificationBundleOption(), GetParamNotificationSlotSptrVector()); }); - callFunctionMap_.emplace("NotificationHelperUpdateNotificationSlotGroups", []() { - OHOS::Notification::NotificationHelper::UpdateNotificationSlotGroups( - *GetParamNotificationBundleOption(), GetParamNotificationSlotGroupSptrVector()); - }); - callFunctionMap_.emplace("NotificationHelperGetAllActiveNotificationsvectorsptrNotification", []() { std::vector> notification = GetParamNotificationSptrVector(); OHOS::Notification::NotificationHelper::GetAllActiveNotifications(notification); diff --git a/test/resource/notificationfuzztest/src/notificationgetparam.cpp b/test/resource/notificationfuzztest/src/notificationgetparam.cpp index ce9232bca..0ff4906fb 100644 --- a/test/resource/notificationfuzztest/src/notificationgetparam.cpp +++ b/test/resource/notificationfuzztest/src/notificationgetparam.cpp @@ -559,32 +559,6 @@ std::vector GetParamNotificationSlotVector return param; } -std::vector GetParamNotificationSlotGroupVector() -{ - vector param; - size_t len = GenRandom(0, MAX_LENGTH); - while (len--) { - OHOS::Notification::NotificationSlotGroup t = *GetParamNotificationSlotGroup(); - param.push_back(t); - } - return param; -} -sptr GetParamNotificationSlotGroup() -{ - sptr param = - new OHOS::Notification::NotificationSlotGroup(GetStringParam(), GetStringParam()); - return param; -} -std::vector> GetParamNotificationSlotGroupSptrVector() -{ - vector> param; - size_t len = GenRandom(0, MAX_LENGTH); - while (len--) { - sptr t = GetParamNotificationSlotGroup(); - param.push_back(t); - } - return param; -} std::shared_ptr GetParamNotificationBundleOption() { if (GetBoolParam()) { -- Gitee