Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Unified Diff: services/preferences/public/cpp/scoped_pref_update.cc

Issue 2812863002: Pref service: Add a ScopedDictionaryPrefUpdate to track value changes. (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: services/preferences/public/cpp/scoped_pref_update.cc
diff --git a/services/preferences/public/cpp/scoped_pref_update.cc b/services/preferences/public/cpp/scoped_pref_update.cc
new file mode 100644
index 0000000000000000000000000000000000000000..433ecd8724e0f9afca822c2e958c4c00b8592bbc
--- /dev/null
+++ b/services/preferences/public/cpp/scoped_pref_update.cc
@@ -0,0 +1,385 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/preferences/public/cpp/scoped_pref_update.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_split.h"
+#include "components/prefs/pref_service.h"
+
+namespace prefs {
+
+ScopedDictionaryPrefUpdate::ScopedDictionaryPrefUpdate(PrefService* service,
+ base::StringPiece path)
+ : service_(service), path_(path.as_string()) {
+ base::DictionaryValue* value = static_cast<base::DictionaryValue*>(
+ service_->GetMutableUserPref(path_, base::Value::Type::DICTIONARY));
+ value_ = Insert(base::WrapUnique(
+ new DictionaryValueUpdate(this, value, std::vector<std::string>())));
+}
+
+ScopedDictionaryPrefUpdate::~ScopedDictionaryPrefUpdate() {
+ if (value_)
+ Notify();
+}
+
+DictionaryValueUpdate* ScopedDictionaryPrefUpdate::Get() {
+ return value_;
+}
+
+DictionaryValueUpdate* ScopedDictionaryPrefUpdate::operator->() {
+ return Get();
+}
+
+void ScopedDictionaryPrefUpdate::Notify() {
+ DCHECK(value_);
+ if (!updated_paths_.empty())
+ service_->ReportUserPrefChanged(path_, std::move(updated_paths_));
+ value_ = nullptr;
+ updates_.clear();
+}
+
+void ScopedDictionaryPrefUpdate::RecordPath(
+ const std::vector<std::string>& path) {
+ updated_paths_.insert(std::move(path));
+}
+
+DictionaryValueUpdate* ScopedDictionaryPrefUpdate::Insert(
+ std::unique_ptr<DictionaryValueUpdate> dictionary_value_update) {
+ updates_.push_back(std::move(dictionary_value_update));
+ return updates_.back().get();
+}
+
+DictionaryValueUpdate::DictionaryValueUpdate(ScopedDictionaryPrefUpdate* update,
+ base::DictionaryValue* value,
+ std::vector<std::string> path)
+ : update_(update), value_(value), path_(std::move(path)) {}
+
+DictionaryValueUpdate::~DictionaryValueUpdate() = default;
+
+bool DictionaryValueUpdate::HasKey(base::StringPiece key) const {
+ return value_->HasKey(key);
+}
+
+size_t DictionaryValueUpdate::size() const {
+ return value_->size();
+}
+
+bool DictionaryValueUpdate::empty() const {
+ return value_->empty();
+}
+
+void DictionaryValueUpdate::Clear() {
+ if (empty())
+ return;
+
+ RecordSplitPath(std::vector<base::StringPiece>());
+ value_->Clear();
+}
+
+void DictionaryValueUpdate::Set(base::StringPiece path,
+ std::unique_ptr<base::Value> in_value) {
+ const base::Value* old_value = nullptr;
+ if (value_->Get(path, &old_value) && *old_value == *in_value)
+ return;
+
+ RecordPath(path);
+ value_->Set(path, std::move(in_value));
+}
+
+void DictionaryValueUpdate::SetBoolean(base::StringPiece path, bool in_value) {
+ Set(path, base::MakeUnique<base::Value>(in_value));
+}
+
+void DictionaryValueUpdate::SetInteger(base::StringPiece path, int in_value) {
+ Set(path, base::MakeUnique<base::Value>(in_value));
+}
+
+void DictionaryValueUpdate::SetDouble(base::StringPiece path, double in_value) {
+ Set(path, base::MakeUnique<base::Value>(in_value));
+}
+
+void DictionaryValueUpdate::SetString(base::StringPiece path,
+ base::StringPiece in_value) {
+ Set(path, base::MakeUnique<base::Value>(in_value));
+}
+
+void DictionaryValueUpdate::SetString(base::StringPiece path,
+ const base::string16& in_value) {
+ Set(path, base::MakeUnique<base::Value>(in_value));
+}
+
+DictionaryValueUpdate* DictionaryValueUpdate::SetDictionary(
+ base::StringPiece path,
+ std::unique_ptr<base::DictionaryValue> in_value) {
+ RecordPath(path);
+ base::DictionaryValue* dictionary_value = in_value.get();
+ value_->Set(path, std::move(in_value));
+
+ return update_->Insert(base::WrapUnique(new DictionaryValueUpdate(
+ update_, dictionary_value, ConcatPath(path_, path))));
+}
+
+void DictionaryValueUpdate::SetWithoutPathExpansion(
+ base::StringPiece key,
+ std::unique_ptr<base::Value> in_value) {
+ const base::Value* old_value = nullptr;
+ if (value_->GetWithoutPathExpansion(key, &old_value) &&
+ *old_value == *in_value) {
+ return;
+ }
+ RecordKey(key);
+ value_->SetWithoutPathExpansion(key, std::move(in_value));
+}
+
+void DictionaryValueUpdate::SetBooleanWithoutPathExpansion(
+ base::StringPiece path,
+ bool in_value) {
+ SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
+}
+
+void DictionaryValueUpdate::SetIntegerWithoutPathExpansion(
+ base::StringPiece path,
+ int in_value) {
+ SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
+}
+
+void DictionaryValueUpdate::SetDoubleWithoutPathExpansion(
+ base::StringPiece path,
+ double in_value) {
+ SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
+}
+
+void DictionaryValueUpdate::SetStringWithoutPathExpansion(
+ base::StringPiece path,
+ base::StringPiece in_value) {
+ SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
+}
+
+void DictionaryValueUpdate::SetStringWithoutPathExpansion(
+ base::StringPiece path,
+ const base::string16& in_value) {
+ SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
+}
+
+DictionaryValueUpdate* DictionaryValueUpdate::SetDictionaryWithoutPathExpansion(
+ base::StringPiece path,
+ std::unique_ptr<base::DictionaryValue> in_value) {
+ RecordKey(path);
+ base::DictionaryValue* dictionary_value = in_value.get();
+ value_->SetWithoutPathExpansion(path, std::move(in_value));
+
+ std::vector<std::string> full_path = path_;
+ full_path.push_back(path.as_string());
+ return update_->Insert(base::WrapUnique(new DictionaryValueUpdate(
+ update_, dictionary_value, std::move(full_path))));
+}
+
+bool DictionaryValueUpdate::GetBoolean(base::StringPiece path,
+ bool* out_value) const {
+ return value_->GetBoolean(path, out_value);
+}
+
+bool DictionaryValueUpdate::GetInteger(base::StringPiece path,
+ int* out_value) const {
+ return value_->GetInteger(path, out_value);
+}
+
+bool DictionaryValueUpdate::GetDouble(base::StringPiece path,
+ double* out_value) const {
+ return value_->GetDouble(path, out_value);
+}
+
+bool DictionaryValueUpdate::GetString(base::StringPiece path,
+ std::string* out_value) const {
+ return value_->GetString(path, out_value);
+}
+
+bool DictionaryValueUpdate::GetString(base::StringPiece path,
+ base::string16* out_value) const {
+ return value_->GetString(path, out_value);
+}
+
+bool DictionaryValueUpdate::GetBinary(base::StringPiece path,
+ const base::Value** out_value) const {
+ return AsConstDictionary()->GetBinary(path, out_value);
+}
+
+bool DictionaryValueUpdate::GetDictionary(
+ base::StringPiece path,
+ const base::DictionaryValue** out_value) const {
+ return AsConstDictionary()->GetDictionary(path, out_value);
+}
+
+bool DictionaryValueUpdate::GetDictionary(base::StringPiece path,
+ DictionaryValueUpdate** out_value) {
+ base::DictionaryValue* dictionary_value = nullptr;
+ if (!value_->GetDictionary(path, &dictionary_value))
+ return false;
+
+ *out_value = update_->Insert(base::WrapUnique(new DictionaryValueUpdate(
+ update_, dictionary_value, ConcatPath(path_, path))));
+ return true;
+}
+
+bool DictionaryValueUpdate::GetList(base::StringPiece path,
+ const base::ListValue** out_value) const {
+ return AsConstDictionary()->GetList(path, out_value);
+}
+
+bool DictionaryValueUpdate::GetList(base::StringPiece path,
+ base::ListValue** out_value) {
+ RecordPath(path);
+ return value_->GetList(path, out_value);
+}
+
+bool DictionaryValueUpdate::GetBooleanWithoutPathExpansion(
+ base::StringPiece key,
+ bool* out_value) const {
+ return value_->GetBooleanWithoutPathExpansion(key, out_value);
+}
+
+bool DictionaryValueUpdate::GetIntegerWithoutPathExpansion(
+ base::StringPiece key,
+ int* out_value) const {
+ return value_->GetIntegerWithoutPathExpansion(key, out_value);
+}
+
+bool DictionaryValueUpdate::GetDoubleWithoutPathExpansion(
+ base::StringPiece key,
+ double* out_value) const {
+ return value_->GetDoubleWithoutPathExpansion(key, out_value);
+}
+
+bool DictionaryValueUpdate::GetStringWithoutPathExpansion(
+ base::StringPiece key,
+ std::string* out_value) const {
+ return value_->GetStringWithoutPathExpansion(key, out_value);
+}
+
+bool DictionaryValueUpdate::GetStringWithoutPathExpansion(
+ base::StringPiece key,
+ base::string16* out_value) const {
+ return value_->GetStringWithoutPathExpansion(key, out_value);
+}
+
+bool DictionaryValueUpdate::GetDictionaryWithoutPathExpansion(
+ base::StringPiece key,
+ const base::DictionaryValue** out_value) const {
+ return value_->GetDictionaryWithoutPathExpansion(key, out_value);
+}
+
+bool DictionaryValueUpdate::GetDictionaryWithoutPathExpansion(
+ base::StringPiece key,
+ DictionaryValueUpdate** out_value) {
+ base::DictionaryValue* dictionary_value = nullptr;
+ if (!value_->GetDictionary(key, &dictionary_value))
+ return false;
+
+ std::vector<std::string> full_path = path_;
+ full_path.push_back(key.as_string());
+ *out_value = update_->Insert(base::WrapUnique(new DictionaryValueUpdate(
+ update_, dictionary_value, std::move(full_path))));
+ return true;
+}
+
+bool DictionaryValueUpdate::GetListWithoutPathExpansion(
+ base::StringPiece key,
+ const base::ListValue** out_value) const {
+ return value_->GetListWithoutPathExpansion(key, out_value);
+}
+
+bool DictionaryValueUpdate::GetListWithoutPathExpansion(
+ base::StringPiece key,
+ base::ListValue** out_value) {
+ RecordKey(key);
+ return value_->GetListWithoutPathExpansion(key, out_value);
+}
+
+bool DictionaryValueUpdate::Remove(base::StringPiece path,
+ std::unique_ptr<base::Value>* out_value) {
+ if (!value_->Remove(path, out_value))
+ return false;
+
+ RecordPath(path);
+ return true;
+}
+
+bool DictionaryValueUpdate::RemoveWithoutPathExpansion(
+ base::StringPiece key,
+ std::unique_ptr<base::Value>* out_value) {
+ if (!value_->RemoveWithoutPathExpansion(key, out_value))
+ return false;
+
+ RecordKey(key);
+ return true;
+}
+
+bool DictionaryValueUpdate::RemovePath(
+ base::StringPiece path,
+ std::unique_ptr<base::Value>* out_value) {
+ if (!value_->RemovePath(path, out_value))
+ return false;
+
+ std::vector<base::StringPiece> split_path = SplitPath(path);
+ base::DictionaryValue* dict = value_;
+ for (size_t i = 0; i < split_path.size() - 1; ++i) {
+ if (!dict->GetDictionary(split_path[i], &dict)) {
+ split_path.resize(i + 1);
+ RecordSplitPath(split_path);
+ return true;
+ }
+ }
+ RecordPath(path);
+ return true;
+}
+
+base::DictionaryValue* DictionaryValueUpdate::AsDictionary() {
+ RecordSplitPath(std::vector<base::StringPiece>());
+ return value_;
+}
+
+const base::DictionaryValue* DictionaryValueUpdate::AsConstDictionary() const {
+ return value_;
+}
+
+void DictionaryValueUpdate::RecordKey(base::StringPiece key) {
+ RecordSplitPath({key});
+}
+
+void DictionaryValueUpdate::RecordPath(base::StringPiece path) {
+ RecordSplitPath(SplitPath(path));
+}
+
+void DictionaryValueUpdate::RecordSplitPath(
+ const std::vector<base::StringPiece>& path) {
+ update_->RecordPath(ConcatPath(path_, path));
+}
+
+std::vector<base::StringPiece> DictionaryValueUpdate::SplitPath(
+ base::StringPiece path) {
+ return base::SplitStringPiece(path, ".", base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY);
+}
+
+std::vector<std::string> DictionaryValueUpdate::ConcatPath(
+ const std::vector<std::string>& base_path,
+ base::StringPiece path) {
+ return ConcatPath(base_path, SplitPath(path));
+}
+
+std::vector<std::string> DictionaryValueUpdate::ConcatPath(
+ const std::vector<std::string>& base_path,
+ const std::vector<base::StringPiece>& path) {
+ std::vector<std::string> full_path = base_path;
+ full_path.reserve(full_path.size() + path.size());
+ std::transform(path.begin(), path.end(), std::back_inserter(full_path),
+ [](base::StringPiece s) { return s.as_string(); });
+ return full_path;
+}
+
+} // namespace prefs
« no previous file with comments | « services/preferences/public/cpp/scoped_pref_update.h ('k') | services/preferences/public/cpp/tests/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698