OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/autofill/browser/phone_number_i18n.h" | 5 #include "components/autofill/browser/phone_number_i18n.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "components/autofill/browser/autofill_country.h" | 13 #include "components/autofill/browser/autofill_country.h" |
14 #include "third_party/libphonenumber/src/phonenumber_api.h" | 14 #include "third_party/libphonenumber/src/phonenumber_api.h" |
15 | 15 |
16 using i18n::phonenumbers::PhoneNumber; | 16 using i18n::phonenumbers::PhoneNumber; |
17 using i18n::phonenumbers::PhoneNumberUtil; | 17 using i18n::phonenumbers::PhoneNumberUtil; |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 std::string SanitizeRegion(const std::string& region) { | 21 std::string SanitizeRegion(const std::string& region, |
| 22 const std::string& app_locale) { |
22 if (region.length() == 2) | 23 if (region.length() == 2) |
23 return region; | 24 return region; |
24 | 25 |
25 return AutofillCountry::CountryCodeForLocale( | 26 return AutofillCountry::CountryCodeForLocale(app_locale); |
26 AutofillCountry::ApplicationLocale()); | |
27 } | 27 } |
28 | 28 |
29 // Returns true if |phone_number| is valid. | 29 // Returns true if |phone_number| is valid. |
30 bool IsValidPhoneNumber(const PhoneNumber& phone_number) { | 30 bool IsValidPhoneNumber(const PhoneNumber& phone_number) { |
31 PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); | 31 PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); |
32 if (!phone_util->IsPossibleNumber(phone_number)) | 32 if (!phone_util->IsPossibleNumber(phone_number)) |
33 return false; | 33 return false; |
34 | 34 |
35 // Verify that the number has a valid area code (that in some cases could be | 35 // Verify that the number has a valid area code (that in some cases could be |
36 // empty) for the parsed country code. Also verify that this is a valid | 36 // empty) for the parsed country code. Also verify that this is a valid |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 !StartsWith(normalized_number, *country_code, | 142 !StartsWith(normalized_number, *country_code, |
143 true /* case_sensitive */)) { | 143 true /* case_sensitive */)) { |
144 country_code->clear(); | 144 country_code->clear(); |
145 } | 145 } |
146 } | 146 } |
147 | 147 |
148 return true; | 148 return true; |
149 } | 149 } |
150 | 150 |
151 string16 NormalizePhoneNumber(const string16& value, | 151 string16 NormalizePhoneNumber(const string16& value, |
152 std::string const& region) { | 152 const std::string& region) { |
| 153 DCHECK_EQ(2u, region.size()); |
153 string16 country_code; | 154 string16 country_code; |
154 string16 unused_city_code; | 155 string16 unused_city_code; |
155 string16 unused_number; | 156 string16 unused_number; |
156 PhoneNumber phone_number; | 157 PhoneNumber phone_number; |
157 if (!ParsePhoneNumber(value, SanitizeRegion(region), &country_code, | 158 if (!ParsePhoneNumber(value, region, &country_code, &unused_city_code, |
158 &unused_city_code, &unused_number, &phone_number)) { | 159 &unused_number, &phone_number)) { |
159 return string16(); // Parsing failed - do not store phone. | 160 return string16(); // Parsing failed - do not store phone. |
160 } | 161 } |
161 | 162 |
162 string16 normalized_number; | 163 string16 normalized_number; |
163 FormatValidatedNumber(phone_number, country_code, NULL, &normalized_number); | 164 FormatValidatedNumber(phone_number, country_code, NULL, &normalized_number); |
164 return normalized_number; | 165 return normalized_number; |
165 } | 166 } |
166 | 167 |
167 bool ConstructPhoneNumber(const string16& country_code, | 168 bool ConstructPhoneNumber(const string16& country_code, |
168 const string16& city_code, | 169 const string16& city_code, |
169 const string16& number, | 170 const string16& number, |
170 const std::string& region, | 171 const std::string& region, |
171 string16* whole_number) { | 172 string16* whole_number) { |
| 173 DCHECK_EQ(2u, region.size()); |
172 whole_number->clear(); | 174 whole_number->clear(); |
173 | 175 |
174 string16 unused_country_code; | 176 string16 unused_country_code; |
175 string16 unused_city_code; | 177 string16 unused_city_code; |
176 string16 unused_number; | 178 string16 unused_number; |
177 PhoneNumber phone_number; | 179 PhoneNumber phone_number; |
178 if (!ParsePhoneNumber(country_code + city_code + number, | 180 if (!ParsePhoneNumber(country_code + city_code + number, region, |
179 SanitizeRegion(region), | |
180 &unused_country_code, &unused_city_code, &unused_number, | 181 &unused_country_code, &unused_city_code, &unused_number, |
181 &phone_number)) { | 182 &phone_number)) { |
182 return false; | 183 return false; |
183 } | 184 } |
184 | 185 |
185 FormatValidatedNumber(phone_number, country_code, whole_number, NULL); | 186 FormatValidatedNumber(phone_number, country_code, whole_number, NULL); |
186 return true; | 187 return true; |
187 } | 188 } |
188 | 189 |
189 bool PhoneNumbersMatch(const string16& number_a, | 190 bool PhoneNumbersMatch(const string16& number_a, |
190 const string16& number_b, | 191 const string16& number_b, |
191 const std::string& raw_region) { | 192 const std::string& raw_region, |
| 193 const std::string& app_locale) { |
192 // Sanitize the provided |raw_region| before trying to use it for parsing. | 194 // Sanitize the provided |raw_region| before trying to use it for parsing. |
193 const std::string region = SanitizeRegion(raw_region); | 195 const std::string region = SanitizeRegion(raw_region, app_locale); |
194 | 196 |
195 PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); | 197 PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); |
196 | 198 |
197 // Parse phone numbers based on the region | 199 // Parse phone numbers based on the region |
198 PhoneNumber i18n_number1; | 200 PhoneNumber i18n_number1; |
199 if (phone_util->Parse(UTF16ToUTF8(number_a), region.c_str(), &i18n_number1) != | 201 if (phone_util->Parse(UTF16ToUTF8(number_a), region.c_str(), &i18n_number1) != |
200 PhoneNumberUtil::NO_PARSING_ERROR) { | 202 PhoneNumberUtil::NO_PARSING_ERROR) { |
201 return false; | 203 return false; |
202 } | 204 } |
203 | 205 |
(...skipping 11 matching lines...) Expand all Loading... |
215 return false; | 217 return false; |
216 case PhoneNumberUtil::NSN_MATCH: | 218 case PhoneNumberUtil::NSN_MATCH: |
217 case PhoneNumberUtil::EXACT_MATCH: | 219 case PhoneNumberUtil::EXACT_MATCH: |
218 return true; | 220 return true; |
219 } | 221 } |
220 | 222 |
221 NOTREACHED(); | 223 NOTREACHED(); |
222 return false; | 224 return false; |
223 } | 225 } |
224 | 226 |
225 PhoneObject::PhoneObject(const string16& number, const std::string& region) | 227 PhoneObject::PhoneObject(const string16& number, |
226 : region_(SanitizeRegion(region)), | 228 const std::string& region) |
| 229 : region_(region), |
227 i18n_number_(NULL) { | 230 i18n_number_(NULL) { |
| 231 DCHECK_EQ(2u, region.size()); |
228 // TODO(isherman): Autofill profiles should always have a |region| set, but in | 232 // TODO(isherman): Autofill profiles should always have a |region| set, but in |
229 // some cases it should be marked as implicit. Otherwise, phone numbers | 233 // some cases it should be marked as implicit. Otherwise, phone numbers |
230 // might behave differently when they are synced across computers: | 234 // might behave differently when they are synced across computers: |
231 // [ http://crbug.com/100845 ]. Once the bug is fixed, add a DCHECK here to | 235 // [ http://crbug.com/100845 ]. Once the bug is fixed, add a DCHECK here to |
232 // verify. | 236 // verify. |
233 | 237 |
234 scoped_ptr<PhoneNumber> i18n_number(new PhoneNumber); | 238 scoped_ptr<PhoneNumber> i18n_number(new PhoneNumber); |
235 if (ParsePhoneNumber(number, region_, &country_code_, &city_code_, &number_, | 239 if (ParsePhoneNumber(number, region_, &country_code_, &city_code_, &number_, |
236 i18n_number.get())) { | 240 i18n_number.get())) { |
237 // The phone number was successfully parsed, so store the parsed version. | 241 // The phone number was successfully parsed, so store the parsed version. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 city_code_ = other.city_code_; | 291 city_code_ = other.city_code_; |
288 number_ = other.number_; | 292 number_ = other.number_; |
289 | 293 |
290 formatted_number_ = other.formatted_number_; | 294 formatted_number_ = other.formatted_number_; |
291 whole_number_ = other.whole_number_; | 295 whole_number_ = other.whole_number_; |
292 | 296 |
293 return *this; | 297 return *this; |
294 } | 298 } |
295 | 299 |
296 } // namespace autofill_i18n | 300 } // namespace autofill_i18n |
OLD | NEW |