/* * Copyright (c) 2022-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "distributed_database.h" #include "ans_log_wrapper.h" #include "device_manager.h" #include "distributed_preferences.h" namespace OHOS { namespace Notification { namespace { 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( std::shared_ptr databaseCb, std::shared_ptr deviceCb) : DistributedFlowControl(), databaseCb_(databaseCb), deviceCb_(deviceCb) { GetKvDataManager(); } DistributedDatabase::~DistributedDatabase() {} void DistributedDatabase::GetKvDataManager() { initCallback_ = std::make_shared(); int32_t ret = DistributedHardware::DeviceManager::GetInstance().InitDeviceManager(APP_ID + STORE_ID, initCallback_); if (ret != ERR_OK) { ANS_LOGE("init device manager failed, ret:%{public}d", ret); return; } ret = DistributedHardware::DeviceManager::GetInstance().RegisterDevStateCallback(APP_ID + STORE_ID, "", deviceCb_); if (ret != ERR_OK) { ANS_LOGE("register devStateCallback failed, ret:%{public}d", ret); return; } kvDataManager_ = std::make_unique(); KvManagerFlowControlClear(); } void DistributedDatabase::DeviceInitCallBack::OnRemoteDied() { ANS_LOGW("DeviceInitCallBack OnRemoteDied"); } bool DistributedDatabase::CheckKvDataManager() { if (kvDataManager_ == nullptr) { GetKvDataManager(); } if (kvDataManager_ == nullptr) { ANS_LOGE("kvDataManager_ is nullptr."); return false; } return true; } void DistributedDatabase::GetKvStore() { if (!CheckKvDataManager()) { return; } bool enable = false; DistributedPreferences::GetInstance()->GetDistributedEnable(enable); if (!enable) { ANS_LOGI("DistributedEnable is false, no need to create db."); return; } DistributedKv::Options options { .createIfMissing = true, .encrypt = false, .autoSync = false, .securityLevel = DistributedKv::SecurityLevel::S1, .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_); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("Failed to GetSingleKvStore ret = 0x%{public}x", status); kvStore_.reset(); DistributedHardware::DeviceManager::GetInstance().UnRegisterDevStateCallback(APP_ID + STORE_ID); kvDataManager_.reset(); return; } if (kvStore_ != nullptr) { status = kvStore_->SubscribeKvStore(DistributedKv::SubscribeType::SUBSCRIBE_TYPE_REMOTE, databaseCb_); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvStore SubscribeKvStore failed ret = 0x%{public}x", status); kvStore_.reset(); } } KvStoreFlowControlClear(); } bool DistributedDatabase::CheckKvStore() { std::lock_guard lock(mutex_); if (kvStore_ == nullptr) { GetKvStore(); } if (kvStore_ == nullptr) { ANS_LOGE("kvStore is nullptr."); return false; } return true; } bool DistributedDatabase::OnDeviceConnected() { return CheckKvStore(); } bool DistributedDatabase::PutToDistributedDB(const std::string &key, const std::string &value) { std::lock_guard lock(mutex_); if (kvStore_ == nullptr) { ANS_LOGE("kvStore is null."); return false; } if (!KvStoreFlowControl()) { ANS_LOGE("KvStore flow control."); return false; } DistributedKv::Key kvStoreKey(key); DistributedKv::Value kvStoreValue(value); DistributedKv::Status status = kvStore_->Put(kvStoreKey, kvStoreValue); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvStore Put() failed ret = 0x%{public}x", status); return false; } return true; } bool DistributedDatabase::GetFromDistributedDB(const std::string &key, std::string &value) { std::lock_guard lock(mutex_); if (kvStore_ == nullptr) { ANS_LOGE("kvStore is nullptr."); return false; } if (!KvStoreFlowControl()) { ANS_LOGE("KvStoreFlowControl is false."); return false; } DistributedKv::Key kvStoreKey(key); DistributedKv::Value kvStoreValue; DistributedKv::Status status = kvStore_->Get(kvStoreKey, kvStoreValue); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvStore Get() failed ret = 0x%{public}x", status); return false; } value = kvStoreValue.ToString(); return true; } bool DistributedDatabase::GetEntriesFromDistributedDB(const std::string &prefixKey, std::vector &entries) { std::lock_guard lock(mutex_); if (kvStore_ == nullptr) { ANS_LOGE("kvStore_ is nullptr."); return false; } if (!KvStoreFlowControl()) { ANS_LOGE("KvStoreFlowControl is fail."); return false; } DistributedKv::Key kvStoreKey(prefixKey); DistributedKv::Status status = kvStore_->GetEntries(kvStoreKey, entries); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvStore GetEntries() failed ret = 0x%{public}x", status); return false; } return true; } bool DistributedDatabase::DeleteToDistributedDB(const std::string &key) { std::lock_guard lock(mutex_); if (kvStore_ == nullptr) { ANS_LOGE("kvStore is nullptr."); return false; } if (!KvStoreFlowControl()) { ANS_LOGE("KvStoreFlowControl is defeat."); return false; } DistributedKv::Key kvStoreKey(key); DistributedKv::Status status = kvStore_->Delete(kvStoreKey); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvStore Delete() failed ret = 0x%{public}x", status); return false; } return true; } bool DistributedDatabase::ClearDataByDevice(const std::string &deviceId) { std::lock_guard lock(mutex_); if (kvStore_ == nullptr) { ANS_LOGE("kvStore is nullptr."); return false; } if (!KvStoreFlowControl()) { ANS_LOGE("KvStore flow control."); return false; } DistributedKv::Status status = kvStore_->RemoveDeviceData(deviceId); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvStore RemoveDeviceData() failed ret = 0x%{public}x", status); return false; } return true; } bool DistributedDatabase::GetLocalDeviceId(std::string &deviceId) { std::lock_guard lock(mutex_); if (!CheckKvDataManager()) { return false; } if (KvManagerFlowControl()) { DistributedHardware::DmDeviceInfo deviceInfo; int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(APP_ID, deviceInfo); if (ret != ERR_OK) { ANS_LOGE("Get trust local device info failed ret = %{public}d", ret); return false; } localDeviceId_ = deviceInfo.deviceId; } if (localDeviceId_.empty()) { return false; } deviceId = localDeviceId_; return true; } bool DistributedDatabase::GetLocalDeviceInfo(DeviceInfo &localInfo) { std::lock_guard lock(mutex_); if (!CheckKvDataManager()) { return false; } if (!KvManagerFlowControl()) { ANS_LOGE("KvManager flow control."); return false; } int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(APP_ID, localInfo); if (ret != ERR_OK) { ANS_LOGE("Get trust local device info failed ret = %{public}d", ret); return false; } return true; } bool DistributedDatabase::GetDeviceInfoList(std::vector &deviceList) { std::lock_guard lock(mutex_); if (!CheckKvDataManager()) { return false; } if (!KvManagerFlowControl()) { ANS_LOGE("KvManager flow control."); return false; } int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(APP_ID, "", deviceList); if (ret != ERR_OK) { ANS_LOGE("Get trust device list failed ret = %{public}d", ret); return false; } return true; } bool DistributedDatabase::RecreateDistributedDB() { std::lock_guard lock(mutex_); if (!CheckKvDataManager()) { return false; } if (!KvManagerFlowControl()) { 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, KV_STORE_PATH); if (status != DistributedKv::Status::SUCCESS) { ANS_LOGE("kvDataManager DeleteKvStore() failed ret = 0x%{public}x", status); return false; } return true; } } // namespace Notification } // namespace OHOS