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/stl_util.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "base/values.h" | 15 #include "base/values.h" |
| 16 #include "chrome/browser/prefs/pref_model_associator_client.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 "components/content_settings/core/browser/website_settings_info.h" | |
| 19 #include "components/content_settings/core/browser/website_settings_registry.h" | |
| 20 #include "sync/api/sync_change.h" | 18 #include "sync/api/sync_change.h" |
| 21 #include "sync/api/sync_error_factory.h" | 19 #include "sync/api/sync_error_factory.h" |
| 22 #include "sync/protocol/preference_specifics.pb.h" | 20 #include "sync/protocol/preference_specifics.pb.h" |
| 23 #include "sync/protocol/sync.pb.h" | 21 #include "sync/protocol/sync.pb.h" |
| 24 | 22 |
| 25 using syncer::PREFERENCES; | 23 using syncer::PREFERENCES; |
| 26 using syncer::PRIORITY_PREFERENCES; | 24 using syncer::PRIORITY_PREFERENCES; |
| 27 | 25 |
| 28 namespace { | 26 namespace { |
| 29 | 27 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 48 return specifics->mutable_preference(); | 46 return specifics->mutable_preference(); |
| 49 } | 47 } |
| 50 } | 48 } |
| 51 | 49 |
| 52 } // namespace | 50 } // namespace |
| 53 | 51 |
| 54 PrefModelAssociator::PrefModelAssociator(syncer::ModelType type) | 52 PrefModelAssociator::PrefModelAssociator(syncer::ModelType type) |
| 55 : models_associated_(false), | 53 : models_associated_(false), |
| 56 processing_syncer_changes_(false), | 54 processing_syncer_changes_(false), |
| 57 pref_service_(NULL), | 55 pref_service_(NULL), |
| 58 type_(type) { | 56 type_(type), |
| 57 pref_model_associator_client_(NULL) { | |
| 59 DCHECK(CalledOnValidThread()); | 58 DCHECK(CalledOnValidThread()); |
| 60 DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); | 59 DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); |
| 61 } | 60 } |
| 62 | 61 |
| 63 PrefModelAssociator::~PrefModelAssociator() { | 62 PrefModelAssociator::~PrefModelAssociator() { |
| 64 DCHECK(CalledOnValidThread()); | 63 DCHECK(CalledOnValidThread()); |
| 65 pref_service_ = NULL; | 64 pref_service_ = NULL; |
| 66 | 65 |
| 67 STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), | 66 STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), |
| 68 synced_pref_observers_.end()); | 67 synced_pref_observers_.end()); |
| 69 synced_pref_observers_.clear(); | 68 synced_pref_observers_.clear(); |
| 70 } | 69 } |
| 71 | 70 |
| 72 void PrefModelAssociator::InitPrefAndAssociate( | 71 void PrefModelAssociator::InitPrefAndAssociate( |
| 73 const syncer::SyncData& sync_pref, | 72 const syncer::SyncData& sync_pref, |
| 74 const std::string& pref_name, | 73 const std::string& pref_name, |
| 75 syncer::SyncChangeList* sync_changes) { | 74 syncer::SyncChangeList* sync_changes) { |
| 76 const base::Value* user_pref_value = pref_service_->GetUserPrefValue( | 75 const base::Value* user_pref_value = |
| 77 pref_name.c_str()); | 76 pref_service_->GetUserPrefValue(pref_name.c_str()); |
| 78 VLOG(1) << "Associating preference " << pref_name; | 77 VLOG(1) << "Associating preference " << pref_name; |
| 79 | 78 |
| 80 if (sync_pref.IsValid()) { | 79 if (sync_pref.IsValid()) { |
| 81 const sync_pb::PreferenceSpecifics& preference = GetSpecifics(sync_pref); | 80 const sync_pb::PreferenceSpecifics& preference = GetSpecifics(sync_pref); |
| 82 DCHECK(pref_name == preference.name()); | 81 DCHECK(pref_name == preference.name()); |
| 83 base::JSONReader reader; | 82 base::JSONReader reader; |
| 84 scoped_ptr<base::Value> sync_value(reader.ReadToValue(preference.value())); | 83 scoped_ptr<base::Value> sync_value(reader.ReadToValue(preference.value())); |
| 85 if (!sync_value.get()) { | 84 if (!sync_value.get()) { |
| 86 LOG(ERROR) << "Failed to deserialize preference value: " | 85 LOG(ERROR) << "Failed to deserialize preference value: " |
| 87 << reader.GetErrorMessage(); | 86 << reader.GetErrorMessage(); |
| 88 return; | 87 return; |
| 89 } | 88 } |
| 90 | 89 |
| 91 if (user_pref_value) { | 90 if (user_pref_value) { |
| 92 DVLOG(1) << "Found user pref value for " << pref_name; | 91 DVLOG(1) << "Found user pref value for " << pref_name; |
| 93 // We have both server and local values. Merge them. | 92 // We have both server and local values. Merge them. |
| 94 scoped_ptr<base::Value> new_value( | 93 scoped_ptr<base::Value> new_value( |
| 95 MergePreference(pref_name, *user_pref_value, *sync_value)); | 94 MergePreference(pref_name, *user_pref_value, *sync_value, |
| 95 pref_model_associator_client_)); | |
| 96 | 96 |
| 97 // Update the local preference based on what we got from the | 97 // Update the local preference based on what we got from the |
| 98 // sync server. Note: this only updates the user value store, which is | 98 // sync server. Note: this only updates the user value store, which is |
| 99 // ignored if the preference is policy controlled. | 99 // ignored if the preference is policy controlled. |
| 100 if (new_value->IsType(base::Value::TYPE_NULL)) { | 100 if (new_value->IsType(base::Value::TYPE_NULL)) { |
| 101 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); | 101 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); |
| 102 pref_service_->ClearPref(pref_name.c_str()); | 102 pref_service_->ClearPref(pref_name.c_str()); |
| 103 } else if (!new_value->IsType(user_pref_value->GetType())) { | 103 } else if (!new_value->IsType(user_pref_value->GetType())) { |
| 104 LOG(WARNING) << "Synced value for " << preference.name() | 104 LOG(WARNING) << "Synced value for " << preference.name() |
| 105 << " is of type " << new_value->GetType() | 105 << " is of type " << new_value->GetType() |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 } | 210 } |
| 211 | 211 |
| 212 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { | 212 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { |
| 213 DCHECK_EQ(type_, type); | 213 DCHECK_EQ(type_, type); |
| 214 models_associated_ = false; | 214 models_associated_ = false; |
| 215 sync_processor_.reset(); | 215 sync_processor_.reset(); |
| 216 sync_error_factory_.reset(); | 216 sync_error_factory_.reset(); |
| 217 pref_service_->OnIsSyncingChanged(); | 217 pref_service_->OnIsSyncingChanged(); |
| 218 } | 218 } |
| 219 | 219 |
| 220 // static | |
| 220 scoped_ptr<base::Value> PrefModelAssociator::MergePreference( | 221 scoped_ptr<base::Value> PrefModelAssociator::MergePreference( |
| 221 const std::string& name, | 222 const std::string& name, |
| 222 const base::Value& local_value, | 223 const base::Value& local_value, |
| 223 const base::Value& server_value) { | 224 const base::Value& server_value, |
| 225 PrefModelAssociatorClient* pref_model_associator_client) { | |
|
gab
2015/09/10 14:15:09
Can we make this a member method and have it use |
| |
| 224 // This function special cases preferences individually, so don't attempt | 226 // This function special cases preferences individually, so don't attempt |
| 225 // to merge for all migrated values. | 227 // to merge for all migrated values. |
| 226 if (name == prefs::kURLsToRestoreOnStartup) | 228 PrefModelAssociatorPreferenceType pref_type; |
| 227 return make_scoped_ptr(MergeListValues(local_value, server_value)); | 229 if (pref_model_associator_client && |
| 228 | 230 pref_model_associator_client->IsPreferenceMerged(name, &pref_type)) { |
| 229 content_settings::WebsiteSettingsRegistry* registry = | 231 switch (pref_type) { |
| 230 content_settings::WebsiteSettingsRegistry::GetInstance(); | 232 case PREF_MODEL_PREFERENCE_TYPE_LIST: |
| 231 for (const content_settings::WebsiteSettingsInfo* info : *registry) { | 233 return make_scoped_ptr(MergeListValues(local_value, server_value)); |
| 232 if (info->pref_name() == name) | 234 case PREF_MODEL_PREFERENCE_TYPE_DICT: |
| 233 return make_scoped_ptr(MergeDictionaryValues(local_value, server_value)); | 235 return make_scoped_ptr( |
| 236 MergeDictionaryValues(local_value, server_value)); | |
| 237 } | |
| 234 } | 238 } |
| 235 | 239 |
| 236 // If this is not a specially handled preference, server wins. | 240 // If this is not a specially handled preference, server wins. |
| 237 return make_scoped_ptr(server_value.DeepCopy()); | 241 return make_scoped_ptr(server_value.DeepCopy()); |
| 238 } | 242 } |
| 239 | 243 |
| 240 bool PrefModelAssociator::CreatePrefSyncData( | 244 bool PrefModelAssociator::CreatePrefSyncData( |
| 241 const std::string& name, | 245 const std::string& name, |
| 242 const base::Value& value, | 246 const base::Value& value, |
| 243 syncer::SyncData* sync_data) const { | 247 syncer::SyncData* sync_data) const { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 } | 326 } |
| 323 } | 327 } |
| 324 return result; | 328 return result; |
| 325 } | 329 } |
| 326 | 330 |
| 327 // Note: This will build a model of all preferences registered as syncable | 331 // Note: This will build a model of all preferences registered as syncable |
| 328 // with user controlled data. We do not track any information for preferences | 332 // with user controlled data. We do not track any information for preferences |
| 329 // not registered locally as syncable and do not inform the syncer of | 333 // not registered locally as syncable and do not inform the syncer of |
| 330 // non-user controlled preferences. | 334 // non-user controlled preferences. |
| 331 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( | 335 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( |
| 332 syncer::ModelType type) | 336 syncer::ModelType type) const { |
| 333 const { | |
| 334 DCHECK_EQ(type_, type); | 337 DCHECK_EQ(type_, type); |
| 335 syncer::SyncDataList current_data; | 338 syncer::SyncDataList current_data; |
| 336 for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); | 339 for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); |
| 337 iter != synced_preferences_.end(); | 340 iter != synced_preferences_.end(); |
| 338 ++iter) { | 341 ++iter) { |
| 339 std::string name = *iter; | 342 std::string name = *iter; |
| 340 const PrefService::Preference* pref = | 343 const PrefService::Preference* pref = |
| 341 pref_service_->FindPreference(name.c_str()); | 344 pref_service_->FindPreference(name.c_str()); |
| 342 DCHECK(pref); | 345 DCHECK(pref); |
| 343 if (!pref->IsUserControlled() || pref->IsDefaultValue()) | 346 if (!pref->IsUserControlled() || pref->IsDefaultValue()) |
| 344 continue; // This is not data we care about. | 347 continue; // This is not data we care about. |
| 345 // TODO(zea): plumb a way to read the user controlled value. | 348 // TODO(zea): plumb a way to read the user controlled value. |
| 346 syncer::SyncData sync_data; | 349 syncer::SyncData sync_data; |
| 347 if (!CreatePrefSyncData(name, *pref->GetValue(), &sync_data)) | 350 if (!CreatePrefSyncData(name, *pref->GetValue(), &sync_data)) |
| 348 continue; | 351 continue; |
| 349 current_data.push_back(sync_data); | 352 current_data.push_back(sync_data); |
| 350 } | 353 } |
| 351 return current_data; | 354 return current_data; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 404 } | 407 } |
| 405 } | 408 } |
| 406 return syncer::SyncError(); | 409 return syncer::SyncError(); |
| 407 } | 410 } |
| 408 | 411 |
| 409 base::Value* PrefModelAssociator::ReadPreferenceSpecifics( | 412 base::Value* PrefModelAssociator::ReadPreferenceSpecifics( |
| 410 const sync_pb::PreferenceSpecifics& preference) { | 413 const sync_pb::PreferenceSpecifics& preference) { |
| 411 base::JSONReader reader; | 414 base::JSONReader reader; |
| 412 scoped_ptr<base::Value> value(reader.ReadToValue(preference.value())); | 415 scoped_ptr<base::Value> value(reader.ReadToValue(preference.value())); |
| 413 if (!value.get()) { | 416 if (!value.get()) { |
| 414 std::string err = "Failed to deserialize preference value: " + | 417 std::string err = |
| 415 reader.GetErrorMessage(); | 418 "Failed to deserialize preference value: " + reader.GetErrorMessage(); |
| 416 LOG(ERROR) << err; | 419 LOG(ERROR) << err; |
| 417 return NULL; | 420 return NULL; |
| 418 } | 421 } |
| 419 return value.release(); | 422 return value.release(); |
| 420 } | 423 } |
| 421 | 424 |
| 422 bool PrefModelAssociator::IsPrefSynced(const std::string& name) const { | 425 bool PrefModelAssociator::IsPrefSynced(const std::string& name) const { |
| 423 return synced_preferences_.find(name) != synced_preferences_.end(); | 426 return synced_preferences_.find(name) != synced_preferences_.end(); |
| 424 } | 427 } |
| 425 | 428 |
| 426 void PrefModelAssociator::AddSyncedPrefObserver(const std::string& name, | 429 void PrefModelAssociator::AddSyncedPrefObserver(const std::string& name, |
| 427 SyncedPrefObserver* observer) { | 430 SyncedPrefObserver* observer) { |
| 428 SyncedPrefObserverList* observers = synced_pref_observers_[name]; | 431 SyncedPrefObserverList* observers = synced_pref_observers_[name]; |
| 429 if (observers == NULL) { | 432 if (observers == NULL) { |
| 430 observers = new SyncedPrefObserverList; | 433 observers = new SyncedPrefObserverList; |
| 431 synced_pref_observers_[name] = observers; | 434 synced_pref_observers_[name] = observers; |
| 432 } | 435 } |
| 433 observers->AddObserver(observer); | 436 observers->AddObserver(observer); |
| 434 } | 437 } |
| 435 | 438 |
| 436 void PrefModelAssociator::RemoveSyncedPrefObserver(const std::string& name, | 439 void PrefModelAssociator::RemoveSyncedPrefObserver( |
| 440 const std::string& name, | |
| 437 SyncedPrefObserver* observer) { | 441 SyncedPrefObserver* observer) { |
| 438 SyncedPrefObserverMap::iterator observer_iter = | 442 SyncedPrefObserverMap::iterator observer_iter = |
| 439 synced_pref_observers_.find(name); | 443 synced_pref_observers_.find(name); |
| 440 if (observer_iter == synced_pref_observers_.end()) | 444 if (observer_iter == synced_pref_observers_.end()) |
| 441 return; | 445 return; |
| 442 SyncedPrefObserverList* observers = observer_iter->second; | 446 SyncedPrefObserverList* observers = observer_iter->second; |
| 443 observers->RemoveObserver(observer); | 447 observers->RemoveObserver(observer); |
| 444 } | 448 } |
| 445 | 449 |
| 446 std::set<std::string> PrefModelAssociator::registered_preferences() const { | 450 std::set<std::string> PrefModelAssociator::registered_preferences() const { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 516 void PrefModelAssociator::NotifySyncedPrefObservers(const std::string& path, | 520 void PrefModelAssociator::NotifySyncedPrefObservers(const std::string& path, |
| 517 bool from_sync) const { | 521 bool from_sync) const { |
| 518 SyncedPrefObserverMap::const_iterator observer_iter = | 522 SyncedPrefObserverMap::const_iterator observer_iter = |
| 519 synced_pref_observers_.find(path); | 523 synced_pref_observers_.find(path); |
| 520 if (observer_iter == synced_pref_observers_.end()) | 524 if (observer_iter == synced_pref_observers_.end()) |
| 521 return; | 525 return; |
| 522 SyncedPrefObserverList* observers = observer_iter->second; | 526 SyncedPrefObserverList* observers = observer_iter->second; |
| 523 FOR_EACH_OBSERVER(SyncedPrefObserver, *observers, | 527 FOR_EACH_OBSERVER(SyncedPrefObserver, *observers, |
| 524 OnSyncedPrefChanged(path, from_sync)); | 528 OnSyncedPrefChanged(path, from_sync)); |
| 525 } | 529 } |
| OLD | NEW |