blob: 55f3f687e2e456645ae4605a0bb5bc5c98322c83 [file] [log] [blame]
[email protected]32c3c752012-01-05 17:33:471// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]39565dd2011-11-14 12:09:272// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
brettwf00b9b42016-02-01 22:11:385#include "components/prefs/overlay_user_pref_store.h"
[email protected]39565dd2011-11-14 12:09:276
dcheng5f043bc2016-04-22 19:09:067#include <memory>
danakj0c8d4aa2015-11-25 05:29:588#include <utility>
9
dcheng5f043bc2016-04-22 19:09:0610#include "base/memory/ptr_util.h"
[email protected]39565dd2011-11-14 12:09:2711#include "base/values.h"
Johan Tibell0595f762017-05-25 23:54:5012#include "components/prefs/in_memory_pref_store.h"
[email protected]39565dd2011-11-14 12:09:2713
Johan Tibell0595f762017-05-25 23:54:5014// Allows us to monitor two pref stores and tell updates from them apart. It
15// essentially mimics a Callback for the Observer interface (e.g. it allows
16// binding additional arguments).
17class OverlayUserPrefStore::ObserverAdapter : public PrefStore::Observer {
18 public:
19 ObserverAdapter(bool overlay, OverlayUserPrefStore* parent)
20 : overlay_(overlay), parent_(parent) {}
21
22 // Methods of PrefStore::Observer.
23 void OnPrefValueChanged(const std::string& key) override {
24 parent_->OnPrefValueChanged(overlay_, key);
25 }
26 void OnInitializationCompleted(bool succeeded) override {
27 parent_->OnInitializationCompleted(overlay_, succeeded);
28 }
29
30 private:
31 // Is the update for the overlay?
32 const bool overlay_;
33 OverlayUserPrefStore* const parent_;
34};
35
36OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* underlay)
37 : OverlayUserPrefStore(new InMemoryPrefStore(), underlay) {}
38
39OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* overlay,
40 PersistentPrefStore* underlay)
41 : overlay_observer_(
42 base::MakeUnique<OverlayUserPrefStore::ObserverAdapter>(true, this)),
43 underlay_observer_(
44 base::MakeUnique<OverlayUserPrefStore::ObserverAdapter>(false, this)),
45 overlay_(overlay),
46 underlay_(underlay) {
47 DCHECK(overlay->IsInitializationComplete());
48 overlay_->AddObserver(overlay_observer_.get());
49 underlay_->AddObserver(underlay_observer_.get());
[email protected]39565dd2011-11-14 12:09:2750}
51
[email protected]39565dd2011-11-14 12:09:2752bool OverlayUserPrefStore::IsSetInOverlay(const std::string& key) const {
Johan Tibell0595f762017-05-25 23:54:5053 return overlay_->GetValue(key, NULL);
[email protected]39565dd2011-11-14 12:09:2754}
55
56void OverlayUserPrefStore::AddObserver(PrefStore::Observer* observer) {
57 observers_.AddObserver(observer);
58}
59
60void OverlayUserPrefStore::RemoveObserver(PrefStore::Observer* observer) {
61 observers_.RemoveObserver(observer);
62}
63
[email protected]14e0ec62013-08-26 22:01:3964bool OverlayUserPrefStore::HasObservers() const {
65 return observers_.might_have_observers();
[email protected]d3b05ea2012-01-24 22:57:0566}
67
[email protected]39565dd2011-11-14 12:09:2768bool OverlayUserPrefStore::IsInitializationComplete() const {
Johan Tibell0595f762017-05-25 23:54:5069 return underlay_->IsInitializationComplete() &&
70 overlay_->IsInitializationComplete();
[email protected]39565dd2011-11-14 12:09:2771}
72
[email protected]892f1d62012-11-08 18:24:3473bool OverlayUserPrefStore::GetValue(const std::string& key,
[email protected]a43a667b2013-06-14 17:56:0874 const base::Value** result) const {
[email protected]39565dd2011-11-14 12:09:2775 // If the |key| shall NOT be stored in the overlay store, there must not
76 // be an entry.
Johan Tibell0595f762017-05-25 23:54:5077 DCHECK(ShallBeStoredInOverlay(key) || !overlay_->GetValue(key, NULL));
[email protected]39565dd2011-11-14 12:09:2778
Johan Tibell0595f762017-05-25 23:54:5079 if (overlay_->GetValue(key, result))
[email protected]892f1d62012-11-08 18:24:3480 return true;
Johan Tibell6566c8ac2017-05-11 03:22:1781 return underlay_->GetValue(key, result);
[email protected]39565dd2011-11-14 12:09:2782}
83
tibelle23659b42017-02-23 01:44:1384std::unique_ptr<base::DictionaryValue> OverlayUserPrefStore::GetValues() const {
85 auto values = underlay_->GetValues();
Johan Tibell0595f762017-05-25 23:54:5086 auto overlay_values = overlay_->GetValues();
Johan Tibell6566c8ac2017-05-11 03:22:1787 for (const auto& key : overlay_names_set_) {
tibelle23659b42017-02-23 01:44:1388 std::unique_ptr<base::Value> out_value;
Johan Tibell6566c8ac2017-05-11 03:22:1789 overlay_values->Remove(key, &out_value);
tibelle23659b42017-02-23 01:44:1390 if (out_value) {
Johan Tibell6566c8ac2017-05-11 03:22:1791 values->Set(key, std::move(out_value));
tibelle23659b42017-02-23 01:44:1392 }
93 }
94 return values;
95}
96
[email protected]892f1d62012-11-08 18:24:3497bool OverlayUserPrefStore::GetMutableValue(const std::string& key,
[email protected]a43a667b2013-06-14 17:56:0898 base::Value** result) {
[email protected]39565dd2011-11-14 12:09:2799 if (!ShallBeStoredInOverlay(key))
Johan Tibell6566c8ac2017-05-11 03:22:17100 return underlay_->GetMutableValue(key, result);
[email protected]39565dd2011-11-14 12:09:27101
Johan Tibell0595f762017-05-25 23:54:50102 written_overlay_names_.insert(key);
103 if (overlay_->GetMutableValue(key, result))
[email protected]892f1d62012-11-08 18:24:34104 return true;
[email protected]39565dd2011-11-14 12:09:27105
106 // Try to create copy of underlay if the overlay does not contain a value.
[email protected]a43a667b2013-06-14 17:56:08107 base::Value* underlay_value = NULL;
Johan Tibell6566c8ac2017-05-11 03:22:17108 if (!underlay_->GetMutableValue(key, &underlay_value))
[email protected]892f1d62012-11-08 18:24:34109 return false;
[email protected]39565dd2011-11-14 12:09:27110
111 *result = underlay_value->DeepCopy();
Johan Tibell0595f762017-05-25 23:54:50112 overlay_->SetValue(key, base::WrapUnique(*result),
113 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
[email protected]892f1d62012-11-08 18:24:34114 return true;
[email protected]39565dd2011-11-14 12:09:27115}
116
117void OverlayUserPrefStore::SetValue(const std::string& key,
dcheng5f043bc2016-04-22 19:09:06118 std::unique_ptr<base::Value> value,
avi9ef8bb02015-12-24 05:29:36119 uint32_t flags) {
[email protected]39565dd2011-11-14 12:09:27120 if (!ShallBeStoredInOverlay(key)) {
Johan Tibell6566c8ac2017-05-11 03:22:17121 underlay_->SetValue(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27122 return;
123 }
124
Johan Tibell0595f762017-05-25 23:54:50125 written_overlay_names_.insert(key);
126 overlay_->SetValue(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27127}
128
129void OverlayUserPrefStore::SetValueSilently(const std::string& key,
dcheng5f043bc2016-04-22 19:09:06130 std::unique_ptr<base::Value> value,
avi9ef8bb02015-12-24 05:29:36131 uint32_t flags) {
[email protected]39565dd2011-11-14 12:09:27132 if (!ShallBeStoredInOverlay(key)) {
Johan Tibell6566c8ac2017-05-11 03:22:17133 underlay_->SetValueSilently(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27134 return;
135 }
136
Johan Tibell0595f762017-05-25 23:54:50137 written_overlay_names_.insert(key);
138 overlay_->SetValueSilently(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27139}
140
avi9ef8bb02015-12-24 05:29:36141void OverlayUserPrefStore::RemoveValue(const std::string& key, uint32_t flags) {
[email protected]39565dd2011-11-14 12:09:27142 if (!ShallBeStoredInOverlay(key)) {
Johan Tibell6566c8ac2017-05-11 03:22:17143 underlay_->RemoveValue(key, flags);
[email protected]39565dd2011-11-14 12:09:27144 return;
145 }
146
Johan Tibell0595f762017-05-25 23:54:50147 written_overlay_names_.insert(key);
148 overlay_->RemoveValue(key, flags);
[email protected]39565dd2011-11-14 12:09:27149}
150
151bool OverlayUserPrefStore::ReadOnly() const {
152 return false;
153}
154
[email protected]59c10712012-03-13 02:10:34155PersistentPrefStore::PrefReadError OverlayUserPrefStore::GetReadError() const {
156 return PersistentPrefStore::PREF_READ_ERROR_NONE;
157}
158
[email protected]39565dd2011-11-14 12:09:27159PersistentPrefStore::PrefReadError OverlayUserPrefStore::ReadPrefs() {
160 // We do not read intentionally.
Johan Tibell0595f762017-05-25 23:54:50161 OnInitializationCompleted(/* overlay */ false, true);
[email protected]39565dd2011-11-14 12:09:27162 return PersistentPrefStore::PREF_READ_ERROR_NONE;
163}
164
165void OverlayUserPrefStore::ReadPrefsAsync(
166 ReadErrorDelegate* error_delegate_raw) {
dcheng5f043bc2016-04-22 19:09:06167 std::unique_ptr<ReadErrorDelegate> error_delegate(error_delegate_raw);
[email protected]39565dd2011-11-14 12:09:27168 // We do not read intentionally.
Johan Tibell0595f762017-05-25 23:54:50169 OnInitializationCompleted(/* overlay */ false, true);
[email protected]39565dd2011-11-14 12:09:27170}
171
Francois Doray405dd2d2017-06-09 15:23:33172void OverlayUserPrefStore::CommitPendingWrite(base::OnceClosure done_callback) {
173 underlay_->CommitPendingWrite(std::move(done_callback));
[email protected]39565dd2011-11-14 12:09:27174 // We do not write our content intentionally.
175}
176
benwells26730592015-05-28 13:08:08177void OverlayUserPrefStore::SchedulePendingLossyWrites() {
178 underlay_->SchedulePendingLossyWrites();
179}
180
raymes76de1af2015-05-06 03:22:21181void OverlayUserPrefStore::ReportValueChanged(const std::string& key,
avi9ef8bb02015-12-24 05:29:36182 uint32_t flags) {
ericwilligers42b92c12016-10-24 20:21:13183 for (PrefStore::Observer& observer : observers_)
184 observer.OnPrefValueChanged(key);
[email protected]39565dd2011-11-14 12:09:27185}
186
[email protected]32c3c752012-01-05 17:33:47187void OverlayUserPrefStore::RegisterOverlayPref(const std::string& key) {
Johan Tibell6566c8ac2017-05-11 03:22:17188 DCHECK(!key.empty()) << "Key is empty";
189 DCHECK(overlay_names_set_.find(key) == overlay_names_set_.end())
190 << "Key already registered";
191 overlay_names_set_.insert(key);
[email protected]39565dd2011-11-14 12:09:27192}
193
dvadym53fc0d42016-02-05 13:34:57194void OverlayUserPrefStore::ClearMutableValues() {
Johan Tibell0595f762017-05-25 23:54:50195 for (const auto& key : written_overlay_names_) {
196 overlay_->RemoveValue(key, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
197 }
dvadym53fc0d42016-02-05 13:34:57198}
199
[email protected]2dea5c02012-04-25 07:01:07200OverlayUserPrefStore::~OverlayUserPrefStore() {
Johan Tibell0595f762017-05-25 23:54:50201 overlay_->RemoveObserver(overlay_observer_.get());
202 underlay_->RemoveObserver(underlay_observer_.get());
203}
204
205void OverlayUserPrefStore::OnPrefValueChanged(bool overlay,
206 const std::string& key) {
207 if (overlay) {
208 ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
209 } else {
210 if (!overlay_->GetValue(key, NULL))
211 ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
212 }
213}
214
215void OverlayUserPrefStore::OnInitializationCompleted(bool overlay,
216 bool succeeded) {
217 if (!IsInitializationComplete())
218 return;
219 for (PrefStore::Observer& observer : observers_)
220 observer.OnInitializationCompleted(succeeded);
[email protected]39565dd2011-11-14 12:09:27221}
222
[email protected]39565dd2011-11-14 12:09:27223bool OverlayUserPrefStore::ShallBeStoredInOverlay(
224 const std::string& key) const {
Johan Tibell6566c8ac2017-05-11 03:22:17225 return overlay_names_set_.find(key) != overlay_names_set_.end();
[email protected]39565dd2011-11-14 12:09:27226}