blob: 2517a0271bd6f2c0c3fd0a30dda9525050a2d5e8 [file] [log] [blame]
// Copyright 2018 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/autofill/core/common/autofill_prefs.h"
#include "base/base64.h"
#include "build/build_config.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "crypto/sha2.h"
namespace autofill {
namespace prefs {
namespace {
// Returns the opt-in bitfield for the specific |account_id| or 0 if no entry
// was found.
int GetSyncTransportOptInBitFieldForAccount(const PrefService* prefs,
const std::string& account_hash) {
const auto& dictionary = prefs->GetDict(prefs::kAutofillSyncTransportOptIn);
// If there is no entry in the dictionary, it means the account didn't opt-in.
// Use 0 because it's the same as not having opted-in to anything.
const auto found = dictionary.FindInt(account_hash);
return found.value_or(0);
}
} // namespace
// Boolean that is true if Autofill is enabled and allowed to save credit card
// data.
const char kAutofillCreditCardEnabled[] = "autofill.credit_card_enabled";
// Boolean that is true if FIDO Authentication is enabled for card unmasking.
const char kAutofillCreditCardFidoAuthEnabled[] =
"autofill.credit_card_fido_auth_enabled";
#if BUILDFLAG(IS_ANDROID)
// Boolean that is true if FIDO Authentication is enabled for card unmasking.
const char kAutofillCreditCardFidoAuthOfferCheckboxState[] =
"autofill.credit_card_fido_auth_offer_checkbox_state";
#endif
// Boolean that is true if Autofill is enabled and allowed to save data.
const char kAutofillEnabledDeprecated[] = "autofill.enabled";
// Boolean that is true if a form with an IBAN field has ever been submitted, or
// an IBAN has ever been saved via Chrome payments settings page. This helps to
// enable IBAN functionality for those users who are not in a country where IBAN
// is generally available but have used IBAN already.
const char kAutofillHasSeenIban[] = "autofill.has_seen_iban";
// Boolean that is true if Autofill is enabled and allowed to save IBAN data.
extern const char kAutofillIBANEnabled[] = "autofill.iban_enabled";
// Integer that is set to the last version where the profile deduping routine
// was run. This routine will be run once per version.
const char kAutofillLastVersionDeduped[] = "autofill.last_version_deduped";
// Integer that is set to the last version where disused addresses were
// deleted. This deletion will be run once per version.
const char kAutofillLastVersionDisusedAddressesDeleted[] =
"autofill.last_version_disused_addresses_deleted";
// Integer that is set to the last version where disused credit cards were
// deleted. This deletion will be run once per version.
const char kAutofillLastVersionDisusedCreditCardsDeleted[] =
"autofill.last_version_disused_credit_cards_deleted";
// Boolean that is true if the orphan rows in the autofill table were removed.
const char kAutofillOrphanRowsRemoved[] = "autofill.orphan_rows_removed";
// Boolean that is true if Autofill is enabled and allowed to save profile data.
const char kAutofillProfileEnabled[] = "autofill.profile_enabled";
// This pref stores the file path where the autofill states data is
// downloaded to.
const char kAutofillStatesDataDir[] = "autofill.states_data_dir";
// The opt-ins for Sync Transport features for each client.
const char kAutofillSyncTransportOptIn[] = "autofill.sync_transport_opt_ins";
// The (randomly inititialied) seed value to use when encoding form/field
// metadata for randomized uploads. The value of this pref is a string.
const char kAutofillUploadEncodingSeed[] = "autofill.upload_encoding_seed";
// Dictionary pref used to track which form signature uploads have been
// performed. Each entry in the dictionary maps a form signature (reduced
// via a 10-bit modulus) to a integer bit-field where each bit denotes whether
// or not a given upload event has occurred.
const char kAutofillUploadEvents[] = "autofill.upload_events";
// The timestamp (seconds since the Epoch UTC) for when the the upload event
// pref was last reset.
const char kAutofillUploadEventsLastResetTimestamp[] =
"autofill.upload_events_last_reset_timestamp";
// Boolean that's true when Wallet card and address import is enabled by the
// user.
const char kAutofillWalletImportEnabled[] = "autofill.wallet_import_enabled";
// Integer that is set to the last major version where the Autocomplete
// retention policy was run.
const char kAutocompleteLastVersionRetentionPolicy[] =
"autocomplete.retention_policy_last_version";
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
// Boolean that is set when payment methods mandatory re-auth is enabled by the
// user.
const char kAutofillPaymentMethodsMandatoryReauth[] =
"autofill.payment_methods_mandatory_reauth";
// Integer that is incremented when the mandatory re-auth promo is shown. If
// this is less than `kMaxValueForMandatoryReauthPromoShownCounter`, that
// implies that the user has not yet decided whether or not to turn on the
// payments mandatory re-auth feature.
const char kAutofillPaymentMethodsMandatoryReauthPromoShownCounter[] =
"autofill.payment_methods_mandatory_reauth_promo_counter";
#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
// Synced prefs. Used for cross-device choices, e.g., credit card Autofill.
registry->RegisterBooleanPref(
prefs::kAutofillProfileEnabled, true,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterIntegerPref(
prefs::kAutofillLastVersionDeduped, 0,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterBooleanPref(
prefs::kAutofillHasSeenIban, false,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterIntegerPref(
prefs::kAutofillLastVersionDisusedAddressesDeleted, 0,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterBooleanPref(
prefs::kAutofillCreditCardEnabled, true,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterBooleanPref(
prefs::kAutofillIBANEnabled, true,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
// Non-synced prefs. Used for per-device choices, e.g., signin promo.
registry->RegisterBooleanPref(prefs::kAutofillCreditCardFidoAuthEnabled,
false);
#if BUILDFLAG(IS_ANDROID)
registry->RegisterBooleanPref(
prefs::kAutofillCreditCardFidoAuthOfferCheckboxState, true);
#endif
registry->RegisterBooleanPref(prefs::kAutofillWalletImportEnabled, true);
registry->RegisterIntegerPref(
prefs::kAutofillLastVersionDisusedCreditCardsDeleted, 0);
registry->RegisterIntegerPref(prefs::kAutocompleteLastVersionRetentionPolicy,
0);
registry->RegisterStringPref(prefs::kAutofillUploadEncodingSeed, "");
registry->RegisterDictionaryPref(prefs::kAutofillUploadEvents);
registry->RegisterTimePref(prefs::kAutofillUploadEventsLastResetTimestamp,
base::Time());
registry->RegisterDictionaryPref(prefs::kAutofillSyncTransportOptIn);
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
registry->RegisterBooleanPref(prefs::kAutofillPaymentMethodsMandatoryReauth,
false);
registry->RegisterIntegerPref(
prefs::kAutofillPaymentMethodsMandatoryReauthPromoShownCounter, 0);
#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
// Deprecated prefs registered for migration.
registry->RegisterBooleanPref(
prefs::kAutofillEnabledDeprecated, true,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterBooleanPref(prefs::kAutofillOrphanRowsRemoved, false);
}
void MigrateDeprecatedAutofillPrefs(PrefService* pref_service) {
// Added 09/2022.
pref_service->ClearPref(prefs::kAutofillEnabledDeprecated);
// Added 05/2023.
pref_service->ClearPref(prefs::kAutofillOrphanRowsRemoved);
}
bool IsAutocompleteEnabled(const PrefService* prefs) {
return IsAutofillProfileEnabled(prefs);
}
bool IsCreditCardFIDOAuthEnabled(PrefService* prefs) {
return prefs->GetBoolean(kAutofillCreditCardFidoAuthEnabled);
}
void SetCreditCardFIDOAuthEnabled(PrefService* prefs, bool enabled) {
prefs->SetBoolean(kAutofillCreditCardFidoAuthEnabled, enabled);
}
bool IsAutofillCreditCardEnabled(const PrefService* prefs) {
return prefs->GetBoolean(kAutofillCreditCardEnabled);
}
void SetAutofillCreditCardEnabled(PrefService* prefs, bool enabled) {
prefs->SetBoolean(kAutofillCreditCardEnabled, enabled);
}
bool HasSeenIban(const PrefService* prefs) {
return prefs->GetBoolean(kAutofillHasSeenIban);
}
// If called, always sets the pref to true, and once true, it will follow the
// user around forever.
void SetAutofillHasSeenIban(PrefService* prefs) {
prefs->SetBoolean(kAutofillHasSeenIban, true);
}
bool IsAutofillIBANEnabled(const PrefService* prefs) {
return prefs->GetBoolean(kAutofillIBANEnabled);
}
void SetAutofillIBANEnabled(PrefService* prefs, bool enabled) {
prefs->SetBoolean(kAutofillIBANEnabled, enabled);
}
bool IsAutofillManaged(const PrefService* prefs) {
return prefs->IsManagedPreference(kAutofillEnabledDeprecated);
}
bool IsAutofillProfileManaged(const PrefService* prefs) {
return prefs->IsManagedPreference(kAutofillProfileEnabled);
}
bool IsAutofillCreditCardManaged(const PrefService* prefs) {
return prefs->IsManagedPreference(kAutofillCreditCardEnabled);
}
bool IsAutofillProfileEnabled(const PrefService* prefs) {
return prefs->GetBoolean(kAutofillProfileEnabled);
}
void SetAutofillProfileEnabled(PrefService* prefs, bool enabled) {
prefs->SetBoolean(kAutofillProfileEnabled, enabled);
}
bool IsPaymentsIntegrationEnabled(const PrefService* prefs) {
return prefs->GetBoolean(kAutofillWalletImportEnabled);
}
void SetPaymentsIntegrationEnabled(PrefService* prefs, bool enabled) {
prefs->SetBoolean(kAutofillWalletImportEnabled, enabled);
}
bool IsAutofillPaymentMethodsMandatoryReauthEnabled(const PrefService* prefs) {
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
return prefs->GetBoolean(kAutofillPaymentMethodsMandatoryReauth);
#else
return false;
#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
}
void SetAutofillPaymentMethodsMandatoryReauth(PrefService* prefs,
bool enabled) {
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
prefs->SetBoolean(kAutofillPaymentMethodsMandatoryReauth, enabled);
#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
}
bool ShouldShowAutofillPaymentMethodsMandatoryReauthPromo(
const PrefService* prefs) {
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
// If the user has made a decision on this feature previously, then we should
// not show the opt-in promo.
if (prefs->GetUserPrefValue(kAutofillPaymentMethodsMandatoryReauth)) {
return false;
}
// We should only show the opt-in promo if we have not reached the maximum
// number of shows for the promo.
return prefs->GetInteger(
kAutofillPaymentMethodsMandatoryReauthPromoShownCounter) <
kMaxValueForMandatoryReauthPromoShownCounter;
#else
return false;
#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
}
void SetAutofillPaymentMethodsMandatoryReauthPromoShownCounter(
PrefService* prefs,
int count) {
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
prefs->SetInteger(kAutofillPaymentMethodsMandatoryReauthPromoShownCounter,
count);
#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
}
void SetUserOptedInWalletSyncTransport(PrefService* prefs,
const CoreAccountId& account_id,
bool opted_in) {
// Get the hash of the account id. The hashing here is only a secondary bit of
// obfuscation. The primary privacy guarantees are handled by clearing this
// whenever cookies are cleared.
std::string account_hash;
base::Base64Encode(crypto::SHA256HashString(account_id.ToString()),
&account_hash);
ScopedDictPrefUpdate update(prefs, prefs::kAutofillSyncTransportOptIn);
int value = GetSyncTransportOptInBitFieldForAccount(prefs, account_hash);
// If the user has opted in, set that bit while leaving the others intact.
if (opted_in) {
update->Set(account_hash, value | sync_transport_opt_in::kWallet);
return;
}
// Invert the mask in order to reset the Wallet bit while leaving the other
// bits intact, or remove the key entirely if the Wallet was the only opt-in.
if (value & ~sync_transport_opt_in::kWallet) {
update->Set(account_hash, value & ~sync_transport_opt_in::kWallet);
} else {
update->Remove(account_hash);
}
}
bool IsUserOptedInWalletSyncTransport(const PrefService* prefs,
const CoreAccountId& account_id) {
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
// On mobile, no specific opt-in is required.
return true;
#else
// Get the hash of the account id.
std::string account_hash;
base::Base64Encode(crypto::SHA256HashString(account_id.ToString()),
&account_hash);
// Return whether the wallet opt-in bit is set.
return GetSyncTransportOptInBitFieldForAccount(prefs, account_hash) &
sync_transport_opt_in::kWallet;
#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
}
void ClearSyncTransportOptIns(PrefService* prefs) {
prefs->SetDict(prefs::kAutofillSyncTransportOptIn, base::Value::Dict());
}
} // namespace prefs
} // namespace autofill