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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), | 94 STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), |
95 synced_pref_observers_.end()); | 95 synced_pref_observers_.end()); |
96 synced_pref_observers_.clear(); | 96 synced_pref_observers_.clear(); |
97 } | 97 } |
98 | 98 |
99 void PrefModelAssociator::InitPrefAndAssociate( | 99 void PrefModelAssociator::InitPrefAndAssociate( |
100 const syncer::SyncData& sync_pref, | 100 const syncer::SyncData& sync_pref, |
101 const std::string& pref_name, | 101 const std::string& pref_name, |
102 syncer::SyncChangeList* sync_changes, | 102 syncer::SyncChangeList* sync_changes, |
103 SyncDataMap* migrated_preference_list) { | 103 SyncDataMap* migrated_preference_list) { |
104 const Value* user_pref_value = pref_service_->GetUserPrefValue( | 104 const base::Value* user_pref_value = pref_service_->GetUserPrefValue( |
105 pref_name.c_str()); | 105 pref_name.c_str()); |
106 VLOG(1) << "Associating preference " << pref_name; | 106 VLOG(1) << "Associating preference " << pref_name; |
107 | 107 |
108 if (sync_pref.IsValid()) { | 108 if (sync_pref.IsValid()) { |
109 const sync_pb::PreferenceSpecifics& preference = GetSpecifics(sync_pref); | 109 const sync_pb::PreferenceSpecifics& preference = GetSpecifics(sync_pref); |
110 DCHECK(pref_name == preference.name() || | 110 DCHECK(pref_name == preference.name() || |
111 (IsMigratedPreference(pref_name.c_str()) && | 111 (IsMigratedPreference(pref_name.c_str()) && |
112 preference.name() == | 112 preference.name() == |
113 GetOldMigratedPreferenceName(pref_name.c_str()))); | 113 GetOldMigratedPreferenceName(pref_name.c_str()))); |
114 base::JSONReader reader; | 114 base::JSONReader reader; |
115 scoped_ptr<Value> sync_value(reader.ReadToValue(preference.value())); | 115 scoped_ptr<base::Value> sync_value(reader.ReadToValue(preference.value())); |
116 if (!sync_value.get()) { | 116 if (!sync_value.get()) { |
117 LOG(ERROR) << "Failed to deserialize preference value: " | 117 LOG(ERROR) << "Failed to deserialize preference value: " |
118 << reader.GetErrorMessage(); | 118 << reader.GetErrorMessage(); |
119 return; | 119 return; |
120 } | 120 } |
121 | 121 |
122 if (user_pref_value) { | 122 if (user_pref_value) { |
123 DVLOG(1) << "Found user pref value for " << pref_name; | 123 DVLOG(1) << "Found user pref value for " << pref_name; |
124 // We have both server and local values. Merge them. | 124 // We have both server and local values. Merge them. |
125 scoped_ptr<Value> new_value( | 125 scoped_ptr<base::Value> new_value( |
126 MergePreference(pref_name, *user_pref_value, *sync_value)); | 126 MergePreference(pref_name, *user_pref_value, *sync_value)); |
127 | 127 |
128 // Update the local preference based on what we got from the | 128 // Update the local preference based on what we got from the |
129 // sync server. Note: this only updates the user value store, which is | 129 // sync server. Note: this only updates the user value store, which is |
130 // ignored if the preference is policy controlled. | 130 // ignored if the preference is policy controlled. |
131 if (new_value->IsType(Value::TYPE_NULL)) { | 131 if (new_value->IsType(base::Value::TYPE_NULL)) { |
132 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); | 132 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); |
133 pref_service_->ClearPref(pref_name.c_str()); | 133 pref_service_->ClearPref(pref_name.c_str()); |
134 } else if (!new_value->IsType(user_pref_value->GetType())) { | 134 } else if (!new_value->IsType(user_pref_value->GetType())) { |
135 LOG(WARNING) << "Synced value for " << preference.name() | 135 LOG(WARNING) << "Synced value for " << preference.name() |
136 << " is of type " << new_value->GetType() | 136 << " is of type " << new_value->GetType() |
137 << " which doesn't match pref type " | 137 << " which doesn't match pref type " |
138 << user_pref_value->GetType(); | 138 << user_pref_value->GetType(); |
139 } else if (!user_pref_value->Equals(new_value.get())) { | 139 } else if (!user_pref_value->Equals(new_value.get())) { |
140 pref_service_->Set(pref_name.c_str(), *new_value); | 140 pref_service_->Set(pref_name.c_str(), *new_value); |
141 } | 141 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 } | 178 } |
179 if (migrated_preference_list) | 179 if (migrated_preference_list) |
180 (*migrated_preference_list)[old_pref_name] = old_sync_data; | 180 (*migrated_preference_list)[old_pref_name] = old_sync_data; |
181 } else { | 181 } else { |
182 sync_changes->push_back( | 182 sync_changes->push_back( |
183 syncer::SyncChange(FROM_HERE, | 183 syncer::SyncChange(FROM_HERE, |
184 syncer::SyncChange::ACTION_UPDATE, | 184 syncer::SyncChange::ACTION_UPDATE, |
185 sync_data)); | 185 sync_data)); |
186 } | 186 } |
187 } | 187 } |
188 } else if (!sync_value->IsType(Value::TYPE_NULL)) { | 188 } else if (!sync_value->IsType(base::Value::TYPE_NULL)) { |
189 // Only a server value exists. Just set the local user value. | 189 // Only a server value exists. Just set the local user value. |
190 pref_service_->Set(pref_name.c_str(), *sync_value); | 190 pref_service_->Set(pref_name.c_str(), *sync_value); |
191 } else { | 191 } else { |
192 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); | 192 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); |
193 } | 193 } |
194 synced_preferences_.insert(preference.name()); | 194 synced_preferences_.insert(preference.name()); |
195 } else if (user_pref_value) { | 195 } else if (user_pref_value) { |
196 // The server does not know about this preference and should be added | 196 // The server does not know about this preference and should be added |
197 // to the syncer's database. | 197 // to the syncer's database. |
198 syncer::SyncData sync_data; | 198 syncer::SyncData sync_data; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 } | 304 } |
305 | 305 |
306 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { | 306 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { |
307 DCHECK_EQ(type_, type); | 307 DCHECK_EQ(type_, type); |
308 models_associated_ = false; | 308 models_associated_ = false; |
309 sync_processor_.reset(); | 309 sync_processor_.reset(); |
310 sync_error_factory_.reset(); | 310 sync_error_factory_.reset(); |
311 pref_service_->OnIsSyncingChanged(); | 311 pref_service_->OnIsSyncingChanged(); |
312 } | 312 } |
313 | 313 |
314 scoped_ptr<Value> PrefModelAssociator::MergePreference( | 314 scoped_ptr<base::Value> PrefModelAssociator::MergePreference( |
315 const std::string& name, | 315 const std::string& name, |
316 const Value& local_value, | 316 const base::Value& local_value, |
317 const Value& server_value) { | 317 const base::Value& server_value) { |
318 // This function special cases preferences individually, so don't attempt | 318 // This function special cases preferences individually, so don't attempt |
319 // to merge for all migrated values. | 319 // to merge for all migrated values. |
320 if (name == prefs::kURLsToRestoreOnStartup || | 320 if (name == prefs::kURLsToRestoreOnStartup || |
321 name == prefs::kURLsToRestoreOnStartupOld) { | 321 name == prefs::kURLsToRestoreOnStartupOld) { |
322 return scoped_ptr<Value>(MergeListValues(local_value, server_value)).Pass(); | 322 return scoped_ptr<base::Value>( |
| 323 MergeListValues(local_value, server_value)).Pass(); |
323 } | 324 } |
324 | 325 |
325 if (name == prefs::kContentSettingsPatternPairs) { | 326 if (name == prefs::kContentSettingsPatternPairs) { |
326 return scoped_ptr<Value>( | 327 return scoped_ptr<base::Value>( |
327 MergeDictionaryValues(local_value, server_value)).Pass(); | 328 MergeDictionaryValues(local_value, server_value)).Pass(); |
328 } | 329 } |
329 | 330 |
330 // If this is not a specially handled preference, server wins. | 331 // If this is not a specially handled preference, server wins. |
331 return scoped_ptr<Value>(server_value.DeepCopy()).Pass(); | 332 return scoped_ptr<base::Value>(server_value.DeepCopy()).Pass(); |
332 } | 333 } |
333 | 334 |
334 bool PrefModelAssociator::CreatePrefSyncData( | 335 bool PrefModelAssociator::CreatePrefSyncData( |
335 const std::string& name, | 336 const std::string& name, |
336 const Value& value, | 337 const base::Value& value, |
337 syncer::SyncData* sync_data) const { | 338 syncer::SyncData* sync_data) const { |
338 if (value.IsType(Value::TYPE_NULL)) { | 339 if (value.IsType(base::Value::TYPE_NULL)) { |
339 LOG(ERROR) << "Attempting to sync a null pref value for " << name; | 340 LOG(ERROR) << "Attempting to sync a null pref value for " << name; |
340 return false; | 341 return false; |
341 } | 342 } |
342 | 343 |
343 std::string serialized; | 344 std::string serialized; |
344 // TODO(zea): consider JSONWriter::Write since you don't have to check | 345 // TODO(zea): consider JSONWriter::Write since you don't have to check |
345 // failures to deserialize. | 346 // failures to deserialize. |
346 JSONStringValueSerializer json(&serialized); | 347 JSONStringValueSerializer json(&serialized); |
347 if (!json.Serialize(value)) { | 348 if (!json.Serialize(value)) { |
348 LOG(ERROR) << "Failed to serialize preference value."; | 349 LOG(ERROR) << "Failed to serialize preference value."; |
349 return false; | 350 return false; |
350 } | 351 } |
351 | 352 |
352 sync_pb::EntitySpecifics specifics; | 353 sync_pb::EntitySpecifics specifics; |
353 sync_pb::PreferenceSpecifics* pref_specifics = | 354 sync_pb::PreferenceSpecifics* pref_specifics = |
354 GetMutableSpecifics(type_, &specifics); | 355 GetMutableSpecifics(type_, &specifics); |
355 | 356 |
356 pref_specifics->set_name(name); | 357 pref_specifics->set_name(name); |
357 pref_specifics->set_value(serialized); | 358 pref_specifics->set_value(serialized); |
358 *sync_data = syncer::SyncData::CreateLocalData(name, name, specifics); | 359 *sync_data = syncer::SyncData::CreateLocalData(name, name, specifics); |
359 return true; | 360 return true; |
360 } | 361 } |
361 | 362 |
362 Value* PrefModelAssociator::MergeListValues(const Value& from_value, | 363 base::Value* PrefModelAssociator::MergeListValues(const base::Value& from_value, |
363 const Value& to_value) { | 364 const base::Value& to_value) { |
364 if (from_value.GetType() == Value::TYPE_NULL) | 365 if (from_value.GetType() == base::Value::TYPE_NULL) |
365 return to_value.DeepCopy(); | 366 return to_value.DeepCopy(); |
366 if (to_value.GetType() == Value::TYPE_NULL) | 367 if (to_value.GetType() == base::Value::TYPE_NULL) |
367 return from_value.DeepCopy(); | 368 return from_value.DeepCopy(); |
368 | 369 |
369 DCHECK(from_value.GetType() == Value::TYPE_LIST); | 370 DCHECK(from_value.GetType() == base::Value::TYPE_LIST); |
370 DCHECK(to_value.GetType() == Value::TYPE_LIST); | 371 DCHECK(to_value.GetType() == base::Value::TYPE_LIST); |
371 const ListValue& from_list_value = static_cast<const ListValue&>(from_value); | 372 const base::ListValue& from_list_value = |
372 const ListValue& to_list_value = static_cast<const ListValue&>(to_value); | 373 static_cast<const base::ListValue&>(from_value); |
373 ListValue* result = to_list_value.DeepCopy(); | 374 const base::ListValue& to_list_value = |
| 375 static_cast<const base::ListValue&>(to_value); |
| 376 base::ListValue* result = to_list_value.DeepCopy(); |
374 | 377 |
375 for (ListValue::const_iterator i = from_list_value.begin(); | 378 for (base::ListValue::const_iterator i = from_list_value.begin(); |
376 i != from_list_value.end(); ++i) { | 379 i != from_list_value.end(); ++i) { |
377 Value* value = (*i)->DeepCopy(); | 380 base::Value* value = (*i)->DeepCopy(); |
378 result->AppendIfNotPresent(value); | 381 result->AppendIfNotPresent(value); |
379 } | 382 } |
380 return result; | 383 return result; |
381 } | 384 } |
382 | 385 |
383 Value* PrefModelAssociator::MergeDictionaryValues( | 386 base::Value* PrefModelAssociator::MergeDictionaryValues( |
384 const Value& from_value, | 387 const base::Value& from_value, |
385 const Value& to_value) { | 388 const base::Value& to_value) { |
386 if (from_value.GetType() == Value::TYPE_NULL) | 389 if (from_value.GetType() == base::Value::TYPE_NULL) |
387 return to_value.DeepCopy(); | 390 return to_value.DeepCopy(); |
388 if (to_value.GetType() == Value::TYPE_NULL) | 391 if (to_value.GetType() == base::Value::TYPE_NULL) |
389 return from_value.DeepCopy(); | 392 return from_value.DeepCopy(); |
390 | 393 |
391 DCHECK_EQ(from_value.GetType(), Value::TYPE_DICTIONARY); | 394 DCHECK_EQ(from_value.GetType(), base::Value::TYPE_DICTIONARY); |
392 DCHECK_EQ(to_value.GetType(), Value::TYPE_DICTIONARY); | 395 DCHECK_EQ(to_value.GetType(), base::Value::TYPE_DICTIONARY); |
393 const DictionaryValue& from_dict_value = | 396 const base::DictionaryValue& from_dict_value = |
394 static_cast<const DictionaryValue&>(from_value); | 397 static_cast<const base::DictionaryValue&>(from_value); |
395 const DictionaryValue& to_dict_value = | 398 const base::DictionaryValue& to_dict_value = |
396 static_cast<const DictionaryValue&>(to_value); | 399 static_cast<const base::DictionaryValue&>(to_value); |
397 DictionaryValue* result = to_dict_value.DeepCopy(); | 400 base::DictionaryValue* result = to_dict_value.DeepCopy(); |
398 | 401 |
399 for (DictionaryValue::Iterator it(from_dict_value); !it.IsAtEnd(); | 402 for (base::DictionaryValue::Iterator it(from_dict_value); !it.IsAtEnd(); |
400 it.Advance()) { | 403 it.Advance()) { |
401 const Value* from_value = &it.value(); | 404 const base::Value* from_value = &it.value(); |
402 Value* to_key_value; | 405 base::Value* to_key_value; |
403 if (result->GetWithoutPathExpansion(it.key(), &to_key_value)) { | 406 if (result->GetWithoutPathExpansion(it.key(), &to_key_value)) { |
404 if (to_key_value->GetType() == Value::TYPE_DICTIONARY) { | 407 if (to_key_value->GetType() == base::Value::TYPE_DICTIONARY) { |
405 Value* merged_value = MergeDictionaryValues(*from_value, *to_key_value); | 408 base::Value* merged_value = |
| 409 MergeDictionaryValues(*from_value, *to_key_value); |
406 result->SetWithoutPathExpansion(it.key(), merged_value); | 410 result->SetWithoutPathExpansion(it.key(), merged_value); |
407 } | 411 } |
408 // Note that for all other types we want to preserve the "to" | 412 // Note that for all other types we want to preserve the "to" |
409 // values so we do nothing here. | 413 // values so we do nothing here. |
410 } else { | 414 } else { |
411 result->SetWithoutPathExpansion(it.key(), from_value->DeepCopy()); | 415 result->SetWithoutPathExpansion(it.key(), from_value->DeepCopy()); |
412 } | 416 } |
413 } | 417 } |
414 return result; | 418 return result; |
415 } | 419 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 } | 468 } |
465 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 469 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); |
466 syncer::SyncChangeList::const_iterator iter; | 470 syncer::SyncChangeList::const_iterator iter; |
467 for (iter = change_list.begin(); iter != change_list.end(); ++iter) { | 471 for (iter = change_list.begin(); iter != change_list.end(); ++iter) { |
468 DCHECK_EQ(type_, iter->sync_data().GetDataType()); | 472 DCHECK_EQ(type_, iter->sync_data().GetDataType()); |
469 | 473 |
470 std::string name; | 474 std::string name; |
471 const sync_pb::PreferenceSpecifics& pref_specifics = | 475 const sync_pb::PreferenceSpecifics& pref_specifics = |
472 GetSpecifics(iter->sync_data()); | 476 GetSpecifics(iter->sync_data()); |
473 | 477 |
474 scoped_ptr<Value> value(ReadPreferenceSpecifics(pref_specifics, | 478 scoped_ptr<base::Value> value(ReadPreferenceSpecifics(pref_specifics, |
475 &name)); | 479 &name)); |
476 | 480 |
477 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { | 481 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { |
478 // We never delete preferences. | 482 // We never delete preferences. |
479 NOTREACHED() << "Attempted to process sync delete change for " << name | 483 NOTREACHED() << "Attempted to process sync delete change for " << name |
480 << ". Skipping."; | 484 << ". Skipping."; |
481 continue; | 485 continue; |
482 } | 486 } |
483 | 487 |
484 // Skip values we can't deserialize. | 488 // Skip values we can't deserialize. |
485 // TODO(zea): consider taking some further action such as erasing the bad | 489 // TODO(zea): consider taking some further action such as erasing the bad |
(...skipping 28 matching lines...) Expand all Loading... |
514 NotifySyncedPrefObservers(name, true /*from_sync*/); | 518 NotifySyncedPrefObservers(name, true /*from_sync*/); |
515 | 519 |
516 // Keep track of any newly synced preferences. | 520 // Keep track of any newly synced preferences. |
517 if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { | 521 if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { |
518 synced_preferences_.insert(name); | 522 synced_preferences_.insert(name); |
519 } | 523 } |
520 } | 524 } |
521 return syncer::SyncError(); | 525 return syncer::SyncError(); |
522 } | 526 } |
523 | 527 |
524 Value* PrefModelAssociator::ReadPreferenceSpecifics( | 528 base::Value* PrefModelAssociator::ReadPreferenceSpecifics( |
525 const sync_pb::PreferenceSpecifics& preference, | 529 const sync_pb::PreferenceSpecifics& preference, |
526 std::string* name) { | 530 std::string* name) { |
527 base::JSONReader reader; | 531 base::JSONReader reader; |
528 scoped_ptr<Value> value(reader.ReadToValue(preference.value())); | 532 scoped_ptr<base::Value> value(reader.ReadToValue(preference.value())); |
529 if (!value.get()) { | 533 if (!value.get()) { |
530 std::string err = "Failed to deserialize preference value: " + | 534 std::string err = "Failed to deserialize preference value: " + |
531 reader.GetErrorMessage(); | 535 reader.GetErrorMessage(); |
532 LOG(ERROR) << err; | 536 LOG(ERROR) << err; |
533 return NULL; | 537 return NULL; |
534 } | 538 } |
535 *name = preference.name(); | 539 *name = preference.name(); |
536 return value.release(); | 540 return value.release(); |
537 } | 541 } |
538 | 542 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 void PrefModelAssociator::NotifySyncedPrefObservers(const std::string& path, | 655 void PrefModelAssociator::NotifySyncedPrefObservers(const std::string& path, |
652 bool from_sync) const { | 656 bool from_sync) const { |
653 SyncedPrefObserverMap::const_iterator observer_iter = | 657 SyncedPrefObserverMap::const_iterator observer_iter = |
654 synced_pref_observers_.find(path); | 658 synced_pref_observers_.find(path); |
655 if (observer_iter == synced_pref_observers_.end()) | 659 if (observer_iter == synced_pref_observers_.end()) |
656 return; | 660 return; |
657 SyncedPrefObserverList* observers = observer_iter->second; | 661 SyncedPrefObserverList* observers = observer_iter->second; |
658 FOR_EACH_OBSERVER(SyncedPrefObserver, *observers, | 662 FOR_EACH_OBSERVER(SyncedPrefObserver, *observers, |
659 OnSyncedPrefChanged(path, from_sync)); | 663 OnSyncedPrefChanged(path, from_sync)); |
660 } | 664 } |
OLD | NEW |