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 |