From 0a8abd1cd85e42b969740ca38e01df01ff244743 Mon Sep 17 00:00:00 2001 From: sebsg Date: Tue, 1 Mar 2016 12:45:03 -0800 Subject: Added two new field types : CREDIT_CARD_NAME_FIRST and CREDIT_CARD_NAME_LAST. Modified the heuristics to recognize these two new fields. Added code to be able to fill these new fields with the data already available. This will fix Keurig.com and sites like this example: https://f117f41fdbc2c18ce6861c4fac2e807ecf7f1d75.googledrive.com/host/0B3xzZ-vFr2LRU0FlVEhGa09uSDA Since it's still pretty conservative. It won't fix sites like Cabelas.com where the fields are named "firstname" and "lastname" The original heuristics predictions on Keurig.com were: NAME_FIRST | card_firstNameOnCard | First Name* NAME_LAST | card_lastNameOnCard | Last Name* UNKNOWN_TYPE | card_accountNumber | Card Number* UNKNOWN_TYPE | card_cardType | Card Type UNKNOWN_TYPE | | Please select a card type UNKNOWN_TYPE | card_expirationMonth | Expiration Date* UNKNOWN_TYPE | | Month CREDIT_CARD_EXP_MONTH | card_expirationYear | Expiration Date* CREDIT_CARD_EXP_4_DIGIT_YEAR | | Year | CREDIT_CARD_VERIFICATION_CODE | card_cvNumber | Security Code* TBR=thestig@chromium.org BUG=579174 TEST=AutofillManagerTest, FormStructureTest Review URL: https://codereview.chromium.org/1694443004 Cr-Commit-Position: refs/heads/master@{#378551} --- components/autofill.gypi | 2 + .../autofill/content/browser/wallet/full_wallet.cc | 2 +- components/autofill/core/browser/BUILD.gn | 3 + .../autofill/core/browser/autofill_data_util.cc | 132 +++++++++++++++++++++ .../autofill/core/browser/autofill_data_util.h | 28 +++++ .../core/browser/autofill_data_util_unittest.cc | 46 +++++++ components/autofill/core/browser/autofill_field.cc | 16 ++- .../core/browser/autofill_ie_toolbar_import_win.cc | 54 ++++----- .../autofill_ie_toolbar_import_win_unittest.cc | 20 ++-- .../autofill/core/browser/autofill_manager.cc | 2 +- .../core/browser/autofill_manager_unittest.cc | 38 +++++- .../autofill/core/browser/autofill_metrics.cc | 6 +- .../autofill/core/browser/autofill_profile.cc | 1 + .../core/browser/autofill_regex_constants.cc | 16 +-- .../autofill/core/browser/autofill_test_utils.cc | 2 +- components/autofill/core/browser/autofill_type.cc | 34 ++++-- components/autofill/core/browser/contact_info.cc | 128 +------------------- components/autofill/core/browser/credit_card.cc | 49 ++++---- .../autofill/core/browser/credit_card_field.cc | 22 +++- .../core/browser/credit_card_field_unittest.cc | 18 +-- .../autofill/core/browser/credit_card_unittest.cc | 20 ++-- components/autofill/core/browser/field_types.h | 12 +- components/autofill/core/browser/form_structure.cc | 8 +- .../core/browser/form_structure_unittest.cc | 88 +++++++++++--- .../core/browser/payments/payments_client.cc | 7 +- .../autofill/core/browser/personal_data_manager.cc | 6 +- .../core/browser/personal_data_manager_unittest.cc | 48 ++++---- .../core/browser/server_field_types_util.cc | 2 +- .../core/browser/webdata/autofill_table.cc | 8 +- .../browser/webdata/autofill_table_unittest.cc | 30 +++-- .../webdata/autofill_wallet_syncable_service.cc | 3 +- .../browser/webdata/web_data_service_unittest.cc | 6 +- .../autofill/ios/browser/credit_card_util.mm | 2 +- components/components_tests.gyp | 1 + 34 files changed, 557 insertions(+), 303 deletions(-) create mode 100644 components/autofill/core/browser/autofill_data_util.cc create mode 100644 components/autofill/core/browser/autofill_data_util.h create mode 100644 components/autofill/core/browser/autofill_data_util_unittest.cc (limited to 'components') diff --git a/components/autofill.gypi b/components/autofill.gypi index 8c5396d..60a1d56 100644 --- a/components/autofill.gypi +++ b/components/autofill.gypi @@ -115,6 +115,8 @@ 'autofill/core/browser/autofill_country.h', 'autofill/core/browser/autofill_data_model.cc', 'autofill/core/browser/autofill_data_model.h', + 'autofill/core/browser/autofill_data_util.cc', + 'autofill/core/browser/autofill_data_util.h', 'autofill/core/browser/autofill_download_manager.cc', 'autofill/core/browser/autofill_download_manager.h', 'autofill/core/browser/autofill_driver.h', diff --git a/components/autofill/content/browser/wallet/full_wallet.cc b/components/autofill/content/browser/wallet/full_wallet.cc index 43e901a..84e8642 100644 --- a/components/autofill/content/browser/wallet/full_wallet.cc +++ b/components/autofill/content/browser/wallet/full_wallet.cc @@ -72,7 +72,7 @@ base::string16 FullWallet::GetInfo(const std::string& app_locale, case CREDIT_CARD_NUMBER: return base::ASCIIToUTF16(GetPan()); - case CREDIT_CARD_NAME: + case CREDIT_CARD_NAME_FULL: return billing_address()->recipient_name(); case CREDIT_CARD_VERIFICATION_CODE: diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 014414b..eed6113 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn @@ -32,6 +32,8 @@ source_set("browser") { "autofill_country.h", "autofill_data_model.cc", "autofill_data_model.h", + "autofill_data_util.cc", + "autofill_data_util.h", "autofill_download_manager.cc", "autofill_download_manager.h", "autofill_driver.h", @@ -263,6 +265,7 @@ source_set("unit_tests") { "autocomplete_history_manager_unittest.cc", "autofill_country_unittest.cc", "autofill_data_model_unittest.cc", + "autofill_data_util_unittest.cc", "autofill_download_manager_unittest.cc", "autofill_external_delegate_unittest.cc", "autofill_field_unittest.cc", diff --git a/components/autofill/core/browser/autofill_data_util.cc b/components/autofill/core/browser/autofill_data_util.cc new file mode 100644 index 0000000..63dc482 --- /dev/null +++ b/components/autofill/core/browser/autofill_data_util.cc @@ -0,0 +1,132 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/autofill_data_util.h" + +#include + +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" + +namespace autofill { +namespace data_util { + +namespace { +const char* const name_prefixes[] = { + "1lt", "1st", "2lt", "2nd", "3rd", "admiral", "capt", + "captain", "col", "cpt", "dr", "gen", "general", "lcdr", + "lt", "ltc", "ltg", "ltjg", "maj", "major", "mg", + "mr", "mrs", "ms", "pastor", "prof", "rep", "reverend", + "rev", "sen", "st"}; + +const char* const name_suffixes[] = {"b.a", "ba", "d.d.s", "dds", "i", "ii", + "iii", "iv", "ix", "jr", "m.a", "m.d", + "ma", "md", "ms", "ph.d", "phd", "sr", + "v", "vi", "vii", "viii", "x"}; + +const char* const family_name_prefixes[] = {"d'", "de", "del", "der", "di", + "la", "le", "mc", "san", "st", + "ter", "van", "von"}; + +// Returns true if |set| contains |element|, modulo a final period. +bool ContainsString(const char* const set[], + size_t set_size, + const base::string16& element) { + if (!base::IsStringASCII(element)) + return false; + + base::string16 trimmed_element; + base::TrimString(element, base::ASCIIToUTF16("."), &trimmed_element); + + for (size_t i = 0; i < set_size; ++i) { + if (base::LowerCaseEqualsASCII(trimmed_element, set[i])) + return true; + } + + return false; +} + +// Removes common name prefixes from |name_tokens|. +void StripPrefixes(std::vector* name_tokens) { + std::vector::iterator iter = name_tokens->begin(); + while (iter != name_tokens->end()) { + if (!ContainsString(name_prefixes, arraysize(name_prefixes), *iter)) + break; + ++iter; + } + + std::vector copy_vector; + copy_vector.assign(iter, name_tokens->end()); + *name_tokens = copy_vector; +} + +// Removes common name suffixes from |name_tokens|. +void StripSuffixes(std::vector* name_tokens) { + while (!name_tokens->empty()) { + if (!ContainsString(name_suffixes, arraysize(name_suffixes), + name_tokens->back())) { + break; + } + name_tokens->pop_back(); + } +} + +} // namespace + +NameParts SplitName(const base::string16& name) { + std::vector name_tokens = + base::SplitString(name, base::ASCIIToUTF16(" ,"), base::KEEP_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + StripPrefixes(&name_tokens); + + // Don't assume "Ma" is a suffix in John Ma. + if (name_tokens.size() > 2) + StripSuffixes(&name_tokens); + + NameParts parts; + + if (name_tokens.empty()) { + // Bad things have happened; just assume the whole thing is a given name. + parts.given = name; + return parts; + } + + // Only one token, assume given name. + if (name_tokens.size() == 1) { + parts.given = name_tokens[0]; + return parts; + } + + // 2 or more tokens. Grab the family, which is the last word plus any + // recognizable family prefixes. + std::vector reverse_family_tokens; + reverse_family_tokens.push_back(name_tokens.back()); + name_tokens.pop_back(); + while (name_tokens.size() >= 1 && + ContainsString(family_name_prefixes, arraysize(family_name_prefixes), + name_tokens.back())) { + reverse_family_tokens.push_back(name_tokens.back()); + name_tokens.pop_back(); + } + + std::vector family_tokens(reverse_family_tokens.rbegin(), + reverse_family_tokens.rend()); + parts.family = base::JoinString(family_tokens, base::ASCIIToUTF16(" ")); + + // Take the last remaining token as the middle name (if there are at least 2 + // tokens). + if (name_tokens.size() >= 2) { + parts.middle = name_tokens.back(); + name_tokens.pop_back(); + } + + // Remainder is given name. + parts.given = base::JoinString(name_tokens, base::ASCIIToUTF16(" ")); + + return parts; +} + +} // namespace data_util +} // namespace autofill diff --git a/components/autofill/core/browser/autofill_data_util.h b/components/autofill/core/browser/autofill_data_util.h new file mode 100644 index 0000000..1cba1b3 --- /dev/null +++ b/components/autofill/core/browser/autofill_data_util.h @@ -0,0 +1,28 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_DATA_UTIL_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_DATA_UTIL_H_ + +#include "base/strings/string16.h" + +namespace autofill { +namespace data_util { + +struct NameParts { + base::string16 given; + base::string16 middle; + base::string16 family; +}; + +// TODO(crbug.com/586510): Investigate the use of app_locale to do better name +// splitting. +// Returns the different name parts (given, middle and family names) of the full +// |name| passed as a parameter. +NameParts SplitName(const base::string16& name); + +} // namespace data_util +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_DATA_UTIL_H_ diff --git a/components/autofill/core/browser/autofill_data_util_unittest.cc b/components/autofill/core/browser/autofill_data_util_unittest.cc new file mode 100644 index 0000000..ebed1f7 --- /dev/null +++ b/components/autofill/core/browser/autofill_data_util_unittest.cc @@ -0,0 +1,46 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/autofill_data_util.h" + +#include "base/strings/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { +namespace data_util { + +TEST(AutofillDataUtilTest, SplitName) { + typedef struct { + std::string full_name; + std::string given_name; + std::string middle_name; + std::string family_name; + + } TestCase; + + TestCase test_cases[] = { + // Full name including given, middle and family names. + {"Homer Jay Simpson", "Homer", "Jay", "Simpson"}, + // No middle name. + {"Moe Szyslak", "Moe", "", "Szyslak"}, + // Common name prefixes removed. + {"Reverend Timothy Lovejoy", "Timothy", "", "Lovejoy"}, + // Common name suffixes removed. + {"John Frink Phd", "John", "", "Frink"}, + // Exception to the name suffix removal. + {"John Ma", "John", "", "Ma"}, + // Common family name prefixes not considered a middle name. + {"Milhouse Van Houten", "Milhouse", "", "Van Houten"}}; + + for (TestCase test_case : test_cases) { + NameParts name_parts = SplitName(base::UTF8ToUTF16(test_case.full_name)); + + EXPECT_EQ(base::UTF8ToUTF16(test_case.given_name), name_parts.given); + EXPECT_EQ(base::UTF8ToUTF16(test_case.middle_name), name_parts.middle); + EXPECT_EQ(base::UTF8ToUTF16(test_case.family_name), name_parts.family); + } +} + +} // namespace data_util +} // namespace autofill diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc index 82b80d9e..c2f3e03 100644 --- a/components/autofill/core/browser/autofill_field.cc +++ b/components/autofill/core/browser/autofill_field.cc @@ -513,15 +513,21 @@ AutofillType AutofillField::Type() const { if (server_type_ != NO_SERVER_DATA) { // See http://crbug.com/429236 for background on why we might not always // believe the server. - // See http://crbug.com/441488 for potential improvements to the server - // which may obviate the need for this logic. + // TODO(http://crbug.com/589129) investigate how well the server is doing in + // regard to credit card predictions. bool believe_server = - !(server_type_ == NAME_FULL && heuristic_type_ == CREDIT_CARD_NAME) && - !(server_type_ == CREDIT_CARD_NAME && heuristic_type_ == NAME_FULL) && + !(server_type_ == NAME_FULL && + heuristic_type_ == CREDIT_CARD_NAME_FULL) && + !(server_type_ == CREDIT_CARD_NAME_FULL && + heuristic_type_ == NAME_FULL) && + !(server_type_ == NAME_FIRST && + heuristic_type_ == CREDIT_CARD_NAME_FIRST) && + !(server_type_ == NAME_LAST && + heuristic_type_ == CREDIT_CARD_NAME_LAST) && // CVC is sometimes type="password", which tricks the server. // See http://crbug.com/469007 !(AutofillType(server_type_).group() == PASSWORD_FIELD && - heuristic_type_ == CREDIT_CARD_VERIFICATION_CODE); + heuristic_type_ == CREDIT_CARD_VERIFICATION_CODE); if (believe_server) return AutofillType(server_type_); } diff --git a/components/autofill/core/browser/autofill_ie_toolbar_import_win.cc b/components/autofill/core/browser/autofill_ie_toolbar_import_win.cc index 15874af..508dfa0 100644 --- a/components/autofill/core/browser/autofill_ie_toolbar_import_win.cc +++ b/components/autofill/core/browser/autofill_ie_toolbar_import_win.cc @@ -103,33 +103,33 @@ struct { ServerFieldType field_type; const wchar_t *reg_value_name; } profile_reg_values[] = { - { NAME_FIRST, L"name_first" }, - { NAME_MIDDLE, L"name_middle" }, - { NAME_LAST, L"name_last" }, - { NAME_SUFFIX, L"name_suffix" }, - { EMAIL_ADDRESS, L"email" }, - { COMPANY_NAME, L"company_name" }, - { PHONE_HOME_NUMBER, L"phone_home_number" }, - { PHONE_HOME_CITY_CODE, L"phone_home_city_code" }, - { PHONE_HOME_COUNTRY_CODE, L"phone_home_country_code" }, - { ADDRESS_HOME_LINE1, L"address_home_line1" }, - { ADDRESS_HOME_LINE2, L"address_home_line2" }, - { ADDRESS_HOME_CITY, L"address_home_city" }, - { ADDRESS_HOME_STATE, L"address_home_state" }, - { ADDRESS_HOME_ZIP, L"address_home_zip" }, - { ADDRESS_HOME_COUNTRY, L"address_home_country" }, - { ADDRESS_BILLING_LINE1, L"address_billing_line1" }, - { ADDRESS_BILLING_LINE2, L"address_billing_line2" }, - { ADDRESS_BILLING_CITY, L"address_billing_city" }, - { ADDRESS_BILLING_STATE, L"address_billing_state" }, - { ADDRESS_BILLING_ZIP, L"address_billing_zip" }, - { ADDRESS_BILLING_COUNTRY, L"address_billing_country" }, - { CREDIT_CARD_NAME, L"credit_card_name" }, - { CREDIT_CARD_NUMBER, L"credit_card_number" }, - { CREDIT_CARD_EXP_MONTH, L"credit_card_exp_month" }, - { CREDIT_CARD_EXP_4_DIGIT_YEAR, L"credit_card_exp_4_digit_year" }, - { CREDIT_CARD_TYPE, L"credit_card_type" }, - // We do not import verification code. + {NAME_FIRST, L"name_first"}, + {NAME_MIDDLE, L"name_middle"}, + {NAME_LAST, L"name_last"}, + {NAME_SUFFIX, L"name_suffix"}, + {EMAIL_ADDRESS, L"email"}, + {COMPANY_NAME, L"company_name"}, + {PHONE_HOME_NUMBER, L"phone_home_number"}, + {PHONE_HOME_CITY_CODE, L"phone_home_city_code"}, + {PHONE_HOME_COUNTRY_CODE, L"phone_home_country_code"}, + {ADDRESS_HOME_LINE1, L"address_home_line1"}, + {ADDRESS_HOME_LINE2, L"address_home_line2"}, + {ADDRESS_HOME_CITY, L"address_home_city"}, + {ADDRESS_HOME_STATE, L"address_home_state"}, + {ADDRESS_HOME_ZIP, L"address_home_zip"}, + {ADDRESS_HOME_COUNTRY, L"address_home_country"}, + {ADDRESS_BILLING_LINE1, L"address_billing_line1"}, + {ADDRESS_BILLING_LINE2, L"address_billing_line2"}, + {ADDRESS_BILLING_CITY, L"address_billing_city"}, + {ADDRESS_BILLING_STATE, L"address_billing_state"}, + {ADDRESS_BILLING_ZIP, L"address_billing_zip"}, + {ADDRESS_BILLING_COUNTRY, L"address_billing_country"}, + {CREDIT_CARD_NAME_FULL, L"credit_card_name_full"}, + {CREDIT_CARD_NUMBER, L"credit_card_number"}, + {CREDIT_CARD_EXP_MONTH, L"credit_card_exp_month"}, + {CREDIT_CARD_EXP_4_DIGIT_YEAR, L"credit_card_exp_4_digit_year"}, + {CREDIT_CARD_TYPE, L"credit_card_type"}, + // We do not import verification code. }; typedef std::map RegToFieldMap; diff --git a/components/autofill/core/browser/autofill_ie_toolbar_import_win_unittest.cc b/components/autofill/core/browser/autofill_ie_toolbar_import_win_unittest.cc index 29bf783..2bf3e45 100644 --- a/components/autofill/core/browser/autofill_ie_toolbar_import_win_unittest.cc +++ b/components/autofill/core/browser/autofill_ie_toolbar_import_win_unittest.cc @@ -61,14 +61,15 @@ ValueDescription profile2[] = { }; ValueDescription credit_card[] = { - { L"credit_card_name", L"Tommy Gun" }, - // "4111111111111111" encrypted: - { L"credit_card_number", L"\xE53F\x19AB\xC1BF\xC9EB\xECCC\x9BDA\x8515" - L"\xE14D\x6852\x80A8\x50A3\x4375\xFD9F\x1E07" - L"\x790E\x7336\xB773\xAF33\x93EA\xB846\xEC89" - L"\x265C\xD0E6\x4E23\xB75F\x7983" }, - { L"credit_card_exp_month", L"11" }, - { L"credit_card_exp_4_digit_year", L"2011" }, + {L"credit_card_name_full", L"Tommy Gun"}, + // "4111111111111111" encrypted: + {L"credit_card_number", + L"\xE53F\x19AB\xC1BF\xC9EB\xECCC\x9BDA\x8515" + L"\xE14D\x6852\x80A8\x50A3\x4375\xFD9F\x1E07" + L"\x790E\x7336\xB773\xAF33\x93EA\xB846\xEC89" + L"\x265C\xD0E6\x4E23\xB75F\x7983"}, + {L"credit_card_exp_month", L"11"}, + {L"credit_card_exp_4_digit_year", L"2011"}, }; ValueDescription empty_salt = { @@ -186,7 +187,8 @@ TEST_F(AutofillIeToolbarImportTest, TestAutofillImport) { EXPECT_EQ(profile2[3].value, profiles[0].GetRawInfo(COMPANY_NAME)); ASSERT_EQ(1U, credit_cards.size()); - EXPECT_EQ(credit_card[0].value, credit_cards[0].GetRawInfo(CREDIT_CARD_NAME)); + EXPECT_EQ(credit_card[0].value, + credit_cards[0].GetRawInfo(CREDIT_CARD_NAME_FULL)); EXPECT_EQ(L"4111111111111111", credit_cards[0].GetRawInfo(CREDIT_CARD_NUMBER)); EXPECT_EQ(credit_card[2].value, diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index cbd77b5..de12b8a 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc @@ -1083,7 +1083,7 @@ bool AutofillManager::GetProfilesForCreditCardUpload( // requests that are guaranteed to fail. base::string16 verified_name; base::string16 card_name = - card.GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_); + card.GetInfo(AutofillType(CREDIT_CARD_NAME_FULL), app_locale_); if (!card_name.empty()) { verified_name = RemoveMiddleInitial(card_name); } diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc index 8a4e17e..f8e9772 100644 --- a/components/autofill/core/browser/autofill_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_manager_unittest.cc @@ -1982,6 +1982,42 @@ TEST_F(AutofillManagerTest, FillCreditCardFormYearMonth) { kDefaultPageID, false, "2012", "04"); } +// Test that we correctly fill a credit card form with first and last cardholder +// name. +TEST_F(AutofillManagerTest, FillCreditCardFormSplitName) { + // Set up our form data. + FormData form; + form.name = ASCIIToUTF16("MyForm"); + form.origin = GURL("https://myform.com/form.html"); + form.action = GURL("https://myform.com/submit.html"); + + FormFieldData field; + test::CreateTestFormField("Card Name", "cardname", "", "text", &field); + form.fields.push_back(field); + test::CreateTestFormField("Last Name", "cardlastname", "", "text", &field); + form.fields.push_back(field); + test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field); + form.fields.push_back(field); + test::CreateTestFormField("CVC", "cvc", "", "text", &field); + form.fields.push_back(field); + + std::vector forms(1, form); + FormsSeen(forms); + + const char guid[] = "00000000-0000-0000-0000-000000000004"; + int response_page_id = 0; + FormData response_data; + FillAutofillFormDataAndSaveResults(kDefaultPageID, form, *form.fields.begin(), + MakeFrontendID(guid, std::string()), + &response_page_id, &response_data); + ExpectFilledField("Card Name", "cardname", "Elvis", "text", + response_data.fields[0]); + ExpectFilledField("Last Name", "cardlastname", "Presley", "text", + response_data.fields[1]); + ExpectFilledField("Card Number", "cardnumber", "4234567890123456", "text", + response_data.fields[2]); +} + // Test that we correctly fill a combined address and credit card form. TEST_F(AutofillManagerTest, FillAddressAndCreditCardForm) { // Set up our form data. @@ -3354,7 +3390,7 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesForUpload) { {"2", PHONE_HOME_CITY_CODE}, // Credit card fields matches. - {"Elvis Presley", CREDIT_CARD_NAME}, + {"Elvis Presley", CREDIT_CARD_NAME_FULL}, {"4234-5678-9012-3456", CREDIT_CARD_NUMBER}, {"04", CREDIT_CARD_EXP_MONTH}, {"April", CREDIT_CARD_EXP_MONTH}, diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc index 5efe96a..d463edf 100644 --- a/components/autofill/core/browser/autofill_metrics.cc +++ b/components/autofill/core/browser/autofill_metrics.cc @@ -31,7 +31,7 @@ enum FieldTypeGroupForMetrics { GROUP_PHONE, GROUP_FAX, // Deprecated. GROUP_EMAIL, - GROUP_CREDIT_CARD_NAME, + GROUP_CREDIT_CARD_NAME_FULL, GROUP_CREDIT_CARD_NUMBER, GROUP_CREDIT_CARD_DATE, GROUP_CREDIT_CARD_TYPE, @@ -129,8 +129,8 @@ int GetFieldTypeGroupMetric(ServerFieldType field_type, case CREDIT_CARD: switch (field_type) { - case CREDIT_CARD_NAME: - group = GROUP_CREDIT_CARD_NAME; + case CREDIT_CARD_NAME_FULL: + group = GROUP_CREDIT_CARD_NAME_FULL; break; case CREDIT_CARD_NUMBER: group = GROUP_CREDIT_CARD_NUMBER; diff --git a/components/autofill/core/browser/autofill_profile.cc b/components/autofill/core/browser/autofill_profile.cc index e055fa6..a8098d1 100644 --- a/components/autofill/core/browser/autofill_profile.cc +++ b/components/autofill/core/browser/autofill_profile.cc @@ -292,6 +292,7 @@ AutofillProfile& AutofillProfile::operator=(const AutofillProfile& profile) { return *this; } +// TODO(crbug.com/589535): Disambiguate similar field types before uploading. void AutofillProfile::GetMatchingTypes( const base::string16& text, const std::string& app_locale, diff --git a/components/autofill/core/browser/autofill_regex_constants.cc b/components/autofill/core/browser/autofill_regex_constants.cc index db5456f..bd97024 100644 --- a/components/autofill/core/browser/autofill_regex_constants.cc +++ b/components/autofill/core/browser/autofill_regex_constants.cc @@ -124,16 +124,16 @@ const char kStateRe[] = // credit_card_field.cc ///////////////////////////////////////////////////////////////////////////// const char kNameOnCardRe[] = - "card.?(?:holder|owner)|name.*\\bon\\b.*card" + "card.?(?:holder|owner)|name.*(\\b)?on(\\b)?.*card" "|(?:card|cc).?name|cc.?full.?name" - "|karteninhaber" // de-DE - "|nombre.*tarjeta" // es - "|nom.*carte" // fr-FR - "|nome.*cart" // it-IT - "|名前" // ja-JP - "|Имя.*карты" // ru + "|karteninhaber" // de-DE + "|nombre.*tarjeta" // es + "|nom.*carte" // fr-FR + "|nome.*cart" // it-IT + "|名前" // ja-JP + "|Имя.*карты" // ru "|信用卡开户名|开户名|持卡人姓名" // zh-CN - "|持卡人姓名"; // zh-TW + "|持卡人姓名"; // zh-TW const char kNameOnCardContextualRe[] = "name"; const char kCardNumberRe[] = diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc index 8854b8b..621baa7 100644 --- a/components/autofill/core/browser/autofill_test_utils.cc +++ b/components/autofill/core/browser/autofill_test_utils.cc @@ -280,7 +280,7 @@ void SetProfileInfoWithGuid(AutofillProfile* profile, void SetCreditCardInfo(CreditCard* credit_card, const char* name_on_card, const char* card_number, const char* expiration_month, const char* expiration_year) { - check_and_set(credit_card, CREDIT_CARD_NAME, name_on_card); + check_and_set(credit_card, CREDIT_CARD_NAME_FULL, name_on_card); check_and_set(credit_card, CREDIT_CARD_NUMBER, card_number); check_and_set(credit_card, CREDIT_CARD_EXP_MONTH, expiration_month); check_and_set(credit_card, CREDIT_CARD_EXP_4_DIGIT_YEAR, expiration_year); diff --git a/components/autofill/core/browser/autofill_type.cc b/components/autofill/core/browser/autofill_type.cc index 71d4955..591220c 100644 --- a/components/autofill/core/browser/autofill_type.cc +++ b/components/autofill/core/browser/autofill_type.cc @@ -102,7 +102,9 @@ FieldTypeGroup AutofillType::group() const { case ADDRESS_BILLING_DEPENDENT_LOCALITY: return ADDRESS_BILLING; - case CREDIT_CARD_NAME: + case CREDIT_CARD_NAME_FULL: + case CREDIT_CARD_NAME_FIRST: + case CREDIT_CARD_NAME_LAST: case CREDIT_CARD_NUMBER: case CREDIT_CARD_EXP_MONTH: case CREDIT_CARD_EXP_2_DIGIT_YEAR: @@ -171,7 +173,9 @@ FieldTypeGroup AutofillType::group() const { case HTML_TYPE_FULL_ADDRESS: return html_mode_ == HTML_MODE_BILLING ? ADDRESS_BILLING : ADDRESS_HOME; - case HTML_TYPE_CREDIT_CARD_NAME: + case HTML_TYPE_CREDIT_CARD_NAME_FULL: + case HTML_TYPE_CREDIT_CARD_NAME_FIRST: + case HTML_TYPE_CREDIT_CARD_NAME_LAST: case HTML_TYPE_CREDIT_CARD_NUMBER: case HTML_TYPE_CREDIT_CARD_EXP: case HTML_TYPE_CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: @@ -340,8 +344,14 @@ ServerFieldType AutofillType::GetStorableType() const { case HTML_TYPE_FULL_ADDRESS: return UNKNOWN_TYPE; - case HTML_TYPE_CREDIT_CARD_NAME: - return CREDIT_CARD_NAME; + case HTML_TYPE_CREDIT_CARD_NAME_FULL: + return CREDIT_CARD_NAME_FULL; + + case HTML_TYPE_CREDIT_CARD_NAME_FIRST: + return CREDIT_CARD_NAME_FIRST; + + case HTML_TYPE_CREDIT_CARD_NAME_LAST: + return CREDIT_CARD_NAME_LAST; case HTML_TYPE_CREDIT_CARD_NUMBER: return CREDIT_CARD_NUMBER; @@ -570,8 +580,12 @@ std::string AutofillType::ToString() const { return "ADDRESS_BILLING_ZIP"; case ADDRESS_BILLING_COUNTRY: return "ADDRESS_BILLING_COUNTRY"; - case CREDIT_CARD_NAME: - return "CREDIT_CARD_NAME"; + case CREDIT_CARD_NAME_FULL: + return "CREDIT_CARD_NAME_FULL"; + case CREDIT_CARD_NAME_FIRST: + return "CREDIT_CARD_NAME_FIRST"; + case CREDIT_CARD_NAME_LAST: + return "CREDIT_CARD_NAME_LAST"; case CREDIT_CARD_NUMBER: return "CREDIT_CARD_NUMBER"; case CREDIT_CARD_EXP_MONTH: @@ -675,8 +689,12 @@ std::string AutofillType::ToString() const { return "HTML_TYPE_POSTAL_CODE"; case HTML_TYPE_FULL_ADDRESS: return "HTML_TYPE_FULL_ADDRESS"; - case HTML_TYPE_CREDIT_CARD_NAME: - return "HTML_TYPE_CREDIT_CARD_NAME"; + case HTML_TYPE_CREDIT_CARD_NAME_FULL: + return "HTML_TYPE_CREDIT_CARD_NAME_FULL"; + case HTML_TYPE_CREDIT_CARD_NAME_FIRST: + return "HTML_TYPE_CREDIT_CARD_NAME_FIRST"; + case HTML_TYPE_CREDIT_CARD_NAME_LAST: + return "HTML_TYPE_CREDIT_CARD_NAME_LAST"; case HTML_TYPE_CREDIT_CARD_NUMBER: return "HTML_TYPE_CREDIT_CARD_NUMBER"; case HTML_TYPE_CREDIT_CARD_EXP: diff --git a/components/autofill/core/browser/contact_info.cc b/components/autofill/core/browser/contact_info.cc index 9e793b9..8db9fc5 100644 --- a/components/autofill/core/browser/contact_info.cc +++ b/components/autofill/core/browser/contact_info.cc @@ -10,138 +10,14 @@ #include "base/logging.h" #include "base/macros.h" -#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/common/autofill_l10n_util.h" namespace autofill { -namespace { - -const char* const name_prefixes[] = { - "1lt", "1st", "2lt", "2nd", "3rd", "admiral", "capt", "captain", "col", - "cpt", "dr", "gen", "general", "lcdr", "lt", "ltc", "ltg", "ltjg", "maj", - "major", "mg", "mr", "mrs", "ms", "pastor", "prof", "rep", "reverend", - "rev", "sen", "st" }; - -const char* const name_suffixes[] = { - "b.a", "ba", "d.d.s", "dds", "i", "ii", "iii", "iv", "ix", "jr", "m.a", - "m.d", "ma", "md", "ms", "ph.d", "phd", "sr", "v", "vi", "vii", "viii", - "x" }; - -const char* const family_name_prefixes[] = { - "d'", "de", "del", "der", "di", "la", "le", "mc", "san", "st", "ter", - "van", "von" }; - -// Returns true if |set| contains |element|, modulo a final period. -bool ContainsString(const char* const set[], - size_t set_size, - const base::string16& element) { - if (!base::IsStringASCII(element)) - return false; - - base::string16 trimmed_element; - base::TrimString(element, base::ASCIIToUTF16("."), &trimmed_element); - - for (size_t i = 0; i < set_size; ++i) { - if (base::LowerCaseEqualsASCII(trimmed_element, set[i])) - return true; - } - - return false; -} - -// Removes common name prefixes from |name_tokens|. -void StripPrefixes(std::vector* name_tokens) { - std::vector::iterator iter = name_tokens->begin(); - while(iter != name_tokens->end()) { - if (!ContainsString(name_prefixes, arraysize(name_prefixes), *iter)) - break; - ++iter; - } - - std::vector copy_vector; - copy_vector.assign(iter, name_tokens->end()); - *name_tokens = copy_vector; -} - -// Removes common name suffixes from |name_tokens|. -void StripSuffixes(std::vector* name_tokens) { - while(!name_tokens->empty()) { - if (!ContainsString(name_suffixes, arraysize(name_suffixes), - name_tokens->back())) { - break; - } - name_tokens->pop_back(); - } -} - -struct NameParts { - base::string16 given; - base::string16 middle; - base::string16 family; -}; - -// TODO(estade): This does Western name splitting. It should do different -// splitting based on the app locale. -NameParts SplitName(const base::string16& name) { - std::vector name_tokens = base::SplitString( - name, base::ASCIIToUTF16(" ,"), base::KEEP_WHITESPACE, - base::SPLIT_WANT_NONEMPTY); - StripPrefixes(&name_tokens); - - // Don't assume "Ma" is a suffix in John Ma. - if (name_tokens.size() > 2) - StripSuffixes(&name_tokens); - - NameParts parts; - - if (name_tokens.empty()) { - // Bad things have happened; just assume the whole thing is a given name. - parts.given = name; - return parts; - } - - // Only one token, assume given name. - if (name_tokens.size() == 1) { - parts.given = name_tokens[0]; - return parts; - } - - // 2 or more tokens. Grab the family, which is the last word plus any - // recognizable family prefixes. - std::vector reverse_family_tokens; - reverse_family_tokens.push_back(name_tokens.back()); - name_tokens.pop_back(); - while (name_tokens.size() >= 1 && - ContainsString(family_name_prefixes, - arraysize(family_name_prefixes), - name_tokens.back())) { - reverse_family_tokens.push_back(name_tokens.back()); - name_tokens.pop_back(); - } - - std::vector family_tokens(reverse_family_tokens.rbegin(), - reverse_family_tokens.rend()); - parts.family = base::JoinString(family_tokens, base::ASCIIToUTF16(" ")); - - // Take the last remaining token as the middle name (if there are at least 2 - // tokens). - if (name_tokens.size() >= 2) { - parts.middle = name_tokens.back(); - name_tokens.pop_back(); - } - - // Remainder is given name. - parts.given = base::JoinString(name_tokens, base::ASCIIToUTF16(" ")); - - return parts; -} - -} // namespace - NameInfo::NameInfo() {} NameInfo::NameInfo(const NameInfo& info) : FormGroup() { @@ -283,7 +159,7 @@ void NameInfo::SetFullName(const base::string16& full) { if (full.empty()) return; - NameParts parts = SplitName(full); + data_util::NameParts parts = data_util::SplitName(full); given_ = parts.given; middle_ = parts.middle; family_ = parts.family; diff --git a/components/autofill/core/browser/credit_card.cc b/components/autofill/core/browser/credit_card.cc index 9083b40..29f0101 100644 --- a/components/autofill/core/browser/credit_card.cc +++ b/components/autofill/core/browser/credit_card.cc @@ -22,6 +22,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "build/build_config.h" +#include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/validation.h" @@ -264,9 +265,15 @@ CreditCard::ServerStatus CreditCard::GetServerStatus() const { base::string16 CreditCard::GetRawInfo(ServerFieldType type) const { DCHECK_EQ(CREDIT_CARD, AutofillType(type).group()); switch (type) { - case CREDIT_CARD_NAME: + case CREDIT_CARD_NAME_FULL: return name_on_card_; + case CREDIT_CARD_NAME_FIRST: + return data_util::SplitName(name_on_card_).given; + + case CREDIT_CARD_NAME_LAST: + return data_util::SplitName(name_on_card_).family; + case CREDIT_CARD_EXP_MONTH: return ExpirationMonthAsString(); @@ -312,7 +319,7 @@ void CreditCard::SetRawInfo(ServerFieldType type, const base::string16& value) { DCHECK_EQ(CREDIT_CARD, AutofillType(type).group()); switch (type) { - case CREDIT_CARD_NAME: + case CREDIT_CARD_NAME_FULL: name_on_card_ = value; break; @@ -552,10 +559,9 @@ int CreditCard::Compare(const CreditCard& credit_card) const { // The following CreditCard field types are the only types we store in the // WebDB so far, so we're only concerned with matching these types in the // credit card. - const ServerFieldType types[] = { CREDIT_CARD_NAME, - CREDIT_CARD_NUMBER, - CREDIT_CARD_EXP_MONTH, - CREDIT_CARD_EXP_4_DIGIT_YEAR }; + const ServerFieldType types[] = {CREDIT_CARD_NAME_FULL, CREDIT_CARD_NUMBER, + CREDIT_CARD_EXP_MONTH, + CREDIT_CARD_EXP_4_DIGIT_YEAR}; for (size_t i = 0; i < arraysize(types); ++i) { int comparison = GetRawInfo(types[i]).compare(credit_card.GetRawInfo(types[i])); @@ -633,8 +639,9 @@ bool CreditCard::IsValid() const { expiration_year_, expiration_month_, base::Time::Now()); } +// TODO(crbug.com/589536): Upload new credit card types to the server. void CreditCard::GetSupportedTypes(ServerFieldTypeSet* supported_types) const { - supported_types->insert(CREDIT_CARD_NAME); + supported_types->insert(CREDIT_CARD_NAME_FULL); supported_types->insert(CREDIT_CARD_NUMBER); supported_types->insert(CREDIT_CARD_TYPE); supported_types->insert(CREDIT_CARD_EXP_MONTH); @@ -763,23 +770,17 @@ bool CreditCard::ConvertMonth(const base::string16& month, // So we can compare CreditCards with EXPECT_EQ(). std::ostream& operator<<(std::ostream& os, const CreditCard& credit_card) { - return os - << base::UTF16ToUTF8(credit_card.Label()) - << " " - << credit_card.guid() - << " " - << credit_card.origin() - << " " - << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NAME)) - << " " - << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_TYPE)) - << " " - << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER)) - << " " - << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_EXP_MONTH)) - << " " - << base::UTF16ToUTF8( - credit_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); + return os << base::UTF16ToUTF8(credit_card.Label()) << " " + << credit_card.guid() << " " << credit_card.origin() << " " + << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NAME_FULL)) + << " " + << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_TYPE)) + << " " + << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER)) + << " " + << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_EXP_MONTH)) + << " " << base::UTF16ToUTF8( + credit_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); } // These values must match the values in WebKitPlatformSupportImpl in diff --git a/components/autofill/core/browser/credit_card_field.cc b/components/autofill/core/browser/credit_card_field.cc index 89d3563..871dcbb 100644 --- a/components/autofill/core/browser/credit_card_field.cc +++ b/components/autofill/core/browser/credit_card_field.cc @@ -111,6 +111,16 @@ scoped_ptr CreditCardField::Parse(AutofillScanner* scanner) { &credit_card_field->cardholder_)) { continue; } + } else if (!credit_card_field->cardholder_last_) { + // Search for a last name. Since this is a dangerously generic search, we + // execute it only after we have found a valid credit card (first) name + // and haven't yet parsed the expiration date (which usually appears at + // the end). + if (!credit_card_field->expiration_month_ && + ParseField(scanner, base::UTF8ToUTF16(kLastNameRe), + &credit_card_field->cardholder_last_)) { + continue; + } } // Check for a credit card type (Visa, MasterCard, etc.) field. @@ -328,9 +338,15 @@ void CreditCardField::AddClassifications( // then ignore both fields. Putting them into separate fields is probably // wrong, because the credit card can also contain a middle name or middle // initial. - if (cardholder_last_ == nullptr) - AddClassification(cardholder_, CREDIT_CARD_NAME, kBaseCreditCardParserScore, - field_candidates); + if (cardholder_last_ == nullptr) { + AddClassification(cardholder_, CREDIT_CARD_NAME_FULL, + kBaseCreditCardParserScore, field_candidates); + } else { + AddClassification(cardholder_, CREDIT_CARD_NAME_FIRST, + kBaseCreditCardParserScore, field_candidates); + AddClassification(cardholder_last_, CREDIT_CARD_NAME_LAST, + kBaseCreditCardParserScore, field_candidates); + } if (expiration_date_) { DCHECK(!expiration_month_); diff --git a/components/autofill/core/browser/credit_card_field_unittest.cc b/components/autofill/core/browser/credit_card_field_unittest.cc index a68c668..263505f 100644 --- a/components/autofill/core/browser/credit_card_field_unittest.cc +++ b/components/autofill/core/browser/credit_card_field_unittest.cc @@ -156,7 +156,7 @@ TEST_F(CreditCardFieldTest, ParseFullCreditCard) { field_candidates_map_[ASCIIToUTF16("type")].BestHeuristicType()); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name")) != field_candidates_map_.end()); - EXPECT_EQ(CREDIT_CARD_NAME, + EXPECT_EQ(CREDIT_CARD_NAME_FULL, field_candidates_map_[ASCIIToUTF16("name")].BestHeuristicType()); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("number")) != field_candidates_map_.end()); @@ -201,7 +201,7 @@ TEST_F(CreditCardFieldTest, ParseExpMonthYear) { AddClassifications(); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name1")) != field_candidates_map_.end()); - EXPECT_EQ(CREDIT_CARD_NAME, + EXPECT_EQ(CREDIT_CARD_NAME_FULL, field_candidates_map_[ASCIIToUTF16("name1")].BestHeuristicType()); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("number2")) != field_candidates_map_.end()); @@ -242,7 +242,7 @@ TEST_F(CreditCardFieldTest, ParseExpMonthYear2) { AddClassifications(); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name1")) != field_candidates_map_.end()); - EXPECT_EQ(CREDIT_CARD_NAME, + EXPECT_EQ(CREDIT_CARD_NAME_FULL, field_candidates_map_[ASCIIToUTF16("name1")].BestHeuristicType()); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("number2")) != field_candidates_map_.end()); @@ -279,7 +279,7 @@ TEST_F(CreditCardFieldTest, ParseExpField) { AddClassifications(); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name1")) != field_candidates_map_.end()); - EXPECT_EQ(CREDIT_CARD_NAME, + EXPECT_EQ(CREDIT_CARD_NAME_FULL, field_candidates_map_[ASCIIToUTF16("name1")].BestHeuristicType()); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("number2")) != field_candidates_map_.end()); @@ -312,7 +312,7 @@ TEST_F(CreditCardFieldTest, ParseExpField2DigitYear) { AddClassifications(); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name1")) != field_candidates_map_.end()); - EXPECT_EQ(CREDIT_CARD_NAME, + EXPECT_EQ(CREDIT_CARD_NAME_FULL, field_candidates_map_[ASCIIToUTF16("name1")].BestHeuristicType()); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("number2")) != field_candidates_map_.end()); @@ -346,7 +346,7 @@ TEST_F(CreditCardFieldTest, ParseExpField2DigitYearDueToMaxLength) { AddClassifications(); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name1")) != field_candidates_map_.end()); - EXPECT_EQ(CREDIT_CARD_NAME, + EXPECT_EQ(CREDIT_CARD_NAME_FULL, field_candidates_map_[ASCIIToUTF16("name1")].BestHeuristicType()); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("number2")) != field_candidates_map_.end()); @@ -379,7 +379,7 @@ TEST_F(CreditCardFieldTest, ParseExpField4DigitYear) { AddClassifications(); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name1")) != field_candidates_map_.end()); - EXPECT_EQ(CREDIT_CARD_NAME, + EXPECT_EQ(CREDIT_CARD_NAME_FULL, field_candidates_map_[ASCIIToUTF16("name1")].BestHeuristicType()); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("number2")) != field_candidates_map_.end()); @@ -404,7 +404,7 @@ TEST_F(CreditCardFieldTest, ParseCreditCardHolderNameWithCCFullName) { AddClassifications(); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name1")) != field_candidates_map_.end()); - EXPECT_EQ(CREDIT_CARD_NAME, + EXPECT_EQ(CREDIT_CARD_NAME_FULL, field_candidates_map_[ASCIIToUTF16("name1")].BestHeuristicType()); } @@ -573,7 +573,7 @@ TEST_F(CreditCardFieldTest, ParseMultipleCreditCardNumbers) { ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name1")) != field_candidates_map_.end()); - EXPECT_EQ(CREDIT_CARD_NAME, + EXPECT_EQ(CREDIT_CARD_NAME_FULL, field_candidates_map_[ASCIIToUTF16("name1")].BestHeuristicType()); ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("number2")) != field_candidates_map_.end()); diff --git a/components/autofill/core/browser/credit_card_unittest.cc b/components/autofill/core/browser/credit_card_unittest.cc index 135d487..10fa35f 100644 --- a/components/autofill/core/browser/credit_card_unittest.cc +++ b/components/autofill/core/browser/credit_card_unittest.cc @@ -301,23 +301,24 @@ TEST(CreditCardTest, UpdateFromImportedCard) { CreditCard b = a; b.set_guid(base::GenerateGUID()); b.set_origin("https://www.example.org"); - b.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("J. Dillinger")); + b.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("J. Dillinger")); b.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("08")); b.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2019")); EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US")); EXPECT_EQ("https://www.example.org", a.origin()); - EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME)); + EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME_FULL)); EXPECT_EQ(ASCIIToUTF16("08"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH)); EXPECT_EQ(ASCIIToUTF16("2019"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); // Try again, but with no name set for |b|. a = original_card; - b.SetRawInfo(CREDIT_CARD_NAME, base::string16()); + b.SetRawInfo(CREDIT_CARD_NAME_FULL, base::string16()); EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US")); EXPECT_EQ("https://www.example.org", a.origin()); - EXPECT_EQ(ASCIIToUTF16("John Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME)); + EXPECT_EQ(ASCIIToUTF16("John Dillinger"), + a.GetRawInfo(CREDIT_CARD_NAME_FULL)); EXPECT_EQ(ASCIIToUTF16("08"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH)); EXPECT_EQ(ASCIIToUTF16("2019"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); @@ -325,11 +326,12 @@ TEST(CreditCardTest, UpdateFromImportedCard) { // |a| should be unchanged. a = original_card; a.set_origin("Chrome settings"); - b.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("J. Dillinger")); + b.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("J. Dillinger")); EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US")); EXPECT_EQ("Chrome settings", a.origin()); - EXPECT_EQ(ASCIIToUTF16("John Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME)); + EXPECT_EQ(ASCIIToUTF16("John Dillinger"), + a.GetRawInfo(CREDIT_CARD_NAME_FULL)); EXPECT_EQ(ASCIIToUTF16("09"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH)); EXPECT_EQ(ASCIIToUTF16("2017"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); @@ -339,7 +341,7 @@ TEST(CreditCardTest, UpdateFromImportedCard) { EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US")); EXPECT_EQ("Chrome settings", a.origin()); - EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME)); + EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME_FULL)); EXPECT_EQ(ASCIIToUTF16("08"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH)); EXPECT_EQ(ASCIIToUTF16("2019"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); @@ -350,7 +352,7 @@ TEST(CreditCardTest, UpdateFromImportedCard) { EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US")); EXPECT_EQ("Chrome settings", a.origin()); - EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME)); + EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME_FULL)); EXPECT_EQ(ASCIIToUTF16("08"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH)); EXPECT_EQ(ASCIIToUTF16("2019"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); @@ -366,7 +368,7 @@ TEST(CreditCardTest, UpdateFromImportedCard) { TEST(CreditCardTest, IsComplete) { CreditCard card(base::GenerateGUID(), "https://www.example.com/"); EXPECT_FALSE(card.IsComplete()); - card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Wally T. Walrus")); + card.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Wally T. Walrus")); EXPECT_FALSE(card.IsComplete()); card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01")); EXPECT_FALSE(card.IsComplete()); diff --git a/components/autofill/core/browser/field_types.h b/components/autofill/core/browser/field_types.h index 4edce98..63410fe 100644 --- a/components/autofill/core/browser/field_types.h +++ b/components/autofill/core/browser/field_types.h @@ -72,7 +72,7 @@ enum ServerFieldType { // ADDRESS_SHIPPING values [44,50] are deprecated. - CREDIT_CARD_NAME = 51, + CREDIT_CARD_NAME_FULL = 51, CREDIT_CARD_NUMBER = 52, CREDIT_CARD_EXP_MONTH = 53, CREDIT_CARD_EXP_2_DIGIT_YEAR = 54, @@ -149,10 +149,14 @@ enum ServerFieldType { PROBABLY_NEW_PASSWORD = 89, NOT_NEW_PASSWORD = 90, + // Additional field types for credit card fields. + CREDIT_CARD_NAME_FIRST = 91, + CREDIT_CARD_NAME_LAST = 92, + // No new types can be added without a corresponding change to the Autofill // server. - MAX_VALID_FIELD_TYPE = 91, + MAX_VALID_FIELD_TYPE = 93, }; // The list of all HTML autocomplete field type hints supported by Chrome. @@ -184,7 +188,9 @@ enum HtmlFieldType { HTML_TYPE_FULL_ADDRESS, // The complete address, formatted for display. // Credit card types. - HTML_TYPE_CREDIT_CARD_NAME, + HTML_TYPE_CREDIT_CARD_NAME_FULL, + HTML_TYPE_CREDIT_CARD_NAME_FIRST, + HTML_TYPE_CREDIT_CARD_NAME_LAST, HTML_TYPE_CREDIT_CARD_NUMBER, HTML_TYPE_CREDIT_CARD_EXP, HTML_TYPE_CREDIT_CARD_EXP_MONTH, diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 5260c12..2b1a312 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc @@ -209,7 +209,13 @@ HtmlFieldType FieldTypeFromAutocompleteAttributeValue( } if (autocomplete_attribute_value == "cc-name") - return HTML_TYPE_CREDIT_CARD_NAME; + return HTML_TYPE_CREDIT_CARD_NAME_FULL; + + if (autocomplete_attribute_value == "cc-given-name") + return HTML_TYPE_CREDIT_CARD_NAME_FIRST; + + if (autocomplete_attribute_value == "cc-family-name") + return HTML_TYPE_CREDIT_CARD_NAME_LAST; if (autocomplete_attribute_value == "cc-number") return HTML_TYPE_CREDIT_CARD_NUMBER; diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc index 4162781..fcf555a 100644 --- a/components/autofill/core/browser/form_structure_unittest.cc +++ b/components/autofill/core/browser/form_structure_unittest.cc @@ -1280,7 +1280,7 @@ TEST_F(FormStructureTest, HeuristicsCreditCardInfo) { ASSERT_EQ(5U, form_structure->autofill_count()); // Credit card name. - EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); + EXPECT_EQ(CREDIT_CARD_NAME_FULL, form_structure->field(0)->heuristic_type()); // Credit card number. EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(1)->heuristic_type()); // Credit card expiration month. @@ -1340,7 +1340,7 @@ TEST_F(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { ASSERT_EQ(5U, form_structure->autofill_count()); // Credit card name. - EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); + EXPECT_EQ(CREDIT_CARD_NAME_FULL, form_structure->field(0)->heuristic_type()); // Credit card type. This is an unknown type but related to the credit card. EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type()); // Credit card number. @@ -1703,7 +1703,7 @@ TEST_F(FormStructureTest, HeuristicsInfernoCC) { EXPECT_EQ(5U, form_structure->autofill_count()); // Name on Card. - EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); + EXPECT_EQ(CREDIT_CARD_NAME_FULL, form_structure->field(0)->heuristic_type()); // Address. EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(1)->heuristic_type()); // Card Number. @@ -1715,7 +1715,9 @@ TEST_F(FormStructureTest, HeuristicsInfernoCC) { form_structure->field(4)->heuristic_type()); } -TEST_F(FormStructureTest, CVCCodeClash) { +// Tests that the heuristics detect split credit card names if they appear in +// the middle of the form. +TEST_F(FormStructureTest, HeuristicsInferCCNames_NamesNotFirst) { scoped_ptr form_structure; FormData form; @@ -1751,15 +1753,73 @@ TEST_F(FormStructureTest, CVCCodeClash) { EXPECT_TRUE(form_structure->IsAutofillable()); // Expect the correct number of fields. - EXPECT_EQ(6U, form_structure->field_count()); - EXPECT_EQ(6U, form_structure->autofill_count()); + ASSERT_EQ(6U, form_structure->field_count()); + ASSERT_EQ(6U, form_structure->autofill_count()); // Card Number. EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(0)->heuristic_type()); - // First name, taken as name on card. - EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(1)->heuristic_type()); - // Last name is picked up by the name parser. - EXPECT_EQ(NAME_LAST, form_structure->field(2)->heuristic_type()); + // First name. + EXPECT_EQ(CREDIT_CARD_NAME_FIRST, form_structure->field(1)->heuristic_type()); + // Last name. + EXPECT_EQ(CREDIT_CARD_NAME_LAST, form_structure->field(2)->heuristic_type()); + // Expiration Date. + EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type()); + // Expiration Year. + EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, + form_structure->field(4)->heuristic_type()); + // CVC code. + EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, + form_structure->field(5)->heuristic_type()); +} + +// Tests that the heuristics detect split credit card names if they appear at +// the beginning of the form. The first name has to contains some credit card +// keyword. +TEST_F(FormStructureTest, HeuristicsInferCCNames_NamesFirst) { + scoped_ptr form_structure; + FormData form; + + FormFieldData field; + field.form_control_type = "text"; + + field.label = ASCIIToUTF16("Cardholder Name"); + field.name = ASCIIToUTF16("cc_first_name"); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Last name"); + field.name = ASCIIToUTF16("last_name"); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Card number"); + field.name = ASCIIToUTF16("ccnumber"); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("Expiration date"); + field.name = ASCIIToUTF16("ccexpiresmonth"); + form.fields.push_back(field); + + field.label = base::string16(); + field.name = ASCIIToUTF16("ccexpiresyear"); + form.fields.push_back(field); + + field.label = ASCIIToUTF16("cvc number"); + field.name = ASCIIToUTF16("csc"); + form.fields.push_back(field); + + form_structure.reset(new FormStructure(form)); + form_structure->DetermineHeuristicTypes(); + EXPECT_TRUE(form_structure->IsAutofillable()); + + // Expect the correct number of fields. + ASSERT_EQ(6U, form_structure->field_count()); + ASSERT_EQ(6U, form_structure->autofill_count()); + + // First name. + EXPECT_EQ(CREDIT_CARD_NAME_FIRST, form_structure->field(0)->heuristic_type()); + // Last name. + EXPECT_EQ(CREDIT_CARD_NAME_LAST, form_structure->field(1)->heuristic_type()); + // Card Number. + EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type()); // Expiration Date. EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type()); // Expiration Year. @@ -2753,7 +2813,7 @@ TEST_F(FormStructureTest, CheckDataPresence) { // datapresent should be "0000000000001fc0" == trimmmed(0x0000000000001fc0) == // 0b0000000000000000000000000000000000000000000000000001111111000000 // The set bits are: - // 51 == CREDIT_CARD_NAME + // 51 == CREDIT_CARD_NAME_FULL // 52 == CREDIT_CARD_NUMBER // 53 == CREDIT_CARD_EXP_MONTH // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR @@ -2761,7 +2821,7 @@ TEST_F(FormStructureTest, CheckDataPresence) { // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR available_field_types.clear(); - available_field_types.insert(CREDIT_CARD_NAME); + available_field_types.insert(CREDIT_CARD_NAME_FULL); available_field_types.insert(CREDIT_CARD_NUMBER); available_field_types.insert(CREDIT_CARD_EXP_MONTH); available_field_types.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR); @@ -2801,7 +2861,7 @@ TEST_F(FormStructureTest, CheckDataPresence) { // 34 == ADDRESS_HOME_STATE // 35 == ADDRESS_HOME_ZIP // 36 == ADDRESS_HOME_COUNTRY - // 51 == CREDIT_CARD_NAME + // 51 == CREDIT_CARD_NAME_FULL // 52 == CREDIT_CARD_NUMBER // 53 == CREDIT_CARD_EXP_MONTH // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR @@ -2827,7 +2887,7 @@ TEST_F(FormStructureTest, CheckDataPresence) { available_field_types.insert(ADDRESS_HOME_STATE); available_field_types.insert(ADDRESS_HOME_ZIP); available_field_types.insert(ADDRESS_HOME_COUNTRY); - available_field_types.insert(CREDIT_CARD_NAME); + available_field_types.insert(CREDIT_CARD_NAME_FULL); available_field_types.insert(CREDIT_CARD_NUMBER); available_field_types.insert(CREDIT_CARD_EXP_MONTH); available_field_types.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR); diff --git a/components/autofill/core/browser/payments/payments_client.cc b/components/autofill/core/browser/payments/payments_client.cc index 24c9207..27694ad 100644 --- a/components/autofill/core/browser/payments/payments_client.cc +++ b/components/autofill/core/browser/payments/payments_client.cc @@ -294,9 +294,10 @@ class UploadCardRequest : public PaymentsRequest { context->SetString("language_code", app_locale); request_dict.Set("context", std::move(context)); - request_dict.SetString("cardholder_name", - request_details_.card.GetInfo( - AutofillType(CREDIT_CARD_NAME), app_locale)); + request_dict.SetString( + "cardholder_name", + request_details_.card.GetInfo(AutofillType(CREDIT_CARD_NAME_FULL), + app_locale)); scoped_ptr addresses(new base::ListValue()); for (const AutofillProfile& profile : request_details_.profiles) { diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index d2e69a1..3ef8d1d 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc @@ -820,9 +820,9 @@ std::vector PersonalDataManager::GetCreditCardSuggestions( suggestion->label = credit_card->GetInfo( AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale_); } else if (credit_card->number().empty()) { - if (type.GetStorableType() != CREDIT_CARD_NAME) { - suggestion->label = - credit_card->GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_); + if (type.GetStorableType() != CREDIT_CARD_NAME_FULL) { + suggestion->label = credit_card->GetInfo( + AutofillType(CREDIT_CARD_NAME_FULL), app_locale_); } } else { #if defined(OS_ANDROID) diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index 28deb80..9964f7a 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc @@ -501,7 +501,7 @@ TEST_F(PersonalDataManagerTest, AddUpdateRemoveCreditCards) { ExpectSameElements(cards, personal_data_->GetCreditCards()); // Update, remove, and add. - credit_card0.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Joe")); + credit_card0.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Joe")); personal_data_->UpdateCreditCard(credit_card0); personal_data_->RemoveByGUID(credit_card1.guid()); personal_data_->AddCreditCard(credit_card2); @@ -585,7 +585,7 @@ TEST_F(PersonalDataManagerTest, UpdateUnverifiedProfilesAndCreditCards) { // Try to update with data changed as well. profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); - credit_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Joe")); + credit_card.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Joe")); personal_data_->UpdateProfile(profile); personal_data_->UpdateCreditCard(credit_card); @@ -839,17 +839,17 @@ TEST_F(PersonalDataManagerTest, PopulateUniqueIDsOnLoad) { TEST_F(PersonalDataManagerTest, SetUniqueCreditCardLabels) { CreditCard credit_card0(base::GenerateGUID(), "https://www.example.com"); - credit_card0.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("John")); + credit_card0.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("John")); CreditCard credit_card1(base::GenerateGUID(), "https://www.example.com"); - credit_card1.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Paul")); + credit_card1.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Paul")); CreditCard credit_card2(base::GenerateGUID(), "https://www.example.com"); - credit_card2.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Ringo")); + credit_card2.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Ringo")); CreditCard credit_card3(base::GenerateGUID(), "https://www.example.com"); - credit_card3.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Other")); + credit_card3.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Other")); CreditCard credit_card4(base::GenerateGUID(), "https://www.example.com"); - credit_card4.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Ozzy")); + credit_card4.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Ozzy")); CreditCard credit_card5(base::GenerateGUID(), "https://www.example.com"); - credit_card5.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Dio")); + credit_card5.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Dio")); // Add the test credit cards to the database. personal_data_->AddCreditCard(credit_card0); @@ -2520,7 +2520,7 @@ TEST_F(PersonalDataManagerTest, SaveImportedCreditCardWithVerifiedData) { CreditCard new_verified_card = credit_card; new_verified_card.set_guid(base::GenerateGUID()); - new_verified_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("B. Small")); + new_verified_card.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("B. Small")); EXPECT_TRUE(new_verified_card.IsVerified()); personal_data_->SaveImportedCreditCard(new_verified_card); @@ -2533,7 +2533,8 @@ TEST_F(PersonalDataManagerTest, SaveImportedCreditCardWithVerifiedData) { // Expect that the saved credit card is updated. const std::vector& results = personal_data_->GetCreditCards(); ASSERT_EQ(1U, results.size()); - EXPECT_EQ(ASCIIToUTF16("B. Small"), results[0]->GetRawInfo(CREDIT_CARD_NAME)); + EXPECT_EQ(ASCIIToUTF16("B. Small"), + results[0]->GetRawInfo(CREDIT_CARD_NAME_FULL)); } TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) { @@ -2650,7 +2651,7 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) { EXPECT_TRUE(non_empty_types.count(PHONE_HOME_COUNTRY_CODE)); EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_AND_NUMBER)); EXPECT_TRUE(non_empty_types.count(PHONE_HOME_WHOLE_NUMBER)); - EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_NAME)); + EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_NAME_FULL)); EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_NUMBER)); EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_TYPE)); EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_EXP_MONTH)); @@ -2700,27 +2701,29 @@ TEST_F(PersonalDataManagerTest, IncognitoReadOnly) { steve_jobs.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Steve")); personal_data_->SaveImportedProfile(steve_jobs); - bill_gates.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Bill Gates")); + bill_gates.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Bill Gates")); personal_data_->SaveImportedCreditCard(bill_gates); ResetPersonalDataManager(USER_MODE_INCOGNITO); EXPECT_EQ(ASCIIToUTF16("Steven"), personal_data_->GetProfiles()[0]->GetRawInfo(NAME_FIRST)); - EXPECT_EQ(ASCIIToUTF16("William H. Gates"), - personal_data_->GetCreditCards()[0]->GetRawInfo(CREDIT_CARD_NAME)); + EXPECT_EQ( + ASCIIToUTF16("William H. Gates"), + personal_data_->GetCreditCards()[0]->GetRawInfo(CREDIT_CARD_NAME_FULL)); // Updating existing profiles shouldn't work. steve_jobs.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Steve")); personal_data_->UpdateProfile(steve_jobs); - bill_gates.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Bill Gates")); + bill_gates.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Bill Gates")); personal_data_->UpdateCreditCard(bill_gates); ResetPersonalDataManager(USER_MODE_INCOGNITO); EXPECT_EQ(ASCIIToUTF16("Steven"), personal_data_->GetProfiles()[0]->GetRawInfo(NAME_FIRST)); - EXPECT_EQ(ASCIIToUTF16("William H. Gates"), - personal_data_->GetCreditCards()[0]->GetRawInfo(CREDIT_CARD_NAME)); + EXPECT_EQ( + ASCIIToUTF16("William H. Gates"), + personal_data_->GetCreditCards()[0]->GetRawInfo(CREDIT_CARD_NAME_FULL)); // Removing shouldn't work. personal_data_->RemoveByGUID(steve_jobs.guid()); @@ -3025,7 +3028,7 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_LocalCardsRanking) { // the platform, but the last 4 digits should appear). std::vector suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NAME), + AutofillType(CREDIT_CARD_NAME_FULL), /* field_contents= */ base::string16()); ASSERT_EQ(3U, suggestions.size()); @@ -3072,7 +3075,7 @@ TEST_F(PersonalDataManagerTest, std::vector suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NAME), + AutofillType(CREDIT_CARD_NAME_FULL), /* field_contents= */ base::string16()); ASSERT_EQ(5U, suggestions.size()); @@ -3171,7 +3174,7 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ServerDuplicates) { std::vector suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NAME), + AutofillType(CREDIT_CARD_NAME_FULL), /* field_contents= */ base::string16()); ASSERT_EQ(4U, suggestions.size()); EXPECT_EQ(ASCIIToUTF16("John Dillinger"), suggestions[0].value); @@ -3218,7 +3221,7 @@ TEST_F(PersonalDataManagerTest, std::vector suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NAME), + AutofillType(CREDIT_CARD_NAME_FULL), /* field_contents= */ base::string16()); ASSERT_EQ(3U, suggestions.size()); @@ -3234,7 +3237,8 @@ TEST_F(PersonalDataManagerTest, base::MessageLoop::current()->Run(); suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NAME), /* field_contents= */ base::string16()); + AutofillType(CREDIT_CARD_NAME_FULL), + /* field_contents= */ base::string16()); ASSERT_EQ(3U, suggestions.size()); } diff --git a/components/autofill/core/browser/server_field_types_util.cc b/components/autofill/core/browser/server_field_types_util.cc index 1d004f5..6d27d3e 100644 --- a/components/autofill/core/browser/server_field_types_util.cc +++ b/components/autofill/core/browser/server_field_types_util.cc @@ -51,7 +51,7 @@ bool ServerTypeMatchesField(DialogSection section, AutofillType field_type = field.Type(); // The credit card name is filled from the billing section's data. - if (field_type.GetStorableType() == CREDIT_CARD_NAME && + if (field_type.GetStorableType() == CREDIT_CARD_NAME_FULL && section == SECTION_BILLING) { return type == NAME_BILLING_FULL; } diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc index 07a291c..2b40540 100644 --- a/components/autofill/core/browser/webdata/autofill_table.cc +++ b/components/autofill/core/browser/webdata/autofill_table.cc @@ -140,7 +140,7 @@ void BindCreditCardToStatement(const CreditCard& credit_card, int index = 0; s->BindString(index++, credit_card.guid()); - s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_NAME)); + s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_NAME_FULL)); s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_EXP_MONTH)); s->BindString16(index++, GetInfo(credit_card, CREDIT_CARD_EXP_4_DIGIT_YEAR)); BindEncryptedCardToColumn(s, index++, @@ -173,7 +173,7 @@ scoped_ptr CreditCardFromStatement(const sql::Statement& s) { credit_card->set_guid(s.ColumnString(index++)); DCHECK(base::IsValidGUID(credit_card->guid())); - credit_card->SetRawInfo(CREDIT_CARD_NAME, s.ColumnString16(index++)); + credit_card->SetRawInfo(CREDIT_CARD_NAME_FULL, s.ColumnString16(index++)); credit_card->SetRawInfo(CREDIT_CARD_EXP_MONTH, s.ColumnString16(index++)); credit_card->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, s.ColumnString16(index++)); @@ -1228,7 +1228,7 @@ bool AutofillTable::GetServerCreditCards( } card->SetServerStatus(ServerStatusStringToEnum(s.ColumnString(index++))); - card->SetRawInfo(CREDIT_CARD_NAME, s.ColumnString16(index++)); + card->SetRawInfo(CREDIT_CARD_NAME_FULL, s.ColumnString16(index++)); card->SetRawInfo(CREDIT_CARD_EXP_MONTH, s.ColumnString16(index++)); card->SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, s.ColumnString16(index++)); credit_cards->push_back(card); @@ -1265,7 +1265,7 @@ void AutofillTable::SetServerCreditCards( masked_insert.BindString(1, card.type()); masked_insert.BindString(2, ServerStatusEnumToString(card.GetServerStatus())); - masked_insert.BindString16(3, card.GetRawInfo(CREDIT_CARD_NAME)); + masked_insert.BindString16(3, card.GetRawInfo(CREDIT_CARD_NAME_FULL)); masked_insert.BindString16(4, card.LastFourDigits()); masked_insert.BindString16(5, card.GetRawInfo(CREDIT_CARD_EXP_MONTH)); masked_insert.BindString16(6, diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc index 8d36d58..e81c82a 100644 --- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc @@ -914,7 +914,8 @@ TEST_F(AutofillTableTest, CreditCard) { // Add a 'Work' credit card. CreditCard work_creditcard; work_creditcard.set_origin("https://www.example.com/"); - work_creditcard.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Jack Torrance")); + work_creditcard.SetRawInfo(CREDIT_CARD_NAME_FULL, + ASCIIToUTF16("Jack Torrance")); work_creditcard.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1234567890123456")); work_creditcard.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("04")); @@ -944,7 +945,8 @@ TEST_F(AutofillTableTest, CreditCard) { // Add a 'Target' credit card. CreditCard target_creditcard; target_creditcard.set_origin(std::string()); - target_creditcard.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Jack Torrance")); + target_creditcard.SetRawInfo(CREDIT_CARD_NAME_FULL, + ASCIIToUTF16("Jack Torrance")); target_creditcard.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1111222233334444")); target_creditcard.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("06")); @@ -970,7 +972,8 @@ TEST_F(AutofillTableTest, CreditCard) { // Update the 'Target' credit card. target_creditcard.set_origin("Interactive Autofill dialog"); - target_creditcard.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Charles Grady")); + target_creditcard.SetRawInfo(CREDIT_CARD_NAME_FULL, + ASCIIToUTF16("Charles Grady")); Time pre_modification_time = Time::Now(); EXPECT_TRUE(table_->UpdateCreditCard(target_creditcard)); Time post_modification_time = Time::Now(); @@ -1077,7 +1080,7 @@ TEST_F(AutofillTableTest, UpdateAutofillProfile) { TEST_F(AutofillTableTest, UpdateCreditCard) { // Add a credit card to the db. CreditCard credit_card; - credit_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Jack Torrance")); + credit_card.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Jack Torrance")); credit_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1234567890123456")); credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("04")); credit_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2013")); @@ -1203,7 +1206,7 @@ TEST_F(AutofillTableTest, UpdateProfileOriginOnly) { TEST_F(AutofillTableTest, UpdateCreditCardOriginOnly) { // Add a credit card to the db. CreditCard credit_card; - credit_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Jack Torrance")); + credit_card.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Jack Torrance")); credit_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1234567890123456")); credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("04")); credit_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2013")); @@ -1563,14 +1566,14 @@ TEST_F(AutofillTableTest, Autofill_GetAllAutofillEntries_TwoSame) { TEST_F(AutofillTableTest, SetGetServerCards) { std::vector inputs; inputs.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "a123")); - inputs[0].SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Paul F. Tompkins")); + inputs[0].SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Paul F. Tompkins")); inputs[0].SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("1")); inputs[0].SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2020")); inputs[0].SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111")); inputs.push_back( CreditCard(CreditCard::MASKED_SERVER_CARD, "b456")); - inputs[1].SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Rick Roman")); + inputs[1].SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Rick Roman")); inputs[1].SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("12")); inputs[1].SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("1997")); inputs[1].SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1111")); @@ -1608,7 +1611,7 @@ TEST_F(AutofillTableTest, MaskUnmaskServerCards) { base::string16 masked_number(ASCIIToUTF16("1111")); std::vector inputs; inputs.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123")); - inputs[0].SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Jay Johnson")); + inputs[0].SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Jay Johnson")); inputs[0].SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("1")); inputs[0].SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2020")); inputs[0].SetRawInfo(CREDIT_CARD_NUMBER, masked_number); @@ -1645,7 +1648,8 @@ TEST_F(AutofillTableTest, MaskUnmaskServerCards) { TEST_F(AutofillTableTest, SetServerCardModify) { // Add a masked card. CreditCard masked_card(CreditCard::MASKED_SERVER_CARD, "a123"); - masked_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Paul F. Tompkins")); + masked_card.SetRawInfo(CREDIT_CARD_NAME_FULL, + ASCIIToUTF16("Paul F. Tompkins")); masked_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("1")); masked_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2020")); masked_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1111")); @@ -1684,7 +1688,7 @@ TEST_F(AutofillTableTest, SetServerCardModify) { // Set inputs that do not include our old card. CreditCard random_card(CreditCard::MASKED_SERVER_CARD, "b456"); - random_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Rick Roman")); + random_card.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Rick Roman")); random_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("12")); random_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("1997")); random_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("2222")); @@ -1719,7 +1723,8 @@ TEST_F(AutofillTableTest, SetServerCardModify) { TEST_F(AutofillTableTest, SetServerCardUpdateUsageStats) { // Add a masked card. CreditCard masked_card(CreditCard::MASKED_SERVER_CARD, "a123"); - masked_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Paul F. Tompkins")); + masked_card.SetRawInfo(CREDIT_CARD_NAME_FULL, + ASCIIToUTF16("Paul F. Tompkins")); masked_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("1")); masked_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2020")); masked_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1111")); @@ -1857,7 +1862,8 @@ TEST_F(AutofillTableTest, DeleteUnmaskedCard) { // Add a masked card. base::string16 masked_number = ASCIIToUTF16("1111"); CreditCard masked_card(CreditCard::MASKED_SERVER_CARD, "a123"); - masked_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Paul F. Tompkins")); + masked_card.SetRawInfo(CREDIT_CARD_NAME_FULL, + ASCIIToUTF16("Paul F. Tompkins")); masked_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("1")); masked_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2020")); masked_card.SetRawInfo(CREDIT_CARD_NUMBER, masked_number); diff --git a/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc index 56d54b1..ae584e7 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc @@ -70,7 +70,8 @@ CreditCard CardFromSpecifics(const sync_pb::WalletMaskedCreditCard& card) { result.SetNumber(base::UTF8ToUTF16(card.last_four())); result.SetServerStatus(ServerToLocalStatus(card.status())); result.SetTypeForMaskedCard(CardTypeFromWalletCardType(card.type())); - result.SetRawInfo(CREDIT_CARD_NAME, base::UTF8ToUTF16(card.name_on_card())); + result.SetRawInfo(CREDIT_CARD_NAME_FULL, + base::UTF8ToUTF16(card.name_on_card())); result.SetExpirationMonth(card.exp_month()); result.SetExpirationYear(card.exp_year()); return result; diff --git a/components/autofill/core/browser/webdata/web_data_service_unittest.cc b/components/autofill/core/browser/webdata/web_data_service_unittest.cc index 26c5b64..87545b4 100644 --- a/components/autofill/core/browser/webdata/web_data_service_unittest.cc +++ b/components/autofill/core/browser/webdata/web_data_service_unittest.cc @@ -440,10 +440,10 @@ TEST_F(WebDataServiceAutofillTest, CreditCardRemove) { TEST_F(WebDataServiceAutofillTest, CreditUpdate) { CreditCard card1("E4D2662E-5E16-44F3-AF5A-5A77FAE4A6F3", "https://ejemplo.mx"); - card1.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Abe")); + card1.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Abe")); CreditCard card2("B9C52112-BD5F-4080-84E1-C651D2CB90E2", "https://example.com"); - card2.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Alice")); + card2.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Alice")); wds_->AddCreditCard(card1); wds_->AddCreditCard(card2); @@ -460,7 +460,7 @@ TEST_F(WebDataServiceAutofillTest, CreditUpdate) { STLDeleteElements(&consumer.result()); CreditCard card2_changed(card2); - card2_changed.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Bill")); + card2_changed.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Bill")); wds_->UpdateCreditCard(card2_changed); WaitForDatabaseThread(); diff --git a/components/autofill/ios/browser/credit_card_util.mm b/components/autofill/ios/browser/credit_card_util.mm index 8d4d625..e62b9e8 100644 --- a/components/autofill/ios/browser/credit_card_util.mm +++ b/components/autofill/ios/browser/credit_card_util.mm @@ -13,7 +13,7 @@ namespace autofill { NSString* GetCreditCardName(const CreditCard& credit_card, const std::string& locale) { return base::SysUTF16ToNSString(credit_card.GetInfo( - autofill::AutofillType(autofill::CREDIT_CARD_NAME), locale)); + autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL), locale)); } NSString* GetCreditCardObfuscatedNumber(const CreditCard& credit_card) { diff --git a/components/components_tests.gyp b/components/components_tests.gyp index f85fe0a..04793f5 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp @@ -29,6 +29,7 @@ 'autofill/core/browser/autocomplete_history_manager_unittest.cc', 'autofill/core/browser/autofill_country_unittest.cc', 'autofill/core/browser/autofill_data_model_unittest.cc', + 'autofill/core/browser/autofill_data_util_unittest.cc', 'autofill/core/browser/autofill_download_manager_unittest.cc', 'autofill/core/browser/autofill_external_delegate_unittest.cc', 'autofill/core/browser/autofill_field_unittest.cc', -- cgit v1.1