Generalize OverlayUserPrefStore
Allows the overlay to be any PersistentPrefStore, thereby allowing us to
use a PersistentPrefStoreClient to connect to a remote in-memory pref
store in the Mojo pref service instead of using a local one.
Bug: 719770
Change-Id: I992c416503ab6f115cbf3d98d658bc0911c4c0c7
Reviewed-on: https://chromium-review.googlesource.com/514842
Reviewed-by: Sam McNally <[email protected]>
Reviewed-by: Bernhard Bauer <[email protected]>
Commit-Queue: Johan Tibell <[email protected]>
Cr-Commit-Position: refs/heads/master@{#474906}
diff --git a/components/prefs/overlay_user_pref_store.cc b/components/prefs/overlay_user_pref_store.cc
index 48271fb..a4d21cd 100644
--- a/components/prefs/overlay_user_pref_store.cc
+++ b/components/prefs/overlay_user_pref_store.cc
@@ -9,15 +9,48 @@
#include "base/memory/ptr_util.h"
#include "base/values.h"
+#include "components/prefs/in_memory_pref_store.h"
-OverlayUserPrefStore::OverlayUserPrefStore(
- PersistentPrefStore* underlay)
- : underlay_(underlay) {
- underlay_->AddObserver(this);
+// Allows us to monitor two pref stores and tell updates from them apart. It
+// essentially mimics a Callback for the Observer interface (e.g. it allows
+// binding additional arguments).
+class OverlayUserPrefStore::ObserverAdapter : public PrefStore::Observer {
+ public:
+ ObserverAdapter(bool overlay, OverlayUserPrefStore* parent)
+ : overlay_(overlay), parent_(parent) {}
+
+ // Methods of PrefStore::Observer.
+ void OnPrefValueChanged(const std::string& key) override {
+ parent_->OnPrefValueChanged(overlay_, key);
+ }
+ void OnInitializationCompleted(bool succeeded) override {
+ parent_->OnInitializationCompleted(overlay_, succeeded);
+ }
+
+ private:
+ // Is the update for the overlay?
+ const bool overlay_;
+ OverlayUserPrefStore* const parent_;
+};
+
+OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* underlay)
+ : OverlayUserPrefStore(new InMemoryPrefStore(), underlay) {}
+
+OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* overlay,
+ PersistentPrefStore* underlay)
+ : overlay_observer_(
+ base::MakeUnique<OverlayUserPrefStore::ObserverAdapter>(true, this)),
+ underlay_observer_(
+ base::MakeUnique<OverlayUserPrefStore::ObserverAdapter>(false, this)),
+ overlay_(overlay),
+ underlay_(underlay) {
+ DCHECK(overlay->IsInitializationComplete());
+ overlay_->AddObserver(overlay_observer_.get());
+ underlay_->AddObserver(underlay_observer_.get());
}
bool OverlayUserPrefStore::IsSetInOverlay(const std::string& key) const {
- return overlay_.GetValue(key, NULL);
+ return overlay_->GetValue(key, NULL);
}
void OverlayUserPrefStore::AddObserver(PrefStore::Observer* observer) {
@@ -33,23 +66,24 @@
}
bool OverlayUserPrefStore::IsInitializationComplete() const {
- return underlay_->IsInitializationComplete();
+ return underlay_->IsInitializationComplete() &&
+ overlay_->IsInitializationComplete();
}
bool OverlayUserPrefStore::GetValue(const std::string& key,
const base::Value** result) const {
// If the |key| shall NOT be stored in the overlay store, there must not
// be an entry.
- DCHECK(ShallBeStoredInOverlay(key) || !overlay_.GetValue(key, NULL));
+ DCHECK(ShallBeStoredInOverlay(key) || !overlay_->GetValue(key, NULL));
- if (overlay_.GetValue(key, result))
+ if (overlay_->GetValue(key, result))
return true;
return underlay_->GetValue(key, result);
}
std::unique_ptr<base::DictionaryValue> OverlayUserPrefStore::GetValues() const {
auto values = underlay_->GetValues();
- auto overlay_values = overlay_.AsDictionaryValue();
+ auto overlay_values = overlay_->GetValues();
for (const auto& key : overlay_names_set_) {
std::unique_ptr<base::Value> out_value;
overlay_values->Remove(key, &out_value);
@@ -65,7 +99,8 @@
if (!ShallBeStoredInOverlay(key))
return underlay_->GetMutableValue(key, result);
- if (overlay_.GetValue(key, result))
+ written_overlay_names_.insert(key);
+ if (overlay_->GetMutableValue(key, result))
return true;
// Try to create copy of underlay if the overlay does not contain a value.
@@ -74,7 +109,8 @@
return false;
*result = underlay_value->DeepCopy();
- overlay_.SetValue(key, base::WrapUnique(*result));
+ overlay_->SetValue(key, base::WrapUnique(*result),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
return true;
}
@@ -86,8 +122,8 @@
return;
}
- if (overlay_.SetValue(key, std::move(value)))
- ReportValueChanged(key, flags);
+ written_overlay_names_.insert(key);
+ overlay_->SetValue(key, std::move(value), flags);
}
void OverlayUserPrefStore::SetValueSilently(const std::string& key,
@@ -98,7 +134,8 @@
return;
}
- overlay_.SetValue(key, std::move(value));
+ written_overlay_names_.insert(key);
+ overlay_->SetValueSilently(key, std::move(value), flags);
}
void OverlayUserPrefStore::RemoveValue(const std::string& key, uint32_t flags) {
@@ -107,8 +144,8 @@
return;
}
- if (overlay_.RemoveValue(key))
- ReportValueChanged(key, flags);
+ written_overlay_names_.insert(key);
+ overlay_->RemoveValue(key, flags);
}
bool OverlayUserPrefStore::ReadOnly() const {
@@ -121,7 +158,7 @@
PersistentPrefStore::PrefReadError OverlayUserPrefStore::ReadPrefs() {
// We do not read intentionally.
- OnInitializationCompleted(true);
+ OnInitializationCompleted(/* overlay */ false, true);
return PersistentPrefStore::PREF_READ_ERROR_NONE;
}
@@ -129,7 +166,7 @@
ReadErrorDelegate* error_delegate_raw) {
std::unique_ptr<ReadErrorDelegate> error_delegate(error_delegate_raw);
// We do not read intentionally.
- OnInitializationCompleted(true);
+ OnInitializationCompleted(/* overlay */ false, true);
}
void OverlayUserPrefStore::CommitPendingWrite() {
@@ -147,16 +184,6 @@
observer.OnPrefValueChanged(key);
}
-void OverlayUserPrefStore::OnPrefValueChanged(const std::string& key) {
- if (!overlay_.GetValue(key, NULL))
- ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
-}
-
-void OverlayUserPrefStore::OnInitializationCompleted(bool succeeded) {
- for (PrefStore::Observer& observer : observers_)
- observer.OnInitializationCompleted(succeeded);
-}
-
void OverlayUserPrefStore::RegisterOverlayPref(const std::string& key) {
DCHECK(!key.empty()) << "Key is empty";
DCHECK(overlay_names_set_.find(key) == overlay_names_set_.end())
@@ -165,11 +192,32 @@
}
void OverlayUserPrefStore::ClearMutableValues() {
- overlay_.Clear();
+ for (const auto& key : written_overlay_names_) {
+ overlay_->RemoveValue(key, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ }
}
OverlayUserPrefStore::~OverlayUserPrefStore() {
- underlay_->RemoveObserver(this);
+ overlay_->RemoveObserver(overlay_observer_.get());
+ underlay_->RemoveObserver(underlay_observer_.get());
+}
+
+void OverlayUserPrefStore::OnPrefValueChanged(bool overlay,
+ const std::string& key) {
+ if (overlay) {
+ ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
+ } else {
+ if (!overlay_->GetValue(key, NULL))
+ ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
+ }
+}
+
+void OverlayUserPrefStore::OnInitializationCompleted(bool overlay,
+ bool succeeded) {
+ if (!IsInitializationComplete())
+ return;
+ for (PrefStore::Observer& observer : observers_)
+ observer.OnInitializationCompleted(succeeded);
}
bool OverlayUserPrefStore::ShallBeStoredInOverlay(