summaryrefslogtreecommitdiff
path: root/chromium/components/autofill/core/common
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-11 11:32:04 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-18 13:40:17 +0000
commit31ccca0778db85c159634478b4ec7997f6704860 (patch)
tree3d33fc3afd9d5ec95541e1bbe074a9cf8da12a0e /chromium/components/autofill/core/common
parent248b70b82a40964d5594eb04feca0fa36716185d (diff)
downloadqtwebengine-chromium-31ccca0778db85c159634478b4ec7997f6704860.tar.gz
BASELINE: Update Chromium to 80.0.3987.136
Change-Id: I98e1649aafae85ba3a83e67af00bb27ef301db7b Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
Diffstat (limited to 'chromium/components/autofill/core/common')
-rw-r--r--chromium/components/autofill/core/common/BUILD.gn2
-rw-r--r--chromium/components/autofill/core/common/DEPS1
-rw-r--r--chromium/components/autofill/core/common/autofill_features.cc4
-rw-r--r--chromium/components/autofill/core/common/autofill_features.h1
-rw-r--r--chromium/components/autofill/core/common/autofill_internals/log_message.h4
-rw-r--r--chromium/components/autofill/core/common/autofill_internals/logging_scope.h4
-rw-r--r--chromium/components/autofill/core/common/autofill_payments_features.cc46
-rw-r--r--chromium/components/autofill/core/common/autofill_payments_features.h17
-rw-r--r--chromium/components/autofill/core/common/autofill_prefs.cc49
-rw-r--r--chromium/components/autofill/core/common/autofill_prefs.h28
-rw-r--r--chromium/components/autofill/core/common/autofill_prefs_unittest.cc16
-rw-r--r--chromium/components/autofill/core/common/form_data.cc44
-rw-r--r--chromium/components/autofill/core/common/form_data.h24
-rw-r--r--chromium/components/autofill/core/common/form_field_data.cc224
-rw-r--r--chromium/components/autofill/core/common/form_field_data.h47
-rw-r--r--chromium/components/autofill/core/common/logging/log_buffer.cc7
-rw-r--r--chromium/components/autofill/core/common/mojom/BUILD.gn1
-rw-r--r--chromium/components/autofill/core/common/mojom/autofill_types.mojom8
-rw-r--r--chromium/components/autofill/core/common/mojom/autofill_types.typemap2
-rw-r--r--chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc11
-rw-r--r--chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits.h23
-rw-r--r--chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc22
-rw-r--r--chromium/components/autofill/core/common/password_form.cc14
-rw-r--r--chromium/components/autofill/core/common/password_form.h7
-rw-r--r--chromium/components/autofill/core/common/password_form_fill_data.cc4
-rw-r--r--chromium/components/autofill/core/common/password_form_fill_data.h11
-rw-r--r--chromium/components/autofill/core/common/save_password_progress_logger.cc6
-rw-r--r--chromium/components/autofill/core/common/save_password_progress_logger.h3
28 files changed, 274 insertions, 356 deletions
diff --git a/chromium/components/autofill/core/common/BUILD.gn b/chromium/components/autofill/core/common/BUILD.gn
index 2f096cab5d5..98837b9f690 100644
--- a/chromium/components/autofill/core/common/BUILD.gn
+++ b/chromium/components/autofill/core/common/BUILD.gn
@@ -67,6 +67,7 @@ jumbo_static_library("common") {
"//components/prefs",
"//components/variations",
"//crypto",
+ "//google_apis:google_apis",
"//ui/base",
"//ui/gfx/geometry",
"//url",
@@ -99,6 +100,7 @@ source_set("unit_tests") {
"//components/pref_registry",
"//components/prefs",
"//components/prefs:test_support",
+ "//google_apis:google_apis",
"//testing/gmock",
"//testing/gtest",
"//url",
diff --git a/chromium/components/autofill/core/common/DEPS b/chromium/components/autofill/core/common/DEPS
index 41f0daa03c5..163b88c9576 100644
--- a/chromium/components/autofill/core/common/DEPS
+++ b/chromium/components/autofill/core/common/DEPS
@@ -1,3 +1,4 @@
include_rules = [
"+crypto/sha2.h",
+ "+google_apis/gaia/core_account_id.h",
]
diff --git a/chromium/components/autofill/core/common/autofill_features.cc b/chromium/components/autofill/core/common/autofill_features.cc
index 7f4ca82a5bf..627d4a9d267 100644
--- a/chromium/components/autofill/core/common/autofill_features.cc
+++ b/chromium/components/autofill/core/common/autofill_features.cc
@@ -54,6 +54,10 @@ const base::Feature kAutofillEnableAccountWalletStorage{
const base::Feature kAutofillEnableCompanyName{
"AutofillEnableCompanyName", base::FEATURE_ENABLED_BY_DEFAULT};
+// Controls whether we show "Hide suggestions" item in the suggestions menu.
+const base::Feature kAutofillEnableHideSuggestionsUI{
+ "AutofillEnableHideSuggestionsUI", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls whether or not a minimum number of fields is required before
// heuristic field type prediction is run for a form.
const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics{
diff --git a/chromium/components/autofill/core/common/autofill_features.h b/chromium/components/autofill/core/common/autofill_features.h
index 78a8bfcbbbc..1306a9f82bf 100644
--- a/chromium/components/autofill/core/common/autofill_features.h
+++ b/chromium/components/autofill/core/common/autofill_features.h
@@ -29,6 +29,7 @@ extern const base::Feature kAutofillCreateDataForTest;
extern const base::Feature kAutofillCreditCardAssist;
extern const base::Feature kAutofillEnableAccountWalletStorage;
extern const base::Feature kAutofillEnableCompanyName;
+extern const base::Feature kAutofillEnableHideSuggestionsUI;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload;
diff --git a/chromium/components/autofill/core/common/autofill_internals/log_message.h b/chromium/components/autofill/core/common/autofill_internals/log_message.h
index a7232ce6cbb..8f4eb5f6a59 100644
--- a/chromium/components/autofill/core/common/autofill_internals/log_message.h
+++ b/chromium/components/autofill/core/common/autofill_internals/log_message.h
@@ -28,7 +28,9 @@ class LogBuffer;
"Abort parsing form: Action URL matches kUrlSearchActionRe, indicating " \
"that the form may lead to a search.") \
T(AbortParsingFormHasNoTextfield, \
- "Abort parsing form: Form has no text field.")
+ "Abort parsing form: Form has no text field.") \
+ T(FunnelMetrics, "Funnel Metrics") \
+ T(KeyMetrics, "Key Metrics")
// Log messages for chrome://autofill-internals.
#define AUTOFILL_TEMPLATE(NAME, MESSAGE) k##NAME,
diff --git a/chromium/components/autofill/core/common/autofill_internals/logging_scope.h b/chromium/components/autofill/core/common/autofill_internals/logging_scope.h
index 5684511f84e..f9f8339ae3b 100644
--- a/chromium/components/autofill/core/common/autofill_internals/logging_scope.h
+++ b/chromium/components/autofill/core/common/autofill_internals/logging_scope.h
@@ -25,7 +25,9 @@ class LogBuffer;
/* Log messages related to the submission of forms. */ \
T(Submission) \
/* Log messages related to communication with autofill server. */ \
- T(AutofillServer)
+ T(AutofillServer) \
+ /* Log messages related to metrics collection. */ \
+ T(Metrics)
// Define a bunch of logging scopes: kContext, kParsing, ...
#define AUTOFILL_TEMPLATE(NAME) k##NAME,
diff --git a/chromium/components/autofill/core/common/autofill_payments_features.cc b/chromium/components/autofill/core/common/autofill_payments_features.cc
index d5a33bdaa85..6063755cd24 100644
--- a/chromium/components/autofill/core/common/autofill_payments_features.cc
+++ b/chromium/components/autofill/core/common/autofill_payments_features.cc
@@ -20,20 +20,6 @@
namespace autofill {
namespace features {
-const char kAutofillSaveCreditCardUsesImprovedMessagingParamName[] =
- "AutofillSaveCreditCardUsesImprovedMessaging";
-
-const char kAutofillSaveCreditCardUsesImprovedMessagingParamValueStoreCard[] =
- "Store Card";
-const char
- kAutofillSaveCreditCardUsesImprovedMessagingParamValueStoreBillingDetails
- [] = "Store Billing Details";
-const char kAutofillSaveCreditCardUsesImprovedMessagingParamValueAddCard[] =
- "Add Card";
-const char
- kAutofillSaveCreditCardUsesImprovedMessagingParamValueConfirmAndSaveCard[] =
- "Confirm & Save Card";
-
// Features
// Controls whether or not Autofill client will populate form with CPAN and
@@ -56,10 +42,6 @@ const base::Feature kAutofillCreditCardAuthentication{
const base::Feature kAutofillCreditCardUploadFeedback{
"AutofillCreditCardUploadFeedback", base::FEATURE_DISABLED_BY_DEFAULT};
-const base::Feature kAutofillDoNotMigrateUnsupportedLocalCards{
- "AutofillDoNotMigrateUnsupportedLocalCards",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
// When enabled, enable local card migration flow for user who has signed in but
// has not turned on sync.
const base::Feature kAutofillEnableLocalCardMigrationForNonSyncUser{
@@ -71,11 +53,10 @@ const base::Feature kAutofillEnableLocalCardMigrationForNonSyncUser{
const base::Feature kAutofillEnableToolbarStatusChip{
"AutofillEnableToolbarStatusChip", base::FEATURE_DISABLED_BY_DEFAULT};
-// Controls whether offering to migrate cards will consider data from the
-// Autofill strike database (new version).
-const base::Feature kAutofillLocalCardMigrationUsesStrikeSystemV2{
- "AutofillLocalCardMigrationUsesStrikeSystemV2",
- base::FEATURE_ENABLED_BY_DEFAULT};
+// When enabled, the option of using cloud token virtual card will be offered
+// when all requirements are met.
+const base::Feature kAutofillEnableVirtualCard{
+ "AutofillEnableVirtualCard", base::FEATURE_DISABLED_BY_DEFAULT};
// When enabled, will remove the option to save unmasked server cards as
// FULL_SERVER_CARDs upon successful unmask.
@@ -92,22 +73,9 @@ const base::Feature kAutofillNoLocalSaveOnUploadSuccess{
const base::Feature kAutofillSaveCardDismissOnNavigation{
"AutofillSaveCardDismissOnNavigation", base::FEATURE_ENABLED_BY_DEFAULT};
-// When enabled, local and upload credit card save dialogs will add a
-// [No thanks] cancel button option. This is intended to bring the
-// AutofillSaveCardImprovedUserConsent functionality to Chrome OS, Android, and
-// iOS without bringing the extended title string change with it.
-const base::Feature kAutofillSaveCardShowNoThanks{
- "AutofillSaveCardShowNoThanks", base::FEATURE_ENABLED_BY_DEFAULT};
-
-// Controls what title and bubble label for the credit card upload bubble are
-// shown to users.
-const base::Feature kAutofillSaveCreditCardUsesImprovedMessaging{
- "AutofillSaveCreditCardUsesImprovedMessaging",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
-// Controls whether to show updated UI for the card unmask prompt.
-const base::Feature kAutofillUpdatedCardUnmaskPromptUi{
- "AutofillUpdatedCardUnmaskPromptUi", base::FEATURE_DISABLED_BY_DEFAULT};
+// When enabled, the Save Card infobar supports editing before submitting.
+const base::Feature kAutofillSaveCardInfobarEditSupport{
+ "AutofillSaveCardInfobarEditSupport", base::FEATURE_DISABLED_BY_DEFAULT};
// Controls offering credit card upload to Google Payments. Cannot ever be
// ENABLED_BY_DEFAULT because it's a country-specific whitelist. There are
diff --git a/chromium/components/autofill/core/common/autofill_payments_features.h b/chromium/components/autofill/core/common/autofill_payments_features.h
index 6dc8e2faa2d..2309c6eb011 100644
--- a/chromium/components/autofill/core/common/autofill_payments_features.h
+++ b/chromium/components/autofill/core/common/autofill_payments_features.h
@@ -23,16 +23,13 @@ extern const base::Feature kAutofillAlwaysReturnCloudTokenizedCard;
extern const base::Feature kAutofillCreditCardAblationExperiment;
extern const base::Feature kAutofillCreditCardAuthentication;
extern const base::Feature kAutofillCreditCardUploadFeedback;
-extern const base::Feature kAutofillDoNotMigrateUnsupportedLocalCards;
extern const base::Feature kAutofillEnableLocalCardMigrationForNonSyncUser;
extern const base::Feature kAutofillEnableToolbarStatusChip;
-extern const base::Feature kAutofillLocalCardMigrationUsesStrikeSystemV2;
+extern const base::Feature kAutofillEnableVirtualCard;
extern const base::Feature kAutofillNoLocalSaveOnUnmaskSuccess;
extern const base::Feature kAutofillNoLocalSaveOnUploadSuccess;
extern const base::Feature kAutofillSaveCardDismissOnNavigation;
-extern const base::Feature kAutofillSaveCardShowNoThanks;
-extern const base::Feature kAutofillSaveCreditCardUsesImprovedMessaging;
-extern const base::Feature kAutofillUpdatedCardUnmaskPromptUi;
+extern const base::Feature kAutofillSaveCardInfobarEditSupport;
extern const base::Feature kAutofillUpstream;
extern const base::Feature kAutofillUpstreamAllowAllEmailDomains;
extern const base::Feature kAutofillUpstreamAlwaysRequestCardholderName;
@@ -40,16 +37,6 @@ extern const base::Feature kAutofillUpstreamBlankCardholderNameField;
extern const base::Feature kAutofillUpstreamEditableCardholderName;
extern const base::Feature kAutofillUpstreamEditableExpirationDate;
-extern const char kAutofillSaveCreditCardUsesImprovedMessagingParamName[];
-extern const char
- kAutofillSaveCreditCardUsesImprovedMessagingParamValueStoreCard[];
-extern const char
- kAutofillSaveCreditCardUsesImprovedMessagingParamValueStoreBillingDetails[];
-extern const char
- kAutofillSaveCreditCardUsesImprovedMessagingParamValueAddCard[];
-extern const char
- kAutofillSaveCreditCardUsesImprovedMessagingParamValueConfirmAndSaveCard[];
-
// Return whether a [No thanks] button and new messaging is shown in the save
// card bubbles. This will be called only on desktop platforms.
bool ShouldShowImprovedUserConsentForCreditCardSave();
diff --git a/chromium/components/autofill/core/common/autofill_prefs.cc b/chromium/components/autofill/core/common/autofill_prefs.cc
index 1607b0d7274..1296451e132 100644
--- a/chromium/components/autofill/core/common/autofill_prefs.cc
+++ b/chromium/components/autofill/core/common/autofill_prefs.cc
@@ -84,11 +84,6 @@ const char kAutofillLastVersionDisusedAddressesDeleted[] =
const char kAutofillLastVersionDisusedCreditCardsDeleted[] =
"autofill.last_version_disused_credit_cards_deleted";
-// Boolean that is set to denote whether user cancelled/rejected local card
-// migration prompt.
-const char kAutofillMigrateLocalCardsCancelledPrompt[] =
- "autofill.migrate_local_card_cancelled_state";
-
// Boolean that is true if the orphan rows in the autofill table were removed.
const char kAutofillOrphanRowsRemoved[] = "autofill.orphan_rows_removed";
@@ -175,8 +170,6 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
prefs::kAutofillLastVersionDisusedCreditCardsDeleted, 0);
registry->RegisterIntegerPref(prefs::kAutocompleteLastVersionRetentionPolicy,
0);
- registry->RegisterBooleanPref(
- prefs::kAutofillMigrateLocalCardsCancelledPrompt, false);
registry->RegisterBooleanPref(prefs::kAutofillOrphanRowsRemoved, false);
registry->RegisterStringPref(prefs::kAutofillUploadEncodingSeed, "");
registry->RegisterDictionaryPref(prefs::kAutofillUploadEvents);
@@ -223,16 +216,7 @@ void MigrateDeprecatedAutofillPrefs(PrefService* prefs) {
}
bool IsAutocompleteEnabled(const PrefService* prefs) {
- return IsProfileAutofillEnabled(prefs);
-}
-
-bool IsAutofillEnabled(const PrefService* prefs) {
- return IsProfileAutofillEnabled(prefs) || IsCreditCardAutofillEnabled(prefs);
-}
-
-void SetAutofillEnabled(PrefService* prefs, bool enabled) {
- SetProfileAutofillEnabled(prefs, enabled);
- SetCreditCardAutofillEnabled(prefs, enabled);
+ return IsAutofillProfileEnabled(prefs);
}
bool IsCreditCardFIDOAuthEnabled(PrefService* prefs) {
@@ -243,11 +227,11 @@ void SetCreditCardFIDOAuthEnabled(PrefService* prefs, bool enabled) {
prefs->SetBoolean(kAutofillCreditCardFidoAuthEnabled, enabled);
}
-bool IsCreditCardAutofillEnabled(const PrefService* prefs) {
+bool IsAutofillCreditCardEnabled(const PrefService* prefs) {
return prefs->GetBoolean(kAutofillCreditCardEnabled);
}
-void SetCreditCardAutofillEnabled(PrefService* prefs, bool enabled) {
+void SetAutofillCreditCardEnabled(PrefService* prefs, bool enabled) {
prefs->SetBoolean(kAutofillCreditCardEnabled, enabled);
}
@@ -255,31 +239,22 @@ bool IsAutofillManaged(const PrefService* prefs) {
return prefs->IsManagedPreference(kAutofillEnabledDeprecated);
}
-bool IsProfileAutofillManaged(const PrefService* prefs) {
+bool IsAutofillProfileManaged(const PrefService* prefs) {
return prefs->IsManagedPreference(kAutofillProfileEnabled);
}
-bool IsCreditCardAutofillManaged(const PrefService* prefs) {
+bool IsAutofillCreditCardManaged(const PrefService* prefs) {
return prefs->IsManagedPreference(kAutofillCreditCardEnabled);
}
-bool IsProfileAutofillEnabled(const PrefService* prefs) {
+bool IsAutofillProfileEnabled(const PrefService* prefs) {
return prefs->GetBoolean(kAutofillProfileEnabled);
}
-void SetProfileAutofillEnabled(PrefService* prefs, bool enabled) {
+void SetAutofillProfileEnabled(PrefService* prefs, bool enabled) {
prefs->SetBoolean(kAutofillProfileEnabled, enabled);
}
-bool IsLocalCardMigrationPromptPreviouslyCancelled(const PrefService* prefs) {
- return prefs->GetBoolean(kAutofillMigrateLocalCardsCancelledPrompt);
-}
-
-void SetLocalCardMigrationPromptPreviouslyCancelled(PrefService* prefs,
- bool enabled) {
- prefs->SetBoolean(kAutofillMigrateLocalCardsCancelledPrompt, enabled);
-}
-
bool IsPaymentsIntegrationEnabled(const PrefService* prefs) {
return prefs->GetBoolean(kAutofillWalletImportEnabled);
}
@@ -296,13 +271,14 @@ std::string GetAllProfilesValidityMapsEncodedString(const PrefService* prefs) {
}
void SetUserOptedInWalletSyncTransport(PrefService* prefs,
- const std::string& account_id,
+ 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), &account_hash);
+ base::Base64Encode(crypto::SHA256HashString(account_id.ToString()),
+ &account_hash);
DictionaryPrefUpdate update(prefs, prefs::kAutofillSyncTransportOptIn);
int value = GetSyncTransportOptInBitFieldForAccount(prefs, account_hash);
@@ -325,10 +301,11 @@ void SetUserOptedInWalletSyncTransport(PrefService* prefs,
}
bool IsUserOptedInWalletSyncTransport(const PrefService* prefs,
- const std::string& account_id) {
+ const CoreAccountId& account_id) {
// Get the hash of the account id.
std::string account_hash;
- base::Base64Encode(crypto::SHA256HashString(account_id), &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) &
diff --git a/chromium/components/autofill/core/common/autofill_prefs.h b/chromium/components/autofill/core/common/autofill_prefs.h
index 7558441a2ac..369f3fde5eb 100644
--- a/chromium/components/autofill/core/common/autofill_prefs.h
+++ b/chromium/components/autofill/core/common/autofill_prefs.h
@@ -7,6 +7,8 @@
#include <string>
+#include "google_apis/gaia/core_account_id.h"
+
class PrefService;
namespace user_prefs {
@@ -31,7 +33,6 @@ extern const char kAutofillLastVersionDeduped[];
extern const char kAutofillLastVersionValidated[];
extern const char kAutofillLastVersionDisusedAddressesDeleted[];
extern const char kAutofillLastVersionDisusedCreditCardsDeleted[];
-extern const char kAutofillMigrateLocalCardsCancelledPrompt[];
extern const char kAutofillOrphanRowsRemoved[];
// Do not get/set the value of this pref directly. Use provided getter/setter.
extern const char kAutofillProfileEnabled[];
@@ -67,32 +68,23 @@ void MigrateDeprecatedAutofillPrefs(PrefService* prefs);
bool IsAutocompleteEnabled(const PrefService* prefs);
-bool IsAutofillEnabled(const PrefService* prefs);
-
-void SetAutofillEnabled(PrefService* prefs, bool enabled);
-
bool IsCreditCardFIDOAuthEnabled(PrefService* prefs);
void SetCreditCardFIDOAuthEnabled(PrefService* prefs, bool enabled);
-bool IsCreditCardAutofillEnabled(const PrefService* prefs);
+bool IsAutofillCreditCardEnabled(const PrefService* prefs);
-void SetCreditCardAutofillEnabled(PrefService* prefs, bool enabled);
+void SetAutofillCreditCardEnabled(PrefService* prefs, bool enabled);
bool IsAutofillManaged(const PrefService* prefs);
-bool IsProfileAutofillManaged(const PrefService* prefs);
-
-bool IsCreditCardAutofillManaged(const PrefService* prefs);
-
-bool IsProfileAutofillEnabled(const PrefService* prefs);
+bool IsAutofillProfileManaged(const PrefService* prefs);
-void SetProfileAutofillEnabled(PrefService* prefs, bool enabled);
+bool IsAutofillCreditCardManaged(const PrefService* prefs);
-bool IsLocalCardMigrationPromptPreviouslyCancelled(const PrefService* prefs);
+bool IsAutofillProfileEnabled(const PrefService* prefs);
-void SetLocalCardMigrationPromptPreviouslyCancelled(PrefService* prefs,
- bool enabled);
+void SetAutofillProfileEnabled(PrefService* prefs, bool enabled);
bool IsPaymentsIntegrationEnabled(const PrefService* prefs);
@@ -101,11 +93,11 @@ void SetPaymentsIntegrationEnabled(PrefService* prefs, bool enabled);
std::string GetAllProfilesValidityMapsEncodedString(const PrefService* prefs);
void SetUserOptedInWalletSyncTransport(PrefService* prefs,
- const std::string& account_id,
+ const CoreAccountId& account_id,
bool opted_in);
bool IsUserOptedInWalletSyncTransport(const PrefService* prefs,
- const std::string& account_id);
+ const CoreAccountId& account_id);
void ClearSyncTransportOptIns(PrefService* prefs);
diff --git a/chromium/components/autofill/core/common/autofill_prefs_unittest.cc b/chromium/components/autofill/core/common/autofill_prefs_unittest.cc
index 085c6e23437..f3d93b25453 100644
--- a/chromium/components/autofill/core/common/autofill_prefs_unittest.cc
+++ b/chromium/components/autofill/core/common/autofill_prefs_unittest.cc
@@ -78,8 +78,8 @@ TEST_F(AutofillPrefsTest, MigrateDeprecatedAutofillPrefs) {
// Tests that setting and getting the AutofillSyncTransportOptIn works as
// expected.
TEST_F(AutofillPrefsTest, WalletSyncTransportPref_GetAndSet) {
- const std::string account1 = "account1";
- const std::string account2 = "account2";
+ const CoreAccountId account1("account1");
+ const CoreAccountId account2("account2");
// There should be no opt-in recorded at first.
ASSERT_FALSE(IsUserOptedInWalletSyncTransport(pref_service(), account1));
@@ -129,7 +129,7 @@ TEST_F(AutofillPrefsTest, WalletSyncTransportPref_GetAndSet) {
// Tests that AutofillSyncTransportOptIn is not stored using the plain text
// account id.
TEST_F(AutofillPrefsTest, WalletSyncTransportPref_UsesHashAccountId) {
- const std::string account1 = "account1";
+ const CoreAccountId account1("account1");
// There should be no opt-in recorded at first.
EXPECT_TRUE(pref_service()
@@ -145,14 +145,14 @@ TEST_F(AutofillPrefsTest, WalletSyncTransportPref_UsesHashAccountId) {
// Make sure that the dictionary keys don't contain the account id.
auto* dictionary =
pref_service()->GetDictionary(prefs::kAutofillSyncTransportOptIn);
- EXPECT_EQ(NULL,
- dictionary->FindKeyOfType(account1, base::Value::Type::INTEGER));
+ EXPECT_EQ(nullptr, dictionary->FindKeyOfType(account1.ToString(),
+ base::Value::Type::INTEGER));
}
// Tests that clearing the AutofillSyncTransportOptIn works as expected.
TEST_F(AutofillPrefsTest, WalletSyncTransportPref_Clear) {
- const std::string account1 = "account1";
- const std::string account2 = "account2";
+ const CoreAccountId account1("account1");
+ const CoreAccountId account2("account2");
// There should be no opt-in recorded at first.
EXPECT_TRUE(pref_service()
@@ -181,7 +181,7 @@ TEST_F(AutofillPrefsTest, WalletSyncTransportPref_Clear) {
// Tests that the account id hash that we generate can be written and read from
// JSON properly.
TEST_F(AutofillPrefsTest, WalletSyncTransportPref_CanBeSetAndReadFromJSON) {
- const std::string account1 = "account1";
+ const CoreAccountId account1("account1");
// Set the opt-in for the first account.
SetUserOptedInWalletSyncTransport(pref_service(), account1, true);
diff --git a/chromium/components/autofill/core/common/form_data.cc b/chromium/components/autofill/core/common/form_data.cc
index e69ae3a8a28..df05fe6e072 100644
--- a/chromium/components/autofill/core/common/form_data.cc
+++ b/chromium/components/autofill/core/common/form_data.cc
@@ -123,28 +123,23 @@ bool FormData::DynamicallySameFormAs(const FormData& form) const {
return true;
}
-bool FormData::operator==(const FormData& form) const {
- return name == form.name && id_attribute == form.id_attribute &&
- name_attribute == form.name_attribute && url == form.url &&
- action == form.action && is_action_empty == form.is_action_empty &&
- unique_renderer_id == form.unique_renderer_id &&
- submission_event == form.submission_event &&
- is_form_tag == form.is_form_tag &&
- is_formless_checkout == form.is_formless_checkout &&
- fields == form.fields &&
- username_predictions == form.username_predictions;
-}
-
-bool FormData::operator!=(const FormData& form) const {
- return !(*this == form);
-}
-
-bool FormData::operator<(const FormData& form) const {
- return std::tie(name, id_attribute, name_attribute, url, action, is_form_tag,
- is_formless_checkout, fields) <
- std::tie(form.name, form.id_attribute, form.name_attribute, form.url,
- form.action, form.is_form_tag, form.is_formless_checkout,
- form.fields);
+bool FormData::IdentityComparator::operator()(const FormData& a,
+ const FormData& b) const {
+ // |unique_renderer_id| uniquely identifies the form, if and only if it is
+ // set; the other members compared below together uniquely identify the form
+ // as well.
+ auto tie = [](const FormData& f) {
+ return std::tie(f.unique_renderer_id, f.name, f.id_attribute,
+ f.name_attribute, f.url, f.action, f.is_form_tag,
+ f.is_formless_checkout);
+ };
+ if (tie(a) < tie(b))
+ return true;
+ if (tie(b) < tie(a))
+ return false;
+ return std::lexicographical_compare(a.fields.begin(), a.fields.end(),
+ b.fields.begin(), b.fields.end(),
+ FormFieldData::IdentityComparator());
}
std::ostream& operator<<(std::ostream& os, const FormData& form) {
@@ -254,4 +249,9 @@ LogBuffer& operator<<(LogBuffer& buffer, const FormData& form) {
return buffer;
}
+bool FormDataEqualForTesting(const FormData& lhs, const FormData& rhs) {
+ FormData::IdentityComparator less;
+ return !less(lhs, rhs) && !less(rhs, lhs);
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/common/form_data.h b/chromium/components/autofill/core/common/form_data.h
index 932394bc09e..1e84cec2998 100644
--- a/chromium/components/autofill/core/common/form_data.h
+++ b/chromium/components/autofill/core/common/form_data.h
@@ -29,6 +29,12 @@ using ButtonTitleList = std::vector<ButtonTitleInfo>;
// Holds information about a form to be filled and/or submitted.
struct FormData {
+ // Less-than relation for STL containers. Compares only members needed to
+ // uniquely identify a form.
+ struct IdentityComparator {
+ bool operator()(const FormData& a, const FormData& b) const;
+ };
+
// TODO(https://crbug.com/875768): Rename this const to kNotSetRendererId, and
// use it also for not set renderer ids in FormFieldData.
static constexpr uint32_t kNotSetFormRendererId =
@@ -52,11 +58,6 @@ struct FormData {
// If |form| is the same as this from the POV of dynamic refills.
bool DynamicallySameFormAs(const FormData& form) const;
- // Note: operator==() performs a full-field-comparison(byte by byte), this is
- // different from SameFormAs(), which ignores comparison for those "values" of
- // all form fields, just like what FormFieldData::SameFieldAs() ignores.
- bool operator==(const FormData& form) const;
- bool operator!=(const FormData& form) const;
// Allow FormData to be a key in STL containers.
bool operator<(const FormData& form) const;
@@ -66,6 +67,11 @@ struct FormData {
// The name attribute of the form.
base::string16 name_attribute;
+ // NOTE: update IdentityComparator when adding new a member.
+ // NOTE: update SameFormAs() if needed when adding new a member.
+ // NOTE: update SimilarFormAs() if needed when adding new a member.
+ // NOTE: update DynamicallySameFormAs() if needed when adding new a member.
+
// The name by which autofill knows this form. This is generally either the
// name attribute or the id_attribute value, which-ever is non-empty with
// priority given to the name_attribute. This value is used when computing
@@ -91,9 +97,9 @@ struct FormData {
// and used if features::kAutofillRestrictUnownedFieldsToFormlessCheckout is
// enabled, to prevent heuristics from running on formless non-checkout.
bool is_formless_checkout = false;
- // Unique renderer id which is returned by function
- // WebFormElement::UniqueRendererFormId(). It is not persistant between page
- // loads, so it is not saved and not used in comparison in SameFormAs().
+ // Unique renderer id returned by WebFormElement::UniqueRendererFormId(). It
+ // is not persistent between page loads, so it is not saved and not used in
+ // comparison in SameFormAs().
uint32_t unique_renderer_id = kNotSetFormRendererId;
// The type of the event that was taken as an indication that this form is
// being or has already been submitted. This field is filled only in Password
@@ -124,6 +130,8 @@ bool DeserializeFormData(base::PickleIterator* iter, FormData* form_data);
LogBuffer& operator<<(LogBuffer& buffer, const FormData& form);
+bool FormDataEqualForTesting(const FormData& lhs, const FormData& rhs);
+
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_COMMON_FORM_DATA_H_
diff --git a/chromium/components/autofill/core/common/form_field_data.cc b/chromium/components/autofill/core/common/form_field_data.cc
index 1a804330c6c..2f233ce7478 100644
--- a/chromium/components/autofill/core/common/form_field_data.cc
+++ b/chromium/components/autofill/core/common/form_field_data.cc
@@ -4,7 +4,11 @@
#include "components/autofill/core/common/form_field_data.h"
+#include <algorithm>
+#include <tuple>
+
#include "base/pickle.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_util.h"
@@ -126,18 +130,71 @@ bool DeserializeSection11(base::PickleIterator* iter,
return iter->ReadString16(&field_data->name_attribute);
}
-bool HaveSameLabel(const FormFieldData& field1, const FormFieldData& field2) {
- if (field1.label == field2.label)
- return true;
-
- // Assume the labels same if they come from same source but not LABEL tag
- // when kAutofillSkipComparingInferredLabels is enabled.
- if (base::FeatureList::IsEnabled(
- features::kAutofillSkipComparingInferredLabels)) {
- return field1.label_source == field2.label_source &&
- field1.label_source != FormFieldData::LabelSource::kLabelTag;
+// LabelInfo is used to implement that "a.label == b.label" can be weakened to
+// "a.label == b.label OR a certain feature is enabled and {a,b}.label_source !=
+// kLabelTag and a.label_source == b.label_source".
+// Beware of the StringPiece member and resulting lifetime issues. Deleted copy
+// and move ctors/operators to reduce risk potential.
+struct LabelInfo {
+ explicit LabelInfo(const FormFieldData& f)
+ : label(f.label), source(f.label_source) {}
+ LabelInfo(const LabelInfo&) = delete;
+ LabelInfo& operator=(const LabelInfo&) = delete;
+ LabelInfo(LabelInfo&&) = default;
+ LabelInfo& operator=(LabelInfo&&) = default;
+
+ bool operator==(const LabelInfo& that) const {
+ if (label == that.label)
+ return true;
+
+ // Feature |kAutofillSkipComparingInferredLabels| weakens equivalence of
+ // labels: two labels are equivalent if they were inferred from the same
+ // type of tag other than a LABEL tag.
+ return base::FeatureList::IsEnabled(
+ features::kAutofillSkipComparingInferredLabels) &&
+ source != FormFieldData::LabelSource::kLabelTag &&
+ source == that.source;
}
- return false;
+
+ bool operator<(const LabelInfo& that) const { return label < that.label; }
+
+ base::StringPiece16 label;
+ FormFieldData::LabelSource source = FormFieldData::LabelSource::kLabelTag;
+};
+
+// CommonTuple(), SimilarityTuple(), DynamicIdentityTuple(), IdentityTuple()
+// return values should be used as temporaries only because they include a
+// StringPiece.
+
+auto CommonTuple(const FormFieldData& f) {
+ return std::tuple_cat(
+ std::make_tuple(LabelInfo(f)),
+ std::tie(f.name, f.name_attribute, f.id_attribute, f.form_control_type));
+}
+
+auto SimilarityTuple(const FormFieldData& f) {
+ return std::tuple_cat(CommonTuple(f),
+ std::make_tuple(IsCheckable(f.check_status)));
+}
+
+auto DynamicIdentityTuple(const FormFieldData& f) {
+ return std::tuple_cat(CommonTuple(f), std::make_tuple(f.IsVisible()));
+}
+
+auto IdentityTuple(const FormFieldData& f) {
+ // |unique_renderer_id| uniquely identifies the field, if and only if it is
+ // set; the other members compared below (excluding label_source) together
+ // uniquely identify the field as well.
+ return std::tuple_cat(
+ SimilarityTuple(f),
+ std::tie(
+// TODO(crbug.com/896689): On iOS the unique_id member uniquely addresses
+// this field in the DOM.
+#if defined(OS_IOS)
+ f.unique_id,
+#endif
+ f.autocomplete_attribute, f.placeholder, f.max_length, f.css_classes,
+ f.is_focusable, f.should_autocomplete, f.role, f.text_direction));
}
} // namespace
@@ -155,55 +212,21 @@ FormFieldData& FormFieldData::operator=(FormFieldData&&) = default;
FormFieldData::~FormFieldData() = default;
bool FormFieldData::SameFieldAs(const FormFieldData& field) const {
-// TODO(crbug.com/896689): On iOS the unique_id member uniquely addresses
-// this field in the DOM.
-#if defined(OS_IOS)
- if (unique_id != field.unique_id)
- return false;
-#endif
-
- // A FormFieldData stores a value, but the value is not part of the identity
- // of the field, so we don't want to compare the values.
- // Similarly, flags like is_enabled, which are only used for parsing but are
- // not stored persistently, are not used for comparison.
- // is_autofilled and section are also secondary properties of a field. Two
- // fields could be the same, and have different sections, because the section
- // is updated for one, but not for the other.
- return name == field.name && id_attribute == field.id_attribute &&
- name_attribute == field.name_attribute &&
- form_control_type == field.form_control_type &&
- autocomplete_attribute == field.autocomplete_attribute &&
- placeholder == field.placeholder && max_length == field.max_length &&
- css_classes == field.css_classes &&
- // is_checked and is_autofilled counts as "value" since these change
- // when we fill things in.
- IsCheckable(check_status) == IsCheckable(field.check_status) &&
- is_focusable == field.is_focusable &&
- should_autocomplete == field.should_autocomplete &&
- role == field.role && text_direction == field.text_direction &&
- HaveSameLabel(*this, field);
- // The option values/contents which are the list of items in the list
- // of a drop-down are currently not considered part of the identity of
- // a form element. This is debatable, since one might base heuristics
- // on the types of elements that are available. Alternatively, one
- // could imagine some forms that dynamically change the element
- // contents (say, insert years starting from the current year) that
- // should not be considered changes in the structure of the form.
+ return IdentityTuple(*this) == IdentityTuple(field);
}
bool FormFieldData::SimilarFieldAs(const FormFieldData& field) const {
- return HaveSameLabel(*this, field) && name == field.name &&
- id_attribute == field.id_attribute &&
- name_attribute == field.name_attribute &&
- form_control_type == field.form_control_type &&
- IsCheckable(check_status) == IsCheckable(field.check_status);
+ return SimilarityTuple(*this) == SimilarityTuple(field);
}
bool FormFieldData::DynamicallySameFieldAs(const FormFieldData& field) const {
- return name == field.name && id_attribute == field.id_attribute &&
- name_attribute == field.name_attribute &&
- HaveSameLabel(*this, field) && IsVisible() == field.IsVisible() &&
- form_control_type == field.form_control_type;
+ return DynamicIdentityTuple(*this) == DynamicIdentityTuple(field);
+}
+
+bool FormFieldData::IdentityComparator::operator()(
+ const FormFieldData& a,
+ const FormFieldData& b) const {
+ return IdentityTuple(a) < IdentityTuple(b);
}
bool FormFieldData::IsTextInputElement() const {
@@ -228,99 +251,6 @@ bool FormFieldData::WasAutofilled() const {
return properties_mask & AUTOFILLED;
}
-bool FormFieldData::operator==(const FormFieldData& field) const {
- return SameFieldAs(field) && unique_renderer_id == field.unique_renderer_id &&
- form_control_ax_id == field.form_control_ax_id &&
- is_autofilled == field.is_autofilled &&
- check_status == field.check_status &&
- option_values == field.option_values &&
- option_contents == field.option_contents &&
- properties_mask == field.properties_mask;
-}
-
-bool FormFieldData::operator!=(const FormFieldData& field) const {
- return !(*this == field);
-}
-
-bool FormFieldData::operator<(const FormFieldData& field) const {
- // This does not use std::tie() as that generates more implicit variables
- // than the max-vartrack-size for var-tracking-assignments when compiling
- // for Android, producing build warnings. (See https://crbug.com/555171 for
- // context.)
-
- // Like SameFieldAs this ignores the value.
- if (label < field.label)
- return true;
- if (label > field.label)
- return false;
- if (name < field.name)
- return true;
- if (name > field.name)
- return false;
-
-// TODO(crbug.com/896689): On iOS the unique_id member uniquely addresses
-// this field in the DOM.
-#if defined(OS_IOS)
- if (unique_id < field.unique_id)
- return true;
- if (unique_id < field.unique_id)
- return false;
-#endif
-
- if (id_attribute < field.id_attribute)
- return true;
- if (id_attribute > field.id_attribute)
- return false;
- if (name_attribute < field.name_attribute)
- return true;
- if (name_attribute > field.name_attribute)
- return false;
- if (form_control_type < field.form_control_type)
- return true;
- if (form_control_type > field.form_control_type)
- return false;
- if (autocomplete_attribute < field.autocomplete_attribute)
- return true;
- if (autocomplete_attribute > field.autocomplete_attribute)
- return false;
- if (placeholder < field.placeholder)
- return true;
- if (placeholder > field.placeholder)
- return false;
- if (max_length < field.max_length)
- return true;
- if (max_length > field.max_length)
- return false;
- if (css_classes < field.css_classes)
- return true;
- if (css_classes > field.css_classes)
- return false;
- // Skip |is_checked| and |is_autofilled| as in SameFieldAs.
- if (IsCheckable(check_status) < IsCheckable(field.check_status))
- return true;
- if (IsCheckable(check_status) > IsCheckable(field.check_status))
- return false;
- if (is_focusable < field.is_focusable)
- return true;
- if (is_focusable > field.is_focusable)
- return false;
- if (should_autocomplete < field.should_autocomplete)
- return true;
- if (should_autocomplete > field.should_autocomplete)
- return false;
- if (role < field.role)
- return true;
- if (role > field.role)
- return false;
- if (text_direction < field.text_direction)
- return true;
- if (text_direction > field.text_direction)
- return false;
- // See SameFieldAs above for why we don't check option_values/contents and
- // flags like is_enabled.
- return false;
-}
-
void SerializeFormFieldData(const FormFieldData& field_data,
base::Pickle* pickle) {
pickle->WriteInt(kFormFieldDataPickleVersion);
diff --git a/chromium/components/autofill/core/common/form_field_data.h b/chromium/components/autofill/core/common/form_field_data.h
index 605f9e0baad..e1c8198c5c7 100644
--- a/chromium/components/autofill/core/common/form_field_data.h
+++ b/chromium/components/autofill/core/common/form_field_data.h
@@ -57,6 +57,12 @@ struct FormFieldData {
using RoleAttribute = mojom::FormFieldData_RoleAttribute;
using LabelSource = mojom::FormFieldData_LabelSource;
+ // Less-than relation for STL containers. Compares only members needed to
+ // uniquely identify a field.
+ struct IdentityComparator {
+ bool operator()(const FormFieldData& a, const FormFieldData& b) const;
+ };
+
static constexpr uint32_t kNotSetFormControlRendererId =
std::numeric_limits<uint32_t>::max();
@@ -67,20 +73,22 @@ struct FormFieldData {
FormFieldData& operator=(FormFieldData&&);
~FormFieldData();
- // Returns true if two form fields are the same, not counting the value.
+ // Returns true if both fields are identical, ignoring value- and
+ // parsing related members.
+ // See also SimilarFieldAs(), DynamicallySameFieldAs().
bool SameFieldAs(const FormFieldData& field) const;
- // SameFieldAs() is a little restricted when field's style changed
- // dynamically, like css.
- // This method only compares critical attributes of field to check whether
- // they are similar enough to be considered as same field if form's
- // other information isn't changed.
+ // Returns true if both fields are identical, ignoring members that
+ // are typically changed dynamically.
+ // Strictly weaker than SameFieldAs().
bool SimilarFieldAs(const FormFieldData& field) const;
- // If |field| is the same as this from the POV of dynamic refills.
+ // Returns true if both forms are equivalent from the POV of dynamic refills.
+ // Strictly weaker than SameFieldAs(): replaces equality of |is_focusable| and
+ // |role| with equality of IsVisible().
bool DynamicallySameFieldAs(const FormFieldData& field) const;
- // Returns true for all of textfield-looking types such as text, password,
+ // Returns true for all of textfield-looking types: text, password,
// search, email, url, and number. It must work the same way as Blink function
// WebInputElement::IsTextField(), and it returns false if |*this| represents
// a textarea.
@@ -99,15 +107,6 @@ struct FormFieldData {
bool HadFocus() const;
bool WasAutofilled() const;
- // Note: operator==() performs a full-field-comparison(byte by byte), this is
- // different from SameFieldAs(), which ignores comparison for those "values"
- // not regarded as part of identity of the field, such as is_autofilled and
- // the option_values/contents etc.
- bool operator==(const FormFieldData& field) const;
- bool operator!=(const FormFieldData& field) const;
- // Comparison operator exposed for STL map. Uses label, then name to sort.
- bool operator<(const FormFieldData& field) const;
-
#if defined(OS_IOS)
// The identifier which uniquely addresses this field in the DOM. This is an
// ephemeral value which is not guaranteed to be stable across page loads. It
@@ -122,6 +121,11 @@ struct FormFieldData {
#define EXPECT_EQ_UNIQUE_ID(expected, actual)
#endif
+ // NOTE: update IdentityComparator when adding new a member.
+ // NOTE: update SameFieldAs() if needed when adding new a member.
+ // NOTE: update SimilarFieldAs() if needed when adding new a member.
+ // NOTE: update DynamicallySameFieldAs() if needed when adding new a member.
+
// The name by which autofill knows this field. This is generally either the
// name attribute or the id_attribute value, which-ever is non-empty with
// priority given to the name_attribute. This value is used when computing
@@ -129,8 +133,6 @@ struct FormFieldData {
// TODO(crbug/896689): remove this and use attributes/unique_id instead.
base::string16 name;
- // If you add more, be sure to update the comparison operators, SameFieldAs,
- // serializing functions (in the .cc file) and the constructor.
base::string16 id_attribute;
base::string16 name_attribute;
base::string16 label;
@@ -142,10 +144,9 @@ struct FormFieldData {
base::string16 aria_label;
base::string16 aria_description;
- // Unique renderer id which is returned by function
- // WebFormControlElement::UniqueRendererFormControlId(). It is not persistant
- // between page loads, so it is not saved and not used in comparison in
- // SameFieldAs().
+ // Unique renderer id returned by WebFormElement::UniqueRendererFormId(). It
+ // is not persistent between page loads, so it is not saved and not used in
+ // comparison in SameFieldAs().
uint32_t unique_renderer_id = kNotSetFormControlRendererId;
// The ax node id of the form control in the accessibility tree.
diff --git a/chromium/components/autofill/core/common/logging/log_buffer.cc b/chromium/components/autofill/core/common/logging/log_buffer.cc
index 5abd4daa207..0f9e6c349d5 100644
--- a/chromium/components/autofill/core/common/logging/log_buffer.cc
+++ b/chromium/components/autofill/core/common/logging/log_buffer.cc
@@ -101,11 +101,10 @@ base::Value LogBuffer::RetrieveResult() {
if (!children || children->GetList().empty())
return base::Value();
- // If the fragment has a single child, return that directly.
+ // If the fragment has a single child, remove it from |children| and return
+ // that directly.
if (children->GetList().size() == 1) {
- base::Value result = std::move(children->GetList().back());
- children->GetList().pop_back();
- return result;
+ return std::move(children->TakeList().back());
}
return std::exchange(buffer_.back(), CreateEmptyFragment());
diff --git a/chromium/components/autofill/core/common/mojom/BUILD.gn b/chromium/components/autofill/core/common/mojom/BUILD.gn
index f3ca8036267..2301e4a6ca8 100644
--- a/chromium/components/autofill/core/common/mojom/BUILD.gn
+++ b/chromium/components/autofill/core/common/mojom/BUILD.gn
@@ -5,6 +5,7 @@
import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojo_types") {
+ generate_java = true
sources = [
"autofill_types.mojom",
]
diff --git a/chromium/components/autofill/core/common/mojom/autofill_types.mojom b/chromium/components/autofill/core/common/mojom/autofill_types.mojom
index 0879248916c..94502751d94 100644
--- a/chromium/components/autofill/core/common/mojom/autofill_types.mojom
+++ b/chromium/components/autofill/core/common/mojom/autofill_types.mojom
@@ -182,10 +182,11 @@ struct FormDataPredictions {
array<FormFieldDataPredictions> fields;
};
-// autofill::PasswordAndRealm
-struct PasswordAndRealm {
+// autofill::PasswordAndMetadata
+struct PasswordAndMetadata {
mojo_base.mojom.String16 password;
string realm;
+ bool uses_account_store;
};
// autofill::PasswordFormFillData
@@ -197,7 +198,8 @@ struct PasswordFormFillData {
FormFieldData password_field;
bool username_may_use_prefilled_placeholder;
string preferred_realm;
- map<mojo_base.mojom.String16, PasswordAndRealm> additional_logins;
+ bool uses_account_store;
+ map<mojo_base.mojom.String16, PasswordAndMetadata> additional_logins;
bool wait_for_username;
bool has_renderer_ids;
};
diff --git a/chromium/components/autofill/core/common/mojom/autofill_types.typemap b/chromium/components/autofill/core/common/mojom/autofill_types.typemap
index 1531e37fb14..d04ee335165 100644
--- a/chromium/components/autofill/core/common/mojom/autofill_types.typemap
+++ b/chromium/components/autofill/core/common/mojom/autofill_types.typemap
@@ -32,7 +32,7 @@ type_mappings = [
"autofill.mojom.FormFieldDataPredictions=::autofill::FormFieldDataPredictions",
"autofill.mojom.FormsPredictionsMap=::autofill::FormsPredictionsMap",
"autofill.mojom.ParsingResult=::autofill::ParsingResult",
- "autofill.mojom.PasswordAndRealm=::autofill::PasswordAndRealm",
+ "autofill.mojom.PasswordAndMetadata=::autofill::PasswordAndMetadata",
"autofill.mojom.PasswordForm=::autofill::PasswordForm",
"autofill.mojom.PasswordFormFieldPredictionMap=::autofill::PasswordFormFieldPredictionMap",
"autofill.mojom.PasswordFormFillData=::autofill::PasswordFormFillData",
diff --git a/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc b/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
index 3962a512072..0c1d1f4a3db 100644
--- a/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
+++ b/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
@@ -169,15 +169,17 @@ bool StructTraits<autofill::mojom::FormDataPredictionsDataView,
}
// static
-bool StructTraits<autofill::mojom::PasswordAndRealmDataView,
- autofill::PasswordAndRealm>::
- Read(autofill::mojom::PasswordAndRealmDataView data,
- autofill::PasswordAndRealm* out) {
+bool StructTraits<autofill::mojom::PasswordAndMetadataDataView,
+ autofill::PasswordAndMetadata>::
+ Read(autofill::mojom::PasswordAndMetadataDataView data,
+ autofill::PasswordAndMetadata* out) {
if (!data.ReadPassword(&out->password))
return false;
if (!data.ReadRealm(&out->realm))
return false;
+ out->uses_account_store = data.uses_account_store();
+
return true;
}
@@ -193,6 +195,7 @@ bool StructTraits<autofill::mojom::PasswordFormFillDataDataView,
!data.ReadAdditionalLogins(&out->additional_logins))
return false;
+ out->uses_account_store = data.uses_account_store();
out->form_renderer_id = data.form_renderer_id();
out->wait_for_username = data.wait_for_username();
out->has_renderer_ids = data.has_renderer_ids();
diff --git a/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits.h b/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
index a26fbd21849..28b4d24052e 100644
--- a/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
+++ b/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
@@ -302,18 +302,23 @@ struct StructTraits<autofill::mojom::FormDataPredictionsDataView,
};
template <>
-struct StructTraits<autofill::mojom::PasswordAndRealmDataView,
- autofill::PasswordAndRealm> {
- static const base::string16& password(const autofill::PasswordAndRealm& r) {
+struct StructTraits<autofill::mojom::PasswordAndMetadataDataView,
+ autofill::PasswordAndMetadata> {
+ static const base::string16& password(
+ const autofill::PasswordAndMetadata& r) {
return r.password;
}
- static const std::string& realm(const autofill::PasswordAndRealm& r) {
+ static const std::string& realm(const autofill::PasswordAndMetadata& r) {
return r.realm;
}
- static bool Read(autofill::mojom::PasswordAndRealmDataView data,
- autofill::PasswordAndRealm* out);
+ static bool uses_account_store(const autofill::PasswordAndMetadata& r) {
+ return r.uses_account_store;
+ }
+
+ static bool Read(autofill::mojom::PasswordAndMetadataDataView data,
+ autofill::PasswordAndMetadata* out);
};
template <>
@@ -351,7 +356,11 @@ struct StructTraits<autofill::mojom::PasswordFormFillDataDataView,
return r.preferred_realm;
}
- static const std::map<base::string16, autofill::PasswordAndRealm>&
+ static bool uses_account_store(const autofill::PasswordFormFillData& r) {
+ return r.uses_account_store;
+ }
+
+ static const std::map<base::string16, autofill::PasswordAndMetadata>&
additional_logins(const autofill::PasswordFormFillData& r) {
return r.additional_logins;
}
diff --git a/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc b/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
index 1fd64be2cfc..8b54588598a 100644
--- a/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
+++ b/chromium/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
@@ -28,6 +28,12 @@ const std::vector<const char*> kOptions = {"Option1", "Option2", "Option3",
"Option4"};
namespace {
+template <typename T>
+bool EquivalentData(const T& a, const T& b) {
+ typename T::IdentityComparator less;
+ return !less(a, b) && !less(b, a);
+}
+
void CreateTestFieldDataPredictions(const std::string& signature,
FormFieldDataPredictions* field_predict) {
test::CreateTestSelectField("TestLabel", "TestName", "TestValue", kOptions,
@@ -51,16 +57,19 @@ void CreateTestPasswordFormFillData(PasswordFormFillData* fill_data) {
"TestPasswordFieldValue", kOptions, kOptions, 4,
&fill_data->password_field);
fill_data->preferred_realm = "https://foo.com/";
+ fill_data->uses_account_store = true;
base::string16 name;
- PasswordAndRealm pr;
+ PasswordAndMetadata pr;
name = base::ASCIIToUTF16("Tom");
pr.password = base::ASCIIToUTF16("Tom_Password");
pr.realm = "https://foo.com/";
+ pr.uses_account_store = false;
fill_data->additional_logins[name] = pr;
name = base::ASCIIToUTF16("Jerry");
pr.password = base::ASCIIToUTF16("Jerry_Password");
pr.realm = "https://bar.com/";
+ pr.uses_account_store = true;
fill_data->additional_logins[name] = pr;
fill_data->wait_for_username = true;
@@ -126,9 +135,10 @@ void CheckEqualPasswordFormFillData(const PasswordFormFillData& expected,
EXPECT_EQ(expected.form_renderer_id, actual.form_renderer_id);
EXPECT_EQ(expected.origin, actual.origin);
EXPECT_EQ(expected.action, actual.action);
- EXPECT_EQ(expected.username_field, actual.username_field);
- EXPECT_EQ(expected.password_field, actual.password_field);
+ EXPECT_TRUE(EquivalentData(expected.username_field, actual.username_field));
+ EXPECT_TRUE(EquivalentData(expected.password_field, actual.password_field));
EXPECT_EQ(expected.preferred_realm, actual.preferred_realm);
+ EXPECT_EQ(expected.uses_account_store, actual.uses_account_store);
{
EXPECT_EQ(expected.additional_logins.size(),
@@ -141,6 +151,8 @@ void CheckEqualPasswordFormFillData(const PasswordFormFillData& expected,
EXPECT_EQ(iter1->first, iter2->first);
EXPECT_EQ(iter1->second.password, iter2->second.password);
EXPECT_EQ(iter1->second.realm, iter2->second.realm);
+ EXPECT_EQ(iter1->second.uses_account_store,
+ iter2->second.uses_account_store);
}
ASSERT_EQ(iter1, end1);
ASSERT_EQ(iter2, end2);
@@ -228,7 +240,7 @@ class AutofillTypeTraitsTestImpl : public testing::Test,
void ExpectFormFieldData(const FormFieldData& expected,
base::OnceClosure closure,
const FormFieldData& passed) {
- EXPECT_EQ(expected, passed);
+ EXPECT_TRUE(EquivalentData(expected, passed));
EXPECT_EQ(expected.value, passed.value);
EXPECT_EQ(expected.typed_value, passed.typed_value);
std::move(closure).Run();
@@ -237,7 +249,7 @@ void ExpectFormFieldData(const FormFieldData& expected,
void ExpectFormData(const FormData& expected,
base::OnceClosure closure,
const FormData& passed) {
- EXPECT_EQ(expected, passed);
+ EXPECT_TRUE(EquivalentData(expected, passed));
std::move(closure).Run();
}
diff --git a/chromium/components/autofill/core/common/password_form.cc b/chromium/components/autofill/core/common/password_form.cc
index d6f0044c8ea..f4ba9d4495b 100644
--- a/chromium/components/autofill/core/common/password_form.cc
+++ b/chromium/components/autofill/core/common/password_form.cc
@@ -26,8 +26,8 @@ std::string ToString(const T& obj) {
return ostream.str();
}
-std::string StoreToString(PasswordForm::Store from_store) {
- switch (from_store) {
+std::string StoreToString(PasswordForm::Store in_store) {
+ switch (in_store) {
case PasswordForm::Store::kNotSet:
return "Not Set";
case PasswordForm::Store::kProfileStore:
@@ -96,7 +96,7 @@ void PasswordFormToJSON(const PasswordForm& form,
target->SetBoolean("is_gaia_with_skip_save_password_form",
form.form_data.is_gaia_with_skip_save_password_form);
target->SetBoolean("is_new_password_reliable", form.is_new_password_reliable);
- target->SetString("from_store", StoreToString(form.from_store));
+ target->SetString("in_store", StoreToString(form.in_store));
}
} // namespace
@@ -149,7 +149,11 @@ bool PasswordForm::IsSingleUsername() const {
}
bool PasswordForm::IsUsingAccountStore() const {
- return from_store == Store::kAccountStore;
+ return in_store == Store::kAccountStore;
+}
+
+bool PasswordForm::HasNonEmptyPasswordValue() const {
+ return !password_value.empty() || !new_password_value.empty();
}
bool PasswordForm::operator==(const PasswordForm& form) const {
@@ -197,7 +201,7 @@ bool PasswordForm::operator==(const PasswordForm& form) const {
submission_event == form.submission_event &&
only_for_fallback == form.only_for_fallback &&
is_new_password_reliable == form.is_new_password_reliable &&
- from_store == form.from_store;
+ in_store == form.in_store;
}
bool PasswordForm::operator!=(const PasswordForm& form) const {
diff --git a/chromium/components/autofill/core/common/password_form.h b/chromium/components/autofill/core/common/password_form.h
index 48e63390f8b..6e2192094c6 100644
--- a/chromium/components/autofill/core/common/password_form.h
+++ b/chromium/components/autofill/core/common/password_form.h
@@ -311,7 +311,7 @@ struct PasswordForm {
// Credential came from the Gaia-account-scoped storage.
kAccountStore
};
- Store from_store = Store::kNotSet;
+ Store in_store = Store::kNotSet;
// Return true if we consider this form to be a change password form.
// We use only client heuristics, so it could include signup forms.
@@ -339,9 +339,12 @@ struct PasswordForm {
bool IsSingleUsername() const;
// Returns whether this form is stored in the account-scoped store, i.e.
- // whether |from_store == Store::kAccountStore|.
+ // whether |in_store == Store::kAccountStore|.
bool IsUsingAccountStore() const;
+ // Returns true when |password_value| or |new_password_value| are non-empty.
+ bool HasNonEmptyPasswordValue() const;
+
// Equality operators for testing.
bool operator==(const PasswordForm& form) const;
bool operator!=(const PasswordForm& form) const;
diff --git a/chromium/components/autofill/core/common/password_form_fill_data.cc b/chromium/components/autofill/core/common/password_form_fill_data.cc
index 06b7eb4de26..e6b2189c4fb 100644
--- a/chromium/components/autofill/core/common/password_form_fill_data.cc
+++ b/chromium/components/autofill/core/common/password_form_fill_data.cc
@@ -31,6 +31,7 @@ PasswordFormFillData::PasswordFormFillData(
name(form_on_page.form_data.name),
origin(form_on_page.origin),
action(form_on_page.action),
+ uses_account_store(preferred_match.IsUsingAccountStore()),
wait_for_username(wait_for_username),
has_renderer_ids(form_on_page.has_renderer_ids) {
// Note that many of the |FormFieldData| members are not initialized for
@@ -68,8 +69,9 @@ PasswordFormFillData::PasswordFormFillData(
for (const PasswordForm* match : matches) {
if (match == &preferred_match)
continue;
- PasswordAndRealm& value = additional_logins[match->username_value];
+ PasswordAndMetadata& value = additional_logins[match->username_value];
value.password = match->password_value;
+ value.uses_account_store = match->IsUsingAccountStore();
if (IsPublicSuffixMatchOrAffiliationBasedMatch(*match))
value.realm = match->signon_realm;
}
diff --git a/chromium/components/autofill/core/common/password_form_fill_data.h b/chromium/components/autofill/core/common/password_form_fill_data.h
index a94a1aeeb28..49d1a4041e4 100644
--- a/chromium/components/autofill/core/common/password_form_fill_data.h
+++ b/chromium/components/autofill/core/common/password_form_fill_data.h
@@ -21,16 +21,17 @@ struct ParsingResult {
uint32_t confirm_password_renderer_id;
};
-struct PasswordAndRealm {
+struct PasswordAndMetadata {
base::string16 password;
std::string realm;
+ bool uses_account_store = false;
};
// Structure used for autofilling password forms. Note that the realms in this
// struct are only set when the password's realm differs from the realm of the
// form that we are filling.
struct PasswordFormFillData {
- using LoginCollection = std::map<base::string16, PasswordAndRealm>;
+ using LoginCollection = std::map<base::string16, PasswordAndMetadata>;
PasswordFormFillData();
@@ -85,7 +86,11 @@ struct PasswordFormFillData {
// The signon realm of the preferred user/pass pair.
std::string preferred_realm;
- // A list of other matching username->PasswordAndRealm pairs for the form.
+ // True iff the password originated from the account store rather than the
+ // local password store.
+ bool uses_account_store = false;
+
+ // A list of other matching username->PasswordAndMetadata pairs for the form.
LoginCollection additional_logins;
// Tells us whether we need to wait for the user to enter a valid username
diff --git a/chromium/components/autofill/core/common/save_password_progress_logger.cc b/chromium/components/autofill/core/common/save_password_progress_logger.cc
index b4bd692a753..9826f0825bf 100644
--- a/chromium/components/autofill/core/common/save_password_progress_logger.cc
+++ b/chromium/components/autofill/core/common/save_password_progress_logger.cc
@@ -434,12 +434,14 @@ std::string SavePasswordProgressLogger::GetStringFromID(
return "Leak detection is off as the safe browsing is disabled";
case STRING_LEAK_DETECTION_FINISHED:
return "Leak detection finished with result";
+ case STRING_LEAK_DETECTION_HASH_ERROR:
+ return "Leak detection failed: hashing/encryption error";
+ case STRING_LEAK_DETECTION_INVALID_SERVER_RESPONSE_ERROR:
+ return "Leak detection failed: invalid server response";
case STRING_LEAK_DETECTION_SIGNED_OUT_ERROR:
return "Leak detection failed: signed out";
case STRING_LEAK_DETECTION_TOKEN_REQUEST_ERROR:
return "Leak detection failed: can't get a token";
- case STRING_LEAK_DETECTION_INVALID_SERVER_RESPONSE_ERROR:
- return "Leak detection failed: invalid server response";
case SavePasswordProgressLogger::
STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_LOWERCASE:
return "Uploading password requirements vote for using lowercase letters";
diff --git a/chromium/components/autofill/core/common/save_password_progress_logger.h b/chromium/components/autofill/core/common/save_password_progress_logger.h
index f6f4a681b76..945c41b9f0e 100644
--- a/chromium/components/autofill/core/common/save_password_progress_logger.h
+++ b/chromium/components/autofill/core/common/save_password_progress_logger.h
@@ -153,9 +153,10 @@ class SavePasswordProgressLogger {
STRING_LEAK_DETECTION_DISABLED_FEATURE,
STRING_LEAK_DETECTION_DISABLED_SAFE_BROWSING,
STRING_LEAK_DETECTION_FINISHED,
+ STRING_LEAK_DETECTION_HASH_ERROR,
+ STRING_LEAK_DETECTION_INVALID_SERVER_RESPONSE_ERROR,
STRING_LEAK_DETECTION_SIGNED_OUT_ERROR,
STRING_LEAK_DETECTION_TOKEN_REQUEST_ERROR,
- STRING_LEAK_DETECTION_INVALID_SERVER_RESPONSE_ERROR,
STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_LOWERCASE,
STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_SPECIAL_SYMBOL,
STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_SPECIFIC_SPECIAL_SYMBOL,