196279301Sopenharmony_ci/*
296279301Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
396279301Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
496279301Sopenharmony_ci * you may not use this file except in compliance with the License.
596279301Sopenharmony_ci * You may obtain a copy of the License at
696279301Sopenharmony_ci *
796279301Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
896279301Sopenharmony_ci *
996279301Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1096279301Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1196279301Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1296279301Sopenharmony_ci * See the License for the specific language governing permissions and
1396279301Sopenharmony_ci * limitations under the License.
1496279301Sopenharmony_ci */
1596279301Sopenharmony_ci
1696279301Sopenharmony_ci#include "distributed_database.h"
1796279301Sopenharmony_ci
1896279301Sopenharmony_ci#include "ans_log_wrapper.h"
1996279301Sopenharmony_ci#include "device_manager.h"
2096279301Sopenharmony_ci#include "distributed_preferences.h"
2196279301Sopenharmony_ci
2296279301Sopenharmony_cinamespace OHOS {
2396279301Sopenharmony_cinamespace Notification {
2496279301Sopenharmony_cinamespace {
2596279301Sopenharmony_ciconst std::string APP_ID = "notification_service";
2696279301Sopenharmony_ciconst std::string STORE_ID = "distributed_notification";
2796279301Sopenharmony_ciconstexpr char KV_STORE_PATH[] = "/data/service/el1/public/database/notification_service";
2896279301Sopenharmony_ci}  // namespace
2996279301Sopenharmony_ci
3096279301Sopenharmony_ciDistributedDatabase::DistributedDatabase(
3196279301Sopenharmony_ci    std::shared_ptr<DistributedDatabaseCallback> databaseCb, std::shared_ptr<DistributedDeviceCallback> deviceCb)
3296279301Sopenharmony_ci    : DistributedFlowControl(), databaseCb_(databaseCb), deviceCb_(deviceCb)
3396279301Sopenharmony_ci{
3496279301Sopenharmony_ci    GetKvDataManager();
3596279301Sopenharmony_ci}
3696279301Sopenharmony_ci
3796279301Sopenharmony_ciDistributedDatabase::~DistributedDatabase()
3896279301Sopenharmony_ci{}
3996279301Sopenharmony_ci
4096279301Sopenharmony_civoid DistributedDatabase::GetKvDataManager()
4196279301Sopenharmony_ci{
4296279301Sopenharmony_ci    initCallback_ = std::make_shared<DeviceInitCallBack>();
4396279301Sopenharmony_ci    int32_t ret = DistributedHardware::DeviceManager::GetInstance().InitDeviceManager(APP_ID + STORE_ID, initCallback_);
4496279301Sopenharmony_ci    if (ret != ERR_OK) {
4596279301Sopenharmony_ci        ANS_LOGE("init device manager failed, ret:%{public}d", ret);
4696279301Sopenharmony_ci        return;
4796279301Sopenharmony_ci    }
4896279301Sopenharmony_ci    ret = DistributedHardware::DeviceManager::GetInstance().RegisterDevStateCallback(APP_ID + STORE_ID, "", deviceCb_);
4996279301Sopenharmony_ci    if (ret != ERR_OK) {
5096279301Sopenharmony_ci        ANS_LOGE("register devStateCallback failed, ret:%{public}d", ret);
5196279301Sopenharmony_ci        return;
5296279301Sopenharmony_ci    }
5396279301Sopenharmony_ci
5496279301Sopenharmony_ci    kvDataManager_ = std::make_unique<DistributedKv::DistributedKvDataManager>();
5596279301Sopenharmony_ci    KvManagerFlowControlClear();
5696279301Sopenharmony_ci}
5796279301Sopenharmony_ci
5896279301Sopenharmony_civoid DistributedDatabase::DeviceInitCallBack::OnRemoteDied()
5996279301Sopenharmony_ci{
6096279301Sopenharmony_ci    ANS_LOGW("DeviceInitCallBack OnRemoteDied");
6196279301Sopenharmony_ci}
6296279301Sopenharmony_ci
6396279301Sopenharmony_cibool DistributedDatabase::CheckKvDataManager()
6496279301Sopenharmony_ci{
6596279301Sopenharmony_ci    if (kvDataManager_ == nullptr) {
6696279301Sopenharmony_ci        GetKvDataManager();
6796279301Sopenharmony_ci    }
6896279301Sopenharmony_ci    if (kvDataManager_ == nullptr) {
6996279301Sopenharmony_ci        ANS_LOGE("kvDataManager_ is nullptr.");
7096279301Sopenharmony_ci        return false;
7196279301Sopenharmony_ci    }
7296279301Sopenharmony_ci    return true;
7396279301Sopenharmony_ci}
7496279301Sopenharmony_ci
7596279301Sopenharmony_civoid DistributedDatabase::GetKvStore()
7696279301Sopenharmony_ci{
7796279301Sopenharmony_ci    if (!CheckKvDataManager()) {
7896279301Sopenharmony_ci        return;
7996279301Sopenharmony_ci    }
8096279301Sopenharmony_ci
8196279301Sopenharmony_ci    bool enable = false;
8296279301Sopenharmony_ci    DistributedPreferences::GetInstance()->GetDistributedEnable(enable);
8396279301Sopenharmony_ci    if (!enable) {
8496279301Sopenharmony_ci        ANS_LOGI("DistributedEnable is false, no need to create db.");
8596279301Sopenharmony_ci        return;
8696279301Sopenharmony_ci    }
8796279301Sopenharmony_ci
8896279301Sopenharmony_ci    DistributedKv::Options options {
8996279301Sopenharmony_ci        .createIfMissing = true,
9096279301Sopenharmony_ci        .encrypt = false,
9196279301Sopenharmony_ci        .autoSync = false,
9296279301Sopenharmony_ci        .securityLevel = DistributedKv::SecurityLevel::S1,
9396279301Sopenharmony_ci        .area = DistributedKv::EL1,
9496279301Sopenharmony_ci        .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION,
9596279301Sopenharmony_ci        .baseDir = KV_STORE_PATH
9696279301Sopenharmony_ci    };
9796279301Sopenharmony_ci    DistributedKv::AppId appId = {.appId = APP_ID};
9896279301Sopenharmony_ci    DistributedKv::StoreId storeId = {.storeId = STORE_ID};
9996279301Sopenharmony_ci    DistributedKv::Status status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_);
10096279301Sopenharmony_ci    if (status != DistributedKv::Status::SUCCESS) {
10196279301Sopenharmony_ci        ANS_LOGE("Failed to GetSingleKvStore ret = 0x%{public}x", status);
10296279301Sopenharmony_ci        kvStore_.reset();
10396279301Sopenharmony_ci        DistributedHardware::DeviceManager::GetInstance().UnRegisterDevStateCallback(APP_ID + STORE_ID);
10496279301Sopenharmony_ci        kvDataManager_.reset();
10596279301Sopenharmony_ci        return;
10696279301Sopenharmony_ci    }
10796279301Sopenharmony_ci
10896279301Sopenharmony_ci    if (kvStore_ != nullptr) {
10996279301Sopenharmony_ci        status = kvStore_->SubscribeKvStore(DistributedKv::SubscribeType::SUBSCRIBE_TYPE_REMOTE, databaseCb_);
11096279301Sopenharmony_ci        if (status != DistributedKv::Status::SUCCESS) {
11196279301Sopenharmony_ci            ANS_LOGE("kvStore SubscribeKvStore failed ret = 0x%{public}x", status);
11296279301Sopenharmony_ci            kvStore_.reset();
11396279301Sopenharmony_ci        }
11496279301Sopenharmony_ci    }
11596279301Sopenharmony_ci
11696279301Sopenharmony_ci    KvStoreFlowControlClear();
11796279301Sopenharmony_ci}
11896279301Sopenharmony_ci
11996279301Sopenharmony_cibool DistributedDatabase::CheckKvStore()
12096279301Sopenharmony_ci{
12196279301Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
12296279301Sopenharmony_ci    if (kvStore_ == nullptr) {
12396279301Sopenharmony_ci        GetKvStore();
12496279301Sopenharmony_ci    }
12596279301Sopenharmony_ci    if (kvStore_ == nullptr) {
12696279301Sopenharmony_ci        ANS_LOGE("kvStore is nullptr.");
12796279301Sopenharmony_ci        return false;
12896279301Sopenharmony_ci    }
12996279301Sopenharmony_ci    return true;
13096279301Sopenharmony_ci}
13196279301Sopenharmony_ci
13296279301Sopenharmony_cibool DistributedDatabase::OnDeviceConnected()
13396279301Sopenharmony_ci{
13496279301Sopenharmony_ci    return CheckKvStore();
13596279301Sopenharmony_ci}
13696279301Sopenharmony_ci
13796279301Sopenharmony_cibool DistributedDatabase::PutToDistributedDB(const std::string &key, const std::string &value)
13896279301Sopenharmony_ci{
13996279301Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
14096279301Sopenharmony_ci
14196279301Sopenharmony_ci    if (kvStore_ == nullptr) {
14296279301Sopenharmony_ci        ANS_LOGE("kvStore is null.");
14396279301Sopenharmony_ci        return false;
14496279301Sopenharmony_ci    }
14596279301Sopenharmony_ci
14696279301Sopenharmony_ci    if (!KvStoreFlowControl()) {
14796279301Sopenharmony_ci        ANS_LOGE("KvStore flow control.");
14896279301Sopenharmony_ci        return false;
14996279301Sopenharmony_ci    }
15096279301Sopenharmony_ci
15196279301Sopenharmony_ci    DistributedKv::Key kvStoreKey(key);
15296279301Sopenharmony_ci    DistributedKv::Value kvStoreValue(value);
15396279301Sopenharmony_ci    DistributedKv::Status status = kvStore_->Put(kvStoreKey, kvStoreValue);
15496279301Sopenharmony_ci    if (status != DistributedKv::Status::SUCCESS) {
15596279301Sopenharmony_ci        ANS_LOGE("kvStore Put() failed ret = 0x%{public}x", status);
15696279301Sopenharmony_ci        return false;
15796279301Sopenharmony_ci    }
15896279301Sopenharmony_ci
15996279301Sopenharmony_ci    return true;
16096279301Sopenharmony_ci}
16196279301Sopenharmony_ci
16296279301Sopenharmony_cibool DistributedDatabase::GetFromDistributedDB(const std::string &key, std::string &value)
16396279301Sopenharmony_ci{
16496279301Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
16596279301Sopenharmony_ci
16696279301Sopenharmony_ci    if (kvStore_ == nullptr) {
16796279301Sopenharmony_ci        ANS_LOGE("kvStore is nullptr.");
16896279301Sopenharmony_ci        return false;
16996279301Sopenharmony_ci    }
17096279301Sopenharmony_ci
17196279301Sopenharmony_ci    if (!KvStoreFlowControl()) {
17296279301Sopenharmony_ci        ANS_LOGE("KvStoreFlowControl is false.");
17396279301Sopenharmony_ci        return false;
17496279301Sopenharmony_ci    }
17596279301Sopenharmony_ci
17696279301Sopenharmony_ci    DistributedKv::Key kvStoreKey(key);
17796279301Sopenharmony_ci    DistributedKv::Value kvStoreValue;
17896279301Sopenharmony_ci    DistributedKv::Status status = kvStore_->Get(kvStoreKey, kvStoreValue);
17996279301Sopenharmony_ci    if (status != DistributedKv::Status::SUCCESS) {
18096279301Sopenharmony_ci        ANS_LOGE("kvStore Get() failed ret = 0x%{public}x", status);
18196279301Sopenharmony_ci        return false;
18296279301Sopenharmony_ci    }
18396279301Sopenharmony_ci
18496279301Sopenharmony_ci    value = kvStoreValue.ToString();
18596279301Sopenharmony_ci
18696279301Sopenharmony_ci    return true;
18796279301Sopenharmony_ci}
18896279301Sopenharmony_ci
18996279301Sopenharmony_cibool DistributedDatabase::GetEntriesFromDistributedDB(const std::string &prefixKey, std::vector<Entry> &entries)
19096279301Sopenharmony_ci{
19196279301Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
19296279301Sopenharmony_ci
19396279301Sopenharmony_ci    if (kvStore_ == nullptr) {
19496279301Sopenharmony_ci        ANS_LOGE("kvStore_ is nullptr.");
19596279301Sopenharmony_ci        return false;
19696279301Sopenharmony_ci    }
19796279301Sopenharmony_ci
19896279301Sopenharmony_ci    if (!KvStoreFlowControl()) {
19996279301Sopenharmony_ci        ANS_LOGE("KvStoreFlowControl is fail.");
20096279301Sopenharmony_ci        return false;
20196279301Sopenharmony_ci    }
20296279301Sopenharmony_ci
20396279301Sopenharmony_ci    DistributedKv::Key kvStoreKey(prefixKey);
20496279301Sopenharmony_ci    DistributedKv::Status status = kvStore_->GetEntries(kvStoreKey, entries);
20596279301Sopenharmony_ci    if (status != DistributedKv::Status::SUCCESS) {
20696279301Sopenharmony_ci        ANS_LOGE("kvStore GetEntries() failed ret = 0x%{public}x", status);
20796279301Sopenharmony_ci        return false;
20896279301Sopenharmony_ci    }
20996279301Sopenharmony_ci
21096279301Sopenharmony_ci    return true;
21196279301Sopenharmony_ci}
21296279301Sopenharmony_ci
21396279301Sopenharmony_cibool DistributedDatabase::DeleteToDistributedDB(const std::string &key)
21496279301Sopenharmony_ci{
21596279301Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
21696279301Sopenharmony_ci
21796279301Sopenharmony_ci    if (kvStore_ == nullptr) {
21896279301Sopenharmony_ci        ANS_LOGE("kvStore is nullptr.");
21996279301Sopenharmony_ci        return false;
22096279301Sopenharmony_ci    }
22196279301Sopenharmony_ci
22296279301Sopenharmony_ci    if (!KvStoreFlowControl()) {
22396279301Sopenharmony_ci        ANS_LOGE("KvStoreFlowControl is defeat.");
22496279301Sopenharmony_ci        return false;
22596279301Sopenharmony_ci    }
22696279301Sopenharmony_ci
22796279301Sopenharmony_ci    DistributedKv::Key kvStoreKey(key);
22896279301Sopenharmony_ci    DistributedKv::Status status = kvStore_->Delete(kvStoreKey);
22996279301Sopenharmony_ci    if (status != DistributedKv::Status::SUCCESS) {
23096279301Sopenharmony_ci        ANS_LOGE("kvStore Delete() failed ret = 0x%{public}x", status);
23196279301Sopenharmony_ci        return false;
23296279301Sopenharmony_ci    }
23396279301Sopenharmony_ci
23496279301Sopenharmony_ci    return true;
23596279301Sopenharmony_ci}
23696279301Sopenharmony_ci
23796279301Sopenharmony_cibool DistributedDatabase::ClearDataByDevice(const std::string &deviceId)
23896279301Sopenharmony_ci{
23996279301Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
24096279301Sopenharmony_ci
24196279301Sopenharmony_ci    if (kvStore_ == nullptr) {
24296279301Sopenharmony_ci        ANS_LOGE("kvStore is nullptr.");
24396279301Sopenharmony_ci        return false;
24496279301Sopenharmony_ci    }
24596279301Sopenharmony_ci
24696279301Sopenharmony_ci    if (!KvStoreFlowControl()) {
24796279301Sopenharmony_ci        ANS_LOGE("KvStore flow control.");
24896279301Sopenharmony_ci        return false;
24996279301Sopenharmony_ci    }
25096279301Sopenharmony_ci
25196279301Sopenharmony_ci    DistributedKv::Status status = kvStore_->RemoveDeviceData(deviceId);
25296279301Sopenharmony_ci    if (status != DistributedKv::Status::SUCCESS) {
25396279301Sopenharmony_ci        ANS_LOGE("kvStore RemoveDeviceData() failed ret = 0x%{public}x", status);
25496279301Sopenharmony_ci        return false;
25596279301Sopenharmony_ci    }
25696279301Sopenharmony_ci
25796279301Sopenharmony_ci    return true;
25896279301Sopenharmony_ci}
25996279301Sopenharmony_ci
26096279301Sopenharmony_cibool DistributedDatabase::GetLocalDeviceId(std::string &deviceId)
26196279301Sopenharmony_ci{
26296279301Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
26396279301Sopenharmony_ci    if (!CheckKvDataManager()) {
26496279301Sopenharmony_ci        return false;
26596279301Sopenharmony_ci    }
26696279301Sopenharmony_ci
26796279301Sopenharmony_ci    if (KvManagerFlowControl()) {
26896279301Sopenharmony_ci        DistributedHardware::DmDeviceInfo deviceInfo;
26996279301Sopenharmony_ci        int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(APP_ID, deviceInfo);
27096279301Sopenharmony_ci        if (ret != ERR_OK) {
27196279301Sopenharmony_ci            ANS_LOGE("Get trust local device info failed ret = %{public}d", ret);
27296279301Sopenharmony_ci            return false;
27396279301Sopenharmony_ci        }
27496279301Sopenharmony_ci        localDeviceId_ = deviceInfo.deviceId;
27596279301Sopenharmony_ci    }
27696279301Sopenharmony_ci
27796279301Sopenharmony_ci    if (localDeviceId_.empty()) {
27896279301Sopenharmony_ci        return false;
27996279301Sopenharmony_ci    }
28096279301Sopenharmony_ci
28196279301Sopenharmony_ci    deviceId = localDeviceId_;
28296279301Sopenharmony_ci
28396279301Sopenharmony_ci    return true;
28496279301Sopenharmony_ci}
28596279301Sopenharmony_ci
28696279301Sopenharmony_cibool DistributedDatabase::GetLocalDeviceInfo(DeviceInfo &localInfo)
28796279301Sopenharmony_ci{
28896279301Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
28996279301Sopenharmony_ci    if (!CheckKvDataManager()) {
29096279301Sopenharmony_ci        return false;
29196279301Sopenharmony_ci    }
29296279301Sopenharmony_ci
29396279301Sopenharmony_ci    if (!KvManagerFlowControl()) {
29496279301Sopenharmony_ci        ANS_LOGE("KvManager flow control.");
29596279301Sopenharmony_ci        return false;
29696279301Sopenharmony_ci    }
29796279301Sopenharmony_ci
29896279301Sopenharmony_ci    int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(APP_ID, localInfo);
29996279301Sopenharmony_ci    if (ret != ERR_OK) {
30096279301Sopenharmony_ci        ANS_LOGE("Get trust local device info failed ret = %{public}d", ret);
30196279301Sopenharmony_ci        return false;
30296279301Sopenharmony_ci    }
30396279301Sopenharmony_ci
30496279301Sopenharmony_ci    return true;
30596279301Sopenharmony_ci}
30696279301Sopenharmony_ci
30796279301Sopenharmony_cibool DistributedDatabase::GetDeviceInfoList(std::vector<DeviceInfo> &deviceList)
30896279301Sopenharmony_ci{
30996279301Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
31096279301Sopenharmony_ci    if (!CheckKvDataManager()) {
31196279301Sopenharmony_ci        return false;
31296279301Sopenharmony_ci    }
31396279301Sopenharmony_ci
31496279301Sopenharmony_ci    if (!KvManagerFlowControl()) {
31596279301Sopenharmony_ci        ANS_LOGE("KvManager flow control.");
31696279301Sopenharmony_ci        return false;
31796279301Sopenharmony_ci    }
31896279301Sopenharmony_ci
31996279301Sopenharmony_ci    int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(APP_ID, "", deviceList);
32096279301Sopenharmony_ci    if (ret != ERR_OK) {
32196279301Sopenharmony_ci        ANS_LOGE("Get trust device list failed ret = %{public}d", ret);
32296279301Sopenharmony_ci        return false;
32396279301Sopenharmony_ci    }
32496279301Sopenharmony_ci
32596279301Sopenharmony_ci    return true;
32696279301Sopenharmony_ci}
32796279301Sopenharmony_ci
32896279301Sopenharmony_cibool DistributedDatabase::RecreateDistributedDB()
32996279301Sopenharmony_ci{
33096279301Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
33196279301Sopenharmony_ci    if (!CheckKvDataManager()) {
33296279301Sopenharmony_ci        return false;
33396279301Sopenharmony_ci    }
33496279301Sopenharmony_ci
33596279301Sopenharmony_ci    if (!KvManagerFlowControl()) {
33696279301Sopenharmony_ci        ANS_LOGE("KvManager flow control.");
33796279301Sopenharmony_ci        return false;
33896279301Sopenharmony_ci    }
33996279301Sopenharmony_ci    kvStore_.reset();
34096279301Sopenharmony_ci    DistributedKv::AppId appId = {.appId = APP_ID};
34196279301Sopenharmony_ci    DistributedKv::StoreId storeId = {.storeId = STORE_ID};
34296279301Sopenharmony_ci    DistributedKv::Status status = kvDataManager_->DeleteKvStore(appId, storeId, KV_STORE_PATH);
34396279301Sopenharmony_ci    if (status != DistributedKv::Status::SUCCESS) {
34496279301Sopenharmony_ci        ANS_LOGE("kvDataManager DeleteKvStore() failed ret = 0x%{public}x", status);
34596279301Sopenharmony_ci        return false;
34696279301Sopenharmony_ci    }
34796279301Sopenharmony_ci
34896279301Sopenharmony_ci    return true;
34996279301Sopenharmony_ci}
35096279301Sopenharmony_ci}  // namespace Notification
35196279301Sopenharmony_ci}  // namespace OHOS
352