summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgeorgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-23 18:24:32 +0000
committergeorgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-23 18:24:32 +0000
commit11c2bdd10912ce3c4a8b9e1f67399e18014d2a19 (patch)
tree3ffbc51e575c7ea7daa582c6b3d41891870e9d7d
parente430bd8865e9444cd8cb742145395addaa4918bd (diff)
downloadchromium_src-11c2bdd10912ce3c4a8b9e1f67399e18014d2a19.zip
chromium_src-11c2bdd10912ce3c4a8b9e1f67399e18014d2a19.tar.gz
chromium_src-11c2bdd10912ce3c4a8b9e1f67399e18014d2a19.tar.bz2
Autofill phone number enhancements and integration of Phone Number Util Library: part 3
BUG=71443 TEST=unit-tested Review URL: http://codereview.chromium.org/6877130 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86305 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/autofill/autofill_ie_toolbar_import_win.cc29
-rw-r--r--chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc10
-rw-r--r--chrome/browser/autofill/autofill_manager_unittest.cc17
-rw-r--r--chrome/browser/autofill/autofill_profile.cc94
-rw-r--r--chrome/browser/autofill/autofill_profile.h18
-rw-r--r--chrome/browser/autofill/autofill_profile_unittest.cc68
-rw-r--r--chrome/browser/autofill/personal_data_manager.cc84
-rw-r--r--chrome/browser/autofill/personal_data_manager_mac.mm29
-rw-r--r--chrome/browser/autofill/personal_data_manager_unittest.cc17
-rw-r--r--chrome/browser/autofill/phone_field.cc4
-rw-r--r--chrome/browser/autofill/phone_number.cc312
-rw-r--r--chrome/browser/autofill/phone_number.h84
-rw-r--r--chrome/browser/autofill/phone_number_i18n.cc11
-rw-r--r--chrome/browser/autofill/phone_number_i18n_unittest.cc29
-rw-r--r--chrome/browser/autofill/phone_number_unittest.cc268
-rw-r--r--chrome/test/data/autofill/merge/input/multimerge.in8
-rw-r--r--chrome/test/data/autofill/merge/input/primarycase.in8
-rw-r--r--chrome/test/data/autofill/merge/input/singlemerge.in8
-rw-r--r--chrome/test/data/autofill/merge/output/multimerge.out6
-rw-r--r--chrome/test/data/autofill/merge/output/primarycase.out6
-rw-r--r--chrome/test/data/autofill/merge/output/singlemerge.out4
21 files changed, 642 insertions, 472 deletions
diff --git a/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc
index 5829c5c..96a4ba1 100644
--- a/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc
+++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc
@@ -19,6 +19,8 @@
#include "chrome/browser/autofill/field_types.h"
#include "chrome/browser/autofill/form_group.h"
#include "chrome/browser/autofill/personal_data_manager.h"
+#include "chrome/browser/autofill/phone_number.h"
+#include "chrome/browser/autofill/phone_number_i18n.h"
#include "chrome/browser/sync/util/data_encryption.h"
using base::win::RegKey;
@@ -131,6 +133,10 @@ bool ImportSingleProfile(FormGroup* profile,
bool has_non_empty_fields = false;
+ // Phones need to be rebuilt.
+ PhoneNumber::PhoneCombineHelper home(AutofillType::PHONE_HOME);
+ PhoneNumber::PhoneCombineHelper fax(AutofillType::PHONE_FAX);
+
for (uint32 value_index = 0; value_index < key->ValueCount(); ++value_index) {
std::wstring value_name;
if (key->ReadName(value_index, &value_name) != ERROR_SUCCESS)
@@ -144,9 +150,21 @@ bool ImportSingleProfile(FormGroup* profile,
if (it->second == CREDIT_CARD_NUMBER) {
field_value = DecryptCCNumber(field_value);
}
- profile->SetInfo(it->second, field_value);
+ // We need to store phone data in the variables, before building the whole
+ // number at the end. The rest of the fields are set "as is".
+ if (!home.SetInfo(it->second, field_value) &&
+ !fax.SetInfo(it->second, field_value)) {
+ profile->SetInfo(it->second, field_value);
+ }
}
}
+ // Now re-construct the phones if needed.
+ string16 constructed_number;
+ if (!home.empty() && home.ParseNumber(std::string("US"), &constructed_number))
+ profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number);
+ if (!fax.empty() && fax.ParseNumber(std::string("US"), &constructed_number))
+ profile->SetInfo(PHONE_FAX_WHOLE_NUMBER, constructed_number);
+
return has_non_empty_fields;
}
@@ -219,15 +237,6 @@ bool ImportCurrentUserProfiles(std::vector<AutofillProfile>* profiles,
AutofillProfile profile;
if (ImportSingleProfile(&profile, &key, reg_to_field)) {
// Combine phones into whole phone #.
- string16 phone;
- phone = profile.GetInfo(PHONE_HOME_COUNTRY_CODE);
- phone.append(profile.GetInfo(PHONE_HOME_CITY_CODE));
- phone.append(profile.GetInfo(PHONE_HOME_NUMBER));
- profile.SetInfo(PHONE_HOME_WHOLE_NUMBER, phone);
- phone = profile.GetInfo(PHONE_FAX_COUNTRY_CODE);
- phone.append(profile.GetInfo(PHONE_FAX_CITY_CODE));
- phone.append(profile.GetInfo(PHONE_FAX_NUMBER));
- profile.SetInfo(PHONE_FAX_WHOLE_NUMBER, phone);
profiles->push_back(profile);
}
}
diff --git a/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc b/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc
index b115038..240055f 100644
--- a/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc
+++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc
@@ -44,7 +44,7 @@ ValueDescription profile1[] = {
{ L"email", L"jdoe@test.com" },
{ L"company_name", L"Testcompany" },
{ L"phone_home_number", L"555-5555" },
- { L"phone_home_city_code", L"444" },
+ { L"phone_home_city_code", L"650" },
{ L"phone_home_country_code", L"1" },
};
@@ -54,8 +54,8 @@ ValueDescription profile2[] = {
{ L"email", L"janedoe@test.com" },
{ L"company_name", L"Testcompany" },
{ L"phone_fax_number", L"555-6666" },
- { L"phone_fax_city_code", L"777" },
- { L"phone_fax_country_code", L"2" },
+ { L"phone_fax_city_code", L"812" },
+ { L"phone_fax_country_code", L"7" },
};
ValueDescription credit_card[] = {
@@ -171,7 +171,7 @@ TEST_F(AutofillIeToolbarImportTest, TestAutofillImport) {
EXPECT_EQ(profiles[1].GetInfo(PHONE_HOME_COUNTRY_CODE), profile1[7].value);
EXPECT_EQ(profiles[1].GetInfo(PHONE_HOME_CITY_CODE), profile1[6].value);
EXPECT_EQ(profiles[1].GetInfo(PHONE_HOME_NUMBER), L"5555555");
- EXPECT_EQ(profiles[1].GetInfo(PHONE_HOME_WHOLE_NUMBER), L"14445555555");
+ EXPECT_EQ(profiles[1].GetInfo(PHONE_HOME_WHOLE_NUMBER), L"+16505555555");
EXPECT_EQ(profiles[0].GetInfo(NAME_FIRST), profile2[0].value);
EXPECT_EQ(profiles[0].GetInfo(NAME_LAST), profile2[1].value);
@@ -180,7 +180,7 @@ TEST_F(AutofillIeToolbarImportTest, TestAutofillImport) {
EXPECT_EQ(profiles[0].GetInfo(PHONE_FAX_COUNTRY_CODE), profile2[6].value);
EXPECT_EQ(profiles[0].GetInfo(PHONE_FAX_CITY_CODE), profile2[5].value);
EXPECT_EQ(profiles[0].GetInfo(PHONE_FAX_NUMBER), L"5556666");
- EXPECT_EQ(profiles[0].GetInfo(PHONE_FAX_WHOLE_NUMBER), L"27775556666");
+ EXPECT_EQ(profiles[0].GetInfo(PHONE_FAX_WHOLE_NUMBER), L"+78125556666");
ASSERT_EQ(credit_cards.size(), 1);
EXPECT_EQ(credit_cards[0].GetInfo(CREDIT_CARD_NAME), credit_card[0].value);
diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc
index 35ae16e..f576f64 100644
--- a/chrome/browser/autofill/autofill_manager_unittest.cc
+++ b/chrome/browser/autofill/autofill_manager_unittest.cc
@@ -1879,16 +1879,15 @@ TEST_F(AutofillManagerTest, FillPhoneNumber) {
AutofillProfile *work_profile = autofill_manager_->GetProfileWithGUID(
"00000000-0000-0000-0000-000000000002");
ASSERT_TRUE(work_profile != NULL);
- string16 saved_phone = work_profile->GetInfo(PHONE_HOME_NUMBER);
GUIDPair guid(work_profile->guid(), 0);
GUIDPair empty(std::string(), 0);
- char test_data[] = "1234567890123456";
+ char test_data[] = "16505554567890123456";
for (int i = arraysize(test_data) - 1; i >= 0; --i) {
test_data[i] = 0;
SCOPED_TRACE(StringPrintf("Testing phone: %s", test_data));
- work_profile->SetInfo(PHONE_HOME_NUMBER, ASCIIToUTF16(test_data));
+ work_profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16(test_data));
// The page ID sent to the AutofillManager from the RenderView, used to send
// an IPC message back to the renderer.
int page_id = 100 - i;
@@ -1899,17 +1898,15 @@ TEST_F(AutofillManagerTest, FillPhoneNumber) {
FormData results;
EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
- if (i != 7) {
- EXPECT_EQ(ASCIIToUTF16(test_data), results.fields[2].value);
- EXPECT_EQ(ASCIIToUTF16(test_data), results.fields[3].value);
+ if (i != 11) {
+ // The only parsable phone is 16505554567.
+ EXPECT_EQ(string16(), results.fields[2].value);
+ EXPECT_EQ(string16(), results.fields[3].value);
} else {
- // The only size that is parsed and split, right now is 7:
- EXPECT_EQ(ASCIIToUTF16("123"), results.fields[2].value);
+ EXPECT_EQ(ASCIIToUTF16("555"), results.fields[2].value);
EXPECT_EQ(ASCIIToUTF16("4567"), results.fields[3].value);
}
}
-
- work_profile->SetInfo(PHONE_HOME_NUMBER, saved_phone);
}
// Test that we can still fill a form when a field has been removed from it.
diff --git a/chrome/browser/autofill/autofill_profile.cc b/chrome/browser/autofill/autofill_profile.cc
index f359799..4df95bd 100644
--- a/chrome/browser/autofill/autofill_profile.cc
+++ b/chrome/browser/autofill/autofill_profile.cc
@@ -15,8 +15,8 @@
#include "chrome/browser/autofill/address.h"
#include "chrome/browser/autofill/autofill_type.h"
#include "chrome/browser/autofill/contact_info.h"
-#include "chrome/browser/autofill/fax_number.h"
-#include "chrome/browser/autofill/home_phone_number.h"
+#include "chrome/browser/autofill/phone_number.h"
+#include "chrome/browser/autofill/phone_number_i18n.h"
#include "chrome/common/guid.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
@@ -117,13 +117,14 @@ const string16 MultiString(const AutofillProfile& p, AutofillFieldType type) {
template <class T>
void CopyValuesToItems(AutofillFieldType type,
const std::vector<string16>& values,
- std::vector<T>* form_group_items) {
+ std::vector<T>* form_group_items,
+ const T& prototype) {
form_group_items->resize(values.size());
for (size_t i = 0; i < form_group_items->size(); ++i)
(*form_group_items)[i].SetInfo(type, CollapseWhitespace(values[i], false));
// Must have at least one (possibly empty) element.
if (form_group_items->empty())
- form_group_items->resize(1);
+ form_group_items->resize(1, prototype);
}
template <class T>
@@ -174,18 +175,42 @@ void CollapseCompoundFieldTypes(FieldTypeSet* type_set) {
std::swap(*type_set, collapsed_set);
}
+class FindByPhone {
+ public:
+ FindByPhone(const string16& phone, const std::string& country_code)
+ : phone_(phone),
+ country_code_(country_code) {
+ }
+
+ bool operator()(const string16& phone) {
+ return autofill_i18n::PhoneNumbersMatch(phone, phone_, country_code_);
+ }
+
+ bool operator()(const string16* phone) {
+ return autofill_i18n::PhoneNumbersMatch(*phone, phone_, country_code_);
+ }
+
+ private:
+ string16 phone_;
+ std::string country_code_;
+};
+
} // namespace
AutofillProfile::AutofillProfile(const std::string& guid)
- : guid_(guid), name_(1), email_(1), home_number_(1), fax_number_(1) {
+ : guid_(guid),
+ name_(1),
+ email_(1),
+ home_number_(1, PhoneNumber(AutofillType::PHONE_HOME)),
+ fax_number_(1, PhoneNumber(AutofillType::PHONE_FAX)) {
}
AutofillProfile::AutofillProfile()
: guid_(guid::GenerateGUID()),
name_(1),
email_(1),
- home_number_(1),
- fax_number_(1) {
+ home_number_(1, PhoneNumber(AutofillType::PHONE_HOME)),
+ fax_number_(1, PhoneNumber(AutofillType::PHONE_FAX)) {
}
AutofillProfile::AutofillProfile(const AutofillProfile& profile)
@@ -246,16 +271,22 @@ void AutofillProfile::SetMultiInfo(AutofillFieldType type,
const std::vector<string16>& values) {
switch (AutofillType(type).group()) {
case AutofillType::NAME:
- CopyValuesToItems(type, values, &name_);
+ CopyValuesToItems(type, values, &name_, NameInfo());
break;
case AutofillType::EMAIL:
- CopyValuesToItems(type, values, &email_);
+ CopyValuesToItems(type, values, &email_, EmailInfo());
break;
case AutofillType::PHONE_HOME:
- CopyValuesToItems(type, values, &home_number_);
+ CopyValuesToItems(type,
+ values,
+ &home_number_,
+ PhoneNumber(AutofillType::PHONE_HOME));
break;
case AutofillType::PHONE_FAX:
- CopyValuesToItems(type, values, &fax_number_);
+ CopyValuesToItems(type,
+ values,
+ &fax_number_,
+ PhoneNumber(AutofillType::PHONE_FAX));
break;
default:
if (values.size() == 1) {
@@ -463,6 +494,22 @@ const string16 AutofillProfile::PrimaryValue() const {
GetInfo(ADDRESS_HOME_CITY);
}
+bool AutofillProfile::NormalizePhones() {
+ // Successful either if nothing to parse, or everything is parsed correctly.
+ bool success = true;
+ for (size_t i = 0; i < home_number_.size(); ++i) {
+ home_number_[i].set_locale(CountryCode());
+ if (!home_number_[i].NormalizePhone())
+ success = false;
+ }
+ for (size_t i = 0; i < fax_number_.size(); ++i) {
+ fax_number_[i].set_locale(CountryCode());
+ if (!fax_number_[i].NormalizePhone())
+ success = false;
+ }
+ return success;
+}
+
void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile) {
FieldTypeSet field_types;
profile.GetNonEmptyTypes(&field_types);
@@ -478,12 +525,18 @@ void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile) {
profile.GetMultiInfo(*iter, &new_values);
std::vector<string16> existing_values;
GetMultiInfo(*iter, &existing_values);
+ FieldTypeGroup group = AutofillType(*iter).group();
for (std::vector<string16>::iterator value_iter = new_values.begin();
value_iter != new_values.end(); ++value_iter) {
// Don't add duplicates.
- if (std::find(existing_values.begin(), existing_values.end(),
- *value_iter) == existing_values.end()) {
- existing_values.insert(existing_values.end(), *value_iter);
+ if (group == AutofillType::PHONE_HOME ||
+ group == AutofillType::PHONE_FAX) {
+ AddPhoneIfUnique(*value_iter, &existing_values);
+ } else {
+ if (std::find(existing_values.begin(), existing_values.end(),
+ *value_iter) == existing_values.end()) {
+ existing_values.insert(existing_values.end(), *value_iter);
+ }
}
}
SetMultiInfo(*iter, existing_values);
@@ -493,6 +546,19 @@ void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile) {
}
}
+void AutofillProfile::AddPhoneIfUnique(const string16& phone,
+ std::vector<string16>* existing_phones) {
+ DCHECK(existing_phones);
+ // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377",
+ // "(800)356-9377" and "356-9377" are considered the same.
+ std::vector<string16>::const_iterator phone_iter;
+ if (std::find_if(existing_phones->begin(), existing_phones->end(),
+ FindByPhone(phone, CountryCode())) ==
+ existing_phones->end()) {
+ existing_phones->push_back(phone);
+ }
+}
+
string16 AutofillProfile::ConstructInferredLabel(
const std::vector<AutofillFieldType>& included_fields,
size_t num_fields_to_use) const {
diff --git a/chrome/browser/autofill/autofill_profile.h b/chrome/browser/autofill/autofill_profile.h
index 80a54e8..1ff9d8d 100644
--- a/chrome/browser/autofill/autofill_profile.h
+++ b/chrome/browser/autofill/autofill_profile.h
@@ -119,6 +119,13 @@ class AutofillProfile : public FormGroup {
// aid with correct aggregation of new data.
const string16 PrimaryValue() const;
+ // Normalizes the home phone and fax numbers.
+ // Should be called after all of the form data is imported into profile.
+ // Drops unparsable numbers, so the numbers that are incomplete or wrong
+ // are not saved. Returns true if all numbers were successfully parsed,
+ // false otherwise.
+ bool NormalizePhones();
+
// Overwrites the single-valued field data in |profile| with this
// Profile. Or, for multi-valued fields append the new values.
void OverwriteWithOrAddTo(const AutofillProfile& profile);
@@ -126,6 +133,13 @@ class AutofillProfile : public FormGroup {
private:
typedef std::vector<const FormGroup*> FormGroupList;
+ // Checks if the |phone| is in the |existing_phones| using fuzzy matching:
+ // for example, "1-800-FLOWERS", "18003569377", "(800)356-9377" and "356-9377"
+ // are considered the same.
+ // Adds the |phone| to the |existing_phones| if not already there.
+ void AddPhoneIfUnique(const string16& phone,
+ std::vector<string16>* existing_phones);
+
// Builds inferred label from the first |num_fields_to_include| non-empty
// fields in |label_fields|. Uses as many fields as possible if there are not
// enough non-empty fields.
@@ -161,8 +175,8 @@ class AutofillProfile : public FormGroup {
std::vector<NameInfo> name_;
std::vector<EmailInfo> email_;
CompanyInfo company_;
- std::vector<HomePhoneNumber> home_number_;
- std::vector<FaxNumber> fax_number_;
+ std::vector<PhoneNumber> home_number_;
+ std::vector<PhoneNumber> fax_number_;
Address address_;
};
diff --git a/chrome/browser/autofill/autofill_profile_unittest.cc b/chrome/browser/autofill/autofill_profile_unittest.cc
index 28b5f84..8bfb3ba 100644
--- a/chrome/browser/autofill/autofill_profile_unittest.cc
+++ b/chrome/browser/autofill/autofill_profile_unittest.cc
@@ -39,7 +39,7 @@ TEST(AutofillProfileTest, PreviewSummaryString) {
AutofillProfile profile00;
autofill_test::SetProfileInfo(&profile00, "", "Mitchell", "",
"johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", "91601", "US",
- "12345678910", "01987654321");
+ "16505678910", "78127654321");
EXPECT_TRUE(UpdateProfileLabel(&profile00));
string16 summary00 = profile00.Label();
EXPECT_EQ(ASCIIToUTF16("Hollywood, CA"), summary00);
@@ -48,7 +48,7 @@ TEST(AutofillProfileTest, PreviewSummaryString) {
AutofillProfile profile1;
autofill_test::SetProfileInfo(&profile1, "", "Mitchell", "",
"johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
- "91601", "US", "12345678910", "01987654321");
+ "91601", "US", "16505678910", "78127654321");
EXPECT_TRUE(UpdateProfileLabel(&profile1));
string16 summary1 = profile1.Label();
EXPECT_EQ(ASCIIToUTF16("123 Zoo St., Hollywood"), summary1);
@@ -57,7 +57,7 @@ TEST(AutofillProfileTest, PreviewSummaryString) {
AutofillProfile profile2;
autofill_test::SetProfileInfo(&profile2, "", "Mitchell",
"Morrison", "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA",
- "91601", "US", "12345678910", "01987654321");
+ "91601", "US", "16505678910", "78127654321");
EXPECT_TRUE(UpdateProfileLabel(&profile2));
string16 summary2 = profile2.Label();
// Summary does include full name which is empty if the first name is empty.
@@ -67,7 +67,7 @@ TEST(AutofillProfileTest, PreviewSummaryString) {
AutofillProfile profile3;
autofill_test::SetProfileInfo(&profile3, "", "Mitchell",
"Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
- "Hollywood", "CA", "91601", "US", "12345678910", "01987654321");
+ "Hollywood", "CA", "91601", "US", "16505678910", "78127654321");
EXPECT_TRUE(UpdateProfileLabel(&profile3));
string16 summary3 = profile3.Label();
EXPECT_EQ(ASCIIToUTF16("123 Zoo St., Hollywood"), summary3);
@@ -76,7 +76,7 @@ TEST(AutofillProfileTest, PreviewSummaryString) {
AutofillProfile profile4;
autofill_test::SetProfileInfo(&profile4, "Marion", "Mitchell", "",
"johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", "91601", "US",
- "12345678910", "01987654321");
+ "16505678910", "01987654321");
EXPECT_TRUE(UpdateProfileLabel(&profile4));
string16 summary4 = profile4.Label();
EXPECT_EQ(ASCIIToUTF16("Marion Mitchell, Hollywood"), summary4);
@@ -85,7 +85,7 @@ TEST(AutofillProfileTest, PreviewSummaryString) {
AutofillProfile profile5;
autofill_test::SetProfileInfo(&profile5, "Marion", "Mitchell", "",
"johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
- "91601", "US", "12345678910", "01987654321");
+ "91601", "US", "16505678910", "78127654321");
EXPECT_TRUE(UpdateProfileLabel(&profile5));
string16 summary5 = profile5.Label();
EXPECT_EQ(ASCIIToUTF16("Marion Mitchell, 123 Zoo St."), summary5);
@@ -94,7 +94,7 @@ TEST(AutofillProfileTest, PreviewSummaryString) {
AutofillProfile profile6;
autofill_test::SetProfileInfo(&profile6, "Marion", "Mitchell",
"Morrison", "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA",
- "91601", "US", "12345678910", "01987654321");
+ "91601", "US", "16505678910", "78127654321");
EXPECT_TRUE(UpdateProfileLabel(&profile6));
string16 summary6 = profile6.Label();
EXPECT_EQ(ASCIIToUTF16("Marion Mitchell Morrison, Hollywood"),
@@ -104,7 +104,7 @@ TEST(AutofillProfileTest, PreviewSummaryString) {
AutofillProfile profile7;
autofill_test::SetProfileInfo(&profile7, "Marion", "Mitchell",
"Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
- "Hollywood", "CA", "91601", "US", "12345678910", "01987654321");
+ "Hollywood", "CA", "91601", "US", "16505678910", "78127654321");
EXPECT_TRUE(UpdateProfileLabel(&profile7));
string16 summary7 = profile7.Label();
EXPECT_EQ(ASCIIToUTF16("Marion Mitchell Morrison, 123 Zoo St."),
@@ -115,7 +115,7 @@ TEST(AutofillProfileTest, PreviewSummaryString) {
AutofillProfile profile7a;
autofill_test::SetProfileInfo(&profile7a, "Marion", "Mitchell",
"Morrison", "marion@me.xyz", "Fox", "123 Zoo St.", "unit 5",
- "Hollywood", "CA", "91601", "US", "12345678910", "01987654321");
+ "Hollywood", "CA", "91601", "US", "16505678910", "78127654321");
std::vector<AutofillProfile*> profiles;
profiles.push_back(&profile7);
profiles.push_back(&profile7a);
@@ -143,8 +143,8 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
"Elysium", "CA",
"91111",
"US",
- "11111111111",
- "22222222222");
+ "16502111111",
+ "16502222222");
profiles.push_back(new AutofillProfile);
autofill_test::SetProfileInfo(
profiles[1],
@@ -182,8 +182,8 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
"Elysium", "CA",
"91111",
"US",
- "11111111111",
- "22222222222");
+ "16502111111",
+ "16502222222");
EXPECT_TRUE(AutofillProfile::AdjustInferredLabels(&profiles));
// Profile 0 and 2 inferred label now includes an e-mail.
@@ -210,17 +210,17 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
"Elysium", "CA",
"91111",
"US",
- "11111111111",
- "33333333333"); // Fax is different
+ "16502111111",
+ "16503333333"); // Fax is different
EXPECT_TRUE(AutofillProfile::AdjustInferredLabels(&profiles));
// Profile 0 and 2 inferred label now includes a fax number.
- EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., fax:#22222222222"),
+ EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., fax:#16502222222"),
profiles[0]->Label());
EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."),
profiles[1]->Label());
- EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., fax:#33333333333"),
+ EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., fax:#16503333333"),
profiles[2]->Label());
profiles.push_back(new AutofillProfile);
@@ -236,22 +236,22 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
"Elysium", "CA",
"91111",
"US",
- "44444444444", // Phone is different for some.
- "33333333333"); // Fax is different for some.
+ "16504444444", // Phone is different for some.
+ "16503333333"); // Fax is different for some.
EXPECT_TRUE(AutofillProfile::AdjustInferredLabels(&profiles));
- EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 11111111111,"
- " fax:#22222222222"),
+ EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 16502111111,"
+ " fax:#16502222222"),
profiles[0]->Label());
EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."),
profiles[1]->Label());
- EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 11111111111,"
- " fax:#33333333333"),
+ EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 16502111111,"
+ " fax:#16503333333"),
profiles[2]->Label());
// This one differs from other ones by unique phone, so no need for extra
// information.
- EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 44444444444"),
+ EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 16504444444"),
profiles[3]->Label());
profiles.push_back(new AutofillProfile);
@@ -267,21 +267,21 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
"Elysium", "CA",
"91111",
"US",
- "44444444444", // Phone is different for some.
- "33333333333"); // Fax is different for some.
+ "16504444444", // Phone is different for some.
+ "16503333333"); // Fax is different for some.
EXPECT_TRUE(AutofillProfile::AdjustInferredLabels(&profiles));
EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., johndoe@hades.com,"
- " 11111111111, fax:#22222222222"),
+ " 16502111111, fax:#16502222222"),
profiles[0]->Label());
EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."),
profiles[1]->Label());
EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., johndoe@hades.com,"
- " 11111111111, fax:#33333333333"),
+ " 16502111111, fax:#16503333333"),
profiles[2]->Label());
EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., johndoe@hades.com,"
- " 44444444444, fax:#33333333333"),
+ " 16504444444, fax:#16503333333"),
profiles[3]->Label());
// This one differs from other ones by unique e-mail, so no need for extra
// information.
@@ -308,8 +308,8 @@ TEST(AutofillProfileTest, CreateInferredLabels) {
"Elysium", "CA",
"91111",
"US",
- "11111111111",
- "22222222222");
+ "16502111111",
+ "16502222222");
profiles.push_back(new AutofillProfile);
autofill_test::SetProfileInfo(profiles[1],
"Jane",
@@ -754,7 +754,7 @@ TEST(AutofillProfileTest, MultiValuePhone) {
AutofillProfile p2 = p;
EXPECT_EQ(0, p.Compare(p2));
EXPECT_EQ(0, p.CompareMulti(p2));
- const string16 kNoOne(ASCIIToUTF16("4151110000"));
+ const string16 kNoOne(ASCIIToUTF16("4152110000"));
set_values[1] = kNoOne;
p.SetMultiInfo(PHONE_HOME_WHOLE_NUMBER, set_values);
p.GetMultiInfo(PHONE_HOME_WHOLE_NUMBER, &get_values);
@@ -777,8 +777,8 @@ TEST(AutofillProfileTest, MultiValuePhone) {
TEST(AutofillProfileTest, MultiValueFax) {
AutofillProfile p;
- const string16 kJohnDoe(ASCIIToUTF16("4151112222"));
- const string16 kJohnPDoe(ASCIIToUTF16("4151113333"));
+ const string16 kJohnDoe(ASCIIToUTF16("4152112222"));
+ const string16 kJohnPDoe(ASCIIToUTF16("4153113333"));
std::vector<string16> set_values;
set_values.push_back(kJohnDoe);
set_values.push_back(kJohnPDoe);
diff --git a/chrome/browser/autofill/personal_data_manager.cc b/chrome/browser/autofill/personal_data_manager.cc
index 3135044..03eb64e 100644
--- a/chrome/browser/autofill/personal_data_manager.cc
+++ b/chrome/browser/autofill/personal_data_manager.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/autofill/autofill_metrics.h"
#include "chrome/browser/autofill/form_structure.h"
#include "chrome/browser/autofill/phone_number.h"
+#include "chrome/browser/autofill/phone_number_i18n.h"
#include "chrome/browser/autofill/select_control_handler.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
@@ -225,6 +226,11 @@ bool PersonalDataManager::ImportFormData(
// Detect and discard forms with multiple fields of the same type.
std::set<AutofillFieldType> types_seen;
+ // We only set complete phone, so aggregate phone parts in these vars and set
+ // complete at the end.
+ PhoneNumber::PhoneCombineHelper home(AutofillType::PHONE_HOME);
+ PhoneNumber::PhoneCombineHelper fax(AutofillType::PHONE_FAX);
+
for (size_t i = 0; i < form.field_count(); ++i) {
const AutofillField* field = form.field(i);
string16 value = CollapseWhitespace(field->value, false);
@@ -262,51 +268,12 @@ bool PersonalDataManager::ImportFormData(
}
++importable_credit_card_fields;
} else {
- // In the case of a phone number, if the whole phone number was entered
- // into a single field, then parse it and set the sub components.
- if (AutofillType(field_type).subgroup() ==
- AutofillType::PHONE_WHOLE_NUMBER) {
- string16 number;
- string16 city_code;
- string16 country_code;
- PhoneNumber::ParsePhoneNumber(value,
- &number,
- &city_code,
- &country_code);
- if (number.empty())
- continue;
-
- if (group == AutofillType::PHONE_HOME) {
- imported_profile->SetInfo(PHONE_HOME_COUNTRY_CODE, country_code);
- imported_profile->SetInfo(PHONE_HOME_CITY_CODE, city_code);
- imported_profile->SetInfo(PHONE_HOME_NUMBER, number);
- } else if (group == AutofillType::PHONE_FAX) {
- imported_profile->SetInfo(PHONE_FAX_COUNTRY_CODE, country_code);
- imported_profile->SetInfo(PHONE_FAX_CITY_CODE, city_code);
- imported_profile->SetInfo(PHONE_FAX_NUMBER, number);
- }
-
- continue;
- }
-
- // Phone and fax numbers can be split across multiple fields, so we
- // might have already stored the prefix, and now be at the suffix.
- // If so, combine them to form the full number.
- if (group == AutofillType::PHONE_HOME ||
- group == AutofillType::PHONE_FAX) {
- AutofillFieldType number_type = PHONE_HOME_NUMBER;
- if (group == AutofillType::PHONE_FAX)
- number_type = PHONE_FAX_NUMBER;
-
- string16 stored_number = imported_profile->GetInfo(number_type);
- if (stored_number.size() ==
- static_cast<size_t>(PhoneNumber::kPrefixLength) &&
- value.size() == static_cast<size_t>(PhoneNumber::kSuffixLength)) {
- value = stored_number + value;
- }
- }
-
- imported_profile->SetInfo(field_type, value);
+ // We need to store phone data in the variables, before building the whole
+ // number at the end. The rest of the fields are set "as is".
+ // If the fields are not the phone fields in question both home.SetInfo()
+ // and fax.SetInfo() are going to return false.
+ if (!home.SetInfo(field_type, value) && !fax.SetInfo(field_type, value))
+ imported_profile->SetInfo(field_type, value);
// Reject profiles with invalid country information.
if (field_type == ADDRESS_HOME_COUNTRY &&
@@ -317,6 +284,33 @@ bool PersonalDataManager::ImportFormData(
}
}
+ // Build phone numbers if they are from parts.
+ if (imported_profile.get()) {
+ string16 constructed_number;
+ if (!home.empty()) {
+ if (!home.ParseNumber(imported_profile->CountryCode(),
+ &constructed_number)) {
+ imported_profile.reset();
+ } else {
+ imported_profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number);
+ }
+ }
+ if (!fax.empty()) {
+ if (!fax.ParseNumber(imported_profile->CountryCode(),
+ &constructed_number)) {
+ imported_profile.reset();
+ } else {
+ imported_profile->SetInfo(PHONE_FAX_WHOLE_NUMBER, constructed_number);
+ }
+ }
+ }
+ // Normalize phone numbers.
+ if (imported_profile.get()) {
+ // Reject profile if even one of the phones is invalid.
+ if (!imported_profile->NormalizePhones())
+ imported_profile.reset();
+ }
+
// Reject the profile if minimum address and validation requirements are not
// met.
if (imported_profile.get() && !IsValidLearnableProfile(*imported_profile))
diff --git a/chrome/browser/autofill/personal_data_manager_mac.mm b/chrome/browser/autofill/personal_data_manager_mac.mm
index c1f9ebe..5d02166 100644
--- a/chrome/browser/autofill/personal_data_manager_mac.mm
+++ b/chrome/browser/autofill/personal_data_manager_mac.mm
@@ -189,10 +189,6 @@ void AuxiliaryProfilesImpl::GetAddressBookPhoneNumbers(
ABPerson* me,
NSString* addressLabelRaw,
AutofillProfile* profile) {
- string16 number;
- string16 city_code;
- string16 country_code;
-
ABMultiValue* phoneNumbers = [me valueForProperty:kABPhoneProperty];
for (NSUInteger k = 0, phoneCount = [phoneNumbers count];
k < phoneCount; k++) {
@@ -202,40 +198,25 @@ void AuxiliaryProfilesImpl::GetAddressBookPhoneNumbers(
[phoneLabelRaw isEqualToString:kABPhoneHomeLabel]) {
string16 homePhone = base::SysNSStringToUTF16(
[phoneNumbers valueAtIndex:reverseK]);
- PhoneNumber::ParsePhoneNumber(
- homePhone, &number, &city_code, &country_code);
- profile->SetInfo(PHONE_HOME_NUMBER, number);
- profile->SetInfo(PHONE_HOME_CITY_CODE, city_code);
- profile->SetInfo(PHONE_HOME_COUNTRY_CODE, country_code);
+ profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, homePhone);
} else if ([addressLabelRaw isEqualToString:kABAddressHomeLabel] &&
[phoneLabelRaw isEqualToString:kABPhoneHomeFAXLabel]) {
string16 homeFax = base::SysNSStringToUTF16(
[phoneNumbers valueAtIndex:reverseK]);
- PhoneNumber::ParsePhoneNumber(homeFax,
- &number, &city_code, &country_code);
- profile->SetInfo(PHONE_FAX_NUMBER, number);
- profile->SetInfo(PHONE_FAX_CITY_CODE, city_code);
- profile->SetInfo(PHONE_FAX_COUNTRY_CODE, country_code);
+ profile->SetInfo(PHONE_FAX_WHOLE_NUMBER, homeFax);
} else if ([addressLabelRaw isEqualToString:kABAddressWorkLabel] &&
[phoneLabelRaw isEqualToString:kABPhoneWorkLabel]) {
string16 workPhone = base::SysNSStringToUTF16(
[phoneNumbers valueAtIndex:reverseK]);
- PhoneNumber::ParsePhoneNumber(workPhone,
- &number, &city_code, &country_code);
- profile->SetInfo(PHONE_HOME_NUMBER, number);
- profile->SetInfo(PHONE_HOME_CITY_CODE, city_code);
- profile->SetInfo(PHONE_HOME_COUNTRY_CODE, country_code);
+ profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, workPhone);
} else if ([addressLabelRaw isEqualToString:kABAddressWorkLabel] &&
[phoneLabelRaw isEqualToString:kABPhoneWorkFAXLabel]) {
string16 workFax = base::SysNSStringToUTF16(
[phoneNumbers valueAtIndex:reverseK]);
- PhoneNumber::ParsePhoneNumber(workFax,
- &number, &city_code, &country_code);
- profile->SetInfo(PHONE_FAX_NUMBER, number);
- profile->SetInfo(PHONE_FAX_CITY_CODE, city_code);
- profile->SetInfo(PHONE_FAX_COUNTRY_CODE, country_code);
+ profile->SetInfo(PHONE_FAX_WHOLE_NUMBER, workFax);
}
}
+ profile->NormalizePhones();
}
} // namespace
diff --git a/chrome/browser/autofill/personal_data_manager_unittest.cc b/chrome/browser/autofill/personal_data_manager_unittest.cc
index 2ddb0c7..5d1b57f 100644
--- a/chrome/browser/autofill/personal_data_manager_unittest.cc
+++ b/chrome/browser/autofill/personal_data_manager_unittest.cc
@@ -889,7 +889,7 @@ TEST_F(PersonalDataManagerTest, AggregateSameProfileWithConflict) {
form1.fields.push_back(field);
// Phone gets updated.
autofill_test::CreateTestFormField(
- "Phone:", "phone", "4445556666", "text", &field);
+ "Phone:", "phone", "6505556666", "text", &field);
form1.fields.push_back(field);
FormStructure form_structure1(form1);
@@ -907,7 +907,7 @@ TEST_F(PersonalDataManagerTest, AggregateSameProfileWithConflict) {
AutofillProfile expected;
autofill_test::SetProfileInfo(&expected, "George", NULL,
"Washington", "theprez@gmail.com", NULL, "1600 Pennsylvania Avenue",
- "Suite A", "San Francisco", "California", "94102", NULL, "4445556666",
+ "Suite A", "San Francisco", "California", "94102", NULL, "4085556666",
NULL);
const std::vector<AutofillProfile*>& results1 = personal_data_->profiles();
ASSERT_EQ(1U, results1.size());
@@ -945,7 +945,7 @@ TEST_F(PersonalDataManagerTest, AggregateSameProfileWithConflict) {
form2.fields.push_back(field);
// Phone gets updated.
autofill_test::CreateTestFormField(
- "Phone:", "phone", "1231231234", "text", &field);
+ "Phone:", "phone", "6502231234", "text", &field);
form2.fields.push_back(field);
FormStructure form_structure2(form2);
@@ -964,7 +964,7 @@ TEST_F(PersonalDataManagerTest, AggregateSameProfileWithConflict) {
// Add multi-valued phone number to expectation. Also, country gets added.
std::vector<string16> values;
expected.GetMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
- values.push_back(ASCIIToUTF16("1231231234"));
+ values.push_back(ASCIIToUTF16("6502231234"));
expected.SetMultiInfo(PHONE_HOME_WHOLE_NUMBER, values);
expected.SetInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("United States"));
ASSERT_EQ(1U, results2.size());
@@ -1632,7 +1632,7 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
autofill_test::SetProfileInfo(&profile0,
"Marion", NULL, "Morrison",
"johnwayne@me.xyz", NULL, "123 Zoo St.", NULL, "Hollywood", "CA",
- "91601", "US", "2345678910", NULL);
+ "91601", "US", "14155678910", NULL);
personal_data_->AddProfile(profile0);
@@ -1642,7 +1642,7 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
MessageLoop::current()->Run();
personal_data_->GetNonEmptyTypes(&non_empty_types);
- EXPECT_EQ(13U, non_empty_types.size());
+ EXPECT_EQ(14U, non_empty_types.size());
EXPECT_TRUE(non_empty_types.count(NAME_FIRST));
EXPECT_TRUE(non_empty_types.count(NAME_LAST));
EXPECT_TRUE(non_empty_types.count(NAME_FULL));
@@ -1653,6 +1653,7 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_ZIP));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_COUNTRY));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_NUMBER));
+ EXPECT_TRUE(non_empty_types.count(PHONE_HOME_COUNTRY_CODE));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_CODE));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_AND_NUMBER));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_WHOLE_NUMBER));
@@ -1662,13 +1663,13 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
autofill_test::SetProfileInfo(&profile1,
"Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "903 Apple Ct.", NULL, "Orlando", "FL", "32801",
- "US", "19482937549", "13502849239");
+ "US", "16502937549", "14082849239");
AutofillProfile profile2;
autofill_test::SetProfileInfo(&profile2,
"Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
- "32801", "US", "19482937549", "13502849239");
+ "32801", "US", "16502937549", "14152849239");
personal_data_->AddProfile(profile1);
personal_data_->AddProfile(profile2);
diff --git a/chrome/browser/autofill/phone_field.cc b/chrome/browser/autofill/phone_field.cc
index c5045aa..d1ba987 100644
--- a/chrome/browser/autofill/phone_field.cc
+++ b/chrome/browser/autofill/phone_field.cc
@@ -330,9 +330,9 @@ void PhoneField::SetPhoneType(PhoneType phone_type) {
// Field types are different as well, so we create a temporary phone number,
// to get relevant field types.
if (phone_type == HOME_PHONE)
- number_.reset(new HomePhoneNumber);
+ number_.reset(new PhoneNumber(AutofillType::PHONE_HOME));
else
- number_.reset(new FaxNumber);
+ number_.reset(new PhoneNumber(AutofillType::PHONE_FAX));
phone_type_ = phone_type;
}
diff --git a/chrome/browser/autofill/phone_number.cc b/chrome/browser/autofill/phone_number.cc
index d1ca32a..1eca43a 100644
--- a/chrome/browser/autofill/phone_number.cc
+++ b/chrome/browser/autofill/phone_number.cc
@@ -5,10 +5,13 @@
#include "chrome/browser/autofill/phone_number.h"
#include "base/basictypes.h"
+#include "base/string_number_conversions.h"
#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/autofill_profile.h"
#include "chrome/browser/autofill/autofill_type.h"
#include "chrome/browser/autofill/field_types.h"
+#include "chrome/browser/autofill/phone_number_i18n.h"
namespace {
@@ -32,7 +35,13 @@ const int kAutofillPhoneLength = arraysize(kAutofillPhoneTypes);
} // namespace
-PhoneNumber::PhoneNumber() {}
+PhoneNumber::PhoneNumber()
+ : phone_group_(AutofillType::NO_GROUP) {
+}
+
+PhoneNumber::PhoneNumber(AutofillType::FieldTypeGroup phone_group)
+ : phone_group_(phone_group) {
+}
PhoneNumber::PhoneNumber(const PhoneNumber& number) : FormGroup() {
*this = number;
@@ -43,10 +52,8 @@ PhoneNumber::~PhoneNumber() {}
PhoneNumber& PhoneNumber::operator=(const PhoneNumber& number) {
if (this == &number)
return *this;
- country_code_ = number.country_code_;
- city_code_ = number.city_code_;
number_ = number.number_;
- extension_ = number.extension_;
+ phone_group_ = number.phone_group_;
return *this;
}
@@ -54,194 +61,247 @@ void PhoneNumber::GetMatchingTypes(const string16& text,
FieldTypeSet* matching_types) const {
string16 stripped_text(text);
StripPunctuation(&stripped_text);
- if (!Validate(stripped_text))
+
+ string16 number;
+ string16 city_code;
+ string16 country_code;
+ // Full number - parse it, split it and re-combine into canonical form.
+ if (!autofill_i18n::ParsePhoneNumber(
+ number_, locale_, &country_code, &city_code, &number))
return;
- if (IsNumber(stripped_text))
+ if (IsNumber(stripped_text, number))
matching_types->insert(GetNumberType());
- if (IsCityCode(stripped_text))
+ if (stripped_text == city_code)
matching_types->insert(GetCityCodeType());
- if (IsCountryCode(stripped_text))
+ if (stripped_text == country_code)
matching_types->insert(GetCountryCodeType());
- if (IsCityAndNumber(stripped_text))
+ city_code.append(number);
+ if (stripped_text == city_code)
matching_types->insert(GetCityAndNumberType());
- if (IsWholeNumber(stripped_text))
+ // Whole number is compared to unfiltered text - it would be parsed for phone
+ // comparision (e.g. 1-800-FLOWERS and 18003569377 are the same)
+ if (IsWholeNumber(text))
matching_types->insert(GetWholeNumberType());
}
-void PhoneNumber::GetNonEmptyTypes(FieldTypeSet* non_empty_typess) const {
- DCHECK(non_empty_typess);
+void PhoneNumber::GetNonEmptyTypes(FieldTypeSet* non_empty_types) const {
+ DCHECK(non_empty_types);
- if (!number().empty())
- non_empty_typess->insert(GetNumberType());
+ if (number_.empty())
+ return;
+
+ non_empty_types->insert(GetWholeNumberType());
- if (!city_code().empty())
- non_empty_typess->insert(GetCityCodeType());
+ string16 number;
+ string16 city_code;
+ string16 country_code;
+ // Full number - parse it, split it and re-combine into canonical form.
+ if (!autofill_i18n::ParsePhoneNumber(
+ number_, locale_, &country_code, &city_code, &number))
+ return;
- if (!country_code().empty())
- non_empty_typess->insert(GetCountryCodeType());
+ non_empty_types->insert(GetNumberType());
- if (!CityAndNumber().empty())
- non_empty_typess->insert(GetCityAndNumberType());
+ if (!city_code.empty()) {
+ non_empty_types->insert(GetCityCodeType());
+ non_empty_types->insert(GetCityAndNumberType());
+ }
- if (!WholeNumber().empty())
- non_empty_typess->insert(GetWholeNumberType());
+ if (!country_code.empty())
+ non_empty_types->insert(GetCountryCodeType());
}
string16 PhoneNumber::GetInfo(AutofillFieldType type) const {
+ if (type == GetWholeNumberType())
+ return number_;
+
+ string16 number;
+ string16 city_code;
+ string16 country_code;
+ // Full number - parse it, split it and re-combine into canonical form.
+ if (!autofill_i18n::ParsePhoneNumber(
+ number_, locale_, &country_code, &city_code, &number))
+ return string16();
+
if (type == GetNumberType())
- return number();
+ return number;
if (type == GetCityCodeType())
- return city_code();
+ return city_code;
if (type == GetCountryCodeType())
- return country_code();
+ return country_code;
+ city_code.append(number);
if (type == GetCityAndNumberType())
- return CityAndNumber();
-
- if (type == GetWholeNumberType())
- return WholeNumber();
+ return city_code;
return string16();
}
void PhoneNumber::SetInfo(AutofillFieldType type, const string16& value) {
- string16 number(value);
- StripPunctuation(&number);
- if (!Validate(number))
- return;
-
FieldTypeSubGroup subgroup = AutofillType(type).subgroup();
- if (subgroup == AutofillType::PHONE_NUMBER)
- set_number(number);
- else if (subgroup == AutofillType::PHONE_CITY_CODE)
- set_city_code(number);
- else if (subgroup == AutofillType::PHONE_COUNTRY_CODE)
- set_country_code(number);
- else if (subgroup == AutofillType::PHONE_CITY_AND_NUMBER ||
- subgroup == AutofillType::PHONE_WHOLE_NUMBER)
- set_whole_number(number);
- else
+ FieldTypeGroup group = AutofillType(type).group();
+ if (phone_group_ == AutofillType::NO_GROUP)
+ phone_group_ = group; // First call on empty phone - set the group.
+ if (subgroup == AutofillType::PHONE_NUMBER) {
+ // Should not be set directly.
NOTREACHED();
+ } else if (subgroup == AutofillType::PHONE_CITY_CODE) {
+ // Should not be set directly.
+ NOTREACHED();
+ } else if (subgroup == AutofillType::PHONE_COUNTRY_CODE) {
+ // Should not be set directly.
+ NOTREACHED();
+ } else if (subgroup == AutofillType::PHONE_CITY_AND_NUMBER ||
+ subgroup == AutofillType::PHONE_WHOLE_NUMBER) {
+ number_ = value;
+ StripPunctuation(&number_);
+ } else {
+ NOTREACHED();
+ }
}
-// Static.
-bool PhoneNumber::ParsePhoneNumber(const string16& value,
- string16* number,
- string16* city_code,
- string16* country_code) {
- DCHECK(number);
- DCHECK(city_code);
- DCHECK(country_code);
-
- // Make a working copy of value.
- string16 working = value;
-
- *number = string16();
- *city_code = string16();
- *country_code = string16();
-
- // First remove any punctuation.
- StripPunctuation(&working);
-
- if (working.size() < kPhoneNumberLength)
- return false;
-
- // Treat the last 7 digits as the number.
- *number = working.substr(working.size() - kPhoneNumberLength,
- kPhoneNumberLength);
- working.resize(working.size() - kPhoneNumberLength);
- if (working.size() < kPhoneCityCodeLength)
+bool PhoneNumber::NormalizePhone() {
+ bool success = true;
+ // Empty number does not need normalization.
+ if (number_.empty())
return true;
- // Treat the next three digits as the city code.
- *city_code = working.substr(working.size() - kPhoneCityCodeLength,
- kPhoneCityCodeLength);
- working.resize(working.size() - kPhoneCityCodeLength);
- if (working.empty())
- return true;
+ string16 number;
+ string16 city_code;
+ string16 country_code;
+ // Full number - parse it, split it and re-combine into canonical form.
+ if (!autofill_i18n::ParsePhoneNumber(
+ number_, locale_, &country_code, &city_code, &number) ||
+ !autofill_i18n::ConstructPhoneNumber(
+ country_code, city_code, number,
+ locale_,
+ (country_code.empty() ?
+ autofill_i18n::NATIONAL : autofill_i18n::INTERNATIONAL),
+ &number_)) {
+ // Parsing failed - do not store phone.
+ number_.clear();
+ success = false;
+ }
+ number_ = autofill_i18n::NormalizePhoneNumber(number_);
+ return success;
+}
- // Treat any remaining digits as the country code.
- *country_code = working;
- return true;
+void PhoneNumber::set_locale(const std::string& locale) {
+ locale_ = locale;
}
-string16 PhoneNumber::WholeNumber() const {
- string16 whole_number;
- if (!country_code_.empty())
- whole_number.append(country_code_);
+AutofillFieldType PhoneNumber::GetNumberType() const {
+ if (phone_group_ == AutofillType::PHONE_HOME)
+ return PHONE_HOME_NUMBER;
+ else if (phone_group_ == AutofillType::PHONE_FAX)
+ return PHONE_FAX_NUMBER;
+ else
+ NOTREACHED();
+ return UNKNOWN_TYPE;
+}
- if (!city_code_.empty())
- whole_number.append(city_code_);
+AutofillFieldType PhoneNumber::GetCityCodeType() const {
+ if (phone_group_ == AutofillType::PHONE_HOME)
+ return PHONE_HOME_CITY_CODE;
+ else if (phone_group_ == AutofillType::PHONE_FAX)
+ return PHONE_FAX_CITY_CODE;
+ else
+ NOTREACHED();
+ return UNKNOWN_TYPE;
+}
- if (!number_.empty())
- whole_number.append(number_);
+AutofillFieldType PhoneNumber::GetCountryCodeType() const {
+ if (phone_group_ == AutofillType::PHONE_HOME)
+ return PHONE_HOME_COUNTRY_CODE;
+ else if (phone_group_ == AutofillType::PHONE_FAX)
+ return PHONE_FAX_COUNTRY_CODE;
+ else
+ NOTREACHED();
+ return UNKNOWN_TYPE;
+}
- return whole_number;
+AutofillFieldType PhoneNumber::GetCityAndNumberType() const {
+ if (phone_group_ == AutofillType::PHONE_HOME)
+ return PHONE_HOME_CITY_AND_NUMBER;
+ else if (phone_group_ == AutofillType::PHONE_FAX)
+ return PHONE_FAX_CITY_AND_NUMBER;
+ else
+ NOTREACHED();
+ return UNKNOWN_TYPE;
}
-void PhoneNumber::set_number(const string16& number) {
- string16 digits(number);
- StripPunctuation(&digits);
- number_ = digits;
+AutofillFieldType PhoneNumber::GetWholeNumberType() const {
+ if (phone_group_ == AutofillType::PHONE_HOME)
+ return PHONE_HOME_WHOLE_NUMBER;
+ else if (phone_group_ == AutofillType::PHONE_FAX)
+ return PHONE_FAX_WHOLE_NUMBER;
+ else
+ NOTREACHED();
+ return UNKNOWN_TYPE;
}
-void PhoneNumber::set_whole_number(const string16& whole_number) {
- string16 number, city_code, country_code;
- ParsePhoneNumber(whole_number, &number, &city_code, &country_code);
- set_number(number);
- set_city_code(city_code);
- set_country_code(country_code);
+bool PhoneNumber::PhoneCombineHelper::SetInfo(AutofillFieldType field_type,
+ const string16& value) {
+ PhoneNumber temp(phone_group_);
+
+ if (field_type == temp.GetCountryCodeType()) {
+ country_ = value;
+ return true;
+ } else if (field_type == temp.GetCityCodeType()) {
+ city_ = value;
+ return true;
+ } else if (field_type == temp.GetCityAndNumberType()) {
+ phone_ = value;
+ return true;
+ } else if (field_type == temp.GetNumberType()) {
+ phone_.append(value);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool PhoneNumber::PhoneCombineHelper::ParseNumber(const std::string& locale,
+ string16* value) {
+ DCHECK(value);
+ return autofill_i18n::ConstructPhoneNumber(
+ country_, city_, phone_,
+ locale,
+ (country_.empty() ?
+ autofill_i18n::NATIONAL : autofill_i18n::INTERNATIONAL),
+ value);
}
-bool PhoneNumber::IsNumber(const string16& text) const {
- // TODO(isherman): This will need to be updated once we add support for
+bool PhoneNumber::IsNumber(const string16& text, const string16& number) const {
+ // TODO(georgey): This will need to be updated once we add support for
// international phone numbers.
const size_t kPrefixLength = 3;
const size_t kSuffixLength = 4;
- if (text == number_)
+ if (text == number)
return true;
- if (text.length() == kPrefixLength && StartsWith(number_, text, true))
+ if (text.length() == kPrefixLength && StartsWith(number, text, true))
return true;
- if (text.length() == kSuffixLength && EndsWith(number_, text, true))
+ if (text.length() == kSuffixLength && EndsWith(number, text, true))
return true;
return false;
}
-bool PhoneNumber::IsCityCode(const string16& text) const {
- return text == city_code_;
-}
-
-bool PhoneNumber::IsCountryCode(const string16& text) const {
- return text == country_code_;
-}
-
-bool PhoneNumber::IsCityAndNumber(const string16& text) const {
- return text == CityAndNumber();
-}
-
bool PhoneNumber::IsWholeNumber(const string16& text) const {
- return text == WholeNumber();
-}
-
-bool PhoneNumber::Validate(const string16& number) const {
- for (size_t i = 0; i < number.length(); ++i) {
- if (!IsAsciiDigit(number[i]))
- return false;
- }
-
- return true;
+ return autofill_i18n::ComparePhones(text, number_, locale_) ==
+ autofill_i18n::PHONES_EQUAL;
}
// Static.
void PhoneNumber::StripPunctuation(string16* number) {
RemoveChars(*number, kPhoneNumberSeparators, number);
}
+
diff --git a/chrome/browser/autofill/phone_number.h b/chrome/browser/autofill/phone_number.h
index 9cbb6b2..2790f9c 100644
--- a/chrome/browser/autofill/phone_number.h
+++ b/chrome/browser/autofill/phone_number.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_AUTOFILL_PHONE_NUMBER_H_
#pragma once
+#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
@@ -17,7 +18,8 @@
class PhoneNumber : public FormGroup {
public:
PhoneNumber();
- explicit PhoneNumber(const PhoneNumber& number);
+ explicit PhoneNumber(AutofillType::FieldTypeGroup phone_group);
+ PhoneNumber(const PhoneNumber& number);
virtual ~PhoneNumber();
PhoneNumber& operator=(const PhoneNumber& number);
@@ -29,15 +31,9 @@ class PhoneNumber : public FormGroup {
virtual string16 GetInfo(AutofillFieldType type) const;
virtual void SetInfo(AutofillFieldType type, const string16& value);
- // Parses |value| to extract the components of a phone number. |number|
- // returns the trailing 7 digits, |city_code| returns the next 3 digits, and
- // |country_code| returns any remaining digits.
- // Separator characters are stripped before parsing the digits.
- // Returns true if parsing was successful, false otherwise.
- static bool ParsePhoneNumber(const string16& value,
- string16* number,
- string16* city_code,
- string16* country_code);
+ // Validates |number_| and translates it into digits-only format.
+ // Locale must be set.
+ bool NormalizePhone();
// Size and offset of the prefix and suffix portions of phone numbers.
static const int kPrefixOffset = 0;
@@ -45,53 +41,55 @@ class PhoneNumber : public FormGroup {
static const int kSuffixOffset = 3;
static const int kSuffixLength = 4;
+ // Sets locale for normalizing phone numbers. Must be called if you get
+ // normalized number or use NormalizePhone() function;
+ // Setting it to "", actually sets it to default locale - "US".
+ void set_locale(const std::string& locale);
+
// The following functions should return the field type for each part of the
// phone number. Currently, these are either fax or home phone number types.
- virtual AutofillFieldType GetNumberType() const = 0;
- virtual AutofillFieldType GetCityCodeType() const = 0;
- virtual AutofillFieldType GetCountryCodeType() const = 0;
- virtual AutofillFieldType GetCityAndNumberType() const = 0;
- virtual AutofillFieldType GetWholeNumberType() const = 0;
+ AutofillFieldType GetNumberType() const;
+ AutofillFieldType GetCityCodeType() const;
+ AutofillFieldType GetCountryCodeType() const;
+ AutofillFieldType GetCityAndNumberType() const;
+ AutofillFieldType GetWholeNumberType() const;
+
+ // The class used to combine home phone or fax parts into a whole number.
+ class PhoneCombineHelper {
+ public:
+ explicit PhoneCombineHelper(AutofillType::FieldTypeGroup phone_group)
+ : phone_group_(phone_group) { }
+ // Sets PHONE_HOME/FAX_CITY_CODE, PHONE_HOME/FAX_COUNTRY_CODE,
+ // PHONE_HOME/FAX_CITY_AND_NUMBER, PHONE_HOME/FAX_NUMBER and returns true.
+ // For all other field types returs false.
+ bool SetInfo(AutofillFieldType type, const string16& value);
+ // Returns true if parsing was successful, false otherwise.
+ bool ParseNumber(const std::string& locale, string16* value);
+
+ bool empty() const { return phone_.empty(); }
+ private:
+ string16 country_;
+ string16 city_;
+ string16 phone_;
+ AutofillType::FieldTypeGroup phone_group_;
+ };
private:
FRIEND_TEST_ALL_PREFIXES(PhoneNumberTest, Matcher);
- const string16& country_code() const { return country_code_; }
- const string16& city_code() const { return city_code_; }
- const string16& number() const { return number_; }
- const string16& extension() const { return extension_; }
- string16 CityAndNumber() const { return city_code_ + number_; }
-
- // Returns the entire phone number as a string, without punctuation.
- virtual string16 WholeNumber() const;
-
- void set_country_code(const string16& country_code) {
- country_code_ = country_code;
- }
- void set_city_code(const string16& city_code) { city_code_ = city_code; }
- void set_number(const string16& number);
- void set_extension(const string16& extension) { extension_ = extension; }
- void set_whole_number(const string16& whole_number);
-
// The numbers will be digits only (no punctuation), so any call to the IsX()
// functions should first call StripPunctuation on the text.
- bool IsNumber(const string16& text) const;
- bool IsCityCode(const string16& text) const;
- bool IsCountryCode(const string16& text) const;
- bool IsCityAndNumber(const string16& text) const;
+ bool IsNumber(const string16& text, const string16& number) const;
bool IsWholeNumber(const string16& text) const;
- // Verifies that |number| is a valid phone number.
- bool Validate(const string16& number) const;
-
- // Removes any punctuation characters from |number|.
static void StripPunctuation(string16* number);
+ // Phone group - currently it is PHONE_HOME and PHONE_FAX.
+ AutofillType::FieldTypeGroup phone_group_;
+ // Locale for phone normalizing.
+ std::string locale_;
// The pieces of the phone number.
- string16 country_code_;
- string16 city_code_; // city or area code.
string16 number_;
- string16 extension_;
};
#endif // CHROME_BROWSER_AUTOFILL_PHONE_NUMBER_H_
diff --git a/chrome/browser/autofill/phone_number_i18n.cc b/chrome/browser/autofill/phone_number_i18n.cc
index 2217fb9..73ee97c 100644
--- a/chrome/browser/autofill/phone_number_i18n.cc
+++ b/chrome/browser/autofill/phone_number_i18n.cc
@@ -9,6 +9,7 @@
#include "base/stringprintf.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/autofill/autofill_country.h"
#include "third_party/libphonenumber/cpp/src/phonenumberutil.h"
namespace {
@@ -16,8 +17,8 @@ namespace {
std::string SanitizeLocaleCode(const std::string& locale_code) {
if (locale_code.length() == 2)
return locale_code;
- // Use USA for incomplete locales.
- return std::string("US");
+ return AutofillCountry::CountryCodeForLocale(
+ AutofillCountry::ApplicationLocale());
}
i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat UtilsTypeToPhoneLibType(
@@ -162,6 +163,12 @@ bool ConstructPhoneNumber(const string16& country_code,
if (validation != i18n::phonenumbers::PhoneNumberUtil::IS_POSSIBLE)
return false;
+ // This verifies that number has a valid area code (that in some cases could
+ // be empty) for parsed country code. Also verifies that this is a valid
+ // number (in US 1234567 is not valid, because numbers do not start with 1).
+ if (!phone_util->IsValidNumber(i18n_number))
+ return false;
+
std::string formatted_number;
phone_util->Format(i18n_number, UtilsTypeToPhoneLibType(phone_format),
diff --git a/chrome/browser/autofill/phone_number_i18n_unittest.cc b/chrome/browser/autofill/phone_number_i18n_unittest.cc
index 4134a82..22a349e 100644
--- a/chrome/browser/autofill/phone_number_i18n_unittest.cc
+++ b/chrome/browser/autofill/phone_number_i18n_unittest.cc
@@ -283,20 +283,29 @@ TEST(PhoneNumberI18NTest, ConstructPhoneNumber) {
&number));
EXPECT_EQ(number, string16());
// Italian number
- EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("39"),
- ASCIIToUTF16(""),
- ASCIIToUTF16("236618300"),
- "US",
+ EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16(""),
+ ASCIIToUTF16("347"),
+ ASCIIToUTF16("2345678"),
+ "IT",
autofill_i18n::INTERNATIONAL,
&number));
- EXPECT_EQ(number, ASCIIToUTF16("+39 236618300"));
- EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("39"),
- ASCIIToUTF16(""),
- ASCIIToUTF16("236618300"),
- "US",
+ EXPECT_EQ(number, ASCIIToUTF16("+39 347 234 5678"));
+ // German number.
+ EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("49"),
+ ASCIIToUTF16("024"),
+ ASCIIToUTF16("2345678901"),
+ "DE",
autofill_i18n::NATIONAL,
&number));
- EXPECT_EQ(number, ASCIIToUTF16("236618300"));
+ EXPECT_EQ(number, ASCIIToUTF16("02423/45678901"));
+
+ EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("49"),
+ ASCIIToUTF16("024"),
+ ASCIIToUTF16("2345678901"),
+ "DE",
+ autofill_i18n::INTERNATIONAL,
+ &number));
+ EXPECT_EQ(number, ASCIIToUTF16("+49 2423/45678901"));
}
TEST(PhoneNumberI18NTest, FormatPhone) {
diff --git a/chrome/browser/autofill/phone_number_unittest.cc b/chrome/browser/autofill/phone_number_unittest.cc
index 8766398..65b5952 100644
--- a/chrome/browser/autofill/phone_number_unittest.cc
+++ b/chrome/browser/autofill/phone_number_unittest.cc
@@ -3,126 +3,160 @@
// found in the LICENSE file.
#include "base/utf_string_conversions.h"
-#include "chrome/browser/autofill/home_phone_number.h"
+#include "chrome/browser/autofill/field_types.h"
#include "chrome/browser/autofill/phone_number.h"
+#include "chrome/browser/autofill/phone_number_i18n.h"
#include "testing/gtest/include/gtest/gtest.h"
-// Tests the phone number parser.
-TEST(PhoneNumberTest, Parser) {
- string16 number;
- string16 city_code;
- string16 country_code;
-
- // Test for empty string. Should give back empty strings.
- string16 phone0;
- PhoneNumber::ParsePhoneNumber(phone0, &number, &city_code, &country_code);
- EXPECT_EQ(string16(), number);
- EXPECT_EQ(string16(), city_code);
- EXPECT_EQ(string16(), country_code);
-
- // Test for string with less than 7 digits. Should give back empty strings.
- string16 phone1(ASCIIToUTF16("1234"));
- PhoneNumber::ParsePhoneNumber(phone1, &number, &city_code, &country_code);
- EXPECT_EQ(string16(), number);
- EXPECT_EQ(string16(), city_code);
- EXPECT_EQ(string16(), country_code);
-
- // Test for string with exactly 7 digits. Should give back only phone number.
- string16 phone2(ASCIIToUTF16("1234567"));
- PhoneNumber::ParsePhoneNumber(phone2, &number, &city_code, &country_code);
- EXPECT_EQ(ASCIIToUTF16("1234567"), number);
- EXPECT_EQ(string16(), city_code);
- EXPECT_EQ(string16(), country_code);
-
- // Test for string with exactly 7 digits and separators. Should give back
- // only phone number.
- string16 phone_separator2(ASCIIToUTF16("123-4567"));
- PhoneNumber::ParsePhoneNumber(phone_separator2,
- &number, &city_code, &country_code);
- EXPECT_EQ(ASCIIToUTF16("1234567"), number);
- EXPECT_EQ(string16(), city_code);
- EXPECT_EQ(string16(), country_code);
-
- // Test for string with greater than 7 digits but less than 10 digits.
- // Should give back only phone number.
- string16 phone3(ASCIIToUTF16("123456789"));
- PhoneNumber::ParsePhoneNumber(phone3, &number, &city_code, &country_code);
- EXPECT_EQ(ASCIIToUTF16("3456789"), number);
- EXPECT_EQ(string16(), city_code);
- EXPECT_EQ(string16(), country_code);
-
- // Test for string with greater than 7 digits but less than 10 digits and
- // separators.
- // Should give back only phone number.
- string16 phone_separator3(ASCIIToUTF16("12.345-6789"));
- PhoneNumber::ParsePhoneNumber(phone3, &number, &city_code, &country_code);
- EXPECT_EQ(ASCIIToUTF16("3456789"), number);
- EXPECT_EQ(string16(), city_code);
- EXPECT_EQ(string16(), country_code);
-
- // Test for string with exactly 10 digits.
- // Should give back phone number and city code.
- string16 phone4(ASCIIToUTF16("1234567890"));
- PhoneNumber::ParsePhoneNumber(phone4, &number, &city_code, &country_code);
- EXPECT_EQ(ASCIIToUTF16("4567890"), number);
- EXPECT_EQ(ASCIIToUTF16("123"), city_code);
- EXPECT_EQ(string16(), country_code);
-
- // Test for string with exactly 10 digits and separators.
- // Should give back phone number and city code.
- string16 phone_separator4(ASCIIToUTF16("(123) 456-7890"));
- PhoneNumber::ParsePhoneNumber(phone_separator4,
- &number, &city_code, &country_code);
- EXPECT_EQ(ASCIIToUTF16("4567890"), number);
- EXPECT_EQ(ASCIIToUTF16("123"), city_code);
- EXPECT_EQ(string16(), country_code);
-
- // Test for string with over 10 digits.
- // Should give back phone number, city code, and country code.
- string16 phone5(ASCIIToUTF16("011234567890"));
- PhoneNumber::ParsePhoneNumber(phone5, &number, &city_code, &country_code);
- EXPECT_EQ(ASCIIToUTF16("4567890"), number);
- EXPECT_EQ(ASCIIToUTF16("123"), city_code);
- EXPECT_EQ(ASCIIToUTF16("01"), country_code);
-
- // Test for string with over 10 digits with separator characters.
- // Should give back phone number, city code, and country code.
- string16 phone6(ASCIIToUTF16("(01) 123-456.7890"));
- PhoneNumber::ParsePhoneNumber(phone6, &number, &city_code, &country_code);
- EXPECT_EQ(ASCIIToUTF16("4567890"), number);
- EXPECT_EQ(ASCIIToUTF16("123"), city_code);
- EXPECT_EQ(ASCIIToUTF16("01"), country_code);
-}
-
TEST(PhoneNumberTest, Matcher) {
- // Set phone number so country_code == 12, city_code = 123, number = 1234567.
- string16 phone(ASCIIToUTF16("121231234567"));
- HomePhoneNumber phone_number;
- phone_number.set_whole_number(phone);
-
- EXPECT_FALSE(phone_number.IsCountryCode(ASCIIToUTF16("")));
- EXPECT_FALSE(phone_number.IsCountryCode(ASCIIToUTF16("1")));
- EXPECT_TRUE(phone_number.IsCountryCode(ASCIIToUTF16("12")));
- EXPECT_FALSE(phone_number.IsCountryCode(ASCIIToUTF16("123")));
-
- EXPECT_FALSE(phone_number.IsCityCode(ASCIIToUTF16("")));
- EXPECT_FALSE(phone_number.IsCityCode(ASCIIToUTF16("1")));
- EXPECT_FALSE(phone_number.IsCityCode(ASCIIToUTF16("12")));
- EXPECT_TRUE(phone_number.IsCityCode(ASCIIToUTF16("123")));
- EXPECT_FALSE(phone_number.IsCityCode(ASCIIToUTF16("1234")));
+ // Set phone number so country_code == 1, city_code = 650, number = 2345678.
+ string16 phone(ASCIIToUTF16("1 [650] 234-5678"));
+ PhoneNumber phone_number(AutofillType::PHONE_HOME);
+ phone_number.SetInfo(PHONE_HOME_WHOLE_NUMBER, phone);
+ phone_number.set_locale(std::string("US"));
+ phone_number.NormalizePhone();
+
+ FieldTypeSet matching_types;
+ phone_number.GetMatchingTypes(ASCIIToUTF16(""), &matching_types);
+ EXPECT_EQ(0U, matching_types.size());
+ matching_types.clear();
+ phone_number.GetMatchingTypes(ASCIIToUTF16("1"), &matching_types);
+ EXPECT_EQ(1U, matching_types.size());
+ EXPECT_TRUE(matching_types.find(PHONE_HOME_COUNTRY_CODE) !=
+ matching_types.end());
+ matching_types.clear();
+ phone_number.GetMatchingTypes(ASCIIToUTF16("16"), &matching_types);
+ EXPECT_EQ(0U, matching_types.size());
+ phone_number.GetMatchingTypes(ASCIIToUTF16("165"), &matching_types);
+ EXPECT_EQ(0U, matching_types.size());
+ phone_number.GetMatchingTypes(ASCIIToUTF16("1650"), &matching_types);
+ EXPECT_EQ(0U, matching_types.size());
+ phone_number.GetMatchingTypes(ASCIIToUTF16("16502"), &matching_types);
+ EXPECT_EQ(0U, matching_types.size());
+ phone_number.GetMatchingTypes(ASCIIToUTF16("165023"), &matching_types);
+ EXPECT_EQ(0U, matching_types.size());
+ phone_number.GetMatchingTypes(ASCIIToUTF16("1650234"), &matching_types);
+ EXPECT_EQ(0U, matching_types.size());
+ matching_types.clear();
+ phone_number.GetMatchingTypes(ASCIIToUTF16("16502345678"), &matching_types);
+ EXPECT_EQ(1U, matching_types.size());
+ EXPECT_TRUE(matching_types.find(PHONE_HOME_WHOLE_NUMBER) !=
+ matching_types.end());
+ matching_types.clear();
+ phone_number.GetMatchingTypes(ASCIIToUTF16("650"), &matching_types);
+ EXPECT_EQ(1U, matching_types.size());
+ EXPECT_TRUE(matching_types.find(PHONE_HOME_CITY_CODE) !=
+ matching_types.end());
+ matching_types.clear();
+ phone_number.GetMatchingTypes(ASCIIToUTF16("2345678"), &matching_types);
+ EXPECT_EQ(1U, matching_types.size());
+ EXPECT_TRUE(matching_types.find(PHONE_HOME_NUMBER) != matching_types.end());
+ matching_types.clear();
+ phone_number.GetMatchingTypes(ASCIIToUTF16("234"), &matching_types);
+ EXPECT_EQ(1U, matching_types.size());
+ EXPECT_TRUE(matching_types.find(PHONE_HOME_NUMBER) != matching_types.end());
+ matching_types.clear();
+ phone_number.GetMatchingTypes(ASCIIToUTF16("5678"), &matching_types);
+ EXPECT_EQ(1U, matching_types.size());
+ EXPECT_TRUE(matching_types.find(PHONE_HOME_NUMBER) != matching_types.end());
+ matching_types.clear();
+ phone_number.GetMatchingTypes(ASCIIToUTF16("2345"), &matching_types);
+ EXPECT_EQ(0U, matching_types.size());
+ matching_types.clear();
+ phone_number.GetMatchingTypes(ASCIIToUTF16("6502345678"), &matching_types);
+ EXPECT_EQ(2U, matching_types.size());
+ EXPECT_TRUE(matching_types.find(PHONE_HOME_CITY_AND_NUMBER) !=
+ matching_types.end());
+ EXPECT_TRUE(matching_types.find(PHONE_HOME_WHOLE_NUMBER) !=
+ matching_types.end());
+ matching_types.clear();
+ phone_number.GetMatchingTypes(ASCIIToUTF16("(650)2345678"), &matching_types);
+ EXPECT_EQ(2U, matching_types.size());
+ EXPECT_TRUE(matching_types.find(PHONE_HOME_CITY_AND_NUMBER) !=
+ matching_types.end());
+ EXPECT_TRUE(matching_types.find(PHONE_HOME_WHOLE_NUMBER) !=
+ matching_types.end());
+
+ string16 fax(ASCIIToUTF16("+1(650)650-5678"));
+ PhoneNumber fax_number;
+ fax_number.set_locale(std::string("US"));
+ fax_number.SetInfo(PHONE_FAX_WHOLE_NUMBER, fax);
+
+ matching_types.clear();
+ fax_number.GetMatchingTypes(ASCIIToUTF16("16506505678"), &matching_types);
+ EXPECT_EQ(1U, matching_types.size());
+ EXPECT_TRUE(matching_types.find(PHONE_FAX_WHOLE_NUMBER) !=
+ matching_types.end());
+
+ matching_types.clear();
+ fax_number.GetMatchingTypes(ASCIIToUTF16("650"), &matching_types);
+ EXPECT_EQ(2U, matching_types.size());
+ EXPECT_TRUE(matching_types.find(PHONE_FAX_CITY_CODE) !=
+ matching_types.end());
+ EXPECT_TRUE(matching_types.find(PHONE_FAX_NUMBER) !=
+ matching_types.end());
+}
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("")));
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("1")));
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("12")));
- EXPECT_TRUE(phone_number.IsNumber(ASCIIToUTF16("123")));
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("1234")));
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("12345")));
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("123456")));
- EXPECT_TRUE(phone_number.IsNumber(ASCIIToUTF16("1234567")));
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("234567")));
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("34567")));
- EXPECT_TRUE(phone_number.IsNumber(ASCIIToUTF16("4567")));
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("567")));
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("67")));
- EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("7")));
+TEST(PhoneNumberTest, PhoneCombineHelper) {
+ PhoneNumber::PhoneCombineHelper number1(AutofillType::PHONE_HOME);
+ EXPECT_FALSE(number1.SetInfo(ADDRESS_BILLING_CITY,
+ ASCIIToUTF16("1")));
+ EXPECT_FALSE(number1.SetInfo(PHONE_FAX_COUNTRY_CODE,
+ ASCIIToUTF16("1")));
+ EXPECT_TRUE(number1.SetInfo(PHONE_HOME_COUNTRY_CODE,
+ ASCIIToUTF16("1")));
+ EXPECT_TRUE(number1.SetInfo(PHONE_HOME_CITY_CODE,
+ ASCIIToUTF16("650")));
+ EXPECT_TRUE(number1.SetInfo(PHONE_HOME_NUMBER,
+ ASCIIToUTF16("2345678")));
+ string16 parsed_phone;
+ EXPECT_TRUE(number1.ParseNumber("US", &parsed_phone));
+ // International format as it has a country code.
+ EXPECT_EQ(ASCIIToUTF16("+1 650-234-5678"), parsed_phone);
+
+ PhoneNumber::PhoneCombineHelper number2(AutofillType::PHONE_FAX);
+ EXPECT_FALSE(number2.SetInfo(PHONE_HOME_COUNTRY_CODE,
+ ASCIIToUTF16("1")));
+ EXPECT_TRUE(number2.SetInfo(PHONE_FAX_COUNTRY_CODE,
+ ASCIIToUTF16("1")));
+ EXPECT_TRUE(number2.SetInfo(PHONE_FAX_CITY_CODE,
+ ASCIIToUTF16("650")));
+ EXPECT_TRUE(number2.SetInfo(PHONE_FAX_NUMBER,
+ ASCIIToUTF16("2345679")));
+ EXPECT_TRUE(number2.ParseNumber("US", &parsed_phone));
+ // International format as it has a country code.
+ EXPECT_EQ(ASCIIToUTF16("+1 650-234-5679"), parsed_phone);
+
+ PhoneNumber::PhoneCombineHelper number3(AutofillType::PHONE_HOME);
+ EXPECT_TRUE(number3.SetInfo(PHONE_HOME_CITY_CODE,
+ ASCIIToUTF16("650")));
+ EXPECT_TRUE(number3.SetInfo(PHONE_HOME_NUMBER,
+ ASCIIToUTF16("2345680")));
+ EXPECT_TRUE(number3.ParseNumber("US", &parsed_phone));
+ // National format as it does not have a country code.
+ EXPECT_EQ(ASCIIToUTF16("(650) 234-5680"), parsed_phone);
+
+ PhoneNumber::PhoneCombineHelper number4(AutofillType::PHONE_HOME);
+ EXPECT_TRUE(number4.SetInfo(PHONE_HOME_CITY_CODE,
+ ASCIIToUTF16("123"))); // Incorrect city code.
+ EXPECT_TRUE(number4.SetInfo(PHONE_HOME_NUMBER,
+ ASCIIToUTF16("2345680")));
+ EXPECT_FALSE(number4.ParseNumber("US", &parsed_phone));
+ EXPECT_EQ(string16(), parsed_phone);
+
+ PhoneNumber::PhoneCombineHelper number5(AutofillType::PHONE_HOME);
+ EXPECT_TRUE(number5.SetInfo(PHONE_HOME_CITY_AND_NUMBER,
+ ASCIIToUTF16("6502345681")));
+ EXPECT_TRUE(number5.ParseNumber("US", &parsed_phone));
+ EXPECT_EQ(ASCIIToUTF16("(650) 234-5681"), parsed_phone);
+
+ PhoneNumber::PhoneCombineHelper number6(AutofillType::PHONE_HOME);
+ EXPECT_TRUE(number6.SetInfo(PHONE_HOME_CITY_CODE,
+ ASCIIToUTF16("650")));
+ EXPECT_TRUE(number6.SetInfo(PHONE_HOME_NUMBER,
+ ASCIIToUTF16("234")));
+ EXPECT_TRUE(number6.SetInfo(PHONE_HOME_NUMBER,
+ ASCIIToUTF16("5682")));
+ EXPECT_TRUE(number6.ParseNumber("US", &parsed_phone));
+ EXPECT_EQ(ASCIIToUTF16("(650) 234-5682"), parsed_phone);
}
diff --git a/chrome/test/data/autofill/merge/input/multimerge.in b/chrome/test/data/autofill/merge/input/multimerge.in
index 9906c27..1a90fcf 100644
--- a/chrome/test/data/autofill/merge/input/multimerge.in
+++ b/chrome/test/data/autofill/merge/input/multimerge.in
@@ -10,8 +10,8 @@ ADDRESS_HOME_CITY: San Francisco
ADDRESS_HOME_STATE: CA
ADDRESS_HOME_ZIP: 94102
ADDRESS_HOME_COUNTRY: United States
-PHONE_HOME_WHOLE_NUMBER: 1110001111
-PHONE_FAX_WHOLE_NUMBER: 8880008888
+PHONE_HOME_WHOLE_NUMBER: 16502101111
+PHONE_FAX_WHOLE_NUMBER: 7812008888
---
NAME_FIRST: Billy
NAME_MIDDLE: Bob
@@ -24,5 +24,5 @@ ADDRESS_HOME_CITY: San Francisco
ADDRESS_HOME_STATE: CA
ADDRESS_HOME_ZIP: 94102
ADDRESS_HOME_COUNTRY: United States
-PHONE_HOME_WHOLE_NUMBER: 2220003333
-PHONE_FAX_WHOLE_NUMBER: 8880008888
+PHONE_HOME_WHOLE_NUMBER: 6502343333
+PHONE_FAX_WHOLE_NUMBER: 7812008888
diff --git a/chrome/test/data/autofill/merge/input/primarycase.in b/chrome/test/data/autofill/merge/input/primarycase.in
index e546f1d3..73dc04b6 100644
--- a/chrome/test/data/autofill/merge/input/primarycase.in
+++ b/chrome/test/data/autofill/merge/input/primarycase.in
@@ -10,8 +10,8 @@ ADDRESS_HOME_CITY: SAN FRANCISCO
ADDRESS_HOME_STATE: CA
ADDRESS_HOME_ZIP: 94102
ADDRESS_HOME_COUNTRY: United States
-PHONE_HOME_WHOLE_NUMBER: 1110001111
-PHONE_FAX_WHOLE_NUMBER: 8880008888
+PHONE_HOME_WHOLE_NUMBER: 16502101111
+PHONE_FAX_WHOLE_NUMBER: 7812008888
---
NAME_FIRST: Billy
NAME_MIDDLE: Bob
@@ -24,5 +24,5 @@ ADDRESS_HOME_CITY: San Francisco
ADDRESS_HOME_STATE: CA
ADDRESS_HOME_ZIP: 94102
ADDRESS_HOME_COUNTRY: United States
-PHONE_HOME_WHOLE_NUMBER: 2220003333
-PHONE_FAX_WHOLE_NUMBER: 8880008888
+PHONE_HOME_WHOLE_NUMBER: 6502343333
+PHONE_FAX_WHOLE_NUMBER: 7812008888
diff --git a/chrome/test/data/autofill/merge/input/singlemerge.in b/chrome/test/data/autofill/merge/input/singlemerge.in
index f264015..58231f4 100644
--- a/chrome/test/data/autofill/merge/input/singlemerge.in
+++ b/chrome/test/data/autofill/merge/input/singlemerge.in
@@ -10,8 +10,8 @@ ADDRESS_HOME_CITY: San Francisco
ADDRESS_HOME_STATE: CA
ADDRESS_HOME_ZIP: 94102
ADDRESS_HOME_COUNTRY: United States
-PHONE_HOME_WHOLE_NUMBER: 1110001111
-PHONE_FAX_WHOLE_NUMBER: 8880008888
+PHONE_HOME_WHOLE_NUMBER: 16502101111
+PHONE_FAX_WHOLE_NUMBER: 7812008888
---
NAME_FIRST: Alice
NAME_MIDDLE: Anne
@@ -24,5 +24,5 @@ ADDRESS_HOME_CITY: San Francisco
ADDRESS_HOME_STATE: NY
ADDRESS_HOME_ZIP: 11001
ADDRESS_HOME_COUNTRY: Canada
-PHONE_HOME_WHOLE_NUMBER: 1110001111
-PHONE_FAX_WHOLE_NUMBER: 8880008888
+PHONE_HOME_WHOLE_NUMBER: 16502101111
+PHONE_FAX_WHOLE_NUMBER: 7812008888
diff --git a/chrome/test/data/autofill/merge/output/multimerge.out b/chrome/test/data/autofill/merge/output/multimerge.out
index 260f8bb..c0ca01d 100644
--- a/chrome/test/data/autofill/merge/output/multimerge.out
+++ b/chrome/test/data/autofill/merge/output/multimerge.out
@@ -14,6 +14,6 @@ ADDRESS_HOME_CITY: San Francisco
ADDRESS_HOME_STATE: CA
ADDRESS_HOME_ZIP: 94102
ADDRESS_HOME_COUNTRY: United States
-PHONE_HOME_WHOLE_NUMBER: 1110001111
-PHONE_HOME_WHOLE_NUMBER: 2220003333
-PHONE_FAX_WHOLE_NUMBER: 8880008888
+PHONE_HOME_WHOLE_NUMBER: 16502101111
+PHONE_HOME_WHOLE_NUMBER: 6502343333
+PHONE_FAX_WHOLE_NUMBER: 7812008888
diff --git a/chrome/test/data/autofill/merge/output/primarycase.out b/chrome/test/data/autofill/merge/output/primarycase.out
index 260f8bb..c0ca01d 100644
--- a/chrome/test/data/autofill/merge/output/primarycase.out
+++ b/chrome/test/data/autofill/merge/output/primarycase.out
@@ -14,6 +14,6 @@ ADDRESS_HOME_CITY: San Francisco
ADDRESS_HOME_STATE: CA
ADDRESS_HOME_ZIP: 94102
ADDRESS_HOME_COUNTRY: United States
-PHONE_HOME_WHOLE_NUMBER: 1110001111
-PHONE_HOME_WHOLE_NUMBER: 2220003333
-PHONE_FAX_WHOLE_NUMBER: 8880008888
+PHONE_HOME_WHOLE_NUMBER: 16502101111
+PHONE_HOME_WHOLE_NUMBER: 6502343333
+PHONE_FAX_WHOLE_NUMBER: 7812008888
diff --git a/chrome/test/data/autofill/merge/output/singlemerge.out b/chrome/test/data/autofill/merge/output/singlemerge.out
index 3181458..c0a25903 100644
--- a/chrome/test/data/autofill/merge/output/singlemerge.out
+++ b/chrome/test/data/autofill/merge/output/singlemerge.out
@@ -10,5 +10,5 @@ ADDRESS_HOME_CITY: San Francisco
ADDRESS_HOME_STATE: NY
ADDRESS_HOME_ZIP: 11001
ADDRESS_HOME_COUNTRY: Canada
-PHONE_HOME_WHOLE_NUMBER: 1110001111
-PHONE_FAX_WHOLE_NUMBER: 8880008888
+PHONE_HOME_WHOLE_NUMBER: 16502101111
+PHONE_FAX_WHOLE_NUMBER: 7812008888