blob: 8985e401835aa3c5b3535e889731193b081e50af [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/browser_sync/sync_api_component_factory_impl.h"
#include <utility>
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/time/default_clock.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h"
#include "components/autofill/core/browser/webdata/addresses/autofill_profile_sync_bridge.h"
#include "components/autofill/core/browser/webdata/addresses/contact_info_model_type_controller.h"
#include "components/autofill/core/browser/webdata/addresses/contact_info_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autocomplete/autocomplete_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/browser/webdata/payments/autofill_wallet_credential_sync_bridge.h"
#include "components/autofill/core/browser/webdata/payments/autofill_wallet_metadata_sync_bridge.h"
#include "components/autofill/core/browser/webdata/payments/autofill_wallet_offer_sync_bridge.h"
#include "components/autofill/core/browser/webdata/payments/autofill_wallet_sync_bridge.h"
#include "components/autofill/core/browser/webdata/payments/autofill_wallet_usage_data_sync_bridge.h"
#include "components/browser_sync/active_devices_provider_impl.h"
#include "components/browser_sync/browser_sync_client.h"
#include "components/commerce/core/commerce_feature_list.h"
#include "components/commerce/core/product_specifications/product_specifications_service.h"
#include "components/data_sharing/public/data_sharing_service.h"
#include "components/data_sharing/public/features.h"
#include "components/history/core/browser/sync/history_delete_directives_model_type_controller.h"
#include "components/history/core/browser/sync/history_model_type_controller.h"
#include "components/password_manager/core/browser/password_store/password_store_interface.h"
#include "components/password_manager/core/browser/sharing/incoming_password_sharing_invitation_model_type_controller.h"
#include "components/password_manager/core/browser/sharing/outgoing_password_sharing_invitation_model_type_controller.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/browser/sync/password_model_type_controller.h"
#include "components/plus_addresses/features.h"
#include "components/plus_addresses/webdata/plus_address_webdata_service.h"
#include "components/power_bookmarks/core/power_bookmark_features.h"
#include "components/power_bookmarks/core/power_bookmark_service.h"
#include "components/prefs/pref_service.h"
#include "components/reading_list/core/reading_list_model.h"
#include "components/send_tab_to_self/send_tab_to_self_model_type_controller.h"
#include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
#include "components/supervised_user/core/common/buildflags.h"
#include "components/sync/base/features.h"
#include "components/sync/base/legacy_directory_deletion.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/report_unrecoverable_error.h"
#include "components/sync/engine/sync_engine.h"
#include "components/sync/invalidations/sync_invalidations_service.h"
#include "components/sync/model/forwarding_model_type_controller_delegate.h"
#include "components/sync/model/proxy_model_type_controller_delegate.h"
#include "components/sync/service/data_type_manager_impl.h"
#include "components/sync/service/glue/sync_engine_impl.h"
#include "components/sync/service/glue/sync_transport_data_prefs.h"
#include "components/sync/service/model_type_controller.h"
#include "components/sync/service/syncable_service_based_model_type_controller.h"
#include "components/sync_bookmarks/bookmark_model_type_controller.h"
#include "components/sync_bookmarks/bookmark_sync_service.h"
#include "components/sync_device_info/device_info_sync_service.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/sync_sessions/session_model_type_controller.h"
#include "components/sync_sessions/session_sync_service.h"
#include "components/sync_user_events/user_event_model_type_controller.h"
#include "components/webauthn/core/browser/passkey_model_type_controller.h"
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
#include "components/supervised_user/core/browser/supervised_user_settings_model_type_controller.h"
#include "components/supervised_user/core/browser/supervised_user_settings_service.h"
#endif // BUILDFLAG(ENABLE_SUPERVISED_USER)
using syncer::DataTypeManager;
using syncer::DataTypeManagerImpl;
using syncer::DataTypeManagerObserver;
using syncer::ModelTypeController;
using syncer::SyncableServiceBasedModelTypeController;
namespace browser_sync {
namespace {
// These helper functions only wrap the factory functions of the bridges. This
// way, it simplifies life for the compiler which cannot directly cast
// "WeakPtr<ModelTypeSyncBridge> (AutofillWebDataService*)" to
// "WeakPtr<ModelTypeControllerDelegate> (AutofillWebDataService*)".
base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutocompleteDelegateFromDataService(autofill::AutofillWebDataService* service) {
return autofill::AutocompleteSyncBridge::FromWebDataService(service)
->change_processor()
->GetControllerDelegate();
}
base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutofillProfileDelegateFromDataService(
autofill::AutofillWebDataService* service) {
return autofill::AutofillProfileSyncBridge::FromWebDataService(service)
->change_processor()
->GetControllerDelegate();
}
base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutofillWalletCredentialDataDelegateFromDataService(
autofill::AutofillWebDataService* service) {
return autofill::AutofillWalletCredentialSyncBridge::FromWebDataService(
service)
->change_processor()
->GetControllerDelegate();
}
base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutofillWalletDelegateFromDataService(
autofill::AutofillWebDataService* service) {
return autofill::AutofillWalletSyncBridge::FromWebDataService(service)
->change_processor()
->GetControllerDelegate();
}
base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutofillWalletMetadataDelegateFromDataService(
autofill::AutofillWebDataService* service) {
return autofill::AutofillWalletMetadataSyncBridge::FromWebDataService(service)
->change_processor()
->GetControllerDelegate();
}
base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutofillWalletOfferDelegateFromDataService(
autofill::AutofillWebDataService* service) {
return autofill::AutofillWalletOfferSyncBridge::FromWebDataService(service)
->change_processor()
->GetControllerDelegate();
}
base::WeakPtr<syncer::ModelTypeControllerDelegate>
AutofillWalletUsageDataDelegateFromDataService(
autofill::AutofillWebDataService* service) {
return autofill::AutofillWalletUsageDataSyncBridge::FromWebDataService(
service)
->change_processor()
->GetControllerDelegate();
}
base::WeakPtr<syncer::ModelTypeControllerDelegate>
ContactInfoDelegateFromDataService(autofill::AutofillWebDataService* service) {
return autofill::ContactInfoSyncBridge::FromWebDataService(service)
->change_processor()
->GetControllerDelegate();
}
// Helper function that deals will null (e.g. tests, iOS webview).
base::WeakPtr<syncer::SyncableService> SyncableServiceForPrefs(
sync_preferences::PrefServiceSyncable* prefs_service,
syncer::ModelType type) {
return prefs_service ? prefs_service->GetSyncableService(type)->AsWeakPtr()
: nullptr;
}
} // namespace
SyncApiComponentFactoryImpl::SyncApiComponentFactoryImpl(
browser_sync::BrowserSyncClient* sync_client,
version_info::Channel channel,
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::PasswordStoreInterface>&
profile_password_store,
const scoped_refptr<password_manager::PasswordStoreInterface>&
account_password_store,
sync_bookmarks::BookmarkSyncService*
local_or_syncable_bookmark_sync_service,
sync_bookmarks::BookmarkSyncService* account_bookmark_sync_service,
power_bookmarks::PowerBookmarkService* power_bookmark_service,
supervised_user::SupervisedUserSettingsService*
supervised_user_settings_service,
const scoped_refptr<plus_addresses::PlusAddressWebDataService>&
plus_address_webdata_service,
commerce::ProductSpecificationsService* product_specifications_service,
data_sharing::DataSharingService* data_sharing_service)
: sync_client_(sync_client),
channel_(channel),
ui_thread_(ui_thread),
db_thread_(db_thread),
engines_and_directory_deletion_thread_(
base::ThreadPool::CreateSequencedTaskRunner(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN})),
web_data_service_on_disk_(web_data_service_on_disk),
web_data_service_in_memory_(web_data_service_in_memory),
profile_password_store_(profile_password_store),
account_password_store_(account_password_store),
local_or_syncable_bookmark_sync_service_(
local_or_syncable_bookmark_sync_service),
account_bookmark_sync_service_(account_bookmark_sync_service),
power_bookmark_service_(power_bookmark_service),
supervised_user_settings_service_(supervised_user_settings_service),
plus_address_webdata_service_(plus_address_webdata_service),
product_specifications_service_(product_specifications_service),
data_sharing_service_(data_sharing_service) {
DCHECK(sync_client_);
}
SyncApiComponentFactoryImpl::~SyncApiComponentFactoryImpl() = default;
syncer::ModelTypeController::TypeVector
SyncApiComponentFactoryImpl::CreateCommonModelTypeControllers(
syncer::ModelTypeSet disabled_types,
syncer::SyncService* sync_service) {
syncer::ModelTypeController::TypeVector controllers;
const base::RepeatingClosure dump_stack =
base::BindRepeating(&syncer::ReportUnrecoverableError, channel_);
// Same delegate for full-sync or transport mode.
controllers.push_back(std::make_unique<ModelTypeController>(
syncer::DEVICE_INFO,
/*delegate_for_full_sync_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
sync_client_->GetDeviceInfoSyncService()
->GetControllerDelegate()
.get()),
/*delegate_for_transport_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
sync_client_->GetDeviceInfoSyncService()
->GetControllerDelegate()
.get())));
// These features are enabled only if there's a DB thread to post tasks to.
if (db_thread_) {
if (!disabled_types.Has(syncer::AUTOFILL)) {
// Note: Transport mode is not and will not be supported.
controllers.push_back(std::make_unique<ModelTypeController>(
syncer::AUTOFILL,
std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
db_thread_, base::BindRepeating(
&AutocompleteDelegateFromDataService,
base::RetainedRef(web_data_service_on_disk_))),
/*delegate_for_transport_mode=*/nullptr));
}
if (!disabled_types.Has(syncer::AUTOFILL_PROFILE)) {
// Note: Transport mode is not and will not be supported - support is
// coming via CONTACT_INFO instead.
controllers.push_back(std::make_unique<syncer::ModelTypeController>(
syncer::AUTOFILL_PROFILE,
std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
db_thread_, base::BindRepeating(
&AutofillProfileDelegateFromDataService,
base::RetainedRef(web_data_service_on_disk_))),
/*delegate_for_transport_mode=*/nullptr));
}
if (!disabled_types.Has(syncer::CONTACT_INFO)) {
// The same delegate is used for full sync and transport mode.
controllers.push_back(
std::make_unique<autofill::ContactInfoModelTypeController>(
/*delegate_for_full_sync_mode=*/
std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
db_thread_,
base::BindRepeating(
&ContactInfoDelegateFromDataService,
base::RetainedRef(web_data_service_on_disk_))),
/*delegate_for_transport_mode=*/
std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
db_thread_,
base::BindRepeating(
&ContactInfoDelegateFromDataService,
base::RetainedRef(web_data_service_on_disk_))),
sync_service, sync_client_->GetIdentityManager()));
}
if (!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA)) {
controllers.push_back(CreateWalletModelTypeController(
syncer::AUTOFILL_WALLET_DATA,
base::BindRepeating(&AutofillWalletDelegateFromDataService),
sync_service, /*with_transport_mode_support=*/true));
}
// Wallet metadata sync depends on Wallet data sync.
if (!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA) &&
!disabled_types.Has(syncer::AUTOFILL_WALLET_METADATA)) {
controllers.push_back(CreateWalletModelTypeController(
syncer::AUTOFILL_WALLET_METADATA,
base::BindRepeating(&AutofillWalletMetadataDelegateFromDataService),
sync_service, /*with_transport_mode_support=*/
base::FeatureList::IsEnabled(
syncer::kSyncEnableWalletMetadataInTransportMode)));
}
// Wallet offer sync depends on Wallet data sync.
if (!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA) &&
!disabled_types.Has(syncer::AUTOFILL_WALLET_OFFER)) {
controllers.push_back(CreateWalletModelTypeController(
syncer::AUTOFILL_WALLET_OFFER,
base::BindRepeating(&AutofillWalletOfferDelegateFromDataService),
sync_service, /*with_transport_mode_support=*/
base::FeatureList::IsEnabled(
syncer::kSyncEnableWalletOfferInTransportMode)));
}
// Wallet usage data sync depends on Wallet data sync.
if (base::FeatureList::IsEnabled(syncer::kSyncAutofillWalletUsageData) &&
!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA) &&
!disabled_types.Has(syncer::AUTOFILL_WALLET_USAGE)) {
controllers.push_back(CreateWalletModelTypeController(
syncer::AUTOFILL_WALLET_USAGE,
base::BindRepeating(&AutofillWalletUsageDataDelegateFromDataService),
sync_service, /*with_transport_mode_support=*/true));
}
// Wallet credential data sync depends on Wallet data sync.
if (base::FeatureList::IsEnabled(
syncer::kSyncAutofillWalletCredentialData) &&
!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA) &&
!disabled_types.Has(syncer::AUTOFILL_WALLET_CREDENTIAL)) {
controllers.push_back(CreateWalletModelTypeController(
syncer::AUTOFILL_WALLET_CREDENTIAL,
base::BindRepeating(
&AutofillWalletCredentialDataDelegateFromDataService),
sync_service, /*with_transport_mode_support=*/true));
}
}
if (!disabled_types.Has(syncer::BOOKMARKS)) {
favicon::FaviconService* favicon_service =
sync_client_->GetFaviconService();
// Services can be null in tests.
if (local_or_syncable_bookmark_sync_service_ && favicon_service) {
auto full_mode_delegate =
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
local_or_syncable_bookmark_sync_service_
->GetBookmarkSyncControllerDelegate(favicon_service)
.get());
auto transport_mode_delegate =
account_bookmark_sync_service_
? std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
account_bookmark_sync_service_
->GetBookmarkSyncControllerDelegate(favicon_service)
.get())
: nullptr;
controllers.push_back(
std::make_unique<sync_bookmarks::BookmarkModelTypeController>(
std::move(full_mode_delegate),
std::move(transport_mode_delegate)));
}
if (!disabled_types.Has(syncer::POWER_BOOKMARK) &&
power_bookmark_service_ &&
base::FeatureList::IsEnabled(power_bookmarks::kPowerBookmarkBackend)) {
// TODO(crbug.com/40261319): Support transport mode for POWER_BOOKMARK.
controllers.push_back(std::make_unique<ModelTypeController>(
syncer::POWER_BOOKMARK,
power_bookmark_service_->CreateSyncControllerDelegate(),
/*delegate_for_transport_mode=*/nullptr));
}
}
if (!disabled_types.Has(syncer::COMPARE) && product_specifications_service_ &&
base::FeatureList::IsEnabled(commerce::kProductSpecificationsSync)) {
syncer::ModelTypeControllerDelegate* delegate =
product_specifications_service_->GetSyncControllerDelegate().get();
controllers.push_back(std::make_unique<ModelTypeController>(
syncer::COMPARE,
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate),
/*delegate_for_transport_mode= */
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate)));
}
if (!disabled_types.Has(syncer::HISTORY)) {
controllers.push_back(std::make_unique<history::HistoryModelTypeController>(
sync_service, sync_client_->GetIdentityManager(),
sync_client_->GetHistoryService(), sync_client_->GetPrefService()));
}
if (!disabled_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
controllers.push_back(
std::make_unique<history::HistoryDeleteDirectivesModelTypeController>(
dump_stack, sync_service, sync_client_->GetModelTypeStoreService(),
sync_client_->GetHistoryService(), sync_client_->GetPrefService()));
}
if (!disabled_types.Has(syncer::SESSIONS)) {
syncer::ModelTypeControllerDelegate* delegate =
sync_client_->GetSessionSyncService()->GetControllerDelegate().get();
auto full_sync_mode_delegate =
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate);
auto transport_mode_delegate =
base::FeatureList::IsEnabled(syncer::kReplaceSyncPromosWithSignInPromos)
? std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate)
: nullptr;
controllers.push_back(
std::make_unique<sync_sessions::SessionModelTypeController>(
sync_service, sync_client_->GetPrefService(),
std::move(full_sync_mode_delegate),
std::move(transport_mode_delegate)));
}
if (!disabled_types.Has(syncer::PASSWORDS)) {
if (profile_password_store_) {
// |profile_password_store_| can be null in tests.
controllers.push_back(
std::make_unique<password_manager::PasswordModelTypeController>(
profile_password_store_->CreateSyncControllerDelegate(),
account_password_store_
? account_password_store_->CreateSyncControllerDelegate()
: nullptr,
sync_client_->GetPrefService(),
sync_client_->GetIdentityManager(), sync_service));
// Couple password sharing invitations with password data type.
if (!disabled_types.Has(syncer::INCOMING_PASSWORD_SHARING_INVITATION) &&
sync_client_->GetPasswordReceiverService()) {
controllers.push_back(
std::make_unique<
password_manager::
IncomingPasswordSharingInvitationModelTypeController>(
sync_service, sync_client_->GetPasswordReceiverService(),
sync_client_->GetPrefService()));
}
if (!disabled_types.Has(syncer::OUTGOING_PASSWORD_SHARING_INVITATION) &&
sync_client_->GetPasswordSenderService()) {
controllers.push_back(
std::make_unique<
password_manager::
OutgoingPasswordSharingInvitationModelTypeController>(
sync_service, sync_client_->GetPasswordSenderService(),
sync_client_->GetPrefService()));
}
}
}
// `plus_address_webdata_service_` is null on iOS WebView.
if (!disabled_types.Has(syncer::PLUS_ADDRESS) &&
plus_address_webdata_service_ &&
base::FeatureList::IsEnabled(
plus_addresses::features::kPlusAddressesEnabled) &&
base::FeatureList::IsEnabled(syncer::kSyncPlusAddress)) {
controllers.push_back(std::make_unique<syncer::ModelTypeController>(
syncer::PLUS_ADDRESS,
/*delegate_for_full_sync_mode=*/
plus_address_webdata_service_->GetSyncControllerDelegate(),
/*delegate_for_transport_mode=*/
plus_address_webdata_service_->GetSyncControllerDelegate()));
}
if (!disabled_types.Has(syncer::PREFERENCES)) {
bool allow_transport_mode =
base::FeatureList::IsEnabled(
syncer::kReplaceSyncPromosWithSignInPromos) &&
base::FeatureList::IsEnabled(syncer::kEnablePreferencesAccountStorage);
controllers.push_back(
std::make_unique<SyncableServiceBasedModelTypeController>(
syncer::PREFERENCES,
sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
SyncableServiceForPrefs(sync_client_->GetPrefServiceSyncable(),
syncer::PREFERENCES),
dump_stack,
allow_transport_mode
? SyncableServiceBasedModelTypeController::DelegateMode::
kTransportModeWithSingleModel
: SyncableServiceBasedModelTypeController::DelegateMode::
kLegacyFullSyncModeOnly));
}
if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) {
bool allow_transport_mode =
base::FeatureList::IsEnabled(
syncer::kReplaceSyncPromosWithSignInPromos) &&
base::FeatureList::IsEnabled(syncer::kEnablePreferencesAccountStorage);
controllers.push_back(
std::make_unique<SyncableServiceBasedModelTypeController>(
syncer::PRIORITY_PREFERENCES,
sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
SyncableServiceForPrefs(sync_client_->GetPrefServiceSyncable(),
syncer::PRIORITY_PREFERENCES),
dump_stack,
allow_transport_mode
? SyncableServiceBasedModelTypeController::DelegateMode::
kTransportModeWithSingleModel
: SyncableServiceBasedModelTypeController::DelegateMode::
kLegacyFullSyncModeOnly));
}
if (!disabled_types.Has(syncer::READING_LIST)) {
// The transport-mode delegate may or may not be null depending on
// platform and feature toggle state.
syncer::ModelTypeControllerDelegate* delegate_for_transport_mode =
sync_client_->GetReadingListModel()
->GetSyncControllerDelegateForTransportMode()
.get();
controllers.push_back(std::make_unique<ModelTypeController>(
syncer::READING_LIST,
/*delegate_for_full_sync_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
sync_client_->GetReadingListModel()
->GetSyncControllerDelegate()
.get()),
/*delegate_for_transport_mode=*/
delegate_for_transport_mode
? std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate_for_transport_mode)
: nullptr));
}
if (!disabled_types.Has(syncer::USER_EVENTS)) {
controllers.push_back(
std::make_unique<syncer::UserEventModelTypeController>(
sync_service,
/*delegate_for_full_sync_mode=*/
CreateForwardingControllerDelegate(syncer::USER_EVENTS),
/*delegate_for_transport_mode=*/
base::FeatureList::IsEnabled(
syncer::kReplaceSyncPromosWithSignInPromos)
? CreateForwardingControllerDelegate(syncer::USER_EVENTS)
: nullptr));
}
if (!disabled_types.Has(syncer::SEND_TAB_TO_SELF)) {
syncer::ModelTypeControllerDelegate* delegate =
sync_client_->GetSendTabToSelfSyncService()
->GetControllerDelegate()
.get();
controllers.push_back(
std::make_unique<send_tab_to_self::SendTabToSelfModelTypeController>(
/*delegate_for_full_sync_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate),
/*delegate_for_transport_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate)));
}
if (!disabled_types.Has(syncer::USER_CONSENTS)) {
// Forward both full-sync and transport-only modes to the same delegate,
// since behavior for USER_CONSENTS does not differ (they are always
// persisted).
controllers.push_back(std::make_unique<ModelTypeController>(
syncer::USER_CONSENTS,
/*delegate_for_full_sync_mode=*/
CreateForwardingControllerDelegate(syncer::USER_CONSENTS),
/*delegate_for_transport_mode=*/
CreateForwardingControllerDelegate(syncer::USER_CONSENTS)));
}
#if !BUILDFLAG(IS_ANDROID)
if (base::FeatureList::IsEnabled(syncer::kSyncWebauthnCredentials) &&
!disabled_types.Has(syncer::WEBAUTHN_CREDENTIAL)) {
controllers.push_back(
std::make_unique<webauthn::PasskeyModelTypeController>(
sync_service,
/*delegate_for_full_sync_mode=*/
CreateForwardingControllerDelegate(syncer::WEBAUTHN_CREDENTIAL),
/*delegate_for_transport_mode=*/
CreateForwardingControllerDelegate(syncer::WEBAUTHN_CREDENTIAL)));
}
#endif
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
if (supervised_user_settings_service_) {
controllers.push_back(
std::make_unique<SupervisedUserSettingsModelTypeController>(
dump_stack,
sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
supervised_user_settings_service_->AsWeakPtr(),
sync_client_->GetPrefService()));
}
#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS)
// `data_sharing_service_` is null on iOS WebView.
if (data_sharing_service_ &&
base::FeatureList::IsEnabled(
data_sharing::features::kDataSharingFeature) &&
!disabled_types.Has(syncer::COLLABORATION_GROUP)) {
syncer::ModelTypeControllerDelegate* delegate =
data_sharing_service_->GetCollaborationGroupControllerDelegate().get();
controllers.push_back(std::make_unique<ModelTypeController>(
syncer::COLLABORATION_GROUP,
/*delegate_for_full_sync_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate),
/*delegate_for_transport_mode=*/
std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
delegate)));
}
return controllers;
}
std::unique_ptr<DataTypeManager>
SyncApiComponentFactoryImpl::CreateDataTypeManager(
const ModelTypeController::TypeMap* controllers,
const syncer::DataTypeEncryptionHandler* encryption_handler,
DataTypeManagerObserver* observer) {
return std::make_unique<DataTypeManagerImpl>(controllers, encryption_handler,
observer);
}
std::unique_ptr<syncer::SyncEngine>
SyncApiComponentFactoryImpl::CreateSyncEngine(
const std::string& name,
syncer::SyncInvalidationsService* sync_invalidation_service) {
return std::make_unique<syncer::SyncEngineImpl>(
name, sync_invalidation_service,
std::make_unique<browser_sync::ActiveDevicesProviderImpl>(
sync_client_->GetDeviceInfoSyncService()->GetDeviceInfoTracker(),
base::DefaultClock::GetInstance()),
std::make_unique<syncer::SyncTransportDataPrefs>(
sync_client_->GetPrefService()),
sync_client_->GetModelTypeStoreService()->GetSyncDataPath(),
engines_and_directory_deletion_thread_,
base::BindRepeating(&syncer::SyncClient::OnLocalSyncTransportDataCleared,
base::Unretained(sync_client_)));
}
bool SyncApiComponentFactoryImpl::HasTransportDataIncludingFirstSync() {
syncer::SyncTransportDataPrefs sync_transport_data_prefs(
sync_client_->GetPrefService());
// NOTE: Keep this logic consistent with how SyncEngineImpl reports
// is-first-sync.
return !sync_transport_data_prefs.GetLastSyncedTime().is_null();
}
void SyncApiComponentFactoryImpl::ClearAllTransportData() {
syncer::SyncTransportDataPrefs sync_transport_data_prefs(
sync_client_->GetPrefService());
// Clearing the Directory via DeleteLegacyDirectoryFilesAndNigoriStorage()
// means there's IO involved which may be considerable overhead if
// triggered consistently upon browser startup (which is the case for
// certain codepaths such as the user being signed out). To avoid that, prefs
// are used to determine whether it's worth it.
if (!sync_transport_data_prefs.GetCacheGuid().empty()) {
engines_and_directory_deletion_thread_->PostTask(
FROM_HERE,
base::BindOnce(
&syncer::DeleteLegacyDirectoryFilesAndNigoriStorage,
sync_client_->GetModelTypeStoreService()->GetSyncDataPath()));
}
sync_transport_data_prefs.ClearAll();
sync_client_->OnLocalSyncTransportDataCleared();
}
std::unique_ptr<syncer::ModelTypeControllerDelegate>
SyncApiComponentFactoryImpl::CreateForwardingControllerDelegate(
syncer::ModelType type) {
return std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
sync_client_->GetControllerDelegateForModelType(type).get());
}
std::unique_ptr<ModelTypeController>
SyncApiComponentFactoryImpl::CreateWalletModelTypeController(
syncer::ModelType type,
const base::RepeatingCallback<
base::WeakPtr<syncer::ModelTypeControllerDelegate>(
autofill::AutofillWebDataService*)>& delegate_from_web_data,
syncer::SyncService* sync_service,
bool with_transport_mode_support) {
// Transport mode should be supported, except for METADATA and OFFER where
// support is still work in progress, see crbug.com/1448894 and
// crbug.com/1448895.
CHECK(with_transport_mode_support ||
type == syncer::AUTOFILL_WALLET_METADATA ||
type == syncer::AUTOFILL_WALLET_OFFER);
auto delegate_for_full_sync_mode =
std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
db_thread_,
base::BindRepeating(delegate_from_web_data,
base::RetainedRef(web_data_service_on_disk_)));
auto delegate_for_transport_mode =
with_transport_mode_support
? std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
db_thread_, base::BindRepeating(
delegate_from_web_data,
base::RetainedRef(web_data_service_in_memory_)))
: nullptr;
return std::make_unique<AutofillWalletModelTypeController>(
type, std::move(delegate_for_full_sync_mode),
std::move(delegate_for_transport_mode), sync_client_->GetPrefService(),
sync_service);
}
} // namespace browser_sync