profile_sync_components_factory_impl.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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/bookmarks/enhanced_bookmarks_features.h"
9#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h"
10#include "chrome/browser/history/history_service.h"
11#include "chrome/browser/history/history_service_factory.h"
12#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
13#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_factory.h"
14#include "chrome/browser/password_manager/password_store_factory.h"
15#include "chrome/browser/pref_service_flags_storage.h"
16#include "chrome/browser/prefs/pref_model_associator.h"
17#include "chrome/browser/prefs/pref_service_syncable.h"
18#include "chrome/browser/profiles/profile.h"
19#include "chrome/browser/search_engines/template_url_service.h"
20#include "chrome/browser/search_engines/template_url_service_factory.h"
21#include "chrome/browser/signin/signin_manager_factory.h"
22#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
23#include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h"
24#include "chrome/browser/sync/glue/bookmark_change_processor.h"
25#include "chrome/browser/sync/glue/bookmark_data_type_controller.h"
26#include "chrome/browser/sync/glue/bookmark_model_associator.h"
27#include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h"
28#include "chrome/browser/sync/glue/extension_data_type_controller.h"
29#include "chrome/browser/sync/glue/extension_setting_data_type_controller.h"
30#include "chrome/browser/sync/glue/password_data_type_controller.h"
31#include "chrome/browser/sync/glue/search_engine_data_type_controller.h"
32#include "chrome/browser/sync/glue/sync_backend_host.h"
33#include "chrome/browser/sync/glue/sync_backend_host_impl.h"
34#include "chrome/browser/sync/glue/theme_data_type_controller.h"
35#include "chrome/browser/sync/glue/typed_url_change_processor.h"
36#include "chrome/browser/sync/glue/typed_url_data_type_controller.h"
37#include "chrome/browser/sync/glue/typed_url_model_associator.h"
38#include "chrome/browser/sync/profile_sync_components_factory_impl.h"
39#include "chrome/browser/sync/profile_sync_service.h"
40#include "chrome/browser/sync/profile_sync_service_factory.h"
41#include "chrome/browser/sync/sessions/session_data_type_controller.h"
42#include "chrome/browser/themes/theme_service.h"
43#include "chrome/browser/themes/theme_service_factory.h"
44#include "chrome/browser/themes/theme_syncable_service.h"
45#include "chrome/browser/webdata/autocomplete_syncable_service.h"
46#include "chrome/browser/webdata/web_data_service_factory.h"
47#include "chrome/common/chrome_switches.h"
48#include "chrome/common/chrome_version_info.h"
49#include "chrome/common/pref_names.h"
50#include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h"
51#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
52#include "components/dom_distiller/core/dom_distiller_service.h"
53#include "components/password_manager/core/browser/password_store.h"
54#include "components/signin/core/browser/signin_manager.h"
55#include "components/sync_driver/data_type_manager_impl.h"
56#include "components/sync_driver/data_type_manager_observer.h"
57#include "components/sync_driver/generic_change_processor.h"
58#include "components/sync_driver/proxy_data_type_controller.h"
59#include "components/sync_driver/shared_change_processor.h"
60#include "components/sync_driver/ui_data_type_controller.h"
61#include "content/public/browser/browser_thread.h"
62#include "extensions/browser/extension_system.h"
63#include "google_apis/gaia/oauth2_token_service_request.h"
64#include "net/url_request/url_request_context_getter.h"
65#include "sync/api/attachments/attachment_service.h"
66#include "sync/api/attachments/attachment_service_impl.h"
67#include "sync/api/syncable_service.h"
68#include "sync/internal_api/public/attachments/attachment_uploader_impl.h"
69#include "sync/internal_api/public/attachments/fake_attachment_downloader.h"
70#include "sync/internal_api/public/attachments/fake_attachment_store.h"
71
72#if defined(ENABLE_EXTENSIONS)
73#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
74#include "chrome/browser/extensions/api/synced_notifications_private/synced_notifications_shim.h"
75#include "chrome/browser/extensions/extension_sync_service.h"
76#endif
77
78#if defined(ENABLE_APP_LIST)
79#include "chrome/browser/ui/app_list/app_list_syncable_service.h"
80#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
81#include "ui/app_list/app_list_switches.h"
82#endif
83
84#if defined(ENABLE_MANAGED_USERS)
85#include "chrome/browser/supervised_user/supervised_user_settings_service.h"
86#include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
87#include "chrome/browser/supervised_user/supervised_user_shared_settings_service.h"
88#include "chrome/browser/supervised_user/supervised_user_shared_settings_service_factory.h"
89#include "chrome/browser/supervised_user/supervised_user_sync_service.h"
90#include "chrome/browser/supervised_user/supervised_user_sync_service_factory.h"
91#endif
92
93#if defined(ENABLE_SPELLCHECK)
94#include "chrome/browser/spellchecker/spellcheck_factory.h"
95#include "chrome/browser/spellchecker/spellcheck_service.h"
96#endif
97
98using browser_sync::AutofillDataTypeController;
99using browser_sync::AutofillProfileDataTypeController;
100using browser_sync::BookmarkChangeProcessor;
101using browser_sync::BookmarkDataTypeController;
102using browser_sync::BookmarkModelAssociator;
103using browser_sync::ChromeReportUnrecoverableError;
104using browser_sync::DataTypeController;
105using browser_sync::DataTypeErrorHandler;
106using browser_sync::DataTypeManager;
107using browser_sync::DataTypeManagerImpl;
108using browser_sync::DataTypeManagerObserver;
109using browser_sync::ExtensionDataTypeController;
110using browser_sync::ExtensionSettingDataTypeController;
111using browser_sync::PasswordDataTypeController;
112using browser_sync::ProxyDataTypeController;
113using browser_sync::SearchEngineDataTypeController;
114using browser_sync::SessionDataTypeController;
115using browser_sync::SharedChangeProcessor;
116using browser_sync::SyncBackendHost;
117using browser_sync::ThemeDataTypeController;
118using browser_sync::TypedUrlChangeProcessor;
119using browser_sync::TypedUrlDataTypeController;
120using browser_sync::TypedUrlModelAssociator;
121using browser_sync::UIDataTypeController;
122using content::BrowserThread;
123
124namespace {
125
126const char kAttachmentsPath[] = "/attachments/";
127
128syncer::ModelTypeSet GetDisabledTypesFromCommandLine(
129    const CommandLine& command_line) {
130  syncer::ModelTypeSet disabled_types;
131  std::string disabled_types_str =
132      command_line.GetSwitchValueASCII(switches::kDisableSyncTypes);
133  disabled_types = syncer::ModelTypeSetFromString(disabled_types_str);
134  return disabled_types;
135}
136
137syncer::ModelTypeSet GetEnabledTypesFromCommandLine(
138    const CommandLine& command_line) {
139  syncer::ModelTypeSet enabled_types;
140  if (command_line.HasSwitch(switches::kEnableSyncSyncedNotifications)) {
141    enabled_types.Put(syncer::SYNCED_NOTIFICATIONS);
142  }
143  return enabled_types;
144}
145
146// Returns the base URL for attachments.
147std::string GetSyncServiceAttachmentsURL(const GURL& sync_service_url) {
148  return sync_service_url.spec() + kAttachmentsPath;
149}
150
151}  // namespace
152
153ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl(
154    Profile* profile,
155    CommandLine* command_line,
156    const GURL& sync_service_url,
157    const std::string& account_id,
158    const OAuth2TokenService::ScopeSet& scope_set,
159    OAuth2TokenService* token_service,
160    net::URLRequestContextGetter* url_request_context_getter)
161    : profile_(profile),
162      command_line_(command_line),
163      extension_system_(extensions::ExtensionSystem::Get(profile)),
164      web_data_service_(WebDataServiceFactory::GetAutofillWebDataForProfile(
165          profile_, Profile::EXPLICIT_ACCESS)),
166      sync_service_url_(sync_service_url),
167      account_id_(account_id),
168      scope_set_(scope_set),
169      token_service_(token_service),
170      url_request_context_getter_(url_request_context_getter),
171      weak_factory_(this) {
172  DCHECK(token_service_);
173  DCHECK(url_request_context_getter_);
174}
175
176ProfileSyncComponentsFactoryImpl::~ProfileSyncComponentsFactoryImpl() {
177}
178
179void ProfileSyncComponentsFactoryImpl::RegisterDataTypes(
180    ProfileSyncService* pss) {
181  syncer::ModelTypeSet disabled_types =
182      GetDisabledTypesFromCommandLine(*command_line_);
183  syncer::ModelTypeSet enabled_types =
184      GetEnabledTypesFromCommandLine(*command_line_);
185  RegisterCommonDataTypes(disabled_types, enabled_types, pss);
186#if !defined(OS_ANDROID)
187  RegisterDesktopDataTypes(disabled_types, enabled_types, pss);
188#endif
189}
190
191void ProfileSyncComponentsFactoryImpl::DisableBrokenType(
192    syncer::ModelType type,
193    const tracked_objects::Location& from_here,
194    const std::string& message) {
195  ProfileSyncService* p = ProfileSyncServiceFactory::GetForProfile(profile_);
196  p->DisableBrokenDatatype(type, from_here, message);
197}
198
199DataTypeController::DisableTypeCallback
200ProfileSyncComponentsFactoryImpl::MakeDisableCallbackFor(
201    syncer::ModelType type) {
202  return base::Bind(&ProfileSyncComponentsFactoryImpl::DisableBrokenType,
203                    weak_factory_.GetWeakPtr(),
204                    type);
205}
206
207void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
208    syncer::ModelTypeSet disabled_types,
209    syncer::ModelTypeSet enabled_types,
210    ProfileSyncService* pss) {
211  // Autofill sync is enabled by default.  Register unless explicitly
212  // disabled.
213  if (!disabled_types.Has(syncer::AUTOFILL)) {
214    pss->RegisterDataTypeController(
215        new AutofillDataTypeController(
216            this, profile_, MakeDisableCallbackFor(syncer::AUTOFILL)));
217  }
218
219  // Autofill profile sync is enabled by default.  Register unless explicitly
220  // disabled.
221  if (!disabled_types.Has(syncer::AUTOFILL_PROFILE)) {
222    pss->RegisterDataTypeController(
223        new AutofillProfileDataTypeController(
224            this, profile_, MakeDisableCallbackFor(syncer::AUTOFILL_PROFILE)));
225  }
226
227  // Bookmark sync is enabled by default.  Register unless explicitly
228  // disabled.
229  if (!disabled_types.Has(syncer::BOOKMARKS)) {
230    pss->RegisterDataTypeController(
231        new BookmarkDataTypeController(this, profile_, pss));
232  }
233
234  // TypedUrl sync is enabled by default.  Register unless explicitly disabled,
235  // or if saving history is disabled.
236  if (!profile_->GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled) &&
237      !disabled_types.Has(syncer::TYPED_URLS)) {
238    pss->RegisterDataTypeController(
239        new TypedUrlDataTypeController(this, profile_, pss));
240  }
241
242  // Delete directive sync is enabled by default.  Register unless full history
243  // sync is disabled.
244  if (!disabled_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
245    pss->RegisterDataTypeController(
246        new UIDataTypeController(
247            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
248            base::Bind(&ChromeReportUnrecoverableError),
249            MakeDisableCallbackFor(syncer::HISTORY_DELETE_DIRECTIVES),
250            syncer::HISTORY_DELETE_DIRECTIVES,
251            this));
252  }
253
254  // Session sync is enabled by default.  Register unless explicitly disabled.
255  if (!disabled_types.Has(syncer::PROXY_TABS)) {
256      pss->RegisterDataTypeController(new ProxyDataTypeController(
257         BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
258         syncer::PROXY_TABS));
259    pss->RegisterDataTypeController(
260        new SessionDataTypeController(
261            this, profile_, MakeDisableCallbackFor(syncer::SESSIONS)));
262  }
263
264  // Favicon sync is enabled by default. Register unless explicitly disabled.
265  if (!disabled_types.Has(syncer::FAVICON_IMAGES) &&
266      !disabled_types.Has(syncer::FAVICON_TRACKING)) {
267    pss->RegisterDataTypeController(
268        new UIDataTypeController(
269            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
270            base::Bind(&ChromeReportUnrecoverableError),
271            MakeDisableCallbackFor(syncer::FAVICON_IMAGES),
272            syncer::FAVICON_IMAGES,
273            this));
274    pss->RegisterDataTypeController(
275        new UIDataTypeController(
276            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
277            base::Bind(&ChromeReportUnrecoverableError),
278            MakeDisableCallbackFor(syncer::FAVICON_TRACKING),
279            syncer::FAVICON_TRACKING,
280            this));
281  }
282
283  // Password sync is enabled by default.  Register unless explicitly
284  // disabled.
285  if (!disabled_types.Has(syncer::PASSWORDS)) {
286    pss->RegisterDataTypeController(
287        new PasswordDataTypeController(
288            this, profile_, MakeDisableCallbackFor(syncer::PASSWORDS)));
289  }
290
291  // Article sync is disabled by default.  Register only if explicitly enabled.
292  if (IsEnableSyncArticlesSet()) {
293    pss->RegisterDataTypeController(
294        new UIDataTypeController(
295            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
296            base::Bind(&ChromeReportUnrecoverableError),
297            MakeDisableCallbackFor(syncer::ARTICLES),
298            syncer::ARTICLES,
299            this));
300  }
301
302#if defined(ENABLE_MANAGED_USERS)
303  if (profile_->IsSupervised()) {
304    pss->RegisterDataTypeController(
305        new UIDataTypeController(
306            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
307            base::Bind(&ChromeReportUnrecoverableError),
308            MakeDisableCallbackFor(syncer::SUPERVISED_USER_SETTINGS),
309            syncer::SUPERVISED_USER_SETTINGS,
310            this));
311  } else {
312    pss->RegisterDataTypeController(
313        new UIDataTypeController(
314            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
315            base::Bind(&ChromeReportUnrecoverableError),
316            MakeDisableCallbackFor(syncer::SUPERVISED_USERS),
317            syncer::SUPERVISED_USERS,
318            this));
319  }
320  pss->RegisterDataTypeController(
321      new UIDataTypeController(
322            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
323            base::Bind(&ChromeReportUnrecoverableError),
324            MakeDisableCallbackFor(syncer::SUPERVISED_USER_SHARED_SETTINGS),
325            syncer::SUPERVISED_USER_SHARED_SETTINGS,
326            this));
327#endif
328}
329
330void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
331    syncer::ModelTypeSet disabled_types,
332    syncer::ModelTypeSet enabled_types,
333    ProfileSyncService* pss) {
334  // App sync is enabled by default.  Register unless explicitly
335  // disabled.
336  if (!disabled_types.Has(syncer::APPS)) {
337    pss->RegisterDataTypeController(
338        new ExtensionDataTypeController(syncer::APPS, this, profile_,
339                                        MakeDisableCallbackFor(syncer::APPS)));
340  }
341
342  // Extension sync is enabled by default.  Register unless explicitly
343  // disabled.
344  if (!disabled_types.Has(syncer::EXTENSIONS)) {
345    pss->RegisterDataTypeController(
346        new ExtensionDataTypeController(
347            syncer::EXTENSIONS, this, profile_,
348            MakeDisableCallbackFor(syncer::EXTENSIONS)));
349  }
350
351  // Preference sync is enabled by default.  Register unless explicitly
352  // disabled.
353  if (!disabled_types.Has(syncer::PREFERENCES)) {
354    pss->RegisterDataTypeController(
355        new UIDataTypeController(
356            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
357            base::Bind(&ChromeReportUnrecoverableError),
358            MakeDisableCallbackFor(syncer::PREFERENCES),
359            syncer::PREFERENCES,
360            this));
361
362  }
363
364  if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) {
365    pss->RegisterDataTypeController(
366        new UIDataTypeController(
367            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
368            base::Bind(&ChromeReportUnrecoverableError),
369            MakeDisableCallbackFor(syncer::PRIORITY_PREFERENCES),
370            syncer::PRIORITY_PREFERENCES,
371            this));
372  }
373
374#if defined(ENABLE_THEMES)
375  // Theme sync is enabled by default.  Register unless explicitly disabled.
376  if (!disabled_types.Has(syncer::THEMES)) {
377    pss->RegisterDataTypeController(
378        new ThemeDataTypeController(this, profile_,
379                                    MakeDisableCallbackFor(syncer::THEMES)));
380  }
381#endif
382
383  // Search Engine sync is enabled by default.  Register unless explicitly
384  // disabled.
385  if (!disabled_types.Has(syncer::SEARCH_ENGINES)) {
386    pss->RegisterDataTypeController(
387        new SearchEngineDataTypeController(
388            this, profile_, MakeDisableCallbackFor(syncer::SEARCH_ENGINES)));
389  }
390
391  // Extension setting sync is enabled by default.  Register unless explicitly
392  // disabled.
393  if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) {
394    pss->RegisterDataTypeController(
395        new ExtensionSettingDataTypeController(
396            syncer::EXTENSION_SETTINGS, this, profile_,
397            MakeDisableCallbackFor(syncer::EXTENSION_SETTINGS)));
398  }
399
400  // App setting sync is enabled by default.  Register unless explicitly
401  // disabled.
402  if (!disabled_types.Has(syncer::APP_SETTINGS)) {
403    pss->RegisterDataTypeController(
404        new ExtensionSettingDataTypeController(
405            syncer::APP_SETTINGS, this, profile_,
406            MakeDisableCallbackFor(syncer::APP_SETTINGS)));
407  }
408
409#if defined(ENABLE_APP_LIST)
410  if (app_list::switches::IsAppListSyncEnabled()) {
411    pss->RegisterDataTypeController(
412        new UIDataTypeController(
413            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
414            base::Bind(&ChromeReportUnrecoverableError),
415            MakeDisableCallbackFor(syncer::APP_LIST),
416            syncer::APP_LIST,
417            this));
418  }
419#endif
420
421  // Synced Notifications are disabled by default.
422#if defined(ENABLE_EXTENSIONS) && defined(ENABLE_NOTIFICATIONS)
423  if (enabled_types.Has(syncer::SYNCED_NOTIFICATIONS)) {
424    pss->RegisterDataTypeController(
425        new UIDataTypeController(
426              BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
427              base::Bind(&ChromeReportUnrecoverableError),
428              MakeDisableCallbackFor(syncer::SYNCED_NOTIFICATIONS),
429              syncer::SYNCED_NOTIFICATIONS,
430              this));
431
432    pss->RegisterDataTypeController(new UIDataTypeController(
433        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
434        base::Bind(&ChromeReportUnrecoverableError),
435        MakeDisableCallbackFor(syncer::SYNCED_NOTIFICATIONS),
436        syncer::SYNCED_NOTIFICATION_APP_INFO,
437        this));
438  }
439#endif
440
441#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_CHROMEOS)
442  // Dictionary sync is enabled by default.
443  if (!disabled_types.Has(syncer::DICTIONARY)) {
444    pss->RegisterDataTypeController(
445        new UIDataTypeController(
446            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
447            base::Bind(&ChromeReportUnrecoverableError),
448            MakeDisableCallbackFor(syncer::DICTIONARY),
449            syncer::DICTIONARY,
450            this));
451  }
452#endif
453}
454
455DataTypeManager* ProfileSyncComponentsFactoryImpl::CreateDataTypeManager(
456    const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
457        debug_info_listener,
458    const DataTypeController::TypeMap* controllers,
459    const browser_sync::DataTypeEncryptionHandler* encryption_handler,
460    SyncBackendHost* backend,
461    DataTypeManagerObserver* observer,
462    browser_sync::FailedDataTypesHandler* failed_data_types_handler) {
463  return new DataTypeManagerImpl(base::Bind(ChromeReportUnrecoverableError),
464                                 debug_info_listener,
465                                 controllers,
466                                 encryption_handler,
467                                 backend,
468                                 observer,
469                                 failed_data_types_handler);
470}
471
472browser_sync::SyncBackendHost*
473ProfileSyncComponentsFactoryImpl::CreateSyncBackendHost(
474    const std::string& name,
475    Profile* profile,
476    invalidation::InvalidationService* invalidator,
477    const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs,
478    const base::FilePath& sync_folder) {
479  return new browser_sync::SyncBackendHostImpl(name, profile, invalidator,
480                                               sync_prefs, sync_folder);
481}
482
483base::WeakPtr<syncer::SyncableService> ProfileSyncComponentsFactoryImpl::
484    GetSyncableServiceForType(syncer::ModelType type) {
485  if (!profile_) {  // For tests.
486     return base::WeakPtr<syncer::SyncableService>();
487  }
488  switch (type) {
489    case syncer::PREFERENCES:
490      return PrefServiceSyncable::FromProfile(
491          profile_)->GetSyncableService(syncer::PREFERENCES)->AsWeakPtr();
492    case syncer::PRIORITY_PREFERENCES:
493      return PrefServiceSyncable::FromProfile(profile_)->GetSyncableService(
494          syncer::PRIORITY_PREFERENCES)->AsWeakPtr();
495    case syncer::AUTOFILL:
496    case syncer::AUTOFILL_PROFILE: {
497      if (!web_data_service_.get())
498        return base::WeakPtr<syncer::SyncableService>();
499      if (type == syncer::AUTOFILL) {
500        return AutocompleteSyncableService::FromWebDataService(
501            web_data_service_.get())->AsWeakPtr();
502      } else {
503        return autofill::AutofillProfileSyncableService::FromWebDataService(
504            web_data_service_.get())->AsWeakPtr();
505      }
506    }
507    case syncer::SEARCH_ENGINES:
508      return TemplateURLServiceFactory::GetForProfile(profile_)->AsWeakPtr();
509#if defined(ENABLE_EXTENSIONS)
510    case syncer::APPS:
511    case syncer::EXTENSIONS:
512      return ExtensionSyncService::Get(profile_)->AsWeakPtr();
513    case syncer::APP_SETTINGS:
514    case syncer::EXTENSION_SETTINGS:
515      return extensions::settings_sync_util::GetSyncableService(profile_, type)
516          ->AsWeakPtr();
517#endif
518#if defined(ENABLE_APP_LIST)
519    case syncer::APP_LIST:
520      return app_list::AppListSyncableServiceFactory::GetForProfile(profile_)->
521          AsWeakPtr();
522#endif
523#if defined(ENABLE_THEMES)
524    case syncer::THEMES:
525      return ThemeServiceFactory::GetForProfile(profile_)->
526          GetThemeSyncableService()->AsWeakPtr();
527#endif
528    case syncer::HISTORY_DELETE_DIRECTIVES: {
529      HistoryService* history =
530          HistoryServiceFactory::GetForProfile(
531              profile_, Profile::EXPLICIT_ACCESS);
532      return history ? history->AsWeakPtr() : base::WeakPtr<HistoryService>();
533    }
534#if defined(ENABLE_EXTENSIONS)
535    case syncer::SYNCED_NOTIFICATIONS:
536    case syncer::SYNCED_NOTIFICATION_APP_INFO: {
537      return notifier::ChromeNotifierServiceFactory::GetForProfile(
538                 profile_, Profile::IMPLICIT_ACCESS)
539          ->GetSyncedNotificationsShim()
540          ->AsWeakPtr();
541    }
542#endif
543#if defined(ENABLE_SPELLCHECK)
544    case syncer::DICTIONARY:
545      return SpellcheckServiceFactory::GetForContext(profile_)->
546          GetCustomDictionary()->AsWeakPtr();
547#endif
548    case syncer::FAVICON_IMAGES:
549    case syncer::FAVICON_TRACKING: {
550      browser_sync::FaviconCache* favicons =
551          ProfileSyncServiceFactory::GetForProfile(profile_)->
552              GetFaviconCache();
553      return favicons ? favicons->AsWeakPtr()
554                      : base::WeakPtr<syncer::SyncableService>();
555    }
556#if defined(ENABLE_MANAGED_USERS)
557    case syncer::SUPERVISED_USER_SETTINGS:
558      return SupervisedUserSettingsServiceFactory::GetForProfile(profile_)->
559          AsWeakPtr();
560    case syncer::SUPERVISED_USERS:
561      return SupervisedUserSyncServiceFactory::GetForProfile(profile_)->
562          AsWeakPtr();
563    case syncer::SUPERVISED_USER_SHARED_SETTINGS:
564      return SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
565          profile_)->AsWeakPtr();
566#endif
567    case syncer::ARTICLES: {
568      dom_distiller::DomDistillerService* service =
569          dom_distiller::DomDistillerServiceFactory::GetForBrowserContext(
570              profile_);
571      if (service)
572        return service->GetSyncableService()->AsWeakPtr();
573      return base::WeakPtr<syncer::SyncableService>();
574    }
575    case syncer::SESSIONS: {
576      return ProfileSyncServiceFactory::GetForProfile(profile_)->
577          GetSessionsSyncableService()->AsWeakPtr();
578    }
579    case syncer::PASSWORDS: {
580#if defined(PASSWORD_MANAGER_ENABLE_SYNC)
581      password_manager::PasswordStore* password_store =
582          PasswordStoreFactory::GetForProfile(profile_,
583                                              Profile::EXPLICIT_ACCESS);
584      return password_store ? password_store->GetPasswordSyncableService()
585                            : base::WeakPtr<syncer::SyncableService>();
586#else
587      return base::WeakPtr<syncer::SyncableService>();
588#endif
589    }
590    default:
591      // The following datatypes still need to be transitioned to the
592      // syncer::SyncableService API:
593      // Bookmarks
594      // Typed URLs
595      NOTREACHED();
596      return base::WeakPtr<syncer::SyncableService>();
597  }
598}
599
600class TokenServiceProvider
601    : public OAuth2TokenServiceRequest::TokenServiceProvider {
602 public:
603  TokenServiceProvider(
604      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
605      OAuth2TokenService* token_service);
606  virtual ~TokenServiceProvider();
607
608  // OAuth2TokenServiceRequest::TokenServiceProvider implementation.
609  virtual scoped_refptr<base::SingleThreadTaskRunner>
610      GetTokenServiceTaskRunner() OVERRIDE;
611  virtual OAuth2TokenService* GetTokenService() OVERRIDE;
612
613 private:
614  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
615  OAuth2TokenService* token_service_;
616};
617
618TokenServiceProvider::TokenServiceProvider(
619    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
620    OAuth2TokenService* token_service)
621    : task_runner_(task_runner), token_service_(token_service) {
622}
623
624TokenServiceProvider::~TokenServiceProvider() {
625}
626
627scoped_refptr<base::SingleThreadTaskRunner>
628TokenServiceProvider::GetTokenServiceTaskRunner() {
629  return task_runner_;
630}
631
632OAuth2TokenService* TokenServiceProvider::GetTokenService() {
633  return token_service_;
634}
635
636scoped_ptr<syncer::AttachmentService>
637ProfileSyncComponentsFactoryImpl::CreateAttachmentService(
638    syncer::AttachmentService::Delegate* delegate) {
639  std::string url_prefix = GetSyncServiceAttachmentsURL(sync_service_url_);
640  scoped_ptr<OAuth2TokenServiceRequest::TokenServiceProvider>
641      token_service_provider(new TokenServiceProvider(
642          content::BrowserThread::GetMessageLoopProxyForThread(
643              content::BrowserThread::UI),
644          token_service_));
645
646  // TODO(maniscalco): Use shared (one per profile) thread-safe instances of
647  // AttachmentUploader and AttachmentDownloader instead of creating a new one
648  // per AttachmentService (bug 369536).
649  scoped_ptr<syncer::AttachmentUploader> attachment_uploader(
650      new syncer::AttachmentUploaderImpl(url_prefix,
651                                         url_request_context_getter_,
652                                         account_id_,
653                                         scope_set_,
654                                         token_service_provider.Pass()));
655
656  scoped_ptr<syncer::AttachmentDownloader> attachment_downloader(
657      new syncer::FakeAttachmentDownloader());
658
659  scoped_ptr<syncer::AttachmentStore> attachment_store(
660      new syncer::FakeAttachmentStore(
661          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)));
662
663  scoped_ptr<syncer::AttachmentService> attachment_service(
664      new syncer::AttachmentServiceImpl(attachment_store.Pass(),
665                                        attachment_uploader.Pass(),
666                                        attachment_downloader.Pass(),
667                                        delegate));
668
669  return attachment_service.Pass();
670}
671
672ProfileSyncComponentsFactory::SyncComponents
673    ProfileSyncComponentsFactoryImpl::CreateBookmarkSyncComponents(
674        ProfileSyncService* profile_sync_service,
675        DataTypeErrorHandler* error_handler) {
676  BookmarkModel* bookmark_model =
677      BookmarkModelFactory::GetForProfile(profile_sync_service->profile());
678  syncer::UserShare* user_share = profile_sync_service->GetUserShare();
679  // TODO(akalin): We may want to propagate this switch up eventually.
680#if defined(OS_ANDROID)
681  const bool kExpectMobileBookmarksFolder = true;
682#else
683  const bool kExpectMobileBookmarksFolder = false;
684#endif
685  BookmarkModelAssociator* model_associator =
686      new BookmarkModelAssociator(bookmark_model,
687                                  profile_sync_service->profile(),
688                                  user_share,
689                                  error_handler,
690                                  kExpectMobileBookmarksFolder);
691  BookmarkChangeProcessor* change_processor =
692      new BookmarkChangeProcessor(profile_sync_service->profile(),
693                                  model_associator,
694                                  error_handler);
695  return SyncComponents(model_associator, change_processor);
696}
697
698ProfileSyncComponentsFactory::SyncComponents
699    ProfileSyncComponentsFactoryImpl::CreateTypedUrlSyncComponents(
700        ProfileSyncService* profile_sync_service,
701        history::HistoryBackend* history_backend,
702        browser_sync::DataTypeErrorHandler* error_handler) {
703  TypedUrlModelAssociator* model_associator =
704      new TypedUrlModelAssociator(profile_sync_service,
705                                  history_backend,
706                                  error_handler);
707  TypedUrlChangeProcessor* change_processor =
708      new TypedUrlChangeProcessor(profile_,
709                                  model_associator,
710                                  history_backend,
711                                  error_handler);
712  return SyncComponents(model_associator, change_processor);
713}
714