| 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 namespace { | 
|  | 27 | 
|  | 28 const sync_pb::PreferenceSpecifics& GetSpecifics(const syncer::SyncData& pref) { | 
|  | 29   DCHECK(pref.GetDataType() == syncer::PREFERENCES || | 
|  | 30          pref.GetDataType() == syncer::PRIORITY_PREFERENCES); | 
|  | 31   if (pref.GetDataType() == syncer::PRIORITY_PREFERENCES) { | 
|  | 32     return pref.GetSpecifics().priority_preference().preference(); | 
|  | 33   } else { | 
|  | 34     return pref.GetSpecifics().preference(); | 
|  | 35   } | 
|  | 36 } | 
|  | 37 | 
|  | 38 sync_pb::PreferenceSpecifics* GetMutableSpecifics( | 
|  | 39     const syncer::ModelType type, | 
|  | 40     sync_pb::EntitySpecifics* specifics) { | 
|  | 41   if (type == syncer::PRIORITY_PREFERENCES) { | 
|  | 42     DCHECK(!specifics->has_preference()); | 
|  | 43     return specifics->mutable_priority_preference()->mutable_preference(); | 
|  | 44   } else { | 
|  | 45     DCHECK(!specifics->has_priority_preference()); | 
|  | 46     return specifics->mutable_preference(); | 
|  | 47   } | 
|  | 48 } | 
|  | 49 | 
|  | 50 }  // namespace | 
|  | 51 | 
|  | 52 PrefModelAssociator::PrefModelAssociator(syncer::ModelType type) | 
| 26     : models_associated_(false), | 53     : models_associated_(false), | 
| 27       processing_syncer_changes_(false), | 54       processing_syncer_changes_(false), | 
| 28       pref_service_(NULL) { | 55       pref_service_(NULL), | 
|  | 56       type_(type) { | 
| 29   DCHECK(CalledOnValidThread()); | 57   DCHECK(CalledOnValidThread()); | 
|  | 58   DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); | 
| 30 } | 59 } | 
| 31 | 60 | 
| 32 PrefModelAssociator::~PrefModelAssociator() { | 61 PrefModelAssociator::~PrefModelAssociator() { | 
| 33   DCHECK(CalledOnValidThread()); | 62   DCHECK(CalledOnValidThread()); | 
| 34   pref_service_ = NULL; | 63   pref_service_ = NULL; | 
| 35 } | 64 } | 
| 36 | 65 | 
| 37 void PrefModelAssociator::InitPrefAndAssociate( | 66 void PrefModelAssociator::InitPrefAndAssociate( | 
| 38     const syncer::SyncData& sync_pref, | 67     const syncer::SyncData& sync_pref, | 
| 39     const std::string& pref_name, | 68     const std::string& pref_name, | 
| 40     syncer::SyncChangeList* sync_changes) { | 69     syncer::SyncChangeList* sync_changes) { | 
| 41   const Value* user_pref_value = pref_service_->GetUserPrefValue( | 70   const Value* user_pref_value = pref_service_->GetUserPrefValue( | 
| 42       pref_name.c_str()); | 71       pref_name.c_str()); | 
| 43   VLOG(1) << "Associating preference " << pref_name; | 72   VLOG(1) << "Associating preference " << pref_name; | 
| 44 | 73 | 
| 45   if (sync_pref.IsValid()) { | 74   if (sync_pref.IsValid()) { | 
| 46     const sync_pb::PreferenceSpecifics& preference = | 75     const sync_pb::PreferenceSpecifics& preference = GetSpecifics(sync_pref); | 
| 47         sync_pref.GetSpecifics().preference(); |  | 
| 48     DCHECK_EQ(pref_name, preference.name()); | 76     DCHECK_EQ(pref_name, preference.name()); | 
| 49 | 77 | 
| 50     base::JSONReader reader; | 78     base::JSONReader reader; | 
| 51     scoped_ptr<Value> sync_value(reader.ReadToValue(preference.value())); | 79     scoped_ptr<Value> sync_value(reader.ReadToValue(preference.value())); | 
| 52     if (!sync_value.get()) { | 80     if (!sync_value.get()) { | 
| 53       LOG(ERROR) << "Failed to deserialize preference value: " | 81       LOG(ERROR) << "Failed to deserialize preference value: " | 
| 54                  << reader.GetErrorMessage(); | 82                  << reader.GetErrorMessage(); | 
| 55       return; | 83       return; | 
| 56     } | 84     } | 
| 57 | 85 | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 117   // the server is aware of. | 145   // the server is aware of. | 
| 118   synced_preferences_.insert(pref_name); | 146   synced_preferences_.insert(pref_name); | 
| 119   return; | 147   return; | 
| 120 } | 148 } | 
| 121 | 149 | 
| 122 syncer::SyncMergeResult PrefModelAssociator::MergeDataAndStartSyncing( | 150 syncer::SyncMergeResult PrefModelAssociator::MergeDataAndStartSyncing( | 
| 123     syncer::ModelType type, | 151     syncer::ModelType type, | 
| 124     const syncer::SyncDataList& initial_sync_data, | 152     const syncer::SyncDataList& initial_sync_data, | 
| 125     scoped_ptr<syncer::SyncChangeProcessor> sync_processor, | 153     scoped_ptr<syncer::SyncChangeProcessor> sync_processor, | 
| 126     scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { | 154     scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { | 
| 127   DCHECK_EQ(type, PREFERENCES); | 155   DCHECK_EQ(type_, type); | 
| 128   DCHECK(CalledOnValidThread()); | 156   DCHECK(CalledOnValidThread()); | 
| 129   DCHECK(pref_service_); | 157   DCHECK(pref_service_); | 
| 130   DCHECK(!sync_processor_.get()); | 158   DCHECK(!sync_processor_.get()); | 
| 131   DCHECK(sync_processor.get()); | 159   DCHECK(sync_processor.get()); | 
| 132   DCHECK(sync_error_factory.get()); | 160   DCHECK(sync_error_factory.get()); | 
| 133   syncer::SyncMergeResult merge_result(type); | 161   syncer::SyncMergeResult merge_result(type); | 
| 134   sync_processor_ = sync_processor.Pass(); | 162   sync_processor_ = sync_processor.Pass(); | 
| 135   sync_error_factory_ = sync_error_factory.Pass(); | 163   sync_error_factory_ = sync_error_factory.Pass(); | 
| 136 | 164 | 
| 137   syncer::SyncChangeList new_changes; | 165   syncer::SyncChangeList new_changes; | 
| 138   std::set<std::string> remaining_preferences = registered_preferences_; | 166   std::set<std::string> remaining_preferences = registered_preferences_; | 
| 139 | 167 | 
| 140   // Go through and check for all preferences we care about that sync already | 168   // Go through and check for all preferences we care about that sync already | 
| 141   // knows about. | 169   // knows about. | 
| 142   for (syncer::SyncDataList::const_iterator sync_iter = | 170   for (syncer::SyncDataList::const_iterator sync_iter = | 
| 143            initial_sync_data.begin(); | 171            initial_sync_data.begin(); | 
| 144        sync_iter != initial_sync_data.end(); | 172        sync_iter != initial_sync_data.end(); | 
| 145        ++sync_iter) { | 173        ++sync_iter) { | 
| 146     DCHECK_EQ(PREFERENCES, sync_iter->GetDataType()); | 174     DCHECK_EQ(type_, sync_iter->GetDataType()); | 
| 147     std::string sync_pref_name = sync_iter->GetSpecifics().preference().name(); | 175 | 
|  | 176     const sync_pb::PreferenceSpecifics& preference = GetSpecifics(*sync_iter); | 
|  | 177     const std::string& sync_pref_name = preference.name(); | 
|  | 178 | 
| 148     if (remaining_preferences.count(sync_pref_name) == 0) { | 179     if (remaining_preferences.count(sync_pref_name) == 0) { | 
| 149       // We're not syncing this preference locally, ignore the sync data. | 180       // 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 | 181       // TODO(zea): Eventually we want to be able to have the syncable service | 
| 151       // reconstruct all sync data for it's datatype (therefore having | 182       // reconstruct all sync data for it's datatype (therefore having | 
| 152       // GetAllSyncData be a complete representation). We should store this data | 183       // GetAllSyncData be a complete representation). We should store this data | 
| 153       // somewhere, even if we don't use it. | 184       // somewhere, even if we don't use it. | 
| 154       continue; | 185       continue; | 
| 155     } | 186     } | 
| 156 | 187 | 
| 157     remaining_preferences.erase(sync_pref_name); | 188     remaining_preferences.erase(sync_pref_name); | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 171       sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); | 202       sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); | 
| 172   if (merge_result.error().IsSet()) | 203   if (merge_result.error().IsSet()) | 
| 173     return merge_result; | 204     return merge_result; | 
| 174 | 205 | 
| 175   models_associated_ = true; | 206   models_associated_ = true; | 
| 176   pref_service_->OnIsSyncingChanged(); | 207   pref_service_->OnIsSyncingChanged(); | 
| 177   return merge_result; | 208   return merge_result; | 
| 178 } | 209 } | 
| 179 | 210 | 
| 180 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { | 211 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { | 
| 181   DCHECK_EQ(type, PREFERENCES); | 212   DCHECK_EQ(type_, type); | 
| 182   models_associated_ = false; | 213   models_associated_ = false; | 
| 183   sync_processor_.reset(); | 214   sync_processor_.reset(); | 
| 184   sync_error_factory_.reset(); | 215   sync_error_factory_.reset(); | 
| 185   pref_service_->OnIsSyncingChanged(); | 216   pref_service_->OnIsSyncingChanged(); | 
| 186 } | 217 } | 
| 187 | 218 | 
| 188 scoped_ptr<Value> PrefModelAssociator::MergePreference( | 219 scoped_ptr<Value> PrefModelAssociator::MergePreference( | 
| 189     const std::string& name, | 220     const std::string& name, | 
| 190     const Value& local_value, | 221     const Value& local_value, | 
| 191     const Value& server_value) { | 222     const Value& server_value) { | 
| 192   if (name == prefs::kURLsToRestoreOnStartup) { | 223   if (name == prefs::kURLsToRestoreOnStartup) { | 
| 193     return scoped_ptr<Value>(MergeListValues(local_value, server_value)).Pass(); | 224     return scoped_ptr<Value>(MergeListValues(local_value, server_value)).Pass(); | 
| 194   } | 225   } | 
| 195 | 226 | 
| 196   if (name == prefs::kContentSettingsPatternPairs) { | 227   if (name == prefs::kContentSettingsPatternPairs) { | 
| 197     return scoped_ptr<Value>( | 228     return scoped_ptr<Value>( | 
| 198         MergeDictionaryValues(local_value, server_value)).Pass(); | 229         MergeDictionaryValues(local_value, server_value)).Pass(); | 
| 199   } | 230   } | 
| 200 | 231 | 
| 201   // If this is not a specially handled preference, server wins. | 232   // If this is not a specially handled preference, server wins. | 
| 202   return scoped_ptr<Value>(server_value.DeepCopy()).Pass(); | 233   return scoped_ptr<Value>(server_value.DeepCopy()).Pass(); | 
| 203 } | 234 } | 
| 204 | 235 | 
| 205 bool PrefModelAssociator::CreatePrefSyncData( | 236 bool PrefModelAssociator::CreatePrefSyncData( | 
| 206     const std::string& name, | 237     const std::string& name, | 
| 207     const Value& value, | 238     const Value& value, | 
| 208     syncer::SyncData* sync_data) { | 239     syncer::SyncData* sync_data) const { | 
| 209   if (value.IsType(Value::TYPE_NULL)) { | 240   if (value.IsType(Value::TYPE_NULL)) { | 
| 210     LOG(ERROR) << "Attempting to sync a null pref value for " << name; | 241     LOG(ERROR) << "Attempting to sync a null pref value for " << name; | 
| 211     return false; | 242     return false; | 
| 212   } | 243   } | 
| 213 | 244 | 
| 214   std::string serialized; | 245   std::string serialized; | 
| 215   // TODO(zea): consider JSONWriter::Write since you don't have to check | 246   // TODO(zea): consider JSONWriter::Write since you don't have to check | 
| 216   // failures to deserialize. | 247   // failures to deserialize. | 
| 217   JSONStringValueSerializer json(&serialized); | 248   JSONStringValueSerializer json(&serialized); | 
| 218   if (!json.Serialize(value)) { | 249   if (!json.Serialize(value)) { | 
| 219     LOG(ERROR) << "Failed to serialize preference value."; | 250     LOG(ERROR) << "Failed to serialize preference value."; | 
| 220     return false; | 251     return false; | 
| 221   } | 252   } | 
| 222 | 253 | 
| 223   sync_pb::EntitySpecifics specifics; | 254   sync_pb::EntitySpecifics specifics; | 
| 224   sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); | 255   sync_pb::PreferenceSpecifics* pref_specifics = | 
|  | 256       GetMutableSpecifics(type_, &specifics); | 
|  | 257 | 
| 225   pref_specifics->set_name(name); | 258   pref_specifics->set_name(name); | 
| 226   pref_specifics->set_value(serialized); | 259   pref_specifics->set_value(serialized); | 
| 227   *sync_data = syncer::SyncData::CreateLocalData(name, name, specifics); | 260   *sync_data = syncer::SyncData::CreateLocalData(name, name, specifics); | 
| 228   return true; | 261   return true; | 
| 229 } | 262 } | 
| 230 | 263 | 
| 231 Value* PrefModelAssociator::MergeListValues(const Value& from_value, | 264 Value* PrefModelAssociator::MergeListValues(const Value& from_value, | 
| 232                                             const Value& to_value) { | 265                                             const Value& to_value) { | 
| 233   if (from_value.GetType() == Value::TYPE_NULL) | 266   if (from_value.GetType() == Value::TYPE_NULL) | 
| 234     return to_value.DeepCopy(); | 267     return to_value.DeepCopy(); | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 283   return result; | 316   return result; | 
| 284 } | 317 } | 
| 285 | 318 | 
| 286 // Note: This will build a model of all preferences registered as syncable | 319 // Note: This will build a model of all preferences registered as syncable | 
| 287 // with user controlled data. We do not track any information for preferences | 320 // with user controlled data. We do not track any information for preferences | 
| 288 // not registered locally as syncable and do not inform the syncer of | 321 // not registered locally as syncable and do not inform the syncer of | 
| 289 // non-user controlled preferences. | 322 // non-user controlled preferences. | 
| 290 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( | 323 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( | 
| 291     syncer::ModelType type) | 324     syncer::ModelType type) | 
| 292     const { | 325     const { | 
| 293   DCHECK_EQ(PREFERENCES, type); | 326   DCHECK_EQ(type_, type); | 
| 294   syncer::SyncDataList current_data; | 327   syncer::SyncDataList current_data; | 
| 295   for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); | 328   for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); | 
| 296        iter != synced_preferences_.end(); | 329        iter != synced_preferences_.end(); | 
| 297        ++iter) { | 330        ++iter) { | 
| 298     std::string name = *iter; | 331     std::string name = *iter; | 
| 299     const PrefService::Preference* pref = | 332     const PrefService::Preference* pref = | 
| 300       pref_service_->FindPreference(name.c_str()); | 333       pref_service_->FindPreference(name.c_str()); | 
| 301     DCHECK(pref); | 334     DCHECK(pref); | 
| 302     if (!pref->IsUserControlled() || pref->IsDefaultValue()) | 335     if (!pref->IsUserControlled() || pref->IsDefaultValue()) | 
| 303       continue;  // This is not data we care about. | 336       continue;  // This is not data we care about. | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 315     const syncer::SyncChangeList& change_list) { | 348     const syncer::SyncChangeList& change_list) { | 
| 316   if (!models_associated_) { | 349   if (!models_associated_) { | 
| 317     syncer::SyncError error(FROM_HERE, | 350     syncer::SyncError error(FROM_HERE, | 
| 318                     "Models not yet associated.", | 351                     "Models not yet associated.", | 
| 319                     PREFERENCES); | 352                     PREFERENCES); | 
| 320     return error; | 353     return error; | 
| 321   } | 354   } | 
| 322   base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 355   base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 
| 323   syncer::SyncChangeList::const_iterator iter; | 356   syncer::SyncChangeList::const_iterator iter; | 
| 324   for (iter = change_list.begin(); iter != change_list.end(); ++iter) { | 357   for (iter = change_list.begin(); iter != change_list.end(); ++iter) { | 
| 325     DCHECK_EQ(PREFERENCES, iter->sync_data().GetDataType()); | 358     DCHECK_EQ(type_, iter->sync_data().GetDataType()); | 
| 326 | 359 | 
| 327     std::string name; | 360     std::string name; | 
| 328     sync_pb::PreferenceSpecifics pref_specifics = | 361     const sync_pb::PreferenceSpecifics& pref_specifics = | 
| 329         iter->sync_data().GetSpecifics().preference(); | 362         GetSpecifics(iter->sync_data()); | 
|  | 363 | 
| 330     scoped_ptr<Value> value(ReadPreferenceSpecifics(pref_specifics, | 364     scoped_ptr<Value> value(ReadPreferenceSpecifics(pref_specifics, | 
| 331                                                     &name)); | 365                                                     &name)); | 
| 332 | 366 | 
| 333     if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { | 367     if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { | 
| 334       // We never delete preferences. | 368       // We never delete preferences. | 
| 335       NOTREACHED() << "Attempted to process sync delete change for " << name | 369       NOTREACHED() << "Attempted to process sync delete change for " << name | 
| 336                    << ". Skipping."; | 370                    << ". Skipping."; | 
| 337       continue; | 371       continue; | 
| 338     } | 372     } | 
| 339 | 373 | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 443   } | 477   } | 
| 444 | 478 | 
| 445   syncer::SyncError error = | 479   syncer::SyncError error = | 
| 446       sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 480       sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 
| 447 } | 481 } | 
| 448 | 482 | 
| 449 void PrefModelAssociator::SetPrefService(PrefServiceSyncable* pref_service) { | 483 void PrefModelAssociator::SetPrefService(PrefServiceSyncable* pref_service) { | 
| 450   DCHECK(pref_service_ == NULL); | 484   DCHECK(pref_service_ == NULL); | 
| 451   pref_service_ = pref_service; | 485   pref_service_ = pref_service; | 
| 452 } | 486 } | 
| OLD | NEW | 
|---|