profile_sync_components_factory_impl.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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 "base/command_line.h"
6#include "build/build_config.h"
7#include "chrome/browser/bookmarks/bookmark_model_factory.h"
8#include "chrome/browser/extensions/api/storage/settings_frontend.h"
9#include "chrome/browser/extensions/extension_service.h"
10#include "chrome/browser/extensions/extension_system.h"
11#include "chrome/browser/extensions/extension_system_factory.h"
12#include "chrome/browser/history/history_service.h"
13#include "chrome/browser/history/history_service_factory.h"
14#include "chrome/browser/prefs/pref_model_associator.h"
15#include "chrome/browser/prefs/pref_service_syncable.h"
16#include "chrome/browser/profiles/profile.h"
17#include "chrome/browser/search_engines/template_url_service.h"
18#include "chrome/browser/search_engines/template_url_service_factory.h"
19#include "chrome/browser/signin/signin_manager.h"
20#include "chrome/browser/signin/signin_manager_factory.h"
21#include "chrome/browser/spellchecker/spellcheck_factory.h"
22#include "chrome/browser/spellchecker/spellcheck_service.h"
23#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
24#include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h"
25#include "chrome/browser/sync/glue/bookmark_change_processor.h"
26#include "chrome/browser/sync/glue/bookmark_data_type_controller.h"
27#include "chrome/browser/sync/glue/bookmark_model_associator.h"
28#include "chrome/browser/sync/glue/data_type_manager_impl.h"
29#include "chrome/browser/sync/glue/data_type_manager_observer.h"
30#include "chrome/browser/sync/glue/extension_data_type_controller.h"
31#include "chrome/browser/sync/glue/extension_setting_data_type_controller.h"
32#include "chrome/browser/sync/glue/generic_change_processor.h"
33#include "chrome/browser/sync/glue/password_change_processor.h"
34#include "chrome/browser/sync/glue/password_data_type_controller.h"
35#include "chrome/browser/sync/glue/password_model_associator.h"
36#include "chrome/browser/sync/glue/proxy_data_type_controller.h"
37#include "chrome/browser/sync/glue/search_engine_data_type_controller.h"
38#include "chrome/browser/sync/glue/session_change_processor.h"
39#include "chrome/browser/sync/glue/session_data_type_controller.h"
40#include "chrome/browser/sync/glue/session_model_associator.h"
41#include "chrome/browser/sync/glue/shared_change_processor.h"
42#include "chrome/browser/sync/glue/sync_backend_host.h"
43#include "chrome/browser/sync/glue/theme_data_type_controller.h"
44#include "chrome/browser/sync/glue/typed_url_change_processor.h"
45#include "chrome/browser/sync/glue/typed_url_data_type_controller.h"
46#include "chrome/browser/sync/glue/typed_url_model_associator.h"
47#include "chrome/browser/sync/glue/ui_data_type_controller.h"
48#include "chrome/browser/sync/profile_sync_components_factory_impl.h"
49#include "chrome/browser/sync/profile_sync_service.h"
50#include "chrome/browser/sync/profile_sync_service_factory.h"
51#include "chrome/browser/themes/theme_service.h"
52#include "chrome/browser/themes/theme_service_factory.h"
53#include "chrome/browser/themes/theme_syncable_service.h"
54#include "chrome/browser/webdata/autocomplete_syncable_service.h"
55#include "chrome/browser/webdata/autofill_profile_syncable_service.h"
56#include "chrome/common/chrome_switches.h"
57#include "chrome/common/pref_names.h"
58#include "components/autofill/browser/webdata/autofill_webdata_service.h"
59#include "content/public/browser/browser_thread.h"
60#include "sync/api/syncable_service.h"
61
62#if defined(ENABLE_MANAGED_USERS)
63#include "chrome/browser/managed_mode/managed_user_registration_service.h"
64#include "chrome/browser/managed_mode/managed_user_registration_service_factory.h"
65#include "chrome/browser/managed_mode/managed_user_service.h"
66#include "chrome/browser/policy/managed_mode_policy_provider.h"
67#include "chrome/browser/policy/profile_policy_connector.h"
68#include "chrome/browser/policy/profile_policy_connector_factory.h"
69#endif
70
71#if !defined(OS_ANDROID)
72#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
73#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_factory.h"
74#endif
75
76using browser_sync::AutofillDataTypeController;
77using browser_sync::AutofillProfileDataTypeController;
78using browser_sync::BookmarkChangeProcessor;
79using browser_sync::BookmarkDataTypeController;
80using browser_sync::BookmarkModelAssociator;
81using browser_sync::DataTypeController;
82using browser_sync::DataTypeErrorHandler;
83using browser_sync::DataTypeManager;
84using browser_sync::DataTypeManagerImpl;
85using browser_sync::DataTypeManagerObserver;
86using browser_sync::ExtensionDataTypeController;
87using browser_sync::ExtensionSettingDataTypeController;
88using browser_sync::GenericChangeProcessor;
89using browser_sync::PasswordChangeProcessor;
90using browser_sync::PasswordDataTypeController;
91using browser_sync::PasswordModelAssociator;
92using browser_sync::ProxyDataTypeController;
93using browser_sync::SearchEngineDataTypeController;
94using browser_sync::SessionChangeProcessor;
95using browser_sync::SessionDataTypeController;
96using browser_sync::SessionModelAssociator;
97using browser_sync::SharedChangeProcessor;
98using browser_sync::SyncBackendHost;
99using browser_sync::ThemeDataTypeController;
100using browser_sync::TypedUrlChangeProcessor;
101using browser_sync::TypedUrlDataTypeController;
102using browser_sync::TypedUrlModelAssociator;
103using browser_sync::UIDataTypeController;
104using content::BrowserThread;
105
106namespace {
107// Based on command line switches, make the call to use SyncedNotifications or
108// not.
109// TODO(petewil): Remove this when the SyncedNotifications feature is ready
110// to be turned on by default, and just use a disable switch instead then.
111bool UseSyncedNotifications(CommandLine* command_line) {
112  if (command_line->HasSwitch(switches::kDisableSyncSyncedNotifications))
113    return false;
114  if (command_line->HasSwitch(switches::kEnableSyncSyncedNotifications))
115    return true;
116  return false;
117}
118}  // namespace
119
120ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl(
121    Profile* profile, CommandLine* command_line)
122    : profile_(profile),
123      command_line_(command_line),
124      extension_system_(
125          extensions::ExtensionSystemFactory::GetForProfile(profile)),
126      web_data_service_(
127          autofill::AutofillWebDataService::FromBrowserContext(profile_)) {
128}
129
130ProfileSyncComponentsFactoryImpl::~ProfileSyncComponentsFactoryImpl() {
131}
132
133void ProfileSyncComponentsFactoryImpl::RegisterDataTypes(
134    ProfileSyncService* pss) {
135  RegisterCommonDataTypes(pss);
136#if !defined(OS_ANDROID)
137  RegisterDesktopDataTypes(pss);
138#endif
139}
140
141void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
142    ProfileSyncService* pss) {
143  // Autofill sync is enabled by default.  Register unless explicitly
144  // disabled.
145  if (!command_line_->HasSwitch(switches::kDisableSyncAutofill)) {
146    pss->RegisterDataTypeController(
147        new AutofillDataTypeController(this, profile_, pss));
148  }
149
150  // Autofill profile sync is enabled by default.  Register unless explicitly
151  // disabled.
152  if (!command_line_->HasSwitch(switches::kDisableSyncAutofillProfile)) {
153    pss->RegisterDataTypeController(
154        new AutofillProfileDataTypeController(this, profile_, pss));
155  }
156
157  // Bookmark sync is enabled by default.  Register unless explicitly
158  // disabled.
159  if (!command_line_->HasSwitch(switches::kDisableSyncBookmarks)) {
160    pss->RegisterDataTypeController(
161        new BookmarkDataTypeController(this, profile_, pss));
162  }
163
164  // TypedUrl sync is enabled by default.  Register unless explicitly disabled,
165  // or if saving history is disabled.
166  if (!profile_->GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled) &&
167      !command_line_->HasSwitch(switches::kDisableSyncTypedUrls)) {
168    pss->RegisterDataTypeController(
169        new TypedUrlDataTypeController(this, profile_, pss));
170  }
171
172  // Delete directive sync is enabled by default.  Register unless full history
173  // sync is disabled.
174  if (!command_line_->HasSwitch(switches::kHistoryDisableFullHistorySync)) {
175    pss->RegisterDataTypeController(
176        new UIDataTypeController(
177            syncer::HISTORY_DELETE_DIRECTIVES, this, profile_, pss));
178  }
179
180  // Session sync is enabled by default.  Register unless explicitly disabled.
181  if (!command_line_->HasSwitch(switches::kDisableSyncTabs)) {
182    pss->RegisterDataTypeController(
183        new ProxyDataTypeController(syncer::PROXY_TABS));
184    pss->RegisterDataTypeController(
185        new SessionDataTypeController(this, profile_, pss));
186  }
187
188  if (command_line_->HasSwitch(switches::kEnableSyncFavicons)) {
189    pss->RegisterDataTypeController(
190        new UIDataTypeController(syncer::FAVICON_IMAGES,
191                                 this,
192                                 profile_,
193                                 pss));
194    pss->RegisterDataTypeController(
195        new UIDataTypeController(syncer::FAVICON_TRACKING,
196                                 this,
197                                 profile_,
198                                 pss));
199  }
200
201  // Password sync is enabled by default.  Register unless explicitly
202  // disabled.
203  if (!command_line_->HasSwitch(switches::kDisableSyncPasswords)) {
204    pss->RegisterDataTypeController(
205        new PasswordDataTypeController(this, profile_, pss));
206  }
207}
208
209void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
210    ProfileSyncService* pss) {
211  // App sync is enabled by default.  Register unless explicitly
212  // disabled.
213  if (!command_line_->HasSwitch(switches::kDisableSyncApps)) {
214    pss->RegisterDataTypeController(
215        new ExtensionDataTypeController(syncer::APPS, this, profile_, pss));
216  }
217
218  // Extension sync is enabled by default.  Register unless explicitly
219  // disabled.
220  if (!command_line_->HasSwitch(switches::kDisableSyncExtensions)) {
221    pss->RegisterDataTypeController(
222        new ExtensionDataTypeController(syncer::EXTENSIONS,
223                                        this, profile_, pss));
224  }
225
226  // Preference sync is enabled by default.  Register unless explicitly
227  // disabled.
228  if (!command_line_->HasSwitch(switches::kDisableSyncPreferences)) {
229    pss->RegisterDataTypeController(
230        new UIDataTypeController(syncer::PREFERENCES, this, profile_, pss));
231
232  }
233
234  if (!command_line_->HasSwitch(switches::kDisableSyncPriorityPreferences)) {
235    pss->RegisterDataTypeController(
236        new UIDataTypeController(syncer::PRIORITY_PREFERENCES,
237                                 this, profile_, pss));
238  }
239
240#if defined(ENABLE_THEMES)
241  // Theme sync is enabled by default.  Register unless explicitly disabled.
242  if (!command_line_->HasSwitch(switches::kDisableSyncThemes)) {
243    pss->RegisterDataTypeController(
244        new ThemeDataTypeController(this, profile_, pss));
245  }
246#endif
247
248  // Search Engine sync is enabled by default.  Register unless explicitly
249  // disabled.
250  if (!command_line_->HasSwitch(switches::kDisableSyncSearchEngines)) {
251    pss->RegisterDataTypeController(
252        new SearchEngineDataTypeController(this, profile_, pss));
253  }
254
255  // Extension setting sync is enabled by default.  Register unless explicitly
256  // disabled.
257  if (!command_line_->HasSwitch(switches::kDisableSyncExtensionSettings)) {
258    pss->RegisterDataTypeController(
259        new ExtensionSettingDataTypeController(
260            syncer::EXTENSION_SETTINGS, this, profile_, pss));
261  }
262
263  // App setting sync is enabled by default.  Register unless explicitly
264  // disabled.
265  if (!command_line_->HasSwitch(switches::kDisableSyncAppSettings)) {
266    pss->RegisterDataTypeController(
267        new ExtensionSettingDataTypeController(
268            syncer::APP_SETTINGS, this, profile_, pss));
269  }
270
271  // Synced Notifications sync datatype is disabled by default.
272  // TODO(petewil): Switch to enabled by default once datatype support is done.
273  if (UseSyncedNotifications(command_line_)) {
274    pss->RegisterDataTypeController(
275        new UIDataTypeController(
276            syncer::SYNCED_NOTIFICATIONS, this, profile_, pss));
277  }
278
279#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_CHROMEOS)
280  // Dictionary sync is enabled by default.
281  if (!command_line_->HasSwitch(switches::kDisableSyncDictionary)) {
282    pss->RegisterDataTypeController(
283        new UIDataTypeController(syncer::DICTIONARY, this, profile_, pss));
284  }
285#endif
286
287#if defined(ENABLE_MANAGED_USERS)
288  if (ManagedUserService::AreManagedUsersEnabled()) {
289    if (ManagedUserService::ProfileIsManaged(profile_)) {
290      pss->RegisterDataTypeController(
291          new UIDataTypeController(
292              syncer::MANAGED_USER_SETTINGS, this, profile_, pss));
293    } else {
294      pss->RegisterDataTypeController(
295          new UIDataTypeController(
296              syncer::MANAGED_USERS, this, profile_, pss));
297    }
298  }
299#endif
300}
301
302DataTypeManager* ProfileSyncComponentsFactoryImpl::CreateDataTypeManager(
303    const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
304        debug_info_listener,
305    const DataTypeController::TypeMap* controllers,
306    const browser_sync::DataTypeEncryptionHandler* encryption_handler,
307    SyncBackendHost* backend,
308    DataTypeManagerObserver* observer,
309    browser_sync::FailedDataTypesHandler* failed_data_types_handler) {
310  return new DataTypeManagerImpl(debug_info_listener,
311                                 controllers,
312                                 encryption_handler,
313                                 backend,
314                                 observer,
315                                 failed_data_types_handler);
316}
317
318browser_sync::GenericChangeProcessor*
319    ProfileSyncComponentsFactoryImpl::CreateGenericChangeProcessor(
320        ProfileSyncService* profile_sync_service,
321        browser_sync::DataTypeErrorHandler* error_handler,
322        const base::WeakPtr<syncer::SyncableService>& local_service,
323        const base::WeakPtr<syncer::SyncMergeResult>& merge_result) {
324  syncer::UserShare* user_share = profile_sync_service->GetUserShare();
325  return new GenericChangeProcessor(error_handler,
326                                    local_service,
327                                    merge_result,
328                                    user_share);
329}
330
331browser_sync::SharedChangeProcessor* ProfileSyncComponentsFactoryImpl::
332    CreateSharedChangeProcessor() {
333  return new SharedChangeProcessor();
334}
335
336base::WeakPtr<syncer::SyncableService> ProfileSyncComponentsFactoryImpl::
337    GetSyncableServiceForType(syncer::ModelType type) {
338  if (!profile_) {  // For tests.
339     return base::WeakPtr<syncer::SyncableService>();
340  }
341  switch (type) {
342    case syncer::PREFERENCES:
343      return PrefServiceSyncable::FromProfile(
344          profile_)->GetSyncableService(syncer::PREFERENCES)->AsWeakPtr();
345    case syncer::PRIORITY_PREFERENCES:
346      return PrefServiceSyncable::FromProfile(profile_)->GetSyncableService(
347          syncer::PRIORITY_PREFERENCES)->AsWeakPtr();
348    case syncer::AUTOFILL:
349    case syncer::AUTOFILL_PROFILE: {
350      if (!web_data_service_.get())
351        return base::WeakPtr<syncer::SyncableService>();
352      if (type == syncer::AUTOFILL) {
353        return AutocompleteSyncableService::FromWebDataService(
354            web_data_service_.get())->AsWeakPtr();
355      } else {
356        return AutofillProfileSyncableService::FromWebDataService(
357            web_data_service_.get())->AsWeakPtr();
358      }
359    }
360    case syncer::APPS:
361    case syncer::EXTENSIONS:
362      return extension_system_->extension_service()->AsWeakPtr();
363    case syncer::SEARCH_ENGINES:
364      return TemplateURLServiceFactory::GetForProfile(profile_)->AsWeakPtr();
365    case syncer::APP_SETTINGS:
366    case syncer::EXTENSION_SETTINGS:
367      return extension_system_->extension_service()->settings_frontend()->
368          GetBackendForSync(type)->AsWeakPtr();
369#if defined(ENABLE_THEMES)
370    case syncer::THEMES:
371      return ThemeServiceFactory::GetForProfile(profile_)->
372          GetThemeSyncableService()->AsWeakPtr();
373#endif
374    case syncer::HISTORY_DELETE_DIRECTIVES: {
375      HistoryService* history =
376          HistoryServiceFactory::GetForProfile(
377              profile_, Profile::EXPLICIT_ACCESS);
378      return history ? history->AsWeakPtr() : base::WeakPtr<HistoryService>();
379    }
380#if !defined(OS_ANDROID)
381    case syncer::SYNCED_NOTIFICATIONS: {
382      notifier::ChromeNotifierService* notifier_service =
383          notifier::ChromeNotifierServiceFactory::GetForProfile(
384              profile_, Profile::EXPLICIT_ACCESS);
385      return notifier_service ? notifier_service->AsWeakPtr()
386          : base::WeakPtr<syncer::SyncableService>();
387    }
388#endif
389    case syncer::DICTIONARY:
390      return SpellcheckServiceFactory::GetForProfile(profile_)->
391          GetCustomDictionary()->AsWeakPtr();
392    case syncer::FAVICON_IMAGES:
393    case syncer::FAVICON_TRACKING:
394      return ProfileSyncServiceFactory::GetForProfile(profile_)->
395          GetSessionModelAssociator()->GetFaviconCache()->AsWeakPtr();
396#if defined(ENABLE_MANAGED_USERS)
397    case syncer::MANAGED_USER_SETTINGS:
398      return policy::ProfilePolicyConnectorFactory::GetForProfile(profile_)->
399          managed_mode_policy_provider()->AsWeakPtr();
400    case syncer::MANAGED_USERS:
401      return ManagedUserRegistrationServiceFactory::GetForProfile(profile_)->
402          AsWeakPtr();
403#endif
404    default:
405      // The following datatypes still need to be transitioned to the
406      // syncer::SyncableService API:
407      // Bookmarks
408      // Passwords
409      // Sessions
410      // Typed URLs
411      NOTREACHED();
412      return base::WeakPtr<syncer::SyncableService>();
413  }
414}
415
416ProfileSyncComponentsFactory::SyncComponents
417    ProfileSyncComponentsFactoryImpl::CreateBookmarkSyncComponents(
418        ProfileSyncService* profile_sync_service,
419        DataTypeErrorHandler* error_handler) {
420  BookmarkModel* bookmark_model =
421      BookmarkModelFactory::GetForProfile(profile_sync_service->profile());
422  syncer::UserShare* user_share = profile_sync_service->GetUserShare();
423  // TODO(akalin): We may want to propagate this switch up eventually.
424#if defined(OS_ANDROID)
425  const bool kExpectMobileBookmarksFolder = true;
426#else
427  const bool kExpectMobileBookmarksFolder = false;
428#endif
429  BookmarkModelAssociator* model_associator =
430      new BookmarkModelAssociator(bookmark_model,
431                                  profile_sync_service->profile(),
432                                  user_share,
433                                  error_handler,
434                                  kExpectMobileBookmarksFolder);
435  BookmarkChangeProcessor* change_processor =
436      new BookmarkChangeProcessor(model_associator,
437                                  error_handler);
438  return SyncComponents(model_associator, change_processor);
439}
440
441ProfileSyncComponentsFactory::SyncComponents
442    ProfileSyncComponentsFactoryImpl::CreatePasswordSyncComponents(
443        ProfileSyncService* profile_sync_service,
444        PasswordStore* password_store,
445        DataTypeErrorHandler* error_handler) {
446  PasswordModelAssociator* model_associator =
447      new PasswordModelAssociator(profile_sync_service,
448                                  password_store,
449                                  error_handler);
450  PasswordChangeProcessor* change_processor =
451      new PasswordChangeProcessor(model_associator,
452                                  password_store,
453                                  error_handler);
454  return SyncComponents(model_associator, change_processor);
455}
456
457ProfileSyncComponentsFactory::SyncComponents
458    ProfileSyncComponentsFactoryImpl::CreateTypedUrlSyncComponents(
459        ProfileSyncService* profile_sync_service,
460        history::HistoryBackend* history_backend,
461        browser_sync::DataTypeErrorHandler* error_handler) {
462  TypedUrlModelAssociator* model_associator =
463      new TypedUrlModelAssociator(profile_sync_service,
464                                  history_backend,
465                                  error_handler);
466  TypedUrlChangeProcessor* change_processor =
467      new TypedUrlChangeProcessor(profile_,
468                                  model_associator,
469                                  history_backend,
470                                  error_handler);
471  return SyncComponents(model_associator, change_processor);
472}
473
474ProfileSyncComponentsFactory::SyncComponents
475    ProfileSyncComponentsFactoryImpl::CreateSessionSyncComponents(
476       ProfileSyncService* profile_sync_service,
477        DataTypeErrorHandler* error_handler) {
478  SessionModelAssociator* model_associator =
479      new SessionModelAssociator(profile_sync_service, error_handler);
480  SessionChangeProcessor* change_processor =
481      new SessionChangeProcessor(error_handler, model_associator);
482  return SyncComponents(model_associator, change_processor);
483}
484