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