summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/prefs/pref_model_associator.cc62
-rw-r--r--chrome/browser/prefs/pref_model_associator.h12
-rw-r--r--chrome/browser/prefs/pref_service_syncable.cc52
-rw-r--r--chrome/browser/prefs/pref_service_syncable.h20
-rw-r--r--chrome/browser/sync/profile_sync_components_factory_impl.cc12
-rw-r--r--chrome/browser/sync/profile_sync_components_factory_impl_unittest.cc1
-rw-r--r--chrome/browser/sync/profile_sync_service.cc12
-rw-r--r--chrome/browser/sync/profile_sync_service.h3
-rw-r--r--chrome/browser/sync/profile_sync_service_preference_unittest.cc11
-rw-r--r--chrome/browser/sync/sync_prefs.cc3
-rw-r--r--chrome/browser/sync/sync_prefs_unittest.cc1
-rw-r--r--chrome/browser/sync/test/integration/enable_disable_test.cc7
-rw-r--r--chrome/browser/sync/test/integration/sync_test.cc5
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/pref_names.cc1
-rw-r--r--chrome/common/pref_names.h1
-rw-r--r--components/user_prefs/pref_registry_syncable.cc9
-rw-r--r--components/user_prefs/pref_registry_syncable.h20
-rw-r--r--sync/internal_api/public/base/model_type.h12
-rw-r--r--sync/protocol/priority_preference_specifics.proto5
-rw-r--r--sync/protocol/proto_value_conversions.cc15
-rw-r--r--sync/syncable/model_type.cc10
-rw-r--r--sync/tools/testserver/chromiumsync.py8
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),