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 "components/browser_sync/profile_sync_components_factory_impl.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/feature_list.h"
11 #include "base/memory/ref_counted.h"
12 #include "build/build_config.h"
13 #include "components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h"
14 #include "components/autofill/core/browser/webdata/autocomplete_sync_bridge.h"
15 #include "components/autofill/core/browser/webdata/autofill_profile_model_type_controller.h"
16 #include "components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h"
17 #include "components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h"
18 #include "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h"
19 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
20 #include "components/browser_sync/browser_sync_client.h"
21 #include "components/history/core/browser/sync/history_delete_directives_model_type_controller.h"
22 #include "components/history/core/browser/sync/typed_url_model_type_controller.h"
23 #include "components/password_manager/core/browser/password_store.h"
24 #include "components/password_manager/core/browser/sync/password_model_type_controller.h"
25 #include "components/prefs/pref_service.h"
26 #include "components/reading_list/features/reading_list_switches.h"
27 #include "components/send_tab_to_self/send_tab_to_self_model_type_controller.h"
28 #include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
29 #include "components/sync/base/report_unrecoverable_error.h"
30 #include "components/sync/base/sync_base_switches.h"
31 #include "components/sync/driver/data_type_manager_impl.h"
32 #include "components/sync/driver/glue/sync_engine_impl.h"
33 #include "components/sync/driver/model_type_controller.h"
34 #include "components/sync/driver/sync_driver_switches.h"
35 #include "components/sync/driver/syncable_service_based_model_type_controller.h"
36 #include "components/sync/engine/sync_engine.h"
37 #include "components/sync/model/model_type_store_service.h"
38 #include "components/sync/model_impl/forwarding_model_type_controller_delegate.h"
39 #include "components/sync/model_impl/proxy_model_type_controller_delegate.h"
40 #include "components/sync_bookmarks/bookmark_sync_service.h"
41 #include "components/sync_device_info/device_info_sync_service.h"
42 #include "components/sync_sessions/proxy_tabs_data_type_controller.h"
43 #include "components/sync_sessions/session_model_type_controller.h"
44 #include "components/sync_sessions/session_sync_service.h"
45 #include "components/sync_user_events/user_event_model_type_controller.h"
46
47 #if defined(OS_CHROMEOS)
48 #include "chromeos/constants/chromeos_features.h"
49 #endif
50
51 using syncer::DataTypeController;
52 using syncer::DataTypeManager;
53 using syncer::DataTypeManagerImpl;
54 using syncer::DataTypeManagerObserver;
55 using syncer::ModelTypeController;
56 using syncer::SyncableServiceBasedModelTypeController;
57
58 namespace browser_sync {
59
60 namespace {
61
62 // These helper functions only wrap the factory functions of the bridges. This
63 // way, it simplifies life for the compiler which cannot directly cast
64 // "WeakPtr<ModelTypeSyncBridge> (AutofillWebDataService*)" to
65 // "WeakPtr<ModelTypeControllerDelegate> (AutofillWebDataService*)".
66 base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutocompleteDelegateFromDataService(autofill::AutofillWebDataService * service)67 AutocompleteDelegateFromDataService(autofill::AutofillWebDataService* service) {
68 return autofill::AutocompleteSyncBridge::FromWebDataService(service)
69 ->change_processor()
70 ->GetControllerDelegate();
71 }
72
73 base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutofillProfileDelegateFromDataService(autofill::AutofillWebDataService * service)74 AutofillProfileDelegateFromDataService(
75 autofill::AutofillWebDataService* service) {
76 return autofill::AutofillProfileSyncBridge::FromWebDataService(service)
77 ->change_processor()
78 ->GetControllerDelegate();
79 }
80
81 base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutofillWalletDelegateFromDataService(autofill::AutofillWebDataService * service)82 AutofillWalletDelegateFromDataService(
83 autofill::AutofillWebDataService* service) {
84 return autofill::AutofillWalletSyncBridge::FromWebDataService(service)
85 ->change_processor()
86 ->GetControllerDelegate();
87 }
88
89 base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutofillWalletMetadataDelegateFromDataService(autofill::AutofillWebDataService * service)90 AutofillWalletMetadataDelegateFromDataService(
91 autofill::AutofillWebDataService* service) {
92 return autofill::AutofillWalletMetadataSyncBridge::FromWebDataService(service)
93 ->change_processor()
94 ->GetControllerDelegate();
95 }
96
97 } // namespace
98
ProfileSyncComponentsFactoryImpl(browser_sync::BrowserSyncClient * sync_client,version_info::Channel channel,const char * history_disabled_pref,const scoped_refptr<base::SequencedTaskRunner> & ui_thread,const scoped_refptr<base::SequencedTaskRunner> & db_thread,const scoped_refptr<autofill::AutofillWebDataService> & web_data_service_on_disk,const scoped_refptr<autofill::AutofillWebDataService> & web_data_service_in_memory,const scoped_refptr<password_manager::PasswordStore> & profile_password_store,const scoped_refptr<password_manager::PasswordStore> & account_password_store,sync_bookmarks::BookmarkSyncService * bookmark_sync_service)99 ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl(
100 browser_sync::BrowserSyncClient* sync_client,
101 version_info::Channel channel,
102 const char* history_disabled_pref,
103 const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
104 const scoped_refptr<base::SequencedTaskRunner>& db_thread,
105 const scoped_refptr<autofill::AutofillWebDataService>&
106 web_data_service_on_disk,
107 const scoped_refptr<autofill::AutofillWebDataService>&
108 web_data_service_in_memory,
109 const scoped_refptr<password_manager::PasswordStore>&
110 profile_password_store,
111 const scoped_refptr<password_manager::PasswordStore>&
112 account_password_store,
113 sync_bookmarks::BookmarkSyncService* bookmark_sync_service)
114 : sync_client_(sync_client),
115 channel_(channel),
116 history_disabled_pref_(history_disabled_pref),
117 ui_thread_(ui_thread),
118 db_thread_(db_thread),
119 web_data_service_on_disk_(web_data_service_on_disk),
120 web_data_service_in_memory_(web_data_service_in_memory),
121 profile_password_store_(profile_password_store),
122 account_password_store_(account_password_store),
123 bookmark_sync_service_(bookmark_sync_service) {
124 DCHECK(sync_client_);
125 }
126
~ProfileSyncComponentsFactoryImpl()127 ProfileSyncComponentsFactoryImpl::~ProfileSyncComponentsFactoryImpl() {}
128
129 syncer::DataTypeController::TypeVector
CreateCommonDataTypeControllers(syncer::ModelTypeSet disabled_types,syncer::SyncService * sync_service)130 ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
131 syncer::ModelTypeSet disabled_types,
132 syncer::SyncService* sync_service) {
133 syncer::DataTypeController::TypeVector controllers;
134
135 const base::RepeatingClosure dump_stack =
136 base::BindRepeating(&syncer::ReportUnrecoverableError, channel_);
137
138 syncer::ModelTypeStoreService* model_type_store_service =
139 sync_client_->GetModelTypeStoreService();
140 DCHECK(model_type_store_service);
141 syncer::RepeatingModelTypeStoreFactory model_type_store_factory =
142 model_type_store_service->GetStoreFactory();
143
144 // TODO(crbug.com/1005651): Consider using a separate delegate for
145 // transport-only.
146 controllers.push_back(std::make_unique<ModelTypeController>(
147 syncer::DEVICE_INFO,
148 /*delegate_for_full_sync_mode=*/
149 std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
150 sync_client_->GetDeviceInfoSyncService()
151 ->GetControllerDelegate()
152 .get()),
153 /*delegate_for_transport_mode=*/
154 std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
155 sync_client_->GetDeviceInfoSyncService()
156 ->GetControllerDelegate()
157 .get())));
158
159 // These features are enabled only if there's a DB thread to post tasks to.
160 if (db_thread_) {
161 // Autocomplete sync is enabled by default. Register unless explicitly
162 // disabled.
163 if (!disabled_types.Has(syncer::AUTOFILL)) {
164 controllers.push_back(std::make_unique<ModelTypeController>(
165 syncer::AUTOFILL,
166 std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
167 db_thread_, base::BindRepeating(
168 &AutocompleteDelegateFromDataService,
169 base::RetainedRef(web_data_service_on_disk_)))));
170 }
171
172 // Autofill sync is enabled by default. Register unless explicitly
173 // disabled.
174 if (!disabled_types.Has(syncer::AUTOFILL_PROFILE)) {
175 controllers.push_back(
176 std::make_unique<AutofillProfileModelTypeController>(
177 std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
178 db_thread_,
179 base::BindRepeating(
180 &AutofillProfileDelegateFromDataService,
181 base::RetainedRef(web_data_service_on_disk_))),
182 sync_client_->GetPrefService(), sync_service));
183 }
184
185 // Wallet data sync is enabled by default. Register unless explicitly
186 // disabled.
187 if (!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA)) {
188 controllers.push_back(CreateWalletModelTypeControllerWithInMemorySupport(
189 syncer::AUTOFILL_WALLET_DATA,
190 base::BindRepeating(&AutofillWalletDelegateFromDataService),
191 sync_service));
192 }
193
194 // Wallet metadata sync depends on Wallet data sync. Register if neither
195 // Wallet data nor Wallet metadata sync is explicitly disabled.
196 if (!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA) &&
197 !disabled_types.Has(syncer::AUTOFILL_WALLET_METADATA)) {
198 controllers.push_back(CreateWalletModelTypeController(
199 syncer::AUTOFILL_WALLET_METADATA,
200 base::BindRepeating(&AutofillWalletMetadataDelegateFromDataService),
201 sync_service));
202 }
203 }
204
205 // Bookmark sync is enabled by default. Register unless explicitly
206 // disabled.
207 if (!disabled_types.Has(syncer::BOOKMARKS)) {
208 controllers.push_back(std::make_unique<ModelTypeController>(
209 syncer::BOOKMARKS,
210 std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
211 ui_thread_,
212 base::BindRepeating(&sync_bookmarks::BookmarkSyncService::
213 GetBookmarkSyncControllerDelegate,
214 base::Unretained(bookmark_sync_service_),
215 sync_client_->GetFaviconService()))));
216 }
217
218 // These features are enabled only if history is not disabled.
219 if (!sync_client_->GetPrefService()->GetBoolean(history_disabled_pref_)) {
220 // TypedUrl sync is enabled by default. Register unless explicitly
221 // disabled.
222 if (!disabled_types.Has(syncer::TYPED_URLS)) {
223 // TypedURLModelTypeController uses a proxy delegate internally, as
224 // provided by HistoryService.
225 controllers.push_back(
226 std::make_unique<history::TypedURLModelTypeController>(
227 sync_client_->GetHistoryService(), sync_client_->GetPrefService(),
228 history_disabled_pref_));
229 }
230
231 // Delete directive sync is enabled by default.
232 if (!disabled_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
233 controllers.push_back(
234 std::make_unique<HistoryDeleteDirectivesModelTypeController>(
235 dump_stack, sync_service,
236 sync_client_->GetModelTypeStoreService(), sync_client_));
237 }
238
239 // Session sync is enabled by default. This is disabled if history is
240 // disabled because the tab sync data is added to the web history on the
241 // server.
242 if (!disabled_types.Has(syncer::PROXY_TABS)) {
243 controllers.push_back(
244 std::make_unique<sync_sessions::ProxyTabsDataTypeController>(
245 base::BindRepeating(
246 &sync_sessions::SessionSyncService::ProxyTabsStateChanged,
247 base::Unretained(sync_client_->GetSessionSyncService()))));
248 controllers.push_back(
249 std::make_unique<sync_sessions::SessionModelTypeController>(
250 sync_service, sync_client_->GetPrefService(),
251 std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
252 sync_client_->GetSessionSyncService()
253 ->GetControllerDelegate()
254 .get()),
255 history_disabled_pref_));
256 }
257 }
258
259 // Password sync is enabled by default. Register unless explicitly
260 // disabled.
261 if (!disabled_types.Has(syncer::PASSWORDS)) {
262 if (profile_password_store_) {
263 // |profile_password_store_| can be null in tests.
264 controllers.push_back(
265 std::make_unique<password_manager::PasswordModelTypeController>(
266 profile_password_store_->CreateSyncControllerDelegate(),
267 account_password_store_
268 ? account_password_store_->CreateSyncControllerDelegate()
269 : nullptr,
270 sync_client_->GetPrefService(),
271 sync_client_->GetIdentityManager(), sync_service,
272 sync_client_->GetPasswordStateChangedCallback()));
273 }
274 }
275
276 if (!disabled_types.Has(syncer::PREFERENCES)) {
277 controllers.push_back(
278 std::make_unique<SyncableServiceBasedModelTypeController>(
279 syncer::PREFERENCES,
280 sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
281 sync_client_->GetSyncableServiceForType(syncer::PREFERENCES),
282 dump_stack));
283 }
284
285 if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) {
286 controllers.push_back(
287 std::make_unique<SyncableServiceBasedModelTypeController>(
288 syncer::PRIORITY_PREFERENCES,
289 sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
290 sync_client_->GetSyncableServiceForType(
291 syncer::PRIORITY_PREFERENCES),
292 dump_stack));
293 }
294
295 #if defined(OS_CHROMEOS)
296 // When SplitSettingsSync is enabled the controller is created in
297 // ChromeSyncClient.
298 if (!disabled_types.Has(syncer::PRINTERS) &&
299 !chromeos::features::IsSplitSettingsSyncEnabled()) {
300 controllers.push_back(
301 CreateModelTypeControllerForModelRunningOnUIThread(syncer::PRINTERS));
302 }
303 #endif // defined(OS_CHROMEOS)
304
305 // Reading list sync is enabled by default only on iOS. Register unless
306 // Reading List or Reading List Sync is explicitly disabled.
307 if (!disabled_types.Has(syncer::READING_LIST) &&
308 reading_list::switches::IsReadingListEnabled()) {
309 controllers.push_back(CreateModelTypeControllerForModelRunningOnUIThread(
310 syncer::READING_LIST));
311 }
312
313 if (!disabled_types.Has(syncer::USER_EVENTS)) {
314 controllers.push_back(
315 std::make_unique<syncer::UserEventModelTypeController>(
316 sync_service,
317 CreateForwardingControllerDelegate(syncer::USER_EVENTS)));
318 }
319
320 if (!disabled_types.Has(syncer::SEND_TAB_TO_SELF)) {
321 controllers.push_back(
322 std::make_unique<send_tab_to_self::SendTabToSelfModelTypeController>(
323 sync_service,
324 std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
325 sync_client_->GetSendTabToSelfSyncService()
326 ->GetControllerDelegate()
327 .get())));
328 }
329
330 // Forward both full-sync and transport-only modes to the same delegate,
331 // since behavior for USER_CONSENTS does not differ (they are always
332 // persisted).
333 controllers.push_back(std::make_unique<ModelTypeController>(
334 syncer::USER_CONSENTS,
335 /*delegate_for_full_sync_mode=*/
336 CreateForwardingControllerDelegate(syncer::USER_CONSENTS),
337 /*delegate_for_transport_mode=*/
338 CreateForwardingControllerDelegate(syncer::USER_CONSENTS)));
339
340 return controllers;
341 }
342
343 std::unique_ptr<DataTypeManager>
CreateDataTypeManager(syncer::ModelTypeSet initial_types,const syncer::WeakHandle<syncer::DataTypeDebugInfoListener> & debug_info_listener,const DataTypeController::TypeMap * controllers,const syncer::DataTypeEncryptionHandler * encryption_handler,syncer::ModelTypeConfigurer * configurer,DataTypeManagerObserver * observer)344 ProfileSyncComponentsFactoryImpl::CreateDataTypeManager(
345 syncer::ModelTypeSet initial_types,
346 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
347 debug_info_listener,
348 const DataTypeController::TypeMap* controllers,
349 const syncer::DataTypeEncryptionHandler* encryption_handler,
350 syncer::ModelTypeConfigurer* configurer,
351 DataTypeManagerObserver* observer) {
352 return std::make_unique<DataTypeManagerImpl>(
353 initial_types, debug_info_listener, controllers, encryption_handler,
354 configurer, observer);
355 }
356
357 std::unique_ptr<syncer::SyncEngine>
CreateSyncEngine(const std::string & name,invalidation::InvalidationService * invalidator,const base::WeakPtr<syncer::SyncPrefs> & sync_prefs)358 ProfileSyncComponentsFactoryImpl::CreateSyncEngine(
359 const std::string& name,
360 invalidation::InvalidationService* invalidator,
361 const base::WeakPtr<syncer::SyncPrefs>& sync_prefs) {
362 return std::make_unique<syncer::SyncEngineImpl>(
363 name, invalidator, sync_prefs,
364 sync_client_->GetModelTypeStoreService()->GetSyncDataPath());
365 }
366
367 std::unique_ptr<syncer::ModelTypeControllerDelegate>
CreateForwardingControllerDelegate(syncer::ModelType type)368 ProfileSyncComponentsFactoryImpl::CreateForwardingControllerDelegate(
369 syncer::ModelType type) {
370 return std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
371 sync_client_->GetControllerDelegateForModelType(type).get());
372 }
373
374 std::unique_ptr<ModelTypeController> ProfileSyncComponentsFactoryImpl::
CreateModelTypeControllerForModelRunningOnUIThread(syncer::ModelType type)375 CreateModelTypeControllerForModelRunningOnUIThread(syncer::ModelType type) {
376 return std::make_unique<ModelTypeController>(
377 type, CreateForwardingControllerDelegate(type));
378 }
379
380 std::unique_ptr<ModelTypeController>
CreateWalletModelTypeController(syncer::ModelType type,const base::RepeatingCallback<base::WeakPtr<syncer::ModelTypeControllerDelegate> (autofill::AutofillWebDataService *)> & delegate_from_web_data,syncer::SyncService * sync_service)381 ProfileSyncComponentsFactoryImpl::CreateWalletModelTypeController(
382 syncer::ModelType type,
383 const base::RepeatingCallback<
384 base::WeakPtr<syncer::ModelTypeControllerDelegate>(
385 autofill::AutofillWebDataService*)>& delegate_from_web_data,
386 syncer::SyncService* sync_service) {
387 return std::make_unique<AutofillWalletModelTypeController>(
388 type,
389 std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
390 db_thread_,
391 base::BindRepeating(delegate_from_web_data,
392 base::RetainedRef(web_data_service_on_disk_))),
393 sync_client_->GetPrefService(), sync_service);
394 }
395
396 std::unique_ptr<ModelTypeController> ProfileSyncComponentsFactoryImpl::
CreateWalletModelTypeControllerWithInMemorySupport(syncer::ModelType type,const base::RepeatingCallback<base::WeakPtr<syncer::ModelTypeControllerDelegate> (autofill::AutofillWebDataService *)> & delegate_from_web_data,syncer::SyncService * sync_service)397 CreateWalletModelTypeControllerWithInMemorySupport(
398 syncer::ModelType type,
399 const base::RepeatingCallback<
400 base::WeakPtr<syncer::ModelTypeControllerDelegate>(
401 autofill::AutofillWebDataService*)>& delegate_from_web_data,
402 syncer::SyncService* sync_service) {
403 return std::make_unique<AutofillWalletModelTypeController>(
404 type, /*delegate_for_full_sync_mode=*/
405 std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
406 db_thread_,
407 base::BindRepeating(delegate_from_web_data,
408 base::RetainedRef(web_data_service_on_disk_))),
409 /*delegate_for_transport_mode=*/
410 std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
411 db_thread_,
412 base::BindRepeating(delegate_from_web_data,
413 base::RetainedRef(web_data_service_in_memory_))),
414 sync_client_->GetPrefService(), sync_service);
415 }
416
417 } // namespace browser_sync
418