Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / chrome / browser / sync / profile_sync_components_factory_impl.cc
bloba30c726e5336d7d8af82250e96f5a7b53b951b88
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.
5 #include "chrome/browser/sync/profile_sync_components_factory_impl.h"
7 #include "base/command_line.h"
8 #include "base/prefs/pref_service.h"
9 #include "build/build_config.h"
10 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/sync/glue/autofill_data_type_controller.h"
13 #include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h"
14 #include "chrome/browser/sync/glue/autofill_wallet_data_type_controller.h"
15 #include "chrome/browser/sync/glue/bookmark_change_processor.h"
16 #include "chrome/browser/sync/glue/bookmark_data_type_controller.h"
17 #include "chrome/browser/sync/glue/bookmark_model_associator.h"
18 #include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h"
19 #include "chrome/browser/sync/glue/history_delete_directives_data_type_controller.h"
20 #include "chrome/browser/sync/glue/local_device_info_provider_impl.h"
21 #include "chrome/browser/sync/glue/password_data_type_controller.h"
22 #include "chrome/browser/sync/glue/search_engine_data_type_controller.h"
23 #include "chrome/browser/sync/glue/sync_backend_host.h"
24 #include "chrome/browser/sync/glue/sync_backend_host_impl.h"
25 #include "chrome/browser/sync/glue/theme_data_type_controller.h"
26 #include "chrome/browser/sync/glue/typed_url_change_processor.h"
27 #include "chrome/browser/sync/glue/typed_url_data_type_controller.h"
28 #include "chrome/browser/sync/profile_sync_service.h"
29 #include "chrome/browser/sync/sessions/session_data_type_controller.h"
30 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/pref_names.h"
32 #include "components/autofill/core/common/autofill_pref_names.h"
33 #include "components/autofill/core/common/autofill_switches.h"
34 #include "components/dom_distiller/core/dom_distiller_features.h"
35 #include "components/sync_driver/data_type_manager_impl.h"
36 #include "components/sync_driver/device_info_data_type_controller.h"
37 #include "components/sync_driver/glue/typed_url_model_associator.h"
38 #include "components/sync_driver/proxy_data_type_controller.h"
39 #include "components/sync_driver/ui_data_type_controller.h"
40 #include "content/public/browser/browser_thread.h"
41 #include "google_apis/gaia/oauth2_token_service.h"
42 #include "google_apis/gaia/oauth2_token_service_request.h"
43 #include "net/url_request/url_request_context_getter.h"
44 #include "sync/internal_api/public/attachments/attachment_downloader.h"
45 #include "sync/internal_api/public/attachments/attachment_service.h"
46 #include "sync/internal_api/public/attachments/attachment_service_impl.h"
47 #include "sync/internal_api/public/attachments/attachment_uploader_impl.h"
49 #if defined(ENABLE_APP_LIST)
50 #include "ui/app_list/app_list_switches.h"
51 #endif
53 #if defined(ENABLE_EXTENSIONS)
54 #include "chrome/browser/sync/glue/extension_data_type_controller.h"
55 #include "chrome/browser/sync/glue/extension_setting_data_type_controller.h"
56 #endif
58 #if defined(ENABLE_SUPERVISED_USERS)
59 #include "chrome/browser/supervised_user/supervised_user_sync_data_type_controller.h"
60 #endif
62 using bookmarks::BookmarkModel;
63 using browser_sync::AutofillDataTypeController;
64 using browser_sync::AutofillProfileDataTypeController;
65 using browser_sync::BookmarkChangeProcessor;
66 using browser_sync::BookmarkDataTypeController;
67 using browser_sync::BookmarkModelAssociator;
68 using browser_sync::ChromeReportUnrecoverableError;
69 #if defined(ENABLE_EXTENSIONS)
70 using browser_sync::ExtensionDataTypeController;
71 using browser_sync::ExtensionSettingDataTypeController;
72 #endif
73 using browser_sync::HistoryDeleteDirectivesDataTypeController;
74 using browser_sync::PasswordDataTypeController;
75 using browser_sync::SearchEngineDataTypeController;
76 using browser_sync::SessionDataTypeController;
77 using browser_sync::SyncBackendHost;
78 using browser_sync::ThemeDataTypeController;
79 using browser_sync::TypedUrlChangeProcessor;
80 using browser_sync::TypedUrlDataTypeController;
81 using browser_sync::TypedUrlModelAssociator;
82 using content::BrowserThread;
83 using sync_driver::DataTypeController;
84 using sync_driver::DataTypeErrorHandler;
85 using sync_driver::DataTypeManager;
86 using sync_driver::DataTypeManagerImpl;
87 using sync_driver::DataTypeManagerObserver;
88 using sync_driver::DeviceInfoDataTypeController;
89 using sync_driver::ProxyDataTypeController;
90 using sync_driver::UIDataTypeController;
92 namespace {
94 syncer::ModelTypeSet GetDisabledTypesFromCommandLine(
95 const base::CommandLine& command_line) {
96 syncer::ModelTypeSet disabled_types;
97 std::string disabled_types_str =
98 command_line.GetSwitchValueASCII(switches::kDisableSyncTypes);
100 // Disable sync types experimentally to measure impact on startup time.
101 // TODO(mlerman): Remove this after the experiment. crbug.com/454788
102 std::string disable_types_finch =
103 variations::GetVariationParamValue("LightSpeed", "DisableSyncPart");
104 if (!disable_types_finch.empty()) {
105 if (disabled_types_str.empty())
106 disabled_types_str = disable_types_finch;
107 else
108 disabled_types_str += ", " + disable_types_finch;
111 disabled_types = syncer::ModelTypeSetFromString(disabled_types_str);
112 return disabled_types;
115 syncer::ModelTypeSet GetEnabledTypesFromCommandLine(
116 const base::CommandLine& command_line) {
117 syncer::ModelTypeSet enabled_types;
118 if (command_line.HasSwitch(autofill::switches::kEnableWalletMetadataSync))
119 enabled_types.Put(syncer::AUTOFILL_WALLET_METADATA);
121 return enabled_types;
124 } // namespace
126 ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl(
127 Profile* profile,
128 base::CommandLine* command_line,
129 const GURL& sync_service_url,
130 OAuth2TokenService* token_service,
131 net::URLRequestContextGetter* url_request_context_getter)
132 : profile_(profile),
133 command_line_(command_line),
134 sync_service_url_(sync_service_url),
135 token_service_(token_service),
136 url_request_context_getter_(url_request_context_getter),
137 chrome_sync_client_(profile_, this),
138 weak_factory_(this) {
139 DCHECK(token_service_);
140 DCHECK(url_request_context_getter_);
143 ProfileSyncComponentsFactoryImpl::~ProfileSyncComponentsFactoryImpl() {
146 void ProfileSyncComponentsFactoryImpl::Initialize(
147 sync_driver::SyncService* sync_service) {
148 chrome_sync_client_.Initialize(sync_service);
151 void ProfileSyncComponentsFactoryImpl::RegisterDataTypes() {
152 syncer::ModelTypeSet disabled_types =
153 GetDisabledTypesFromCommandLine(*command_line_);
154 syncer::ModelTypeSet enabled_types =
155 GetEnabledTypesFromCommandLine(*command_line_);
156 RegisterCommonDataTypes(disabled_types, enabled_types);
157 #if !defined(OS_ANDROID)
158 RegisterDesktopDataTypes(disabled_types, enabled_types);
159 #endif
162 void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
163 syncer::ModelTypeSet disabled_types,
164 syncer::ModelTypeSet enabled_types) {
165 sync_driver::SyncService* sync_service = chrome_sync_client_.GetSyncService();
167 // TODO(stanisc): can DEVICE_INFO be one of disabled datatypes?
168 sync_service->RegisterDataTypeController(new DeviceInfoDataTypeController(
169 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
170 base::Bind(&ChromeReportUnrecoverableError),
171 &chrome_sync_client_,
172 sync_service->GetLocalDeviceInfoProvider()));
174 // Autofill sync is enabled by default. Register unless explicitly
175 // disabled.
176 if (!disabled_types.Has(syncer::AUTOFILL)) {
177 sync_service->RegisterDataTypeController(
178 new AutofillDataTypeController(&chrome_sync_client_));
181 // Autofill profile sync is enabled by default. Register unless explicitly
182 // disabled.
183 if (!disabled_types.Has(syncer::AUTOFILL_PROFILE)) {
184 sync_service->RegisterDataTypeController(
185 new AutofillProfileDataTypeController(&chrome_sync_client_));
188 // Wallet data sync is enabled by default, but behind a syncer experiment
189 // enforced by the datatype controller. Register unless explicitly disabled.
190 bool wallet_disabled = disabled_types.Has(syncer::AUTOFILL_WALLET_DATA);
191 if (!wallet_disabled) {
192 sync_service->RegisterDataTypeController(
193 new browser_sync::AutofillWalletDataTypeController(
194 &chrome_sync_client_, syncer::AUTOFILL_WALLET_DATA));
197 // Wallet metadata sync depends on Wallet data sync and is disabled by
198 // default. Register if Wallet data is syncing and metadata sync is explicitly
199 // enabled.
200 if (!wallet_disabled && enabled_types.Has(syncer::AUTOFILL_WALLET_METADATA)) {
201 sync_service->RegisterDataTypeController(
202 new browser_sync::AutofillWalletDataTypeController(
203 &chrome_sync_client_, syncer::AUTOFILL_WALLET_METADATA));
206 // Bookmark sync is enabled by default. Register unless explicitly
207 // disabled.
208 if (!disabled_types.Has(syncer::BOOKMARKS)) {
209 sync_service->RegisterDataTypeController(
210 new BookmarkDataTypeController(&chrome_sync_client_));
213 const bool history_disabled =
214 profile_->GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled);
215 // TypedUrl sync is enabled by default. Register unless explicitly disabled,
216 // or if saving history is disabled.
217 if (!disabled_types.Has(syncer::TYPED_URLS) && !history_disabled) {
218 sync_service->RegisterDataTypeController(
219 new TypedUrlDataTypeController(&chrome_sync_client_));
222 // Delete directive sync is enabled by default. Register unless full history
223 // sync is disabled.
224 if (!disabled_types.Has(syncer::HISTORY_DELETE_DIRECTIVES) &&
225 !history_disabled) {
226 sync_service->RegisterDataTypeController(
227 new HistoryDeleteDirectivesDataTypeController(&chrome_sync_client_));
230 // Session sync is enabled by default. Register unless explicitly disabled.
231 // This is also disabled if the browser history is disabled, because the
232 // tab sync data is added to the web history on the server.
233 if (!disabled_types.Has(syncer::PROXY_TABS) && !history_disabled) {
234 sync_service->RegisterDataTypeController(new ProxyDataTypeController(
235 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
236 syncer::PROXY_TABS));
237 // TODO(zea): remove this once SyncedWindowDelegateGetter is componentized.
238 // For now, we know that the implementation of SyncService is always a
239 // ProfileSyncService at this level.
240 ProfileSyncService* pss = static_cast<ProfileSyncService*>(sync_service);
241 sync_service->RegisterDataTypeController(new SessionDataTypeController(
242 &chrome_sync_client_, profile_, pss->GetSyncedWindowDelegatesGetter(),
243 sync_service->GetLocalDeviceInfoProvider()));
246 // Favicon sync is enabled by default. Register unless explicitly disabled.
247 if (!disabled_types.Has(syncer::FAVICON_IMAGES) &&
248 !disabled_types.Has(syncer::FAVICON_TRACKING) &&
249 !history_disabled) {
250 // crbug/384552. We disable error uploading for this data types for now.
251 sync_service->RegisterDataTypeController(
252 new UIDataTypeController(
253 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
254 base::Closure(),
255 syncer::FAVICON_IMAGES,
256 &chrome_sync_client_));
257 sync_service->RegisterDataTypeController(
258 new UIDataTypeController(
259 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
260 base::Closure(),
261 syncer::FAVICON_TRACKING,
262 &chrome_sync_client_));
265 // Password sync is enabled by default. Register unless explicitly
266 // disabled.
267 if (!disabled_types.Has(syncer::PASSWORDS)) {
268 sync_service->RegisterDataTypeController(
269 new PasswordDataTypeController(&chrome_sync_client_, profile_));
272 if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) {
273 sync_service->RegisterDataTypeController(
274 new UIDataTypeController(
275 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
276 base::Bind(&ChromeReportUnrecoverableError),
277 syncer::PRIORITY_PREFERENCES,
278 &chrome_sync_client_));
281 // Article sync is disabled by default. Register only if explicitly enabled.
282 if (dom_distiller::IsEnableSyncArticlesSet()) {
283 sync_service->RegisterDataTypeController(
284 new UIDataTypeController(
285 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
286 base::Bind(&ChromeReportUnrecoverableError),
287 syncer::ARTICLES,
288 &chrome_sync_client_));
291 #if defined(ENABLE_SUPERVISED_USERS)
292 sync_service->RegisterDataTypeController(
293 new SupervisedUserSyncDataTypeController(
294 syncer::SUPERVISED_USER_SETTINGS,
295 &chrome_sync_client_,
296 profile_));
297 sync_service->RegisterDataTypeController(
298 new SupervisedUserSyncDataTypeController(
299 syncer::SUPERVISED_USER_WHITELISTS,
300 &chrome_sync_client_,
301 profile_));
302 #endif
305 void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
306 syncer::ModelTypeSet disabled_types,
307 syncer::ModelTypeSet enabled_types) {
308 sync_driver::SyncService* sync_service = chrome_sync_client_.GetSyncService();
310 #if defined(ENABLE_EXTENSIONS)
311 // App sync is enabled by default. Register unless explicitly
312 // disabled.
313 if (!disabled_types.Has(syncer::APPS)) {
314 sync_service->RegisterDataTypeController(new ExtensionDataTypeController(
315 syncer::APPS, &chrome_sync_client_, profile_));
318 // Extension sync is enabled by default. Register unless explicitly
319 // disabled.
320 if (!disabled_types.Has(syncer::EXTENSIONS)) {
321 sync_service->RegisterDataTypeController(new ExtensionDataTypeController(
322 syncer::EXTENSIONS, &chrome_sync_client_, profile_));
324 #endif
326 // Preference sync is enabled by default. Register unless explicitly
327 // disabled.
328 if (!disabled_types.Has(syncer::PREFERENCES)) {
329 sync_service->RegisterDataTypeController(
330 new UIDataTypeController(
331 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
332 base::Bind(&ChromeReportUnrecoverableError),
333 syncer::PREFERENCES,
334 &chrome_sync_client_));
337 #if defined(ENABLE_THEMES)
338 // Theme sync is enabled by default. Register unless explicitly disabled.
339 if (!disabled_types.Has(syncer::THEMES)) {
340 sync_service->RegisterDataTypeController(
341 new ThemeDataTypeController(&chrome_sync_client_, profile_));
343 #endif
345 // Search Engine sync is enabled by default. Register unless explicitly
346 // disabled.
347 if (!disabled_types.Has(syncer::SEARCH_ENGINES)) {
348 sync_service->RegisterDataTypeController(
349 new SearchEngineDataTypeController(&chrome_sync_client_, profile_));
352 #if defined(ENABLE_EXTENSIONS)
353 // Extension setting sync is enabled by default. Register unless explicitly
354 // disabled.
355 if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) {
356 sync_service->RegisterDataTypeController(
357 new ExtensionSettingDataTypeController(syncer::EXTENSION_SETTINGS,
358 &chrome_sync_client_, profile_));
361 // App setting sync is enabled by default. Register unless explicitly
362 // disabled.
363 if (!disabled_types.Has(syncer::APP_SETTINGS)) {
364 sync_service->RegisterDataTypeController(
365 new ExtensionSettingDataTypeController(syncer::APP_SETTINGS,
366 &chrome_sync_client_, profile_));
368 #endif
370 #if defined(ENABLE_APP_LIST)
371 if (app_list::switches::IsAppListSyncEnabled()) {
372 sync_service->RegisterDataTypeController(
373 new UIDataTypeController(
374 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
375 base::Bind(&ChromeReportUnrecoverableError),
376 syncer::APP_LIST,
377 &chrome_sync_client_));
379 #endif
381 #if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_CHROMEOS)
382 // Dictionary sync is enabled by default.
383 if (!disabled_types.Has(syncer::DICTIONARY)) {
384 sync_service->RegisterDataTypeController(
385 new UIDataTypeController(
386 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
387 base::Bind(&ChromeReportUnrecoverableError),
388 syncer::DICTIONARY,
389 &chrome_sync_client_));
391 #endif
393 #if defined(ENABLE_SUPERVISED_USERS)
394 sync_service->RegisterDataTypeController(
395 new SupervisedUserSyncDataTypeController(
396 syncer::SUPERVISED_USERS,
397 &chrome_sync_client_,
398 profile_));
399 sync_service->RegisterDataTypeController(
400 new SupervisedUserSyncDataTypeController(
401 syncer::SUPERVISED_USER_SHARED_SETTINGS,
402 &chrome_sync_client_,
403 profile_));
404 #endif
406 #if defined(OS_CHROMEOS)
407 if (command_line_->HasSwitch(switches::kEnableWifiCredentialSync) &&
408 !disabled_types.Has(syncer::WIFI_CREDENTIALS)) {
409 sync_service->RegisterDataTypeController(
410 new UIDataTypeController(
411 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
412 base::Bind(&ChromeReportUnrecoverableError),
413 syncer::WIFI_CREDENTIALS,
414 &chrome_sync_client_));
416 #endif
419 DataTypeManager* ProfileSyncComponentsFactoryImpl::CreateDataTypeManager(
420 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
421 debug_info_listener,
422 const DataTypeController::TypeMap* controllers,
423 const sync_driver::DataTypeEncryptionHandler* encryption_handler,
424 SyncBackendHost* backend,
425 DataTypeManagerObserver* observer) {
426 return new DataTypeManagerImpl(base::Bind(ChromeReportUnrecoverableError),
427 debug_info_listener,
428 controllers,
429 encryption_handler,
430 backend,
431 observer);
434 browser_sync::SyncBackendHost*
435 ProfileSyncComponentsFactoryImpl::CreateSyncBackendHost(
436 const std::string& name,
437 invalidation::InvalidationService* invalidator,
438 const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs,
439 const base::FilePath& sync_folder) {
440 return new browser_sync::SyncBackendHostImpl(
441 name, profile_,
442 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
443 invalidator, sync_prefs, sync_folder);
446 scoped_ptr<sync_driver::LocalDeviceInfoProvider>
447 ProfileSyncComponentsFactoryImpl::CreateLocalDeviceInfoProvider() {
448 return scoped_ptr<sync_driver::LocalDeviceInfoProvider>(
449 new browser_sync::LocalDeviceInfoProviderImpl());
452 class TokenServiceProvider
453 : public OAuth2TokenServiceRequest::TokenServiceProvider {
454 public:
455 TokenServiceProvider(
456 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
457 OAuth2TokenService* token_service);
459 // OAuth2TokenServiceRequest::TokenServiceProvider implementation.
460 scoped_refptr<base::SingleThreadTaskRunner> GetTokenServiceTaskRunner()
461 override;
462 OAuth2TokenService* GetTokenService() override;
464 private:
465 ~TokenServiceProvider() override;
467 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
468 OAuth2TokenService* token_service_;
471 TokenServiceProvider::TokenServiceProvider(
472 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
473 OAuth2TokenService* token_service)
474 : task_runner_(task_runner), token_service_(token_service) {
477 TokenServiceProvider::~TokenServiceProvider() {
480 scoped_refptr<base::SingleThreadTaskRunner>
481 TokenServiceProvider::GetTokenServiceTaskRunner() {
482 return task_runner_;
485 OAuth2TokenService* TokenServiceProvider::GetTokenService() {
486 return token_service_;
489 scoped_ptr<syncer::AttachmentService>
490 ProfileSyncComponentsFactoryImpl::CreateAttachmentService(
491 scoped_ptr<syncer::AttachmentStoreForSync> attachment_store,
492 const syncer::UserShare& user_share,
493 const std::string& store_birthday,
494 syncer::ModelType model_type,
495 syncer::AttachmentService::Delegate* delegate) {
496 scoped_ptr<syncer::AttachmentUploader> attachment_uploader;
497 scoped_ptr<syncer::AttachmentDownloader> attachment_downloader;
498 // Only construct an AttachmentUploader and AttachmentDownload if we have sync
499 // credentials. We may not have sync credentials because there may not be a
500 // signed in sync user (e.g. sync is running in "backup" mode).
501 if (!user_share.sync_credentials.email.empty() &&
502 !user_share.sync_credentials.scope_set.empty()) {
503 scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>
504 token_service_provider(new TokenServiceProvider(
505 content::BrowserThread::GetMessageLoopProxyForThread(
506 content::BrowserThread::UI),
507 token_service_));
508 // TODO(maniscalco): Use shared (one per profile) thread-safe instances of
509 // AttachmentUploader and AttachmentDownloader instead of creating a new one
510 // per AttachmentService (bug 369536).
511 attachment_uploader.reset(new syncer::AttachmentUploaderImpl(
512 sync_service_url_, url_request_context_getter_,
513 user_share.sync_credentials.email,
514 user_share.sync_credentials.scope_set, token_service_provider,
515 store_birthday, model_type));
517 token_service_provider = new TokenServiceProvider(
518 content::BrowserThread::GetMessageLoopProxyForThread(
519 content::BrowserThread::UI),
520 token_service_);
521 attachment_downloader = syncer::AttachmentDownloader::Create(
522 sync_service_url_, url_request_context_getter_,
523 user_share.sync_credentials.email,
524 user_share.sync_credentials.scope_set, token_service_provider,
525 store_birthday, model_type);
528 // It is important that the initial backoff delay is relatively large. For
529 // whatever reason, the server may fail all requests for a short period of
530 // time. When this happens we don't want to overwhelm the server with
531 // requests so we use a large initial backoff.
532 const base::TimeDelta initial_backoff_delay =
533 base::TimeDelta::FromMinutes(30);
534 const base::TimeDelta max_backoff_delay = base::TimeDelta::FromHours(4);
535 scoped_ptr<syncer::AttachmentService> attachment_service(
536 new syncer::AttachmentServiceImpl(
537 attachment_store.Pass(), attachment_uploader.Pass(),
538 attachment_downloader.Pass(), delegate, initial_backoff_delay,
539 max_backoff_delay));
540 return attachment_service.Pass();
543 sync_driver::SyncApiComponentFactory::SyncComponents
544 ProfileSyncComponentsFactoryImpl::CreateBookmarkSyncComponents(
545 sync_driver::SyncService* sync_service,
546 sync_driver::DataTypeErrorHandler* error_handler) {
547 BookmarkModel* bookmark_model =
548 BookmarkModelFactory::GetForProfile(profile_);
549 syncer::UserShare* user_share = sync_service->GetUserShare();
550 // TODO(akalin): We may want to propagate this switch up eventually.
551 #if defined(OS_ANDROID)
552 const bool kExpectMobileBookmarksFolder = true;
553 #else
554 const bool kExpectMobileBookmarksFolder = false;
555 #endif
556 BookmarkModelAssociator* model_associator =
557 new BookmarkModelAssociator(bookmark_model,
558 profile_,
559 user_share,
560 error_handler,
561 kExpectMobileBookmarksFolder);
562 BookmarkChangeProcessor* change_processor =
563 new BookmarkChangeProcessor(profile_,
564 model_associator,
565 error_handler);
566 return SyncComponents(model_associator, change_processor);
569 sync_driver::SyncApiComponentFactory::SyncComponents
570 ProfileSyncComponentsFactoryImpl::CreateTypedUrlSyncComponents(
571 sync_driver::SyncService* sync_service,
572 history::HistoryBackend* history_backend,
573 sync_driver::DataTypeErrorHandler* error_handler) {
574 // TODO(zea): Once TypedURLs are converted to SyncableService, remove
575 // |sync_service_| member, and make GetSyncService require it be called on
576 // the UI thread.
577 TypedUrlModelAssociator* model_associator =
578 new TypedUrlModelAssociator(sync_service,
579 history_backend,
580 error_handler);
581 TypedUrlChangeProcessor* change_processor =
582 new TypedUrlChangeProcessor(profile_,
583 model_associator,
584 history_backend,
585 error_handler);
586 return SyncComponents(model_associator, change_processor);