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