Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(411)

Side by Side Diff: chrome/browser/prefs/pref_model_associator.cc

Issue 12033093: sync: Implementation of Priority Preferences. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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,
40 syncer::SyncChangeList* sync_changes) { 43 syncer::SyncChangeList* sync_changes) {
41 const Value* user_pref_value = pref_service_->GetUserPrefValue( 44 const Value* user_pref_value = pref_service_->GetUserPrefValue(
42 pref_name.c_str()); 45 pref_name.c_str());
43 VLOG(1) << "Associating preference " << pref_name; 46 VLOG(1) << "Associating preference " << pref_name;
44 47
45 if (sync_pref.IsValid()) { 48 if (sync_pref.IsValid()) {
46 const sync_pb::PreferenceSpecifics& preference = 49 const sync_pb::PreferenceSpecifics* preference;
47 sync_pref.GetSpecifics().preference(); 50
48 DCHECK_EQ(pref_name, preference.name()); 51 if (type_ == PREFERENCES) {
Nicolas Zea 2013/02/25 23:47:47 Yeah, I think an anon namespace helper function wo
albertb 2013/03/01 22:01:56 Done.
52 preference = &sync_pref.GetSpecifics().preference();
53 } else {
54 preference = &sync_pref.GetSpecifics().priority_preference().preference();
55 }
56 DCHECK_EQ(pref_name, preference->name());
49 57
50 base::JSONReader reader; 58 base::JSONReader reader;
51 scoped_ptr<Value> sync_value(reader.ReadToValue(preference.value())); 59 scoped_ptr<Value> sync_value(reader.ReadToValue(preference->value()));
52 if (!sync_value.get()) { 60 if (!sync_value.get()) {
53 LOG(ERROR) << "Failed to deserialize preference value: " 61 LOG(ERROR) << "Failed to deserialize preference value: "
54 << reader.GetErrorMessage(); 62 << reader.GetErrorMessage();
55 return; 63 return;
56 } 64 }
57 65
58 if (user_pref_value) { 66 if (user_pref_value) {
59 // We have both server and local values. Merge them. 67 // We have both server and local values. Merge them.
60 scoped_ptr<Value> new_value( 68 scoped_ptr<Value> new_value(
61 MergePreference(pref_name, *user_pref_value, *sync_value)); 69 MergePreference(pref_name, *user_pref_value, *sync_value));
62 70
63 // Update the local preference based on what we got from the 71 // Update the local preference based on what we got from the
64 // sync server. Note: this only updates the user value store, which is 72 // sync server. Note: this only updates the user value store, which is
65 // ignored if the preference is policy controlled. 73 // ignored if the preference is policy controlled.
66 if (new_value->IsType(Value::TYPE_NULL)) { 74 if (new_value->IsType(Value::TYPE_NULL)) {
67 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); 75 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str();
68 pref_service_->ClearPref(pref_name.c_str()); 76 pref_service_->ClearPref(pref_name.c_str());
69 } else if (!new_value->IsType(user_pref_value->GetType())) { 77 } else if (!new_value->IsType(user_pref_value->GetType())) {
70 LOG(WARNING) << "Synced value for " << preference.name() 78 LOG(WARNING) << "Synced value for " << preference->name()
71 << " is of type " << new_value->GetType() 79 << " is of type " << new_value->GetType()
72 << " which doesn't match pref type " 80 << " which doesn't match pref type "
73 << user_pref_value->GetType(); 81 << user_pref_value->GetType();
74 } else if (!user_pref_value->Equals(new_value.get())) { 82 } else if (!user_pref_value->Equals(new_value.get())) {
75 pref_service_->Set(pref_name.c_str(), *new_value); 83 pref_service_->Set(pref_name.c_str(), *new_value);
76 } 84 }
77 85
78 // If the merge resulted in an updated value, inform the syncer. 86 // If the merge resulted in an updated value, inform the syncer.
79 if (!sync_value->Equals(new_value.get())) { 87 if (!sync_value->Equals(new_value.get())) {
80 syncer::SyncData sync_data; 88 syncer::SyncData sync_data;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 // the server is aware of. 125 // the server is aware of.
118 synced_preferences_.insert(pref_name); 126 synced_preferences_.insert(pref_name);
119 return; 127 return;
120 } 128 }
121 129
122 syncer::SyncMergeResult PrefModelAssociator::MergeDataAndStartSyncing( 130 syncer::SyncMergeResult PrefModelAssociator::MergeDataAndStartSyncing(
123 syncer::ModelType type, 131 syncer::ModelType type,
124 const syncer::SyncDataList& initial_sync_data, 132 const syncer::SyncDataList& initial_sync_data,
125 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, 133 scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
126 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { 134 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) {
127 DCHECK_EQ(type, PREFERENCES); 135 DCHECK_EQ(type_, type);
128 DCHECK(CalledOnValidThread()); 136 DCHECK(CalledOnValidThread());
129 DCHECK(pref_service_); 137 DCHECK(pref_service_);
130 DCHECK(!sync_processor_.get()); 138 DCHECK(!sync_processor_.get());
131 DCHECK(sync_processor.get()); 139 DCHECK(sync_processor.get());
132 DCHECK(sync_error_factory.get()); 140 DCHECK(sync_error_factory.get());
133 syncer::SyncMergeResult merge_result(type); 141 syncer::SyncMergeResult merge_result(type);
134 sync_processor_ = sync_processor.Pass(); 142 sync_processor_ = sync_processor.Pass();
135 sync_error_factory_ = sync_error_factory.Pass(); 143 sync_error_factory_ = sync_error_factory.Pass();
136 144
137 syncer::SyncChangeList new_changes; 145 syncer::SyncChangeList new_changes;
138 std::set<std::string> remaining_preferences = registered_preferences_; 146 std::set<std::string> remaining_preferences = registered_preferences_;
139 147
140 // Go through and check for all preferences we care about that sync already 148 // Go through and check for all preferences we care about that sync already
141 // knows about. 149 // knows about.
142 for (syncer::SyncDataList::const_iterator sync_iter = 150 for (syncer::SyncDataList::const_iterator sync_iter =
143 initial_sync_data.begin(); 151 initial_sync_data.begin();
144 sync_iter != initial_sync_data.end(); 152 sync_iter != initial_sync_data.end();
145 ++sync_iter) { 153 ++sync_iter) {
146 DCHECK_EQ(PREFERENCES, sync_iter->GetDataType()); 154 DCHECK_EQ(type_, sync_iter->GetDataType());
147 std::string sync_pref_name = sync_iter->GetSpecifics().preference().name(); 155 std::string sync_pref_name;
156
157 if (type_ == PREFERENCES) {
158 sync_pref_name = sync_iter->GetSpecifics().preference().name();
159 } else {
160 sync_pref_name =
161 sync_iter->GetSpecifics().priority_preference().preference().name();
162 }
148 if (remaining_preferences.count(sync_pref_name) == 0) { 163 if (remaining_preferences.count(sync_pref_name) == 0) {
149 // We're not syncing this preference locally, ignore the sync data. 164 // 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 165 // TODO(zea): Eventually we want to be able to have the syncable service
151 // reconstruct all sync data for it's datatype (therefore having 166 // reconstruct all sync data for it's datatype (therefore having
152 // GetAllSyncData be a complete representation). We should store this data 167 // GetAllSyncData be a complete representation). We should store this data
153 // somewhere, even if we don't use it. 168 // somewhere, even if we don't use it.
154 continue; 169 continue;
155 } 170 }
156 171
157 remaining_preferences.erase(sync_pref_name); 172 remaining_preferences.erase(sync_pref_name);
(...skipping 13 matching lines...) Expand all
171 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); 186 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes));
172 if (merge_result.error().IsSet()) 187 if (merge_result.error().IsSet())
173 return merge_result; 188 return merge_result;
174 189
175 models_associated_ = true; 190 models_associated_ = true;
176 pref_service_->OnIsSyncingChanged(); 191 pref_service_->OnIsSyncingChanged();
177 return merge_result; 192 return merge_result;
178 } 193 }
179 194
180 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { 195 void PrefModelAssociator::StopSyncing(syncer::ModelType type) {
181 DCHECK_EQ(type, PREFERENCES); 196 DCHECK_EQ(type_, type);
182 models_associated_ = false; 197 models_associated_ = false;
183 sync_processor_.reset(); 198 sync_processor_.reset();
184 sync_error_factory_.reset(); 199 sync_error_factory_.reset();
185 pref_service_->OnIsSyncingChanged(); 200 pref_service_->OnIsSyncingChanged();
186 } 201 }
187 202
188 scoped_ptr<Value> PrefModelAssociator::MergePreference( 203 scoped_ptr<Value> PrefModelAssociator::MergePreference(
189 const std::string& name, 204 const std::string& name,
190 const Value& local_value, 205 const Value& local_value,
191 const Value& server_value) { 206 const Value& server_value) {
192 if (name == prefs::kURLsToRestoreOnStartup) { 207 if (name == prefs::kURLsToRestoreOnStartup) {
193 return scoped_ptr<Value>(MergeListValues(local_value, server_value)).Pass(); 208 return scoped_ptr<Value>(MergeListValues(local_value, server_value)).Pass();
194 } 209 }
195 210
196 if (name == prefs::kContentSettingsPatternPairs) { 211 if (name == prefs::kContentSettingsPatternPairs) {
197 return scoped_ptr<Value>( 212 return scoped_ptr<Value>(
198 MergeDictionaryValues(local_value, server_value)).Pass(); 213 MergeDictionaryValues(local_value, server_value)).Pass();
199 } 214 }
200 215
201 // If this is not a specially handled preference, server wins. 216 // If this is not a specially handled preference, server wins.
202 return scoped_ptr<Value>(server_value.DeepCopy()).Pass(); 217 return scoped_ptr<Value>(server_value.DeepCopy()).Pass();
203 } 218 }
204 219
205 bool PrefModelAssociator::CreatePrefSyncData( 220 bool PrefModelAssociator::CreatePrefSyncData(
206 const std::string& name, 221 const std::string& name,
207 const Value& value, 222 const Value& value,
208 syncer::SyncData* sync_data) { 223 syncer::SyncData* sync_data) const {
209 if (value.IsType(Value::TYPE_NULL)) { 224 if (value.IsType(Value::TYPE_NULL)) {
210 LOG(ERROR) << "Attempting to sync a null pref value for " << name; 225 LOG(ERROR) << "Attempting to sync a null pref value for " << name;
211 return false; 226 return false;
212 } 227 }
213 228
214 std::string serialized; 229 std::string serialized;
215 // TODO(zea): consider JSONWriter::Write since you don't have to check 230 // TODO(zea): consider JSONWriter::Write since you don't have to check
216 // failures to deserialize. 231 // failures to deserialize.
217 JSONStringValueSerializer json(&serialized); 232 JSONStringValueSerializer json(&serialized);
218 if (!json.Serialize(value)) { 233 if (!json.Serialize(value)) {
219 LOG(ERROR) << "Failed to serialize preference value."; 234 LOG(ERROR) << "Failed to serialize preference value.";
220 return false; 235 return false;
221 } 236 }
222 237
223 sync_pb::EntitySpecifics specifics; 238 sync_pb::EntitySpecifics specifics;
224 sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); 239 sync_pb::PreferenceSpecifics* pref_specifics;
240
241 if (type_ == PREFERENCES) {
242 pref_specifics = specifics.mutable_preference();
243 } else {
244 pref_specifics =
245 specifics.mutable_priority_preference()->mutable_preference();
246 }
247
225 pref_specifics->set_name(name); 248 pref_specifics->set_name(name);
226 pref_specifics->set_value(serialized); 249 pref_specifics->set_value(serialized);
250
227 *sync_data = syncer::SyncData::CreateLocalData(name, name, specifics); 251 *sync_data = syncer::SyncData::CreateLocalData(name, name, specifics);
228 return true; 252 return true;
229 } 253 }
230 254
231 Value* PrefModelAssociator::MergeListValues(const Value& from_value, 255 Value* PrefModelAssociator::MergeListValues(const Value& from_value,
232 const Value& to_value) { 256 const Value& to_value) {
233 if (from_value.GetType() == Value::TYPE_NULL) 257 if (from_value.GetType() == Value::TYPE_NULL)
234 return to_value.DeepCopy(); 258 return to_value.DeepCopy();
235 if (to_value.GetType() == Value::TYPE_NULL) 259 if (to_value.GetType() == Value::TYPE_NULL)
236 return from_value.DeepCopy(); 260 return from_value.DeepCopy();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 return result; 310 return result;
287 } 311 }
288 312
289 // Note: This will build a model of all preferences registered as syncable 313 // 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 314 // 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 315 // not registered locally as syncable and do not inform the syncer of
292 // non-user controlled preferences. 316 // non-user controlled preferences.
293 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( 317 syncer::SyncDataList PrefModelAssociator::GetAllSyncData(
294 syncer::ModelType type) 318 syncer::ModelType type)
295 const { 319 const {
296 DCHECK_EQ(PREFERENCES, type); 320 DCHECK_EQ(type_, type);
297 syncer::SyncDataList current_data; 321 syncer::SyncDataList current_data;
298 for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); 322 for (PreferenceSet::const_iterator iter = synced_preferences_.begin();
299 iter != synced_preferences_.end(); 323 iter != synced_preferences_.end();
300 ++iter) { 324 ++iter) {
301 std::string name = *iter; 325 std::string name = *iter;
302 const PrefService::Preference* pref = 326 const PrefService::Preference* pref =
303 pref_service_->FindPreference(name.c_str()); 327 pref_service_->FindPreference(name.c_str());
304 DCHECK(pref); 328 DCHECK(pref);
305 if (!pref->IsUserControlled() || pref->IsDefaultValue()) 329 if (!pref->IsUserControlled() || pref->IsDefaultValue())
306 continue; // This is not data we care about. 330 continue; // This is not data we care about.
(...skipping 11 matching lines...) Expand all
318 const syncer::SyncChangeList& change_list) { 342 const syncer::SyncChangeList& change_list) {
319 if (!models_associated_) { 343 if (!models_associated_) {
320 syncer::SyncError error(FROM_HERE, 344 syncer::SyncError error(FROM_HERE,
321 "Models not yet associated.", 345 "Models not yet associated.",
322 PREFERENCES); 346 PREFERENCES);
323 return error; 347 return error;
324 } 348 }
325 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); 349 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
326 syncer::SyncChangeList::const_iterator iter; 350 syncer::SyncChangeList::const_iterator iter;
327 for (iter = change_list.begin(); iter != change_list.end(); ++iter) { 351 for (iter = change_list.begin(); iter != change_list.end(); ++iter) {
328 DCHECK_EQ(PREFERENCES, iter->sync_data().GetDataType()); 352 DCHECK_EQ(type_, iter->sync_data().GetDataType());
329 353
330 std::string name; 354 std::string name;
331 sync_pb::PreferenceSpecifics pref_specifics = 355 sync_pb::PreferenceSpecifics pref_specifics;
332 iter->sync_data().GetSpecifics().preference(); 356 if (type_ == PREFERENCES) {
357 pref_specifics = iter->sync_data().GetSpecifics().preference();
358 } else {
359 pref_specifics =
360 iter->sync_data().GetSpecifics().priority_preference().preference();
361 }
333 scoped_ptr<Value> value(ReadPreferenceSpecifics(pref_specifics, 362 scoped_ptr<Value> value(ReadPreferenceSpecifics(pref_specifics,
334 &name)); 363 &name));
335 364
336 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { 365 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) {
337 // We never delete preferences. 366 // We never delete preferences.
338 NOTREACHED() << "Attempted to process sync delete change for " << name 367 NOTREACHED() << "Attempted to process sync delete change for " << name
339 << ". Skipping."; 368 << ". Skipping.";
340 continue; 369 continue;
341 } 370 }
342 371
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 } 475 }
447 476
448 syncer::SyncError error = 477 syncer::SyncError error =
449 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); 478 sync_processor_->ProcessSyncChanges(FROM_HERE, changes);
450 } 479 }
451 480
452 void PrefModelAssociator::SetPrefService(PrefServiceSyncable* pref_service) { 481 void PrefModelAssociator::SetPrefService(PrefServiceSyncable* pref_service) {
453 DCHECK(pref_service_ == NULL); 482 DCHECK(pref_service_ == NULL);
454 pref_service_ = pref_service; 483 pref_service_ = pref_service;
455 } 484 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698