Home | History | Annotate | Download | only in sync_driver
      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
      3 // found in the LICENSE file.
      4 
      5 #include "components/sync_driver/sync_prefs.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/prefs/pref_member.h"
      9 #include "base/prefs/pref_service.h"
     10 #include "base/strings/string_number_conversions.h"
     11 #include "base/values.h"
     12 #include "build/build_config.h"
     13 #include "components/pref_registry/pref_registry_syncable.h"
     14 #include "components/sync_driver/pref_names.h"
     15 
     16 namespace sync_driver {
     17 
     18 SyncPrefObserver::~SyncPrefObserver() {}
     19 
     20 SyncPrefs::SyncPrefs(PrefService* pref_service) : pref_service_(pref_service) {
     21   DCHECK(pref_service);
     22   RegisterPrefGroups();
     23   // Watch the preference that indicates sync is managed so we can take
     24   // appropriate action.
     25   pref_sync_managed_.Init(
     26       prefs::kSyncManaged,
     27       pref_service_,
     28       base::Bind(&SyncPrefs::OnSyncManagedPrefChanged, base::Unretained(this)));
     29 }
     30 
     31 SyncPrefs::SyncPrefs() : pref_service_(NULL) {}
     32 
     33 SyncPrefs::~SyncPrefs() { DCHECK(CalledOnValidThread()); }
     34 
     35 // static
     36 void SyncPrefs::RegisterProfilePrefs(
     37     user_prefs::PrefRegistrySyncable* registry) {
     38   registry->RegisterBooleanPref(
     39       prefs::kSyncHasSetupCompleted,
     40       false,
     41       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     42   registry->RegisterBooleanPref(
     43       prefs::kSyncSuppressStart,
     44       false,
     45       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     46   registry->RegisterInt64Pref(
     47       prefs::kSyncLastSyncedTime,
     48       0,
     49       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     50   registry->RegisterInt64Pref(
     51       prefs::kSyncFirstSyncTime,
     52       0,
     53       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     54 
     55   // All datatypes are on by default, but this gets set explicitly
     56   // when you configure sync (when turning it on), in
     57   // ProfileSyncService::OnUserChoseDatatypes.
     58   registry->RegisterBooleanPref(
     59       prefs::kSyncKeepEverythingSynced,
     60       true,
     61       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     62 
     63   syncer::ModelTypeSet user_types = syncer::UserTypes();
     64 
     65   // Include proxy types as well, as they can be individually selected,
     66   // although they don't have sync representations.
     67   user_types.PutAll(syncer::ProxyTypes());
     68 
     69   // Treat bookmarks and device info specially.
     70   RegisterDataTypePreferredPref(registry, syncer::BOOKMARKS, true);
     71   RegisterDataTypePreferredPref(registry, syncer::DEVICE_INFO, true);
     72   user_types.Remove(syncer::BOOKMARKS);
     73   user_types.Remove(syncer::DEVICE_INFO);
     74 
     75   // These two prefs are set from sync experiment to enable enhanced bookmarks.
     76   registry->RegisterIntegerPref(
     77       prefs::kEnhancedBookmarksExperimentEnabled,
     78       0,
     79       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     80 
     81   registry->RegisterStringPref(
     82       prefs::kEnhancedBookmarksExtensionId,
     83       std::string(),
     84       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     85 
     86   // All types are set to off by default, which forces a configuration to
     87   // explicitly enable them. GetPreferredTypes() will ensure that any new
     88   // implicit types are enabled when their pref group is, or via
     89   // KeepEverythingSynced.
     90   for (syncer::ModelTypeSet::Iterator it = user_types.First(); it.Good();
     91        it.Inc()) {
     92     RegisterDataTypePreferredPref(registry, it.Get(), false);
     93   }
     94 
     95   registry->RegisterBooleanPref(
     96       prefs::kSyncManaged,
     97       false,
     98       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     99   registry->RegisterStringPref(
    100       prefs::kSyncEncryptionBootstrapToken,
    101       std::string(),
    102       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    103   registry->RegisterStringPref(
    104       prefs::kSyncKeystoreEncryptionBootstrapToken,
    105       std::string(),
    106       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    107 #if defined(OS_CHROMEOS)
    108   registry->RegisterStringPref(
    109       prefs::kSyncSpareBootstrapToken,
    110       "",
    111       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    112 #endif
    113 
    114   registry->RegisterBooleanPref(
    115       prefs::kSyncHasAuthError,
    116       false,
    117       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    118 
    119   registry->RegisterStringPref(
    120       prefs::kSyncSessionsGUID,
    121       std::string(),
    122       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    123 
    124   // We will start prompting people about new data types after the launch of
    125   // SESSIONS - all previously launched data types are treated as if they are
    126   // already acknowledged.
    127   syncer::ModelTypeSet model_set;
    128   model_set.Put(syncer::BOOKMARKS);
    129   model_set.Put(syncer::PREFERENCES);
    130   model_set.Put(syncer::PASSWORDS);
    131   model_set.Put(syncer::AUTOFILL_PROFILE);
    132   model_set.Put(syncer::AUTOFILL);
    133   model_set.Put(syncer::THEMES);
    134   model_set.Put(syncer::EXTENSIONS);
    135   model_set.Put(syncer::NIGORI);
    136   model_set.Put(syncer::SEARCH_ENGINES);
    137   model_set.Put(syncer::APPS);
    138   model_set.Put(syncer::APP_LIST);
    139   model_set.Put(syncer::TYPED_URLS);
    140   model_set.Put(syncer::SESSIONS);
    141   model_set.Put(syncer::ARTICLES);
    142   registry->RegisterListPref(prefs::kSyncAcknowledgedSyncTypes,
    143                              syncer::ModelTypeSetToValue(model_set),
    144                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    145 
    146   registry->RegisterIntegerPref(
    147       prefs::kSyncRemainingRollbackTries, 0,
    148       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    149 }
    150 
    151 void SyncPrefs::AddSyncPrefObserver(SyncPrefObserver* sync_pref_observer) {
    152   DCHECK(CalledOnValidThread());
    153   sync_pref_observers_.AddObserver(sync_pref_observer);
    154 }
    155 
    156 void SyncPrefs::RemoveSyncPrefObserver(SyncPrefObserver* sync_pref_observer) {
    157   DCHECK(CalledOnValidThread());
    158   sync_pref_observers_.RemoveObserver(sync_pref_observer);
    159 }
    160 
    161 void SyncPrefs::ClearPreferences() {
    162   DCHECK(CalledOnValidThread());
    163   pref_service_->ClearPref(prefs::kSyncLastSyncedTime);
    164   pref_service_->ClearPref(prefs::kSyncHasSetupCompleted);
    165   pref_service_->ClearPref(prefs::kSyncEncryptionBootstrapToken);
    166   pref_service_->ClearPref(prefs::kSyncKeystoreEncryptionBootstrapToken);
    167 
    168   // TODO(nick): The current behavior does not clear
    169   // e.g. prefs::kSyncBookmarks.  Is that really what we want?
    170 }
    171 
    172 bool SyncPrefs::HasSyncSetupCompleted() const {
    173   DCHECK(CalledOnValidThread());
    174   return pref_service_->GetBoolean(prefs::kSyncHasSetupCompleted);
    175 }
    176 
    177 void SyncPrefs::SetSyncSetupCompleted() {
    178   DCHECK(CalledOnValidThread());
    179   pref_service_->SetBoolean(prefs::kSyncHasSetupCompleted, true);
    180   SetStartSuppressed(false);
    181 }
    182 
    183 bool SyncPrefs::SyncHasAuthError() const {
    184   DCHECK(CalledOnValidThread());
    185   return pref_service_->GetBoolean(prefs::kSyncHasAuthError);
    186 }
    187 
    188 void SyncPrefs::SetSyncAuthError(bool error) {
    189   DCHECK(CalledOnValidThread());
    190   pref_service_->SetBoolean(prefs::kSyncHasAuthError, error);
    191 }
    192 
    193 bool SyncPrefs::IsStartSuppressed() const {
    194   DCHECK(CalledOnValidThread());
    195   return pref_service_->GetBoolean(prefs::kSyncSuppressStart);
    196 }
    197 
    198 void SyncPrefs::SetStartSuppressed(bool is_suppressed) {
    199   DCHECK(CalledOnValidThread());
    200   pref_service_->SetBoolean(prefs::kSyncSuppressStart, is_suppressed);
    201 }
    202 
    203 base::Time SyncPrefs::GetLastSyncedTime() const {
    204   DCHECK(CalledOnValidThread());
    205   return base::Time::FromInternalValue(
    206       pref_service_->GetInt64(prefs::kSyncLastSyncedTime));
    207 }
    208 
    209 void SyncPrefs::SetLastSyncedTime(base::Time time) {
    210   DCHECK(CalledOnValidThread());
    211   pref_service_->SetInt64(prefs::kSyncLastSyncedTime, time.ToInternalValue());
    212 }
    213 
    214 bool SyncPrefs::HasKeepEverythingSynced() const {
    215   DCHECK(CalledOnValidThread());
    216   return pref_service_->GetBoolean(prefs::kSyncKeepEverythingSynced);
    217 }
    218 
    219 void SyncPrefs::SetKeepEverythingSynced(bool keep_everything_synced) {
    220   DCHECK(CalledOnValidThread());
    221   pref_service_->SetBoolean(prefs::kSyncKeepEverythingSynced,
    222                             keep_everything_synced);
    223 }
    224 
    225 syncer::ModelTypeSet SyncPrefs::GetPreferredDataTypes(
    226     syncer::ModelTypeSet registered_types) const {
    227   DCHECK(CalledOnValidThread());
    228 
    229   if (pref_service_->GetBoolean(prefs::kSyncKeepEverythingSynced)) {
    230     return registered_types;
    231   }
    232 
    233   syncer::ModelTypeSet preferred_types;
    234   for (syncer::ModelTypeSet::Iterator it = registered_types.First(); it.Good();
    235        it.Inc()) {
    236     if (GetDataTypePreferred(it.Get())) {
    237       preferred_types.Put(it.Get());
    238     }
    239   }
    240   return ResolvePrefGroups(registered_types, preferred_types);
    241 }
    242 
    243 void SyncPrefs::SetPreferredDataTypes(syncer::ModelTypeSet registered_types,
    244                                       syncer::ModelTypeSet preferred_types) {
    245   DCHECK(CalledOnValidThread());
    246   DCHECK(registered_types.HasAll(preferred_types));
    247   preferred_types = ResolvePrefGroups(registered_types, preferred_types);
    248   for (syncer::ModelTypeSet::Iterator i = registered_types.First(); i.Good();
    249        i.Inc()) {
    250     SetDataTypePreferred(i.Get(), preferred_types.Has(i.Get()));
    251   }
    252 }
    253 
    254 bool SyncPrefs::IsManaged() const {
    255   DCHECK(CalledOnValidThread());
    256   return pref_service_->GetBoolean(prefs::kSyncManaged);
    257 }
    258 
    259 std::string SyncPrefs::GetEncryptionBootstrapToken() const {
    260   DCHECK(CalledOnValidThread());
    261   return pref_service_->GetString(prefs::kSyncEncryptionBootstrapToken);
    262 }
    263 
    264 void SyncPrefs::SetEncryptionBootstrapToken(const std::string& token) {
    265   DCHECK(CalledOnValidThread());
    266   pref_service_->SetString(prefs::kSyncEncryptionBootstrapToken, token);
    267 }
    268 
    269 std::string SyncPrefs::GetKeystoreEncryptionBootstrapToken() const {
    270   DCHECK(CalledOnValidThread());
    271   return pref_service_->GetString(prefs::kSyncKeystoreEncryptionBootstrapToken);
    272 }
    273 
    274 void SyncPrefs::SetKeystoreEncryptionBootstrapToken(const std::string& token) {
    275   DCHECK(CalledOnValidThread());
    276   pref_service_->SetString(prefs::kSyncKeystoreEncryptionBootstrapToken, token);
    277 }
    278 
    279 std::string SyncPrefs::GetSyncSessionsGUID() const {
    280   DCHECK(CalledOnValidThread());
    281   return pref_service_->GetString(prefs::kSyncSessionsGUID);
    282 }
    283 
    284 void SyncPrefs::SetSyncSessionsGUID(const std::string& guid) {
    285   DCHECK(CalledOnValidThread());
    286   pref_service_->SetString(prefs::kSyncSessionsGUID, guid);
    287 }
    288 
    289 // static
    290 const char* SyncPrefs::GetPrefNameForDataType(syncer::ModelType data_type) {
    291   switch (data_type) {
    292     case syncer::BOOKMARKS:
    293       return prefs::kSyncBookmarks;
    294     case syncer::PASSWORDS:
    295       return prefs::kSyncPasswords;
    296     case syncer::PREFERENCES:
    297       return prefs::kSyncPreferences;
    298     case syncer::AUTOFILL:
    299       return prefs::kSyncAutofill;
    300     case syncer::AUTOFILL_PROFILE:
    301       return prefs::kSyncAutofillProfile;
    302     case syncer::THEMES:
    303       return prefs::kSyncThemes;
    304     case syncer::TYPED_URLS:
    305       return prefs::kSyncTypedUrls;
    306     case syncer::EXTENSION_SETTINGS:
    307       return prefs::kSyncExtensionSettings;
    308     case syncer::EXTENSIONS:
    309       return prefs::kSyncExtensions;
    310     case syncer::APP_LIST:
    311       return prefs::kSyncAppList;
    312     case syncer::APP_SETTINGS:
    313       return prefs::kSyncAppSettings;
    314     case syncer::APPS:
    315       return prefs::kSyncApps;
    316     case syncer::SEARCH_ENGINES:
    317       return prefs::kSyncSearchEngines;
    318     case syncer::SESSIONS:
    319       return prefs::kSyncSessions;
    320     case syncer::APP_NOTIFICATIONS:
    321       return prefs::kSyncAppNotifications;
    322     case syncer::HISTORY_DELETE_DIRECTIVES:
    323       return prefs::kSyncHistoryDeleteDirectives;
    324     case syncer::SYNCED_NOTIFICATIONS:
    325       return prefs::kSyncSyncedNotifications;
    326     case syncer::SYNCED_NOTIFICATION_APP_INFO:
    327       return prefs::kSyncSyncedNotificationAppInfo;
    328     case syncer::DICTIONARY:
    329       return prefs::kSyncDictionary;
    330     case syncer::FAVICON_IMAGES:
    331       return prefs::kSyncFaviconImages;
    332     case syncer::FAVICON_TRACKING:
    333       return prefs::kSyncFaviconTracking;
    334     case syncer::SUPERVISED_USER_SETTINGS:
    335       return prefs::kSyncSupervisedUserSettings;
    336     case syncer::PROXY_TABS:
    337       return prefs::kSyncTabs;
    338     case syncer::PRIORITY_PREFERENCES:
    339       return prefs::kSyncPriorityPreferences;
    340     case syncer::SUPERVISED_USERS:
    341       return prefs::kSyncSupervisedUsers;
    342     case syncer::ARTICLES:
    343       return prefs::kSyncArticles;
    344     case syncer::SUPERVISED_USER_SHARED_SETTINGS:
    345       return prefs::kSyncSupervisedUserSharedSettings;
    346     case syncer::DEVICE_INFO:
    347       return prefs::kSyncDeviceInfo;
    348     default:
    349       break;
    350   }
    351   NOTREACHED() << "Type is " << data_type;
    352   return NULL;
    353 }
    354 
    355 #if defined(OS_CHROMEOS)
    356 std::string SyncPrefs::GetSpareBootstrapToken() const {
    357   DCHECK(CalledOnValidThread());
    358   return pref_service_->GetString(prefs::kSyncSpareBootstrapToken);
    359 }
    360 
    361 void SyncPrefs::SetSpareBootstrapToken(const std::string& token) {
    362   DCHECK(CalledOnValidThread());
    363   pref_service_->SetString(prefs::kSyncSpareBootstrapToken, token);
    364 }
    365 #endif
    366 
    367 void SyncPrefs::AcknowledgeSyncedTypes(syncer::ModelTypeSet types) {
    368   DCHECK(CalledOnValidThread());
    369   // Add the types to the current set of acknowledged
    370   // types, and then store the resulting set in prefs.
    371   const syncer::ModelTypeSet acknowledged_types =
    372       Union(types,
    373             syncer::ModelTypeSetFromValue(
    374                 *pref_service_->GetList(prefs::kSyncAcknowledgedSyncTypes)));
    375 
    376   scoped_ptr<base::ListValue> value(
    377       syncer::ModelTypeSetToValue(acknowledged_types));
    378   pref_service_->Set(prefs::kSyncAcknowledgedSyncTypes, *value);
    379 }
    380 
    381 int SyncPrefs::GetRemainingRollbackTries() const {
    382   return pref_service_->GetInteger(prefs::kSyncRemainingRollbackTries);
    383 }
    384 
    385 void SyncPrefs::SetRemainingRollbackTries(int times) {
    386   pref_service_->SetInteger(prefs::kSyncRemainingRollbackTries, times);
    387 }
    388 
    389 void SyncPrefs::OnSyncManagedPrefChanged() {
    390   DCHECK(CalledOnValidThread());
    391   FOR_EACH_OBSERVER(SyncPrefObserver,
    392                     sync_pref_observers_,
    393                     OnSyncManagedPrefChange(*pref_sync_managed_));
    394 }
    395 
    396 void SyncPrefs::SetManagedForTest(bool is_managed) {
    397   DCHECK(CalledOnValidThread());
    398   pref_service_->SetBoolean(prefs::kSyncManaged, is_managed);
    399 }
    400 
    401 syncer::ModelTypeSet SyncPrefs::GetAcknowledgeSyncedTypesForTest() const {
    402   DCHECK(CalledOnValidThread());
    403   return syncer::ModelTypeSetFromValue(
    404       *pref_service_->GetList(prefs::kSyncAcknowledgedSyncTypes));
    405 }
    406 
    407 void SyncPrefs::RegisterPrefGroups() {
    408   pref_groups_[syncer::APPS].Put(syncer::APP_NOTIFICATIONS);
    409   pref_groups_[syncer::APPS].Put(syncer::APP_SETTINGS);
    410   pref_groups_[syncer::APPS].Put(syncer::APP_LIST);
    411 
    412   pref_groups_[syncer::AUTOFILL].Put(syncer::AUTOFILL_PROFILE);
    413 
    414   pref_groups_[syncer::EXTENSIONS].Put(syncer::EXTENSION_SETTINGS);
    415 
    416   pref_groups_[syncer::PREFERENCES].Put(syncer::DICTIONARY);
    417   pref_groups_[syncer::PREFERENCES].Put(syncer::PRIORITY_PREFERENCES);
    418   pref_groups_[syncer::PREFERENCES].Put(syncer::SEARCH_ENGINES);
    419 
    420   pref_groups_[syncer::TYPED_URLS].Put(syncer::HISTORY_DELETE_DIRECTIVES);
    421   pref_groups_[syncer::TYPED_URLS].Put(syncer::SESSIONS);
    422   pref_groups_[syncer::TYPED_URLS].Put(syncer::FAVICON_IMAGES);
    423   pref_groups_[syncer::TYPED_URLS].Put(syncer::FAVICON_TRACKING);
    424 
    425   pref_groups_[syncer::PROXY_TABS].Put(syncer::SESSIONS);
    426   pref_groups_[syncer::PROXY_TABS].Put(syncer::FAVICON_IMAGES);
    427   pref_groups_[syncer::PROXY_TABS].Put(syncer::FAVICON_TRACKING);
    428 
    429   // TODO(zea): put favicons in the bookmarks group as well once it handles
    430   // those favicons.
    431 }
    432 
    433 // static
    434 void SyncPrefs::RegisterDataTypePreferredPref(
    435     user_prefs::PrefRegistrySyncable* registry,
    436     syncer::ModelType type,
    437     bool is_preferred) {
    438   const char* pref_name = GetPrefNameForDataType(type);
    439   if (!pref_name) {
    440     NOTREACHED();
    441     return;
    442   }
    443   registry->RegisterBooleanPref(
    444       pref_name,
    445       is_preferred,
    446       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    447 }
    448 
    449 bool SyncPrefs::GetDataTypePreferred(syncer::ModelType type) const {
    450   DCHECK(CalledOnValidThread());
    451   const char* pref_name = GetPrefNameForDataType(type);
    452   if (!pref_name) {
    453     NOTREACHED();
    454     return false;
    455   }
    456 
    457   // Device info is always enabled.
    458   if (pref_name == prefs::kSyncDeviceInfo)
    459     return true;
    460 
    461   if (type == syncer::PROXY_TABS &&
    462       pref_service_->GetUserPrefValue(pref_name) == NULL &&
    463       pref_service_->IsUserModifiablePreference(pref_name)) {
    464     // If there is no tab sync preference yet (i.e. newly enabled type),
    465     // default to the session sync preference value.
    466     pref_name = GetPrefNameForDataType(syncer::SESSIONS);
    467   }
    468 
    469   return pref_service_->GetBoolean(pref_name);
    470 }
    471 
    472 void SyncPrefs::SetDataTypePreferred(syncer::ModelType type,
    473                                      bool is_preferred) {
    474   DCHECK(CalledOnValidThread());
    475   const char* pref_name = GetPrefNameForDataType(type);
    476   if (!pref_name) {
    477     NOTREACHED();
    478     return;
    479   }
    480 
    481   // Device info is always preferred.
    482   if (type == syncer::DEVICE_INFO)
    483     return;
    484 
    485   pref_service_->SetBoolean(pref_name, is_preferred);
    486 }
    487 
    488 syncer::ModelTypeSet SyncPrefs::ResolvePrefGroups(
    489     syncer::ModelTypeSet registered_types,
    490     syncer::ModelTypeSet types) const {
    491   DCHECK(registered_types.HasAll(types));
    492   syncer::ModelTypeSet types_with_groups = types;
    493   for (PrefGroupsMap::const_iterator i = pref_groups_.begin();
    494        i != pref_groups_.end();
    495        ++i) {
    496     if (types.Has(i->first))
    497       types_with_groups.PutAll(i->second);
    498   }
    499   types_with_groups.RetainAll(registered_types);
    500   return types_with_groups;
    501 }
    502 
    503 base::Time SyncPrefs::GetFirstSyncTime() const {
    504   return base::Time::FromInternalValue(
    505       pref_service_->GetInt64(prefs::kSyncFirstSyncTime));
    506 }
    507 
    508 void SyncPrefs::SetFirstSyncTime(base::Time time) {
    509   pref_service_->SetInt64(prefs::kSyncFirstSyncTime, time.ToInternalValue());
    510 }
    511 
    512 void SyncPrefs::ClearFirstSyncTime() {
    513   pref_service_->ClearPref(prefs::kSyncFirstSyncTime);
    514 }
    515 
    516 }  // namespace sync_driver
    517