1 /*
2 * Copyright (c) 2021 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_impl.h"
17
18 #include <cinttypes>
19 #include <climits>
20 #include <cstdlib>
21
22 #include <functional>
23
24 #include "logger.h"
25 #include "preferences_errno.h"
26 #include "preferences_xml_utils.h"
27 #include "securec.h"
28
29 namespace OHOS {
30 namespace NativePreferences {
IsFileExist(const std::filesystem::path & inputPath)31 static bool IsFileExist(const std::filesystem::path &inputPath)
32 {
33 char path[PATH_MAX + 1] = { 0x00 };
34 if (strlen(inputPath.c_str()) > PATH_MAX || realpath(inputPath.c_str(), path) == nullptr) {
35 return false;
36 }
37 const char *pathString = path;
38 FILE *file = std::fopen(pathString, "r");
39 if (file != nullptr) {
40 std::fclose(file);
41 return true;
42 }
43 return false;
44 }
45
PreferencesImpl(const std::filesystem::path & filePath)46 PreferencesImpl::PreferencesImpl(const std::filesystem::path &filePath)
47 : loaded_(false), filePath_(filePath), backupPath_(MakeBackupPath(filePath_)),
48 brokenPath_(MakeBrokenPath(filePath_)), taskPool_(TaskPool(MAX_TP_THREADS, MIN_TP_THREADS))
49 {
50 currentMemoryStateGeneration_ = 0;
51 diskStateGeneration_ = 0;
52 }
53
MakeBackupPath(const std::filesystem::path & prefPath)54 std::filesystem::path PreferencesImpl::MakeBackupPath(const std::filesystem::path &prefPath)
55 {
56 std::filesystem::path backupPath = prefPath;
57 backupPath += ".bak";
58 return backupPath;
59 }
60
MakeBrokenPath(const std::filesystem::path & prefPath)61 std::filesystem::path PreferencesImpl::MakeBrokenPath(const std::filesystem::path &prefPath)
62 {
63 std::filesystem::path brokenPath = prefPath;
64 brokenPath += ".bak";
65 return brokenPath;
66 }
67
~PreferencesImpl()68 PreferencesImpl::~PreferencesImpl()
69 {
70 taskPool_.Stop();
71 }
72
Init()73 int PreferencesImpl::Init()
74 {
75 int errCode = taskPool_.Start();
76 if (errCode != E_OK) {
77 return errCode;
78 }
79 StartLoadFromDisk();
80 return E_OK;
81 }
82
StartLoadFromDisk()83 void PreferencesImpl::StartLoadFromDisk()
84 {
85 {
86 std::lock_guard<std::mutex> lock(mutex_);
87 loaded_ = false;
88 }
89 taskPool_.Schedule(std::string("PreferencesImpl"), std::bind(&PreferencesImpl::LoadFromDisk, std::ref(*this)));
90 }
91
CheckKey(const std::string & key)92 int PreferencesImpl::CheckKey(const std::string &key)
93 {
94 if (key.empty()) {
95 LOG_ERROR("The key string is null or empty.");
96 return E_KEY_EMPTY;
97 }
98 if (Preferences::MAX_KEY_LENGTH < key.length()) {
99 LOG_ERROR("The key string length should shorter than 80.");
100 return E_KEY_EXCEED_MAX_LENGTH;
101 }
102 return E_OK;
103 }
104
105 /* static */
LoadFromDisk(PreferencesImpl & pref)106 void PreferencesImpl::LoadFromDisk(PreferencesImpl &pref)
107 {
108 std::lock_guard<std::mutex> lock(pref.mutex_);
109 if (pref.loaded_) {
110 return;
111 }
112
113 if (IsFileExist(pref.backupPath_)) {
114 if (std::remove(pref.filePath_.c_str())) {
115 LOG_ERROR("Couldn't delete file %{private}s when LoadFromDisk and backup exist.", pref.filePath_.c_str());
116 }
117 if (std::rename(pref.backupPath_.c_str(), pref.filePath_.c_str())) {
118 LOG_ERROR("Couldn't rename backup file %{private}s to file %{private}s,when LoadFromDisk and backup "
119 "exist.",
120 pref.backupPath_.c_str(), pref.filePath_.c_str());
121 } else {
122 PreferencesXmlUtils::LimitXmlPermission(pref.filePath_);
123 }
124 }
125
126 if (IsFileExist(pref.filePath_)) {
127 pref.ReadSettingXml(pref.filePath_, pref.map_);
128 }
129
130 pref.loaded_ = true;
131 pref.cond_.notify_all();
132 }
133
AwaitLoadFile()134 void PreferencesImpl::AwaitLoadFile()
135 {
136 std::unique_lock<std::mutex> lock(mutex_);
137 if (!loaded_) {
138 cond_.wait(lock, [this] { return loaded_; });
139 }
140 }
141
WriteToDiskFile(std::shared_ptr<MemoryToDiskRequest> mcr)142 void PreferencesImpl::WriteToDiskFile(std::shared_ptr<MemoryToDiskRequest> mcr)
143 {
144 bool fileExists = false;
145 if (IsFileExist(filePath_)) {
146 fileExists = true;
147 }
148
149 if (fileExists) {
150 bool needWrite = CheckRequestValidForStateGeneration(*mcr);
151 if (!needWrite) {
152 mcr->SetDiskWriteResult(false, E_OK);
153 return;
154 }
155
156 if (IsFileExist(backupPath_)) {
157 if (std::remove(filePath_.c_str())) {
158 LOG_ERROR("Couldn't delete file %{private}s when writeToFile and backup exist.", filePath_.c_str());
159 }
160 } else {
161 if (std::rename(filePath_.c_str(), backupPath_.c_str())) {
162 LOG_ERROR("Couldn't rename file %{private}s to backup file %{private}s", filePath_.c_str(),
163 backupPath_.c_str());
164 mcr->SetDiskWriteResult(false, E_ERROR);
165 return;
166 } else {
167 PreferencesXmlUtils::LimitXmlPermission(backupPath_);
168 }
169 }
170 }
171
172 if (WriteSettingXml(filePath_, mcr->writeToDiskMap_)) {
173 if (IsFileExist(backupPath_) && std::remove(backupPath_.c_str())) {
174 LOG_ERROR("Couldn't delete backup file %{private}s when writeToFile finish.", backupPath_.c_str());
175 }
176 diskStateGeneration_ = mcr->memoryStateGeneration_;
177 mcr->SetDiskWriteResult(true, E_OK);
178 } else {
179 /* Clean up an unsuccessfully written file */
180 if (IsFileExist(filePath_)) {
181 if (std::remove(filePath_.c_str())) {
182 LOG_ERROR("Couldn't clean up partially-written file %{private}s", filePath_.c_str());
183 }
184 }
185 mcr->SetDiskWriteResult(false, E_ERROR);
186 }
187 }
188
CheckRequestValidForStateGeneration(const MemoryToDiskRequest & mcr)189 bool PreferencesImpl::CheckRequestValidForStateGeneration(const MemoryToDiskRequest &mcr)
190 {
191 bool valid = false;
192
193 if (diskStateGeneration_ < mcr.memoryStateGeneration_) {
194 if (mcr.isSyncRequest_) {
195 valid = true;
196 } else {
197 if (currentMemoryStateGeneration_ == mcr.memoryStateGeneration_) {
198 valid = true;
199 }
200 }
201 }
202 return valid;
203 }
204
GetInt(const std::string & key,int defValue)205 int PreferencesImpl::GetInt(const std::string &key, int defValue)
206 {
207 if (CheckKey(key) != E_OK) {
208 return defValue;
209 }
210
211 AwaitLoadFile();
212
213 std::lock_guard<std::mutex> lock(mutex_);
214 int ret = defValue;
215
216 auto iter = map_.find(key);
217 if (iter != map_.end()) {
218 PreferencesValue val = iter->second;
219 if (val.IsInt()) {
220 ret = val;
221 }
222 }
223 return ret;
224 }
225
GetString(const std::string & key,const std::string & defValue)226 std::string PreferencesImpl::GetString(const std::string &key, const std::string &defValue)
227 {
228 if (CheckKey(key) != E_OK) {
229 return defValue;
230 }
231
232 AwaitLoadFile();
233
234 std::lock_guard<std::mutex> lock(mutex_);
235 std::string ret = defValue;
236
237 auto iter = map_.find(key);
238 if (iter != map_.end()) {
239 PreferencesValue val = iter->second;
240 if (val.IsString()) {
241 ret = (std::string)val;
242 }
243 }
244 return ret;
245 }
246
GetBool(const std::string & key,bool defValue)247 bool PreferencesImpl::GetBool(const std::string &key, bool defValue)
248 {
249 if (CheckKey(key) != E_OK) {
250 return defValue;
251 }
252
253 AwaitLoadFile();
254
255 std::lock_guard<std::mutex> lock(mutex_);
256 bool ret = defValue;
257
258 auto iter = map_.find(key);
259 if (iter != map_.end()) {
260 PreferencesValue val = iter->second;
261 if (val.IsBool()) {
262 ret = val;
263 }
264 }
265 return ret;
266 }
267
GetFloat(const std::string & key,float defValue)268 float PreferencesImpl::GetFloat(const std::string &key, float defValue)
269 {
270 if (CheckKey(key) != E_OK) {
271 return defValue;
272 }
273
274 AwaitLoadFile();
275
276 std::lock_guard<std::mutex> lock(mutex_);
277 float ret = defValue;
278
279 auto iter = map_.find(key);
280 if (iter != map_.end()) {
281 PreferencesValue val = iter->second;
282 if (val.IsFloat()) {
283 ret = val;
284 }
285 }
286 return ret;
287 }
288
GetDouble(const std::string & key,double defValue)289 double PreferencesImpl::GetDouble(const std::string &key, double defValue)
290 {
291 if (CheckKey(key) != E_OK) {
292 return defValue;
293 }
294
295 AwaitLoadFile();
296
297 std::lock_guard<std::mutex> lock(mutex_);
298 double ret = defValue;
299
300 auto iter = map_.find(key);
301 if (iter != map_.end()) {
302 PreferencesValue val = iter->second;
303 if (val.IsDouble()) {
304 ret = val;
305 }
306 }
307 return ret;
308 }
309
GetLong(const std::string & key,int64_t defValue)310 int64_t PreferencesImpl::GetLong(const std::string &key, int64_t defValue)
311 {
312 if (CheckKey(key) != E_OK) {
313 return defValue;
314 }
315
316 AwaitLoadFile();
317
318 std::lock_guard<std::mutex> lock(mutex_);
319 int64_t ret = defValue;
320
321 auto iter = map_.find(key);
322 if (iter != map_.end()) {
323 PreferencesValue val = iter->second;
324 if (val.IsLong()) {
325 ret = val;
326 }
327 }
328 return ret;
329 }
330
GetStringSet(const std::string & key,std::set<std::string> & defValue)331 std::set<std::string> PreferencesImpl::GetStringSet(const std::string &key, std::set<std::string> &defValue)
332 {
333 if (CheckKey(key) != E_OK) {
334 return defValue;
335 }
336
337 AwaitLoadFile();
338
339 std::lock_guard<std::mutex> lock(mutex_);
340 std::set<std::string> ret = defValue;
341
342 auto iter = map_.find(key);
343 if (iter != map_.end()) {
344 PreferencesValue val = iter->second;
345 if (val.IsSet()) {
346 ret = val;
347 }
348 }
349 return ret;
350 }
351
GetAll()352 std::map<std::string, PreferencesValue> PreferencesImpl::GetAll()
353 {
354 AwaitLoadFile();
355
356 return map_;
357 }
358
ReadSettingXml(const std::filesystem::path & prefPath,std::map<std::string,PreferencesValue> & prefMap)359 bool PreferencesImpl::ReadSettingXml(
360 const std::filesystem::path &prefPath, std::map<std::string, PreferencesValue> &prefMap)
361 {
362 std::vector<Element> settings;
363 if (!PreferencesXmlUtils::ReadSettingXml(prefPath.generic_string(), settings)) {
364 LOG_ERROR("ReadSettingXml:%{private}s failed!", filePath_.c_str());
365 return false;
366 }
367
368 for (auto it = settings.begin(); it != settings.end(); it++) {
369 Element element = *it;
370 if (element.tag_.compare("int") == 0) {
371 int value = atoi(element.value_.c_str());
372 prefMap.insert(std::make_pair(element.key_, PreferencesValue(value)));
373 } else if (element.tag_.compare("bool") == 0) {
374 bool value = (element.value_.compare("true") == 0) ? true : false;
375 prefMap.insert(std::make_pair(element.key_, PreferencesValue(value)));
376 } else if (element.tag_.compare("long") == 0) {
377 int64_t value = static_cast<int64_t>(atoll(element.value_.c_str()));
378 prefMap.insert(std::make_pair(element.key_, PreferencesValue(value)));
379 } else if (element.tag_.compare("float") == 0) {
380 float value = atof(element.value_.c_str());
381 prefMap.insert(std::make_pair(element.key_, PreferencesValue(value)));
382 } else if (element.tag_.compare("double") == 0) {
383 double value = atof(element.value_.c_str());
384 prefMap.insert(std::make_pair(element.key_, PreferencesValue(value)));
385 } else if (element.tag_.compare("string") == 0) {
386 prefMap.insert(std::make_pair(element.key_, PreferencesValue(element.value_)));
387 } else if (element.tag_.compare("set") == 0) {
388 std::set<std::string> values;
389 for (auto child : element.children_) {
390 values.insert(child.value_);
391 }
392 prefMap.insert(std::make_pair(element.key_, PreferencesValue(values)));
393 } else {
394 LOG_WARN(
395 "ReadSettingXml:%{private}s, unknown element tag:%{public}s.", prefPath.c_str(), element.tag_.c_str());
396 }
397 }
398 return true;
399 }
400
WriteSettingXml(const std::filesystem::path & prefPath,const std::map<std::string,PreferencesValue> & prefMap)401 bool PreferencesImpl::WriteSettingXml(
402 const std::filesystem::path &prefPath, const std::map<std::string, PreferencesValue> &prefMap)
403 {
404 std::vector<Element> settings;
405 for (auto it = prefMap.begin(); it != prefMap.end(); it++) {
406 Element elem;
407 elem.key_ = it->first;
408
409 PreferencesValue value = it->second;
410 if (value.IsInt()) {
411 elem.tag_ = std::string("int");
412 elem.value_ = std::to_string((int)value);
413 } else if (value.IsBool()) {
414 elem.tag_ = std::string("bool");
415 elem.value_ = std::to_string((bool)value);
416 } else if (value.IsLong()) {
417 elem.tag_ = std::string("long");
418 elem.value_ = std::to_string((int64_t)value);
419 } else if (value.IsFloat()) {
420 elem.tag_ = std::string("float");
421 elem.value_ = std::to_string((float)value);
422 } else if (value.IsDouble()) {
423 elem.tag_ = std::string("double");
424 elem.value_ = std::to_string((double)value);
425 } else if (value.IsString()) {
426 elem.tag_ = std::string("string");
427 elem.value_ = (std::string)value;
428 } else if (value.IsSet()) {
429 elem.tag_ = std::string("set");
430 auto values = (std::set<std::string>)value;
431 for (std::string val : values) {
432 Element element;
433 element.tag_ = std::string("string");
434 element.value_ = (std::string)val;
435 elem.children_.push_back(element);
436 }
437 } else {
438 LOG_WARN("WriteSettingXml:%{private}s, unknown element type.", filePath_.c_str());
439 continue;
440 }
441 settings.push_back(elem);
442 }
443
444 return PreferencesXmlUtils::WriteSettingXml(prefPath.generic_string(), settings);
445 }
446
HasKey(const std::string & key)447 bool PreferencesImpl::HasKey(const std::string &key)
448 {
449 if (CheckKey(key) != E_OK) {
450 return false;
451 }
452
453 AwaitLoadFile();
454
455 std::lock_guard<std::mutex> lock(mutex_);
456 return (map_.find(key) != map_.end());
457 }
458
RegisterObserver(std::shared_ptr<PreferencesObserver> preferencesObserver)459 void PreferencesImpl::RegisterObserver(std::shared_ptr<PreferencesObserver> preferencesObserver)
460 {
461 std::lock_guard<std::mutex> lock(mutex_);
462 std::weak_ptr<PreferencesObserver> weakPreferencesObserver = preferencesObserver;
463 preferencesObservers_.push_back(weakPreferencesObserver);
464 }
465
UnRegisterObserver(std::shared_ptr<PreferencesObserver> preferencesObserver)466 void PreferencesImpl::UnRegisterObserver(std::shared_ptr<PreferencesObserver> preferencesObserver)
467 {
468 std::lock_guard<std::mutex> lock(mutex_);
469 for (auto it = preferencesObservers_.begin(); it != preferencesObservers_.end(); ++it) {
470 std::weak_ptr<PreferencesObserver> weakPreferencesObserver = *it;
471 std::shared_ptr<PreferencesObserver> sharedPreferencesObserver = weakPreferencesObserver.lock();
472 if (!sharedPreferencesObserver || sharedPreferencesObserver == preferencesObserver) {
473 preferencesObservers_.erase(it);
474 break;
475 }
476 }
477 }
478
PutPreferencesValue(const std::string & key,const PreferencesValue & value)479 void PreferencesImpl::PutPreferencesValue(const std::string &key, const PreferencesValue &value)
480 {
481 AwaitLoadFile();
482
483 std::lock_guard<std::mutex> lock(mutex_);
484
485 auto iter = map_.find(key);
486 if (iter != map_.end()) {
487 PreferencesValue &val = iter->second;
488 if (val == value) {
489 return;
490 }
491 }
492
493 map_.insert_or_assign(key, value);
494 modifiedKeys_.push_back(key);
495 }
496
PutInt(const std::string & key,int value)497 int PreferencesImpl::PutInt(const std::string &key, int value)
498 {
499 int errCode = CheckKey(key);
500 if (errCode != E_OK) {
501 return errCode;
502 }
503 PutPreferencesValue(key, PreferencesValue(value));
504 return E_OK;
505 }
506
CheckStringValue(const std::string & value)507 int PreferencesImpl::CheckStringValue(const std::string &value)
508 {
509 if (Preferences::MAX_VALUE_LENGTH < value.length()) {
510 LOG_ERROR("The value string length should shorter than 8 * 1024.");
511 return E_VALUE_EXCEED_MAX_LENGTH;
512 }
513 return E_OK;
514 }
515
PutString(const std::string & key,const std::string & value)516 int PreferencesImpl::PutString(const std::string &key, const std::string &value)
517 {
518 int errCode = CheckKey(key);
519 if (errCode != E_OK) {
520 return errCode;
521 }
522 errCode = CheckStringValue(value);
523 if (errCode != E_OK) {
524 return errCode;
525 }
526 PutPreferencesValue(key, PreferencesValue(value));
527 return E_OK;
528 }
529
PutBool(const std::string & key,bool value)530 int PreferencesImpl::PutBool(const std::string &key, bool value)
531 {
532 int errCode = CheckKey(key);
533 if (errCode != E_OK) {
534 return errCode;
535 }
536 PutPreferencesValue(key, PreferencesValue(value));
537 return E_OK;
538 }
539
PutLong(const std::string & key,int64_t value)540 int PreferencesImpl::PutLong(const std::string &key, int64_t value)
541 {
542 int errCode = CheckKey(key);
543 if (errCode != E_OK) {
544 return errCode;
545 }
546 PutPreferencesValue(key, PreferencesValue(value));
547 return E_OK;
548 }
549
PutFloat(const std::string & key,float value)550 int PreferencesImpl::PutFloat(const std::string &key, float value)
551 {
552 int errCode = CheckKey(key);
553 if (errCode != E_OK) {
554 return errCode;
555 }
556 PutPreferencesValue(key, PreferencesValue(value));
557 return E_OK;
558 }
559
PutDouble(const std::string & key,double value)560 int PreferencesImpl::PutDouble(const std::string &key, double value)
561 {
562 int errCode = CheckKey(key);
563 if (errCode != E_OK) {
564 return errCode;
565 }
566 PutPreferencesValue(key, PreferencesValue(value));
567 return E_OK;
568 }
569
PutStringSet(const std::string & key,const std::set<std::string> & value)570 int PreferencesImpl::PutStringSet(const std::string &key, const std::set<std::string> &value)
571 {
572 int errCode = CheckKey(key);
573 if (errCode != E_OK) {
574 return errCode;
575 }
576 for (auto child : value) {
577 if (CheckStringValue(child) != E_OK) {
578 return errCode;
579 }
580 }
581 PutPreferencesValue(key, PreferencesValue(value));
582 return E_OK;
583 }
584
Delete(const std::string & key)585 int PreferencesImpl::Delete(const std::string &key)
586 {
587 int errCode = CheckKey(key);
588 if (errCode != E_OK) {
589 return errCode;
590 }
591
592 std::lock_guard<std::mutex> lock(mutex_);
593
594 auto pos = map_.find(key);
595 if (pos != map_.end()) {
596 map_.erase(pos);
597 modifiedKeys_.push_back(key);
598 }
599
600 return E_OK;
601 }
602
Clear()603 int PreferencesImpl::Clear()
604 {
605 std::lock_guard<std::mutex> lock(mutex_);
606
607 if (!map_.empty()) {
608 for (auto &kv : map_) {
609 modifiedKeys_.push_back(kv.first);
610 }
611 map_.clear();
612 }
613 return E_OK;
614 }
615
Flush()616 void PreferencesImpl::Flush()
617 {
618 std::shared_ptr<PreferencesImpl::MemoryToDiskRequest> request = commitToMemory();
619 request->isSyncRequest_ = false;
620
621 taskPool_.Schedule(
622 std::string("PreferencesImpl"), std::bind(&PreferencesImpl::WriteToDiskFile, std::ref(*this), request));
623 notifyPreferencesObserver(*request);
624 }
625
FlushSync()626 int PreferencesImpl::FlushSync()
627 {
628 std::shared_ptr<PreferencesImpl::MemoryToDiskRequest> request = commitToMemory();
629 request->isSyncRequest_ = true;
630
631 taskPool_.Schedule(
632 std::string("PreferencesImpl"), std::bind(&PreferencesImpl::WriteToDiskFile, std::ref(*this), request));
633 std::unique_lock<std::mutex> lock(request->reqMutex_);
634 request->reqCond_.wait(lock, [request] { return request->handled_; });
635 if (request->wasWritten_) {
636 LOG_DEBUG("%{private}s:%{public}" PRId64 " written", filePath_.c_str(), request->memoryStateGeneration_);
637 }
638
639 notifyPreferencesObserver(*request);
640 return request->writeToDiskResult_;
641 }
642
commitToMemory()643 std::shared_ptr<PreferencesImpl::MemoryToDiskRequest> PreferencesImpl::commitToMemory()
644 {
645 std::lock_guard<std::mutex> lock(mutex_);
646 int64_t memoryStateGeneration = -1;
647 std::list<std::string> keysModified;
648 std::vector<std::weak_ptr<PreferencesObserver>> preferencesObservers;
649 std::map<std::string, PreferencesValue> writeToDiskMap;
650 writeToDiskMap = map_;
651 if (!modifiedKeys_.empty()) {
652 currentMemoryStateGeneration_++;
653 keysModified = modifiedKeys_;
654 modifiedKeys_.clear();
655 }
656 memoryStateGeneration = currentMemoryStateGeneration_;
657 preferencesObservers = preferencesObservers_;
658 return std::make_shared<MemoryToDiskRequest>(
659 writeToDiskMap, keysModified, preferencesObservers, memoryStateGeneration);
660 }
661
notifyPreferencesObserver(const PreferencesImpl::MemoryToDiskRequest & request)662 void PreferencesImpl::notifyPreferencesObserver(const PreferencesImpl::MemoryToDiskRequest &request)
663 {
664 if ((request.preferencesObservers_.empty()) || (request.keysModified_.empty())) {
665 return;
666 }
667 for (auto key = request.keysModified_.begin(); key != request.keysModified_.end(); ++key) {
668 for (auto it = request.preferencesObservers_.begin(); it != request.preferencesObservers_.end(); ++it) {
669 std::weak_ptr<PreferencesObserver> weakPreferencesObserver = *it;
670 if (std::shared_ptr<PreferencesObserver> sharedPreferencesObserver = weakPreferencesObserver.lock()) {
671 sharedPreferencesObserver->OnChange(*this, *key);
672 }
673 }
674 }
675 }
676
MemoryToDiskRequest(const std::map<std::string,PreferencesValue> & writeToDiskMap,const std::list<std::string> & keysModified,const std::vector<std::weak_ptr<PreferencesObserver>> preferencesObservers,int64_t memStataGeneration)677 PreferencesImpl::MemoryToDiskRequest::MemoryToDiskRequest(
678 const std::map<std::string, PreferencesValue> &writeToDiskMap, const std::list<std::string> &keysModified,
679 const std::vector<std::weak_ptr<PreferencesObserver>> preferencesObservers, int64_t memStataGeneration)
680 {
681 writeToDiskMap_ = writeToDiskMap;
682 keysModified_ = keysModified;
683 preferencesObservers_ = preferencesObservers;
684 memoryStateGeneration_ = memStataGeneration;
685 isSyncRequest_ = false;
686 handled_ = false;
687 wasWritten_ = false;
688 writeToDiskResult_ = E_ERROR;
689 }
690
SetDiskWriteResult(bool wasWritten,int result)691 void PreferencesImpl::MemoryToDiskRequest::SetDiskWriteResult(bool wasWritten, int result)
692 {
693 writeToDiskResult_ = result;
694 wasWritten_ = wasWritten;
695 handled_ = true;
696 reqCond_.notify_one();
697 }
698 } // End of namespace NativePreferences
699 } // End of namespace OHOS
700