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