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/stl_util.h" | 13 #include "base/stl_util.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
15 #include "base/values.h" | 15 #include "base/values.h" |
16 #include "chrome/browser/prefs/pref_model_associator_client.h" | |
16 #include "chrome/browser/prefs/pref_service_syncable.h" | 17 #include "chrome/browser/prefs/pref_service_syncable.h" |
17 #include "chrome/common/pref_names.h" | |
18 #include "components/content_settings/core/browser/website_settings_info.h" | |
19 #include "components/content_settings/core/browser/website_settings_registry.h" | |
20 #include "sync/api/sync_change.h" | 18 #include "sync/api/sync_change.h" |
21 #include "sync/api/sync_error_factory.h" | 19 #include "sync/api/sync_error_factory.h" |
22 #include "sync/protocol/preference_specifics.pb.h" | 20 #include "sync/protocol/preference_specifics.pb.h" |
23 #include "sync/protocol/sync.pb.h" | 21 #include "sync/protocol/sync.pb.h" |
24 | 22 |
25 using syncer::PREFERENCES; | 23 using syncer::PREFERENCES; |
26 using syncer::PRIORITY_PREFERENCES; | 24 using syncer::PRIORITY_PREFERENCES; |
27 | 25 |
28 namespace { | 26 namespace { |
29 | 27 |
(...skipping 18 matching lines...) Expand all Loading... | |
48 return specifics->mutable_preference(); | 46 return specifics->mutable_preference(); |
49 } | 47 } |
50 } | 48 } |
51 | 49 |
52 } // namespace | 50 } // namespace |
53 | 51 |
54 PrefModelAssociator::PrefModelAssociator(syncer::ModelType type) | 52 PrefModelAssociator::PrefModelAssociator(syncer::ModelType type) |
55 : models_associated_(false), | 53 : models_associated_(false), |
56 processing_syncer_changes_(false), | 54 processing_syncer_changes_(false), |
57 pref_service_(NULL), | 55 pref_service_(NULL), |
58 type_(type) { | 56 type_(type), |
57 pref_model_associator_client_(NULL) { | |
59 DCHECK(CalledOnValidThread()); | 58 DCHECK(CalledOnValidThread()); |
60 DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); | 59 DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); |
61 } | 60 } |
62 | 61 |
63 PrefModelAssociator::~PrefModelAssociator() { | 62 PrefModelAssociator::~PrefModelAssociator() { |
64 DCHECK(CalledOnValidThread()); | 63 DCHECK(CalledOnValidThread()); |
65 pref_service_ = NULL; | 64 pref_service_ = NULL; |
66 | 65 |
67 STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), | 66 STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), |
68 synced_pref_observers_.end()); | 67 synced_pref_observers_.end()); |
69 synced_pref_observers_.clear(); | 68 synced_pref_observers_.clear(); |
70 } | 69 } |
71 | 70 |
72 void PrefModelAssociator::InitPrefAndAssociate( | 71 void PrefModelAssociator::InitPrefAndAssociate( |
73 const syncer::SyncData& sync_pref, | 72 const syncer::SyncData& sync_pref, |
74 const std::string& pref_name, | 73 const std::string& pref_name, |
75 syncer::SyncChangeList* sync_changes) { | 74 syncer::SyncChangeList* sync_changes) { |
76 const base::Value* user_pref_value = pref_service_->GetUserPrefValue( | 75 const base::Value* user_pref_value = |
77 pref_name.c_str()); | 76 pref_service_->GetUserPrefValue(pref_name.c_str()); |
78 VLOG(1) << "Associating preference " << pref_name; | 77 VLOG(1) << "Associating preference " << pref_name; |
79 | 78 |
80 if (sync_pref.IsValid()) { | 79 if (sync_pref.IsValid()) { |
81 const sync_pb::PreferenceSpecifics& preference = GetSpecifics(sync_pref); | 80 const sync_pb::PreferenceSpecifics& preference = GetSpecifics(sync_pref); |
82 DCHECK(pref_name == preference.name()); | 81 DCHECK(pref_name == preference.name()); |
83 base::JSONReader reader; | 82 base::JSONReader reader; |
84 scoped_ptr<base::Value> sync_value(reader.ReadToValue(preference.value())); | 83 scoped_ptr<base::Value> sync_value(reader.ReadToValue(preference.value())); |
85 if (!sync_value.get()) { | 84 if (!sync_value.get()) { |
86 LOG(ERROR) << "Failed to deserialize preference value: " | 85 LOG(ERROR) << "Failed to deserialize preference value: " |
87 << reader.GetErrorMessage(); | 86 << reader.GetErrorMessage(); |
88 return; | 87 return; |
89 } | 88 } |
90 | 89 |
91 if (user_pref_value) { | 90 if (user_pref_value) { |
92 DVLOG(1) << "Found user pref value for " << pref_name; | 91 DVLOG(1) << "Found user pref value for " << pref_name; |
93 // We have both server and local values. Merge them. | 92 // We have both server and local values. Merge them. |
94 scoped_ptr<base::Value> new_value( | 93 scoped_ptr<base::Value> new_value( |
95 MergePreference(pref_name, *user_pref_value, *sync_value)); | 94 MergePreference(pref_name, *user_pref_value, *sync_value, |
95 pref_model_associator_client_)); | |
96 | 96 |
97 // Update the local preference based on what we got from the | 97 // Update the local preference based on what we got from the |
98 // sync server. Note: this only updates the user value store, which is | 98 // sync server. Note: this only updates the user value store, which is |
99 // ignored if the preference is policy controlled. | 99 // ignored if the preference is policy controlled. |
100 if (new_value->IsType(base::Value::TYPE_NULL)) { | 100 if (new_value->IsType(base::Value::TYPE_NULL)) { |
101 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); | 101 LOG(WARNING) << "Sync has null value for pref " << pref_name.c_str(); |
102 pref_service_->ClearPref(pref_name.c_str()); | 102 pref_service_->ClearPref(pref_name.c_str()); |
103 } else if (!new_value->IsType(user_pref_value->GetType())) { | 103 } else if (!new_value->IsType(user_pref_value->GetType())) { |
104 LOG(WARNING) << "Synced value for " << preference.name() | 104 LOG(WARNING) << "Synced value for " << preference.name() |
105 << " is of type " << new_value->GetType() | 105 << " is of type " << new_value->GetType() |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 } | 210 } |
211 | 211 |
212 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { | 212 void PrefModelAssociator::StopSyncing(syncer::ModelType type) { |
213 DCHECK_EQ(type_, type); | 213 DCHECK_EQ(type_, type); |
214 models_associated_ = false; | 214 models_associated_ = false; |
215 sync_processor_.reset(); | 215 sync_processor_.reset(); |
216 sync_error_factory_.reset(); | 216 sync_error_factory_.reset(); |
217 pref_service_->OnIsSyncingChanged(); | 217 pref_service_->OnIsSyncingChanged(); |
218 } | 218 } |
219 | 219 |
220 // static | |
220 scoped_ptr<base::Value> PrefModelAssociator::MergePreference( | 221 scoped_ptr<base::Value> PrefModelAssociator::MergePreference( |
221 const std::string& name, | 222 const std::string& name, |
222 const base::Value& local_value, | 223 const base::Value& local_value, |
223 const base::Value& server_value) { | 224 const base::Value& server_value, |
225 PrefModelAssociatorClient* pref_model_associator_client) { | |
gab
2015/09/10 14:15:09
Can we make this a member method and have it use |
| |
224 // This function special cases preferences individually, so don't attempt | 226 // This function special cases preferences individually, so don't attempt |
225 // to merge for all migrated values. | 227 // to merge for all migrated values. |
226 if (name == prefs::kURLsToRestoreOnStartup) | 228 PrefModelAssociatorPreferenceType pref_type; |
227 return make_scoped_ptr(MergeListValues(local_value, server_value)); | 229 if (pref_model_associator_client && |
228 | 230 pref_model_associator_client->IsPreferenceMerged(name, &pref_type)) { |
229 content_settings::WebsiteSettingsRegistry* registry = | 231 switch (pref_type) { |
230 content_settings::WebsiteSettingsRegistry::GetInstance(); | 232 case PREF_MODEL_PREFERENCE_TYPE_LIST: |
231 for (const content_settings::WebsiteSettingsInfo* info : *registry) { | 233 return make_scoped_ptr(MergeListValues(local_value, server_value)); |
232 if (info->pref_name() == name) | 234 case PREF_MODEL_PREFERENCE_TYPE_DICT: |
233 return make_scoped_ptr(MergeDictionaryValues(local_value, server_value)); | 235 return make_scoped_ptr( |
236 MergeDictionaryValues(local_value, server_value)); | |
237 } | |
234 } | 238 } |
235 | 239 |
236 // If this is not a specially handled preference, server wins. | 240 // If this is not a specially handled preference, server wins. |
237 return make_scoped_ptr(server_value.DeepCopy()); | 241 return make_scoped_ptr(server_value.DeepCopy()); |
238 } | 242 } |
239 | 243 |
240 bool PrefModelAssociator::CreatePrefSyncData( | 244 bool PrefModelAssociator::CreatePrefSyncData( |
241 const std::string& name, | 245 const std::string& name, |
242 const base::Value& value, | 246 const base::Value& value, |
243 syncer::SyncData* sync_data) const { | 247 syncer::SyncData* sync_data) const { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 } | 326 } |
323 } | 327 } |
324 return result; | 328 return result; |
325 } | 329 } |
326 | 330 |
327 // Note: This will build a model of all preferences registered as syncable | 331 // Note: This will build a model of all preferences registered as syncable |
328 // with user controlled data. We do not track any information for preferences | 332 // with user controlled data. We do not track any information for preferences |
329 // not registered locally as syncable and do not inform the syncer of | 333 // not registered locally as syncable and do not inform the syncer of |
330 // non-user controlled preferences. | 334 // non-user controlled preferences. |
331 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( | 335 syncer::SyncDataList PrefModelAssociator::GetAllSyncData( |
332 syncer::ModelType type) | 336 syncer::ModelType type) const { |
333 const { | |
334 DCHECK_EQ(type_, type); | 337 DCHECK_EQ(type_, type); |
335 syncer::SyncDataList current_data; | 338 syncer::SyncDataList current_data; |
336 for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); | 339 for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); |
337 iter != synced_preferences_.end(); | 340 iter != synced_preferences_.end(); |
338 ++iter) { | 341 ++iter) { |
339 std::string name = *iter; | 342 std::string name = *iter; |
340 const PrefService::Preference* pref = | 343 const PrefService::Preference* pref = |
341 pref_service_->FindPreference(name.c_str()); | 344 pref_service_->FindPreference(name.c_str()); |
342 DCHECK(pref); | 345 DCHECK(pref); |
343 if (!pref->IsUserControlled() || pref->IsDefaultValue()) | 346 if (!pref->IsUserControlled() || pref->IsDefaultValue()) |
344 continue; // This is not data we care about. | 347 continue; // This is not data we care about. |
345 // TODO(zea): plumb a way to read the user controlled value. | 348 // TODO(zea): plumb a way to read the user controlled value. |
346 syncer::SyncData sync_data; | 349 syncer::SyncData sync_data; |
347 if (!CreatePrefSyncData(name, *pref->GetValue(), &sync_data)) | 350 if (!CreatePrefSyncData(name, *pref->GetValue(), &sync_data)) |
348 continue; | 351 continue; |
349 current_data.push_back(sync_data); | 352 current_data.push_back(sync_data); |
350 } | 353 } |
351 return current_data; | 354 return current_data; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
404 } | 407 } |
405 } | 408 } |
406 return syncer::SyncError(); | 409 return syncer::SyncError(); |
407 } | 410 } |
408 | 411 |
409 base::Value* PrefModelAssociator::ReadPreferenceSpecifics( | 412 base::Value* PrefModelAssociator::ReadPreferenceSpecifics( |
410 const sync_pb::PreferenceSpecifics& preference) { | 413 const sync_pb::PreferenceSpecifics& preference) { |
411 base::JSONReader reader; | 414 base::JSONReader reader; |
412 scoped_ptr<base::Value> value(reader.ReadToValue(preference.value())); | 415 scoped_ptr<base::Value> value(reader.ReadToValue(preference.value())); |
413 if (!value.get()) { | 416 if (!value.get()) { |
414 std::string err = "Failed to deserialize preference value: " + | 417 std::string err = |
415 reader.GetErrorMessage(); | 418 "Failed to deserialize preference value: " + reader.GetErrorMessage(); |
416 LOG(ERROR) << err; | 419 LOG(ERROR) << err; |
417 return NULL; | 420 return NULL; |
418 } | 421 } |
419 return value.release(); | 422 return value.release(); |
420 } | 423 } |
421 | 424 |
422 bool PrefModelAssociator::IsPrefSynced(const std::string& name) const { | 425 bool PrefModelAssociator::IsPrefSynced(const std::string& name) const { |
423 return synced_preferences_.find(name) != synced_preferences_.end(); | 426 return synced_preferences_.find(name) != synced_preferences_.end(); |
424 } | 427 } |
425 | 428 |
426 void PrefModelAssociator::AddSyncedPrefObserver(const std::string& name, | 429 void PrefModelAssociator::AddSyncedPrefObserver(const std::string& name, |
427 SyncedPrefObserver* observer) { | 430 SyncedPrefObserver* observer) { |
428 SyncedPrefObserverList* observers = synced_pref_observers_[name]; | 431 SyncedPrefObserverList* observers = synced_pref_observers_[name]; |
429 if (observers == NULL) { | 432 if (observers == NULL) { |
430 observers = new SyncedPrefObserverList; | 433 observers = new SyncedPrefObserverList; |
431 synced_pref_observers_[name] = observers; | 434 synced_pref_observers_[name] = observers; |
432 } | 435 } |
433 observers->AddObserver(observer); | 436 observers->AddObserver(observer); |
434 } | 437 } |
435 | 438 |
436 void PrefModelAssociator::RemoveSyncedPrefObserver(const std::string& name, | 439 void PrefModelAssociator::RemoveSyncedPrefObserver( |
440 const std::string& name, | |
437 SyncedPrefObserver* observer) { | 441 SyncedPrefObserver* observer) { |
438 SyncedPrefObserverMap::iterator observer_iter = | 442 SyncedPrefObserverMap::iterator observer_iter = |
439 synced_pref_observers_.find(name); | 443 synced_pref_observers_.find(name); |
440 if (observer_iter == synced_pref_observers_.end()) | 444 if (observer_iter == synced_pref_observers_.end()) |
441 return; | 445 return; |
442 SyncedPrefObserverList* observers = observer_iter->second; | 446 SyncedPrefObserverList* observers = observer_iter->second; |
443 observers->RemoveObserver(observer); | 447 observers->RemoveObserver(observer); |
444 } | 448 } |
445 | 449 |
446 std::set<std::string> PrefModelAssociator::registered_preferences() const { | 450 std::set<std::string> PrefModelAssociator::registered_preferences() const { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
516 void PrefModelAssociator::NotifySyncedPrefObservers(const std::string& path, | 520 void PrefModelAssociator::NotifySyncedPrefObservers(const std::string& path, |
517 bool from_sync) const { | 521 bool from_sync) const { |
518 SyncedPrefObserverMap::const_iterator observer_iter = | 522 SyncedPrefObserverMap::const_iterator observer_iter = |
519 synced_pref_observers_.find(path); | 523 synced_pref_observers_.find(path); |
520 if (observer_iter == synced_pref_observers_.end()) | 524 if (observer_iter == synced_pref_observers_.end()) |
521 return; | 525 return; |
522 SyncedPrefObserverList* observers = observer_iter->second; | 526 SyncedPrefObserverList* observers = observer_iter->second; |
523 FOR_EACH_OBSERVER(SyncedPrefObserver, *observers, | 527 FOR_EACH_OBSERVER(SyncedPrefObserver, *observers, |
524 OnSyncedPrefChanged(path, from_sync)); | 528 OnSyncedPrefChanged(path, from_sync)); |
525 } | 529 } |
OLD | NEW |