1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/phone_number_i18n.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_country.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/libphonenumber/src/phonenumber_api.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using i18n::phonenumbers::PhoneNumber; 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using i18n::phonenumbers::PhoneNumberUtil; 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace autofill { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string SanitizeRegion(const std::string& region, 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& app_locale) { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (region.length() == 2) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return region; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return AutofillCountry::CountryCodeForLocale(app_locale); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if |phone_number| is valid. 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsValidPhoneNumber(const PhoneNumber& phone_number) { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!phone_util->IsPossibleNumber(phone_number)) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify that the number has a valid area code (that in some cases could be 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // empty) for the parsed country code. Also verify that this is a valid 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // number (for example, in the US 1234567 is not valid, because numbers do not 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // start with 1). 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!phone_util->IsValidNumber(phone_number)) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Formats the given |number| as a human-readable string, and writes the result 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// into |formatted_number|. Also, normalizes the formatted number, and writes 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// that result into |normalized_number|. This function should only be called 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// with numbers already known to be valid, i.e. validation should be done prior 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// to calling this function. Note that the |country_code|, which determines 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// whether to format in the national or in the international format, is passed 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in explicitly, as |number| might have an implicit country code set, even 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// though the original input lacked a country code. 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FormatValidatedNumber(const PhoneNumber& number, 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& country_code, 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16* formatted_number, 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16* normalized_number) { 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumberUtil::PhoneNumberFormat format = 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) country_code.empty() ? 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumberUtil::NATIONAL : 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumberUtil::INTERNATIONAL; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string processed_number; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) phone_util->Format(number, format, &processed_number); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string region_code; 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) phone_util->GetRegionCodeForNumber(number, ®ion_code); 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Drop the leading '+' for US numbers as some US sites can't handle the "+", 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // and in the US dialing "+1..." is the same as dialing "1...". 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string prefix; 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (processed_number[0] == '+') { 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) processed_number = processed_number.substr(1); 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (region_code != "US") 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prefix = "+"; 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (formatted_number) 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *formatted_number = base::UTF8ToUTF16(prefix + processed_number); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (normalized_number) { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) phone_util->NormalizeDigitsOnly(&processed_number); 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *normalized_number = base::UTF8ToUTF16(prefix + processed_number); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace i18n { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Parses the number stored in |value| as it should be interpreted in the given 9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// |default_region|, and stores the results into the remaining arguments. 9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// The |default_region| should be sanitized prior to calling this function. 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ParsePhoneNumber(const base::string16& value, 9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const std::string& default_region, 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16* country_code, 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16* city_code, 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16* number, 10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::string* inferred_region, 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumber* i18n_number) { 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) country_code->clear(); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) city_code->clear(); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) number->clear(); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *i18n_number = PhoneNumber(); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string number_text(base::UTF16ToUTF8(value)); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Parse phone number based on the region. 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // The |default_region| should already be sanitized. 11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK_EQ(2U, default_region.size()); 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (phone_util->ParseAndKeepRawInput( 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch number_text, default_region, i18n_number) != 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PhoneNumberUtil::NO_PARSING_ERROR) { 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!IsValidPhoneNumber(*i18n_number)) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string national_significant_number; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) phone_util->GetNationalSignificantNumber(*i18n_number, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &national_significant_number); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int area_length = phone_util->GetLengthOfGeographicalAreaCode(*i18n_number); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int destination_length = 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) phone_util->GetLengthOfNationalDestinationCode(*i18n_number); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Some phones have a destination code in lieu of area code: mobile operators 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in Europe, toll and toll-free numbers in USA, etc. From our point of view 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // these two types of codes are the same. 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (destination_length > area_length) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) area_length = destination_length; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string area_code; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string subscriber_number; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (area_length > 0) { 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) area_code = national_significant_number.substr(0, area_length); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) subscriber_number = national_significant_number.substr(area_length); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) subscriber_number = national_significant_number; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *number = base::UTF8ToUTF16(subscriber_number); 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *city_code = base::UTF8ToUTF16(area_code); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if parsed number has a country code that was not inferred from the 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // region. 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (i18n_number->has_country_code() && 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i18n_number->country_code_source() != PhoneNumber::FROM_DEFAULT_COUNTRY) { 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *country_code = base::UTF8ToUTF16( 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPrintf("%d", i18n_number->country_code())); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // The region might be different from what we started with. 15723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) phone_util->GetRegionCodeForNumber(*i18n_number, inferred_region); 15823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 NormalizePhoneNumber(const base::string16& value, 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& region) { 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(2u, region.size()); 16523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::string16 country_code, unused_city_code, unused_number; 16623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::string unused_region; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumber phone_number; 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!ParsePhoneNumber(value, region, &country_code, &unused_city_code, 16923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &unused_number, &unused_region, &phone_number)) { 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::string16(); // Parsing failed - do not store phone. 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 normalized_number; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FormatValidatedNumber(phone_number, country_code, NULL, &normalized_number); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return normalized_number; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ConstructPhoneNumber(const base::string16& country_code, 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& city_code, 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& number, 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& region, 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16* whole_number) { 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(2u, region.size()); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) whole_number->clear(); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::string16 unused_country_code, unused_city_code, unused_number; 18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::string unused_region; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumber phone_number; 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!ParsePhoneNumber(country_code + city_code + number, region, 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &unused_country_code, &unused_city_code, &unused_number, 19123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &unused_region, &phone_number)) { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FormatValidatedNumber(phone_number, country_code, whole_number, NULL); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool PhoneNumbersMatch(const base::string16& number_a, 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& number_b, 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& raw_region, 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& app_locale) { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanitize the provided |raw_region| before trying to use it for parsing. 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string region = SanitizeRegion(raw_region, app_locale); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Parse phone numbers based on the region 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumber i18n_number1; 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (phone_util->Parse( 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF16ToUTF8(number_a), region.c_str(), &i18n_number1) != 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PhoneNumberUtil::NO_PARSING_ERROR) { 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PhoneNumber i18n_number2; 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (phone_util->Parse( 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF16ToUTF8(number_b), region.c_str(), &i18n_number2) != 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PhoneNumberUtil::NO_PARSING_ERROR) { 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (phone_util->IsNumberMatch(i18n_number1, i18n_number2)) { 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case PhoneNumberUtil::INVALID_NUMBER: 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case PhoneNumberUtil::NO_MATCH: 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case PhoneNumberUtil::SHORT_NSN_MATCH: 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case PhoneNumberUtil::NSN_MATCH: 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case PhoneNumberUtil::EXACT_MATCH: 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PhoneObject::PhoneObject(const base::string16& number, 23923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const std::string& region) { 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(2u, region.size()); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(isherman): Autofill profiles should always have a |region| set, but in 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // some cases it should be marked as implicit. Otherwise, phone numbers 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // might behave differently when they are synced across computers: 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // [ http://crbug.com/100845 ]. Once the bug is fixed, add a DCHECK here to 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // verify. 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<PhoneNumber> i18n_number(new PhoneNumber); 24823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (ParsePhoneNumber(number, region, &country_code_, &city_code_, &number_, 24923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ®ion_, i18n_number.get())) { 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The phone number was successfully parsed, so store the parsed version. 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The formatted and normalized versions will be set on the first call to 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the coresponding methods. 25323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) i18n_number_ = i18n_number.Pass(); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Parsing failed. Store passed phone "as is" into |whole_number_|. 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) whole_number_ = number; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PhoneObject::PhoneObject(const PhoneObject& other) { *this = other; } 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PhoneObject::PhoneObject() {} 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)PhoneObject::~PhoneObject() {} 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const base::string16& PhoneObject::GetFormattedNumber() const { 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i18n_number_ && formatted_number_.empty()) { 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FormatValidatedNumber(*i18n_number_, country_code_, &formatted_number_, 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &whole_number_); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return formatted_number_; 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)base::string16 PhoneObject::GetNationallyFormattedNumber() const { 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::string16 formatted = whole_number_; 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (i18n_number_) 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FormatValidatedNumber(*i18n_number_, base::string16(), &formatted, NULL); 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return formatted; 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const base::string16& PhoneObject::GetWholeNumber() const { 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i18n_number_ && whole_number_.empty()) { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FormatValidatedNumber(*i18n_number_, country_code_, &formatted_number_, 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &whole_number_); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return whole_number_; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PhoneObject& PhoneObject::operator=(const PhoneObject& other) { 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (this == &other) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *this; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) region_ = other.region_; 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (other.i18n_number_.get()) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i18n_number_.reset(new PhoneNumber(*other.i18n_number_)); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i18n_number_.reset(); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) country_code_ = other.country_code_; 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) city_code_ = other.city_code_; 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) number_ = other.number_; 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) formatted_number_ = other.formatted_number_; 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) whole_number_ = other.whole_number_; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *this; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace i18n 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace autofill 315