Commit 211b5b7b authored by Matthias Körber's avatar Matthias Körber Committed by Commit Bot

[Autofill][Slimshady] Give heuristics precedence for Spanish last name types.

This CL grants precedence to the heuristic field type detection if a
structured last name type is detected.

Change-Id: Ic058b13b641328ed4bc583d786836f71d527dbe7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2353347
Commit-Queue: Matthias Körber <koerber@google.com>
Reviewed-by: default avatarChristoph Schwering <schwering@google.com>
Cr-Commit-Position: refs/heads/master@{#798487}
parent 29723f90
...@@ -903,6 +903,7 @@ void FormStructure::ProcessQueryResponse( ...@@ -903,6 +903,7 @@ void FormStructure::ProcessQueryResponse(
form->UpdateAutofillCount(); form->UpdateAutofillCount();
form->RationalizeRepeatedFields(form_interactions_ukm_logger); form->RationalizeRepeatedFields(form_interactions_ukm_logger);
form->RationalizeFieldTypePredictions(); form->RationalizeFieldTypePredictions();
form->OverrideServerPredictionsWithHeuristics();
form->IdentifySections(false); form->IdentifySections(false);
} }
...@@ -1860,6 +1861,25 @@ void FormStructure::RationalizeAddressStateCountry( ...@@ -1860,6 +1861,25 @@ void FormStructure::RationalizeAddressStateCountry(
} }
} }
void FormStructure::OverrideServerPredictionsWithHeuristics() {
if (!base::FeatureList::IsEnabled(
features::kAutofillEnableSupportForMoreStructureInNames)) {
return;
}
for (const auto& field : fields_) {
// If the heuristic type is |LAST_NAME_SECOND| or |LAST_NAME_FIRST|
// unconditionally use this prediction.
switch (field->heuristic_type()) {
case NAME_LAST_SECOND:
case NAME_LAST_FIRST:
field->SetTypeTo(AutofillType(field->heuristic_type()));
break;
default: {
};
}
}
}
void FormStructure::RationalizeRepeatedFields( void FormStructure::RationalizeRepeatedFields(
AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger) { AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger) {
// The type of every field whose index is in // The type of every field whose index is in
......
...@@ -211,6 +211,10 @@ class FormStructure { ...@@ -211,6 +211,10 @@ class FormStructure {
// the fields that are considered composing a first complete phone number. // the fields that are considered composing a first complete phone number.
void RationalizePhoneNumbersInSection(std::string section); void RationalizePhoneNumbersInSection(std::string section);
// Overrides server predictions with specific heuristic predictions:
// * NAME_LAST_SECOND heuristic predictions are unconditionally used.
void OverrideServerPredictionsWithHeuristics();
const AutofillField* field(size_t index) const; const AutofillField* field(size_t index) const;
AutofillField* field(size_t index); AutofillField* field(size_t index);
size_t field_count() const; size_t field_count() const;
......
...@@ -5197,6 +5197,88 @@ TEST_F(FormStructureTest, PossibleValues) { ...@@ -5197,6 +5197,88 @@ TEST_F(FormStructureTest, PossibleValues) {
EXPECT_EQ(0U, form_structure2.PossibleValues(ADDRESS_BILLING_COUNTRY).size()); EXPECT_EQ(0U, form_structure2.PossibleValues(ADDRESS_BILLING_COUNTRY).size());
} }
// Test the heuristic predictions the NAME_LAST_SECOND override server
// predictions.
TEST_F(FormStructureTest,
ParseQueryResponse_HeuristicsOverrideSpanishLastNameTypes) {
base::test::ScopedFeatureList scoped_feature;
scoped_feature.InitAndEnableFeature(
features::kAutofillEnableSupportForMoreStructureInNames);
FormData form_data;
FormFieldData field;
form_data.url = GURL("http://foo.com");
field.form_control_type = "text";
// First name field.
field.label = ASCIIToUTF16("Nombre");
field.name = ASCIIToUTF16("Nombre");
form_data.fields.push_back(field);
// First last name field.
// Should be identified by local heuristics.
field.label = ASCIIToUTF16("Apellido Paterno");
field.name = ASCIIToUTF16("apellido_paterno");
form_data.fields.push_back(field);
// Second last name field.
// Should be identified by local heuristics.
field.label = ASCIIToUTF16("Apellido Materno");
field.name = ASCIIToUTF16("apellido materno");
form_data.fields.push_back(field);
FormStructure form(form_data);
form.DetermineHeuristicTypes();
// Setup the query response.
AutofillQueryResponseContents response;
std::string response_string;
response.add_field()->set_overall_type_prediction(NAME_FIRST);
// Simulate a NAME_LAST classification for the two last name fields.
response.add_field()->set_overall_type_prediction(NAME_LAST);
response.add_field()->set_overall_type_prediction(NAME_LAST);
ASSERT_TRUE(response.SerializeToString(&response_string));
// Parse the response and update the field type predictions.
std::vector<FormStructure*> forms{&form};
FormStructure::ParseQueryResponse(response_string, forms,
test::GetEncodedSignatures(forms), nullptr);
ASSERT_EQ(form.field_count(), 3U);
// Validate the heuristic and server predictions.
EXPECT_EQ(NAME_LAST_FIRST, form.field(1)->heuristic_type());
EXPECT_EQ(NAME_LAST_SECOND, form.field(2)->heuristic_type());
EXPECT_EQ(NAME_LAST, form.field(1)->server_type());
EXPECT_EQ(NAME_LAST, form.field(2)->server_type());
// Validate that the heuristic prediction wins for the two last name fields.
EXPECT_EQ(form.field(0)->Type().GetStorableType(), NAME_FIRST);
EXPECT_EQ(form.field(1)->Type().GetStorableType(), NAME_LAST_FIRST);
EXPECT_EQ(form.field(2)->Type().GetStorableType(), NAME_LAST_SECOND);
// Now disable the feature and process the query again.
scoped_feature.Reset();
scoped_feature.InitAndDisableFeature(
features::kAutofillEnableSupportForMoreStructureInNames);
std::vector<FormStructure*> forms2{&form};
FormStructure::ParseQueryResponse(
response_string, forms2, test::GetEncodedSignatures(forms2), nullptr);
ASSERT_EQ(form.field_count(), 3U);
// Validate the heuristic and server predictions.
EXPECT_EQ(NAME_LAST_FIRST, form.field(1)->heuristic_type());
EXPECT_EQ(NAME_LAST_SECOND, form.field(2)->heuristic_type());
EXPECT_EQ(NAME_LAST, form.field(1)->server_type());
EXPECT_EQ(NAME_LAST, form.field(2)->server_type());
// Validate that the heuristic prediction does not win for the two last name
// fields.
EXPECT_EQ(form.field(0)->Type().GetStorableType(), NAME_FIRST);
EXPECT_EQ(form.field(1)->Type().GetStorableType(), NAME_LAST);
EXPECT_EQ(form.field(2)->Type().GetStorableType(), NAME_LAST);
}
// Tests proper resolution heuristic, server and html field types when the // Tests proper resolution heuristic, server and html field types when the
// server returns NO_SERVER_DATA, UNKNOWN_TYPE, and a valid type. // server returns NO_SERVER_DATA, UNKNOWN_TYPE, and a valid type.
TEST_F(FormStructureTest, ParseQueryResponse_TooManyTypes) { TEST_F(FormStructureTest, ParseQueryResponse_TooManyTypes) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment