| // 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 <optional> | |
| #include <string> | |
| #include <utility> | |
| #include "base/check.h" | |
| #include "base/files/file_path.h" | |
| #include "base/no_destructor.h" | |
| #include "base/path_service.h" | |
| #include "base/syslog_logging.h" | |
| #include "base/task/sequenced_task_runner.h" | |
| #include "build/build_config.h" | |
| #include "chrome/browser/browser_process.h" | |
| #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" | |
| #include "chrome/browser/sync/glue/extensions_activity_monitor.h" | |
| #include "chrome/common/buildflags.h" | |
| #include "chrome/common/chrome_paths.h" | |
| #include "components/browser_sync/sync_engine_factory_impl.h" | |
| #include "components/network_time/network_time_tracker.h" | |
| #include "components/password_manager/core/browser/features/password_features.h" | |
| #include "components/prefs/pref_service.h" | |
| #include "components/supervised_user/core/browser/family_link_settings_service.h" | |
| #include "components/sync/base/pref_names.h" | |
| #include "components/sync/model/data_type_store_service.h" | |
| #include "components/sync/service/trusted_vault_synthetic_field_trial.h" | |
| #include "components/sync_device_info/device_info_sync_service.h" | |
| #include "components/trusted_vault/trusted_vault_server_constants.h" | |
| #include "components/trusted_vault/trusted_vault_service.h" | |
| #include "content/public/browser/browser_thread.h" | |
| namespace browser_sync { | |
| namespace { | |
| using content::BrowserThread; | |
| #if BUILDFLAG(IS_WIN) | |
| constexpr base::FilePath::CharType kLoopbackServerBackendFilename[] = | |
| FILE_PATH_LITERAL("profile.pb"); | |
| #endif // BUILDFLAG(IS_WIN) | |
| // A global variable is needed to detect multi-profile scenarios where more than | |
| // one profile try to register a synthetic field trial. Rather than using a | |
| // boolean, a struct is used to handle the case where the same profile is loaded | |
| // multiple times and tries to register the very same synthetic field trial | |
| // group (which shouldn't be considered a conflict). | |
| struct ProfileAndGroupName { | |
| base::FilePath profile_base_name; | |
| std::string group_name; | |
| friend bool operator==(const ProfileAndGroupName& lhs, | |
| const ProfileAndGroupName& rhs) = default; | |
| }; | |
| std::optional<ProfileAndGroupName>& GetRegisteredProfileAndGroupName() { | |
| static base::NoDestructor<std::optional<ProfileAndGroupName>> value; | |
| return *value; | |
| } | |
| } // namespace | |
| ChromeSyncClient::ChromeSyncClient( | |
| const base::FilePath& profile_base_name, | |
| PrefService* pref_service, | |
| signin::IdentityManager* identity_manager, | |
| trusted_vault::TrustedVaultService* trusted_vault_service, | |
| syncer::SyncInvalidationsService* sync_invalidations_service, | |
| syncer::DeviceInfoSyncService* device_info_sync_service, | |
| syncer::DataTypeStoreService* data_type_store_service, | |
| supervised_user::FamilyLinkSettingsService* family_link_settings_service, | |
| std::unique_ptr<ExtensionsActivityMonitor> extensions_activity_monitor) | |
| : profile_base_name_(profile_base_name), | |
| pref_service_(pref_service), | |
| identity_manager_(identity_manager), | |
| trusted_vault_service_(trusted_vault_service), | |
| sync_invalidations_service_(sync_invalidations_service), | |
| family_link_settings_service_(family_link_settings_service), | |
| extensions_activity_monitor_(std::move(extensions_activity_monitor)), | |
| engine_factory_(this, | |
| device_info_sync_service->GetDeviceInfoTracker(), | |
| data_type_store_service->GetSyncDataPath()) { | |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| } | |
| ChromeSyncClient::~ChromeSyncClient() = default; | |
| PrefService* ChromeSyncClient::GetPrefService() { | |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| return pref_service_; | |
| } | |
| signin::IdentityManager* ChromeSyncClient::GetIdentityManager() { | |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| return identity_manager_; | |
| } | |
| network_time::NetworkTimeTracker* ChromeSyncClient::GetNetworkTimeTracker() { | |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| return g_browser_process->network_time_tracker(); | |
| } | |
| 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/41291598 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_base_name_); | |
| local_sync_backend_folder = | |
| local_sync_backend_folder.Append(kLoopbackServerBackendFilename); | |
| #endif // BUILDFLAG(IS_WIN) | |
| return local_sync_backend_folder; | |
| } | |
| trusted_vault::TrustedVaultClient* ChromeSyncClient::GetTrustedVaultClient() { | |
| return trusted_vault_service_->GetTrustedVaultClient( | |
| trusted_vault::SecurityDomainId::kChromeSync); | |
| } | |
| syncer::SyncInvalidationsService* | |
| ChromeSyncClient::GetSyncInvalidationsService() { | |
| return sync_invalidations_service_; | |
| } | |
| scoped_refptr<syncer::ExtensionsActivity> | |
| ChromeSyncClient::GetExtensionsActivity() { | |
| return extensions_activity_monitor_->GetExtensionsActivity(); | |
| } | |
| syncer::SyncEngineFactory* ChromeSyncClient::GetSyncEngineFactory() { | |
| return &engine_factory_; | |
| } | |
| bool ChromeSyncClient::IsCustomPassphraseAllowed() { | |
| if (family_link_settings_service_) { | |
| return family_link_settings_service_->IsCustomPassphraseAllowed(); | |
| } | |
| return true; | |
| } | |
| void ChromeSyncClient::RegisterTrustedVaultAutoUpgradeSyntheticFieldTrial( | |
| const syncer::TrustedVaultAutoUpgradeSyntheticFieldTrialGroup& group) { | |
| CHECK(group.is_valid()); | |
| ProfileAndGroupName new_profile_and_group_name{profile_base_name_, | |
| group.name()}; | |
| std::optional<ProfileAndGroupName>& global_profile_and_group_name = | |
| GetRegisteredProfileAndGroupName(); | |
| // If a group is previously set, it may imply that a different profile has | |
| // just been loaded, as this function is invoked at most once per profile. | |
| // However, on some platforms (e.g. Mac), the same profile can be closed and | |
| // loaded once again, and this case should not count as a conflict case. | |
| const bool multi_profile_conflict = | |
| global_profile_and_group_name.has_value() && | |
| global_profile_and_group_name.value() != new_profile_and_group_name; | |
| // Use a special group name if a multi-profile conflict was detected. | |
| const std::string group_name = | |
| multi_profile_conflict | |
| ? syncer::TrustedVaultAutoUpgradeSyntheticFieldTrialGroup:: | |
| GetMultiProfileConflictGroupName() | |
| : group.name(); | |
| // If a conflict was detected, ensure that future runs of this function will | |
| // also report a conflict by using a pair that won't match future invocations | |
| // of this function. | |
| global_profile_and_group_name = | |
| multi_profile_conflict ? ProfileAndGroupName{base::FilePath(), group_name} | |
| : new_profile_and_group_name; | |
| ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial( | |
| syncer::kTrustedVaultAutoUpgradeSyntheticFieldTrialName, group_name, | |
| variations::SyntheticTrialAnnotationMode::kCurrentLog); | |
| } | |
| bool ChromeSyncClient::IsMetricsAndCrashReportingEnabled() { | |
| return ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(); | |
| } | |
| } // namespace browser_sync |