| 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" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 sync_pb::EntitySpecifics* specifics) { | 42 sync_pb::EntitySpecifics* specifics) { |
| 43 if (type == syncer::PRIORITY_PREFERENCES) { | 43 if (type == syncer::PRIORITY_PREFERENCES) { |
| 44 DCHECK(!specifics->has_preference()); | 44 DCHECK(!specifics->has_preference()); |
| 45 return specifics->mutable_priority_preference()->mutable_preference(); | 45 return specifics->mutable_priority_preference()->mutable_preference(); |
| 46 } else { | 46 } else { |
| 47 DCHECK(!specifics->has_priority_preference()); | 47 DCHECK(!specifics->has_priority_preference()); |
| 48 return specifics->mutable_preference(); | 48 return specifics->mutable_preference(); |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 | 51 |
| 52 // List of migrated preference name pairs. If a preference is migrated | |
| 53 // (meaning renamed) adding the old and new preference names here will ensure | |
| 54 // that the sync engine knows how to deal with the synced values coming in | |
| 55 // with the old name. Preference migration itself doesn't happen here. It may | |
| 56 // happen in session_startup_pref.cc. | |
| 57 const struct MigratedPreferences { | |
| 58 const char* const old_name; | |
| 59 const char* const new_name; | |
| 60 } kMigratedPreferences[] = { | |
| 61 { prefs::kURLsToRestoreOnStartupOld, prefs::kURLsToRestoreOnStartup }, | |
| 62 }; | |
| 63 | |
| 64 std::string GetOldMigratedPreferenceName(const char* preference_name) { | |
| 65 for (size_t i = 0; i < arraysize(kMigratedPreferences); ++i) { | |
| 66 if (!strcmp(kMigratedPreferences[i].new_name, preference_name)) | |
| 67 return kMigratedPreferences[i].old_name; | |
| 68 } | |
| 69 return std::string(); | |
| 70 } | |
| 71 | |
| 72 std::string GetNewMigratedPreferenceName(const char* old_preference_name) { | |
| 73 for (size_t i = 0; i < arraysize(kMigratedPreferences); ++i) { | |
| 74 if (!strcmp(kMigratedPreferences[i].old_name, old_preference_name)) | |
| 75 return kMigratedPreferences[i].new_name; | |
| 76 } | |
| 77 return std::string(); | |
| 78 } | |
| 79 | |
| 80 } // namespace | 52 } // namespace |
| 81 | 53 |
| 82 PrefModelAssociator::PrefModelAssociator(syncer::ModelType type) | 54 PrefModelAssociator::PrefModelAssociator(syncer::ModelType type) |
| 83 : models_associated_(false), | 55 : models_associated_(false), |
| 84 processing_syncer_changes_(false), | 56 processing_syncer_changes_(false), |
| 85 pref_service_(NULL), | 57 pref_service_(NULL), |
| 86 type_(type) { | 58 type_(type) { |
| 87 DCHECK(CalledOnValidThread()); | 59 DCHECK(CalledOnValidThread()); |
| 88 DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); | 60 DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); |
| 89 } | 61 } |
| 90 | 62 |
| 91 PrefModelAssociator::~PrefModelAssociator() { | 63 PrefModelAssociator::~PrefModelAssociator() { |
| 92 DCHECK(CalledOnValidThread()); | 64 DCHECK(CalledOnValidThread()); |
| 93 pref_service_ = NULL; | 65 pref_service_ = NULL; |
| 94 | 66 |
| 95 STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), | 67 STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), |
| 96 synced_pref_observers_.end()); | 68 synced_pref_observers_.end()); |
| 97 synced_pref_observers_.clear(); | 69 synced_pref_observers_.clear(); |
| 98 } | 70 } |
| 99 | 71 |
| 100 void PrefModelAssociator::InitPrefAndAssociate( | 72 void PrefModelAssociator::InitPrefAndAssociate( |
| 101 const syncer::SyncData& sync_pref, | 73 const syncer::SyncData& sync_pref, |
| 102 const std::string& pref_name, | 74 const std::string& pref_name, |
| 103 syncer::SyncChangeList* sync_changes, | 75 syncer::SyncChangeList* sync_changes) { |
| 104 SyncDataMap* migrated_preference_list) { | |
| 105 const base::Value* user_pref_value = pref_service_->GetUserPrefValue( | 76 const base::Value* user_pref_value = pref_service_->GetUserPrefValue( |
| 106 pref_name.c_str()); | 77 pref_name.c_str()); |
| 107 VLOG(1) << "Associating preference " << pref_name; | 78 VLOG(1) << "Associating preference " << pref_name; |
| 108 | 79 |
| 109 if (sync_pref.IsValid()) { | 80 if (sync_pref.IsValid()) { |
| 110 const sync_pb::PreferenceSpecifics& preference = GetSpecifics(sync_pref); | 81 const sync_pb::PreferenceSpecifics& preference = GetSpecifics(sync_pref); |
| 111 DCHECK(pref_name == preference.name() || | 82 DCHECK(pref_name == preference.name()); |
| 112 (IsMigratedPreference(pref_name.c_str()) && | |
| 113 preference.name() == | |
| 114 GetOldMigratedPreferenceName(pref_name.c_str()))); | |
| 115 base::JSONReader reader; | 83 base::JSONReader reader; |
| 116 scoped_ptr<base::Value> sync_value(reader.ReadToValue(preference.value())); | 84 scoped_ptr<base::Value> sync_value(reader.ReadToValue(preference.value())); |
| 117 if (!sync_value.get()) { | 85 if (!sync_value.get()) { |
| 118 LOG(ERROR) << "Failed to deserialize preference value: " | 86 LOG(ERROR) << "Failed to deserialize preference value: " |
| 119 << reader.GetErrorMessage(); | 87 << reader.GetErrorMessage(); |
| 120 return; | 88 return; |
| 121 } | 89 } |
| 122 | 90 |
| 123 if (user_pref_value) { | 91 if (user_pref_value) { |
| 124 DVLOG(1) << "Found user pref value for " << pref_name; | 92 DVLOG(1) << "Found user pref value for " << pref_name; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 141 pref_service_->Set(pref_name.c_str(), *new_value); | 109 pref_service_->Set(pref_name.c_str(), *new_value); |
| 142 } | 110 } |
| 143 | 111 |
| 144 // If the merge resulted in an updated value, inform the syncer. | 112 // If the merge resulted in an updated value, inform the syncer. |
| 145 if (!sync_value->Equals(new_value.get())) { | 113 if (!sync_value->Equals(new_value.get())) { |
| 146 syncer::SyncData sync_data; | 114 syncer::SyncData sync_data; |
| 147 if (!CreatePrefSyncData(pref_name, *new_value, &sync_data)) { | 115 if (!CreatePrefSyncData(pref_name, *new_value, &sync_data)) { |
| 148 LOG(ERROR) << "Failed to update preference."; | 116 LOG(ERROR) << "Failed to update preference."; |
| 149 return; | 117 return; |
| 150 } | 118 } |
| 151 | |
| 152 if (IsMigratedPreference(pref_name.c_str())) { | |
| 153 // This preference has been migrated from an old version that must be | |
| 154 // kept in sync on older versions of Chrome. | |
| 155 std::string old_pref_name = | |
| 156 GetOldMigratedPreferenceName(pref_name.c_str()); | |
| 157 | |
| 158 if (preference.name() == old_pref_name) { | |
| 159 DCHECK(migrated_preference_list); | |
| 160 // If the name the syncer has is the old pre-migration value, then | |
| 161 // it's possible the new migrated preference name hasn't been synced | |
| 162 // yet. In that case the SyncChange should be an ACTION_ADD rather | |
| 163 // than an ACTION_UPDATE. Defer the decision of whether to sync with | |
| 164 // ACTION_ADD or ACTION_UPDATE until the migrated_preferences phase. | |
| 165 if (migrated_preference_list) | |
| 166 (*migrated_preference_list)[pref_name] = sync_data; | |
| 167 } else { | |
| 168 DCHECK_EQ(preference.name(), pref_name); | |
| 169 sync_changes->push_back( | |
| 170 syncer::SyncChange(FROM_HERE, | |
| 171 syncer::SyncChange::ACTION_UPDATE, | |
| 172 sync_data)); | |
| 173 } | |
| 174 | |
| 175 syncer::SyncData old_sync_data; | |
| 176 if (!CreatePrefSyncData(old_pref_name, *new_value, &old_sync_data)) { | |
| 177 LOG(ERROR) << "Failed to update preference."; | |
| 178 return; | |
| 179 } | |
| 180 if (migrated_preference_list) | |
| 181 (*migrated_preference_list)[old_pref_name] = old_sync_data; | |
| 182 } else { | |
| 183 sync_changes->push_back( | |
| 184 syncer::SyncChange(FROM_HERE, | |
| 185 syncer::SyncChange::ACTION_UPDATE, | |
| 186 sync_data)); | |
| 187 } | |
| 188 } | 119 } |
| 189 } else if (!sync_value->IsType(base::Value::TYPE_NULL)) { | 120 } else if (!sync_value->IsType(base::Value::TYPE_NULL)) { |
| 190 // Only a server value exists. Just set the local user value. | 121 // Only a server value exists. Just set the local user value. |
| 191 pref_service_->Set(pref_name.c_str(), *sync_value); | 122 pref_service_->Set(pref_name.c_str(), *sync_value); |
| 192 } else { | 123 } else { |
| 193 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); | 124 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); |
| 194 } | 125 } |
| 195 synced_preferences_.insert(preference.name()); | 126 synced_preferences_.insert(preference.name()); |
| 196 } else if (user_pref_value) { | 127 } else if (user_pref_value) { |
| 197 // The server does not know about this preference and should be added | 128 // The server does not know about this preference and should be added |
| (...skipping 27 matching lines...) Expand all Loading... |
| 225 DCHECK(!sync_processor_.get()); | 156 DCHECK(!sync_processor_.get()); |
| 226 DCHECK(sync_processor.get()); | 157 DCHECK(sync_processor.get()); |
| 227 DCHECK(sync_error_factory.get()); | 158 DCHECK(sync_error_factory.get()); |
| 228 syncer::SyncMergeResult merge_result(type); | 159 syncer::SyncMergeResult merge_result(type); |
| 229 sync_processor_ = sync_processor.Pass(); | 160 sync_processor_ = sync_processor.Pass(); |
| 230 sync_error_factory_ = sync_error_factory.Pass(); | 161 sync_error_factory_ = sync_error_factory.Pass(); |
| 231 | 162 |
| 232 syncer::SyncChangeList new_changes; | 163 syncer::SyncChangeList new_changes; |
| 233 std::set<std::string> remaining_preferences = registered_preferences_; | 164 std::set<std::string> remaining_preferences = registered_preferences_; |
| 234 | 165 |
| 235 // Maintains a list of old migrated preference names that we wish to sync. | |
| 236 // Keep track of these in a list such that when the preference iteration | |
| 237 // loops below are complete we can go back and determine whether | |
| 238 SyncDataMap migrated_preference_list; | |
| 239 | |
| 240 // Go through and check for all preferences we care about that sync already | 166 // Go through and check for all preferences we care about that sync already |
| 241 // knows about. | 167 // knows about. |
| 242 for (syncer::SyncDataList::const_iterator sync_iter = | 168 for (syncer::SyncDataList::const_iterator sync_iter = |
| 243 initial_sync_data.begin(); | 169 initial_sync_data.begin(); |
| 244 sync_iter != initial_sync_data.end(); | 170 sync_iter != initial_sync_data.end(); |
| 245 ++sync_iter) { | 171 ++sync_iter) { |
| 246 DCHECK_EQ(type_, sync_iter->GetDataType()); | 172 DCHECK_EQ(type_, sync_iter->GetDataType()); |
| 247 | 173 |
| 248 const sync_pb::PreferenceSpecifics& preference = GetSpecifics(*sync_iter); | 174 const sync_pb::PreferenceSpecifics& preference = GetSpecifics(*sync_iter); |
| 249 std::string sync_pref_name = preference.name(); | 175 std::string sync_pref_name = preference.name(); |
| 250 | 176 |
| 251 if (remaining_preferences.count(sync_pref_name) == 0) { | 177 if (remaining_preferences.count(sync_pref_name) == 0) { |
| 252 if (IsOldMigratedPreference(sync_pref_name.c_str())) { | 178 // We're not syncing this preference locally, ignore the sync data. |
| 253 // This old pref name is not syncable locally anymore but we accept | 179 // TODO(zea): Eventually we want to be able to have the syncable service |
| 254 // changes from other Chrome installs of previous versions and migrate | 180 // reconstruct all sync data for its datatype (therefore having |
| 255 // them to the new name. Note that we will be merging any differences | 181 // GetAllSyncData be a complete representation). We should store this |
| 256 // between the new and old values and sync'ing them back. | 182 // data somewhere, even if we don't use it. |
| 257 sync_pref_name = GetNewMigratedPreferenceName(sync_pref_name.c_str()); | 183 continue; |
| 258 } else { | |
| 259 // We're not syncing this preference locally, ignore the sync data. | |
| 260 // TODO(zea): Eventually we want to be able to have the syncable service | |
| 261 // reconstruct all sync data for its datatype (therefore having | |
| 262 // GetAllSyncData be a complete representation). We should store this | |
| 263 // data somewhere, even if we don't use it. | |
| 264 continue; | |
| 265 } | |
| 266 } else { | 184 } else { |
| 267 remaining_preferences.erase(sync_pref_name); | 185 remaining_preferences.erase(sync_pref_name); |
| 268 } | 186 } |
| 269 InitPrefAndAssociate(*sync_iter, sync_pref_name, &new_changes, | 187 InitPrefAndAssociate(*sync_iter, sync_pref_name, &new_changes); |
| 270 &migrated_preference_list); | |
| 271 } | 188 } |
| 272 | 189 |
| 273 // Go through and build sync data for any remaining preferences. | 190 // Go through and build sync data for any remaining preferences. |
| 274 for (std::set<std::string>::iterator pref_name_iter = | 191 for (std::set<std::string>::iterator pref_name_iter = |
| 275 remaining_preferences.begin(); | 192 remaining_preferences.begin(); |
| 276 pref_name_iter != remaining_preferences.end(); | 193 pref_name_iter != remaining_preferences.end(); |
| 277 ++pref_name_iter) { | 194 ++pref_name_iter) { |
| 278 InitPrefAndAssociate(syncer::SyncData(), *pref_name_iter, &new_changes, | 195 InitPrefAndAssociate(syncer::SyncData(), *pref_name_iter, &new_changes); |
| 279 &migrated_preference_list); | |
| 280 } | |
| 281 | |
| 282 // Now go over any migrated preference names and build sync data for them too. | |
| 283 for (SyncDataMap::const_iterator migrated_pref_iter = | |
| 284 migrated_preference_list.begin(); | |
| 285 migrated_pref_iter != migrated_preference_list.end(); | |
| 286 ++migrated_pref_iter) { | |
| 287 syncer::SyncChange::SyncChangeType change_type = | |
| 288 (synced_preferences_.count(migrated_pref_iter->first) == 0) ? | |
| 289 syncer::SyncChange::ACTION_ADD : | |
| 290 syncer::SyncChange::ACTION_UPDATE; | |
| 291 new_changes.push_back( | |
| 292 syncer::SyncChange(FROM_HERE, change_type, migrated_pref_iter->second)); | |
| 293 synced_preferences_.insert(migrated_pref_iter->first); | |
| 294 } | 196 } |
| 295 | 197 |
| 296 // Push updates to sync. | 198 // Push updates to sync. |
| 297 merge_result.set_error( | 199 merge_result.set_error( |
| 298 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); | 200 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); |
| 299 if (merge_result.error().IsSet()) | 201 if (merge_result.error().IsSet()) |
| 300 return merge_result; | 202 return merge_result; |
| 301 | 203 |
| 302 models_associated_ = true; | 204 models_associated_ = true; |
| 303 pref_service_->OnIsSyncingChanged(); | 205 pref_service_->OnIsSyncingChanged(); |
| 304 return merge_result; | 206 return merge_result; |
| 305 } | 207 } |
| 306 | 208 |
| 307 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { | 209 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { |
| 308 DCHECK_EQ(type_, type); | 210 DCHECK_EQ(type_, type); |
| 309 models_associated_ = false; | 211 models_associated_ = false; |
| 310 sync_processor_.reset(); | 212 sync_processor_.reset(); |
| 311 sync_error_factory_.reset(); | 213 sync_error_factory_.reset(); |
| 312 pref_service_->OnIsSyncingChanged(); | 214 pref_service_->OnIsSyncingChanged(); |
| 313 } | 215 } |
| 314 | 216 |
| 315 scoped_ptr<base::Value> PrefModelAssociator::MergePreference( | 217 scoped_ptr<base::Value> PrefModelAssociator::MergePreference( |
| 316 const std::string& name, | 218 const std::string& name, |
| 317 const base::Value& local_value, | 219 const base::Value& local_value, |
| 318 const base::Value& server_value) { | 220 const base::Value& server_value) { |
| 319 // This function special cases preferences individually, so don't attempt | 221 if (name == prefs::kURLsToRestoreOnStartup) { |
| 320 // to merge for all migrated values. | |
| 321 if (name == prefs::kURLsToRestoreOnStartup || | |
| 322 name == prefs::kURLsToRestoreOnStartupOld) { | |
| 323 return make_scoped_ptr(MergeListValues(local_value, server_value)); | 222 return make_scoped_ptr(MergeListValues(local_value, server_value)); |
| 324 } | 223 } |
| 325 | 224 |
| 326 content_settings::WebsiteSettingsRegistry* registry = | 225 content_settings::WebsiteSettingsRegistry* registry = |
| 327 content_settings::WebsiteSettingsRegistry::GetInstance(); | 226 content_settings::WebsiteSettingsRegistry::GetInstance(); |
| 328 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | 227 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { |
| 329 ContentSettingsType type = static_cast<ContentSettingsType>(i); | 228 ContentSettingsType type = static_cast<ContentSettingsType>(i); |
| 330 if (registry->Get(type)->pref_name() == name) | 229 if (registry->Get(type)->pref_name() == name) |
| 331 return make_scoped_ptr(MergeDictionaryValues(local_value, server_value)); | 230 return make_scoped_ptr(MergeDictionaryValues(local_value, server_value)); |
| 332 } | 231 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 } | 314 } |
| 416 // Note that for all other types we want to preserve the "to" | 315 // Note that for all other types we want to preserve the "to" |
| 417 // values so we do nothing here. | 316 // values so we do nothing here. |
| 418 } else { | 317 } else { |
| 419 result->SetWithoutPathExpansion(it.key(), from_key_value->DeepCopy()); | 318 result->SetWithoutPathExpansion(it.key(), from_key_value->DeepCopy()); |
| 420 } | 319 } |
| 421 } | 320 } |
| 422 return result; | 321 return result; |
| 423 } | 322 } |
| 424 | 323 |
| 425 // static | |
| 426 bool PrefModelAssociator::IsMigratedPreference(const char* preference_name) { | |
| 427 return !GetOldMigratedPreferenceName(preference_name).empty(); | |
| 428 } | |
| 429 | |
| 430 // static | |
| 431 bool PrefModelAssociator::IsOldMigratedPreference( | |
| 432 const char* old_preference_name) { | |
| 433 return !GetNewMigratedPreferenceName(old_preference_name).empty(); | |
| 434 } | |
| 435 | |
| 436 // Note: This will build a model of all preferences registered as syncable | 324 // Note: This will build a model of all preferences registered as syncable |
| 437 // with user controlled data. We do not track any information for preferences | 325 // with user controlled data. We do not track any information for preferences |
| 438 // not registered locally as syncable and do not inform the syncer of | 326 // not registered locally as syncable and do not inform the syncer of |
| 439 // non-user controlled preferences. | 327 // non-user controlled preferences. |
| 440 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( | 328 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( |
| 441 syncer::ModelType type) | 329 syncer::ModelType type) |
| 442 const { | 330 const { |
| 443 DCHECK_EQ(type_, type); | 331 DCHECK_EQ(type_, type); |
| 444 syncer::SyncDataList current_data; | 332 syncer::SyncDataList current_data; |
| 445 for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); | 333 for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 | 365 |
| 478 const sync_pb::PreferenceSpecifics& pref_specifics = | 366 const sync_pb::PreferenceSpecifics& pref_specifics = |
| 479 GetSpecifics(iter->sync_data()); | 367 GetSpecifics(iter->sync_data()); |
| 480 | 368 |
| 481 std::string name = pref_specifics.name(); | 369 std::string name = pref_specifics.name(); |
| 482 // It is possible that we may receive a change to a preference we do not | 370 // It is possible that we may receive a change to a preference we do not |
| 483 // want to sync. For example if the user is syncing a Mac client and a | 371 // want to sync. For example if the user is syncing a Mac client and a |
| 484 // Windows client, the Windows client does not support | 372 // Windows client, the Windows client does not support |
| 485 // kConfirmToQuitEnabled. Ignore updates from these preferences. | 373 // kConfirmToQuitEnabled. Ignore updates from these preferences. |
| 486 const char* pref_name = name.c_str(); | 374 const char* pref_name = name.c_str(); |
| 487 std::string new_name; | |
| 488 // We migrated this preference name, so do as if the name had not changed. | |
| 489 if (IsOldMigratedPreference(pref_name)) { | |
| 490 new_name = GetNewMigratedPreferenceName(pref_name); | |
| 491 pref_name = new_name.c_str(); | |
| 492 } | |
| 493 | |
| 494 if (!IsPrefRegistered(pref_name)) | 375 if (!IsPrefRegistered(pref_name)) |
| 495 continue; | 376 continue; |
| 496 | 377 |
| 497 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { | 378 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { |
| 498 pref_service_->ClearPref(pref_name); | 379 pref_service_->ClearPref(pref_name); |
| 499 continue; | 380 continue; |
| 500 } | 381 } |
| 501 | 382 |
| 502 scoped_ptr<base::Value> value(ReadPreferenceSpecifics(pref_specifics)); | 383 scoped_ptr<base::Value> value(ReadPreferenceSpecifics(pref_specifics)); |
| 503 if (!value.get()) { | 384 if (!value.get()) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 } | 480 } |
| 600 | 481 |
| 601 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 482 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); |
| 602 | 483 |
| 603 NotifySyncedPrefObservers(name, false /*from_sync*/); | 484 NotifySyncedPrefObservers(name, false /*from_sync*/); |
| 604 | 485 |
| 605 if (synced_preferences_.count(name) == 0) { | 486 if (synced_preferences_.count(name) == 0) { |
| 606 // Not in synced_preferences_ means no synced data. InitPrefAndAssociate(..) | 487 // Not in synced_preferences_ means no synced data. InitPrefAndAssociate(..) |
| 607 // will determine if we care about its data (e.g. if it has a default value | 488 // will determine if we care about its data (e.g. if it has a default value |
| 608 // and hasn't been changed yet we don't) and take care syncing any new data. | 489 // and hasn't been changed yet we don't) and take care syncing any new data. |
| 609 InitPrefAndAssociate(syncer::SyncData(), name, &changes, NULL); | 490 InitPrefAndAssociate(syncer::SyncData(), name, &changes); |
| 610 } else { | 491 } else { |
| 611 // We are already syncing this preference, just update it's sync node. | 492 // We are already syncing this preference, just update it's sync node. |
| 612 syncer::SyncData sync_data; | 493 syncer::SyncData sync_data; |
| 613 if (!CreatePrefSyncData(name, *preference->GetValue(), &sync_data)) { | 494 if (!CreatePrefSyncData(name, *preference->GetValue(), &sync_data)) { |
| 614 LOG(ERROR) << "Failed to update preference."; | 495 LOG(ERROR) << "Failed to update preference."; |
| 615 return; | 496 return; |
| 616 } | 497 } |
| 617 changes.push_back( | 498 changes.push_back( |
| 618 syncer::SyncChange(FROM_HERE, | 499 syncer::SyncChange(FROM_HERE, |
| 619 syncer::SyncChange::ACTION_UPDATE, | 500 syncer::SyncChange::ACTION_UPDATE, |
| 620 sync_data)); | 501 sync_data)); |
| 621 // This preference has been migrated from an old version that must be kept | |
| 622 // in sync on older versions of Chrome. | |
| 623 if (IsMigratedPreference(name.c_str())) { | |
| 624 std::string old_pref_name = GetOldMigratedPreferenceName(name.c_str()); | |
| 625 if (!CreatePrefSyncData(old_pref_name, | |
| 626 *preference->GetValue(), | |
| 627 &sync_data)) { | |
| 628 LOG(ERROR) << "Failed to update preference."; | |
| 629 return; | |
| 630 } | |
| 631 | |
| 632 syncer::SyncChange::SyncChangeType change_type = | |
| 633 (synced_preferences_.count(old_pref_name) == 0) ? | |
| 634 syncer::SyncChange::ACTION_ADD : | |
| 635 syncer::SyncChange::ACTION_UPDATE; | |
| 636 changes.push_back( | |
| 637 syncer::SyncChange(FROM_HERE, change_type, sync_data)); | |
| 638 } | |
| 639 } | 502 } |
| 640 | 503 |
| 641 syncer::SyncError error = | 504 syncer::SyncError error = |
| 642 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 505 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
| 643 } | 506 } |
| 644 | 507 |
| 645 void PrefModelAssociator::SetPrefService(PrefServiceSyncable* pref_service) { | 508 void PrefModelAssociator::SetPrefService(PrefServiceSyncable* pref_service) { |
| 646 DCHECK(pref_service_ == NULL); | 509 DCHECK(pref_service_ == NULL); |
| 647 pref_service_ = pref_service; | 510 pref_service_ = pref_service; |
| 648 } | 511 } |
| 649 | 512 |
| 650 void PrefModelAssociator::NotifySyncedPrefObservers(const std::string& path, | 513 void PrefModelAssociator::NotifySyncedPrefObservers(const std::string& path, |
| 651 bool from_sync) const { | 514 bool from_sync) const { |
| 652 SyncedPrefObserverMap::const_iterator observer_iter = | 515 SyncedPrefObserverMap::const_iterator observer_iter = |
| 653 synced_pref_observers_.find(path); | 516 synced_pref_observers_.find(path); |
| 654 if (observer_iter == synced_pref_observers_.end()) | 517 if (observer_iter == synced_pref_observers_.end()) |
| 655 return; | 518 return; |
| 656 SyncedPrefObserverList* observers = observer_iter->second; | 519 SyncedPrefObserverList* observers = observer_iter->second; |
| 657 FOR_EACH_OBSERVER(SyncedPrefObserver, *observers, | 520 FOR_EACH_OBSERVER(SyncedPrefObserver, *observers, |
| 658 OnSyncedPrefChanged(path, from_sync)); | 521 OnSyncedPrefChanged(path, from_sync)); |
| 659 } | 522 } |
| OLD | NEW |