Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "services/preferences/persistent_pref_store_impl.h" | 5 #include "services/preferences/persistent_pref_store_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #include "components/prefs/persistent_pref_store.h" | 13 #include "components/prefs/persistent_pref_store.h" |
| 14 #include "mojo/common/values_struct_traits.h" | 14 #include "mojo/common/values_struct_traits.h" |
| 15 #include "mojo/public/cpp/bindings/binding.h" | 15 #include "mojo/public/cpp/bindings/binding.h" |
| 16 #include "services/preferences/public/cpp/lib/util.h" | 16 #include "services/preferences/public/cpp/lib/util.h" |
| 17 | 17 |
| 18 namespace prefs { | 18 namespace prefs { |
| 19 | 19 |
| 20 class PersistentPrefStoreImpl::Connection : public mojom::PersistentPrefStore { | 20 class PersistentPrefStoreImpl::Connection { |
| 21 public: | 21 public: |
| 22 Connection(PersistentPrefStoreImpl* pref_store, | 22 Connection(PersistentPrefStoreImpl* pref_store, |
| 23 mojom::PersistentPrefStoreRequest request, | |
| 24 mojom::PrefStoreObserverPtr observer, | 23 mojom::PrefStoreObserverPtr observer, |
| 25 ObservedPrefs observed_keys) | 24 ObservedPrefs observed_keys) |
| 26 : pref_store_(pref_store), | 25 : pref_store_(pref_store), |
| 27 binding_(this, std::move(request)), | |
| 28 observer_(std::move(observer)), | 26 observer_(std::move(observer)), |
| 29 observed_keys_(std::move(observed_keys)) { | 27 observed_keys_(std::move(observed_keys)) { |
| 30 auto error_callback = | 28 observer_.set_connection_error_handler( |
| 31 base::Bind(&PersistentPrefStoreImpl::Connection::OnConnectionError, | 29 base::Bind(&PersistentPrefStoreImpl::Connection::OnConnectionError, |
| 32 base::Unretained(this)); | 30 base::Unretained(this))); |
| 33 binding_.set_connection_error_handler(error_callback); | |
| 34 observer_.set_connection_error_handler(error_callback); | |
| 35 } | 31 } |
| 36 | 32 |
| 37 ~Connection() override = default; | 33 virtual ~Connection() = default; |
| 38 | 34 |
| 39 void OnPrefValuesChanged(const std::vector<mojom::PrefUpdatePtr>& updates) { | 35 virtual void OnPrefsChanged( |
| 40 if (write_in_progress_) | 36 const std::vector<mojom::PrefUpdatePtr>& updates) { |
| 41 return; | |
| 42 | |
| 43 std::vector<mojom::PrefUpdatePtr> filtered_updates; | 37 std::vector<mojom::PrefUpdatePtr> filtered_updates; |
| 44 for (const auto& update : updates) { | 38 for (const auto& update : updates) { |
| 45 if (base::ContainsKey(observed_keys_, update->key)) { | 39 if (base::ContainsKey(observed_keys_, update->key)) { |
| 46 filtered_updates.push_back(update->Clone()); | 40 filtered_updates.push_back(update->Clone()); |
| 47 } | 41 } |
| 48 } | 42 } |
| 49 if (!filtered_updates.empty()) | 43 if (!filtered_updates.empty()) |
| 50 observer_->OnPrefsChanged(std::move(filtered_updates)); | 44 observer_->OnPrefsChanged(std::move(filtered_updates)); |
| 51 } | 45 } |
| 52 | 46 |
| 47 protected: | |
| 48 // Owns |this|. | |
| 49 PersistentPrefStoreImpl* const pref_store_; | |
| 50 | |
| 51 void OnConnectionError() { pref_store_->OnConnectionError(this); } | |
|
Sam McNally
2017/05/10 01:22:16
Methods before fields.
| |
| 52 | |
| 53 private: | |
| 54 mojom::PrefStoreObserverPtr observer_; | |
| 55 const ObservedPrefs observed_keys_; | |
| 56 | |
| 57 DISALLOW_COPY_AND_ASSIGN(Connection); | |
| 58 }; | |
| 59 | |
| 60 class PersistentPrefStoreImpl::WritableConnection | |
| 61 : public PersistentPrefStoreImpl::Connection, | |
| 62 public mojom::PersistentPrefStore { | |
| 63 public: | |
| 64 WritableConnection(PersistentPrefStoreImpl* pref_store, | |
| 65 mojom::PersistentPrefStoreRequest request, | |
| 66 mojom::PrefStoreObserverPtr observer, | |
| 67 ObservedPrefs observed_keys) | |
| 68 : Connection(pref_store, std::move(observer), std::move(observed_keys)), | |
| 69 binding_(this, std::move(request)) { | |
| 70 binding_.set_connection_error_handler(base::Bind( | |
| 71 &PersistentPrefStoreImpl::WritableConnection::OnConnectionError, | |
| 72 base::Unretained(this))); | |
| 73 } | |
| 74 | |
| 75 ~WritableConnection() override = default; | |
| 76 | |
| 77 void OnPrefsChanged( | |
| 78 const std::vector<mojom::PrefUpdatePtr>& updates) override { | |
| 79 if (write_in_progress_) | |
| 80 return; | |
| 81 Connection::OnPrefsChanged(updates); | |
| 82 } | |
| 83 | |
| 53 private: | 84 private: |
| 54 // mojom::PersistentPrefStore: | 85 // mojom::PersistentPrefStore: |
| 55 void SetValues(std::vector<mojom::PrefUpdatePtr> updates) override { | 86 void SetValues(std::vector<mojom::PrefUpdatePtr> updates) override { |
| 56 base::AutoReset<bool> scoped_call_in_progress(&write_in_progress_, true); | 87 base::AutoReset<bool> scoped_call_in_progress(&write_in_progress_, true); |
| 57 pref_store_->SetValues(std::move(updates)); | 88 pref_store_->SetValues(std::move(updates)); |
| 58 } | 89 } |
| 59 | 90 |
| 60 void CommitPendingWrite() override { pref_store_->CommitPendingWrite(); } | 91 void CommitPendingWrite() override { pref_store_->CommitPendingWrite(); } |
| 61 void SchedulePendingLossyWrites() override { | 92 void SchedulePendingLossyWrites() override { |
| 62 pref_store_->SchedulePendingLossyWrites(); | 93 pref_store_->SchedulePendingLossyWrites(); |
| 63 } | 94 } |
| 64 void ClearMutableValues() override { pref_store_->ClearMutableValues(); } | 95 void ClearMutableValues() override { pref_store_->ClearMutableValues(); } |
| 65 | 96 |
| 66 void OnConnectionError() { pref_store_->OnConnectionError(this); } | 97 // MSVC requires this as using a reference to the protected version in the |
| 67 | 98 // super class in base::Bind doesn't work. |
| 68 // Owns |this|. | 99 void OnConnectionError() { Connection::OnConnectionError(); } |
| 69 PersistentPrefStoreImpl* const pref_store_; | |
| 70 | 100 |
| 71 mojo::Binding<mojom::PersistentPrefStore> binding_; | 101 mojo::Binding<mojom::PersistentPrefStore> binding_; |
| 72 mojom::PrefStoreObserverPtr observer_; | |
| 73 const ObservedPrefs observed_keys_; | |
| 74 | 102 |
| 75 // If true then a write is in progress and any update notifications should be | 103 // If true then a write is in progress and any update notifications should be |
| 76 // ignored, as those updates would originate from ourselves. | 104 // ignored, as those updates would originate from ourselves. |
| 77 bool write_in_progress_ = false; | 105 bool write_in_progress_ = false; |
| 78 | 106 |
| 79 DISALLOW_COPY_AND_ASSIGN(Connection); | 107 DISALLOW_COPY_AND_ASSIGN(WritableConnection); |
| 80 }; | 108 }; |
| 81 | 109 |
| 82 PersistentPrefStoreImpl::PersistentPrefStoreImpl( | 110 PersistentPrefStoreImpl::PersistentPrefStoreImpl( |
| 83 scoped_refptr<PersistentPrefStore> backing_pref_store, | 111 scoped_refptr<PersistentPrefStore> backing_pref_store, |
| 84 base::OnceClosure on_initialized) | 112 base::OnceClosure on_initialized) |
| 85 : backing_pref_store_(backing_pref_store) { | 113 : backing_pref_store_(backing_pref_store) { |
| 86 if (!backing_pref_store_->IsInitializationComplete()) { | 114 if (!backing_pref_store_->IsInitializationComplete()) { |
| 87 backing_pref_store_->AddObserver(this); | 115 backing_pref_store_->AddObserver(this); |
| 88 on_initialized_ = std::move(on_initialized); | 116 on_initialized_ = std::move(on_initialized); |
| 89 initializing_ = true; | 117 initializing_ = true; |
| 90 backing_pref_store_->ReadPrefsAsync(nullptr); | 118 backing_pref_store_->ReadPrefsAsync(nullptr); |
| 91 } | 119 } |
| 92 } | 120 } |
| 93 | 121 |
| 94 PersistentPrefStoreImpl::~PersistentPrefStoreImpl() = default; | 122 PersistentPrefStoreImpl::~PersistentPrefStoreImpl() = default; |
| 95 | 123 |
| 96 mojom::PersistentPrefStoreConnectionPtr | 124 mojom::PersistentPrefStoreConnectionPtr |
| 97 PersistentPrefStoreImpl::CreateConnection(ObservedPrefs observed_prefs) { | 125 PersistentPrefStoreImpl::CreateConnection(ObservedPrefs observed_prefs) { |
| 98 DCHECK(!initializing_); | 126 DCHECK(!initializing_); |
| 99 if (!backing_pref_store_->IsInitializationComplete()) { | 127 if (!backing_pref_store_->IsInitializationComplete()) { |
| 100 // |backing_pref_store_| initialization failed. | 128 // |backing_pref_store_| initialization failed. |
| 101 return mojom::PersistentPrefStoreConnection::New( | 129 return mojom::PersistentPrefStoreConnection::New( |
| 102 nullptr, nullptr, backing_pref_store_->GetReadError(), | 130 nullptr, nullptr, backing_pref_store_->GetReadError(), |
| 103 backing_pref_store_->ReadOnly()); | 131 backing_pref_store_->ReadOnly()); |
| 104 } | 132 } |
| 105 mojom::PersistentPrefStorePtr pref_store_ptr; | 133 mojom::PersistentPrefStorePtr pref_store_ptr; |
| 106 mojom::PrefStoreObserverPtr observer; | 134 mojom::PrefStoreObserverPtr observer; |
| 107 mojom::PrefStoreObserverRequest observer_request = | 135 mojom::PrefStoreObserverRequest observer_request = |
| 108 mojo::MakeRequest(&observer); | 136 mojo::MakeRequest(&observer); |
| 109 auto connection = base::MakeUnique<Connection>( | 137 auto connection = base::MakeUnique<WritableConnection>( |
| 110 this, mojo::MakeRequest(&pref_store_ptr), std::move(observer), | 138 this, mojo::MakeRequest(&pref_store_ptr), std::move(observer), |
| 111 std::move(observed_prefs)); | 139 std::move(observed_prefs)); |
| 112 auto* connection_ptr = connection.get(); | 140 auto* connection_ptr = connection.get(); |
| 113 connections_.insert(std::make_pair(connection_ptr, std::move(connection))); | 141 connections_.insert(std::make_pair(connection_ptr, std::move(connection))); |
| 114 return mojom::PersistentPrefStoreConnection::New( | 142 return mojom::PersistentPrefStoreConnection::New( |
| 115 mojom::PrefStoreConnection::New(std::move(observer_request), | 143 mojom::PrefStoreConnection::New(std::move(observer_request), |
| 116 backing_pref_store_->GetValues(), true), | 144 backing_pref_store_->GetValues(), true), |
| 117 std::move(pref_store_ptr), backing_pref_store_->GetReadError(), | 145 std::move(pref_store_ptr), backing_pref_store_->GetReadError(), |
| 118 backing_pref_store_->ReadOnly()); | 146 backing_pref_store_->ReadOnly()); |
| 119 } | 147 } |
| 120 | 148 |
| 121 void PersistentPrefStoreImpl::OnPrefValueChanged(const std::string& key) {} | 149 void PersistentPrefStoreImpl::OnPrefValueChanged(const std::string& key) {} |
| 122 | 150 |
| 123 void PersistentPrefStoreImpl::OnInitializationCompleted(bool succeeded) { | 151 void PersistentPrefStoreImpl::OnInitializationCompleted(bool succeeded) { |
| 124 DCHECK(initializing_); | 152 DCHECK(initializing_); |
| 125 backing_pref_store_->RemoveObserver(this); | 153 backing_pref_store_->RemoveObserver(this); |
| 126 initializing_ = false; | 154 initializing_ = false; |
| 127 std::move(on_initialized_).Run(); | 155 std::move(on_initialized_).Run(); |
| 128 } | 156 } |
| 129 | 157 |
| 158 void PersistentPrefStoreImpl::AddObserver( | |
| 159 const std::vector<std::string>& prefs_to_observe, | |
| 160 const AddObserverCallback& callback) { | |
| 161 mojom::PrefStoreObserverPtr observer; | |
| 162 auto observer_request = mojo::MakeRequest(&observer); | |
| 163 auto connection = base::MakeUnique<Connection>( | |
| 164 this, std::move(observer), | |
| 165 ObservedPrefs(prefs_to_observe.begin(), prefs_to_observe.end())); | |
| 166 auto* connection_ptr = connection.get(); | |
| 167 connections_.insert(std::make_pair(connection_ptr, std::move(connection))); | |
| 168 callback.Run(mojom::PrefStoreConnection::New( | |
| 169 std::move(observer_request), backing_pref_store_->GetValues(), | |
| 170 backing_pref_store_->IsInitializationComplete())); | |
| 171 } | |
| 172 | |
| 130 void PersistentPrefStoreImpl::SetValues( | 173 void PersistentPrefStoreImpl::SetValues( |
| 131 std::vector<mojom::PrefUpdatePtr> updates) { | 174 std::vector<mojom::PrefUpdatePtr> updates) { |
| 132 for (auto& entry : connections_) | 175 for (auto& entry : connections_) |
| 133 entry.first->OnPrefValuesChanged(updates); | 176 entry.first->OnPrefsChanged(updates); |
| 134 | 177 |
| 135 for (auto& update : updates) { | 178 for (auto& update : updates) { |
| 136 if (update->value->is_atomic_update()) { | 179 if (update->value->is_atomic_update()) { |
| 137 auto& value = update->value->get_atomic_update(); | 180 auto& value = update->value->get_atomic_update(); |
| 138 if (value) { | 181 if (value) { |
| 139 backing_pref_store_->SetValue(update->key, std::move(value), | 182 backing_pref_store_->SetValue(update->key, std::move(value), |
| 140 update->flags); | 183 update->flags); |
| 141 } else { | 184 } else { |
| 142 backing_pref_store_->RemoveValue(update->key, update->flags); | 185 backing_pref_store_->RemoveValue(update->key, update->flags); |
| 143 } | 186 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 | 224 |
| 182 void PersistentPrefStoreImpl::ClearMutableValues() { | 225 void PersistentPrefStoreImpl::ClearMutableValues() { |
| 183 backing_pref_store_->ClearMutableValues(); | 226 backing_pref_store_->ClearMutableValues(); |
| 184 } | 227 } |
| 185 | 228 |
| 186 void PersistentPrefStoreImpl::OnConnectionError(Connection* connection) { | 229 void PersistentPrefStoreImpl::OnConnectionError(Connection* connection) { |
| 187 connections_.erase(connection); | 230 connections_.erase(connection); |
| 188 } | 231 } |
| 189 | 232 |
| 190 } // namespace prefs | 233 } // namespace prefs |
| OLD | NEW |