• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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