Home | History | Annotate | Download | only in sync
      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 
     98 using browser_sync::AutofillDataTypeController;
     99 using browser_sync::AutofillProfileDataTypeController;
    100 using browser_sync::BookmarkChangeProcessor;
    101 using browser_sync::BookmarkDataTypeController;
    102 using browser_sync::BookmarkModelAssociator;
    103 using browser_sync::ChromeReportUnrecoverableError;
    104 using browser_sync::DataTypeController;
    105 using browser_sync::DataTypeErrorHandler;
    106 using browser_sync::DataTypeManager;
    107 using browser_sync::DataTypeManagerImpl;
    108 using browser_sync::DataTypeManagerObserver;
    109 using browser_sync::ExtensionDataTypeController;
    110 using browser_sync::ExtensionSettingDataTypeController;
    111 using browser_sync::PasswordDataTypeController;
    112 using browser_sync::ProxyDataTypeController;
    113 using browser_sync::SearchEngineDataTypeController;
    114 using browser_sync::SessionDataTypeController;
    115 using browser_sync::SharedChangeProcessor;
    116 using browser_sync::SyncBackendHost;
    117 using browser_sync::ThemeDataTypeController;
    118 using browser_sync::TypedUrlChangeProcessor;
    119 using browser_sync::TypedUrlDataTypeController;
    120 using browser_sync::TypedUrlModelAssociator;
    121 using browser_sync::UIDataTypeController;
    122 using content::BrowserThread;
    123 
    124 namespace {
    125 
    126 const char kAttachmentsPath[] = "/attachments/";
    127 
    128 syncer::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 
    137 syncer::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.
    147 std::string GetSyncServiceAttachmentsURL(const GURL& sync_service_url) {
    148   return sync_service_url.spec() + kAttachmentsPath;
    149 }
    150 
    151 }  // namespace
    152 
    153 ProfileSyncComponentsFactoryImpl::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 
    176 ProfileSyncComponentsFactoryImpl::~ProfileSyncComponentsFactoryImpl() {
    177 }
    178 
    179 void 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 
    191 void 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->DisableDatatype(type, from_here, message);
    197 }
    198 
    199 DataTypeController::DisableTypeCallback
    200 ProfileSyncComponentsFactoryImpl::MakeDisableCallbackFor(
    201     syncer::ModelType type) {
    202   return base::Bind(&ProfileSyncComponentsFactoryImpl::DisableBrokenType,
    203                     weak_factory_.GetWeakPtr(),
    204                     type);
    205 }
    206 
    207 void 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 
    330 void 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 
    455 DataTypeManager* 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 
    472 browser_sync::SyncBackendHost*
    473 ProfileSyncComponentsFactoryImpl::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 
    483 base::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 
    600 class 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 
    618 TokenServiceProvider::TokenServiceProvider(
    619     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
    620     OAuth2TokenService* token_service)
    621     : task_runner_(task_runner), token_service_(token_service) {
    622 }
    623 
    624 TokenServiceProvider::~TokenServiceProvider() {
    625 }
    626 
    627 scoped_refptr<base::SingleThreadTaskRunner>
    628 TokenServiceProvider::GetTokenServiceTaskRunner() {
    629   return task_runner_;
    630 }
    631 
    632 OAuth2TokenService* TokenServiceProvider::GetTokenService() {
    633   return token_service_;
    634 }
    635 
    636 scoped_ptr<syncer::AttachmentService>
    637 ProfileSyncComponentsFactoryImpl::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 
    672 ProfileSyncComponentsFactory::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 
    698 ProfileSyncComponentsFactory::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