| // 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/sync/service/sync_prefs.h" | |
| #include <utility> | |
| #include "base/auto_reset.h" | |
| #include "base/base64.h" | |
| #include "base/check_op.h" | |
| #include "base/containers/to_vector.h" | |
| #include "base/feature_list.h" | |
| #include "base/files/file_path.h" | |
| #include "base/functional/bind.h" | |
| #include "base/notreached.h" | |
| #include "base/observer_list.h" | |
| #include "base/values.h" | |
| #include "build/build_config.h" | |
| #include "components/prefs/pref_registry_simple.h" | |
| #include "components/prefs/pref_service.h" | |
| #include "components/prefs/pref_value_map.h" | |
| #include "components/prefs/scoped_user_pref_update.h" | |
| #include "components/saved_tab_groups/public/pref_names.h" | |
| #include "components/signin/public/base/gaia_id_hash.h" | |
| #include "components/signin/public/base/signin_buildflags.h" | |
| #include "components/signin/public/base/signin_pref_names.h" | |
| #include "components/signin/public/base/signin_prefs.h" | |
| #include "components/signin/public/base/signin_switches.h" | |
| #include "components/sync/base/account_pref_utils.h" | |
| #include "components/sync/base/custom_passphrase_bootstrap_token.h" | |
| #include "components/sync/base/features.h" | |
| #include "components/sync/base/passphrase_enums.h" | |
| #include "components/sync/base/pref_names.h" | |
| #include "components/sync/base/user_selectable_type.h" | |
| #include "components/sync/protocol/nigori_specifics.pb.h" | |
| #include "components/sync/service/glue/sync_transport_data_prefs.h" | |
| #include "components/sync/service/sync_feature_status_for_migrations_recorder.h" | |
| #include "google_apis/gaia/gaia_id.h" | |
| namespace syncer { | |
| namespace { | |
| #if BUILDFLAG(ENABLE_DICE_SUPPORT) | |
| // Pref to record if the one-off MaybeMigrateAutofillToPerAccountPref() | |
| // migration ran. | |
| constexpr char kAutofillPerAccountPrefMigrationDone[] = | |
| "sync.passwords_per_account_pref_migration_done"; | |
| #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) | |
| constexpr int kNotMigrated = 0; | |
| constexpr int kMigratedPart1ButNot2 = 1; | |
| constexpr int kMigratedPart2AndFullyDone = 2; | |
| // Encodes a protobuf instance of type | |
| // sync_pb::TrustedVaultAutoUpgradeExperimentGroup in a way that can be safely | |
| // stored in prefs, i.e. using base64 encoding. | |
| std::string EncodeTrustedVaultAutoUpgradeExperimentGroupToString( | |
| const sync_pb::TrustedVaultAutoUpgradeExperimentGroup& group) { | |
| return base::Base64Encode(group.SerializeAsString()); | |
| } | |
| // Does the opposite of EncodeTrustedVaultAutoUpgradeExperimentGroupToString(), | |
| // i.e. transforms from a string representation to a protobuf instance. | |
| sync_pb::TrustedVaultAutoUpgradeExperimentGroup | |
| DecodeTrustedVaultAutoUpgradeExperimentGroupFromString( | |
| const std::string& encoded_group) { | |
| sync_pb::TrustedVaultAutoUpgradeExperimentGroup proto; | |
| std::string serialized_proto; | |
| if (!base::Base64Decode(encoded_group, &serialized_proto)) { | |
| return proto; | |
| } | |
| proto.ParseFromString(serialized_proto); | |
| return proto; | |
| } | |
| bool IsBookmarksSelectedByDefaultInTransportMode(PrefService& pref_service, | |
| const GaiaId& gaia_id) { | |
| #if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) | |
| return true; | |
| #else | |
| // Bookmarks and reading list are enabled by default for new sign-ins (not | |
| // pre-existing sessions). This pref is set if the above conditions are met. | |
| return SigninPrefs(pref_service).GetBookmarksExplicitBrowserSignin(gaia_id); | |
| #endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) | |
| } | |
| bool IsExtensionsSelectedByDefaultInTransportMode(PrefService& pref_service, | |
| const GaiaId& gaia_id) { | |
| #if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) | |
| return true; | |
| #else | |
| // Extensions are enabled by default for new sign-ins (not pre-existing | |
| // sessions). This pref is set if the above conditions are met. | |
| return SigninPrefs(pref_service).GetExtensionsExplicitBrowserSignin(gaia_id); | |
| #endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) | |
| } | |
| } // namespace | |
| SyncPrefObserver::~SyncPrefObserver() = default; | |
| SyncPrefs::SyncPrefs(PrefService* pref_service) | |
| : pref_service_(pref_service), | |
| local_sync_enabled_( | |
| pref_service_->GetBoolean(prefs::kEnableLocalSyncBackend)) { | |
| DCHECK(pref_service); | |
| // Watch the preference that indicates sync is managed so we can take | |
| // appropriate action. | |
| pref_sync_managed_.Init( | |
| prefs::internal::kSyncManaged, pref_service_, | |
| base::BindRepeating(&SyncPrefs::OnSyncManagedPrefChanged, | |
| base::Unretained(this))); | |
| // Observe changes to all of the prefs that may influence the selected types. | |
| pref_change_registrar_.Init(pref_service_); | |
| // The individual data type prefs are used for syncing users, as well as for | |
| // enterprise policy. | |
| for (UserSelectableType type : UserSelectableTypeSet::All()) { | |
| pref_change_registrar_.Add( | |
| GetPrefNameForType(type), | |
| base::BindRepeating(&SyncPrefs::OnSelectedTypesPrefChanged, | |
| base::Unretained(this))); | |
| } | |
| // The "sync everything" pref is used for syncing users. | |
| pref_change_registrar_.Add( | |
| prefs::internal::kSyncKeepEverythingSynced, | |
| base::BindRepeating(&SyncPrefs::OnSelectedTypesPrefChanged, | |
| base::Unretained(this))); | |
| // The per-account data types dictionary pref is used for signed-in | |
| // non-syncing users. | |
| pref_change_registrar_.Add( | |
| prefs::internal::kSelectedTypesPerAccount, | |
| base::BindRepeating(&SyncPrefs::OnSelectedTypesPrefChanged, | |
| base::Unretained(this))); | |
| #if BUILDFLAG(ENABLE_DICE_SUPPORT) | |
| // The explicit browser signin pref is used for determining whether some data | |
| // types are selected by default. Therefore, upon a change, the selected types | |
| // may change. | |
| pref_change_registrar_.Add( | |
| ::prefs::kExplicitBrowserSignin, | |
| base::BindRepeating(&SyncPrefs::OnSelectedTypesPrefChanged, | |
| base::Unretained(this))); | |
| #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) | |
| } | |
| SyncPrefs::~SyncPrefs() { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| } | |
| // static | |
| void SyncPrefs::RegisterProfilePrefs(PrefRegistrySimple* registry) { | |
| // Actual user-controlled preferences. | |
| registry->RegisterBooleanPref(prefs::internal::kSyncKeepEverythingSynced, | |
| true); | |
| registry->RegisterDictionaryPref(prefs::internal::kSelectedTypesPerAccount); | |
| for (UserSelectableType type : UserSelectableTypeSet::All()) { | |
| RegisterTypeSelectedPref(registry, type); | |
| } | |
| #if BUILDFLAG(IS_CHROMEOS) | |
| registry->RegisterBooleanPref(prefs::internal::kSyncDisabledViaDashboard, | |
| false); | |
| registry->RegisterBooleanPref(prefs::internal::kSyncAllOsTypes, true); | |
| registry->RegisterBooleanPref(prefs::internal::kSyncOsApps, false); | |
| registry->RegisterBooleanPref(prefs::internal::kSyncOsPreferences, false); | |
| registry->RegisterBooleanPref(prefs::internal::kSyncWifiConfigurations, | |
| false); | |
| #else // BUILDFLAG(IS_CHROMEOS) | |
| registry->RegisterBooleanPref( | |
| prefs::internal::kSyncInitialSyncFeatureSetupComplete, false); | |
| #endif // BUILDFLAG(IS_CHROMEOS) | |
| registry->RegisterIntegerPref(prefs::internal::kSyncToSigninMigrationState, | |
| kNotMigrated); | |
| registry->RegisterBooleanPref( | |
| prefs::internal::kMigrateReadingListFromLocalToAccount, false); | |
| registry->RegisterBooleanPref( | |
| prefs::internal::kMigrateExtensionsFromLocalToAccount, false); | |
| registry->RegisterBooleanPref( | |
| prefs::internal::kMigrateThemeFromLocalToAccount, false); | |
| #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) | |
| registry->RegisterBooleanPref( | |
| prefs::internal::kReadingListPrefMigratedToAccount, false); | |
| #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) | |
| registry->RegisterBooleanPref( | |
| prefs::kCleanUpStatsTableFromAccountPasswordStore, false); | |
| // The passphrase type, determined upon the first engine initialization. | |
| registry->RegisterIntegerPref( | |
| prefs::internal::kSyncCachedPassphraseType, | |
| sync_pb::NigoriSpecifics_PassphraseType_UNKNOWN); | |
| // The user's TrustedVaultAutoUpgradeExperimentGroup, determined the first | |
| // time the engine is successfully initialized. | |
| registry->RegisterStringPref( | |
| prefs::internal::kSyncCachedTrustedVaultAutoUpgradeExperimentGroup, ""); | |
| // Cached notion of whether or not a persistent auth error exists. | |
| registry->RegisterBooleanPref( | |
| prefs::internal::kSyncCachedPersistentAuthErrorForMetrics, false); | |
| // The encryption bootstrap token represents a user-entered passphrase per | |
| // account. | |
| registry->RegisterDictionaryPref( | |
| prefs::internal::kSyncEncryptionBootstrapTokenPerAccount); | |
| registry->RegisterBooleanPref(prefs::internal::kSyncManaged, false); | |
| registry->RegisterIntegerPref( | |
| prefs::internal::kSyncPassphrasePromptMutedProductVersion, 0); | |
| registry->RegisterBooleanPref(prefs::kEnableLocalSyncBackend, false); | |
| registry->RegisterFilePathPref(prefs::kLocalSyncBackendDir, base::FilePath()); | |
| #if BUILDFLAG(ENABLE_DICE_SUPPORT) | |
| registry->RegisterBooleanPref(kAutofillPerAccountPrefMigrationDone, false); | |
| #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) | |
| registry->RegisterTimePref( | |
| prefs::internal::kFirstTimeTriedToMigrateSyncFeaturePausedToSignin, | |
| base::Time()); | |
| #if !BUILDFLAG(IS_CHROMEOS) | |
| registry->RegisterBooleanPref(prefs::internal::kWipedAppsAndAppSettingsData, | |
| false); | |
| #endif // !BUILDFLAG(IS_CHROMEOS) | |
| SyncFeatureStatusForMigrationsRecorder::RegisterProfilePrefs(registry); | |
| } | |
| void SyncPrefs::AddObserver(SyncPrefObserver* sync_pref_observer) { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| sync_pref_observers_.AddObserver(sync_pref_observer); | |
| } | |
| void SyncPrefs::RemoveObserver(SyncPrefObserver* sync_pref_observer) { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| sync_pref_observers_.RemoveObserver(sync_pref_observer); | |
| } | |
| bool SyncPrefs::IsInitialSyncFeatureSetupComplete() const { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| #if BUILDFLAG(IS_CHROMEOS) | |
| return true; | |
| #else // BUILDFLAG(IS_CHROMEOS) | |
| return pref_service_->GetBoolean( | |
| prefs::internal::kSyncInitialSyncFeatureSetupComplete); | |
| #endif // BUILDFLAG(IS_CHROMEOS) | |
| } | |
| #if !BUILDFLAG(IS_CHROMEOS) | |
| void SyncPrefs::SetInitialSyncFeatureSetupComplete() { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| pref_service_->SetBoolean( | |
| prefs::internal::kSyncInitialSyncFeatureSetupComplete, true); | |
| } | |
| void SyncPrefs::ClearInitialSyncFeatureSetupComplete() { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| pref_service_->ClearPref( | |
| prefs::internal::kSyncInitialSyncFeatureSetupComplete); | |
| } | |
| #endif // !BUILDFLAG(IS_CHROMEOS) | |
| bool SyncPrefs::HasKeepEverythingSynced() const { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| return pref_service_->GetBoolean(prefs::internal::kSyncKeepEverythingSynced); | |
| } | |
| UserSelectableTypeSet SyncPrefs::GetSelectedTypesForAccount( | |
| const GaiaId& gaia_id) const { | |
| const signin::GaiaIdHash gaia_id_hash = | |
| signin::GaiaIdHash::FromGaiaId(gaia_id); | |
| UserSelectableTypeSet selected_types; | |
| for (UserSelectableType type : UserSelectableTypeSet::All()) { | |
| if (!IsTypeSupportedInTransportMode(type)) { | |
| continue; | |
| } | |
| const char* pref_name = GetPrefNameForType(type); | |
| DCHECK(pref_name); | |
| bool type_enabled = false; | |
| if (IsTypeManagedByPolicy(type) || IsTypeManagedByCustodian(type)) { | |
| type_enabled = pref_service_->GetBoolean(pref_name); | |
| } else { | |
| const base::Value* pref_value = GetAccountKeyedPrefDictEntry( | |
| pref_service_, prefs::internal::kSelectedTypesPerAccount, | |
| gaia_id_hash, pref_name); | |
| if (pref_value && pref_value->is_bool()) { | |
| type_enabled = pref_value->GetBool(); | |
| } else { | |
| type_enabled = IsTypeSelectedByDefaultInTransportMode(type, gaia_id); | |
| } | |
| } | |
| if (type_enabled) { | |
| selected_types.Put(type); | |
| } | |
| } | |
| return selected_types; | |
| } | |
| UserSelectableTypeSet SyncPrefs::GetSelectedTypesForSyncingUser() const { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| UserSelectableTypeSet selected_types; | |
| for (UserSelectableType type : UserSelectableTypeSet::All()) { | |
| const char* pref_name = GetPrefNameForType(type); | |
| DCHECK(pref_name); | |
| if (pref_service_->GetBoolean(pref_name) || | |
| (!IsTypeManagedByPolicy(type) && !IsTypeManagedByCustodian(type) && | |
| pref_service_->GetBoolean( | |
| prefs::internal::kSyncKeepEverythingSynced))) { | |
| // In full-sync mode, the "sync everything" bit is honored. If it's | |
| // true, all types are considered selected, irrespective of their | |
| // individual prefs. | |
| selected_types.Put(type); | |
| } | |
| } | |
| return selected_types; | |
| } | |
| bool SyncPrefs::IsTypeManagedByPolicy(UserSelectableType type) const { | |
| const char* pref_name = GetPrefNameForType(type); | |
| CHECK(pref_name); | |
| return pref_service_->IsManagedPreference(pref_name); | |
| } | |
| bool SyncPrefs::IsTypeManagedByCustodian(UserSelectableType type) const { | |
| const char* pref_name = GetPrefNameForType(type); | |
| CHECK(pref_name); | |
| return pref_service_->IsPreferenceManagedByCustodian(pref_name); | |
| } | |
| bool SyncPrefs::DoesTypeHaveDefaultValueForAccount( | |
| const UserSelectableType type, | |
| const GaiaId& gaia_id) { | |
| const char* pref_name = GetPrefNameForType(type); | |
| DCHECK(pref_name); | |
| const base::Value* value = GetAccountKeyedPrefDictEntry( | |
| pref_service_, prefs::internal::kSelectedTypesPerAccount, | |
| signin::GaiaIdHash::FromGaiaId(gaia_id), pref_name); | |
| return !value; | |
| } | |
| bool SyncPrefs::IsTypeDisabledByUserForAccount(const UserSelectableType type, | |
| const GaiaId& gaia_id) { | |
| const char* pref_name = GetPrefNameForType(type); | |
| DCHECK(pref_name); | |
| const base::Value* value = GetAccountKeyedPrefDictEntry( | |
| pref_service_, prefs::internal::kSelectedTypesPerAccount, | |
| signin::GaiaIdHash::FromGaiaId(gaia_id), pref_name); | |
| if (value && value->is_bool()) { | |
| return !value->GetBool(); | |
| } | |
| return false; | |
| } | |
| void SyncPrefs::SetSelectedTypesForSyncingUser( | |
| bool keep_everything_synced, | |
| UserSelectableTypeSet registered_types, | |
| UserSelectableTypeSet selected_types) { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| { | |
| // Prevent OnSelectedTypesPrefChanged() from notifying observers about each | |
| // of the type changes individually. | |
| base::AutoReset<bool> batch_update(&batch_updating_selected_types_, true); | |
| pref_service_->SetBoolean(prefs::internal::kSyncKeepEverythingSynced, | |
| keep_everything_synced); | |
| for (UserSelectableType type : registered_types) { | |
| const char* pref_name = GetPrefNameForType(type); | |
| pref_service_->SetBoolean(pref_name, selected_types.Has(type)); | |
| } | |
| } | |
| for (SyncPrefObserver& observer : sync_pref_observers_) { | |
| observer.OnSelectedTypesPrefChange(); | |
| } | |
| } | |
| void SyncPrefs::SetSelectedTypeForAccount(UserSelectableType type, | |
| bool is_type_on, | |
| const GaiaId& gaia_id) { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| CHECK(!gaia_id.empty()); | |
| SetAccountKeyedPrefDictEntry( | |
| pref_service_, prefs::internal::kSelectedTypesPerAccount, | |
| signin::GaiaIdHash::FromGaiaId(gaia_id), GetPrefNameForType(type), | |
| base::Value(is_type_on)); | |
| } | |
| void SyncPrefs::ResetSelectedTypeForAccount(UserSelectableType type, | |
| const GaiaId& gaia_id) { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| RemoveAccountKeyedPrefDictEntry( | |
| pref_service_, prefs::internal::kSelectedTypesPerAccount, | |
| signin::GaiaIdHash::FromGaiaId(gaia_id), GetPrefNameForType(type)); | |
| } | |
| void SyncPrefs::KeepAccountSettingsPrefsOnlyForUsers( | |
| const std::vector<GaiaId>& available_gaia_ids) { | |
| std::vector<signin::GaiaIdHash> hashes = | |
| base::ToVector(available_gaia_ids, &signin::GaiaIdHash::FromGaiaId); | |
| KeepAccountKeyedPrefValuesOnlyForUsers( | |
| pref_service_, prefs::internal::kSelectedTypesPerAccount, hashes); | |
| KeepAccountKeyedPrefValuesOnlyForUsers( | |
| pref_service_, prefs::internal::kSyncEncryptionBootstrapTokenPerAccount, | |
| hashes); | |
| // TODO(crbug.com/368409110): This is not the right place for clearing | |
| // transport-data-related prefs - ideally there'd be an observer API for | |
| // "accounts on this device". | |
| SyncTransportDataPrefs::KeepAccountSettingsPrefsOnlyForUsers(pref_service_, | |
| hashes); | |
| // TODO(crbug.com/368409110): This is *absolutely* not the right place for | |
| // clearing not-sync-related prefs. Move this elsewhere once signin code | |
| // provides an observer API for "accounts on this device". | |
| tab_groups::prefs::KeepAccountSettingsPrefsOnlyForUsers(pref_service_, | |
| hashes); | |
| } | |
| #if BUILDFLAG(IS_CHROMEOS) | |
| bool SyncPrefs::IsSyncFeatureDisabledViaDashboard() const { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| return pref_service_->GetBoolean(prefs::internal::kSyncDisabledViaDashboard); | |
| } | |
| void SyncPrefs::SetSyncFeatureDisabledViaDashboard() { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| pref_service_->SetBoolean(prefs::internal::kSyncDisabledViaDashboard, true); | |
| } | |
| void SyncPrefs::ClearSyncFeatureDisabledViaDashboard() { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| pref_service_->ClearPref(prefs::internal::kSyncDisabledViaDashboard); | |
| } | |
| bool SyncPrefs::IsSyncAllOsTypesEnabled() const { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| return pref_service_->GetBoolean(prefs::internal::kSyncAllOsTypes); | |
| } | |
| UserSelectableOsTypeSet SyncPrefs::GetSelectedOsTypes() const { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| UserSelectableOsTypeSet selected_types; | |
| const bool sync_all_os_types = IsSyncAllOsTypesEnabled(); | |
| for (UserSelectableOsType type : UserSelectableOsTypeSet::All()) { | |
| const char* pref_name = GetPrefNameForOsType(type); | |
| DCHECK(pref_name); | |
| // If the type is managed, `sync_all_os_types` is ignored for this type. | |
| if (pref_service_->GetBoolean(pref_name) || | |
| (sync_all_os_types && !IsOsTypeManagedByPolicy(type))) { | |
| selected_types.Put(type); | |
| } | |
| } | |
| return selected_types; | |
| } | |
| bool SyncPrefs::IsOsTypeManagedByPolicy(UserSelectableOsType type) const { | |
| const char* pref_name = GetPrefNameForOsType(type); | |
| CHECK(pref_name); | |
| return pref_service_->IsManagedPreference(pref_name); | |
| } | |
| void SyncPrefs::SetSelectedOsTypes(bool sync_all_os_types, | |
| UserSelectableOsTypeSet registered_types, | |
| UserSelectableOsTypeSet selected_types) { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| { | |
| // Prevent OnSelectedTypesPrefChanged() from notifying about each of the | |
| // type changes individually. | |
| base::AutoReset<bool> batch_update(&batch_updating_selected_types_, true); | |
| pref_service_->SetBoolean(prefs::internal::kSyncAllOsTypes, | |
| sync_all_os_types); | |
| for (UserSelectableOsType type : registered_types) { | |
| const char* pref_name = GetPrefNameForOsType(type); | |
| DCHECK(pref_name); | |
| pref_service_->SetBoolean(pref_name, selected_types.Has(type)); | |
| } | |
| } | |
| for (SyncPrefObserver& observer : sync_pref_observers_) { | |
| observer.OnSelectedTypesPrefChange(); | |
| } | |
| } | |
| // static | |
| const char* SyncPrefs::GetPrefNameForOsTypeForTesting( | |
| UserSelectableOsType type) { | |
| return GetPrefNameForOsType(type); | |
| } | |
| // static | |
| const char* SyncPrefs::GetPrefNameForOsType(UserSelectableOsType type) { | |
| switch (type) { | |
| case UserSelectableOsType::kOsApps: | |
| return prefs::internal::kSyncOsApps; | |
| case UserSelectableOsType::kOsPreferences: | |
| return prefs::internal::kSyncOsPreferences; | |
| case UserSelectableOsType::kOsWifiConfigurations: | |
| return prefs::internal::kSyncWifiConfigurations; | |
| } | |
| NOTREACHED(); | |
| } | |
| // static | |
| void SyncPrefs::SetOsTypeDisabledByPolicy(PrefValueMap* policy_prefs, | |
| UserSelectableOsType type) { | |
| const char* pref_name = syncer::SyncPrefs::GetPrefNameForOsType(type); | |
| CHECK(pref_name); | |
| policy_prefs->SetValue(pref_name, base::Value(false)); | |
| } | |
| #endif // BUILDFLAG(IS_CHROMEOS) | |
| bool SyncPrefs::IsSyncClientDisabledByPolicy() const { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| return pref_service_->GetBoolean(prefs::internal::kSyncManaged); | |
| } | |
| std::optional<PassphraseType> SyncPrefs::GetCachedPassphraseType() const { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| return ProtoPassphraseInt32ToEnum( | |
| pref_service_->GetInteger(prefs::internal::kSyncCachedPassphraseType)); | |
| } | |
| void SyncPrefs::SetCachedPassphraseType(PassphraseType passphrase_type) { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| pref_service_->SetInteger(prefs::internal::kSyncCachedPassphraseType, | |
| EnumPassphraseTypeToProto(passphrase_type)); | |
| } | |
| void SyncPrefs::ClearCachedPassphraseType() { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| pref_service_->ClearPref(prefs::internal::kSyncCachedPassphraseType); | |
| } | |
| bool SyncPrefs::HasCachedPersistentAuthErrorForMetrics() const { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| return pref_service_->GetBoolean( | |
| prefs::internal::kSyncCachedPersistentAuthErrorForMetrics); | |
| } | |
| void SyncPrefs::SetHasCachedPersistentAuthErrorForMetrics( | |
| bool has_persistent_auth_error) { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| pref_service_->SetBoolean( | |
| prefs::internal::kSyncCachedPersistentAuthErrorForMetrics, | |
| has_persistent_auth_error); | |
| } | |
| void SyncPrefs::ClearCachedPersistentAuthErrorForMetrics() { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| pref_service_->ClearPref( | |
| prefs::internal::kSyncCachedPersistentAuthErrorForMetrics); | |
| } | |
| std::optional<sync_pb::TrustedVaultAutoUpgradeExperimentGroup> | |
| SyncPrefs::GetCachedTrustedVaultAutoUpgradeExperimentGroup() const { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| const std::string& encoded_group = pref_service_->GetString( | |
| prefs::internal::kSyncCachedTrustedVaultAutoUpgradeExperimentGroup); | |
| if (encoded_group.empty()) { | |
| return std::nullopt; | |
| } | |
| return DecodeTrustedVaultAutoUpgradeExperimentGroupFromString(encoded_group); | |
| } | |
| void SyncPrefs::SetCachedTrustedVaultAutoUpgradeExperimentGroup( | |
| const sync_pb::TrustedVaultAutoUpgradeExperimentGroup& group) { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| pref_service_->SetString( | |
| prefs::internal::kSyncCachedTrustedVaultAutoUpgradeExperimentGroup, | |
| EncodeTrustedVaultAutoUpgradeExperimentGroupToString(group)); | |
| } | |
| void SyncPrefs::ClearCachedTrustedVaultAutoUpgradeExperimentGroup() { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| pref_service_->ClearPref( | |
| prefs::internal::kSyncCachedTrustedVaultAutoUpgradeExperimentGroup); | |
| } | |
| void SyncPrefs::ClearAllEncryptionBootstrapTokens() { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| if (IsInitialSyncFeatureSetupComplete()) { | |
| // When Sync-the-feature gets turned off, the user's encryption bootstrap | |
| // token should be cleared. However, at this point it's hard to determine | |
| // the right account, since the user is already signed out. For simplicity, | |
| // just clear all existing bootstrap tokens (in practice, there will almost | |
| // always be at most one anyway). | |
| KeepAccountKeyedPrefValuesOnlyForUsers( | |
| pref_service_, prefs::internal::kSyncEncryptionBootstrapTokenPerAccount, | |
| {}); | |
| } | |
| } | |
| CustomPassphraseBootstrapToken SyncPrefs::GetEncryptionBootstrapTokenForAccount( | |
| const os_crypt_async::Encryptor& encryptor, | |
| const GaiaId& gaia_id) const { | |
| if (gaia_id.empty()) { | |
| return CustomPassphraseBootstrapToken(); | |
| } | |
| const std::string* account_passphrase = | |
| pref_service_ | |
| ->GetDict(prefs::internal::kSyncEncryptionBootstrapTokenPerAccount) | |
| .FindString(signin::GaiaIdHash::FromGaiaId(gaia_id).ToBase64()); | |
| if (!account_passphrase) { | |
| return CustomPassphraseBootstrapToken(); | |
| } | |
| return CustomPassphraseBootstrapToken::FromEncryptedPref(*account_passphrase, | |
| encryptor); | |
| } | |
| void SyncPrefs::SetEncryptionBootstrapTokenForAccount( | |
| const CustomPassphraseBootstrapToken& token, | |
| const os_crypt_async::Encryptor& encryptor, | |
| const GaiaId& gaia_id) { | |
| CHECK(!gaia_id.empty()); | |
| SetAccountKeyedPrefValue( | |
| pref_service_, prefs::internal::kSyncEncryptionBootstrapTokenPerAccount, | |
| signin::GaiaIdHash::FromGaiaId(gaia_id), | |
| base::Value(token.ToEncryptedPref(encryptor))); | |
| } | |
| void SyncPrefs::ClearEncryptionBootstrapTokenForAccount(const GaiaId& gaia_id) { | |
| ClearAccountKeyedPrefValue( | |
| pref_service_, prefs::internal::kSyncEncryptionBootstrapTokenPerAccount, | |
| signin::GaiaIdHash::FromGaiaId(gaia_id)); | |
| } | |
| // static | |
| const char* SyncPrefs::GetPrefNameForTypeForTesting(UserSelectableType type) { | |
| return GetPrefNameForType(type); | |
| } | |
| // static | |
| const char* SyncPrefs::GetPrefNameForType(UserSelectableType type) { | |
| switch (type) { | |
| case UserSelectableType::kBookmarks: | |
| return prefs::internal::kSyncBookmarks; | |
| case UserSelectableType::kPreferences: | |
| return prefs::internal::kSyncPreferences; | |
| case UserSelectableType::kPasswords: | |
| return prefs::internal::kSyncPasswords; | |
| case UserSelectableType::kAutofill: | |
| return prefs::internal::kSyncAutofill; | |
| case UserSelectableType::kThemes: | |
| return prefs::internal::kSyncThemes; | |
| case UserSelectableType::kHistory: | |
| return prefs::internal::kSyncHistory; | |
| case UserSelectableType::kExtensions: | |
| return prefs::internal::kSyncExtensions; | |
| case UserSelectableType::kApps: | |
| return prefs::internal::kSyncApps; | |
| case UserSelectableType::kReadingList: | |
| return prefs::internal::kSyncReadingList; | |
| case UserSelectableType::kTabs: | |
| return prefs::internal::kSyncTabs; | |
| case UserSelectableType::kSavedTabGroups: | |
| return prefs::internal::kSyncSavedTabGroups; | |
| case UserSelectableType::kPayments: | |
| return prefs::internal::kSyncPayments; | |
| case UserSelectableType::kProductComparison: | |
| return prefs::internal::kSyncProductComparison; | |
| case UserSelectableType::kCookies: | |
| return prefs::internal::kSyncCookies; | |
| } | |
| NOTREACHED(); | |
| } | |
| // static | |
| void SyncPrefs::SetTypeDisabledByPolicy(PrefValueMap* policy_prefs, | |
| UserSelectableType type) { | |
| const char* pref_name = syncer::SyncPrefs::GetPrefNameForType(type); | |
| CHECK(pref_name); | |
| CHECK(policy_prefs); | |
| policy_prefs->SetValue(pref_name, base::Value(false)); | |
| } | |
| // static void | |
| void SyncPrefs::SetTypeDisabledByCustodian(PrefValueMap* supervised_user_prefs, | |
| UserSelectableType type) { | |
| const char* pref_name = syncer::SyncPrefs::GetPrefNameForType(type); | |
| CHECK(pref_name); | |
| CHECK(supervised_user_prefs); | |
| supervised_user_prefs->SetValue(pref_name, base::Value(false)); | |
| } | |
| // static | |
| bool SyncPrefs::IsTypeSupportedInTransportMode(UserSelectableType type) { | |
| // Not all types are supported in transport mode, and many require one or more | |
| // Features to be enabled. | |
| switch (type) { | |
| case UserSelectableType::kBookmarks: | |
| return base::FeatureList::IsEnabled( | |
| switches::kSyncEnableBookmarksInTransportMode); | |
| case UserSelectableType::kReadingList: | |
| return true; | |
| case UserSelectableType::kPreferences: | |
| return base::FeatureList::IsEnabled( | |
| switches::kEnablePreferencesAccountStorage); | |
| case UserSelectableType::kPasswords: | |
| return true; | |
| case UserSelectableType::kAutofill: | |
| return true; | |
| case UserSelectableType::kPayments: | |
| // Always supported, since AUTOFILL_WALLET_DATA is supported in | |
| // transport mode everywhere. | |
| return true; | |
| case UserSelectableType::kHistory: | |
| case UserSelectableType::kTabs: | |
| case UserSelectableType::kProductComparison: | |
| case UserSelectableType::kSavedTabGroups: | |
| case UserSelectableType::kExtensions: | |
| return true; | |
| case UserSelectableType::kThemes: | |
| #if BUILDFLAG(IS_ANDROID) | |
| return base::FeatureList::IsEnabled( | |
| syncer::kNewTabPageCustomizationThemeSync); | |
| #elif BUILDFLAG(IS_IOS) | |
| // Allow 'Themes' toggle on iOS if the feature is enabled. | |
| return base::FeatureList::IsEnabled(syncer::kSyncThemesIos); | |
| #else | |
| return true; | |
| #endif | |
| case UserSelectableType::kApps: | |
| return true; | |
| case UserSelectableType::kCookies: | |
| #if BUILDFLAG(IS_CHROMEOS) | |
| return true; | |
| #else | |
| // ChromeOS-only type. | |
| return false; | |
| #endif | |
| } | |
| NOTREACHED(); | |
| } | |
| void SyncPrefs::OnSyncManagedPrefChanged() { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| for (SyncPrefObserver& observer : sync_pref_observers_) { | |
| observer.OnSyncManagedPrefChange(*pref_sync_managed_); | |
| } | |
| } | |
| void SyncPrefs::OnSelectedTypesPrefChanged(const std::string& pref_name) { | |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
| // If there is a batch update of selected-types prefs ongoing, don't notify | |
| // observers - the call site will take care of it. | |
| if (batch_updating_selected_types_) { | |
| return; | |
| } | |
| for (SyncPrefObserver& observer : sync_pref_observers_) { | |
| observer.OnSelectedTypesPrefChange(); | |
| } | |
| } | |
| // static | |
| void SyncPrefs::RegisterTypeSelectedPref(PrefRegistrySimple* registry, | |
| UserSelectableType type) { | |
| const char* pref_name = GetPrefNameForType(type); | |
| DCHECK(pref_name); | |
| registry->RegisterBooleanPref(pref_name, false); | |
| } | |
| bool SyncPrefs::IsLocalSyncEnabled() const { | |
| return local_sync_enabled_; | |
| } | |
| int SyncPrefs::GetPassphrasePromptMutedProductVersion() const { | |
| return pref_service_->GetInteger( | |
| prefs::internal::kSyncPassphrasePromptMutedProductVersion); | |
| } | |
| void SyncPrefs::SetPassphrasePromptMutedProductVersion(int major_version) { | |
| pref_service_->SetInteger( | |
| prefs::internal::kSyncPassphrasePromptMutedProductVersion, major_version); | |
| } | |
| void SyncPrefs::ClearPassphrasePromptMutedProductVersion() { | |
| pref_service_->ClearPref( | |
| prefs::internal::kSyncPassphrasePromptMutedProductVersion); | |
| } | |
| bool SyncPrefs::MaybeMigratePrefsForSyncToSigninPart1( | |
| SyncAccountState account_state, | |
| const GaiaId& gaia_id) { | |
| // Don't migrate again if this profile was previously migrated. | |
| if (pref_service_->GetInteger(prefs::internal::kSyncToSigninMigrationState) != | |
| kNotMigrated) { | |
| return false; | |
| } | |
| if (IsLocalSyncEnabled()) { | |
| // Special case for local sync: There isn't necessarily a signed-in user | |
| // (even if the SyncAccountState is kSyncing), so just mark the migration as | |
| // done. | |
| pref_service_->SetInteger(prefs::internal::kSyncToSigninMigrationState, | |
| kMigratedPart2AndFullyDone); | |
| return false; | |
| } | |
| switch (account_state) { | |
| case SyncAccountState::kNotSignedIn: | |
| case SyncAccountState::kSyncing: { | |
| // Nothing to migrate for signed-out or syncing users. Also make sure the | |
| // second part of the migration does *not* run if a signed-out user does | |
| // later sign in / turn on sync. | |
| pref_service_->SetInteger(prefs::internal::kSyncToSigninMigrationState, | |
| kMigratedPart2AndFullyDone); | |
| return false; | |
| } | |
| case SyncAccountState::kSignedInWithoutSyncConsent: { | |
| pref_service_->SetInteger(prefs::internal::kSyncToSigninMigrationState, | |
| kMigratedPart1ButNot2); | |
| CHECK(!gaia_id.empty()); | |
| ScopedDictPrefUpdate update_selected_types_dict( | |
| pref_service_, prefs::internal::kSelectedTypesPerAccount); | |
| base::DictValue* account_settings = | |
| update_selected_types_dict->EnsureDict( | |
| signin::GaiaIdHash::FromGaiaId(gaia_id).ToBase64()); | |
| #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) | |
| // Preserve the user's existing enabled state for Bookmarks, Reading List, | |
| // and Preferences. Otherwise, use the default value, which is true. | |
| for (UserSelectableType type : | |
| {UserSelectableType::kBookmarks, UserSelectableType::kReadingList, | |
| UserSelectableType::kPreferences}) { | |
| const char* pref_name = GetPrefNameForType(type); | |
| DCHECK(pref_name); | |
| const base::Value* value = account_settings->Find(pref_name); | |
| if (value && value->is_bool()) { | |
| account_settings->Set(pref_name, value->GetBool()); | |
| } | |
| } | |
| #else | |
| // Settings aka preferences always starts out "off" for existing | |
| // signed-in non-syncing users. | |
| account_settings->Set( | |
| GetPrefNameForType(UserSelectableType::kPreferences), false); | |
| // Bookmarks and reading list remain enabled only if the user previously | |
| // explicitly opted in, which is represented in the regular account-keyed | |
| // prefs. However, the default value for new sign-ins is enabled, so it is | |
| // important to grab a snapshot now during migration. | |
| for (UserSelectableType type : | |
| {UserSelectableType::kBookmarks, UserSelectableType::kReadingList}) { | |
| const char* pref_name = GetPrefNameForType(type); | |
| DCHECK(pref_name); | |
| const base::Value* value = account_settings->Find(pref_name); | |
| const bool is_type_on = value && value->is_bool() && value->GetBool(); | |
| // Setting the value explicitly is important to convert absence to | |
| // false, so it doesn't use the default, which is enabled. | |
| account_settings->Set(pref_name, is_type_on); | |
| } | |
| #endif | |
| return true; | |
| } | |
| } | |
| } | |
| bool SyncPrefs::MaybeMigratePrefsForSyncToSigninPart2( | |
| const GaiaId& gaia_id, | |
| bool is_using_explicit_passphrase) { | |
| // Only run part 2 of the migration if part 1 has run but part 2 hasn't yet. | |
| // This ensures that it only runs once. | |
| if (pref_service_->GetInteger(prefs::internal::kSyncToSigninMigrationState) != | |
| kMigratedPart1ButNot2) { | |
| return false; | |
| } | |
| pref_service_->SetInteger(prefs::internal::kSyncToSigninMigrationState, | |
| kMigratedPart2AndFullyDone); | |
| // The actual migration: For explicit-passphrase users, addresses sync gets | |
| // disabled by default. | |
| if (is_using_explicit_passphrase && !IsLocalSyncEnabled()) { | |
| CHECK(!gaia_id.empty()); | |
| SetAccountKeyedPrefDictEntry( | |
| pref_service_, prefs::internal::kSelectedTypesPerAccount, | |
| signin::GaiaIdHash::FromGaiaId(gaia_id), | |
| GetPrefNameForType(UserSelectableType::kAutofill), base::Value(false)); | |
| return true; | |
| } | |
| return false; | |
| } | |
| // static | |
| void SyncPrefs::MigrateGlobalDataTypePrefsToAccount(PrefService* pref_service, | |
| const GaiaId& gaia_id) { | |
| CHECK(!gaia_id.empty()); | |
| // Note: This method does *not* ensure that the migration only runs once - | |
| // that's the caller's responsibility! (In practice, that's | |
| // MaybeMigrateSyncingUserToSignedIn()). | |
| ScopedDictPrefUpdate update_selected_types_dict( | |
| pref_service, prefs::internal::kSelectedTypesPerAccount); | |
| base::DictValue* account_settings = update_selected_types_dict->EnsureDict( | |
| signin::GaiaIdHash::FromGaiaId(gaia_id).ToBase64()); | |
| // The values of the "global" data type prefs get copied to the | |
| // account-specific ones. | |
| bool everything_enabled = | |
| pref_service->GetBoolean(prefs::internal::kSyncKeepEverythingSynced); | |
| // Most of the per-account prefs default to "true", so nothing needs to be | |
| // done for those. The exceptions are History, Tabs and Saved Tab Groups, | |
| // which need to be enabled explicitly, and should remain enabled only if they | |
| // were enabled previously, so they're specially tracked here. | |
| bool history_enabled = everything_enabled; | |
| bool tabs_enabled = everything_enabled; | |
| #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) | |
| // Saved Tab Groups user toggle is only used on desktop. | |
| bool saved_tab_groups_enabled = everything_enabled; | |
| // Explicitly set the extensions toggle, which otherwise requires an explicit | |
| // sign-in to be enabled by default. This is to specifically handle the case | |
| // when `syncer::kExplicitSigninForExtension` is true. | |
| bool extensions_enabled = everything_enabled; | |
| // Explicitly set the bookmarks and reading list toggles, which otherwise | |
| // require an explicit sign-in to be enabled by default (see | |
| // `SigninPrefs::GetBookmarksExplicitBrowserSignin()`). | |
| bool bookmarks_enabled = everything_enabled; | |
| bool reading_list_enabled = everything_enabled; | |
| #endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) | |
| if (everything_enabled) { | |
| // On desktop, Passwords is considered disabled by default and | |
| // so also needs to be enabled explicitly. | |
| #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) | |
| // TODO(b/314773312): Remove this when Uno is enabled. | |
| account_settings->Set(GetPrefNameForType(UserSelectableType::kPasswords), | |
| true); | |
| #endif | |
| } else { | |
| // "Sync everything" is off, so copy over the individual value for each | |
| // type. | |
| for (UserSelectableType type : UserSelectableTypeSet::All()) { | |
| const char* pref_name = GetPrefNameForType(type); | |
| CHECK(pref_name); | |
| // Copy value from global to per-account pref. | |
| account_settings->Set(pref_name, pref_service->GetBoolean(pref_name)); | |
| } | |
| history_enabled = pref_service->GetBoolean( | |
| GetPrefNameForType(UserSelectableType::kHistory)); | |
| tabs_enabled = | |
| pref_service->GetBoolean(GetPrefNameForType(UserSelectableType::kTabs)); | |
| #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) | |
| saved_tab_groups_enabled = pref_service->GetBoolean( | |
| GetPrefNameForType(UserSelectableType::kSavedTabGroups)); | |
| extensions_enabled = pref_service->GetBoolean( | |
| GetPrefNameForType(UserSelectableType::kExtensions)); | |
| bookmarks_enabled = pref_service->GetBoolean( | |
| GetPrefNameForType(UserSelectableType::kBookmarks)); | |
| reading_list_enabled = pref_service->GetBoolean( | |
| GetPrefNameForType(UserSelectableType::kReadingList)); | |
| #endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) | |
| } | |
| #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) | |
| // On mobile, History and Tabs remain enabled only if they were both | |
| // enabled previously. | |
| account_settings->Set(GetPrefNameForType(UserSelectableType::kHistory), | |
| history_enabled && tabs_enabled); | |
| account_settings->Set(GetPrefNameForType(UserSelectableType::kTabs), | |
| history_enabled && tabs_enabled); | |
| #else | |
| // On desktop, History, Tabs and Saved Tab Groups carry over their individual | |
| // values. | |
| account_settings->Set(GetPrefNameForType(UserSelectableType::kHistory), | |
| history_enabled); | |
| account_settings->Set(GetPrefNameForType(UserSelectableType::kTabs), | |
| tabs_enabled); | |
| account_settings->Set(GetPrefNameForType(UserSelectableType::kBookmarks), | |
| bookmarks_enabled); | |
| account_settings->Set(GetPrefNameForType(UserSelectableType::kReadingList), | |
| reading_list_enabled); | |
| account_settings->Set(GetPrefNameForType(UserSelectableType::kSavedTabGroups), | |
| saved_tab_groups_enabled); | |
| account_settings->Set(GetPrefNameForType(UserSelectableType::kExtensions), | |
| extensions_enabled); | |
| #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) | |
| // Record that this migration now covers the Reading List toggle, to be able | |
| // to identify users who were migrated before it did (crbug.com/568406887). | |
| pref_service->SetBoolean(prefs::internal::kReadingListPrefMigratedToAccount, | |
| true); | |
| #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) | |
| #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) | |
| #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) | |
| // Another special case: For custom passphrase users, "Addresses and more" | |
| // gets disabled by default. The reason is that for syncing custom passphrase | |
| // users, this toggle mapped to the legacy AUTOFILL_PROFILE type (which | |
| // supported custom passphrase), but for migrated users it maps to | |
| // CONTACT_INFO (which does not). This is only done on Mobile because on | |
| // Desktop the strings already mention that the addresses are not encrypted | |
| // with the passphrase. | |
| std::optional<PassphraseType> passphrase_type = ProtoPassphraseInt32ToEnum( | |
| pref_service->GetInteger(prefs::internal::kSyncCachedPassphraseType)); | |
| if (passphrase_type.has_value() && IsExplicitPassphrase(*passphrase_type)) { | |
| account_settings->Set(GetPrefNameForType(UserSelectableType::kAutofill), | |
| false); | |
| } | |
| #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) | |
| // Usually, the "SyncToSignin" migration (aka phase 2) will have completed | |
| // previously. But just in case it hasn't, make sure it doesn't run in the | |
| // future - it's not neeced, and in fact it might mess up some of the things | |
| // that were just migrated here. | |
| pref_service->SetInteger(prefs::internal::kSyncToSigninMigrationState, | |
| kMigratedPart2AndFullyDone); | |
| } | |
| void SyncPrefs::MarkPartialSyncToSigninMigrationFullyDone() { | |
| // If the first part of the migration has run, but the second part has not, | |
| // then mark the migration as fully done - at this point (after signout) | |
| // there's no more need for any migration. | |
| // In all other cases (migration never even started, or completed fully), | |
| // nothing to be done here. | |
| if (pref_service_->GetInteger(prefs::internal::kSyncToSigninMigrationState) == | |
| kMigratedPart1ButNot2) { | |
| pref_service_->SetInteger(prefs::internal::kSyncToSigninMigrationState, | |
| kMigratedPart2AndFullyDone); | |
| } | |
| } | |
| bool SyncPrefs::IsTypeSelectedByDefaultInTransportMode( | |
| UserSelectableType type, | |
| const GaiaId& gaia_id) const { | |
| switch (type) { | |
| case UserSelectableType::kPayments: | |
| case UserSelectableType::kPasswords: | |
| case UserSelectableType::kAutofill: | |
| return true; | |
| case UserSelectableType::kHistory: | |
| case UserSelectableType::kTabs: | |
| case UserSelectableType::kSavedTabGroups: | |
| #if BUILDFLAG(IS_CHROMEOS) | |
| return true; | |
| #else | |
| // History and tabs require a separate opt in. | |
| return false; | |
| #endif | |
| case UserSelectableType::kBookmarks: | |
| case UserSelectableType::kReadingList: | |
| return IsBookmarksSelectedByDefaultInTransportMode(*pref_service_, | |
| gaia_id); | |
| case UserSelectableType::kPreferences: | |
| case UserSelectableType::kThemes: | |
| case UserSelectableType::kApps: | |
| case UserSelectableType::kProductComparison: | |
| case UserSelectableType::kCookies: | |
| return true; | |
| case UserSelectableType::kExtensions: | |
| return IsExtensionsSelectedByDefaultInTransportMode(*pref_service_, | |
| gaia_id); | |
| } | |
| NOTREACHED(); | |
| } | |
| } // namespace syncer |