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