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

Side by Side Diff: chrome/browser/prefs/tracked/tracked_preferences_migration.cc

Issue 324493002: Move preference MACs to the protected preference stores. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comment typo. Created 6 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/browser/prefs/tracked/tracked_preferences_migration.h" 5 #include "chrome/browser/prefs/tracked/tracked_preferences_migration.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/metrics/histogram.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "chrome/browser/prefs/interceptable_pref_filter.h" 13 #include "chrome/browser/prefs/interceptable_pref_filter.h"
14 #include "chrome/browser/prefs/pref_hash_store.h"
15 #include "chrome/browser/prefs/pref_hash_store_transaction.h"
16 #include "chrome/browser/prefs/tracked/dictionary_hash_store_contents.h"
17 #include "chrome/browser/prefs/tracked/hash_store_contents.h"
14 18
15 namespace { 19 namespace {
16 20
17 class TrackedPreferencesMigrator 21 class TrackedPreferencesMigrator
18 : public base::RefCounted<TrackedPreferencesMigrator> { 22 : public base::RefCounted<TrackedPreferencesMigrator> {
19 public: 23 public:
20 TrackedPreferencesMigrator( 24 TrackedPreferencesMigrator(
21 const std::set<std::string>& unprotected_pref_names, 25 const std::set<std::string>& unprotected_pref_names,
22 const std::set<std::string>& protected_pref_names, 26 const std::set<std::string>& protected_pref_names,
23 const base::Callback<void(const std::string& key)>& 27 const base::Callback<void(const std::string& key)>&
24 unprotected_store_cleaner, 28 unprotected_store_cleaner,
25 const base::Callback<void(const std::string& key)>& 29 const base::Callback<void(const std::string& key)>&
26 protected_store_cleaner, 30 protected_store_cleaner,
27 const base::Callback<void(const base::Closure&)>& 31 const base::Callback<void(const base::Closure&)>&
28 register_on_successful_unprotected_store_write_callback, 32 register_on_successful_unprotected_store_write_callback,
29 const base::Callback<void(const base::Closure&)>& 33 const base::Callback<void(const base::Closure&)>&
30 register_on_successful_protected_store_write_callback, 34 register_on_successful_protected_store_write_callback,
35 scoped_ptr<PrefHashStore> unprotected_pref_hash_store,
36 scoped_ptr<PrefHashStore> protected_pref_hash_store,
37 scoped_ptr<HashStoreContents> legacy_pref_hash_store,
31 InterceptablePrefFilter* unprotected_pref_filter, 38 InterceptablePrefFilter* unprotected_pref_filter,
32 InterceptablePrefFilter* protected_pref_filter); 39 InterceptablePrefFilter* protected_pref_filter);
33 40
34 private: 41 private:
35 friend class base::RefCounted<TrackedPreferencesMigrator>; 42 friend class base::RefCounted<TrackedPreferencesMigrator>;
36 43
37 enum PrefFilterID { 44 enum PrefFilterID {
38 UNPROTECTED_PREF_FILTER, 45 UNPROTECTED_PREF_FILTER,
39 PROTECTED_PREF_FILTER 46 PROTECTED_PREF_FILTER
40 }; 47 };
(...skipping 20 matching lines...) Expand all
61 const base::Callback<void(const base::Closure&)> 68 const base::Callback<void(const base::Closure&)>
62 register_on_successful_unprotected_store_write_callback_; 69 register_on_successful_unprotected_store_write_callback_;
63 const base::Callback<void(const base::Closure&)> 70 const base::Callback<void(const base::Closure&)>
64 register_on_successful_protected_store_write_callback_; 71 register_on_successful_protected_store_write_callback_;
65 72
66 InterceptablePrefFilter::FinalizeFilterOnLoadCallback 73 InterceptablePrefFilter::FinalizeFilterOnLoadCallback
67 finalize_unprotected_filter_on_load_; 74 finalize_unprotected_filter_on_load_;
68 InterceptablePrefFilter::FinalizeFilterOnLoadCallback 75 InterceptablePrefFilter::FinalizeFilterOnLoadCallback
69 finalize_protected_filter_on_load_; 76 finalize_protected_filter_on_load_;
70 77
78 scoped_ptr<PrefHashStore> unprotected_pref_hash_store_;
79 scoped_ptr<PrefHashStore> protected_pref_hash_store_;
80 scoped_ptr<HashStoreContents> legacy_pref_hash_store_;
81
71 scoped_ptr<base::DictionaryValue> unprotected_prefs_; 82 scoped_ptr<base::DictionaryValue> unprotected_prefs_;
72 scoped_ptr<base::DictionaryValue> protected_prefs_; 83 scoped_ptr<base::DictionaryValue> protected_prefs_;
73 84
74 DISALLOW_COPY_AND_ASSIGN(TrackedPreferencesMigrator); 85 DISALLOW_COPY_AND_ASSIGN(TrackedPreferencesMigrator);
75 }; 86 };
76 87
77 // Invokes |store_cleaner| for every |keys_to_clean|. 88 // Invokes |store_cleaner| for every |keys_to_clean|.
78 void CleanupPrefStore( 89 void CleanupPrefStore(
79 const base::Callback<void(const std::string& key)>& store_cleaner, 90 const base::Callback<void(const std::string& key)>& store_cleaner,
80 const std::set<std::string>& keys_to_clean) { 91 const std::set<std::string>& keys_to_clean) {
(...skipping 16 matching lines...) Expand all
97 bool wait_for_commit_to_destination_store) { 108 bool wait_for_commit_to_destination_store) {
98 DCHECK(!keys_to_clean.empty()); 109 DCHECK(!keys_to_clean.empty());
99 if (wait_for_commit_to_destination_store) { 110 if (wait_for_commit_to_destination_store) {
100 register_on_successful_destination_store_write_callback.Run( 111 register_on_successful_destination_store_write_callback.Run(
101 base::Bind(&CleanupPrefStore, source_store_cleaner, keys_to_clean)); 112 base::Bind(&CleanupPrefStore, source_store_cleaner, keys_to_clean));
102 } else { 113 } else {
103 CleanupPrefStore(source_store_cleaner, keys_to_clean); 114 CleanupPrefStore(source_store_cleaner, keys_to_clean);
104 } 115 }
105 } 116 }
106 117
118 // Removes hashes for |migrated_pref_names| from |origin_pref_store| using
119 // the configuration/implementation in |origin_pref_hash_store|.
120 void CleanupMigratedHashes(const std::set<std::string>& migrated_pref_names,
121 PrefHashStore* origin_pref_hash_store,
122 base::DictionaryValue* origin_pref_store) {
123 scoped_ptr<PrefHashStoreTransaction> transaction(
124 origin_pref_hash_store->BeginTransaction(scoped_ptr<HashStoreContents>(
125 new DictionaryHashStoreContents(origin_pref_store))));
126 for (std::set<std::string>::const_iterator it = migrated_pref_names.begin();
127 it != migrated_pref_names.end();
128 ++it) {
129 transaction->ClearHash(*it);
130 }
131 }
132
107 // Copies the value of each pref in |pref_names| which is set in |old_store|, 133 // Copies the value of each pref in |pref_names| which is set in |old_store|,
108 // but not in |new_store| into |new_store|. Sets |old_store_needs_cleanup| to 134 // but not in |new_store| into |new_store|. Sets |old_store_needs_cleanup| to
109 // true if any old duplicates remain in |old_store| and sets |new_store_altered| 135 // true if any old duplicates remain in |old_store| and sets |new_store_altered|
110 // to true if any value was copied to |new_store|. 136 // to true if any value was copied to |new_store|.
111 void MigratePrefsFromOldToNewStore(const std::set<std::string>& pref_names, 137 void MigratePrefsFromOldToNewStore(const std::set<std::string>& pref_names,
112 const base::DictionaryValue* old_store, 138 base::DictionaryValue* old_store,
113 base::DictionaryValue* new_store, 139 base::DictionaryValue* new_store,
140 PrefHashStore* new_hash_store,
141 HashStoreContents* legacy_hash_store,
114 bool* old_store_needs_cleanup, 142 bool* old_store_needs_cleanup,
115 bool* new_store_altered) { 143 bool* new_store_altered,
144 bool* used_legacy_pref_hashes) {
145 const base::DictionaryValue* old_hash_store_contents =
146 DictionaryHashStoreContents(old_store).GetContents();
147 const base::DictionaryValue* legacy_hash_store_contents =
148 legacy_hash_store->GetContents();
149 scoped_ptr<PrefHashStoreTransaction> new_hash_store_transaction(
150 new_hash_store->BeginTransaction(scoped_ptr<HashStoreContents>(
151 new DictionaryHashStoreContents(new_store))));
152
116 for (std::set<std::string>::const_iterator it = pref_names.begin(); 153 for (std::set<std::string>::const_iterator it = pref_names.begin();
117 it != pref_names.end(); ++it) { 154 it != pref_names.end();
118 const std::string& pref_name = *it; 155 ++it) {
156 const std::string& pref_name = *it;
157 const base::Value* value_in_old_store = NULL;
119 158
120 const base::Value* value_in_old_store = NULL; 159 // If the destination does not have a hash for this pref we will
121 if (!old_store->Get(pref_name, &value_in_old_store)) 160 // unconditionally attempt to move it.
122 continue; 161 bool destination_hash_missing =
162 !new_hash_store_transaction->HasHash(pref_name);
163 // If we migrate the value we will also attempt to migrate the hash.
164 bool migrated_value = false;
165 if (old_store->Get(pref_name, &value_in_old_store)) {
166 // Whether this value ends up being copied below or was left behind by a
167 // previous incomplete migration, it should be cleaned up.
168 *old_store_needs_cleanup = true;
123 169
124 // Whether this value ends up being copied below or was left behind by a 170 if (!new_store->Get(pref_name, NULL)) {
125 // previous incomplete migration, it should be cleaned up. 171 // Copy the value from |old_store| to |new_store| rather than moving it
126 *old_store_needs_cleanup = true; 172 // to avoid data loss should |old_store| be flushed to disk without
173 // |new_store| having equivalently been successfully flushed to disk
174 // (e.g., on crash or in cases where |new_store| is read-only following
175 // a read error on startup).
176 new_store->Set(pref_name, value_in_old_store->DeepCopy());
177 migrated_value = true;
178 *new_store_altered = true;
179 }
180 }
127 181
128 if (new_store->Get(pref_name, NULL)) 182 if (destination_hash_missing || migrated_value) {
129 continue; 183 const base::Value* old_hash = NULL;
130 184 if (old_hash_store_contents)
131 // Copy the value from |old_store| to |new_store| rather than moving it to 185 old_hash_store_contents->Get(pref_name, &old_hash);
132 // avoid data loss should |old_store| be flushed to disk without |new_store| 186 if (!old_hash && legacy_hash_store_contents) {
133 // having equivalently been successfully flushed to disk (e.g., on crash or 187 legacy_hash_store_contents->Get(pref_name, &old_hash);
134 // in cases where |new_store| is read-only following a read error on 188 if (old_hash)
135 // startup). 189 *used_legacy_pref_hashes = true;
136 new_store->Set(pref_name, value_in_old_store->DeepCopy()); 190 }
137 *new_store_altered = true; 191 if (old_hash) {
192 new_hash_store_transaction->ImportHash(pref_name, old_hash);
193 *new_store_altered = true;
194 } else if (!destination_hash_missing) {
195 new_hash_store_transaction->ClearHash(pref_name);
196 *new_store_altered = true;
197 }
198 }
138 } 199 }
139 } 200 }
140 201
141 TrackedPreferencesMigrator::TrackedPreferencesMigrator( 202 TrackedPreferencesMigrator::TrackedPreferencesMigrator(
142 const std::set<std::string>& unprotected_pref_names, 203 const std::set<std::string>& unprotected_pref_names,
143 const std::set<std::string>& protected_pref_names, 204 const std::set<std::string>& protected_pref_names,
144 const base::Callback<void(const std::string& key)>& 205 const base::Callback<void(const std::string& key)>&
145 unprotected_store_cleaner, 206 unprotected_store_cleaner,
146 const base::Callback<void(const std::string& key)>& protected_store_cleaner, 207 const base::Callback<void(const std::string& key)>& protected_store_cleaner,
147 const base::Callback<void(const base::Closure&)>& 208 const base::Callback<void(const base::Closure&)>&
148 register_on_successful_unprotected_store_write_callback, 209 register_on_successful_unprotected_store_write_callback,
149 const base::Callback<void(const base::Closure&)>& 210 const base::Callback<void(const base::Closure&)>&
150 register_on_successful_protected_store_write_callback, 211 register_on_successful_protected_store_write_callback,
212 scoped_ptr<PrefHashStore> unprotected_pref_hash_store,
213 scoped_ptr<PrefHashStore> protected_pref_hash_store,
214 scoped_ptr<HashStoreContents> legacy_pref_hash_store,
151 InterceptablePrefFilter* unprotected_pref_filter, 215 InterceptablePrefFilter* unprotected_pref_filter,
152 InterceptablePrefFilter* protected_pref_filter) 216 InterceptablePrefFilter* protected_pref_filter)
153 : unprotected_pref_names_(unprotected_pref_names), 217 : unprotected_pref_names_(unprotected_pref_names),
154 protected_pref_names_(protected_pref_names), 218 protected_pref_names_(protected_pref_names),
155 unprotected_store_cleaner_(unprotected_store_cleaner), 219 unprotected_store_cleaner_(unprotected_store_cleaner),
156 protected_store_cleaner_(protected_store_cleaner), 220 protected_store_cleaner_(protected_store_cleaner),
157 register_on_successful_unprotected_store_write_callback_( 221 register_on_successful_unprotected_store_write_callback_(
158 register_on_successful_unprotected_store_write_callback), 222 register_on_successful_unprotected_store_write_callback),
159 register_on_successful_protected_store_write_callback_( 223 register_on_successful_protected_store_write_callback_(
160 register_on_successful_protected_store_write_callback) { 224 register_on_successful_protected_store_write_callback),
225 unprotected_pref_hash_store_(unprotected_pref_hash_store.Pass()),
226 protected_pref_hash_store_(protected_pref_hash_store.Pass()),
227 legacy_pref_hash_store_(legacy_pref_hash_store.Pass()) {
161 // The callbacks bound below will own this TrackedPreferencesMigrator by 228 // The callbacks bound below will own this TrackedPreferencesMigrator by
162 // reference. 229 // reference.
163 unprotected_pref_filter->InterceptNextFilterOnLoad( 230 unprotected_pref_filter->InterceptNextFilterOnLoad(
164 base::Bind(&TrackedPreferencesMigrator::InterceptFilterOnLoad, 231 base::Bind(&TrackedPreferencesMigrator::InterceptFilterOnLoad,
165 this, 232 this,
166 UNPROTECTED_PREF_FILTER)); 233 UNPROTECTED_PREF_FILTER));
167 protected_pref_filter->InterceptNextFilterOnLoad( 234 protected_pref_filter->InterceptNextFilterOnLoad(
168 base::Bind(&TrackedPreferencesMigrator::InterceptFilterOnLoad, 235 base::Bind(&TrackedPreferencesMigrator::InterceptFilterOnLoad,
169 this, 236 this,
170 PROTECTED_PREF_FILTER)); 237 PROTECTED_PREF_FILTER));
(...skipping 18 matching lines...) Expand all
189 } 256 }
190 257
191 MigrateIfReady(); 258 MigrateIfReady();
192 } 259 }
193 260
194 void TrackedPreferencesMigrator::MigrateIfReady() { 261 void TrackedPreferencesMigrator::MigrateIfReady() {
195 // Wait for both stores to have been read before proceeding. 262 // Wait for both stores to have been read before proceeding.
196 if (!protected_prefs_ || !unprotected_prefs_) 263 if (!protected_prefs_ || !unprotected_prefs_)
197 return; 264 return;
198 265
266 bool used_legacy_pref_hashes = false;
199 bool protected_prefs_need_cleanup = false; 267 bool protected_prefs_need_cleanup = false;
200 bool unprotected_prefs_altered = false; 268 bool unprotected_prefs_altered = false;
201 MigratePrefsFromOldToNewStore(unprotected_pref_names_, 269 MigratePrefsFromOldToNewStore(unprotected_pref_names_,
202 protected_prefs_.get(), 270 protected_prefs_.get(),
203 unprotected_prefs_.get(), 271 unprotected_prefs_.get(),
272 unprotected_pref_hash_store_.get(),
273 legacy_pref_hash_store_.get(),
204 &protected_prefs_need_cleanup, 274 &protected_prefs_need_cleanup,
205 &unprotected_prefs_altered); 275 &unprotected_prefs_altered,
276 &used_legacy_pref_hashes);
206 bool unprotected_prefs_need_cleanup = false; 277 bool unprotected_prefs_need_cleanup = false;
207 bool protected_prefs_altered = false; 278 bool protected_prefs_altered = false;
208 MigratePrefsFromOldToNewStore(protected_pref_names_, 279 MigratePrefsFromOldToNewStore(protected_pref_names_,
209 unprotected_prefs_.get(), 280 unprotected_prefs_.get(),
210 protected_prefs_.get(), 281 protected_prefs_.get(),
282 protected_pref_hash_store_.get(),
283 legacy_pref_hash_store_.get(),
211 &unprotected_prefs_need_cleanup, 284 &unprotected_prefs_need_cleanup,
212 &protected_prefs_altered); 285 &protected_prefs_altered,
286 &used_legacy_pref_hashes);
287 UMA_HISTOGRAM_BOOLEAN("Settings.MigratedHashesFromLocalState",
288 used_legacy_pref_hashes);
289
290 if (!unprotected_prefs_altered && !protected_prefs_altered) {
291 // Clean up any MACs that might have been previously migrated from the
292 // various stores. It's safe to leave them behind for a little while as they
293 // will be ignored unless the corresponding value is _also_ present. The
294 // cleanup must be deferred until the MACs have been written to their target
295 // stores, and doing so in a subsequent launch is easier than within the
296 // same process.
297 CleanupMigratedHashes(unprotected_pref_names_,
298 protected_pref_hash_store_.get(),
299 protected_prefs_.get());
300 CleanupMigratedHashes(protected_pref_names_,
301 unprotected_pref_hash_store_.get(),
302 unprotected_prefs_.get());
303 legacy_pref_hash_store_->Reset();
304 }
213 305
214 // Hand the processed prefs back to their respective filters. 306 // Hand the processed prefs back to their respective filters.
215 finalize_unprotected_filter_on_load_.Run(unprotected_prefs_.Pass(), 307 finalize_unprotected_filter_on_load_.Run(unprotected_prefs_.Pass(),
216 unprotected_prefs_altered); 308 unprotected_prefs_altered);
217 finalize_protected_filter_on_load_.Run(protected_prefs_.Pass(), 309 finalize_protected_filter_on_load_.Run(protected_prefs_.Pass(),
218 protected_prefs_altered); 310 protected_prefs_altered);
219 311
220 if (unprotected_prefs_need_cleanup) { 312 if (unprotected_prefs_need_cleanup) {
221 // Schedule a cleanup of the |protected_pref_names_| from the unprotected 313 // Schedule a cleanup of the |protected_pref_names_| from the unprotected
222 // prefs once the protected prefs were successfully written to disk (or 314 // prefs once the protected prefs were successfully written to disk (or
(...skipping 22 matching lines...) Expand all
245 void SetupTrackedPreferencesMigration( 337 void SetupTrackedPreferencesMigration(
246 const std::set<std::string>& unprotected_pref_names, 338 const std::set<std::string>& unprotected_pref_names,
247 const std::set<std::string>& protected_pref_names, 339 const std::set<std::string>& protected_pref_names,
248 const base::Callback<void(const std::string& key)>& 340 const base::Callback<void(const std::string& key)>&
249 unprotected_store_cleaner, 341 unprotected_store_cleaner,
250 const base::Callback<void(const std::string& key)>& protected_store_cleaner, 342 const base::Callback<void(const std::string& key)>& protected_store_cleaner,
251 const base::Callback<void(const base::Closure&)>& 343 const base::Callback<void(const base::Closure&)>&
252 register_on_successful_unprotected_store_write_callback, 344 register_on_successful_unprotected_store_write_callback,
253 const base::Callback<void(const base::Closure&)>& 345 const base::Callback<void(const base::Closure&)>&
254 register_on_successful_protected_store_write_callback, 346 register_on_successful_protected_store_write_callback,
347 scoped_ptr<PrefHashStore> unprotected_pref_hash_store,
348 scoped_ptr<PrefHashStore> protected_pref_hash_store,
349 scoped_ptr<HashStoreContents> legacy_pref_hash_store,
255 InterceptablePrefFilter* unprotected_pref_filter, 350 InterceptablePrefFilter* unprotected_pref_filter,
256 InterceptablePrefFilter* protected_pref_filter) { 351 InterceptablePrefFilter* protected_pref_filter) {
257 scoped_refptr<TrackedPreferencesMigrator> prefs_migrator( 352 scoped_refptr<TrackedPreferencesMigrator> prefs_migrator(
258 new TrackedPreferencesMigrator( 353 new TrackedPreferencesMigrator(
259 unprotected_pref_names, 354 unprotected_pref_names,
260 protected_pref_names, 355 protected_pref_names,
261 unprotected_store_cleaner, 356 unprotected_store_cleaner,
262 protected_store_cleaner, 357 protected_store_cleaner,
263 register_on_successful_unprotected_store_write_callback, 358 register_on_successful_unprotected_store_write_callback,
264 register_on_successful_protected_store_write_callback, 359 register_on_successful_protected_store_write_callback,
360 unprotected_pref_hash_store.Pass(),
361 protected_pref_hash_store.Pass(),
362 legacy_pref_hash_store.Pass(),
265 unprotected_pref_filter, 363 unprotected_pref_filter,
266 protected_pref_filter)); 364 protected_pref_filter));
267 } 365 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698