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/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/prefs/pref_service_syncable.h" | 15 #include "chrome/browser/prefs/pref_service_syncable.h" |
| 16 #include "chrome/common/chrome_notification_types.h" | 16 #include "chrome/common/chrome_notification_types.h" |
| 17 #include "chrome/common/pref_names.h" | 17 #include "chrome/common/pref_names.h" |
| 18 #include "sync/api/sync_change.h" | 18 #include "sync/api/sync_change.h" |
| 19 #include "sync/api/sync_error_factory.h" | 19 #include "sync/api/sync_error_factory.h" |
| 20 #include "sync/protocol/preference_specifics.pb.h" | 20 #include "sync/protocol/preference_specifics.pb.h" |
| 21 #include "sync/protocol/sync.pb.h" | 21 #include "sync/protocol/sync.pb.h" |
| 22 | 22 |
| 23 using syncer::PREFERENCES; | 23 using syncer::PREFERENCES; |
| 24 using syncer::PRIORITY_PREFERENCES; | |
| 24 | 25 |
| 25 PrefModelAssociator::PrefModelAssociator() | 26 PrefModelAssociator::PrefModelAssociator(syncer::ModelType type) |
| 26 : models_associated_(false), | 27 : models_associated_(false), |
| 27 processing_syncer_changes_(false), | 28 processing_syncer_changes_(false), |
| 28 pref_service_(NULL) { | 29 pref_service_(NULL), |
| 30 type_(type) { | |
| 29 DCHECK(CalledOnValidThread()); | 31 DCHECK(CalledOnValidThread()); |
| 32 DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); | |
| 30 } | 33 } |
| 31 | 34 |
| 32 PrefModelAssociator::~PrefModelAssociator() { | 35 PrefModelAssociator::~PrefModelAssociator() { |
| 33 DCHECK(CalledOnValidThread()); | 36 DCHECK(CalledOnValidThread()); |
| 34 pref_service_ = NULL; | 37 pref_service_ = NULL; |
| 35 } | 38 } |
| 36 | 39 |
| 37 void PrefModelAssociator::InitPrefAndAssociate( | 40 void PrefModelAssociator::InitPrefAndAssociate( |
| 38 const syncer::SyncData& sync_pref, | 41 const syncer::SyncData& sync_pref, |
| 39 const std::string& pref_name, | 42 const std::string& pref_name, |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 // the server is aware of. | 120 // the server is aware of. |
| 118 synced_preferences_.insert(pref_name); | 121 synced_preferences_.insert(pref_name); |
| 119 return; | 122 return; |
| 120 } | 123 } |
| 121 | 124 |
| 122 syncer::SyncMergeResult PrefModelAssociator::MergeDataAndStartSyncing( | 125 syncer::SyncMergeResult PrefModelAssociator::MergeDataAndStartSyncing( |
| 123 syncer::ModelType type, | 126 syncer::ModelType type, |
| 124 const syncer::SyncDataList& initial_sync_data, | 127 const syncer::SyncDataList& initial_sync_data, |
| 125 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, | 128 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, |
| 126 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { | 129 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { |
| 127 DCHECK_EQ(type, PREFERENCES); | 130 DCHECK_EQ(type_, type); |
| 128 DCHECK(CalledOnValidThread()); | 131 DCHECK(CalledOnValidThread()); |
| 129 DCHECK(pref_service_); | 132 DCHECK(pref_service_); |
| 130 DCHECK(!sync_processor_.get()); | 133 DCHECK(!sync_processor_.get()); |
| 131 DCHECK(sync_processor.get()); | 134 DCHECK(sync_processor.get()); |
| 132 DCHECK(sync_error_factory.get()); | 135 DCHECK(sync_error_factory.get()); |
| 133 syncer::SyncMergeResult merge_result(type); | 136 syncer::SyncMergeResult merge_result(type); |
| 134 sync_processor_ = sync_processor.Pass(); | 137 sync_processor_ = sync_processor.Pass(); |
| 135 sync_error_factory_ = sync_error_factory.Pass(); | 138 sync_error_factory_ = sync_error_factory.Pass(); |
| 136 | 139 |
| 137 syncer::SyncChangeList new_changes; | 140 syncer::SyncChangeList new_changes; |
| 138 std::set<std::string> remaining_preferences = registered_preferences_; | 141 std::set<std::string> remaining_preferences = registered_preferences_; |
| 139 | 142 |
| 140 // Go through and check for all preferences we care about that sync already | 143 // Go through and check for all preferences we care about that sync already |
| 141 // knows about. | 144 // knows about. |
| 142 for (syncer::SyncDataList::const_iterator sync_iter = | 145 for (syncer::SyncDataList::const_iterator sync_iter = |
| 143 initial_sync_data.begin(); | 146 initial_sync_data.begin(); |
| 144 sync_iter != initial_sync_data.end(); | 147 sync_iter != initial_sync_data.end(); |
| 145 ++sync_iter) { | 148 ++sync_iter) { |
| 146 DCHECK_EQ(PREFERENCES, sync_iter->GetDataType()); | 149 DCHECK_EQ(type_, sync_iter->GetDataType()); |
| 147 std::string sync_pref_name = sync_iter->GetSpecifics().preference().name(); | 150 std::string sync_pref_name = sync_iter->GetSpecifics().preference().name(); |
| 148 if (remaining_preferences.count(sync_pref_name) == 0) { | 151 if (remaining_preferences.count(sync_pref_name) == 0) { |
| 149 // We're not syncing this preference locally, ignore the sync data. | 152 // We're not syncing this preference locally, ignore the sync data. |
| 150 // TODO(zea): Eventually we want to be able to have the syncable service | 153 // TODO(zea): Eventually we want to be able to have the syncable service |
| 151 // reconstruct all sync data for it's datatype (therefore having | 154 // reconstruct all sync data for it's datatype (therefore having |
| 152 // GetAllSyncData be a complete representation). We should store this data | 155 // GetAllSyncData be a complete representation). We should store this data |
| 153 // somewhere, even if we don't use it. | 156 // somewhere, even if we don't use it. |
| 154 continue; | 157 continue; |
| 155 } | 158 } |
| 156 | 159 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 171 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); | 174 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); |
| 172 if (merge_result.error().IsSet()) | 175 if (merge_result.error().IsSet()) |
| 173 return merge_result; | 176 return merge_result; |
| 174 | 177 |
| 175 models_associated_ = true; | 178 models_associated_ = true; |
| 176 pref_service_->OnIsSyncingChanged(); | 179 pref_service_->OnIsSyncingChanged(); |
| 177 return merge_result; | 180 return merge_result; |
| 178 } | 181 } |
| 179 | 182 |
| 180 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { | 183 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { |
| 181 DCHECK_EQ(type, PREFERENCES); | 184 DCHECK_EQ(type_, type); |
| 182 models_associated_ = false; | 185 models_associated_ = false; |
| 183 sync_processor_.reset(); | 186 sync_processor_.reset(); |
| 184 sync_error_factory_.reset(); | 187 sync_error_factory_.reset(); |
| 185 pref_service_->OnIsSyncingChanged(); | 188 pref_service_->OnIsSyncingChanged(); |
| 186 } | 189 } |
| 187 | 190 |
| 188 scoped_ptr<Value> PrefModelAssociator::MergePreference( | 191 scoped_ptr<Value> PrefModelAssociator::MergePreference( |
| 189 const std::string& name, | 192 const std::string& name, |
| 190 const Value& local_value, | 193 const Value& local_value, |
| 191 const Value& server_value) { | 194 const Value& server_value) { |
| 192 if (name == prefs::kURLsToRestoreOnStartup) { | 195 if (name == prefs::kURLsToRestoreOnStartup) { |
| 193 return scoped_ptr<Value>(MergeListValues(local_value, server_value)).Pass(); | 196 return scoped_ptr<Value>(MergeListValues(local_value, server_value)).Pass(); |
| 194 } | 197 } |
| 195 | 198 |
| 196 if (name == prefs::kContentSettingsPatternPairs) { | 199 if (name == prefs::kContentSettingsPatternPairs) { |
| 197 return scoped_ptr<Value>( | 200 return scoped_ptr<Value>( |
| 198 MergeDictionaryValues(local_value, server_value)).Pass(); | 201 MergeDictionaryValues(local_value, server_value)).Pass(); |
| 199 } | 202 } |
| 200 | 203 |
| 201 // If this is not a specially handled preference, server wins. | 204 // If this is not a specially handled preference, server wins. |
| 202 return scoped_ptr<Value>(server_value.DeepCopy()).Pass(); | 205 return scoped_ptr<Value>(server_value.DeepCopy()).Pass(); |
| 203 } | 206 } |
| 204 | 207 |
| 205 bool PrefModelAssociator::CreatePrefSyncData( | 208 bool PrefModelAssociator::CreatePrefSyncData( |
| 206 const std::string& name, | 209 const std::string& name, |
| 207 const Value& value, | 210 const Value& value, |
| 208 syncer::SyncData* sync_data) { | 211 syncer::SyncData* sync_data) const { |
| 209 if (value.IsType(Value::TYPE_NULL)) { | 212 if (value.IsType(Value::TYPE_NULL)) { |
| 210 LOG(ERROR) << "Attempting to sync a null pref value for " << name; | 213 LOG(ERROR) << "Attempting to sync a null pref value for " << name; |
| 211 return false; | 214 return false; |
| 212 } | 215 } |
| 213 | 216 |
| 214 std::string serialized; | 217 std::string serialized; |
| 215 // TODO(zea): consider JSONWriter::Write since you don't have to check | 218 // TODO(zea): consider JSONWriter::Write since you don't have to check |
| 216 // failures to deserialize. | 219 // failures to deserialize. |
| 217 JSONStringValueSerializer json(&serialized); | 220 JSONStringValueSerializer json(&serialized); |
| 218 if (!json.Serialize(value)) { | 221 if (!json.Serialize(value)) { |
| 219 LOG(ERROR) << "Failed to serialize preference value."; | 222 LOG(ERROR) << "Failed to serialize preference value."; |
| 220 return false; | 223 return false; |
| 221 } | 224 } |
| 222 | 225 |
| 223 sync_pb::EntitySpecifics specifics; | 226 sync_pb::EntitySpecifics specifics; |
| 224 sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); | 227 sync_pb::PreferenceSpecifics* pref_specifics; |
| 228 | |
| 229 if (type_ == PREFERENCES) { | |
| 230 pref_specifics = specifics.mutable_preference(); | |
| 231 } else { | |
| 232 pref_specifics = | |
| 233 specifics.mutable_priority_preference()->mutable_preference(); | |
| 234 } | |
| 235 | |
| 225 pref_specifics->set_name(name); | 236 pref_specifics->set_name(name); |
| 226 pref_specifics->set_value(serialized); | 237 pref_specifics->set_value(serialized); |
| 238 | |
| 227 *sync_data = syncer::SyncData::CreateLocalData(name, name, specifics); | 239 *sync_data = syncer::SyncData::CreateLocalData(name, name, specifics); |
| 228 return true; | 240 return true; |
| 229 } | 241 } |
| 230 | 242 |
| 231 Value* PrefModelAssociator::MergeListValues(const Value& from_value, | 243 Value* PrefModelAssociator::MergeListValues(const Value& from_value, |
| 232 const Value& to_value) { | 244 const Value& to_value) { |
| 233 if (from_value.GetType() == Value::TYPE_NULL) | 245 if (from_value.GetType() == Value::TYPE_NULL) |
| 234 return to_value.DeepCopy(); | 246 return to_value.DeepCopy(); |
| 235 if (to_value.GetType() == Value::TYPE_NULL) | 247 if (to_value.GetType() == Value::TYPE_NULL) |
| 236 return from_value.DeepCopy(); | 248 return from_value.DeepCopy(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 286 return result; | 298 return result; |
| 287 } | 299 } |
| 288 | 300 |
| 289 // Note: This will build a model of all preferences registered as syncable | 301 // Note: This will build a model of all preferences registered as syncable |
| 290 // with user controlled data. We do not track any information for preferences | 302 // with user controlled data. We do not track any information for preferences |
| 291 // not registered locally as syncable and do not inform the syncer of | 303 // not registered locally as syncable and do not inform the syncer of |
| 292 // non-user controlled preferences. | 304 // non-user controlled preferences. |
| 293 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( | 305 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( |
| 294 syncer::ModelType type) | 306 syncer::ModelType type) |
| 295 const { | 307 const { |
| 296 DCHECK_EQ(PREFERENCES, type); | 308 DCHECK_EQ(type_, type); |
| 297 syncer::SyncDataList current_data; | 309 syncer::SyncDataList current_data; |
| 298 for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); | 310 for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); |
| 299 iter != synced_preferences_.end(); | 311 iter != synced_preferences_.end(); |
| 300 ++iter) { | 312 ++iter) { |
| 301 std::string name = *iter; | 313 std::string name = *iter; |
| 302 const PrefService::Preference* pref = | 314 const PrefService::Preference* pref = |
| 303 pref_service_->FindPreference(name.c_str()); | 315 pref_service_->FindPreference(name.c_str()); |
| 304 DCHECK(pref); | 316 DCHECK(pref); |
| 305 if (!pref->IsUserControlled() || pref->IsDefaultValue()) | 317 if (!pref->IsUserControlled() || pref->IsDefaultValue()) |
| 306 continue; // This is not data we care about. | 318 continue; // This is not data we care about. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 318 const syncer::SyncChangeList& change_list) { | 330 const syncer::SyncChangeList& change_list) { |
| 319 if (!models_associated_) { | 331 if (!models_associated_) { |
| 320 syncer::SyncError error(FROM_HERE, | 332 syncer::SyncError error(FROM_HERE, |
| 321 "Models not yet associated.", | 333 "Models not yet associated.", |
| 322 PREFERENCES); | 334 PREFERENCES); |
| 323 return error; | 335 return error; |
| 324 } | 336 } |
| 325 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 337 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); |
| 326 syncer::SyncChangeList::const_iterator iter; | 338 syncer::SyncChangeList::const_iterator iter; |
| 327 for (iter = change_list.begin(); iter != change_list.end(); ++iter) { | 339 for (iter = change_list.begin(); iter != change_list.end(); ++iter) { |
| 328 DCHECK_EQ(PREFERENCES, iter->sync_data().GetDataType()); | 340 DCHECK_EQ(type_, iter->sync_data().GetDataType()); |
| 329 | 341 |
| 330 std::string name; | 342 std::string name; |
| 331 sync_pb::PreferenceSpecifics pref_specifics = | 343 sync_pb::PreferenceSpecifics pref_specifics = |
|
Nicolas Zea
2013/02/21 23:41:11
nit:prefer an if/else here based on type
albertb
2013/02/22 20:08:47
Done.
| |
| 332 iter->sync_data().GetSpecifics().preference(); | 344 iter->sync_data().GetSpecifics().preference(); |
| 345 if (type_ == PRIORITY_PREFERENCES) { | |
| 346 pref_specifics = | |
| 347 iter->sync_data().GetSpecifics().priority_preference().preference(); | |
| 348 } | |
| 333 scoped_ptr<Value> value(ReadPreferenceSpecifics(pref_specifics, | 349 scoped_ptr<Value> value(ReadPreferenceSpecifics(pref_specifics, |
| 334 &name)); | 350 &name)); |
| 335 | 351 |
| 336 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { | 352 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { |
| 337 // We never delete preferences. | 353 // We never delete preferences. |
| 338 NOTREACHED() << "Attempted to process sync delete change for " << name | 354 NOTREACHED() << "Attempted to process sync delete change for " << name |
| 339 << ". Skipping."; | 355 << ". Skipping."; |
| 340 continue; | 356 continue; |
| 341 } | 357 } |
| 342 | 358 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 420 if (!preference->IsUserModifiable()) { | 436 if (!preference->IsUserModifiable()) { |
| 421 // If the preference is no longer user modifiable, it must now be controlled | 437 // If the preference is no longer user modifiable, it must now be controlled |
| 422 // by policy, whose values we do not sync. Just return. If the preference | 438 // by policy, whose values we do not sync. Just return. If the preference |
| 423 // stops being controlled by policy, it will revert back to the user value | 439 // stops being controlled by policy, it will revert back to the user value |
| 424 // (which we continue to update with sync changes). | 440 // (which we continue to update with sync changes). |
| 425 return; | 441 return; |
| 426 } | 442 } |
| 427 | 443 |
| 428 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 444 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); |
| 429 | 445 |
| 446 LOG(ERROR) << "synced pref(" << type_ << ") change: " << name; | |
|
Nicolas Zea
2013/02/21 23:41:11
did you mean to live this?
albertb
2013/02/22 20:08:47
Done.
| |
| 430 if (synced_preferences_.count(name) == 0) { | 447 if (synced_preferences_.count(name) == 0) { |
| 431 // Not in synced_preferences_ means no synced data. InitPrefAndAssociate(..) | 448 // Not in synced_preferences_ means no synced data. InitPrefAndAssociate(..) |
| 432 // will determine if we care about its data (e.g. if it has a default value | 449 // will determine if we care about its data (e.g. if it has a default value |
| 433 // and hasn't been changed yet we don't) and take care syncing any new data. | 450 // and hasn't been changed yet we don't) and take care syncing any new data. |
| 434 InitPrefAndAssociate(syncer::SyncData(), name, &changes); | 451 InitPrefAndAssociate(syncer::SyncData(), name, &changes); |
| 435 } else { | 452 } else { |
| 436 // We are already syncing this preference, just update it's sync node. | 453 // We are already syncing this preference, just update it's sync node. |
| 437 syncer::SyncData sync_data; | 454 syncer::SyncData sync_data; |
| 438 if (!CreatePrefSyncData(name, *preference->GetValue(), &sync_data)) { | 455 if (!CreatePrefSyncData(name, *preference->GetValue(), &sync_data)) { |
| 439 LOG(ERROR) << "Failed to update preference."; | 456 LOG(ERROR) << "Failed to update preference."; |
| 440 return; | 457 return; |
| 441 } | 458 } |
| 442 changes.push_back( | 459 changes.push_back( |
| 443 syncer::SyncChange(FROM_HERE, | 460 syncer::SyncChange(FROM_HERE, |
| 444 syncer::SyncChange::ACTION_UPDATE, | 461 syncer::SyncChange::ACTION_UPDATE, |
| 445 sync_data)); | 462 sync_data)); |
| 446 } | 463 } |
| 447 | 464 |
| 448 syncer::SyncError error = | 465 syncer::SyncError error = |
| 449 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 466 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
| 450 } | 467 } |
| 451 | 468 |
| 452 void PrefModelAssociator::SetPrefService(PrefServiceSyncable* pref_service) { | 469 void PrefModelAssociator::SetPrefService(PrefServiceSyncable* pref_service) { |
| 453 DCHECK(pref_service_ == NULL); | 470 DCHECK(pref_service_ == NULL); |
| 454 pref_service_ = pref_service; | 471 pref_service_ = pref_service; |
| 455 } | 472 } |
| OLD | NEW |