1 // Copyright 2015 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 "chrome/browser/sync/chrome_sync_client.h"
6 
7 #include <string>
8 #include <utility>
9 
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/feature_list.h"
13 #include "base/path_service.h"
14 #include "base/syslog_logging.h"
15 #include "build/build_config.h"
16 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
17 #include "chrome/browser/consent_auditor/consent_auditor_factory.h"
18 #include "chrome/browser/dom_distiller/dom_distiller_service_factory.h"
19 #include "chrome/browser/favicon/favicon_service_factory.h"
20 #include "chrome/browser/history/history_service_factory.h"
21 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
22 #include "chrome/browser/password_manager/account_password_store_factory.h"
23 #include "chrome/browser/password_manager/password_store_factory.h"
24 #include "chrome/browser/prefs/pref_service_syncable_util.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/search_engines/template_url_service_factory.h"
27 #include "chrome/browser/security_events/security_event_recorder.h"
28 #include "chrome/browser/security_events/security_event_recorder_factory.h"
29 #include "chrome/browser/sharing/sharing_message_bridge.h"
30 #include "chrome/browser/sharing/sharing_message_bridge_factory.h"
31 #include "chrome/browser/sharing/sharing_message_model_type_controller.h"
32 #include "chrome/browser/signin/identity_manager_factory.h"
33 #include "chrome/browser/sync/bookmark_sync_service_factory.h"
34 #include "chrome/browser/sync/device_info_sync_service_factory.h"
35 #include "chrome/browser/sync/model_type_store_service_factory.h"
36 #include "chrome/browser/sync/profile_sync_service_factory.h"
37 #include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h"
38 #include "chrome/browser/sync/session_sync_service_factory.h"
39 #include "chrome/browser/sync/sync_invalidations_service_factory.h"
40 #include "chrome/browser/sync/user_event_service_factory.h"
41 #include "chrome/browser/themes/theme_service.h"
42 #include "chrome/browser/themes/theme_service_factory.h"
43 #include "chrome/browser/themes/theme_syncable_service.h"
44 #include "chrome/browser/ui/read_later/reading_list_model_factory.h"
45 #include "chrome/browser/undo/bookmark_undo_service_factory.h"
46 #include "chrome/browser/web_applications/web_app_provider.h"
47 #include "chrome/browser/web_applications/web_app_sync_bridge.h"
48 #include "chrome/browser/web_data_service_factory.h"
49 #include "chrome/common/buildflags.h"
50 #include "chrome/common/channel_info.h"
51 #include "chrome/common/chrome_features.h"
52 #include "chrome/common/chrome_paths.h"
53 #include "chrome/common/pref_names.h"
54 #include "components/autofill/core/browser/webdata/autocomplete_sync_bridge.h"
55 #include "components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h"
56 #include "components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h"
57 #include "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h"
58 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
59 #include "components/autofill/core/common/autofill_features.h"
60 #include "components/browser_sync/browser_sync_switches.h"
61 #include "components/browser_sync/profile_sync_components_factory_impl.h"
62 #include "components/consent_auditor/consent_auditor.h"
63 #include "components/dom_distiller/core/dom_distiller_service.h"
64 #include "components/history/core/browser/history_service.h"
65 #include "components/history/core/common/pref_names.h"
66 #include "components/invalidation/impl/invalidation_switches.h"
67 #include "components/invalidation/impl/profile_invalidation_provider.h"
68 #include "components/metrics/demographics/user_demographics.h"
69 #include "components/password_manager/core/browser/password_store.h"
70 #include "components/prefs/pref_service.h"
71 #include "components/reading_list/core/reading_list_model.h"
72 #include "components/reading_list/features/reading_list_switches.h"
73 #include "components/search_engines/template_url_service.h"
74 #include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
75 #include "components/spellcheck/spellcheck_buildflags.h"
76 #include "components/sync/base/pref_names.h"
77 #include "components/sync/base/report_unrecoverable_error.h"
78 #include "components/sync/base/sync_base_switches.h"
79 #include "components/sync/base/sync_util.h"
80 #include "components/sync/driver/model_type_controller.h"
81 #include "components/sync/driver/sync_api_component_factory.h"
82 #include "components/sync/driver/sync_driver_switches.h"
83 #include "components/sync/driver/syncable_service_based_model_type_controller.h"
84 #include "components/sync/model/model_type_store.h"
85 #include "components/sync/model/model_type_store_service.h"
86 #include "components/sync/model_impl/forwarding_model_type_controller_delegate.h"
87 #include "components/sync/trusted_vault/standalone_trusted_vault_client.h"
88 #include "components/sync_bookmarks/bookmark_sync_service.h"
89 #include "components/sync_preferences/pref_service_syncable.h"
90 #include "components/sync_sessions/session_sync_service.h"
91 #include "components/sync_user_events/user_event_service.h"
92 #include "content/public/browser/browser_task_traits.h"
93 #include "content/public/browser/browser_thread.h"
94 #include "content/public/browser/storage_partition.h"
95 #include "extensions/browser/api/storage/backend_task_runner.h"
96 #include "extensions/buildflags/buildflags.h"
97 
98 #if BUILDFLAG(ENABLE_EXTENSIONS)
99 #include "chrome/browser/extensions/api/storage/settings_sync_util.h"
100 #include "chrome/browser/extensions/extension_sync_service.h"
101 #include "chrome/browser/sync/glue/extension_model_type_controller.h"
102 #include "chrome/browser/sync/glue/extension_setting_model_type_controller.h"
103 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
104 
105 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
106 #include "chrome/browser/profiles/profile_key.h"
107 #include "chrome/browser/supervised_user/supervised_user_allowlist_service.h"
108 #include "chrome/browser/supervised_user/supervised_user_service.h"
109 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
110 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
111 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
112 #include "chrome/browser/supervised_user/supervised_user_sync_model_type_controller.h"
113 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
114 
115 #if BUILDFLAG(ENABLE_SPELLCHECK)
116 #include "chrome/browser/spellchecker/spellcheck_factory.h"
117 #include "chrome/browser/spellchecker/spellcheck_service.h"
118 #include "components/spellcheck/browser/pref_names.h"
119 #endif  // BUILDFLAG(ENABLE_SPELLCHECK)
120 
121 #if defined(OS_ANDROID)
122 #include "chrome/browser/sync/trusted_vault_client_android.h"
123 #endif  // defined(OS_ANDROID)
124 
125 #if defined(OS_CHROMEOS)
126 #include "ash/public/cpp/app_list/app_list_switches.h"
127 #include "chrome/browser/chromeos/arc/arc_util.h"
128 #include "chrome/browser/chromeos/printing/printers_sync_bridge.h"
129 #include "chrome/browser/chromeos/printing/synced_printers_manager.h"
130 #include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h"
131 #include "chrome/browser/chromeos/sync/app_settings_model_type_controller.h"
132 #include "chrome/browser/chromeos/sync/apps_model_type_controller.h"
133 #include "chrome/browser/chromeos/sync/os_sync_model_type_controller.h"
134 #include "chrome/browser/chromeos/sync/os_syncable_service_model_type_controller.h"
135 #include "chrome/browser/sync/wifi_configuration_sync_service_factory.h"
136 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
137 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
138 #include "chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h"
139 #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service.h"
140 #include "chromeos/components/sync_wifi/wifi_configuration_sync_service.h"
141 #include "chromeos/constants/chromeos_features.h"
142 #include "chromeos/constants/chromeos_switches.h"
143 #include "components/arc/arc_util.h"
144 #endif  // defined(OS_CHROMEOS)
145 
146 using content::BrowserThread;
147 using syncer::ForwardingModelTypeControllerDelegate;
148 
149 #if BUILDFLAG(ENABLE_EXTENSIONS)
150 using browser_sync::ExtensionModelTypeController;
151 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
152 
153 namespace browser_sync {
154 
155 namespace {
156 
157 #if !defined(OS_ANDROID)
158 const base::FilePath::CharType kTrustedVaultFilename[] =
159     FILE_PATH_LITERAL("Trusted Vault");
160 #endif  // !defined(OS_ANDROID)
161 
162 #if defined(OS_WIN)
163 const base::FilePath::CharType kLoopbackServerBackendFilename[] =
164     FILE_PATH_LITERAL("profile.pb");
165 #endif  // defined(OS_WIN)
166 
GetDisabledTypesFromCommandLine()167 syncer::ModelTypeSet GetDisabledTypesFromCommandLine() {
168   std::string disabled_types_str =
169       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
170           switches::kDisableSyncTypes);
171 
172   syncer::ModelTypeSet disabled_types =
173       syncer::ModelTypeSetFromString(disabled_types_str);
174   if (disabled_types.Has(syncer::DEVICE_INFO)) {
175     DLOG(WARNING) << "DEVICE_INFO cannot be disabled via a command-line switch";
176     disabled_types.Remove(syncer::DEVICE_INFO);
177   }
178   return disabled_types;
179 }
180 
GetWeakPtrOrNull(syncer::SyncableService * service)181 base::WeakPtr<syncer::SyncableService> GetWeakPtrOrNull(
182     syncer::SyncableService* service) {
183   return service ? service->AsWeakPtr() : nullptr;
184 }
185 
GetDumpStackClosure()186 base::RepeatingClosure GetDumpStackClosure() {
187   return base::BindRepeating(&syncer::ReportUnrecoverableError,
188                              chrome::GetChannel());
189 }
190 
191 }  // namespace
192 
ChromeSyncClient(Profile * profile)193 ChromeSyncClient::ChromeSyncClient(Profile* profile) : profile_(profile) {
194   DCHECK_CURRENTLY_ON(BrowserThread::UI);
195 
196   profile_web_data_service_ =
197       WebDataServiceFactory::GetAutofillWebDataForProfile(
198           profile_, ServiceAccessType::IMPLICIT_ACCESS);
199   account_web_data_service_ =
200       base::FeatureList::IsEnabled(
201           autofill::features::kAutofillEnableAccountWalletStorage)
202           ? WebDataServiceFactory::GetAutofillWebDataForAccount(
203                 profile_, ServiceAccessType::IMPLICIT_ACCESS)
204           : nullptr;
205   web_data_service_thread_ = profile_web_data_service_
206                                  ? profile_web_data_service_->GetDBTaskRunner()
207                                  : nullptr;
208 
209   // This class assumes that the database thread is the same across the profile
210   // and account storage. This DCHECK makes that assumption explicit.
211   DCHECK(!account_web_data_service_ ||
212          web_data_service_thread_ ==
213              account_web_data_service_->GetDBTaskRunner());
214   profile_password_store_ = PasswordStoreFactory::GetForProfile(
215       profile_, ServiceAccessType::IMPLICIT_ACCESS);
216   account_password_store_ = AccountPasswordStoreFactory::GetForProfile(
217       profile_, ServiceAccessType::IMPLICIT_ACCESS);
218 
219   component_factory_ = std::make_unique<ProfileSyncComponentsFactoryImpl>(
220       this, chrome::GetChannel(), prefs::kSavingBrowserHistoryDisabled,
221       content::GetUIThreadTaskRunner({}), web_data_service_thread_,
222       profile_web_data_service_, account_web_data_service_,
223       profile_password_store_, account_password_store_,
224       BookmarkSyncServiceFactory::GetForProfile(profile_));
225 
226 #if defined(OS_ANDROID)
227   trusted_vault_client_ = std::make_unique<TrustedVaultClientAndroid>();
228 #else
229   // TODO(crbug.com/1113597): consider destroying/notifying
230   // |trusted_vault_client_| upon IdentityManager shutdown, to avoid its usages
231   // afterwards. This can be done by tranferring |trusted_vault_client_|
232   // ownership to ProfileSyncService and acting on
233   // ProfileSyncService::Shutdown() or by handling
234   // IdentityManagerFactory::Observer::IdentityManagerShutdown().
235   trusted_vault_client_ =
236       std::make_unique<syncer::StandaloneTrustedVaultClient>(
237           profile_->GetPath().Append(kTrustedVaultFilename),
238           IdentityManagerFactory::GetForProfile(profile_),
239           content::BrowserContext::GetDefaultStoragePartition(profile_)
240               ->GetURLLoaderFactoryForBrowserProcess());
241 #endif  // defined(OS_ANDROID)
242 }
243 
244 ChromeSyncClient::~ChromeSyncClient() = default;
245 
GetPrefService()246 PrefService* ChromeSyncClient::GetPrefService() {
247   DCHECK_CURRENTLY_ON(BrowserThread::UI);
248   return profile_->GetPrefs();
249 }
250 
GetIdentityManager()251 signin::IdentityManager* ChromeSyncClient::GetIdentityManager() {
252   DCHECK_CURRENTLY_ON(BrowserThread::UI);
253   return IdentityManagerFactory::GetForProfile(profile_);
254 }
255 
GetLocalSyncBackendFolder()256 base::FilePath ChromeSyncClient::GetLocalSyncBackendFolder() {
257   base::FilePath local_sync_backend_folder =
258       GetPrefService()->GetFilePath(syncer::prefs::kLocalSyncBackendDir);
259 
260 #if defined(OS_WIN)
261   if (local_sync_backend_folder.empty()) {
262     if (!base::PathService::Get(chrome::DIR_ROAMING_USER_DATA,
263                                 &local_sync_backend_folder)) {
264       SYSLOG(WARNING) << "Local sync can not get the roaming profile folder.";
265       return base::FilePath();
266     }
267   }
268 
269   // This code as it is now will assume the same profile order is present on
270   // all machines, which is not a given. It is to be defined if only the
271   // Default profile should get this treatment or all profile as is the case
272   // now.
273   // TODO(pastarmovj): http://crbug.com/674928 Decide if only the Default one
274   // should be considered roamed. For now the code assumes all profiles are
275   // created in the same order on all machines.
276   local_sync_backend_folder =
277       local_sync_backend_folder.Append(profile_->GetPath().BaseName());
278   local_sync_backend_folder =
279       local_sync_backend_folder.Append(kLoopbackServerBackendFilename);
280 #endif  // defined(OS_WIN)
281 
282   return local_sync_backend_folder;
283 }
284 
GetModelTypeStoreService()285 syncer::ModelTypeStoreService* ChromeSyncClient::GetModelTypeStoreService() {
286   DCHECK_CURRENTLY_ON(BrowserThread::UI);
287   return ModelTypeStoreServiceFactory::GetForProfile(profile_);
288 }
289 
GetDeviceInfoSyncService()290 syncer::DeviceInfoSyncService* ChromeSyncClient::GetDeviceInfoSyncService() {
291   return DeviceInfoSyncServiceFactory::GetForProfile(profile_);
292 }
293 
GetBookmarkModel()294 bookmarks::BookmarkModel* ChromeSyncClient::GetBookmarkModel() {
295   DCHECK_CURRENTLY_ON(BrowserThread::UI);
296   return BookmarkModelFactory::GetForBrowserContext(profile_);
297 }
298 
GetFaviconService()299 favicon::FaviconService* ChromeSyncClient::GetFaviconService() {
300   DCHECK_CURRENTLY_ON(BrowserThread::UI);
301   return FaviconServiceFactory::GetForProfile(
302       profile_, ServiceAccessType::IMPLICIT_ACCESS);
303 }
304 
GetHistoryService()305 history::HistoryService* ChromeSyncClient::GetHistoryService() {
306   DCHECK_CURRENTLY_ON(BrowserThread::UI);
307   return HistoryServiceFactory::GetForProfile(
308       profile_, ServiceAccessType::EXPLICIT_ACCESS);
309 }
310 
311 send_tab_to_self::SendTabToSelfSyncService*
GetSendTabToSelfSyncService()312 ChromeSyncClient::GetSendTabToSelfSyncService() {
313   DCHECK_CURRENTLY_ON(BrowserThread::UI);
314   return SendTabToSelfSyncServiceFactory::GetForProfile(profile_);
315 }
316 
317 sync_preferences::PrefServiceSyncable*
GetPrefServiceSyncable()318 ChromeSyncClient::GetPrefServiceSyncable() {
319   return PrefServiceSyncableFromProfile(profile_);
320 }
321 
GetSessionSyncService()322 sync_sessions::SessionSyncService* ChromeSyncClient::GetSessionSyncService() {
323   DCHECK_CURRENTLY_ON(BrowserThread::UI);
324   return SessionSyncServiceFactory::GetForProfile(profile_);
325 }
326 
GetPasswordStateChangedCallback()327 base::RepeatingClosure ChromeSyncClient::GetPasswordStateChangedCallback() {
328   return base::BindRepeating(
329       &PasswordStoreFactory::OnPasswordsSyncedStatePotentiallyChanged,
330       base::Unretained(profile_));
331 }
332 
333 syncer::DataTypeController::TypeVector
CreateDataTypeControllers(syncer::SyncService * sync_service)334 ChromeSyncClient::CreateDataTypeControllers(syncer::SyncService* sync_service) {
335   syncer::ModelTypeSet disabled_types = GetDisabledTypesFromCommandLine();
336 
337   syncer::DataTypeController::TypeVector controllers =
338       component_factory_->CreateCommonDataTypeControllers(disabled_types,
339                                                           sync_service);
340 
341   const base::RepeatingClosure dump_stack = GetDumpStackClosure();
342 
343   syncer::RepeatingModelTypeStoreFactory model_type_store_factory =
344       GetModelTypeStoreService()->GetStoreFactory();
345 
346   if (!disabled_types.Has(syncer::SECURITY_EVENTS)) {
347     syncer::ModelTypeControllerDelegate* delegate =
348         SecurityEventRecorderFactory::GetForProfile(profile_)
349             ->GetControllerDelegate()
350             .get();
351     // Forward both full-sync and transport-only modes to the same delegate,
352     // since behavior for SECURITY_EVENTS does not differ.
353     controllers.push_back(std::make_unique<syncer::ModelTypeController>(
354         syncer::SECURITY_EVENTS,
355         /*delegate_for_full_sync_mode=*/
356         std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
357             delegate),
358         /*delegate_for_transport_mode=*/
359         std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
360             delegate)));
361   }
362 
363   if (!disabled_types.Has(syncer::SHARING_MESSAGE)) {
364     // Forward both full-sync and transport-only modes to the same delegate,
365     // since behavior for SHARING_MESSAGE does not differ. They both do not
366     // store data on persistent storage.
367     syncer::ModelTypeControllerDelegate* delegate =
368         GetControllerDelegateForModelType(syncer::SHARING_MESSAGE).get();
369     controllers.push_back(std::make_unique<SharingMessageModelTypeController>(
370         sync_service,
371         /*delegate_for_full_sync_mode=*/
372         std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
373             delegate),
374         /*delegate_for_transport_mode=*/
375         std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
376             delegate)));
377   }
378 
379 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
380   controllers.push_back(std::make_unique<SupervisedUserSyncModelTypeController>(
381       syncer::SUPERVISED_USER_SETTINGS, profile_, dump_stack,
382       model_type_store_factory,
383       GetSyncableServiceForType(syncer::SUPERVISED_USER_SETTINGS)));
384   controllers.push_back(std::make_unique<SupervisedUserSyncModelTypeController>(
385       syncer::SUPERVISED_USER_ALLOWLISTS, profile_, dump_stack,
386       model_type_store_factory,
387       GetSyncableServiceForType(syncer::SUPERVISED_USER_ALLOWLISTS)));
388 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
389 
390 #if BUILDFLAG(ENABLE_EXTENSIONS)
391   // App sync is enabled by default.  Register unless explicitly
392   // disabled.
393   if (!disabled_types.Has(syncer::APPS)) {
394     controllers.push_back(CreateAppsModelTypeController(sync_service));
395   }
396 
397   // Extension sync is enabled by default.  Register unless explicitly
398   // disabled.
399   if (!disabled_types.Has(syncer::EXTENSIONS)) {
400     controllers.push_back(std::make_unique<ExtensionModelTypeController>(
401         syncer::EXTENSIONS, model_type_store_factory,
402         GetSyncableServiceForType(syncer::EXTENSIONS), dump_stack, profile_));
403   }
404 
405   // Extension setting sync is enabled by default.  Register unless explicitly
406   // disabled.
407   if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) {
408     controllers.push_back(std::make_unique<ExtensionSettingModelTypeController>(
409         syncer::EXTENSION_SETTINGS, model_type_store_factory,
410         extensions::settings_sync_util::GetSyncableServiceProvider(
411             profile_, syncer::EXTENSION_SETTINGS),
412         dump_stack, profile_));
413   }
414 
415   // App setting sync is enabled by default.  Register unless explicitly
416   // disabled.
417   if (!disabled_types.Has(syncer::APP_SETTINGS)) {
418     controllers.push_back(CreateAppSettingsModelTypeController(sync_service));
419   }
420 
421   // Web Apps sync is disabled by default.
422   if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions) &&
423       web_app::WebAppProvider::Get(profile_)) {
424     if (!disabled_types.Has(syncer::WEB_APPS)) {
425       controllers.push_back(CreateWebAppsModelTypeController(sync_service));
426     }
427   }
428 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
429 
430 #if !defined(OS_ANDROID)
431   // Theme sync is enabled by default.  Register unless explicitly disabled.
432   if (!disabled_types.Has(syncer::THEMES)) {
433     controllers.push_back(std::make_unique<ExtensionModelTypeController>(
434         syncer::THEMES, model_type_store_factory,
435         GetSyncableServiceForType(syncer::THEMES), dump_stack, profile_));
436   }
437 
438   // Search Engine sync is enabled by default.  Register unless explicitly
439   // disabled. The service can be null in tests.
440   if (!disabled_types.Has(syncer::SEARCH_ENGINES)) {
441     controllers.push_back(
442         std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
443             syncer::SEARCH_ENGINES, model_type_store_factory,
444             GetSyncableServiceForType(syncer::SEARCH_ENGINES), dump_stack));
445   }
446 #endif  // !defined(OS_ANDROID)
447 
448 #if defined(OS_CHROMEOS)
449   // Some profile types (e.g. sign-in screen) don't support app list.
450   // Temporarily Disable AppListSyncableService for tablet form factor devices.
451   // See crbug/1013732 for details.
452   if (app_list::AppListSyncableServiceFactory::GetForProfile(profile_) &&
453       !chromeos::switches::IsTabletFormFactor()) {
454     if (chromeos::features::IsSplitSettingsSyncEnabled()) {
455       // Runs in sync transport-mode and full-sync mode.
456       controllers.push_back(
457           std::make_unique<OsSyncableServiceModelTypeController>(
458               syncer::APP_LIST, model_type_store_factory,
459               GetSyncableServiceForType(syncer::APP_LIST), dump_stack,
460               profile_->GetPrefs(), sync_service));
461     } else {
462       // Only runs in full-sync mode.
463       controllers.push_back(
464           std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
465               syncer::APP_LIST, model_type_store_factory,
466               GetSyncableServiceForType(syncer::APP_LIST), dump_stack));
467     }
468   }
469 #endif  // defined(OS_CHROMEOS)
470 
471 // Chrome prefers OS provided spell checkers where they exist. So only sync the
472 // custom dictionary on platforms that typically don't provide one.
473 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_BSD)
474   // Dictionary sync is enabled by default.
475   if (!disabled_types.Has(syncer::DICTIONARY) &&
476       GetPrefService()->GetBoolean(spellcheck::prefs::kSpellCheckEnable)) {
477     controllers.push_back(
478         std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
479             syncer::DICTIONARY, model_type_store_factory,
480             GetSyncableServiceForType(syncer::DICTIONARY), dump_stack));
481   }
482 #endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_BSD)
483 
484 #if defined(OS_CHROMEOS)
485   if (arc::IsArcAllowedForProfile(profile_) &&
486       !arc::IsArcAppSyncFlowDisabled()) {
487     controllers.push_back(std::make_unique<ArcPackageSyncModelTypeController>(
488         model_type_store_factory,
489         GetSyncableServiceForType(syncer::ARC_PACKAGE), dump_stack,
490         sync_service, profile_));
491   }
492   if (chromeos::features::IsSplitSettingsSyncEnabled()) {
493     if (!disabled_types.Has(syncer::OS_PREFERENCES)) {
494       controllers.push_back(
495           std::make_unique<OsSyncableServiceModelTypeController>(
496               syncer::OS_PREFERENCES, model_type_store_factory,
497               GetSyncableServiceForType(syncer::OS_PREFERENCES), dump_stack,
498               profile_->GetPrefs(), sync_service));
499     }
500     if (!disabled_types.Has(syncer::OS_PRIORITY_PREFERENCES)) {
501       controllers.push_back(
502           std::make_unique<OsSyncableServiceModelTypeController>(
503               syncer::OS_PRIORITY_PREFERENCES, model_type_store_factory,
504               GetSyncableServiceForType(syncer::OS_PRIORITY_PREFERENCES),
505               dump_stack, profile_->GetPrefs(), sync_service));
506     }
507     if (!disabled_types.Has(syncer::PRINTERS)) {
508       // Use the same delegate in full-sync and transport-only modes.
509       syncer::ModelTypeControllerDelegate* delegate =
510           GetControllerDelegateForModelType(syncer::PRINTERS).get();
511       controllers.push_back(std::make_unique<OsSyncModelTypeController>(
512           syncer::PRINTERS,
513           /*delegate_for_full_sync_mode=*/
514           std::make_unique<ForwardingModelTypeControllerDelegate>(delegate),
515           /*delegate_for_transport_mode=*/
516           std::make_unique<ForwardingModelTypeControllerDelegate>(delegate),
517           profile_->GetPrefs(), sync_service));
518     }
519     if (!disabled_types.Has(syncer::WIFI_CONFIGURATIONS) &&
520         base::FeatureList::IsEnabled(switches::kSyncWifiConfigurations) &&
521         WifiConfigurationSyncServiceFactory::ShouldRunInProfile(profile_)) {
522       // Use the same delegate in full-sync and transport-only modes.
523       syncer::ModelTypeControllerDelegate* delegate =
524           GetControllerDelegateForModelType(syncer::WIFI_CONFIGURATIONS).get();
525       controllers.push_back(std::make_unique<OsSyncModelTypeController>(
526           syncer::WIFI_CONFIGURATIONS,
527           /*delegate_for_full_sync_mode=*/
528           std::make_unique<ForwardingModelTypeControllerDelegate>(delegate),
529           /*delegate_for_transport_mode=*/
530           std::make_unique<ForwardingModelTypeControllerDelegate>(delegate),
531           profile_->GetPrefs(), sync_service));
532     }
533   } else {
534     // SplitSettingsSync is disabled.
535     if (!disabled_types.Has(syncer::WIFI_CONFIGURATIONS) &&
536         base::FeatureList::IsEnabled(switches::kSyncWifiConfigurations) &&
537         WifiConfigurationSyncServiceFactory::ShouldRunInProfile(profile_)) {
538       syncer::ModelTypeControllerDelegate* delegate =
539           GetControllerDelegateForModelType(syncer::WIFI_CONFIGURATIONS).get();
540       controllers.push_back(std::make_unique<syncer::ModelTypeController>(
541           syncer::WIFI_CONFIGURATIONS,
542           std::make_unique<ForwardingModelTypeControllerDelegate>(delegate)));
543     }
544   }
545 #endif  // defined(OS_CHROMEOS)
546 
547   return controllers;
548 }
549 
GetBookmarkUndoService()550 BookmarkUndoService* ChromeSyncClient::GetBookmarkUndoService() {
551   return BookmarkUndoServiceFactory::GetForProfile(profile_);
552 }
553 
GetTrustedVaultClient()554 syncer::TrustedVaultClient* ChromeSyncClient::GetTrustedVaultClient() {
555   return trusted_vault_client_.get();
556 }
557 
GetInvalidationService()558 invalidation::InvalidationService* ChromeSyncClient::GetInvalidationService() {
559   invalidation::ProfileInvalidationProvider* provider =
560       invalidation::ProfileInvalidationProviderFactory::GetForProfile(profile_);
561 
562   if (provider)
563     return provider->GetInvalidationService();
564   return nullptr;
565 }
566 
567 syncer::SyncInvalidationsService*
GetSyncInvalidationsService()568 ChromeSyncClient::GetSyncInvalidationsService() {
569   return SyncInvalidationsServiceFactory::GetForProfile(profile_);
570 }
571 
572 scoped_refptr<syncer::ExtensionsActivity>
GetExtensionsActivity()573 ChromeSyncClient::GetExtensionsActivity() {
574   return extensions_activity_monitor_.GetExtensionsActivity();
575 }
576 
577 base::WeakPtr<syncer::SyncableService>
GetSyncableServiceForType(syncer::ModelType type)578 ChromeSyncClient::GetSyncableServiceForType(syncer::ModelType type) {
579   switch (type) {
580     case syncer::SEARCH_ENGINES:
581       return GetWeakPtrOrNull(
582           TemplateURLServiceFactory::GetForProfile(profile_));
583 #if BUILDFLAG(ENABLE_EXTENSIONS)
584     case syncer::APPS:
585     case syncer::EXTENSIONS:
586       return GetWeakPtrOrNull(ExtensionSyncService::Get(profile_));
587 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
588 #if defined(OS_CHROMEOS)
589     case syncer::APP_LIST:
590       return GetWeakPtrOrNull(
591           app_list::AppListSyncableServiceFactory::GetForProfile(profile_));
592 #endif  // defined(OS_CHROMEOS)
593 #if !defined(OS_ANDROID)
594     case syncer::THEMES:
595       return ThemeServiceFactory::GetForProfile(profile_)->
596           GetThemeSyncableService()->AsWeakPtr();
597 #endif  // !defined(OS_ANDROID)
598 #if BUILDFLAG(ENABLE_SPELLCHECK)
599     case syncer::DICTIONARY: {
600       SpellcheckService* spellcheck_service =
601           SpellcheckServiceFactory::GetForContext(profile_);
602       return spellcheck_service
603                  ? spellcheck_service->GetCustomDictionary()->AsWeakPtr()
604                  : nullptr;
605     }
606 #endif  // BUILDFLAG(ENABLE_SPELLCHECK)
607 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
608     case syncer::SUPERVISED_USER_SETTINGS:
609       return SupervisedUserSettingsServiceFactory::GetForKey(
610                  profile_->GetProfileKey())
611           ->AsWeakPtr();
612     case syncer::SUPERVISED_USER_ALLOWLISTS:
613       return SupervisedUserServiceFactory::GetForProfile(profile_)
614           ->GetAllowlistService()
615           ->AsWeakPtr();
616 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
617 #if defined(OS_CHROMEOS)
618     case syncer::ARC_PACKAGE:
619       return arc::ArcPackageSyncableService::Get(profile_)->AsWeakPtr();
620     case syncer::OS_PREFERENCES:
621     case syncer::OS_PRIORITY_PREFERENCES:
622       return PrefServiceSyncableFromProfile(profile_)
623           ->GetSyncableService(type)
624           ->AsWeakPtr();
625 #endif  // defined(OS_CHROMEOS)
626     default:
627       NOTREACHED();
628       return nullptr;
629   }
630 }
631 
632 base::WeakPtr<syncer::ModelTypeControllerDelegate>
GetControllerDelegateForModelType(syncer::ModelType type)633 ChromeSyncClient::GetControllerDelegateForModelType(syncer::ModelType type) {
634   switch (type) {
635     case syncer::READING_LIST: {
636       DCHECK(reading_list::switches::IsReadingListEnabled());
637       return ReadingListModelFactory::GetForBrowserContext(profile_)
638           ->GetModelTypeSyncBridge()
639           ->change_processor()
640           ->GetControllerDelegate();
641     }
642 #if defined(OS_CHROMEOS)
643     case syncer::PRINTERS:
644       return chromeos::SyncedPrintersManagerFactory::GetForBrowserContext(
645                  profile_)
646           ->GetSyncBridge()
647           ->change_processor()
648           ->GetControllerDelegate();
649     case syncer::WIFI_CONFIGURATIONS:
650       return WifiConfigurationSyncServiceFactory::GetForProfile(profile_,
651                                                                 /*create=*/true)
652           ->GetControllerDelegate();
653 #endif  // defined(OS_CHROMEOS)
654     case syncer::SHARING_MESSAGE:
655       return SharingMessageBridgeFactory::GetForBrowserContext(profile_)
656           ->GetControllerDelegate();
657     case syncer::USER_CONSENTS:
658       return ConsentAuditorFactory::GetForProfile(profile_)
659           ->GetControllerDelegate();
660     case syncer::USER_EVENTS:
661       return browser_sync::UserEventServiceFactory::GetForProfile(profile_)
662           ->GetControllerDelegate();
663 #if BUILDFLAG(ENABLE_EXTENSIONS)
664     case syncer::WEB_APPS: {
665       DCHECK(base::FeatureList::IsEnabled(
666           features::kDesktopPWAsWithoutExtensions));
667       auto* provider = web_app::WebAppProvider::Get(profile_);
668       DCHECK(provider);
669 
670       web_app::WebAppSyncBridge* sync_bridge =
671           provider->registry_controller().AsWebAppSyncBridge();
672       DCHECK(sync_bridge);
673 
674       return sync_bridge->change_processor()->GetControllerDelegate();
675     }
676 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
677     // We don't exercise this function for certain datatypes, because their
678     // controllers get the delegate elsewhere.
679     case syncer::AUTOFILL:
680     case syncer::AUTOFILL_PROFILE:
681     case syncer::AUTOFILL_WALLET_DATA:
682     case syncer::AUTOFILL_WALLET_METADATA:
683     case syncer::BOOKMARKS:
684     case syncer::DEVICE_INFO:
685     case syncer::SECURITY_EVENTS:
686     case syncer::SEND_TAB_TO_SELF:
687     case syncer::SESSIONS:
688     case syncer::TYPED_URLS:
689       NOTREACHED();
690       return base::WeakPtr<syncer::ModelTypeControllerDelegate>();
691 
692     default:
693       NOTREACHED();
694       return base::WeakPtr<syncer::ModelTypeControllerDelegate>();
695   }
696 }
697 
698 syncer::SyncApiComponentFactory*
GetSyncApiComponentFactory()699 ChromeSyncClient::GetSyncApiComponentFactory() {
700   return component_factory_.get();
701 }
702 
GetPreferenceProvider()703 syncer::SyncTypePreferenceProvider* ChromeSyncClient::GetPreferenceProvider() {
704 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
705   return SupervisedUserServiceFactory::GetForProfile(profile_);
706 #else
707   return nullptr;
708 #endif
709 }
710 
OnLocalSyncTransportDataCleared()711 void ChromeSyncClient::OnLocalSyncTransportDataCleared() {
712   metrics::ClearDemographicsPrefs(profile_->GetPrefs());
713 }
714 
715 #if BUILDFLAG(ENABLE_EXTENSIONS)
716 std::unique_ptr<syncer::ModelTypeController>
CreateAppsModelTypeController(syncer::SyncService * sync_service)717 ChromeSyncClient::CreateAppsModelTypeController(
718     syncer::SyncService* sync_service) {
719 #if defined(OS_CHROMEOS)
720   if (chromeos::features::IsSplitSettingsSyncEnabled()) {
721     return AppsModelTypeController::Create(
722         GetModelTypeStoreService()->GetStoreFactory(),
723         GetSyncableServiceForType(syncer::APPS), GetDumpStackClosure(),
724         sync_service, profile_);
725   }
726   // Fall through.
727 #endif
728   return std::make_unique<ExtensionModelTypeController>(
729       syncer::APPS, GetModelTypeStoreService()->GetStoreFactory(),
730       GetSyncableServiceForType(syncer::APPS), GetDumpStackClosure(), profile_);
731 }
732 
733 std::unique_ptr<syncer::ModelTypeController>
CreateAppSettingsModelTypeController(syncer::SyncService * sync_service)734 ChromeSyncClient::CreateAppSettingsModelTypeController(
735     syncer::SyncService* sync_service) {
736 #if defined(OS_CHROMEOS)
737   if (chromeos::features::IsSplitSettingsSyncEnabled()) {
738     return std::make_unique<AppSettingsModelTypeController>(
739         GetModelTypeStoreService()->GetStoreFactory(),
740         extensions::settings_sync_util::GetSyncableServiceProvider(
741             profile_, syncer::APP_SETTINGS),
742         GetDumpStackClosure(), profile_, sync_service);
743   }
744   // Fall through.
745 #endif
746   return std::make_unique<ExtensionSettingModelTypeController>(
747       syncer::APP_SETTINGS, GetModelTypeStoreService()->GetStoreFactory(),
748       extensions::settings_sync_util::GetSyncableServiceProvider(
749           profile_, syncer::APP_SETTINGS),
750       GetDumpStackClosure(), profile_);
751 }
752 
753 std::unique_ptr<syncer::ModelTypeController>
CreateWebAppsModelTypeController(syncer::SyncService * sync_service)754 ChromeSyncClient::CreateWebAppsModelTypeController(
755     syncer::SyncService* sync_service) {
756   syncer::ModelTypeControllerDelegate* delegate =
757       GetControllerDelegateForModelType(syncer::WEB_APPS).get();
758 #if defined(OS_CHROMEOS)
759   if (chromeos::features::IsSplitSettingsSyncEnabled()) {
760     // Use the same delegate in full-sync and transport-only modes.
761     return std::make_unique<OsSyncModelTypeController>(
762         syncer::WEB_APPS,
763         /*delegate_for_full_sync_mode=*/
764         std::make_unique<ForwardingModelTypeControllerDelegate>(delegate),
765         /*delegate_for_transport_mode=*/
766         std::make_unique<ForwardingModelTypeControllerDelegate>(delegate),
767         profile_->GetPrefs(), sync_service);
768   }
769   // Fall through.
770 #endif
771   return std::make_unique<syncer::ModelTypeController>(
772       syncer::WEB_APPS,
773       std::make_unique<ForwardingModelTypeControllerDelegate>(delegate));
774 }
775 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
776 
777 }  // namespace browser_sync
778