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