OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/pref_model_associator.h" | 5 #include "chrome/browser/prefs/pref_model_associator.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
9 #include "base/json/json_string_value_serializer.h" | 9 #include "base/json/json_string_value_serializer.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/prefs/pref_service.h" | 12 #include "base/prefs/pref_service.h" |
| 13 #include "base/stl_util.h" |
13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
14 #include "base/values.h" | 15 #include "base/values.h" |
15 #include "chrome/browser/chrome_notification_types.h" | 16 #include "chrome/browser/chrome_notification_types.h" |
16 #include "chrome/browser/prefs/pref_service_syncable.h" | 17 #include "chrome/browser/prefs/pref_service_syncable.h" |
17 #include "chrome/common/pref_names.h" | 18 #include "chrome/common/pref_names.h" |
18 #include "sync/api/sync_change.h" | 19 #include "sync/api/sync_change.h" |
19 #include "sync/api/sync_error_factory.h" | 20 #include "sync/api/sync_error_factory.h" |
20 #include "sync/protocol/preference_specifics.pb.h" | 21 #include "sync/protocol/preference_specifics.pb.h" |
21 #include "sync/protocol/sync.pb.h" | 22 #include "sync/protocol/sync.pb.h" |
22 | 23 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 processing_syncer_changes_(false), | 55 processing_syncer_changes_(false), |
55 pref_service_(NULL), | 56 pref_service_(NULL), |
56 type_(type) { | 57 type_(type) { |
57 DCHECK(CalledOnValidThread()); | 58 DCHECK(CalledOnValidThread()); |
58 DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); | 59 DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); |
59 } | 60 } |
60 | 61 |
61 PrefModelAssociator::~PrefModelAssociator() { | 62 PrefModelAssociator::~PrefModelAssociator() { |
62 DCHECK(CalledOnValidThread()); | 63 DCHECK(CalledOnValidThread()); |
63 pref_service_ = NULL; | 64 pref_service_ = NULL; |
| 65 |
| 66 STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), |
| 67 synced_pref_observers_.end()); |
| 68 synced_pref_observers_.clear(); |
64 } | 69 } |
65 | 70 |
66 void PrefModelAssociator::InitPrefAndAssociate( | 71 void PrefModelAssociator::InitPrefAndAssociate( |
67 const syncer::SyncData& sync_pref, | 72 const syncer::SyncData& sync_pref, |
68 const std::string& pref_name, | 73 const std::string& pref_name, |
69 syncer::SyncChangeList* sync_changes) { | 74 syncer::SyncChangeList* sync_changes) { |
70 const Value* user_pref_value = pref_service_->GetUserPrefValue( | 75 const Value* user_pref_value = pref_service_->GetUserPrefValue( |
71 pref_name.c_str()); | 76 pref_name.c_str()); |
72 VLOG(1) << "Associating preference " << pref_name; | 77 VLOG(1) << "Associating preference " << pref_name; |
73 | 78 |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 | 393 |
389 const PrefService::Preference* pref = | 394 const PrefService::Preference* pref = |
390 pref_service_->FindPreference(pref_name); | 395 pref_service_->FindPreference(pref_name); |
391 DCHECK(pref); | 396 DCHECK(pref); |
392 | 397 |
393 // This will only modify the user controlled value store, which takes | 398 // This will only modify the user controlled value store, which takes |
394 // priority over the default value but is ignored if the preference is | 399 // priority over the default value but is ignored if the preference is |
395 // policy controlled. | 400 // policy controlled. |
396 pref_service_->Set(pref_name, *value); | 401 pref_service_->Set(pref_name, *value); |
397 | 402 |
| 403 NotifySyncedPrefObservers(name, true /*from_sync*/); |
| 404 |
398 // Keep track of any newly synced preferences. | 405 // Keep track of any newly synced preferences. |
399 if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { | 406 if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { |
400 synced_preferences_.insert(name); | 407 synced_preferences_.insert(name); |
401 } | 408 } |
402 } | 409 } |
403 return syncer::SyncError(); | 410 return syncer::SyncError(); |
404 } | 411 } |
405 | 412 |
406 Value* PrefModelAssociator::ReadPreferenceSpecifics( | 413 Value* PrefModelAssociator::ReadPreferenceSpecifics( |
407 const sync_pb::PreferenceSpecifics& preference, | 414 const sync_pb::PreferenceSpecifics& preference, |
408 std::string* name) { | 415 std::string* name) { |
409 base::JSONReader reader; | 416 base::JSONReader reader; |
410 scoped_ptr<Value> value(reader.ReadToValue(preference.value())); | 417 scoped_ptr<Value> value(reader.ReadToValue(preference.value())); |
411 if (!value.get()) { | 418 if (!value.get()) { |
412 std::string err = "Failed to deserialize preference value: " + | 419 std::string err = "Failed to deserialize preference value: " + |
413 reader.GetErrorMessage(); | 420 reader.GetErrorMessage(); |
414 LOG(ERROR) << err; | 421 LOG(ERROR) << err; |
415 return NULL; | 422 return NULL; |
416 } | 423 } |
417 *name = preference.name(); | 424 *name = preference.name(); |
418 return value.release(); | 425 return value.release(); |
419 } | 426 } |
420 | 427 |
421 bool PrefModelAssociator::IsPrefSynced(const std::string& name) const { | 428 bool PrefModelAssociator::IsPrefSynced(const std::string& name) const { |
422 return synced_preferences_.find(name) != synced_preferences_.end(); | 429 return synced_preferences_.find(name) != synced_preferences_.end(); |
423 } | 430 } |
424 | 431 |
| 432 void PrefModelAssociator::AddSyncedPrefObserver(const std::string& name, |
| 433 SyncedPrefObserver* observer) { |
| 434 SyncedPrefObserverList* observers = synced_pref_observers_[name]; |
| 435 if (observers == NULL) { |
| 436 observers = new SyncedPrefObserverList; |
| 437 synced_pref_observers_[name] = observers; |
| 438 } |
| 439 observers->AddObserver(observer); |
| 440 } |
| 441 |
| 442 void PrefModelAssociator::RemoveSyncedPrefObserver(const std::string& name, |
| 443 SyncedPrefObserver* observer) { |
| 444 SyncedPrefObserverMap::iterator observer_iter = |
| 445 synced_pref_observers_.find(name); |
| 446 if (observer_iter == synced_pref_observers_.end()) |
| 447 return; |
| 448 SyncedPrefObserverList* observers = observer_iter->second; |
| 449 observers->RemoveObserver(observer); |
| 450 } |
| 451 |
425 std::set<std::string> PrefModelAssociator::registered_preferences() const { | 452 std::set<std::string> PrefModelAssociator::registered_preferences() const { |
426 return registered_preferences_; | 453 return registered_preferences_; |
427 } | 454 } |
428 | 455 |
429 void PrefModelAssociator::RegisterPref(const char* name) { | 456 void PrefModelAssociator::RegisterPref(const char* name) { |
430 DCHECK(!models_associated_ && registered_preferences_.count(name) == 0); | 457 DCHECK(!models_associated_ && registered_preferences_.count(name) == 0); |
431 registered_preferences_.insert(name); | 458 registered_preferences_.insert(name); |
432 } | 459 } |
433 | 460 |
434 bool PrefModelAssociator::IsPrefRegistered(const char* name) { | 461 bool PrefModelAssociator::IsPrefRegistered(const char* name) { |
(...skipping 21 matching lines...) Expand all Loading... |
456 if (!preference->IsUserModifiable()) { | 483 if (!preference->IsUserModifiable()) { |
457 // If the preference is no longer user modifiable, it must now be controlled | 484 // If the preference is no longer user modifiable, it must now be controlled |
458 // by policy, whose values we do not sync. Just return. If the preference | 485 // by policy, whose values we do not sync. Just return. If the preference |
459 // stops being controlled by policy, it will revert back to the user value | 486 // stops being controlled by policy, it will revert back to the user value |
460 // (which we continue to update with sync changes). | 487 // (which we continue to update with sync changes). |
461 return; | 488 return; |
462 } | 489 } |
463 | 490 |
464 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 491 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); |
465 | 492 |
| 493 NotifySyncedPrefObservers(name, false /*from_sync*/); |
| 494 |
466 if (synced_preferences_.count(name) == 0) { | 495 if (synced_preferences_.count(name) == 0) { |
467 // Not in synced_preferences_ means no synced data. InitPrefAndAssociate(..) | 496 // Not in synced_preferences_ means no synced data. InitPrefAndAssociate(..) |
468 // will determine if we care about its data (e.g. if it has a default value | 497 // will determine if we care about its data (e.g. if it has a default value |
469 // and hasn't been changed yet we don't) and take care syncing any new data. | 498 // and hasn't been changed yet we don't) and take care syncing any new data. |
470 InitPrefAndAssociate(syncer::SyncData(), name, &changes); | 499 InitPrefAndAssociate(syncer::SyncData(), name, &changes); |
471 } else { | 500 } else { |
472 // We are already syncing this preference, just update it's sync node. | 501 // We are already syncing this preference, just update it's sync node. |
473 syncer::SyncData sync_data; | 502 syncer::SyncData sync_data; |
474 if (!CreatePrefSyncData(name, *preference->GetValue(), &sync_data)) { | 503 if (!CreatePrefSyncData(name, *preference->GetValue(), &sync_data)) { |
475 LOG(ERROR) << "Failed to update preference."; | 504 LOG(ERROR) << "Failed to update preference."; |
476 return; | 505 return; |
477 } | 506 } |
478 changes.push_back( | 507 changes.push_back( |
479 syncer::SyncChange(FROM_HERE, | 508 syncer::SyncChange(FROM_HERE, |
480 syncer::SyncChange::ACTION_UPDATE, | 509 syncer::SyncChange::ACTION_UPDATE, |
481 sync_data)); | 510 sync_data)); |
482 } | 511 } |
483 | 512 |
484 syncer::SyncError error = | 513 syncer::SyncError error = |
485 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 514 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
486 } | 515 } |
487 | 516 |
488 void PrefModelAssociator::SetPrefService(PrefServiceSyncable* pref_service) { | 517 void PrefModelAssociator::SetPrefService(PrefServiceSyncable* pref_service) { |
489 DCHECK(pref_service_ == NULL); | 518 DCHECK(pref_service_ == NULL); |
490 pref_service_ = pref_service; | 519 pref_service_ = pref_service; |
491 } | 520 } |
| 521 |
| 522 void PrefModelAssociator::NotifySyncedPrefObservers(const std::string& path, |
| 523 bool from_sync) const { |
| 524 SyncedPrefObserverMap::const_iterator observer_iter = |
| 525 synced_pref_observers_.find(path); |
| 526 if (observer_iter == synced_pref_observers_.end()) |
| 527 return; |
| 528 SyncedPrefObserverList* observers = observer_iter->second; |
| 529 FOR_EACH_OBSERVER(SyncedPrefObserver, *observers, |
| 530 OnSyncedPrefChanged(path, from_sync)); |
| 531 } |
OLD | NEW |