• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
~SyncPrefObserver()19 SyncPrefObserver::~SyncPrefObserver() {}
20 
SyncPrefs(PrefService * pref_service)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 
SyncPrefs()32 SyncPrefs::SyncPrefs() : pref_service_(NULL) {}
33 
~SyncPrefs()34 SyncPrefs::~SyncPrefs() { DCHECK(CalledOnValidThread()); }
35 
36 // static
RegisterProfilePrefs(user_prefs::PrefRegistrySyncable * registry)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 
AddSyncPrefObserver(SyncPrefObserver * sync_pref_observer)150 void SyncPrefs::AddSyncPrefObserver(SyncPrefObserver* sync_pref_observer) {
151   DCHECK(CalledOnValidThread());
152   sync_pref_observers_.AddObserver(sync_pref_observer);
153 }
154 
RemoveSyncPrefObserver(SyncPrefObserver * sync_pref_observer)155 void SyncPrefs::RemoveSyncPrefObserver(SyncPrefObserver* sync_pref_observer) {
156   DCHECK(CalledOnValidThread());
157   sync_pref_observers_.RemoveObserver(sync_pref_observer);
158 }
159 
ClearPreferences()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 
HasSyncSetupCompleted() const171 bool SyncPrefs::HasSyncSetupCompleted() const {
172   DCHECK(CalledOnValidThread());
173   return pref_service_->GetBoolean(prefs::kSyncHasSetupCompleted);
174 }
175 
SetSyncSetupCompleted()176 void SyncPrefs::SetSyncSetupCompleted() {
177   DCHECK(CalledOnValidThread());
178   pref_service_->SetBoolean(prefs::kSyncHasSetupCompleted, true);
179   SetStartSuppressed(false);
180 }
181 
SyncHasAuthError() const182 bool SyncPrefs::SyncHasAuthError() const {
183   DCHECK(CalledOnValidThread());
184   return pref_service_->GetBoolean(prefs::kSyncHasAuthError);
185 }
186 
SetSyncAuthError(bool error)187 void SyncPrefs::SetSyncAuthError(bool error) {
188   DCHECK(CalledOnValidThread());
189   pref_service_->SetBoolean(prefs::kSyncHasAuthError, error);
190 }
191 
IsStartSuppressed() const192 bool SyncPrefs::IsStartSuppressed() const {
193   DCHECK(CalledOnValidThread());
194   return pref_service_->GetBoolean(prefs::kSyncSuppressStart);
195 }
196 
SetStartSuppressed(bool is_suppressed)197 void SyncPrefs::SetStartSuppressed(bool is_suppressed) {
198   DCHECK(CalledOnValidThread());
199   pref_service_->SetBoolean(prefs::kSyncSuppressStart, is_suppressed);
200 }
201 
GetLastSyncedTime() const202 base::Time SyncPrefs::GetLastSyncedTime() const {
203   DCHECK(CalledOnValidThread());
204   return base::Time::FromInternalValue(
205       pref_service_->GetInt64(prefs::kSyncLastSyncedTime));
206 }
207 
SetLastSyncedTime(base::Time time)208 void SyncPrefs::SetLastSyncedTime(base::Time time) {
209   DCHECK(CalledOnValidThread());
210   pref_service_->SetInt64(prefs::kSyncLastSyncedTime, time.ToInternalValue());
211 }
212 
HasKeepEverythingSynced() const213 bool SyncPrefs::HasKeepEverythingSynced() const {
214   DCHECK(CalledOnValidThread());
215   return pref_service_->GetBoolean(prefs::kSyncKeepEverythingSynced);
216 }
217 
SetKeepEverythingSynced(bool keep_everything_synced)218 void SyncPrefs::SetKeepEverythingSynced(bool keep_everything_synced) {
219   DCHECK(CalledOnValidThread());
220   pref_service_->SetBoolean(prefs::kSyncKeepEverythingSynced,
221                             keep_everything_synced);
222 }
223 
GetPreferredDataTypes(syncer::ModelTypeSet registered_types) const224 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 
SetPreferredDataTypes(syncer::ModelTypeSet registered_types,syncer::ModelTypeSet preferred_types)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 
IsManaged() const253 bool SyncPrefs::IsManaged() const {
254   DCHECK(CalledOnValidThread());
255   return pref_service_->GetBoolean(prefs::kSyncManaged);
256 }
257 
GetEncryptionBootstrapToken() const258 std::string SyncPrefs::GetEncryptionBootstrapToken() const {
259   DCHECK(CalledOnValidThread());
260   return pref_service_->GetString(prefs::kSyncEncryptionBootstrapToken);
261 }
262 
SetEncryptionBootstrapToken(const std::string & token)263 void SyncPrefs::SetEncryptionBootstrapToken(const std::string& token) {
264   DCHECK(CalledOnValidThread());
265   pref_service_->SetString(prefs::kSyncEncryptionBootstrapToken, token);
266 }
267 
GetKeystoreEncryptionBootstrapToken() const268 std::string SyncPrefs::GetKeystoreEncryptionBootstrapToken() const {
269   DCHECK(CalledOnValidThread());
270   return pref_service_->GetString(prefs::kSyncKeystoreEncryptionBootstrapToken);
271 }
272 
SetKeystoreEncryptionBootstrapToken(const std::string & token)273 void SyncPrefs::SetKeystoreEncryptionBootstrapToken(const std::string& token) {
274   DCHECK(CalledOnValidThread());
275   pref_service_->SetString(prefs::kSyncKeystoreEncryptionBootstrapToken, token);
276 }
277 
GetSyncSessionsGUID() const278 std::string SyncPrefs::GetSyncSessionsGUID() const {
279   DCHECK(CalledOnValidThread());
280   return pref_service_->GetString(prefs::kSyncSessionsGUID);
281 }
282 
SetSyncSessionsGUID(const std::string & guid)283 void SyncPrefs::SetSyncSessionsGUID(const std::string& guid) {
284   DCHECK(CalledOnValidThread());
285   pref_service_->SetString(prefs::kSyncSessionsGUID, guid);
286 }
287 
288 // static
GetPrefNameForDataType(syncer::ModelType data_type)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)
GetSpareBootstrapToken() const353 std::string SyncPrefs::GetSpareBootstrapToken() const {
354   DCHECK(CalledOnValidThread());
355   return pref_service_->GetString(prefs::kSyncSpareBootstrapToken);
356 }
357 
SetSpareBootstrapToken(const std::string & token)358 void SyncPrefs::SetSpareBootstrapToken(const std::string& token) {
359   DCHECK(CalledOnValidThread());
360   pref_service_->SetString(prefs::kSyncSpareBootstrapToken, token);
361 }
362 #endif
363 
AcknowledgeSyncedTypes(syncer::ModelTypeSet types)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 
GetRemainingRollbackTries() const378 int SyncPrefs::GetRemainingRollbackTries() const {
379   return pref_service_->GetInteger(prefs::kSyncRemainingRollbackTries);
380 }
381 
SetRemainingRollbackTries(int times)382 void SyncPrefs::SetRemainingRollbackTries(int times) {
383   pref_service_->SetInteger(prefs::kSyncRemainingRollbackTries, times);
384 }
385 
OnSyncManagedPrefChanged()386 void SyncPrefs::OnSyncManagedPrefChanged() {
387   DCHECK(CalledOnValidThread());
388   FOR_EACH_OBSERVER(SyncPrefObserver,
389                     sync_pref_observers_,
390                     OnSyncManagedPrefChange(*pref_sync_managed_));
391 }
392 
SetManagedForTest(bool is_managed)393 void SyncPrefs::SetManagedForTest(bool is_managed) {
394   DCHECK(CalledOnValidThread());
395   pref_service_->SetBoolean(prefs::kSyncManaged, is_managed);
396 }
397 
GetAcknowledgeSyncedTypesForTest() const398 syncer::ModelTypeSet SyncPrefs::GetAcknowledgeSyncedTypesForTest() const {
399   DCHECK(CalledOnValidThread());
400   return syncer::ModelTypeSetFromValue(
401       *pref_service_->GetList(prefs::kSyncAcknowledgedSyncTypes));
402 }
403 
RegisterPrefGroups()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
RegisterDataTypePreferredPref(user_prefs::PrefRegistrySyncable * registry,syncer::ModelType type,bool is_preferred)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 
GetDataTypePreferred(syncer::ModelType type) const448 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 
SetDataTypePreferred(syncer::ModelType type,bool is_preferred)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 
ResolvePrefGroups(syncer::ModelTypeSet registered_types,syncer::ModelTypeSet types) const477 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 
GetFirstSyncTime() const492 base::Time SyncPrefs::GetFirstSyncTime() const {
493   return base::Time::FromInternalValue(
494       pref_service_->GetInt64(prefs::kSyncFirstSyncTime));
495 }
496 
SetFirstSyncTime(base::Time time)497 void SyncPrefs::SetFirstSyncTime(base::Time time) {
498   pref_service_->SetInt64(prefs::kSyncFirstSyncTime, time.ToInternalValue());
499 }
500 
ClearFirstSyncTime()501 void SyncPrefs::ClearFirstSyncTime() {
502   pref_service_->ClearPref(prefs::kSyncFirstSyncTime);
503 }
504 
505 }  // namespace browser_sync
506