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