Chromium Code Reviews| 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); | |
|
battre
2013/08/05 17:17:26
nit: true /*from_sync*/
Ken Rockot(use gerrit already)
2013/08/06 20:18:32
Done.
| |
| 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); | |
|
battre
2013/08/05 17:17:26
nit: true /*from_false*/
battre
2013/08/06 15:54:39
I think this is a bug: You notify the observers he
Ken Rockot(use gerrit already)
2013/08/06 16:27:46
The pref has its new value at this point. This met
Ken Rockot(use gerrit already)
2013/08/06 20:18:32
Done.
| |
| 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) { | |
|
battre
2013/08/06 15:54:39
nit: align parameters.
Ken Rockot(use gerrit already)
2013/08/06 20:18:32
Done.
| |
| 524 SyncedPrefObserverMap::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 |