OLD | NEW |
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/profile_pref_store_manager.h" | 5 #include "chrome/browser/prefs/profile_pref_store_manager.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/json/json_file_value_serializer.h" | 8 #include "base/json/json_file_value_serializer.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/prefs/json_pref_store.h" | 11 #include "base/prefs/json_pref_store.h" |
12 #include "base/prefs/persistent_pref_store.h" | 12 #include "base/prefs/persistent_pref_store.h" |
13 #include "base/prefs/pref_registry_simple.h" | 13 #include "base/prefs/pref_registry_simple.h" |
14 #include "chrome/browser/prefs/pref_hash_store_impl.h" | 14 #include "chrome/browser/prefs/pref_hash_store_impl.h" |
15 #include "chrome/browser/prefs/tracked/pref_service_hash_store_contents.h" | 15 #include "chrome/browser/prefs/tracked/pref_service_hash_store_contents.h" |
16 #include "chrome/browser/prefs/tracked/segregated_pref_store.h" | 16 #include "chrome/browser/prefs/tracked/segregated_pref_store.h" |
| 17 #include "chrome/browser/prefs/tracked/tracked_preference_validation_observer.h" |
17 #include "chrome/common/chrome_constants.h" | 18 #include "chrome/common/chrome_constants.h" |
18 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
19 #include "components/user_prefs/pref_registry_syncable.h" | 20 #include "components/user_prefs/pref_registry_syncable.h" |
20 | 21 |
21 namespace { | 22 namespace { |
22 | 23 |
23 // An adaptor that allows a PrefHashStoreImpl to access a preference store | 24 // An adaptor that allows a PrefHashStoreImpl to access a preference store |
24 // directly as a dictionary. Uses an equivalent layout to | 25 // directly as a dictionary. Uses an equivalent layout to |
25 // PrefStoreHashStoreContents. | 26 // PrefStoreHashStoreContents. |
26 class DictionaryHashStoreContents : public HashStoreContents { | 27 class DictionaryHashStoreContents : public HashStoreContents { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 void InitializeHashStoreObserver::OnPrefValueChanged(const std::string& key) {} | 174 void InitializeHashStoreObserver::OnPrefValueChanged(const std::string& key) {} |
174 | 175 |
175 void InitializeHashStoreObserver::OnInitializationCompleted(bool succeeded) { | 176 void InitializeHashStoreObserver::OnInitializationCompleted(bool succeeded) { |
176 // If we successfully loaded the preferences _and_ the PrefHashStoreImpl | 177 // If we successfully loaded the preferences _and_ the PrefHashStoreImpl |
177 // hasn't been initialized by someone else in the meantime, initialize it now. | 178 // hasn't been initialized by someone else in the meantime, initialize it now. |
178 const PrefHashStoreImpl::StoreVersion pre_update_version = | 179 const PrefHashStoreImpl::StoreVersion pre_update_version = |
179 pref_hash_store_impl_->GetCurrentVersion(); | 180 pref_hash_store_impl_->GetCurrentVersion(); |
180 if (succeeded && pre_update_version < PrefHashStoreImpl::VERSION_LATEST) { | 181 if (succeeded && pre_update_version < PrefHashStoreImpl::VERSION_LATEST) { |
181 PrefHashFilter(pref_hash_store_impl_.PassAs<PrefHashStore>(), | 182 PrefHashFilter(pref_hash_store_impl_.PassAs<PrefHashStore>(), |
182 tracking_configuration_, | 183 tracking_configuration_, |
| 184 scoped_ptr<TrackedPreferenceValidationObserver>(), |
183 reporting_ids_count_).Initialize(*pref_store_); | 185 reporting_ids_count_).Initialize(*pref_store_); |
184 UMA_HISTOGRAM_ENUMERATION( | 186 UMA_HISTOGRAM_ENUMERATION( |
185 "Settings.TrackedPreferencesAlternateStoreVersionUpdatedFrom", | 187 "Settings.TrackedPreferencesAlternateStoreVersionUpdatedFrom", |
186 pre_update_version, | 188 pre_update_version, |
187 PrefHashStoreImpl::VERSION_LATEST + 1); | 189 PrefHashStoreImpl::VERSION_LATEST + 1); |
188 } | 190 } |
189 pref_store_->RemoveObserver(this); | 191 pref_store_->RemoveObserver(this); |
190 delete this; | 192 delete this; |
191 } | 193 } |
192 | 194 |
| 195 // A TrackedPreferenceValidationObserver that delegates to another shared |
| 196 // observer instance. |
| 197 class DelegatingValidationObserver |
| 198 : public TrackedPreferenceValidationObserver { |
| 199 public: |
| 200 // A reference-counted holder of a TrackedPreferenceValidationObserver. |
| 201 class RefCountedObserver : public base::RefCounted<RefCountedObserver> { |
| 202 public: |
| 203 explicit RefCountedObserver( |
| 204 scoped_ptr<TrackedPreferenceValidationObserver> observer); |
| 205 TrackedPreferenceValidationObserver* get(); |
| 206 |
| 207 private: |
| 208 friend class base::RefCounted<RefCountedObserver>; |
| 209 ~RefCountedObserver(); |
| 210 |
| 211 scoped_ptr<TrackedPreferenceValidationObserver> observer_; |
| 212 }; |
| 213 |
| 214 explicit DelegatingValidationObserver( |
| 215 const scoped_refptr<RefCountedObserver>& observer); |
| 216 virtual ~DelegatingValidationObserver(); |
| 217 |
| 218 // TrackedPreferenceValidationObserver methods. |
| 219 virtual void OnAtomicPreferenceValidation( |
| 220 const std::string& pref_path, |
| 221 const base::Value* value, |
| 222 PrefHashStoreTransaction::ValueState value_state, |
| 223 TrackedPreferenceHelper::ResetAction reset_action) OVERRIDE; |
| 224 virtual void OnSplitPreferenceValidation( |
| 225 const std::string& pref_path, |
| 226 const base::DictionaryValue* dict_value, |
| 227 const std::vector<std::string>& invalid_keys, |
| 228 PrefHashStoreTransaction::ValueState value_state, |
| 229 TrackedPreferenceHelper::ResetAction reset_action) OVERRIDE; |
| 230 |
| 231 private: |
| 232 scoped_refptr<RefCountedObserver> observer_; |
| 233 DISALLOW_COPY_AND_ASSIGN(DelegatingValidationObserver); |
| 234 }; |
| 235 |
| 236 DelegatingValidationObserver::RefCountedObserver::RefCountedObserver( |
| 237 scoped_ptr<TrackedPreferenceValidationObserver> observer) |
| 238 : observer_(observer.Pass()) { |
| 239 } |
| 240 |
| 241 DelegatingValidationObserver::RefCountedObserver::~RefCountedObserver() { |
| 242 } |
| 243 |
| 244 TrackedPreferenceValidationObserver* |
| 245 DelegatingValidationObserver::RefCountedObserver::get() { |
| 246 return observer_.get(); |
| 247 } |
| 248 |
| 249 DelegatingValidationObserver::DelegatingValidationObserver( |
| 250 const scoped_refptr<RefCountedObserver>& observer) |
| 251 : observer_(observer) { |
| 252 } |
| 253 |
| 254 DelegatingValidationObserver::~DelegatingValidationObserver() { |
| 255 } |
| 256 |
| 257 void DelegatingValidationObserver::OnAtomicPreferenceValidation( |
| 258 const std::string& pref_path, |
| 259 const base::Value* value, |
| 260 PrefHashStoreTransaction::ValueState value_state, |
| 261 TrackedPreferenceHelper::ResetAction reset_action) { |
| 262 observer_->get()->OnAtomicPreferenceValidation( |
| 263 pref_path, value, value_state, reset_action); |
| 264 } |
| 265 |
| 266 void DelegatingValidationObserver::OnSplitPreferenceValidation( |
| 267 const std::string& pref_path, |
| 268 const base::DictionaryValue* dict_value, |
| 269 const std::vector<std::string>& invalid_keys, |
| 270 PrefHashStoreTransaction::ValueState value_state, |
| 271 TrackedPreferenceHelper::ResetAction reset_action) { |
| 272 observer_->get()->OnSplitPreferenceValidation( |
| 273 pref_path, dict_value, invalid_keys, value_state, reset_action); |
| 274 } |
| 275 |
193 } // namespace | 276 } // namespace |
194 | 277 |
195 // TODO(erikwright): Enable this on Chrome OS and Android once MACs are moved | 278 // TODO(erikwright): Enable this on Chrome OS and Android once MACs are moved |
196 // out of Local State. This will resolve a race condition on Android and a | 279 // out of Local State. This will resolve a race condition on Android and a |
197 // privacy issue on ChromeOS. http://crbug.com/349158 | 280 // privacy issue on ChromeOS. http://crbug.com/349158 |
198 const bool ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking = | 281 const bool ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking = |
199 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 282 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
200 false; | 283 false; |
201 #else | 284 #else |
202 true; | 285 true; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 // pref store before being deleted from the latter. | 346 // pref store before being deleted from the latter. |
264 PrefHashFilter::ClearResetTime(pref_service); | 347 PrefHashFilter::ClearResetTime(pref_service); |
265 } | 348 } |
266 | 349 |
267 void ProfilePrefStoreManager::ResetPrefHashStore() { | 350 void ProfilePrefStoreManager::ResetPrefHashStore() { |
268 if (kPlatformSupportsPreferenceTracking) | 351 if (kPlatformSupportsPreferenceTracking) |
269 GetPrefHashStoreImpl()->Reset(); | 352 GetPrefHashStoreImpl()->Reset(); |
270 } | 353 } |
271 | 354 |
272 PersistentPrefStore* ProfilePrefStoreManager::CreateProfilePrefStore( | 355 PersistentPrefStore* ProfilePrefStoreManager::CreateProfilePrefStore( |
273 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) { | 356 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner, |
| 357 scoped_ptr<TrackedPreferenceValidationObserver> verification_observer) { |
274 scoped_ptr<PrefFilter> pref_filter; | 358 scoped_ptr<PrefFilter> pref_filter; |
275 if (!kPlatformSupportsPreferenceTracking) { | 359 if (!kPlatformSupportsPreferenceTracking) { |
276 return new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_), | 360 return new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_), |
277 io_task_runner, | 361 io_task_runner, |
278 scoped_ptr<PrefFilter>()); | 362 scoped_ptr<PrefFilter>()); |
279 } | 363 } |
280 | 364 |
281 std::vector<PrefHashFilter::TrackedPreferenceMetadata> | 365 std::vector<PrefHashFilter::TrackedPreferenceMetadata> |
282 unprotected_configuration; | 366 unprotected_configuration; |
283 std::vector<PrefHashFilter::TrackedPreferenceMetadata> | 367 std::vector<PrefHashFilter::TrackedPreferenceMetadata> |
284 protected_configuration; | 368 protected_configuration; |
285 std::set<std::string> protected_pref_names; | 369 std::set<std::string> protected_pref_names; |
286 for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::const_iterator | 370 for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::const_iterator |
287 it = tracking_configuration_.begin(); | 371 it = tracking_configuration_.begin(); |
288 it != tracking_configuration_.end(); | 372 it != tracking_configuration_.end(); |
289 ++it) { | 373 ++it) { |
290 if (it->enforcement_level > PrefHashFilter::NO_ENFORCEMENT) { | 374 if (it->enforcement_level > PrefHashFilter::NO_ENFORCEMENT) { |
291 protected_configuration.push_back(*it); | 375 protected_configuration.push_back(*it); |
292 protected_pref_names.insert(it->name); | 376 protected_pref_names.insert(it->name); |
293 } else { | 377 } else { |
294 unprotected_configuration.push_back(*it); | 378 unprotected_configuration.push_back(*it); |
295 } | 379 } |
296 } | 380 } |
297 | 381 |
298 scoped_ptr<PrefFilter> unprotected_pref_hash_filter( | 382 scoped_refptr<DelegatingValidationObserver::RefCountedObserver> observer; |
299 new PrefHashFilter(GetPrefHashStoreImpl().PassAs<PrefHashStore>(), | 383 if (verification_observer) { |
300 unprotected_configuration, | 384 observer = new DelegatingValidationObserver::RefCountedObserver( |
301 reporting_ids_count_)); | 385 verification_observer.Pass()); |
302 scoped_ptr<PrefFilter> protected_pref_hash_filter( | 386 } |
303 new PrefHashFilter(GetPrefHashStoreImpl().PassAs<PrefHashStore>(), | 387 |
304 protected_configuration, | 388 scoped_ptr<PrefFilter> unprotected_pref_hash_filter(new PrefHashFilter( |
305 reporting_ids_count_)); | 389 GetPrefHashStoreImpl().PassAs<PrefHashStore>(), |
| 390 unprotected_configuration, |
| 391 observer ? |
| 392 scoped_ptr<TrackedPreferenceValidationObserver>( |
| 393 new DelegatingValidationObserver(observer)) : |
| 394 scoped_ptr<TrackedPreferenceValidationObserver>(), |
| 395 reporting_ids_count_)); |
| 396 scoped_ptr<PrefFilter> protected_pref_hash_filter(new PrefHashFilter( |
| 397 GetPrefHashStoreImpl().PassAs<PrefHashStore>(), |
| 398 protected_configuration, |
| 399 observer ? |
| 400 scoped_ptr<TrackedPreferenceValidationObserver>( |
| 401 new DelegatingValidationObserver(observer)) : |
| 402 scoped_ptr<TrackedPreferenceValidationObserver>(), |
| 403 reporting_ids_count_)); |
306 | 404 |
307 scoped_refptr<PersistentPrefStore> unprotected_pref_store( | 405 scoped_refptr<PersistentPrefStore> unprotected_pref_store( |
308 new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_), | 406 new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_), |
309 io_task_runner, | 407 io_task_runner, |
310 unprotected_pref_hash_filter.Pass())); | 408 unprotected_pref_hash_filter.Pass())); |
311 scoped_refptr<PersistentPrefStore> protected_pref_store(new JsonPrefStore( | 409 scoped_refptr<PersistentPrefStore> protected_pref_store(new JsonPrefStore( |
312 profile_path_.Append(chrome::kProtectedPreferencesFilename), | 410 profile_path_.Append(chrome::kProtectedPreferencesFilename), |
313 io_task_runner, | 411 io_task_runner, |
314 protected_pref_hash_filter.Pass())); | 412 protected_pref_hash_filter.Pass())); |
315 | 413 |
316 // The on_initialized callback is used to migrate newly protected values from | 414 // The on_initialized callback is used to migrate newly protected values from |
317 // the main Preferences store to the Protected Preferences store. It is also | 415 // the main Preferences store to the Protected Preferences store. It is also |
318 // responsible for the initial migration to a two-store model. | 416 // responsible for the initial migration to a two-store model. |
319 return new SegregatedPrefStore( | 417 return new SegregatedPrefStore( |
320 unprotected_pref_store, | 418 unprotected_pref_store, |
321 protected_pref_store, | 419 protected_pref_store, |
322 protected_pref_names, | 420 protected_pref_names, |
323 base::Bind(&PrefHashFilter::MigrateValues, | 421 base::Bind( |
324 base::Owned(new PrefHashFilter( | 422 &PrefHashFilter::MigrateValues, |
325 CopyPrefHashStore(), | 423 base::Owned(new PrefHashFilter( |
326 protected_configuration, | 424 CopyPrefHashStore(), |
327 reporting_ids_count_)), | 425 protected_configuration, |
328 unprotected_pref_store, | 426 observer ? |
329 protected_pref_store)); | 427 scoped_ptr<TrackedPreferenceValidationObserver>( |
| 428 new DelegatingValidationObserver(observer)) : |
| 429 scoped_ptr<TrackedPreferenceValidationObserver>(), |
| 430 reporting_ids_count_)), |
| 431 unprotected_pref_store, |
| 432 protected_pref_store)); |
330 } | 433 } |
331 | 434 |
332 void ProfilePrefStoreManager::UpdateProfileHashStoreIfRequired( | 435 void ProfilePrefStoreManager::UpdateProfileHashStoreIfRequired( |
333 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) { | 436 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) { |
334 if (!kPlatformSupportsPreferenceTracking) | 437 if (!kPlatformSupportsPreferenceTracking) |
335 return; | 438 return; |
336 scoped_ptr<PrefHashStoreImpl> pref_hash_store_impl(GetPrefHashStoreImpl()); | 439 scoped_ptr<PrefHashStoreImpl> pref_hash_store_impl(GetPrefHashStoreImpl()); |
337 const PrefHashStoreImpl::StoreVersion current_version = | 440 const PrefHashStoreImpl::StoreVersion current_version = |
338 pref_hash_store_impl->GetCurrentVersion(); | 441 pref_hash_store_impl->GetCurrentVersion(); |
339 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferencesAlternateStoreVersion", | 442 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferencesAlternateStoreVersion", |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 // complete before Chrome can start (as master preferences seed the Local | 475 // complete before Chrome can start (as master preferences seed the Local |
373 // State and Preferences files). This won't trip ThreadIORestrictions as they | 476 // State and Preferences files). This won't trip ThreadIORestrictions as they |
374 // won't have kicked in yet on the main thread. | 477 // won't have kicked in yet on the main thread. |
375 bool success = serializer.Serialize(master_prefs); | 478 bool success = serializer.Serialize(master_prefs); |
376 | 479 |
377 if (success && kPlatformSupportsPreferenceTracking) { | 480 if (success && kPlatformSupportsPreferenceTracking) { |
378 scoped_refptr<const PrefStore> pref_store( | 481 scoped_refptr<const PrefStore> pref_store( |
379 new DictionaryPrefStore(&master_prefs)); | 482 new DictionaryPrefStore(&master_prefs)); |
380 PrefHashFilter(GetPrefHashStoreImpl().PassAs<PrefHashStore>(), | 483 PrefHashFilter(GetPrefHashStoreImpl().PassAs<PrefHashStore>(), |
381 tracking_configuration_, | 484 tracking_configuration_, |
| 485 scoped_ptr<TrackedPreferenceValidationObserver>(), |
382 reporting_ids_count_).Initialize(*pref_store); | 486 reporting_ids_count_).Initialize(*pref_store); |
383 } | 487 } |
384 | 488 |
385 UMA_HISTOGRAM_BOOLEAN("Settings.InitializedFromMasterPrefs", success); | 489 UMA_HISTOGRAM_BOOLEAN("Settings.InitializedFromMasterPrefs", success); |
386 return success; | 490 return success; |
387 } | 491 } |
388 | 492 |
389 PersistentPrefStore* | 493 PersistentPrefStore* |
390 ProfilePrefStoreManager::CreateDeprecatedCombinedProfilePrefStore( | 494 ProfilePrefStoreManager::CreateDeprecatedCombinedProfilePrefStore( |
391 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) { | 495 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) { |
392 scoped_ptr<PrefFilter> pref_filter; | 496 scoped_ptr<PrefFilter> pref_filter; |
393 if (kPlatformSupportsPreferenceTracking) { | 497 if (kPlatformSupportsPreferenceTracking) { |
394 pref_filter.reset( | 498 pref_filter.reset( |
395 new PrefHashFilter(GetPrefHashStoreImpl().PassAs<PrefHashStore>(), | 499 new PrefHashFilter(GetPrefHashStoreImpl().PassAs<PrefHashStore>(), |
396 tracking_configuration_, | 500 tracking_configuration_, |
| 501 scoped_ptr<TrackedPreferenceValidationObserver>(), |
397 reporting_ids_count_)); | 502 reporting_ids_count_)); |
398 } | 503 } |
399 return new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_), | 504 return new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_), |
400 io_task_runner, | 505 io_task_runner, |
401 pref_filter.Pass()); | 506 pref_filter.Pass()); |
402 } | 507 } |
403 | 508 |
404 scoped_ptr<PrefHashStoreImpl> ProfilePrefStoreManager::GetPrefHashStoreImpl() { | 509 scoped_ptr<PrefHashStoreImpl> ProfilePrefStoreManager::GetPrefHashStoreImpl() { |
405 DCHECK(kPlatformSupportsPreferenceTracking); | 510 DCHECK(kPlatformSupportsPreferenceTracking); |
406 | 511 |
407 return make_scoped_ptr(new PrefHashStoreImpl( | 512 return make_scoped_ptr(new PrefHashStoreImpl( |
408 seed_, | 513 seed_, |
409 device_id_, | 514 device_id_, |
410 scoped_ptr<HashStoreContents>(new PrefServiceHashStoreContents( | 515 scoped_ptr<HashStoreContents>(new PrefServiceHashStoreContents( |
411 profile_path_.AsUTF8Unsafe(), local_state_)))); | 516 profile_path_.AsUTF8Unsafe(), local_state_)))); |
412 } | 517 } |
413 | 518 |
414 scoped_ptr<PrefHashStore> ProfilePrefStoreManager::CopyPrefHashStore() { | 519 scoped_ptr<PrefHashStore> ProfilePrefStoreManager::CopyPrefHashStore() { |
415 DCHECK(kPlatformSupportsPreferenceTracking); | 520 DCHECK(kPlatformSupportsPreferenceTracking); |
416 | 521 |
417 PrefServiceHashStoreContents real_contents(profile_path_.AsUTF8Unsafe(), | 522 PrefServiceHashStoreContents real_contents(profile_path_.AsUTF8Unsafe(), |
418 local_state_); | 523 local_state_); |
419 return scoped_ptr<PrefHashStore>(new PrefHashStoreImpl( | 524 return scoped_ptr<PrefHashStore>(new PrefHashStoreImpl( |
420 seed_, | 525 seed_, |
421 device_id_, | 526 device_id_, |
422 scoped_ptr<HashStoreContents>( | 527 scoped_ptr<HashStoreContents>( |
423 new DictionaryHashStoreContents(real_contents)))); | 528 new DictionaryHashStoreContents(real_contents)))); |
424 } | 529 } |
OLD | NEW |