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