blob: 3f8aed9ac932a75b29bbb92d4745b011f9350de5 [file] [log] [blame]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/sync/chrome_sync_client.h"
#include <memory>
#include <utility>
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/path_service.h"
#include "base/syslog_logging.h"
#include "base/task/sequenced_task_runner.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/commerce/product_specifications/product_specifications_service_factory.h"
#include "chrome/browser/consent_auditor/consent_auditor_factory.h"
#include "chrome/browser/data_sharing/data_sharing_service_factory.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/metrics/variations/google_groups_updater_service_factory.h"
#include "chrome/browser/password_manager/account_password_store_factory.h"
#include "chrome/browser/password_manager/password_receiver_service_factory.h"
#include "chrome/browser/password_manager/password_sender_service_factory.h"
#include "chrome/browser/password_manager/profile_password_store_factory.h"
#include "chrome/browser/power_bookmarks/power_bookmark_service_factory.h"
#include "chrome/browser/prefs/pref_service_syncable_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_key.h"
#include "chrome/browser/reading_list/reading_list_model_factory.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/security_events/security_event_recorder.h"
#include "chrome/browser/security_events/security_event_recorder_factory.h"
#include "chrome/browser/sharing/sharing_message_bridge.h"
#include "chrome/browser/sharing/sharing_message_bridge_factory.h"
#include "chrome/browser/sharing/sharing_message_model_type_controller.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
#include "chrome/browser/sync/account_bookmark_sync_service_factory.h"
#include "chrome/browser/sync/device_info_sync_service_factory.h"
#include "chrome/browser/sync/local_or_syncable_bookmark_sync_service_factory.h"
#include "chrome/browser/sync/model_type_store_service_factory.h"
#include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h"
#include "chrome/browser/sync/session_sync_service_factory.h"
#include "chrome/browser/sync/sync_invalidations_service_factory.h"
#include "chrome/browser/sync/user_event_service_factory.h"
#include "chrome/browser/tab_group_sync/feature_utils.h"
#include "chrome/browser/tab_group_sync/tab_group_sync_service_factory.h"
#include "chrome/browser/tab_group_sync/tab_group_trial.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/themes/theme_syncable_service.h"
#include "chrome/browser/trusted_vault/trusted_vault_service_factory.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/browser/webdata_services/web_data_service_factory.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_paths.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/browser_sync/sync_api_component_factory_impl.h"
#include "components/consent_auditor/consent_auditor.h"
#include "components/data_sharing/public/features.h"
#include "components/desks_storage/core/desk_sync_service.h"
#include "components/history/core/browser/history_service.h"
#include "components/metrics/demographics/user_demographics.h"
#include "components/password_manager/core/browser/password_store/password_store_interface.h"
#include "components/password_manager/core/browser/sharing/password_receiver_service.h"
#include "components/password_manager/core/browser/sharing/password_sender_service.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/plus_addresses/webdata/plus_address_webdata_service.h"
#include "components/prefs/pref_service.h"
#include "components/saved_tab_groups/tab_group_sync_service.h"
#include "components/search_engines/template_url_service.h"
#include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
#include "components/spellcheck/spellcheck_buildflags.h"
#include "components/supervised_user/core/browser/supervised_user_settings_service.h"
#include "components/sync/base/features.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/pref_names.h"
#include "components/sync/base/report_unrecoverable_error.h"
#include "components/sync/model/forwarding_model_type_controller_delegate.h"
#include "components/sync/model/model_type_controller_delegate.h"
#include "components/sync/model/model_type_store.h"
#include "components/sync/model/model_type_store_service.h"
#include "components/sync/service/model_type_controller.h"
#include "components/sync/service/sync_api_component_factory.h"
#include "components/sync/service/syncable_service_based_model_type_controller.h"
#include "components/sync/service/trusted_vault_synthetic_field_trial.h"
#include "components/sync_bookmarks/bookmark_sync_service.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/sync_sessions/session_sync_service.h"
#include "components/sync_user_events/user_event_service.h"
#include "components/trusted_vault/trusted_vault_service.h"
#include "components/variations/service/google_groups_updater_service.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/buildflags/buildflags.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
#include "chrome/browser/extensions/extension_sync_service.h"
#include "chrome/browser/sync/glue/extension_model_type_controller.h"
#include "chrome/browser/sync/glue/extension_setting_model_type_controller.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_sync_bridge.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_SPELLCHECK)
#include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "components/spellcheck/browser/pref_names.h"
#endif // BUILDFLAG(ENABLE_SPELLCHECK)
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
BUILDFLAG(IS_WIN)
#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h"
#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h"
#elif BUILDFLAG(IS_ANDROID)
#include "components/saved_tab_groups/features.h"
#endif // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) ||
// BUILDFLAG(IS_WIN)
#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/webauthn/passkey_model_factory.h"
#include "components/webauthn/core/browser/passkey_model.h"
#endif // !BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/components/arc/arc_util.h"
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_switches.h"
#include "chrome/browser/ash/app_list/app_list_syncable_service.h"
#include "chrome/browser/ash/app_list/app_list_syncable_service_factory.h"
#include "chrome/browser/ash/app_list/arc/arc_package_sync_model_type_controller.h"
#include "chrome/browser/ash/app_list/arc/arc_package_syncable_service.h"
#include "chrome/browser/ash/arc/arc_util.h"
#include "chrome/browser/ash/crosapi/browser_util.h"
#include "chrome/browser/ash/printing/oauth2/authorization_zones_manager.h"
#include "chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.h"
#include "chrome/browser/ash/printing/printers_sync_bridge.h"
#include "chrome/browser/ash/printing/synced_printers_manager.h"
#include "chrome/browser/ash/printing/synced_printers_manager_factory.h"
#include "chrome/browser/sync/desk_sync_service_factory.h"
#include "chrome/browser/sync/wifi_configuration_sync_service_factory.h"
#include "chromeos/ash/components/sync_wifi/wifi_configuration_sync_service.h"
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/android/webapk/webapk_sync_service.h"
#endif // BUILDFLAG(IS_ANDROID)
using content::BrowserThread;
namespace browser_sync {
namespace {
#if BUILDFLAG(IS_WIN)
constexpr base::FilePath::CharType kLoopbackServerBackendFilename[] =
FILE_PATH_LITERAL("profile.pb");
#endif // BUILDFLAG(IS_WIN)
base::WeakPtr<syncer::SyncableService> GetWeakPtrOrNull(
syncer::SyncableService* service) {
return service ? service->AsWeakPtr() : nullptr;
}
base::RepeatingClosure GetDumpStackClosure() {
return base::BindRepeating(&syncer::ReportUnrecoverableError,
chrome::GetChannel());
}
bool ShouldSyncBrowserTypes() {
#if BUILDFLAG(IS_CHROMEOS_ASH)
return crosapi::browser_util::IsAshBrowserSyncEnabled();
#else
return true;
#endif
}
syncer::ModelTypeSet GetDisabledCommonDataTypes() {
if (!ShouldSyncBrowserTypes()) {
// If browser-sync is disabled (on ChromeOS Ash), most "common" data types
// are disabled. These types will be synced in Lacros instead.
return base::Difference(syncer::UserTypes(),
{syncer::DEVICE_INFO, syncer::USER_CONSENTS});
}
// Common case: No disabled types.
return {};
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
// App sync is enabled by default, with the exception of Lacros secondary
// profiles.
bool IsAppSyncEnabled(Profile* profile) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
if (!profile->IsMainProfile() &&
!web_app::IsMainProfileCheckSkippedForTesting()) {
return false;
}
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
return true;
}
bool ShouldSyncAppsTypesInTransportMode() {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
// When apps sync controlled by Ash Sync settings, allow running apps-related
// types (WEB_APPS, APPS and APP_SETTINGS) in transport-only mode using the
// same `delegate`.
return base::FeatureList::IsEnabled(syncer::kSyncChromeOSAppsToggleSharing);
#else
return false;
#endif
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
} // namespace
ChromeSyncClient::ChromeSyncClient(Profile* profile)
: profile_(profile), extensions_activity_monitor_(profile) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
scoped_refptr<autofill::AutofillWebDataService> profile_web_data_service =
WebDataServiceFactory::GetAutofillWebDataForProfile(
profile_, ServiceAccessType::IMPLICIT_ACCESS);
scoped_refptr<autofill::AutofillWebDataService> account_web_data_service =
WebDataServiceFactory::GetAutofillWebDataForAccount(
profile_, ServiceAccessType::IMPLICIT_ACCESS);
scoped_refptr<base::SequencedTaskRunner> web_data_service_thread =
profile_web_data_service ? profile_web_data_service->GetDBTaskRunner()
: nullptr;
// This class assumes that the database thread is the same across the profile
// and account storage. This DCHECK makes that assumption explicit.
DCHECK(!account_web_data_service ||
web_data_service_thread ==
account_web_data_service->GetDBTaskRunner());
scoped_refptr<password_manager::PasswordStoreInterface>
profile_password_store = ProfilePasswordStoreFactory::GetForProfile(
profile_, ServiceAccessType::IMPLICIT_ACCESS);
scoped_refptr<password_manager::PasswordStoreInterface>
account_password_store = AccountPasswordStoreFactory::GetForProfile(
profile_, ServiceAccessType::IMPLICIT_ACCESS);
supervised_user::SupervisedUserSettingsService*
supervised_user_settings_service =
SupervisedUserSettingsServiceFactory::GetForKey(
profile_->GetProfileKey());
component_factory_ = std::make_unique<SyncApiComponentFactoryImpl>(
this, chrome::GetChannel(), content::GetUIThreadTaskRunner({}),
web_data_service_thread, profile_web_data_service,
account_web_data_service, profile_password_store, account_password_store,
LocalOrSyncableBookmarkSyncServiceFactory::GetForProfile(profile_),
AccountBookmarkSyncServiceFactory::GetForProfile(profile_),
PowerBookmarkServiceFactory::GetForBrowserContext(profile_),
supervised_user_settings_service,
WebDataServiceFactory::GetPlusAddressWebDataForProfile(
profile_, ServiceAccessType::IMPLICIT_ACCESS),
commerce::ProductSpecificationsServiceFactory::GetForBrowserContext(
profile_),
data_sharing::DataSharingServiceFactory::GetForProfile(profile_));
}
ChromeSyncClient::~ChromeSyncClient() = default;
PrefService* ChromeSyncClient::GetPrefService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return profile_->GetPrefs();
}
signin::IdentityManager* ChromeSyncClient::GetIdentityManager() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return IdentityManagerFactory::GetForProfile(profile_);
}
base::FilePath ChromeSyncClient::GetLocalSyncBackendFolder() {
base::FilePath local_sync_backend_folder =
GetPrefService()->GetFilePath(syncer::prefs::kLocalSyncBackendDir);
#if BUILDFLAG(IS_WIN)
if (local_sync_backend_folder.empty()) {
if (!base::PathService::Get(chrome::DIR_ROAMING_USER_DATA,
&local_sync_backend_folder)) {
SYSLOG(WARNING) << "Local sync can not get the roaming profile folder.";
return base::FilePath();
}
}
// This code as it is now will assume the same profile order is present on
// all machines, which is not a given. It is to be defined if only the
// Default profile should get this treatment or all profile as is the case
// now.
// TODO(pastarmovj): http://crbug.com/674928 Decide if only the Default one
// should be considered roamed. For now the code assumes all profiles are
// created in the same order on all machines.
local_sync_backend_folder =
local_sync_backend_folder.Append(profile_->GetBaseName());
local_sync_backend_folder =
local_sync_backend_folder.Append(kLoopbackServerBackendFilename);
#endif // BUILDFLAG(IS_WIN)
return local_sync_backend_folder;
}
syncer::ModelTypeStoreService* ChromeSyncClient::GetModelTypeStoreService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return ModelTypeStoreServiceFactory::GetForProfile(profile_);
}
syncer::DeviceInfoSyncService* ChromeSyncClient::GetDeviceInfoSyncService() {
return DeviceInfoSyncServiceFactory::GetForProfile(profile_);
}
favicon::FaviconService* ChromeSyncClient::GetFaviconService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return FaviconServiceFactory::GetForProfile(
profile_, ServiceAccessType::IMPLICIT_ACCESS);
}
history::HistoryService* ChromeSyncClient::GetHistoryService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return HistoryServiceFactory::GetForProfile(
profile_, ServiceAccessType::EXPLICIT_ACCESS);
}
ReadingListModel* ChromeSyncClient::GetReadingListModel() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return ReadingListModelFactory::GetForBrowserContext(profile_);
}
send_tab_to_self::SendTabToSelfSyncService*
ChromeSyncClient::GetSendTabToSelfSyncService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return SendTabToSelfSyncServiceFactory::GetForProfile(profile_);
}
sync_preferences::PrefServiceSyncable*
ChromeSyncClient::GetPrefServiceSyncable() {
return PrefServiceSyncableFromProfile(profile_);
}
sync_sessions::SessionSyncService* ChromeSyncClient::GetSessionSyncService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return SessionSyncServiceFactory::GetForProfile(profile_);
}
password_manager::PasswordReceiverService*
ChromeSyncClient::GetPasswordReceiverService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return PasswordReceiverServiceFactory::GetForProfile(profile_);
}
password_manager::PasswordSenderService*
ChromeSyncClient::GetPasswordSenderService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return PasswordSenderServiceFactory::GetForProfile(profile_);
}
syncer::ModelTypeController::TypeVector
ChromeSyncClient::CreateModelTypeControllers(
syncer::SyncService* sync_service) {
syncer::ModelTypeController::TypeVector controllers =
component_factory_->CreateCommonModelTypeControllers(
GetDisabledCommonDataTypes(), sync_service);
const base::RepeatingClosure dump_stack = GetDumpStackClosure();
syncer::RepeatingModelTypeStoreFactory model_type_store_factory =
GetModelTypeStoreService()->GetStoreFactory();
if (ShouldSyncBrowserTypes()) {
syncer::ModelTypeControllerDelegate* security_events_delegate =
SecurityEventRecorderFactory::GetForProfile(profile_)
->GetControllerDelegate()
.get();
// Forward both full-sync and transport-only modes to the same delegate,
// since behavior for SECURITY_EVENTS does not differ.
controllers.push_back(std::make_unique<syncer::ModelTypeController>(
syncer::SECURITY_EVENTS,
/*delegate_for_full_sync_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
security_events_delegate),
/*delegate_for_transport_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
security_events_delegate)));
// Forward both full-sync and transport-only modes to the same delegate,
// since behavior for SHARING_MESSAGE does not differ. They both do not
// store data on persistent storage.
syncer::ModelTypeControllerDelegate* sharing_message_delegate =
GetControllerDelegateForModelType(syncer::SHARING_MESSAGE).get();
controllers.push_back(std::make_unique<SharingMessageModelTypeController>(
/*delegate_for_full_sync_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
sharing_message_delegate),
/*delegate_for_transport_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
sharing_message_delegate)));
#if BUILDFLAG(ENABLE_EXTENSIONS)
// Extension sync is enabled by default.
controllers.push_back(std::make_unique<ExtensionModelTypeController>(
syncer::EXTENSIONS, model_type_store_factory,
GetSyncableServiceForType(syncer::EXTENSIONS), dump_stack,
ExtensionModelTypeController::DelegateMode::kLegacyFullSyncModeOnly,
profile_));
// Extension setting sync is enabled by default.
controllers.push_back(std::make_unique<ExtensionSettingModelTypeController>(
syncer::EXTENSION_SETTINGS, model_type_store_factory,
extensions::settings_sync_util::GetSyncableServiceProvider(
profile_, syncer::EXTENSION_SETTINGS),
dump_stack,
ExtensionSettingModelTypeController::DelegateMode::
kLegacyFullSyncModeOnly,
profile_));
if (IsAppSyncEnabled(profile_)) {
controllers.push_back(CreateAppsModelTypeController());
controllers.push_back(CreateAppSettingsModelTypeController(sync_service));
if (web_app::AreWebAppsEnabled(profile_) &&
web_app::WebAppProvider::GetForWebApps(profile_)) {
controllers.push_back(CreateWebAppsModelTypeController());
}
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(IS_ANDROID)
if (base::FeatureList::IsEnabled(syncer::kWebApkBackupAndRestoreBackend)) {
syncer::ModelTypeControllerDelegate* delegate =
GetControllerDelegateForModelType(syncer::WEB_APKS).get();
controllers.push_back(std::make_unique<syncer::ModelTypeController>(
syncer::WEB_APKS,
/*delegate_for_full_sync_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate),
/*delegate_for_transport_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate)));
}
#endif // BUILDFLAG(IS_ANDROID)
#if !BUILDFLAG(IS_ANDROID)
// Theme sync is enabled by default.
controllers.push_back(std::make_unique<ExtensionModelTypeController>(
syncer::THEMES, model_type_store_factory,
GetSyncableServiceForType(syncer::THEMES), dump_stack,
ExtensionModelTypeController::DelegateMode::kLegacyFullSyncModeOnly,
profile_));
// Search Engine sync is enabled by default.
controllers.push_back(
std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
syncer::SEARCH_ENGINES, model_type_store_factory,
GetSyncableServiceForType(syncer::SEARCH_ENGINES), dump_stack,
syncer::SyncableServiceBasedModelTypeController::DelegateMode::
kLegacyFullSyncModeOnly));
#endif // !BUILDFLAG(IS_ANDROID)
// Tab group sync is enabled via separate feature flags on different
// platforms.
bool enable_tab_group_sync = false;
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
BUILDFLAG(IS_WIN)
enable_tab_group_sync = true;
#elif BUILDFLAG(IS_ANDROID)
enable_tab_group_sync = tab_groups::IsTabGroupSyncEnabled(GetPrefService());
tab_groups::TabGroupTrial::OnTabgroupSyncEnabled(enable_tab_group_sync);
#endif // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) ||
// BUILDFLAG(IS_WIN)
if (enable_tab_group_sync) {
controllers.push_back(std::make_unique<syncer::ModelTypeController>(
syncer::SAVED_TAB_GROUP,
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
GetControllerDelegateForModelType(syncer::SAVED_TAB_GROUP).get()),
/*delegate_for_transport_mode=*/nullptr));
}
if (base::FeatureList::IsEnabled(
data_sharing::features::kDataSharingFeature)) {
controllers.push_back(std::make_unique<syncer::ModelTypeController>(
syncer::SHARED_TAB_GROUP_DATA,
/*delegate_for_full_sync_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
GetControllerDelegateForModelType(syncer::SHARED_TAB_GROUP_DATA)
.get()),
/*delegate_for_transport_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
GetControllerDelegateForModelType(syncer::SHARED_TAB_GROUP_DATA)
.get())));
}
// Chrome prefers OS provided spell checkers where they exist. So only sync the
// custom dictionary on platforms that typically don't provide one.
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
// Dictionary sync is enabled by default.
if (GetPrefService()->GetBoolean(spellcheck::prefs::kSpellCheckEnable)) {
controllers.push_back(
std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
syncer::DICTIONARY, model_type_store_factory,
GetSyncableServiceForType(syncer::DICTIONARY), dump_stack,
syncer::SyncableServiceBasedModelTypeController::DelegateMode::
kLegacyFullSyncModeOnly));
}
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
// Some profile types (e.g. sign-in screen) don't support app list.
// Temporarily Disable AppListSyncableService for tablet form factor devices.
// See crbug/1013732 for details.
if (app_list::AppListSyncableServiceFactory::GetForProfile(profile_) &&
!ash::switches::IsTabletFormFactor()) {
// Runs in sync transport-mode and full-sync mode.
controllers.push_back(
std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
syncer::APP_LIST, model_type_store_factory,
GetSyncableServiceForType(syncer::APP_LIST), dump_stack,
syncer::SyncableServiceBasedModelTypeController::DelegateMode::
kTransportModeWithSingleModel));
}
if (arc::IsArcAllowedForProfile(profile_) &&
!arc::IsArcAppSyncFlowDisabled()) {
controllers.push_back(std::make_unique<ArcPackageSyncModelTypeController>(
model_type_store_factory,
GetSyncableServiceForType(syncer::ARC_PACKAGE), dump_stack,
sync_service, profile_));
}
controllers.push_back(
std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
syncer::OS_PREFERENCES, model_type_store_factory,
GetSyncableServiceForType(syncer::OS_PREFERENCES), dump_stack,
syncer::SyncableServiceBasedModelTypeController::DelegateMode::
kTransportModeWithSingleModel));
controllers.push_back(
std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
syncer::OS_PRIORITY_PREFERENCES, model_type_store_factory,
GetSyncableServiceForType(syncer::OS_PRIORITY_PREFERENCES),
dump_stack,
syncer::SyncableServiceBasedModelTypeController::DelegateMode::
kTransportModeWithSingleModel));
syncer::ModelTypeControllerDelegate* printers_delegate =
GetControllerDelegateForModelType(syncer::PRINTERS).get();
controllers.push_back(std::make_unique<syncer::ModelTypeController>(
syncer::PRINTERS,
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
printers_delegate),
/*delegate_for_transport_mode=*/nullptr));
if (WifiConfigurationSyncServiceFactory::ShouldRunInProfile(profile_)) {
syncer::ModelTypeControllerDelegate* wifi_configurations_delegate =
GetControllerDelegateForModelType(syncer::WIFI_CONFIGURATIONS).get();
controllers.push_back(std::make_unique<syncer::ModelTypeController>(
syncer::WIFI_CONFIGURATIONS,
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
wifi_configurations_delegate),
/*delegate_for_transport_mode=*/nullptr));
}
syncer::ModelTypeControllerDelegate* workspace_desk_delegate =
GetControllerDelegateForModelType(syncer::WORKSPACE_DESK).get();
controllers.push_back(std::make_unique<syncer::ModelTypeController>(
syncer::WORKSPACE_DESK,
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
workspace_desk_delegate),
/*delegate_for_transport_mode=*/nullptr));
if (ash::features::IsOAuthIppEnabled()) {
syncer::ModelTypeControllerDelegate*
printers_authorization_servers_delegate =
GetControllerDelegateForModelType(
syncer::PRINTERS_AUTHORIZATION_SERVERS)
.get();
controllers.push_back(std::make_unique<syncer::ModelTypeController>(
syncer::PRINTERS_AUTHORIZATION_SERVERS,
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
printers_authorization_servers_delegate),
/*delegate_for_transport_mode=*/nullptr));
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
return controllers;
}
trusted_vault::TrustedVaultClient* ChromeSyncClient::GetTrustedVaultClient() {
return TrustedVaultServiceFactory::GetForProfile(profile_)
->GetTrustedVaultClient(trusted_vault::SecurityDomainId::kChromeSync);
}
syncer::SyncInvalidationsService*
ChromeSyncClient::GetSyncInvalidationsService() {
return SyncInvalidationsServiceFactory::GetForProfile(profile_);
}
scoped_refptr<syncer::ExtensionsActivity>
ChromeSyncClient::GetExtensionsActivity() {
return extensions_activity_monitor_.GetExtensionsActivity();
}
base::WeakPtr<syncer::SyncableService>
ChromeSyncClient::GetSyncableServiceForType(syncer::ModelType type) {
switch (type) {
case syncer::SEARCH_ENGINES:
return GetWeakPtrOrNull(
TemplateURLServiceFactory::GetForProfile(profile_));
#if BUILDFLAG(ENABLE_EXTENSIONS)
case syncer::APPS:
case syncer::EXTENSIONS:
return GetWeakPtrOrNull(ExtensionSyncService::Get(profile_));
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(IS_CHROMEOS_ASH)
case syncer::APP_LIST:
return GetWeakPtrOrNull(
app_list::AppListSyncableServiceFactory::GetForProfile(profile_));
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
#if !BUILDFLAG(IS_ANDROID)
case syncer::THEMES:
return ThemeServiceFactory::GetForProfile(profile_)
->GetThemeSyncableService()
->AsWeakPtr();
#endif // !BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(ENABLE_SPELLCHECK)
case syncer::DICTIONARY: {
SpellcheckService* spellcheck_service =
SpellcheckServiceFactory::GetForContext(profile_);
return spellcheck_service
? spellcheck_service->GetCustomDictionary()->AsWeakPtr()
: nullptr;
}
#endif // BUILDFLAG(ENABLE_SPELLCHECK)
#if BUILDFLAG(IS_CHROMEOS_ASH)
case syncer::ARC_PACKAGE:
return arc::ArcPackageSyncableService::Get(profile_)->AsWeakPtr();
case syncer::OS_PREFERENCES:
case syncer::OS_PRIORITY_PREFERENCES:
return PrefServiceSyncableFromProfile(profile_)
->GetSyncableService(type)
->AsWeakPtr();
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
default:
NOTREACHED();
return nullptr;
}
}
base::WeakPtr<syncer::ModelTypeControllerDelegate>
ChromeSyncClient::GetControllerDelegateForModelType(syncer::ModelType type) {
switch (type) {
case syncer::SAVED_TAB_GROUP: {
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
BUILDFLAG(IS_WIN)
auto* keyed_service =
tab_groups::SavedTabGroupServiceFactory::GetForProfile(profile_);
CHECK(keyed_service);
return keyed_service->GetSavedTabGroupControllerDelegate();
#elif BUILDFLAG(IS_ANDROID)
DCHECK(tab_groups::IsTabGroupSyncEnabled(GetPrefService()));
return tab_groups::TabGroupSyncServiceFactory::GetForProfile(profile_)
->GetSavedTabGroupControllerDelegate();
#else
NOTREACHED();
return base::WeakPtr<syncer::ModelTypeControllerDelegate>();
#endif // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) ||
// BUILDFLAG(IS_WIN)
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
case syncer::PRINTERS:
return ash::SyncedPrintersManagerFactory::GetForBrowserContext(profile_)
->GetSyncBridge()
->change_processor()
->GetControllerDelegate();
case syncer::PRINTERS_AUTHORIZATION_SERVERS:
return ash::printing::oauth2::AuthorizationZonesManagerFactory::
GetForBrowserContext(profile_)
->GetModelTypeSyncBridge()
->change_processor()
->GetControllerDelegate();
case syncer::WIFI_CONFIGURATIONS:
return WifiConfigurationSyncServiceFactory::GetForProfile(profile_,
/*create=*/true)
->GetControllerDelegate();
case syncer::WORKSPACE_DESK:
return DeskSyncServiceFactory::GetForProfile(profile_)
->GetControllerDelegate();
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
case syncer::SHARING_MESSAGE:
return SharingMessageBridgeFactory::GetForBrowserContext(profile_)
->GetControllerDelegate();
case syncer::USER_CONSENTS:
return ConsentAuditorFactory::GetForProfile(profile_)
->GetControllerDelegate();
case syncer::USER_EVENTS:
return browser_sync::UserEventServiceFactory::GetForProfile(profile_)
->GetControllerDelegate();
#if BUILDFLAG(ENABLE_EXTENSIONS)
case syncer::WEB_APPS: {
auto* provider = web_app::WebAppProvider::GetForWebApps(profile_);
// CreateWebAppsModelTypeController(), and therefore this code, should
// never be called when GetForWebApps() returns nullptr.
DCHECK(provider);
DCHECK(web_app::AreWebAppsEnabled(profile_));
return provider->sync_bridge_unsafe()
.change_processor()
->GetControllerDelegate();
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(IS_ANDROID)
case syncer::WEB_APKS: {
webapk::WebApkSyncService* service =
webapk::WebApkSyncService::GetForProfile(profile_);
CHECK(service);
return service->GetModelTypeControllerDelegate();
}
#endif // BUILDFLAG(IS_ANDROID)
#if !BUILDFLAG(IS_ANDROID)
case syncer::WEBAUTHN_CREDENTIAL: {
DCHECK(base::FeatureList::IsEnabled(syncer::kSyncWebauthnCredentials));
return PasskeyModelFactory::GetForProfile(profile_)
->GetModelTypeControllerDelegate();
}
#endif // !BUILDFLAG(IS_ANDROID)
case syncer::SHARED_TAB_GROUP_DATA:
CHECK(base::FeatureList::IsEnabled(
data_sharing::features::kDataSharingFeature));
return tab_groups::TabGroupSyncServiceFactory::GetForProfile(profile_)
->GetSharedTabGroupControllerDelegate();
// We don't exercise this function for certain datatypes, because their
// controllers get the delegate elsewhere.
case syncer::AUTOFILL:
case syncer::AUTOFILL_PROFILE:
case syncer::AUTOFILL_WALLET_DATA:
case syncer::AUTOFILL_WALLET_METADATA:
case syncer::BOOKMARKS:
case syncer::DEVICE_INFO:
case syncer::READING_LIST:
case syncer::SECURITY_EVENTS:
case syncer::SEND_TAB_TO_SELF:
case syncer::SESSIONS:
NOTREACHED();
return base::WeakPtr<syncer::ModelTypeControllerDelegate>();
default:
NOTREACHED();
return base::WeakPtr<syncer::ModelTypeControllerDelegate>();
}
}
syncer::SyncApiComponentFactory*
ChromeSyncClient::GetSyncApiComponentFactory() {
return component_factory_.get();
}
bool ChromeSyncClient::IsCustomPassphraseAllowed() {
supervised_user::SupervisedUserSettingsService*
supervised_user_settings_service =
SupervisedUserSettingsServiceFactory::GetForKey(
profile_->GetProfileKey());
if (supervised_user_settings_service) {
return supervised_user_settings_service->IsCustomPassphraseAllowed();
}
return true;
}
void ChromeSyncClient::OnLocalSyncTransportDataCleared() {
metrics::ClearDemographicsPrefs(profile_->GetPrefs());
GoogleGroupsUpdaterService* google_groups_updater =
GoogleGroupsUpdaterServiceFactory::GetForBrowserContext(profile_);
if (google_groups_updater != nullptr) {
google_groups_updater->ClearSigninScopedState();
}
}
bool ChromeSyncClient::IsPasswordSyncAllowed() {
#if BUILDFLAG(IS_ANDROID)
return profile_->GetPrefs()->GetInteger(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores) !=
static_cast<int>(
password_manager::prefs::UseUpmLocalAndSeparateStoresState::
kOffAndMigrationPending);
#else
return true;
#endif // BUILDFLAG(IS_ANDROID)
}
void ChromeSyncClient::SetPasswordSyncAllowedChangeCb(
const base::RepeatingClosure& cb) {
#if BUILDFLAG(IS_ANDROID)
CHECK(!upm_pref_change_registrar_.prefs())
<< "SetPasswordSyncAllowedChangeCb() must be called at most once";
upm_pref_change_registrar_.Init(profile_->GetPrefs());
// This overfires: the kPasswordsUseUPMLocalAndSeparateStores pref might have
// changed value, but not IsPasswordSyncAllowed(). That's fine, `cb` should
// handle this case.
upm_pref_change_registrar_.Add(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores, cb);
#else
// IsPasswordSyncAllowed() doesn't change outside of Android.
#endif // BUILDFLAG(IS_ANDROID)
}
void ChromeSyncClient::RegisterTrustedVaultAutoUpgradeSyntheticFieldTrial(
const syncer::TrustedVaultAutoUpgradeSyntheticFieldTrialGroup& group) {
CHECK(group.is_valid());
NOTIMPLEMENTED();
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
std::unique_ptr<syncer::ModelTypeController>
ChromeSyncClient::CreateAppsModelTypeController() {
auto delegate_mode =
ExtensionModelTypeController::DelegateMode::kLegacyFullSyncModeOnly;
if (ShouldSyncAppsTypesInTransportMode()) {
delegate_mode = ExtensionModelTypeController::DelegateMode::
kTransportModeWithSingleModel;
}
return std::make_unique<ExtensionModelTypeController>(
syncer::APPS, GetModelTypeStoreService()->GetStoreFactory(),
GetSyncableServiceForType(syncer::APPS), GetDumpStackClosure(),
delegate_mode, profile_);
}
std::unique_ptr<syncer::ModelTypeController>
ChromeSyncClient::CreateAppSettingsModelTypeController(
syncer::SyncService* sync_service) {
auto delegate_mode = ExtensionSettingModelTypeController::DelegateMode::
kLegacyFullSyncModeOnly;
if (ShouldSyncAppsTypesInTransportMode()) {
delegate_mode = ExtensionSettingModelTypeController::DelegateMode::
kTransportModeWithSingleModel;
}
return std::make_unique<ExtensionSettingModelTypeController>(
syncer::APP_SETTINGS, GetModelTypeStoreService()->GetStoreFactory(),
extensions::settings_sync_util::GetSyncableServiceProvider(
profile_, syncer::APP_SETTINGS),
GetDumpStackClosure(), delegate_mode, profile_);
}
std::unique_ptr<syncer::ModelTypeController>
ChromeSyncClient::CreateWebAppsModelTypeController() {
syncer::ModelTypeControllerDelegate* delegate =
GetControllerDelegateForModelType(syncer::WEB_APPS).get();
std::unique_ptr<syncer::ModelTypeControllerDelegate>
delegate_for_transport_mode = nullptr;
if (ShouldSyncAppsTypesInTransportMode()) {
delegate_for_transport_mode =
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate);
}
return std::make_unique<syncer::ModelTypeController>(
syncer::WEB_APPS,
/*delegate_for_full_sync_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(delegate),
/*delegate_for_transport_mode=*/
std::move(delegate_for_transport_mode));
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
} // namespace browser_sync