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