1fc223305Sopenharmony_ci/*
2fc223305Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3fc223305Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fc223305Sopenharmony_ci * you may not use this file except in compliance with the License.
5fc223305Sopenharmony_ci * You may obtain a copy of the License at
6fc223305Sopenharmony_ci *
7fc223305Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8fc223305Sopenharmony_ci *
9fc223305Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fc223305Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fc223305Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fc223305Sopenharmony_ci * See the License for the specific language governing permissions and
13fc223305Sopenharmony_ci * limitations under the License.
14fc223305Sopenharmony_ci */
15fc223305Sopenharmony_ci
16fc223305Sopenharmony_ci#include "preferences_base.h"
17fc223305Sopenharmony_ci
18fc223305Sopenharmony_ci#include <cinttypes>
19fc223305Sopenharmony_ci#include <climits>
20fc223305Sopenharmony_ci#include <cstdint>
21fc223305Sopenharmony_ci#include <cstdlib>
22fc223305Sopenharmony_ci#include <functional>
23fc223305Sopenharmony_ci#include <sstream>
24fc223305Sopenharmony_ci
25fc223305Sopenharmony_ci#include "base64_helper.h"
26fc223305Sopenharmony_ci#include "executor_pool.h"
27fc223305Sopenharmony_ci#include "log_print.h"
28fc223305Sopenharmony_ci#include "preferences_observer_stub.h"
29fc223305Sopenharmony_ci
30fc223305Sopenharmony_cinamespace OHOS {
31fc223305Sopenharmony_cinamespace NativePreferences {
32fc223305Sopenharmony_ci
33fc223305Sopenharmony_ciExecutorPool PreferencesBase::executorPool_ = ExecutorPool(1, 0);
34fc223305Sopenharmony_ci
35fc223305Sopenharmony_ciPreferencesBase::PreferencesBase(const Options &options) : options_(options)
36fc223305Sopenharmony_ci{
37fc223305Sopenharmony_ci}
38fc223305Sopenharmony_ci
39fc223305Sopenharmony_ciPreferencesBase::~PreferencesBase()
40fc223305Sopenharmony_ci{
41fc223305Sopenharmony_ci}
42fc223305Sopenharmony_ci
43fc223305Sopenharmony_ciPreferencesValue PreferencesBase::Get(const std::string &key, const PreferencesValue &defValue)
44fc223305Sopenharmony_ci{
45fc223305Sopenharmony_ci    return defValue;
46fc223305Sopenharmony_ci}
47fc223305Sopenharmony_ci
48fc223305Sopenharmony_ciint PreferencesBase::Put(const std::string &key, const PreferencesValue &value)
49fc223305Sopenharmony_ci{
50fc223305Sopenharmony_ci    return E_OK;
51fc223305Sopenharmony_ci}
52fc223305Sopenharmony_ci
53fc223305Sopenharmony_ciint PreferencesBase::GetInt(const std::string &key, const int &defValue = {})
54fc223305Sopenharmony_ci{
55fc223305Sopenharmony_ci    PreferencesValue preferencesValue = Get(key, defValue);
56fc223305Sopenharmony_ci    if (!preferencesValue.IsInt()) {
57fc223305Sopenharmony_ci        return defValue;
58fc223305Sopenharmony_ci    }
59fc223305Sopenharmony_ci    return preferencesValue;
60fc223305Sopenharmony_ci}
61fc223305Sopenharmony_ci
62fc223305Sopenharmony_cistd::string PreferencesBase::GetString(const std::string &key, const std::string &defValue = {})
63fc223305Sopenharmony_ci{
64fc223305Sopenharmony_ci    PreferencesValue preferencesValue = Get(key, defValue);
65fc223305Sopenharmony_ci    if (!preferencesValue.IsString()) {
66fc223305Sopenharmony_ci        return defValue;
67fc223305Sopenharmony_ci    }
68fc223305Sopenharmony_ci    return preferencesValue;
69fc223305Sopenharmony_ci}
70fc223305Sopenharmony_cibool PreferencesBase::GetBool(const std::string &key, const bool &defValue = {})
71fc223305Sopenharmony_ci{
72fc223305Sopenharmony_ci    PreferencesValue preferencesValue = Get(key, defValue);
73fc223305Sopenharmony_ci    if (!preferencesValue.IsBool()) {
74fc223305Sopenharmony_ci        return defValue;
75fc223305Sopenharmony_ci    }
76fc223305Sopenharmony_ci    return preferencesValue;
77fc223305Sopenharmony_ci}
78fc223305Sopenharmony_cifloat PreferencesBase::GetFloat(const std::string &key, const float &defValue = {})
79fc223305Sopenharmony_ci{
80fc223305Sopenharmony_ci    PreferencesValue preferencesValue = Get(key, defValue);
81fc223305Sopenharmony_ci    if (!preferencesValue.IsFloat()) {
82fc223305Sopenharmony_ci        return defValue;
83fc223305Sopenharmony_ci    }
84fc223305Sopenharmony_ci    return preferencesValue;
85fc223305Sopenharmony_ci}
86fc223305Sopenharmony_ci
87fc223305Sopenharmony_cidouble PreferencesBase::GetDouble(const std::string &key, const double &defValue = {})
88fc223305Sopenharmony_ci{
89fc223305Sopenharmony_ci    PreferencesValue preferencesValue = Get(key, defValue);
90fc223305Sopenharmony_ci    if (!preferencesValue.IsDouble()) {
91fc223305Sopenharmony_ci        return defValue;
92fc223305Sopenharmony_ci    }
93fc223305Sopenharmony_ci    return preferencesValue;
94fc223305Sopenharmony_ci}
95fc223305Sopenharmony_ci
96fc223305Sopenharmony_ciint64_t PreferencesBase::GetLong(const std::string &key, const int64_t &defValue = {})
97fc223305Sopenharmony_ci{
98fc223305Sopenharmony_ci    PreferencesValue preferencesValue = Get(key, defValue);
99fc223305Sopenharmony_ci    if (!preferencesValue.IsLong()) {
100fc223305Sopenharmony_ci        return defValue;
101fc223305Sopenharmony_ci    }
102fc223305Sopenharmony_ci    return preferencesValue;
103fc223305Sopenharmony_ci}
104fc223305Sopenharmony_ci
105fc223305Sopenharmony_cistd::map<std::string, PreferencesValue> PreferencesBase::GetAll()
106fc223305Sopenharmony_ci{
107fc223305Sopenharmony_ci    return {};
108fc223305Sopenharmony_ci}
109fc223305Sopenharmony_ci
110fc223305Sopenharmony_cibool PreferencesBase::HasKey(const std::string &key)
111fc223305Sopenharmony_ci{
112fc223305Sopenharmony_ci    return true;
113fc223305Sopenharmony_ci}
114fc223305Sopenharmony_ci
115fc223305Sopenharmony_ciint PreferencesBase::PutInt(const std::string &key, int value)
116fc223305Sopenharmony_ci{
117fc223305Sopenharmony_ci    return Put(key, value);
118fc223305Sopenharmony_ci}
119fc223305Sopenharmony_ci
120fc223305Sopenharmony_ciint PreferencesBase::PutString(const std::string &key, const std::string &value)
121fc223305Sopenharmony_ci{
122fc223305Sopenharmony_ci    return Put(key, value);
123fc223305Sopenharmony_ci}
124fc223305Sopenharmony_ci
125fc223305Sopenharmony_ciint PreferencesBase::PutBool(const std::string &key, bool value)
126fc223305Sopenharmony_ci{
127fc223305Sopenharmony_ci    return Put(key, value);
128fc223305Sopenharmony_ci}
129fc223305Sopenharmony_ci
130fc223305Sopenharmony_ciint PreferencesBase::PutLong(const std::string &key, int64_t value)
131fc223305Sopenharmony_ci{
132fc223305Sopenharmony_ci    return Put(key, value);
133fc223305Sopenharmony_ci}
134fc223305Sopenharmony_ci
135fc223305Sopenharmony_ciint PreferencesBase::PutFloat(const std::string &key, float value)
136fc223305Sopenharmony_ci{
137fc223305Sopenharmony_ci    return Put(key, value);
138fc223305Sopenharmony_ci}
139fc223305Sopenharmony_ciint PreferencesBase::PutDouble(const std::string &key, double value)
140fc223305Sopenharmony_ci{
141fc223305Sopenharmony_ci    return Put(key, value);
142fc223305Sopenharmony_ci}
143fc223305Sopenharmony_ciint PreferencesBase::Delete(const std::string &key)
144fc223305Sopenharmony_ci{
145fc223305Sopenharmony_ci    return E_OK;
146fc223305Sopenharmony_ci}
147fc223305Sopenharmony_ci
148fc223305Sopenharmony_ciint PreferencesBase::Clear()
149fc223305Sopenharmony_ci{
150fc223305Sopenharmony_ci    return E_OK;
151fc223305Sopenharmony_ci}
152fc223305Sopenharmony_ci
153fc223305Sopenharmony_civoid PreferencesBase::Flush()
154fc223305Sopenharmony_ci{
155fc223305Sopenharmony_ci}
156fc223305Sopenharmony_ci
157fc223305Sopenharmony_ciint PreferencesBase::FlushSync()
158fc223305Sopenharmony_ci{
159fc223305Sopenharmony_ci    return E_OK;
160fc223305Sopenharmony_ci}
161fc223305Sopenharmony_ci
162fc223305Sopenharmony_ciint PreferencesBase::RegisterObserver(std::shared_ptr<PreferencesObserver> preferencesObserver, RegisterMode mode)
163fc223305Sopenharmony_ci{
164fc223305Sopenharmony_ci    std::unique_lock<std::shared_mutex> writeLock(obseverMetux_);
165fc223305Sopenharmony_ci    if (mode == RegisterMode::LOCAL_CHANGE) {
166fc223305Sopenharmony_ci        std::weak_ptr<PreferencesObserver> weakPreferencesObserver = preferencesObserver;
167fc223305Sopenharmony_ci        localObservers_.push_back(weakPreferencesObserver);
168fc223305Sopenharmony_ci    } else if (mode == RegisterMode::MULTI_PRECESS_CHANGE) {
169fc223305Sopenharmony_ci        auto dataObsMgrClient = DataObsMgrClient::GetInstance();
170fc223305Sopenharmony_ci        if (dataObsMgrClient == nullptr) {
171fc223305Sopenharmony_ci            return E_GET_DATAOBSMGRCLIENT_FAIL;
172fc223305Sopenharmony_ci        }
173fc223305Sopenharmony_ci        sptr<DataPreferencesObserverStub> observer(new (std::nothrow) DataPreferencesObserverStub(preferencesObserver));
174fc223305Sopenharmony_ci        int errcode = dataObsMgrClient->RegisterObserver(MakeUri(), observer);
175fc223305Sopenharmony_ci        if (errcode != 0) {
176fc223305Sopenharmony_ci            LOG_ERROR("RegisterObserver multiProcessChange failed, errCode %{public}d", errcode);
177fc223305Sopenharmony_ci            return errcode;
178fc223305Sopenharmony_ci        }
179fc223305Sopenharmony_ci        multiProcessObservers_.push_back(observer);
180fc223305Sopenharmony_ci    }
181fc223305Sopenharmony_ci    LOG_INFO("The local observer subscribed succeeded.");
182fc223305Sopenharmony_ci    return E_OK;
183fc223305Sopenharmony_ci}
184fc223305Sopenharmony_ci
185fc223305Sopenharmony_ciint PreferencesBase::UnRegisterDataObserver(std::shared_ptr<PreferencesObserver> preferencesObserver,
186fc223305Sopenharmony_ci    const std::vector<std::string> &keys)
187fc223305Sopenharmony_ci{
188fc223305Sopenharmony_ci    std::unique_lock<std::shared_mutex> writeLock(obseverMetux_);
189fc223305Sopenharmony_ci    auto it = dataObserversMap_.find(preferencesObserver);
190fc223305Sopenharmony_ci    if (it == dataObserversMap_.end()) {
191fc223305Sopenharmony_ci        return E_OK;
192fc223305Sopenharmony_ci    }
193fc223305Sopenharmony_ci    for (const auto &key : keys) {
194fc223305Sopenharmony_ci        auto keyIt = it->second.find(key);
195fc223305Sopenharmony_ci        if (keyIt != it->second.end()) {
196fc223305Sopenharmony_ci            it->second.erase(key);
197fc223305Sopenharmony_ci        }
198fc223305Sopenharmony_ci    }
199fc223305Sopenharmony_ci    LOG_DEBUG("UnRegisterObserver keysSize:%{public}zu, curSize:%{public}zu", keys.size(), it->second.size());
200fc223305Sopenharmony_ci    if (keys.empty()) {
201fc223305Sopenharmony_ci        it->second.clear();
202fc223305Sopenharmony_ci    }
203fc223305Sopenharmony_ci    if (it->second.empty()) {
204fc223305Sopenharmony_ci        it = dataObserversMap_.erase(it);
205fc223305Sopenharmony_ci        LOG_DEBUG("UnRegisterObserver finish. obSize:%{public}zu", dataObserversMap_.size());
206fc223305Sopenharmony_ci        return E_OK;
207fc223305Sopenharmony_ci    }
208fc223305Sopenharmony_ci    LOG_DEBUG("UnRegisterObserver finish, observer need reserve. obSize:%{public}zu", dataObserversMap_.size());
209fc223305Sopenharmony_ci    return E_OBSERVER_RESERVE;
210fc223305Sopenharmony_ci}
211fc223305Sopenharmony_ci
212fc223305Sopenharmony_cistd::string PreferencesBase::GetGroupId() const
213fc223305Sopenharmony_ci{
214fc223305Sopenharmony_ci    return options_.dataGroupId;
215fc223305Sopenharmony_ci}
216fc223305Sopenharmony_ci
217fc223305Sopenharmony_ciint PreferencesBase::CloseDb()
218fc223305Sopenharmony_ci{
219fc223305Sopenharmony_ci    return E_OK;
220fc223305Sopenharmony_ci}
221fc223305Sopenharmony_ci
222fc223305Sopenharmony_cistd::pair<int, PreferencesValue> PreferencesBase::GetValue(const std::string &key, const PreferencesValue &defValue)
223fc223305Sopenharmony_ci{
224fc223305Sopenharmony_ci    return std::make_pair(E_OK, defValue);
225fc223305Sopenharmony_ci}
226fc223305Sopenharmony_ci
227fc223305Sopenharmony_cistd::pair<int, std::map<std::string, PreferencesValue>> PreferencesBase::GetAllData()
228fc223305Sopenharmony_ci{
229fc223305Sopenharmony_ci    std::map<std::string, PreferencesValue> map;
230fc223305Sopenharmony_ci    return std::make_pair(E_OK, map);
231fc223305Sopenharmony_ci}
232fc223305Sopenharmony_ci
233fc223305Sopenharmony_ciint PreferencesBase::RegisterDataObserver(std::shared_ptr<PreferencesObserver> preferencesObserver,
234fc223305Sopenharmony_ci    const std::vector<std::string> &keys)
235fc223305Sopenharmony_ci{
236fc223305Sopenharmony_ci    std::unique_lock<std::shared_mutex> writeLock(obseverMetux_);
237fc223305Sopenharmony_ci    auto it = dataObserversMap_.find(preferencesObserver);
238fc223305Sopenharmony_ci    if (it == dataObserversMap_.end()) {
239fc223305Sopenharmony_ci        std::set<std::string> callKeys(keys.begin(), keys.end());
240fc223305Sopenharmony_ci        std::weak_ptr<PreferencesObserver> weakPreferencesObserver = preferencesObserver;
241fc223305Sopenharmony_ci        dataObserversMap_.insert({weakPreferencesObserver, std::move(callKeys)});
242fc223305Sopenharmony_ci    } else {
243fc223305Sopenharmony_ci        it->second.insert(keys.begin(), keys.end());
244fc223305Sopenharmony_ci    }
245fc223305Sopenharmony_ci    return E_OK;
246fc223305Sopenharmony_ci}
247fc223305Sopenharmony_ci
248fc223305Sopenharmony_ciint PreferencesBase::UnRegisterObserver(std::shared_ptr<PreferencesObserver> preferencesObserver, RegisterMode mode)
249fc223305Sopenharmony_ci{
250fc223305Sopenharmony_ci    std::unique_lock<std::shared_mutex> writeLock(obseverMetux_);
251fc223305Sopenharmony_ci    if (mode == RegisterMode::LOCAL_CHANGE) {
252fc223305Sopenharmony_ci        for (auto it = localObservers_.begin(); it != localObservers_.end(); ++it) {
253fc223305Sopenharmony_ci            std::weak_ptr<PreferencesObserver> weakPreferencesObserver = *it;
254fc223305Sopenharmony_ci            std::shared_ptr<PreferencesObserver> sharedObserver = weakPreferencesObserver.lock();
255fc223305Sopenharmony_ci            if (!sharedObserver || sharedObserver == preferencesObserver) {
256fc223305Sopenharmony_ci                localObservers_.erase(it);
257fc223305Sopenharmony_ci                break;
258fc223305Sopenharmony_ci            }
259fc223305Sopenharmony_ci        }
260fc223305Sopenharmony_ci        return E_OK;
261fc223305Sopenharmony_ci    }
262fc223305Sopenharmony_ci    for (auto it = multiProcessObservers_.begin(); it != multiProcessObservers_.end(); ++it) {
263fc223305Sopenharmony_ci        std::shared_ptr<PreferencesObserver> sharedObserver = (*it)->preferencesObserver_.lock();
264fc223305Sopenharmony_ci        if (!sharedObserver || sharedObserver == preferencesObserver) {
265fc223305Sopenharmony_ci            auto dataObsMgrClient = DataObsMgrClient::GetInstance();
266fc223305Sopenharmony_ci            if (dataObsMgrClient == nullptr) {
267fc223305Sopenharmony_ci                return E_GET_DATAOBSMGRCLIENT_FAIL;
268fc223305Sopenharmony_ci            }
269fc223305Sopenharmony_ci            int errcode = dataObsMgrClient->UnregisterObserver(MakeUri(), *it);
270fc223305Sopenharmony_ci            if (errcode != 0) {
271fc223305Sopenharmony_ci                LOG_ERROR("UnRegisterObserver multiProcessChange failed, errCode %{public}d", errcode);
272fc223305Sopenharmony_ci                return errcode;
273fc223305Sopenharmony_ci            }
274fc223305Sopenharmony_ci            multiProcessObservers_.erase(it);
275fc223305Sopenharmony_ci            break;
276fc223305Sopenharmony_ci        }
277fc223305Sopenharmony_ci    }
278fc223305Sopenharmony_ci    LOG_INFO("The observer unsubscribed succeeded.");
279fc223305Sopenharmony_ci    return E_OK;
280fc223305Sopenharmony_ci}
281fc223305Sopenharmony_ci
282fc223305Sopenharmony_ciUri PreferencesBase::MakeUri(const std::string &key)
283fc223305Sopenharmony_ci{
284fc223305Sopenharmony_ci    std::string uriStr;
285fc223305Sopenharmony_ci    if (options_.dataGroupId.empty()) {
286fc223305Sopenharmony_ci        uriStr = STR_SCHEME + options_.bundleName + STR_SLASH + options_.filePath;
287fc223305Sopenharmony_ci    } else {
288fc223305Sopenharmony_ci        uriStr = STR_SCHEME + options_.dataGroupId + STR_SLASH + options_.filePath;
289fc223305Sopenharmony_ci    }
290fc223305Sopenharmony_ci
291fc223305Sopenharmony_ci    if (!key.empty()) {
292fc223305Sopenharmony_ci        uriStr = uriStr + STR_QUERY + key;
293fc223305Sopenharmony_ci    }
294fc223305Sopenharmony_ci    return Uri(uriStr);
295fc223305Sopenharmony_ci}
296fc223305Sopenharmony_ci} // End of namespace NativePreferences
297fc223305Sopenharmony_ci} // End of namespace OHOS
298