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