blob: 0baa6c4b8ad7306cffab5347fa47ed40357f8146 [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:
Ramin Halavatif623bafe92018-07-17 12:12:5819 ObserverAdapter(bool ephemeral, OverlayUserPrefStore* parent)
20 : ephemeral_user_pref_store_(ephemeral), parent_(parent) {}
Johan Tibell0595f762017-05-25 23:54:5021
22 // Methods of PrefStore::Observer.
23 void OnPrefValueChanged(const std::string& key) override {
Ramin Halavatif623bafe92018-07-17 12:12:5824 parent_->OnPrefValueChanged(ephemeral_user_pref_store_, key);
Johan Tibell0595f762017-05-25 23:54:5025 }
26 void OnInitializationCompleted(bool succeeded) override {
Ramin Halavatif623bafe92018-07-17 12:12:5827 parent_->OnInitializationCompleted(ephemeral_user_pref_store_, succeeded);
Johan Tibell0595f762017-05-25 23:54:5028 }
29
30 private:
Ramin Halavatif623bafe92018-07-17 12:12:5831 // Is the update for the ephemeral?
32 const bool ephemeral_user_pref_store_;
Johan Tibell0595f762017-05-25 23:54:5033 OverlayUserPrefStore* const parent_;
34};
35
Ramin Halavatif623bafe92018-07-17 12:12:5836OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* persistent)
37 : OverlayUserPrefStore(new InMemoryPrefStore(), persistent) {}
Johan Tibell0595f762017-05-25 23:54:5038
Ramin Halavatif623bafe92018-07-17 12:12:5839OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* ephemeral,
40 PersistentPrefStore* persistent)
41 : ephemeral_pref_store_observer_(
Jinho Bang84b58bd2018-01-01 21:44:4842 std::make_unique<OverlayUserPrefStore::ObserverAdapter>(true, this)),
Ramin Halavatif623bafe92018-07-17 12:12:5843 persistent_pref_store_observer_(
Jinho Bang84b58bd2018-01-01 21:44:4844 std::make_unique<OverlayUserPrefStore::ObserverAdapter>(false, this)),
Ramin Halavatif623bafe92018-07-17 12:12:5845 ephemeral_user_pref_store_(ephemeral),
46 persistent_user_pref_store_(persistent) {
47 DCHECK(ephemeral->IsInitializationComplete());
48 ephemeral_user_pref_store_->AddObserver(ephemeral_pref_store_observer_.get());
49 persistent_user_pref_store_->AddObserver(
50 persistent_pref_store_observer_.get());
[email protected]39565dd2011-11-14 12:09:2751}
52
[email protected]39565dd2011-11-14 12:09:2753bool OverlayUserPrefStore::IsSetInOverlay(const std::string& key) const {
Ramin Halavatif623bafe92018-07-17 12:12:5854 return ephemeral_user_pref_store_->GetValue(key, nullptr);
[email protected]39565dd2011-11-14 12:09:2755}
56
57void OverlayUserPrefStore::AddObserver(PrefStore::Observer* observer) {
58 observers_.AddObserver(observer);
59}
60
61void OverlayUserPrefStore::RemoveObserver(PrefStore::Observer* observer) {
62 observers_.RemoveObserver(observer);
63}
64
[email protected]14e0ec62013-08-26 22:01:3965bool OverlayUserPrefStore::HasObservers() const {
66 return observers_.might_have_observers();
[email protected]d3b05ea2012-01-24 22:57:0567}
68
[email protected]39565dd2011-11-14 12:09:2769bool OverlayUserPrefStore::IsInitializationComplete() const {
Ramin Halavatif623bafe92018-07-17 12:12:5870 return persistent_user_pref_store_->IsInitializationComplete() &&
71 ephemeral_user_pref_store_->IsInitializationComplete();
[email protected]39565dd2011-11-14 12:09:2772}
73
[email protected]892f1d62012-11-08 18:24:3474bool OverlayUserPrefStore::GetValue(const std::string& key,
[email protected]a43a667b2013-06-14 17:56:0875 const base::Value** result) const {
Ramin Halavatif623bafe92018-07-17 12:12:5876 // If the |key| shall NOT be stored in the ephemeral store, there must not
[email protected]39565dd2011-11-14 12:09:2777 // be an entry.
Ramin Halavatif623bafe92018-07-17 12:12:5878 DCHECK(!ShallBeStoredInPersistent(key) ||
79 !ephemeral_user_pref_store_->GetValue(key, nullptr));
[email protected]39565dd2011-11-14 12:09:2780
Ramin Halavatif623bafe92018-07-17 12:12:5881 if (ephemeral_user_pref_store_->GetValue(key, result))
[email protected]892f1d62012-11-08 18:24:3482 return true;
Ramin Halavatif623bafe92018-07-17 12:12:5883 return persistent_user_pref_store_->GetValue(key, result);
[email protected]39565dd2011-11-14 12:09:2784}
85
tibelle23659b42017-02-23 01:44:1386std::unique_ptr<base::DictionaryValue> OverlayUserPrefStore::GetValues() const {
Ramin Halavatif623bafe92018-07-17 12:12:5887 auto values = ephemeral_user_pref_store_->GetValues();
88 auto persistent_values = persistent_user_pref_store_->GetValues();
89
90 // Output |values| are read from |ephemeral_user_pref_store_| (in-memory
91 // store). Then the values of preferences in |persistent_names_set_| are
92 // overwritten by the content of |persistent_user_pref_store_| (the persistent
93 // store).
94 for (const auto& key : persistent_names_set_) {
tibelle23659b42017-02-23 01:44:1395 std::unique_ptr<base::Value> out_value;
Ramin Halavatif623bafe92018-07-17 12:12:5896 persistent_values->Remove(key, &out_value);
tibelle23659b42017-02-23 01:44:1397 if (out_value) {
Johan Tibell6566c8ac2017-05-11 03:22:1798 values->Set(key, std::move(out_value));
tibelle23659b42017-02-23 01:44:1399 }
100 }
101 return values;
102}
103
[email protected]892f1d62012-11-08 18:24:34104bool OverlayUserPrefStore::GetMutableValue(const std::string& key,
[email protected]a43a667b2013-06-14 17:56:08105 base::Value** result) {
Ramin Halavatif623bafe92018-07-17 12:12:58106 if (ShallBeStoredInPersistent(key))
107 return persistent_user_pref_store_->GetMutableValue(key, result);
[email protected]39565dd2011-11-14 12:09:27108
Ramin Halavatif623bafe92018-07-17 12:12:58109 written_ephemeral_names_.insert(key);
110 if (ephemeral_user_pref_store_->GetMutableValue(key, result))
[email protected]892f1d62012-11-08 18:24:34111 return true;
[email protected]39565dd2011-11-14 12:09:27112
Ramin Halavatif623bafe92018-07-17 12:12:58113 // Try to create copy of persistent if the ephemeral does not contain a value.
114 base::Value* persistent_value = nullptr;
115 if (!persistent_user_pref_store_->GetMutableValue(key, &persistent_value))
[email protected]892f1d62012-11-08 18:24:34116 return false;
[email protected]39565dd2011-11-14 12:09:27117
Ramin Halavatif623bafe92018-07-17 12:12:58118 ephemeral_user_pref_store_->SetValue(
Vladislav Kuzkokov8ee75fbc2019-01-14 14:14:04119 key, persistent_value->CreateDeepCopy(),
Ramin Halavatif623bafe92018-07-17 12:12:58120 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
Vladislav Kuzkokov8ee75fbc2019-01-14 14:14:04121 ephemeral_user_pref_store_->GetMutableValue(key, result);
[email protected]892f1d62012-11-08 18:24:34122 return true;
[email protected]39565dd2011-11-14 12:09:27123}
124
125void OverlayUserPrefStore::SetValue(const std::string& key,
dcheng5f043bc2016-04-22 19:09:06126 std::unique_ptr<base::Value> value,
avi9ef8bb02015-12-24 05:29:36127 uint32_t flags) {
Ramin Halavatif623bafe92018-07-17 12:12:58128 if (ShallBeStoredInPersistent(key)) {
129 persistent_user_pref_store_->SetValue(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27130 return;
131 }
132
Ramin Halavatif623bafe92018-07-17 12:12:58133 // TODO(https://crbug.com/861722): If we always store in in-memory storage
134 // and conditionally also stored in persistent one, we wouldn't have to do a
135 // complex merge in GetValues().
136 written_ephemeral_names_.insert(key);
137 ephemeral_user_pref_store_->SetValue(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27138}
139
140void OverlayUserPrefStore::SetValueSilently(const std::string& key,
dcheng5f043bc2016-04-22 19:09:06141 std::unique_ptr<base::Value> value,
avi9ef8bb02015-12-24 05:29:36142 uint32_t flags) {
Ramin Halavatif623bafe92018-07-17 12:12:58143 if (ShallBeStoredInPersistent(key)) {
144 persistent_user_pref_store_->SetValueSilently(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27145 return;
146 }
147
Ramin Halavatif623bafe92018-07-17 12:12:58148 written_ephemeral_names_.insert(key);
149 ephemeral_user_pref_store_->SetValueSilently(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27150}
151
avi9ef8bb02015-12-24 05:29:36152void OverlayUserPrefStore::RemoveValue(const std::string& key, uint32_t flags) {
Ramin Halavatif623bafe92018-07-17 12:12:58153 if (ShallBeStoredInPersistent(key)) {
154 persistent_user_pref_store_->RemoveValue(key, flags);
[email protected]39565dd2011-11-14 12:09:27155 return;
156 }
157
Ramin Halavatif623bafe92018-07-17 12:12:58158 written_ephemeral_names_.insert(key);
159 ephemeral_user_pref_store_->RemoveValue(key, flags);
[email protected]39565dd2011-11-14 12:09:27160}
161
162bool OverlayUserPrefStore::ReadOnly() const {
163 return false;
164}
165
[email protected]59c10712012-03-13 02:10:34166PersistentPrefStore::PrefReadError OverlayUserPrefStore::GetReadError() const {
167 return PersistentPrefStore::PREF_READ_ERROR_NONE;
168}
169
[email protected]39565dd2011-11-14 12:09:27170PersistentPrefStore::PrefReadError OverlayUserPrefStore::ReadPrefs() {
171 // We do not read intentionally.
Ramin Halavatif623bafe92018-07-17 12:12:58172 OnInitializationCompleted(/* ephemeral */ false, true);
[email protected]39565dd2011-11-14 12:09:27173 return PersistentPrefStore::PREF_READ_ERROR_NONE;
174}
175
176void OverlayUserPrefStore::ReadPrefsAsync(
177 ReadErrorDelegate* error_delegate_raw) {
dcheng5f043bc2016-04-22 19:09:06178 std::unique_ptr<ReadErrorDelegate> error_delegate(error_delegate_raw);
[email protected]39565dd2011-11-14 12:09:27179 // We do not read intentionally.
Ramin Halavatif623bafe92018-07-17 12:12:58180 OnInitializationCompleted(/* ephemeral */ false, true);
[email protected]39565dd2011-11-14 12:09:27181}
182
Gabriel Charette788eaf62018-08-07 20:11:46183void OverlayUserPrefStore::CommitPendingWrite(
184 base::OnceClosure reply_callback,
185 base::OnceClosure synchronous_done_callback) {
186 persistent_user_pref_store_->CommitPendingWrite(
187 std::move(reply_callback), std::move(synchronous_done_callback));
[email protected]39565dd2011-11-14 12:09:27188 // We do not write our content intentionally.
189}
190
benwells26730592015-05-28 13:08:08191void OverlayUserPrefStore::SchedulePendingLossyWrites() {
Ramin Halavatif623bafe92018-07-17 12:12:58192 persistent_user_pref_store_->SchedulePendingLossyWrites();
benwells26730592015-05-28 13:08:08193}
194
raymes76de1af2015-05-06 03:22:21195void OverlayUserPrefStore::ReportValueChanged(const std::string& key,
avi9ef8bb02015-12-24 05:29:36196 uint32_t flags) {
ericwilligers42b92c12016-10-24 20:21:13197 for (PrefStore::Observer& observer : observers_)
198 observer.OnPrefValueChanged(key);
[email protected]39565dd2011-11-14 12:09:27199}
200
Ramin Halavatif623bafe92018-07-17 12:12:58201void OverlayUserPrefStore::RegisterPersistentPref(const std::string& key) {
Johan Tibell6566c8ac2017-05-11 03:22:17202 DCHECK(!key.empty()) << "Key is empty";
Ramin Halavatif623bafe92018-07-17 12:12:58203 DCHECK(persistent_names_set_.find(key) == persistent_names_set_.end())
204 << "Key already registered: " << key;
205 persistent_names_set_.insert(key);
[email protected]39565dd2011-11-14 12:09:27206}
207
dvadym53fc0d42016-02-05 13:34:57208void OverlayUserPrefStore::ClearMutableValues() {
Ramin Halavatif623bafe92018-07-17 12:12:58209 for (const auto& key : written_ephemeral_names_) {
210 ephemeral_user_pref_store_->RemoveValue(
211 key, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
Johan Tibell0595f762017-05-25 23:54:50212 }
dvadym53fc0d42016-02-05 13:34:57213}
214
proberge45e347282017-08-16 21:24:05215void OverlayUserPrefStore::OnStoreDeletionFromDisk() {
Ramin Halavatif623bafe92018-07-17 12:12:58216 persistent_user_pref_store_->OnStoreDeletionFromDisk();
proberge45e347282017-08-16 21:24:05217}
218
[email protected]2dea5c02012-04-25 07:01:07219OverlayUserPrefStore::~OverlayUserPrefStore() {
Ramin Halavatif623bafe92018-07-17 12:12:58220 ephemeral_user_pref_store_->RemoveObserver(
221 ephemeral_pref_store_observer_.get());
222 persistent_user_pref_store_->RemoveObserver(
223 persistent_pref_store_observer_.get());
Johan Tibell0595f762017-05-25 23:54:50224}
225
Ramin Halavatif623bafe92018-07-17 12:12:58226void OverlayUserPrefStore::OnPrefValueChanged(bool ephemeral,
Johan Tibell0595f762017-05-25 23:54:50227 const std::string& key) {
Ramin Halavatif623bafe92018-07-17 12:12:58228 if (ephemeral) {
Johan Tibell0595f762017-05-25 23:54:50229 ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
230 } else {
Ramin Halavatif623bafe92018-07-17 12:12:58231 if (!ephemeral_user_pref_store_->GetValue(key, nullptr))
Johan Tibell0595f762017-05-25 23:54:50232 ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
233 }
234}
235
Ramin Halavatif623bafe92018-07-17 12:12:58236void OverlayUserPrefStore::OnInitializationCompleted(bool ephemeral,
Johan Tibell0595f762017-05-25 23:54:50237 bool succeeded) {
238 if (!IsInitializationComplete())
239 return;
240 for (PrefStore::Observer& observer : observers_)
241 observer.OnInitializationCompleted(succeeded);
[email protected]39565dd2011-11-14 12:09:27242}
243
Ramin Halavatif623bafe92018-07-17 12:12:58244bool OverlayUserPrefStore::ShallBeStoredInPersistent(
[email protected]39565dd2011-11-14 12:09:27245 const std::string& key) const {
Ramin Halavatif623bafe92018-07-17 12:12:58246 return persistent_names_set_.find(key) != persistent_names_set_.end();
[email protected]39565dd2011-11-14 12:09:27247}