diff options
24 files changed, 221 insertions, 66 deletions
diff --git a/chrome/browser/prefs/pref_model_associator.cc b/chrome/browser/prefs/pref_model_associator.cc index 09e98d5..d908304 100644 --- a/chrome/browser/prefs/pref_model_associator.cc +++ b/chrome/browser/prefs/pref_model_associator.cc @@ -21,12 +21,41 @@ #include "sync/protocol/sync.pb.h" using syncer::PREFERENCES; +using syncer::PRIORITY_PREFERENCES; -PrefModelAssociator::PrefModelAssociator() +namespace { + +const sync_pb::PreferenceSpecifics& GetSpecifics(const syncer::SyncData& pref) { + DCHECK(pref.GetDataType() == syncer::PREFERENCES || + pref.GetDataType() == syncer::PRIORITY_PREFERENCES); + if (pref.GetDataType() == syncer::PRIORITY_PREFERENCES) { + return pref.GetSpecifics().priority_preference().preference(); + } else { + return pref.GetSpecifics().preference(); + } +} + +sync_pb::PreferenceSpecifics* GetMutableSpecifics( + const syncer::ModelType type, + sync_pb::EntitySpecifics* specifics) { + if (type == syncer::PRIORITY_PREFERENCES) { + DCHECK(!specifics->has_preference()); + return specifics->mutable_priority_preference()->mutable_preference(); + } else { + DCHECK(!specifics->has_priority_preference()); + return specifics->mutable_preference(); + } +} + +} // namespace + +PrefModelAssociator::PrefModelAssociator(syncer::ModelType type) : models_associated_(false), processing_syncer_changes_(false), - pref_service_(NULL) { + pref_service_(NULL), + type_(type) { DCHECK(CalledOnValidThread()); + DCHECK(type_ == PREFERENCES || type_ == PRIORITY_PREFERENCES); } PrefModelAssociator::~PrefModelAssociator() { @@ -43,8 +72,7 @@ void PrefModelAssociator::InitPrefAndAssociate( VLOG(1) << "Associating preference " << pref_name; if (sync_pref.IsValid()) { - const sync_pb::PreferenceSpecifics& preference = - sync_pref.GetSpecifics().preference(); + const sync_pb::PreferenceSpecifics& preference = GetSpecifics(sync_pref); DCHECK_EQ(pref_name, preference.name()); base::JSONReader reader; @@ -124,7 +152,7 @@ syncer::SyncMergeResult PrefModelAssociator::MergeDataAndStartSyncing( const syncer::SyncDataList& initial_sync_data, scoped_ptr<syncer::SyncChangeProcessor> sync_processor, scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { - DCHECK_EQ(type, PREFERENCES); + DCHECK_EQ(type_, type); DCHECK(CalledOnValidThread()); DCHECK(pref_service_); DCHECK(!sync_processor_.get()); @@ -143,8 +171,11 @@ syncer::SyncMergeResult PrefModelAssociator::MergeDataAndStartSyncing( initial_sync_data.begin(); sync_iter != initial_sync_data.end(); ++sync_iter) { - DCHECK_EQ(PREFERENCES, sync_iter->GetDataType()); - std::string sync_pref_name = sync_iter->GetSpecifics().preference().name(); + DCHECK_EQ(type_, sync_iter->GetDataType()); + + const sync_pb::PreferenceSpecifics& preference = GetSpecifics(*sync_iter); + const std::string& sync_pref_name = preference.name(); + if (remaining_preferences.count(sync_pref_name) == 0) { // We're not syncing this preference locally, ignore the sync data. // TODO(zea): Eventually we want to be able to have the syncable service @@ -178,7 +209,7 @@ syncer::SyncMergeResult PrefModelAssociator::MergeDataAndStartSyncing( } void PrefModelAssociator::StopSyncing(syncer::ModelType type) { - DCHECK_EQ(type, PREFERENCES); + DCHECK_EQ(type_, type); models_associated_ = false; sync_processor_.reset(); sync_error_factory_.reset(); @@ -205,7 +236,7 @@ scoped_ptr<Value> PrefModelAssociator::MergePreference( bool PrefModelAssociator::CreatePrefSyncData( const std::string& name, const Value& value, - syncer::SyncData* sync_data) { + syncer::SyncData* sync_data) const { if (value.IsType(Value::TYPE_NULL)) { LOG(ERROR) << "Attempting to sync a null pref value for " << name; return false; @@ -221,7 +252,9 @@ bool PrefModelAssociator::CreatePrefSyncData( } sync_pb::EntitySpecifics specifics; - sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); + sync_pb::PreferenceSpecifics* pref_specifics = + GetMutableSpecifics(type_, &specifics); + pref_specifics->set_name(name); pref_specifics->set_value(serialized); *sync_data = syncer::SyncData::CreateLocalData(name, name, specifics); @@ -290,7 +323,7 @@ Value* PrefModelAssociator::MergeDictionaryValues( syncer::SyncDataList PrefModelAssociator::GetAllSyncData( syncer::ModelType type) const { - DCHECK_EQ(PREFERENCES, type); + DCHECK_EQ(type_, type); syncer::SyncDataList current_data; for (PreferenceSet::const_iterator iter = synced_preferences_.begin(); iter != synced_preferences_.end(); @@ -322,11 +355,12 @@ syncer::SyncError PrefModelAssociator::ProcessSyncChanges( base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); syncer::SyncChangeList::const_iterator iter; for (iter = change_list.begin(); iter != change_list.end(); ++iter) { - DCHECK_EQ(PREFERENCES, iter->sync_data().GetDataType()); + DCHECK_EQ(type_, iter->sync_data().GetDataType()); std::string name; - sync_pb::PreferenceSpecifics pref_specifics = - iter->sync_data().GetSpecifics().preference(); + const sync_pb::PreferenceSpecifics& pref_specifics = + GetSpecifics(iter->sync_data()); + scoped_ptr<Value> value(ReadPreferenceSpecifics(pref_specifics, &name)); diff --git a/chrome/browser/prefs/pref_model_associator.h b/chrome/browser/prefs/pref_model_associator.h index eb815e3..2bfe0cd 100644 --- a/chrome/browser/prefs/pref_model_associator.h +++ b/chrome/browser/prefs/pref_model_associator.h @@ -33,7 +33,7 @@ class PrefModelAssociator : public syncer::SyncableService, public base::NonThreadSafe { public: - PrefModelAssociator(); + explicit PrefModelAssociator(syncer::ModelType type); virtual ~PrefModelAssociator(); // See description above field for details. @@ -84,9 +84,9 @@ class PrefModelAssociator // Fills |sync_data| with a sync representation of the preference data // provided. - static bool CreatePrefSyncData(const std::string& name, - const base::Value& value, - syncer::SyncData* sync_data); + bool CreatePrefSyncData(const std::string& name, + const base::Value& value, + syncer::SyncData* sync_data) const; // Extract preference value and name from sync specifics. base::Value* ReadPreferenceSpecifics( @@ -149,6 +149,10 @@ class PrefModelAssociator // Sync's error handler. We use this to create sync errors. scoped_ptr<syncer::SyncErrorFactory> sync_error_factory_; + // The datatype that this associator is responible for, either PREFERENCES or + // PRIORITY_PREFERENCES. + syncer::ModelType type_; + DISALLOW_COPY_AND_ASSIGN(PrefModelAssociator); }; diff --git a/chrome/browser/prefs/pref_service_syncable.cc b/chrome/browser/prefs/pref_service_syncable.cc index 8f2f867..b5e0267 100644 --- a/chrome/browser/prefs/pref_service_syncable.cc +++ b/chrome/browser/prefs/pref_service_syncable.cc @@ -43,21 +43,25 @@ PrefServiceSyncable::PrefServiceSyncable( user_prefs, pref_registry, read_error_callback, - async) { + async), + pref_sync_associator_(syncer::PREFERENCES), + priority_pref_sync_associator_(syncer::PRIORITY_PREFERENCES) { pref_sync_associator_.SetPrefService(this); + priority_pref_sync_associator_.SetPrefService(this); - // Let PrefModelAssociator know about changes to preference values. + // Let PrefModelAssociators know about changes to preference values. pref_value_store->set_callback( - base::Bind(&PrefModelAssociator::ProcessPrefChange, - base::Unretained(&pref_sync_associator_))); + base::Bind(&PrefServiceSyncable::ProcessPrefChange, + base::Unretained(this))); // Add already-registered syncable preferences to PrefModelAssociator. - const std::set<std::string>& syncable_preferences = + const PrefRegistrySyncable::PrefToStatus& syncable_preferences = pref_registry->syncable_preferences(); - for (std::set<std::string>::const_iterator it = syncable_preferences.begin(); + for (PrefRegistrySyncable::PrefToStatus::const_iterator it = + syncable_preferences.begin(); it != syncable_preferences.end(); ++it) { - AddRegisteredSyncablePreference(it->c_str()); + AddRegisteredSyncablePreference(it->first.c_str(), it->second); } // Watch for syncable preferences registered after this point. @@ -106,6 +110,11 @@ bool PrefServiceSyncable::IsSyncing() { return pref_sync_associator_.models_associated(); } + +bool PrefServiceSyncable::IsPrioritySyncing() { + return priority_pref_sync_associator_.models_associated(); +} + void PrefServiceSyncable::AddObserver(PrefServiceSyncableObserver* observer) { observer_list_.AddObserver(observer); } @@ -115,8 +124,16 @@ void PrefServiceSyncable::RemoveObserver( observer_list_.RemoveObserver(observer); } -syncer::SyncableService* PrefServiceSyncable::GetSyncableService() { - return &pref_sync_associator_; +syncer::SyncableService* PrefServiceSyncable::GetSyncableService( + const syncer::ModelType& type) { + if (type == syncer::PREFERENCES) { + return &pref_sync_associator_; + } else if (type == syncer::PRIORITY_PREFERENCES) { + return &priority_pref_sync_associator_; + } else { + NOTREACHED() << "invalid model type: " << type; + return NULL; + } } void PrefServiceSyncable::UpdateCommandLinePrefStore( @@ -127,12 +144,25 @@ void PrefServiceSyncable::UpdateCommandLinePrefStore( PrefService::UpdateCommandLinePrefStore(cmd_line_store); } -void PrefServiceSyncable::AddRegisteredSyncablePreference(const char* path) { +void PrefServiceSyncable::AddRegisteredSyncablePreference( + const char* path, + const PrefRegistrySyncable::PrefSyncStatus sync_status) { DCHECK(FindPreference(path)); - pref_sync_associator_.RegisterPref(path); + if (sync_status == PrefRegistrySyncable::SYNCABLE_PREF) { + pref_sync_associator_.RegisterPref(path); + } else if (sync_status == PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF) { + priority_pref_sync_associator_.RegisterPref(path); + } else { + NOTREACHED() << "invalid sync_status: " << sync_status; + } } void PrefServiceSyncable::OnIsSyncingChanged() { FOR_EACH_OBSERVER(PrefServiceSyncableObserver, observer_list_, OnIsSyncingChanged()); } + +void PrefServiceSyncable::ProcessPrefChange(const std::string& name) { + pref_sync_associator_.ProcessPrefChange(name); + priority_pref_sync_associator_.ProcessPrefChange(name); +} diff --git a/chrome/browser/prefs/pref_service_syncable.h b/chrome/browser/prefs/pref_service_syncable.h index 18926b6..971a922 100644 --- a/chrome/browser/prefs/pref_service_syncable.h +++ b/chrome/browser/prefs/pref_service_syncable.h @@ -7,6 +7,7 @@ #include "base/prefs/pref_service.h" #include "chrome/browser/prefs/pref_model_associator.h" +#include "components/user_prefs/pref_registry_syncable.h" class PrefRegistrySyncable; class PrefServiceSyncableObserver; @@ -56,14 +57,22 @@ class PrefServiceSyncable : public PrefService { // preferences. If true is returned it can be assumed the local preferences // has applied changes from the remote preferences. The two may not be // identical if a change is in flight (from either side). + // + // TODO(albertb): Given that we now support priority preferences, callers of + // this method are likely better off making the preferences they care about + // into priority preferences and calling IsPrioritySyncing(). bool IsSyncing(); + // Returns true if priority preferences state has synchronized with the remote + // priority preferences. + bool IsPrioritySyncing(); + void AddObserver(PrefServiceSyncableObserver* observer); void RemoveObserver(PrefServiceSyncableObserver* observer); // TODO(zea): Have PrefServiceSyncable implement // syncer::SyncableService directly. - syncer::SyncableService* GetSyncableService(); + syncer::SyncableService* GetSyncableService(const syncer::ModelType& type); // Do not call this after having derived an incognito or per tab pref service. virtual void UpdateCommandLinePrefStore(PrefStore* cmd_line_store) OVERRIDE; @@ -71,16 +80,23 @@ class PrefServiceSyncable : public PrefService { private: friend class PrefModelAssociator; - void AddRegisteredSyncablePreference(const char* path); + void AddRegisteredSyncablePreference( + const char* path, + const PrefRegistrySyncable::PrefSyncStatus sync_status); // Invoked internally when the IsSyncing() state changes. void OnIsSyncingChanged(); + // Process a local preference change. This can trigger new SyncChanges being + // sent to the syncer. + void ProcessPrefChange(const std::string& name); + // Whether CreateIncognitoPrefService() has been called to create a // "forked" PrefService. bool pref_service_forked_; PrefModelAssociator pref_sync_associator_; + PrefModelAssociator priority_pref_sync_associator_; ObserverList<PrefServiceSyncableObserver> observer_list_; diff --git a/chrome/browser/sync/profile_sync_components_factory_impl.cc b/chrome/browser/sync/profile_sync_components_factory_impl.cc index aace606..10fb96a 100644 --- a/chrome/browser/sync/profile_sync_components_factory_impl.cc +++ b/chrome/browser/sync/profile_sync_components_factory_impl.cc @@ -205,6 +205,13 @@ void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes( if (!command_line_->HasSwitch(switches::kDisableSyncPreferences)) { pss->RegisterDataTypeController( new UIDataTypeController(syncer::PREFERENCES, this, profile_, pss)); + + } + + if (!command_line_->HasSwitch(switches::kDisableSyncPriorityPreferences)) { + pss->RegisterDataTypeController( + new UIDataTypeController(syncer::PRIORITY_PREFERENCES, + this, profile_, pss)); } #if defined(ENABLE_THEMES) @@ -298,7 +305,10 @@ base::WeakPtr<syncer::SyncableService> ProfileSyncComponentsFactoryImpl:: switch (type) { case syncer::PREFERENCES: return PrefServiceSyncable::FromProfile( - profile_)->GetSyncableService()->AsWeakPtr(); + profile_)->GetSyncableService(syncer::PREFERENCES)->AsWeakPtr(); + case syncer::PRIORITY_PREFERENCES: + return PrefServiceSyncable::FromProfile(profile_)->GetSyncableService( + syncer::PRIORITY_PREFERENCES)->AsWeakPtr(); case syncer::AUTOFILL: case syncer::AUTOFILL_PROFILE: { if (!web_data_service_.get()) diff --git a/chrome/browser/sync/profile_sync_components_factory_impl_unittest.cc b/chrome/browser/sync/profile_sync_components_factory_impl_unittest.cc index 7e30fca..ad3a0ed 100644 --- a/chrome/browser/sync/profile_sync_components_factory_impl_unittest.cc +++ b/chrome/browser/sync/profile_sync_components_factory_impl_unittest.cc @@ -45,6 +45,7 @@ class ProfileSyncComponentsFactoryImplTest : public testing::Test { datatypes.push_back(syncer::EXTENSION_SETTINGS); datatypes.push_back(syncer::PASSWORDS); datatypes.push_back(syncer::PREFERENCES); + datatypes.push_back(syncer::PRIORITY_PREFERENCES); datatypes.push_back(syncer::SEARCH_ENGINES); datatypes.push_back(syncer::SESSIONS); datatypes.push_back(syncer::PROXY_TABS); diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index 8db6c45..35e5681 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -1513,6 +1513,17 @@ SyncBackendHost* ProfileSyncService::GetBackendForTest() { return backend_.get(); } +void ProfileSyncService::ConfigurePriorityDataTypes() { + const syncer::ModelTypeSet priority_types = + Intersection(GetPreferredDataTypes(), syncer::PriorityUserTypes()); + if (!priority_types.Empty()) { + const syncer::ConfigureReason reason = HasSyncSetupCompleted() ? + syncer::CONFIGURE_REASON_RECONFIGURATION : + syncer::CONFIGURE_REASON_NEW_CLIENT; + data_type_manager_->Configure(priority_types, reason); + } +} + void ProfileSyncService::ConfigureDataTypeManager() { // Don't configure datatypes if the setup UI is still on the screen - this // is to help multi-screen setting UIs (like iOS) where they don't want to @@ -1540,6 +1551,7 @@ void ProfileSyncService::ConfigureDataTypeManager() { base::Bind(&ProfileSyncService::StartSyncingWithServer, base::Unretained(this)))); } + ConfigurePriorityDataTypes(); #if defined(OS_ANDROID) if (GetPreferredDataTypes().Has(syncer::PASSWORDS) && diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h index 2bf6d87..5cccdbf 100644 --- a/chrome/browser/sync/profile_sync_service.h +++ b/chrome/browser/sync/profile_sync_service.h @@ -623,6 +623,9 @@ class ProfileSyncService : public ProfileSyncServiceBase, // Used by test classes that derive from ProfileSyncService. virtual browser_sync::SyncBackendHost* GetBackendForTest(); + // Helper to configure the priority data types. + void ConfigurePriorityDataTypes(); + // Helper to install and configure a data type manager. void ConfigureDataTypeManager(); diff --git a/chrome/browser/sync/profile_sync_service_preference_unittest.cc b/chrome/browser/sync/profile_sync_service_preference_unittest.cc index 9e9fb57..70aec28 100644 --- a/chrome/browser/sync/profile_sync_service_preference_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_preference_unittest.cc @@ -156,7 +156,7 @@ class ProfileSyncServicePreferenceTest profile_.get(), &TestProfileSyncService::BuildAutoStartAsyncInit)); sync_service_->set_backend_init_callback(callback); pref_sync_service_ = reinterpret_cast<PrefModelAssociator*>( - prefs_->GetSyncableService()); + prefs_->GetSyncableService(syncer::PREFERENCES)); if (!pref_sync_service_) return false; ProfileSyncComponentsFactoryMock* components = @@ -223,9 +223,9 @@ class ProfileSyncServicePreferenceTest const Value& value, syncer::WriteNode* node) { syncer::SyncData sync_data; - if (!PrefModelAssociator::CreatePrefSyncData(name, - value, - &sync_data)) { + if (!pref_sync_service_->CreatePrefSyncData(name, + value, + &sync_data)) { return syncer::kInvalidId; } node->SetEntitySpecifics(sync_data.GetSpecifics()); @@ -301,7 +301,7 @@ TEST_F(ProfileSyncServicePreferenceTest, CreatePrefSyncData) { const PrefService::Preference* pref = prefs_->FindPreference(prefs::kHomePage); syncer::SyncData sync_data; - EXPECT_TRUE(PrefModelAssociator::CreatePrefSyncData(pref->name(), + EXPECT_TRUE(pref_sync_service_->CreatePrefSyncData(pref->name(), *pref->GetValue(), &sync_data)); EXPECT_EQ(std::string(prefs::kHomePage), sync_data.GetTag()); const sync_pb::PreferenceSpecifics& specifics(sync_data.GetSpecifics(). @@ -595,6 +595,7 @@ TEST_F(ProfileSyncServicePreferenceTest, DynamicManagedPreferences) { Value::CreateStringValue("http://example.com/initial")); profile_->GetPrefs()->Set(prefs::kHomePage, *initial_value); scoped_ptr<const Value> actual(GetSyncedValue(prefs::kHomePage)); + ASSERT_TRUE(actual.get()); EXPECT_TRUE(initial_value->Equals(actual.get())); // Switch kHomePage to managed and set a different value. diff --git a/chrome/browser/sync/sync_prefs.cc b/chrome/browser/sync/sync_prefs.cc index e26d56e..0c7a4bd 100644 --- a/chrome/browser/sync/sync_prefs.cc +++ b/chrome/browser/sync/sync_prefs.cc @@ -344,6 +344,8 @@ const char* SyncPrefs::GetPrefNameForDataType(syncer::ModelType data_type) { return prefs::kSyncFaviconTracking; case syncer::PROXY_TABS: return prefs::kSyncTabs; + case syncer::PRIORITY_PREFERENCES: + return prefs::kSyncPriorityPreferences; default: break; } @@ -409,6 +411,7 @@ void SyncPrefs::RegisterPrefGroups() { pref_groups_[syncer::EXTENSIONS].Put(syncer::EXTENSION_SETTINGS); pref_groups_[syncer::PREFERENCES].Put(syncer::DICTIONARY); + pref_groups_[syncer::PREFERENCES].Put(syncer::PRIORITY_PREFERENCES); pref_groups_[syncer::PREFERENCES].Put(syncer::SEARCH_ENGINES); pref_groups_[syncer::TYPED_URLS].Put(syncer::HISTORY_DELETE_DIRECTIVES); diff --git a/chrome/browser/sync/sync_prefs_unittest.cc b/chrome/browser/sync/sync_prefs_unittest.cc index 6b4d035..c6f1b66 100644 --- a/chrome/browser/sync/sync_prefs_unittest.cc +++ b/chrome/browser/sync/sync_prefs_unittest.cc @@ -145,6 +145,7 @@ TEST_F(SyncPrefsTest, PreferredTypesNotKeepEverythingSynced) { } if (it.Get() == syncer::PREFERENCES) { expected_preferred_types.Put(syncer::DICTIONARY); + expected_preferred_types.Put(syncer::PRIORITY_PREFERENCES); expected_preferred_types.Put(syncer::SEARCH_ENGINES); } if (it.Get() == syncer::APPS) { diff --git a/chrome/browser/sync/test/integration/enable_disable_test.cc b/chrome/browser/sync/test/integration/enable_disable_test.cc index 38ba937..244550e 100644 --- a/chrome/browser/sync/test/integration/enable_disable_test.cc +++ b/chrome/browser/sync/test/integration/enable_disable_test.cc @@ -113,7 +113,9 @@ IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, DisableOneAtATime) { // AUTOFILL_PROFILE is lumped together with AUTOFILL. // SESSIONS is lumped together with PROXY_TABS and // HISTORY_DELETE_DIRECTIVES. - if (it.Get() == syncer::AUTOFILL_PROFILE || it.Get() == syncer::SESSIONS) { + // PRIORITY_PREFERENCES is lumped together with PREFERENCES. + if (it.Get() == syncer::AUTOFILL_PROFILE || it.Get() == syncer::SESSIONS || + it.Get() == syncer::PRIORITY_PREFERENCES) { continue; } @@ -131,6 +133,9 @@ IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, DisableOneAtATime) { it.Get() == syncer::PROXY_TABS) { ASSERT_FALSE(DoesTopLevelNodeExist(user_share, syncer::SESSIONS)); + } else if (it.Get() == syncer::PREFERENCES) { + ASSERT_FALSE(DoesTopLevelNodeExist(user_share, + syncer::PRIORITY_PREFERENCES)); } } diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index 3897b99..fbe9500 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc @@ -211,6 +211,11 @@ void SyncTest::AddTestSwitches(CommandLine* cl) { if (!cl->HasSwitch(switches::kSyncShortInitialRetryOverride)) cl->AppendSwitch(switches::kSyncShortInitialRetryOverride); + + // TODO(sync): Fix enable_disable_test.cc to play nice with priority + // preferences. + if (!cl->HasSwitch(switches::kDisableSyncPriorityPreferences)) + cl->AppendSwitch(switches::kDisableSyncPriorityPreferences); } void SyncTest::AddOptionalTypesToCommandLine(CommandLine* cl) {} diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 83b40b9..2a526de 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -397,6 +397,10 @@ const char kDisableSyncPasswords[] = "disable-sync-passwords"; // Disables syncing of preferences. const char kDisableSyncPreferences[] = "disable-sync-preferences"; +// Disables syncing of priority preferences. +const char kDisableSyncPriorityPreferences[] = + "disable-sync-priority-preferences"; + // Disable syncing custom search engines. const char kDisableSyncSearchEngines[] = "disable-sync-search-engines"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 69d9bd1..2e63055 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -119,6 +119,7 @@ extern const char kDisableSyncExtensions[]; extern const char kDisableSyncHistoryDeleteDirectives[]; extern const char kDisableSyncPasswords[]; extern const char kDisableSyncPreferences[]; +extern const char kDisableSyncPriorityPreferences[]; extern const char kDisableSyncSearchEngines[]; extern const char kDisableSyncThemes[]; extern const char kDisableSyncTypedUrls[]; diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index b9b0bed..fbd98ad 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -1722,6 +1722,7 @@ const char kSyncKeepEverythingSynced[] = "sync.keep_everything_synced"; const char kSyncBookmarks[] = "sync.bookmarks"; const char kSyncPasswords[] = "sync.passwords"; const char kSyncPreferences[] = "sync.preferences"; +const char kSyncPriorityPreferences[] = "sync.priority_preferences"; const char kSyncAppNotifications[] = "sync.app_notifications"; const char kSyncAppSettings[] = "sync.app_settings"; const char kSyncApps[] = "sync.apps"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 765a1c8..5b44e9b 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -605,6 +605,7 @@ extern const char kSyncKeepEverythingSynced[]; extern const char kSyncBookmarks[]; extern const char kSyncPasswords[]; extern const char kSyncPreferences[]; +extern const char kSyncPriorityPreferences[]; extern const char kSyncAppNotifications[]; extern const char kSyncAppSettings[]; extern const char kSyncApps[]; diff --git a/components/user_prefs/pref_registry_syncable.cc b/components/user_prefs/pref_registry_syncable.cc index 874f8a6..81eb65c 100644 --- a/components/user_prefs/pref_registry_syncable.cc +++ b/components/user_prefs/pref_registry_syncable.cc @@ -62,7 +62,7 @@ PrefRegistrySyncable::PrefRegistrySyncable() { PrefRegistrySyncable::~PrefRegistrySyncable() { } -const std::set<std::string>& +const PrefRegistrySyncable::PrefToStatus& PrefRegistrySyncable::syncable_preferences() const { return syncable_preferences_; } @@ -202,11 +202,12 @@ void PrefRegistrySyncable::RegisterSyncablePreference( PrefSyncStatus sync_status) { PrefRegistry::RegisterPreference(path, default_value); - if (sync_status == SYNCABLE_PREF) { - syncable_preferences_.insert(path); + if (sync_status == PrefRegistrySyncable::SYNCABLE_PREF || + sync_status == PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF) { + syncable_preferences_[path] = sync_status; if (!callback_.is_null()) - callback_.Run(path); + callback_.Run(path, sync_status); } } diff --git a/components/user_prefs/pref_registry_syncable.h b/components/user_prefs/pref_registry_syncable.h index 08477f2..811209b 100644 --- a/components/user_prefs/pref_registry_syncable.h +++ b/components/user_prefs/pref_registry_syncable.h @@ -30,19 +30,27 @@ class Value; // does this for Chrome. class USER_PREFS_EXPORT PrefRegistrySyncable : public PrefRegistry { public: - typedef base::Callback<void(const char* path)> SyncableRegistrationCallback; - // Enum used when registering preferences to determine if it should - // be synced or not. + // be synced or not. Syncable priority preferences are preferences that are + // never encrypted and are synced before other datatypes. Because they're + // never encrypted, on first sync, they can be synced down before the user + // is prompted for a passphrase. enum PrefSyncStatus { UNSYNCABLE_PREF, - SYNCABLE_PREF + SYNCABLE_PREF, + SYNCABLE_PRIORITY_PREF, }; + typedef + base::Callback<void(const char* path, const PrefSyncStatus sync_status)> + SyncableRegistrationCallback; + PrefRegistrySyncable(); + typedef std::map<std::string, PrefSyncStatus> PrefToStatus; + // Retrieve the set of syncable preferences currently registered. - const std::set<std::string>& syncable_preferences() const; + const PrefToStatus& syncable_preferences() const; // Exactly one callback can be set for the event of a syncable // preference being registered. It will be fired after the @@ -111,7 +119,7 @@ class USER_PREFS_EXPORT PrefRegistrySyncable : public PrefRegistry { SyncableRegistrationCallback callback_; // Contains the names of all registered preferences that are syncable. - std::set<std::string> syncable_preferences_; + PrefToStatus syncable_preferences_; DISALLOW_COPY_AND_ASSIGN(PrefRegistrySyncable); }; diff --git a/sync/internal_api/public/base/model_type.h b/sync/internal_api/public/base/model_type.h index ebf7665..92df116 100644 --- a/sync/internal_api/public/base/model_type.h +++ b/sync/internal_api/public/base/model_type.h @@ -90,6 +90,9 @@ enum ModelType { FAVICON_IMAGES, // Favicon tracking information. FAVICON_TRACKING, + // These preferences are synced before other user types and are never + // encrypted. + PRIORITY_PREFERENCES, // ---- Proxy types ---- // Proxy types are excluded from the sync protocol, but are still considered @@ -113,10 +116,7 @@ enum ModelType { DEVICE_INFO, // Flags to enable experimental features. EXPERIMENTS, - // These preferences are never encrypted so that they can be applied before - // the encryption system is fully initialized. - PRIORITY_PREFERENCES, - LAST_CONTROL_MODEL_TYPE = PRIORITY_PREFERENCES, + LAST_CONTROL_MODEL_TYPE = EXPERIMENTS, LAST_REAL_MODEL_TYPE = LAST_CONTROL_MODEL_TYPE, @@ -179,6 +179,10 @@ SYNC_EXPORT bool IsUserSelectableType(ModelType model_type); // This is the subset of UserTypes() that can be encrypted. SYNC_EXPORT_PRIVATE ModelTypeSet EncryptableUserTypes(); +// This is the subset of UserTypes() that have priority over other types. These +// types are synced before other user types and are never encrypted. +SYNC_EXPORT ModelTypeSet PriorityUserTypes(); + // Proxy types are placeholder types for handling implicitly enabling real // types. They do not exist at the server, and are simply used for // UI/Configuration logic. diff --git a/sync/protocol/priority_preference_specifics.proto b/sync/protocol/priority_preference_specifics.proto index e52e0be..97b554e 100644 --- a/sync/protocol/priority_preference_specifics.proto +++ b/sync/protocol/priority_preference_specifics.proto @@ -14,8 +14,9 @@ option retain_unknown_fields = true; package sync_pb; +import "preference_specifics.proto"; + // Properties of a synced priority preference. message PriorityPreferenceSpecifics { - optional string name = 1; - optional string value = 2; + optional PreferenceSpecifics preference = 1; } diff --git a/sync/protocol/proto_value_conversions.cc b/sync/protocol/proto_value_conversions.cc index ebb4d95..d102b7c 100644 --- a/sync/protocol/proto_value_conversions.cc +++ b/sync/protocol/proto_value_conversions.cc @@ -312,14 +312,6 @@ base::DictionaryValue* BookmarkSpecificsToValue( return value; } -base::DictionaryValue* PriorityPreferenceSpecificsToValue( - const sync_pb::PriorityPreferenceSpecifics& proto) { - base::DictionaryValue* value = new base::DictionaryValue(); - SET_STR(name); - SET_STR(value); - return value; -} - base::DictionaryValue* DeviceInfoSpecificsToValue( const sync_pb::DeviceInfoSpecifics& proto) { base::DictionaryValue* value = new base::DictionaryValue(); @@ -450,6 +442,13 @@ base::DictionaryValue* PreferenceSpecificsToValue( return value; } +base::DictionaryValue* PriorityPreferenceSpecificsToValue( + const sync_pb::PriorityPreferenceSpecifics& specifics) { + base::DictionaryValue* value = new base::DictionaryValue(); + SET_FIELD(preference, PreferenceSpecificsToValue); + return value; +} + base::DictionaryValue* SyncedNotificationSpecificsToValue( const sync_pb::SyncedNotificationSpecifics& proto) { base::DictionaryValue* value = new base::DictionaryValue(); diff --git a/sync/syncable/model_type.cc b/sync/syncable/model_type.cc index 37bdd36..31120a7 100644 --- a/sync/syncable/model_type.cc +++ b/sync/syncable/model_type.cc @@ -353,6 +353,9 @@ ModelTypeSet EncryptableUserTypes() { encryptable_user_types.Remove(HISTORY_DELETE_DIRECTIVES); // Synced notifications are not encrypted since the server must see changes. encryptable_user_types.Remove(SYNCED_NOTIFICATIONS); + // Priority preferences are not encrypted because they might be synced before + // encryption is ready. + encryptable_user_types.RemoveAll(PriorityUserTypes()); // Proxy types have no sync representation and are therefore not encrypted. // Note however that proxy types map to one or more protocol types, which // may or may not be encrypted themselves. @@ -360,6 +363,10 @@ ModelTypeSet EncryptableUserTypes() { return encryptable_user_types; } +ModelTypeSet PriorityUserTypes() { + return ModelTypeSet(PRIORITY_PREFERENCES); +} + ModelTypeSet ControlTypes() { ModelTypeSet set; // TODO(sync): We should be able to build the actual enumset's internal @@ -369,9 +376,6 @@ ModelTypeSet ControlTypes() { set.Put(ModelTypeFromInt(i)); } - // TODO(albertb): Re-enable this when the server supports it. - set.Remove(PRIORITY_PREFERENCES); - return set; } diff --git a/sync/tools/testserver/chromiumsync.py b/sync/tools/testserver/chromiumsync.py index d33ed01..06dfa40 100644 --- a/sync/tools/testserver/chromiumsync.py +++ b/sync/tools/testserver/chromiumsync.py @@ -34,6 +34,7 @@ import history_delete_directive_specifics_pb2 import nigori_specifics_pb2 import password_specifics_pb2 import preference_specifics_pb2 +import priority_preference_specifics_pb2 import search_engine_specifics_pb2 import session_specifics_pb2 import sync_pb2 @@ -62,6 +63,7 @@ ALL_TYPES = ( NIGORI, PASSWORD, PREFERENCE, + PRIORITY_PREFERENCE, SEARCH_ENGINE, SESSION, SYNCED_NOTIFICATION, @@ -69,7 +71,7 @@ ALL_TYPES = ( TYPED_URL, EXTENSION_SETTINGS, FAVICON_IMAGES, - FAVICON_TRACKING) = range(23) + FAVICON_TRACKING) = range(24) # An enumeration on the frequency at which the server should send errors # to the client. This would be specified by the url that triggers the error. @@ -103,6 +105,7 @@ SYNC_TYPE_TO_DESCRIPTOR = { NIGORI: SYNC_TYPE_FIELDS['nigori'], PASSWORD: SYNC_TYPE_FIELDS['password'], PREFERENCE: SYNC_TYPE_FIELDS['preference'], + PRIORITY_PREFERENCE: SYNC_TYPE_FIELDS['priority_preference'], SEARCH_ENGINE: SYNC_TYPE_FIELDS['search_engine'], SESSION: SYNC_TYPE_FIELDS['session'], SYNCED_NOTIFICATION: SYNC_TYPE_FIELDS["synced_notification"], @@ -494,6 +497,9 @@ class SyncDataModel(object): parent_tag=ROOT_ID, sync_type=PASSWORD), PermanentItem('google_chrome_preferences', name='Preferences', parent_tag=ROOT_ID, sync_type=PREFERENCE), + PermanentItem('google_chrome_priority_preferences', + name='Priority Preferences', + parent_tag=ROOT_ID, sync_type=PRIORITY_PREFERENCE), PermanentItem('google_chrome_synced_notifications', name='Synced Notifications', parent_tag=ROOT_ID, sync_type=SYNCED_NOTIFICATION), |