196279301Sopenharmony_ci/*
296279301Sopenharmony_ci * Copyright (c) 2022 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_preferences.h"
1796279301Sopenharmony_ci
1896279301Sopenharmony_ci#include <map>
1996279301Sopenharmony_ci
2096279301Sopenharmony_ci#include "ans_log_wrapper.h"
2196279301Sopenharmony_ci
2296279301Sopenharmony_cinamespace OHOS {
2396279301Sopenharmony_cinamespace Notification {
2496279301Sopenharmony_cinamespace {
2596279301Sopenharmony_ciconst std::string DISTRIBUTED_LABEL = "distributed";
2696279301Sopenharmony_ciconst std::string DELIMITER = "|";
2796279301Sopenharmony_ciconst std::string MAIN_LABEL = "ans_main";
2896279301Sopenharmony_ciconst std::string BUNDLE_LABEL = "bundle";
2996279301Sopenharmony_ciconst std::string WITHOUT_APP = "without_app";
3096279301Sopenharmony_ci}  // namespace
3196279301Sopenharmony_ci
3296279301Sopenharmony_ciinline bool GetBoolFromString(const std::string &str)
3396279301Sopenharmony_ci{
3496279301Sopenharmony_ci    return static_cast<bool>(atoi(str.data()));
3596279301Sopenharmony_ci}
3696279301Sopenharmony_ci
3796279301Sopenharmony_ciDistributedPreferences::DistributedPreferences()
3896279301Sopenharmony_ci{
3996279301Sopenharmony_ci    database_ = std::make_unique<DistributedPreferencesDatabase>();
4096279301Sopenharmony_ci    preferencesInfo_ = std::make_unique<DistributedPreferencesInfo>();
4196279301Sopenharmony_ci    InitDistributedAllInfo();
4296279301Sopenharmony_ci}
4396279301Sopenharmony_ci
4496279301Sopenharmony_ciDistributedPreferences::~DistributedPreferences()
4596279301Sopenharmony_ci{}
4696279301Sopenharmony_ci
4796279301Sopenharmony_cibool DistributedPreferences::InitDistributedAllInfo()
4896279301Sopenharmony_ci{
4996279301Sopenharmony_ci    std::vector<DistributedPreferencesDatabase::Entry> entries;
5096279301Sopenharmony_ci    if (!database_->GetEntriesFromDistributedDB(DISTRIBUTED_LABEL, entries)) {
5196279301Sopenharmony_ci        return false;
5296279301Sopenharmony_ci    }
5396279301Sopenharmony_ci
5496279301Sopenharmony_ci    for (auto entry : entries) {
5596279301Sopenharmony_ci        if (!ResolveDistributedKey(entry)) {
5696279301Sopenharmony_ci            ANS_LOGE("key <%{public}s> is invalid.", entry.key.ToString().c_str());
5796279301Sopenharmony_ci        }
5896279301Sopenharmony_ci    }
5996279301Sopenharmony_ci
6096279301Sopenharmony_ci    return true;
6196279301Sopenharmony_ci}
6296279301Sopenharmony_ci
6396279301Sopenharmony_civoid DistributedPreferences::GetDistributedMainKey(std::string &key)
6496279301Sopenharmony_ci{
6596279301Sopenharmony_ci    key = DISTRIBUTED_LABEL + DELIMITER + MAIN_LABEL + DELIMITER;
6696279301Sopenharmony_ci}
6796279301Sopenharmony_ci
6896279301Sopenharmony_civoid DistributedPreferences::GetDistributedBundleKey(
6996279301Sopenharmony_ci    const sptr<NotificationBundleOption> &bundleOption, std::string &key)
7096279301Sopenharmony_ci{
7196279301Sopenharmony_ci    if (bundleOption) {
7296279301Sopenharmony_ci        key = DISTRIBUTED_LABEL + DELIMITER + BUNDLE_LABEL + DELIMITER + bundleOption->GetBundleName() + DELIMITER +
7396279301Sopenharmony_ci            std::to_string(bundleOption->GetUid());
7496279301Sopenharmony_ci    }
7596279301Sopenharmony_ci}
7696279301Sopenharmony_ci
7796279301Sopenharmony_cibool DistributedPreferences::ResolveDistributedKey(const DistributedKv::Entry &entry)
7896279301Sopenharmony_ci{
7996279301Sopenharmony_ci    std::string key = entry.key.ToString();
8096279301Sopenharmony_ci    std::size_t distributedLabelPosition = 0;
8196279301Sopenharmony_ci    std::size_t distributedLabelEndPosition = key.find(DELIMITER, distributedLabelPosition);
8296279301Sopenharmony_ci    if (distributedLabelEndPosition == std::string::npos) {
8396279301Sopenharmony_ci        return false;
8496279301Sopenharmony_ci    }
8596279301Sopenharmony_ci    std::size_t typeLabelPosition = distributedLabelEndPosition + DELIMITER.size();
8696279301Sopenharmony_ci    std::size_t typeLabelEndPosition = key.find(DELIMITER, typeLabelPosition);
8796279301Sopenharmony_ci    if (typeLabelPosition == std::string::npos) {
8896279301Sopenharmony_ci        return false;
8996279301Sopenharmony_ci    }
9096279301Sopenharmony_ci
9196279301Sopenharmony_ci    std::string sign = key.substr(typeLabelPosition, typeLabelEndPosition - typeLabelPosition);
9296279301Sopenharmony_ci    if (sign == MAIN_LABEL) {
9396279301Sopenharmony_ci        return ResolveDistributedEnable(entry.value.ToString());
9496279301Sopenharmony_ci    }
9596279301Sopenharmony_ci    if (sign == WITHOUT_APP) {
9696279301Sopenharmony_ci        return ResolveSyncWithoutAppEnable(key, typeLabelEndPosition, entry.value.ToString());
9796279301Sopenharmony_ci    }
9896279301Sopenharmony_ci    return ResolveDistributedBundleEnable(key, typeLabelEndPosition, entry.value.ToString());
9996279301Sopenharmony_ci}
10096279301Sopenharmony_ci
10196279301Sopenharmony_cibool DistributedPreferences::ResolveDistributedEnable(const std::string &value)
10296279301Sopenharmony_ci{
10396279301Sopenharmony_ci    int32_t enabled = atoi(value.data());
10496279301Sopenharmony_ci    preferencesInfo_->SetDistributedEnable(static_cast<bool>(enabled));
10596279301Sopenharmony_ci
10696279301Sopenharmony_ci    return true;
10796279301Sopenharmony_ci}
10896279301Sopenharmony_ci
10996279301Sopenharmony_cibool DistributedPreferences::ResolveDistributedBundleEnable(const std::string &key,
11096279301Sopenharmony_ci    const int32_t startPos, const std::string &value)
11196279301Sopenharmony_ci{
11296279301Sopenharmony_ci    std::size_t bundleNamePosition = startPos + DELIMITER.size();
11396279301Sopenharmony_ci    std::size_t bundleNameEndPosition = key.find(DELIMITER, bundleNamePosition);
11496279301Sopenharmony_ci    if (bundleNameEndPosition == std::string::npos) {
11596279301Sopenharmony_ci        return false;
11696279301Sopenharmony_ci    }
11796279301Sopenharmony_ci
11896279301Sopenharmony_ci    std::size_t uidPosition = key.find_last_of(DELIMITER) + DELIMITER.size();
11996279301Sopenharmony_ci    if (uidPosition < bundleNameEndPosition) {
12096279301Sopenharmony_ci        return false;
12196279301Sopenharmony_ci    }
12296279301Sopenharmony_ci
12396279301Sopenharmony_ci    std::string bundleName = key.substr(bundleNamePosition, bundleNameEndPosition - bundleNamePosition);
12496279301Sopenharmony_ci    int32_t uid = atoi(&key[uidPosition]);
12596279301Sopenharmony_ci    preferencesInfo_->SetDistributedBundleEnable(bundleName, uid, GetBoolFromString(value));
12696279301Sopenharmony_ci
12796279301Sopenharmony_ci    return true;
12896279301Sopenharmony_ci}
12996279301Sopenharmony_ci
13096279301Sopenharmony_cibool DistributedPreferences::ResolveSyncWithoutAppEnable(const std::string &key,
13196279301Sopenharmony_ci    const int32_t startPos, const std::string &value)
13296279301Sopenharmony_ci{
13396279301Sopenharmony_ci    std::size_t pos = startPos + DELIMITER.size();
13496279301Sopenharmony_ci    int32_t userId = atoi(&key[pos]);
13596279301Sopenharmony_ci    preferencesInfo_->SetSyncEnabledWithoutApp(userId, GetBoolFromString(value));
13696279301Sopenharmony_ci
13796279301Sopenharmony_ci    return true;
13896279301Sopenharmony_ci}
13996279301Sopenharmony_ci
14096279301Sopenharmony_ciErrCode DistributedPreferences::SetDistributedEnable(bool isEnable)
14196279301Sopenharmony_ci{
14296279301Sopenharmony_ci    ANS_LOGI("start");
14396279301Sopenharmony_ci    std::string key;
14496279301Sopenharmony_ci    GetDistributedMainKey(key);
14596279301Sopenharmony_ci
14696279301Sopenharmony_ci    if (!database_->PutToDistributedDB(key, std::to_string(isEnable))) {
14796279301Sopenharmony_ci        ANS_LOGE("put to distributed DB failed. key:%{public}s", key.c_str());
14896279301Sopenharmony_ci        return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
14996279301Sopenharmony_ci    }
15096279301Sopenharmony_ci
15196279301Sopenharmony_ci    preferencesInfo_->SetDistributedEnable(isEnable);
15296279301Sopenharmony_ci
15396279301Sopenharmony_ci    return ERR_OK;
15496279301Sopenharmony_ci}
15596279301Sopenharmony_ci
15696279301Sopenharmony_ciErrCode DistributedPreferences::GetDistributedEnable(bool &isEnable)
15796279301Sopenharmony_ci{
15896279301Sopenharmony_ci    ANS_LOGI("start");
15996279301Sopenharmony_ci
16096279301Sopenharmony_ci    isEnable = preferencesInfo_->GetDistributedEnable();
16196279301Sopenharmony_ci
16296279301Sopenharmony_ci    return ERR_OK;
16396279301Sopenharmony_ci}
16496279301Sopenharmony_ci
16596279301Sopenharmony_ciErrCode DistributedPreferences::SetDistributedBundleEnable(
16696279301Sopenharmony_ci    const sptr<NotificationBundleOption> &bundleOption, bool isEnable)
16796279301Sopenharmony_ci{
16896279301Sopenharmony_ci    ANS_LOGI("start");
16996279301Sopenharmony_ci    if (bundleOption == nullptr) {
17096279301Sopenharmony_ci        ANS_LOGE("bundleOption is nullptr.");
17196279301Sopenharmony_ci        return ERR_ANS_INVALID_PARAM;
17296279301Sopenharmony_ci    }
17396279301Sopenharmony_ci
17496279301Sopenharmony_ci    std::string key;
17596279301Sopenharmony_ci    GetDistributedBundleKey(bundleOption, key);
17696279301Sopenharmony_ci
17796279301Sopenharmony_ci    if (!database_->PutToDistributedDB(key, std::to_string(isEnable))) {
17896279301Sopenharmony_ci        ANS_LOGE("put to distributed DB failed. key:%{public}s", key.c_str());
17996279301Sopenharmony_ci        return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
18096279301Sopenharmony_ci    }
18196279301Sopenharmony_ci
18296279301Sopenharmony_ci    preferencesInfo_->SetDistributedBundleEnable(bundleOption->GetBundleName(), bundleOption->GetUid(), isEnable);
18396279301Sopenharmony_ci
18496279301Sopenharmony_ci    return ERR_OK;
18596279301Sopenharmony_ci}
18696279301Sopenharmony_ci
18796279301Sopenharmony_ciErrCode DistributedPreferences::GetDistributedBundleEnable(
18896279301Sopenharmony_ci    const sptr<NotificationBundleOption> &bundleOption, bool &isEnable)
18996279301Sopenharmony_ci{
19096279301Sopenharmony_ci    if (bundleOption == nullptr) {
19196279301Sopenharmony_ci        ANS_LOGE("bundleOption is nullptr.");
19296279301Sopenharmony_ci        return ERR_ANS_INVALID_PARAM;
19396279301Sopenharmony_ci    }
19496279301Sopenharmony_ci
19596279301Sopenharmony_ci    if (preferencesInfo_ == nullptr) {
19696279301Sopenharmony_ci        ANS_LOGE("preferencesInfo is nullptr");
19796279301Sopenharmony_ci        return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
19896279301Sopenharmony_ci    }
19996279301Sopenharmony_ci
20096279301Sopenharmony_ci    isEnable = preferencesInfo_->GetDistributedBundleEnable(bundleOption->GetBundleName(), bundleOption->GetUid());
20196279301Sopenharmony_ci
20296279301Sopenharmony_ci    return ERR_OK;
20396279301Sopenharmony_ci}
20496279301Sopenharmony_ci
20596279301Sopenharmony_ciErrCode DistributedPreferences::DeleteDistributedBundleInfo(const sptr<NotificationBundleOption> &bundleOption)
20696279301Sopenharmony_ci{
20796279301Sopenharmony_ci    if (bundleOption == nullptr) {
20896279301Sopenharmony_ci        ANS_LOGE("bundleOption is nullptr.");
20996279301Sopenharmony_ci        return ERR_ANS_INVALID_PARAM;
21096279301Sopenharmony_ci    }
21196279301Sopenharmony_ci
21296279301Sopenharmony_ci    if (database_ == nullptr || preferencesInfo_ == nullptr) {
21396279301Sopenharmony_ci        ANS_LOGE("database or preferencesInfo is nullptr");
21496279301Sopenharmony_ci        return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
21596279301Sopenharmony_ci    }
21696279301Sopenharmony_ci
21796279301Sopenharmony_ci    std::string key;
21896279301Sopenharmony_ci    GetDistributedBundleKey(bundleOption, key);
21996279301Sopenharmony_ci
22096279301Sopenharmony_ci    if (!database_->DeleteToDistributedDB(key)) {
22196279301Sopenharmony_ci        ANS_LOGE("delete to distributed DB failed. key:%{public}s", key.c_str());
22296279301Sopenharmony_ci        return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
22396279301Sopenharmony_ci    }
22496279301Sopenharmony_ci
22596279301Sopenharmony_ci    preferencesInfo_->DeleteDistributedBundleInfo(bundleOption->GetBundleName(), bundleOption->GetUid());
22696279301Sopenharmony_ci
22796279301Sopenharmony_ci    return ERR_OK;
22896279301Sopenharmony_ci}
22996279301Sopenharmony_ci
23096279301Sopenharmony_ciErrCode DistributedPreferences::ClearDataInRestoreFactorySettings()
23196279301Sopenharmony_ci{
23296279301Sopenharmony_ci    if (database_ == nullptr) {
23396279301Sopenharmony_ci        ANS_LOGE("database is nullptr");
23496279301Sopenharmony_ci        return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
23596279301Sopenharmony_ci    }
23696279301Sopenharmony_ci
23796279301Sopenharmony_ci    if (!database_->ClearDatabase()) {
23896279301Sopenharmony_ci        return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
23996279301Sopenharmony_ci    }
24096279301Sopenharmony_ci
24196279301Sopenharmony_ci    SetDistributedEnable(false);
24296279301Sopenharmony_ci
24396279301Sopenharmony_ci    preferencesInfo_ = std::make_unique<DistributedPreferencesInfo>();
24496279301Sopenharmony_ci
24596279301Sopenharmony_ci    return ERR_OK;
24696279301Sopenharmony_ci}
24796279301Sopenharmony_ci
24896279301Sopenharmony_civoid DistributedPreferences::GetEnabledWithoutApp(const int32_t userId, std::string &key)
24996279301Sopenharmony_ci{
25096279301Sopenharmony_ci    key = DISTRIBUTED_LABEL + DELIMITER + WITHOUT_APP + DELIMITER + std::to_string(userId) + DELIMITER;
25196279301Sopenharmony_ci}
25296279301Sopenharmony_ci
25396279301Sopenharmony_ciErrCode DistributedPreferences::SetSyncEnabledWithoutApp(const int32_t userId, const bool enabled)
25496279301Sopenharmony_ci{
25596279301Sopenharmony_ci    if (database_ == nullptr || preferencesInfo_ == nullptr) {
25696279301Sopenharmony_ci        ANS_LOGE("database or preferencesInfo is nullptr");
25796279301Sopenharmony_ci        return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
25896279301Sopenharmony_ci    }
25996279301Sopenharmony_ci    std::string key;
26096279301Sopenharmony_ci    GetEnabledWithoutApp(userId, key);
26196279301Sopenharmony_ci    if (!database_->PutToDistributedDB(key, std::to_string(enabled))) {
26296279301Sopenharmony_ci        ANS_LOGE("put to distributed DB failed. key:%{public}s", key.c_str());
26396279301Sopenharmony_ci        return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
26496279301Sopenharmony_ci    }
26596279301Sopenharmony_ci    preferencesInfo_->SetSyncEnabledWithoutApp(userId, enabled);
26696279301Sopenharmony_ci    return ERR_OK;
26796279301Sopenharmony_ci}
26896279301Sopenharmony_ci
26996279301Sopenharmony_ciErrCode DistributedPreferences::GetSyncEnabledWithoutApp(const int32_t userId, bool &enabled)
27096279301Sopenharmony_ci{
27196279301Sopenharmony_ci    return preferencesInfo_ == nullptr ?
27296279301Sopenharmony_ci        ERR_ANS_DISTRIBUTED_OPERATION_FAILED : preferencesInfo_->GetSyncEnabledWithoutApp(userId, enabled);
27396279301Sopenharmony_ci}
27496279301Sopenharmony_ci}  // namespace Notification
27596279301Sopenharmony_ci}  // namespace OHOS