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