| 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" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 observed_keys_(std::move(observed_keys)) { | 27 observed_keys_(std::move(observed_keys)) { |
| 28 auto error_callback = | 28 auto error_callback = |
| 29 base::Bind(&PersistentPrefStoreImpl::Connection::OnConnectionError, | 29 base::Bind(&PersistentPrefStoreImpl::Connection::OnConnectionError, |
| 30 base::Unretained(this)); | 30 base::Unretained(this)); |
| 31 binding_.set_connection_error_handler(error_callback); | 31 binding_.set_connection_error_handler(error_callback); |
| 32 observer_.set_connection_error_handler(error_callback); | 32 observer_.set_connection_error_handler(error_callback); |
| 33 } | 33 } |
| 34 | 34 |
| 35 ~Connection() override = default; | 35 ~Connection() override = default; |
| 36 | 36 |
| 37 void OnPrefValueChanged(const std::string& key, const base::Value* value) { | 37 void OnPrefValuesChanged(const std::vector<mojom::PrefUpdatePtr>& updates) { |
| 38 if (write_in_progress_ || !base::ContainsKey(observed_keys_, key)) | 38 if (write_in_progress_) |
| 39 return; | 39 return; |
| 40 | 40 |
| 41 observer_->OnPrefChanged(key, value ? value->CreateDeepCopy() : nullptr); | 41 std::vector<mojom::PrefUpdatePtr> filtered_updates; |
| 42 for (const auto& update : updates) { |
| 43 if (base::ContainsKey(observed_keys_, update->key)) { |
| 44 filtered_updates.push_back(mojom::PrefUpdate::New( |
| 45 update->key, |
| 46 update->value ? update->value->CreateDeepCopy() : nullptr, 0)); |
| 47 } |
| 48 } |
| 49 if (!filtered_updates.empty()) |
| 50 observer_->OnPrefsChanged(std::move(filtered_updates)); |
| 42 } | 51 } |
| 43 | 52 |
| 44 private: | 53 private: |
| 45 // mojom::PersistentPrefStore: | 54 // mojom::PersistentPrefStore: |
| 46 void SetValue(const std::string& key, | 55 void SetValues(std::vector<mojom::PrefUpdatePtr> updates) override { |
| 47 std::unique_ptr<base::Value> value, | |
| 48 uint32_t flags) override { | |
| 49 base::AutoReset<bool> scoped_call_in_progress(&write_in_progress_, true); | 56 base::AutoReset<bool> scoped_call_in_progress(&write_in_progress_, true); |
| 50 pref_store_->SetValue(key, std::move(value), flags); | 57 pref_store_->SetValues(std::move(updates)); |
| 51 } | 58 } |
| 52 | 59 |
| 53 void CommitPendingWrite() override { pref_store_->CommitPendingWrite(); } | 60 void CommitPendingWrite() override { pref_store_->CommitPendingWrite(); } |
| 54 void SchedulePendingLossyWrites() override { | 61 void SchedulePendingLossyWrites() override { |
| 55 pref_store_->SchedulePendingLossyWrites(); | 62 pref_store_->SchedulePendingLossyWrites(); |
| 56 } | 63 } |
| 57 void ClearMutableValues() override { pref_store_->ClearMutableValues(); } | 64 void ClearMutableValues() override { pref_store_->ClearMutableValues(); } |
| 58 | 65 |
| 59 void OnConnectionError() { pref_store_->OnConnectionError(this); } | 66 void OnConnectionError() { pref_store_->OnConnectionError(this); } |
| 60 | 67 |
| 61 // Owns |this|. | 68 // Owns |this|. |
| 62 PersistentPrefStoreImpl* const pref_store_; | 69 PersistentPrefStoreImpl* const pref_store_; |
| 63 | 70 |
| 64 mojo::Binding<mojom::PersistentPrefStore> binding_; | 71 mojo::Binding<mojom::PersistentPrefStore> binding_; |
| 65 mojom::PrefStoreObserverPtr observer_; | 72 mojom::PrefStoreObserverPtr observer_; |
| 66 const ObservedPrefs observed_keys_; | 73 const ObservedPrefs observed_keys_; |
| 67 | 74 |
| 68 // If true then a write is in progress and any update notifications should be | 75 // If true then a write is in progress and any update notifications should be |
| 69 // ignored, as those updates would originate from ourselves. | 76 // ignored, as those updates would originate from ourselves. |
| 70 bool write_in_progress_ = false; | 77 bool write_in_progress_ = false; |
| 71 | 78 |
| 72 DISALLOW_COPY_AND_ASSIGN(Connection); | 79 DISALLOW_COPY_AND_ASSIGN(Connection); |
| 73 }; | 80 }; |
| 74 | 81 |
| 75 PersistentPrefStoreImpl::PersistentPrefStoreImpl( | 82 PersistentPrefStoreImpl::PersistentPrefStoreImpl( |
| 76 scoped_refptr<PersistentPrefStore> backing_pref_store, | 83 scoped_refptr<PersistentPrefStore> backing_pref_store, |
| 77 base::OnceClosure on_initialized) | 84 base::OnceClosure on_initialized) |
| 78 : backing_pref_store_(backing_pref_store) { | 85 : backing_pref_store_(backing_pref_store) { |
| 79 backing_pref_store_->AddObserver(this); | |
| 80 if (!backing_pref_store_->IsInitializationComplete()) { | 86 if (!backing_pref_store_->IsInitializationComplete()) { |
| 87 backing_pref_store_->AddObserver(this); |
| 81 on_initialized_ = std::move(on_initialized); | 88 on_initialized_ = std::move(on_initialized); |
| 82 initializing_ = true; | 89 initializing_ = true; |
| 83 backing_pref_store_->ReadPrefsAsync(nullptr); | 90 backing_pref_store_->ReadPrefsAsync(nullptr); |
| 84 } | 91 } |
| 85 } | 92 } |
| 86 | 93 |
| 87 PersistentPrefStoreImpl::~PersistentPrefStoreImpl() { | 94 PersistentPrefStoreImpl::~PersistentPrefStoreImpl() = default; |
| 88 backing_pref_store_->RemoveObserver(this); | |
| 89 } | |
| 90 | 95 |
| 91 mojom::PersistentPrefStoreConnectionPtr | 96 mojom::PersistentPrefStoreConnectionPtr |
| 92 PersistentPrefStoreImpl::CreateConnection(ObservedPrefs observed_prefs) { | 97 PersistentPrefStoreImpl::CreateConnection(ObservedPrefs observed_prefs) { |
| 93 DCHECK(!initializing_); | 98 DCHECK(!initializing_); |
| 94 if (!backing_pref_store_->IsInitializationComplete()) { | 99 if (!backing_pref_store_->IsInitializationComplete()) { |
| 95 // |backing_pref_store_| initialization failed. | 100 // |backing_pref_store_| initialization failed. |
| 96 return mojom::PersistentPrefStoreConnection::New( | 101 return mojom::PersistentPrefStoreConnection::New( |
| 97 nullptr, nullptr, backing_pref_store_->GetReadError(), | 102 nullptr, nullptr, backing_pref_store_->GetReadError(), |
| 98 backing_pref_store_->ReadOnly()); | 103 backing_pref_store_->ReadOnly()); |
| 99 } | 104 } |
| 100 mojom::PersistentPrefStorePtr pref_store_ptr; | 105 mojom::PersistentPrefStorePtr pref_store_ptr; |
| 101 mojom::PrefStoreObserverPtr observer; | 106 mojom::PrefStoreObserverPtr observer; |
| 102 mojom::PrefStoreObserverRequest observer_request = | 107 mojom::PrefStoreObserverRequest observer_request = |
| 103 mojo::MakeRequest(&observer); | 108 mojo::MakeRequest(&observer); |
| 104 auto connection = base::MakeUnique<Connection>( | 109 auto connection = base::MakeUnique<Connection>( |
| 105 this, mojo::MakeRequest(&pref_store_ptr), std::move(observer), | 110 this, mojo::MakeRequest(&pref_store_ptr), std::move(observer), |
| 106 std::move(observed_prefs)); | 111 std::move(observed_prefs)); |
| 107 auto* connection_ptr = connection.get(); | 112 auto* connection_ptr = connection.get(); |
| 108 connections_.insert(std::make_pair(connection_ptr, std::move(connection))); | 113 connections_.insert(std::make_pair(connection_ptr, std::move(connection))); |
| 109 return mojom::PersistentPrefStoreConnection::New( | 114 return mojom::PersistentPrefStoreConnection::New( |
| 110 mojom::PrefStoreConnection::New(std::move(observer_request), | 115 mojom::PrefStoreConnection::New(std::move(observer_request), |
| 111 backing_pref_store_->GetValues(), true), | 116 backing_pref_store_->GetValues(), true), |
| 112 std::move(pref_store_ptr), backing_pref_store_->GetReadError(), | 117 std::move(pref_store_ptr), backing_pref_store_->GetReadError(), |
| 113 backing_pref_store_->ReadOnly()); | 118 backing_pref_store_->ReadOnly()); |
| 114 } | 119 } |
| 115 | 120 |
| 116 void PersistentPrefStoreImpl::OnPrefValueChanged(const std::string& key) { | 121 void PersistentPrefStoreImpl::OnPrefValueChanged(const std::string& key) {} |
| 117 // All mutations are triggered by a client. Updates are only sent to clients | |
| 118 // other than the instigator so if there is only one client, it will ignore | |
| 119 // the update. | |
| 120 if (connections_.size() == 1) | |
| 121 return; | |
| 122 | |
| 123 const base::Value* value = nullptr; | |
| 124 backing_pref_store_->GetValue(key, &value); | |
| 125 for (auto& entry : connections_) | |
| 126 entry.first->OnPrefValueChanged(key, value); | |
| 127 } | |
| 128 | 122 |
| 129 void PersistentPrefStoreImpl::OnInitializationCompleted(bool succeeded) { | 123 void PersistentPrefStoreImpl::OnInitializationCompleted(bool succeeded) { |
| 130 DCHECK(initializing_); | 124 DCHECK(initializing_); |
| 125 backing_pref_store_->RemoveObserver(this); |
| 131 initializing_ = false; | 126 initializing_ = false; |
| 132 std::move(on_initialized_).Run(); | 127 std::move(on_initialized_).Run(); |
| 133 } | 128 } |
| 134 | 129 |
| 135 void PersistentPrefStoreImpl::SetValue(const std::string& key, | 130 void PersistentPrefStoreImpl::SetValues( |
| 136 std::unique_ptr<base::Value> value, | 131 std::vector<mojom::PrefUpdatePtr> updates) { |
| 137 uint32_t flags) { | 132 for (auto& entry : connections_) |
| 138 if (value) | 133 entry.first->OnPrefValuesChanged(updates); |
| 139 backing_pref_store_->SetValue(key, std::move(value), flags); | 134 |
| 140 else | 135 for (auto& update : updates) { |
| 141 backing_pref_store_->RemoveValue(key, flags); | 136 if (update->value) { |
| 137 backing_pref_store_->SetValue(update->key, std::move(update->value), |
| 138 update->flags); |
| 139 } else { |
| 140 backing_pref_store_->RemoveValue(update->key, update->flags); |
| 141 } |
| 142 } |
| 142 } | 143 } |
| 143 | 144 |
| 144 void PersistentPrefStoreImpl::CommitPendingWrite() { | 145 void PersistentPrefStoreImpl::CommitPendingWrite() { |
| 145 backing_pref_store_->CommitPendingWrite(); | 146 backing_pref_store_->CommitPendingWrite(); |
| 146 } | 147 } |
| 147 | 148 |
| 148 void PersistentPrefStoreImpl::SchedulePendingLossyWrites() { | 149 void PersistentPrefStoreImpl::SchedulePendingLossyWrites() { |
| 149 backing_pref_store_->SchedulePendingLossyWrites(); | 150 backing_pref_store_->SchedulePendingLossyWrites(); |
| 150 } | 151 } |
| 151 | 152 |
| 152 void PersistentPrefStoreImpl::ClearMutableValues() { | 153 void PersistentPrefStoreImpl::ClearMutableValues() { |
| 153 backing_pref_store_->ClearMutableValues(); | 154 backing_pref_store_->ClearMutableValues(); |
| 154 } | 155 } |
| 155 | 156 |
| 156 void PersistentPrefStoreImpl::OnConnectionError(Connection* connection) { | 157 void PersistentPrefStoreImpl::OnConnectionError(Connection* connection) { |
| 157 connections_.erase(connection); | 158 connections_.erase(connection); |
| 158 } | 159 } |
| 159 | 160 |
| 160 } // namespace prefs | 161 } // namespace prefs |
| OLD | NEW |