| 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 "chrome/browser/autofill/personal_data_manager.h" | 5 #include "chrome/browser/autofill/personal_data_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
| 12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 13 #include "chrome/browser/autofill/autofill-inl.h" | 13 #include "chrome/browser/autofill/autofill-inl.h" |
| 14 #include "chrome/browser/autofill/autofill_field.h" | 14 #include "chrome/browser/autofill/autofill_field.h" |
| 15 #include "chrome/browser/autofill/autofill_metrics.h" | 15 #include "chrome/browser/autofill/autofill_metrics.h" |
| 16 #include "chrome/browser/autofill/form_structure.h" | 16 #include "chrome/browser/autofill/form_structure.h" |
| 17 #include "chrome/browser/autofill/phone_number.h" | 17 #include "chrome/browser/autofill/phone_number.h" |
| 18 #include "chrome/browser/autofill/phone_number_i18n.h" |
| 18 #include "chrome/browser/autofill/select_control_handler.h" | 19 #include "chrome/browser/autofill/select_control_handler.h" |
| 19 #include "chrome/browser/prefs/pref_service.h" | 20 #include "chrome/browser/prefs/pref_service.h" |
| 20 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
| 21 #include "chrome/browser/sync/profile_sync_service.h" | 22 #include "chrome/browser/sync/profile_sync_service.h" |
| 22 #include "chrome/browser/webdata/web_data_service.h" | 23 #include "chrome/browser/webdata/web_data_service.h" |
| 23 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
| 24 #include "content/browser/browser_thread.h" | 25 #include "content/browser/browser_thread.h" |
| 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRegularExpression.
h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRegularExpression.
h" |
| 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" | 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" |
| 27 | 28 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 scoped_ptr<CreditCard> local_imported_credit_card(new CreditCard); | 219 scoped_ptr<CreditCard> local_imported_credit_card(new CreditCard); |
| 219 | 220 |
| 220 // Parse the form and construct a profile based on the information that is | 221 // Parse the form and construct a profile based on the information that is |
| 221 // possible to import. | 222 // possible to import. |
| 222 int importable_credit_card_fields = 0; | 223 int importable_credit_card_fields = 0; |
| 223 std::vector<const FormStructure*>::const_iterator iter; | 224 std::vector<const FormStructure*>::const_iterator iter; |
| 224 | 225 |
| 225 // Detect and discard forms with multiple fields of the same type. | 226 // Detect and discard forms with multiple fields of the same type. |
| 226 std::set<AutofillFieldType> types_seen; | 227 std::set<AutofillFieldType> types_seen; |
| 227 | 228 |
| 229 // We only set complete phone, so aggregate phone parts in these vars and set |
| 230 // complete at the end. |
| 231 PhoneNumber::PhoneCombineHelper home(AutofillType::PHONE_HOME); |
| 232 PhoneNumber::PhoneCombineHelper fax(AutofillType::PHONE_FAX); |
| 233 |
| 228 for (size_t i = 0; i < form.field_count(); ++i) { | 234 for (size_t i = 0; i < form.field_count(); ++i) { |
| 229 const AutofillField* field = form.field(i); | 235 const AutofillField* field = form.field(i); |
| 230 string16 value = CollapseWhitespace(field->value, false); | 236 string16 value = CollapseWhitespace(field->value, false); |
| 231 | 237 |
| 232 // If we don't know the type of the field, or the user hasn't entered any | 238 // If we don't know the type of the field, or the user hasn't entered any |
| 233 // information into the field, then skip it. | 239 // information into the field, then skip it. |
| 234 if (!field->IsFieldFillable() || value.empty()) | 240 if (!field->IsFieldFillable() || value.empty()) |
| 235 continue; | 241 continue; |
| 236 | 242 |
| 237 AutofillFieldType field_type = field->type(); | 243 AutofillFieldType field_type = field->type(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 255 local_imported_credit_card->SetInfoForMonthInputType(value); | 261 local_imported_credit_card->SetInfoForMonthInputType(value); |
| 256 } else { | 262 } else { |
| 257 if (field_type == CREDIT_CARD_NUMBER) { | 263 if (field_type == CREDIT_CARD_NUMBER) { |
| 258 // Clean up any imported credit card numbers. | 264 // Clean up any imported credit card numbers. |
| 259 value = CreditCard::StripSeparators(value); | 265 value = CreditCard::StripSeparators(value); |
| 260 } | 266 } |
| 261 local_imported_credit_card->SetInfo(field_type, value); | 267 local_imported_credit_card->SetInfo(field_type, value); |
| 262 } | 268 } |
| 263 ++importable_credit_card_fields; | 269 ++importable_credit_card_fields; |
| 264 } else { | 270 } else { |
| 265 // In the case of a phone number, if the whole phone number was entered | 271 // We need to store phone data in the variables, before building the whole |
| 266 // into a single field, then parse it and set the sub components. | 272 // number at the end. The rest of the fields are set "as is". |
| 267 if (AutofillType(field_type).subgroup() == | 273 // If the fields are not the phone fields in question both home.SetInfo() |
| 268 AutofillType::PHONE_WHOLE_NUMBER) { | 274 // and fax.SetInfo() are going to return false. |
| 269 string16 number; | 275 if (!home.SetInfo(field_type, value) && !fax.SetInfo(field_type, value)) |
| 270 string16 city_code; | 276 imported_profile->SetInfo(field_type, value); |
| 271 string16 country_code; | |
| 272 PhoneNumber::ParsePhoneNumber(value, | |
| 273 &number, | |
| 274 &city_code, | |
| 275 &country_code); | |
| 276 if (number.empty()) | |
| 277 continue; | |
| 278 | |
| 279 if (group == AutofillType::PHONE_HOME) { | |
| 280 imported_profile->SetInfo(PHONE_HOME_COUNTRY_CODE, country_code); | |
| 281 imported_profile->SetInfo(PHONE_HOME_CITY_CODE, city_code); | |
| 282 imported_profile->SetInfo(PHONE_HOME_NUMBER, number); | |
| 283 } else if (group == AutofillType::PHONE_FAX) { | |
| 284 imported_profile->SetInfo(PHONE_FAX_COUNTRY_CODE, country_code); | |
| 285 imported_profile->SetInfo(PHONE_FAX_CITY_CODE, city_code); | |
| 286 imported_profile->SetInfo(PHONE_FAX_NUMBER, number); | |
| 287 } | |
| 288 | |
| 289 continue; | |
| 290 } | |
| 291 | |
| 292 // Phone and fax numbers can be split across multiple fields, so we | |
| 293 // might have already stored the prefix, and now be at the suffix. | |
| 294 // If so, combine them to form the full number. | |
| 295 if (group == AutofillType::PHONE_HOME || | |
| 296 group == AutofillType::PHONE_FAX) { | |
| 297 AutofillFieldType number_type = PHONE_HOME_NUMBER; | |
| 298 if (group == AutofillType::PHONE_FAX) | |
| 299 number_type = PHONE_FAX_NUMBER; | |
| 300 | |
| 301 string16 stored_number = imported_profile->GetInfo(number_type); | |
| 302 if (stored_number.size() == | |
| 303 static_cast<size_t>(PhoneNumber::kPrefixLength) && | |
| 304 value.size() == static_cast<size_t>(PhoneNumber::kSuffixLength)) { | |
| 305 value = stored_number + value; | |
| 306 } | |
| 307 } | |
| 308 | |
| 309 imported_profile->SetInfo(field_type, value); | |
| 310 | 277 |
| 311 // Reject profiles with invalid country information. | 278 // Reject profiles with invalid country information. |
| 312 if (field_type == ADDRESS_HOME_COUNTRY && | 279 if (field_type == ADDRESS_HOME_COUNTRY && |
| 313 !value.empty() && imported_profile->CountryCode().empty()) { | 280 !value.empty() && imported_profile->CountryCode().empty()) { |
| 314 imported_profile.reset(); | 281 imported_profile.reset(); |
| 315 break; | 282 break; |
| 316 } | 283 } |
| 317 } | 284 } |
| 318 } | 285 } |
| 319 | 286 |
| 287 // Build phone numbers if they are from parts. |
| 288 if (imported_profile.get()) { |
| 289 string16 constructed_number; |
| 290 if (!home.empty()) { |
| 291 if (!home.ParseNumber(imported_profile->CountryCode(), |
| 292 &constructed_number)) { |
| 293 imported_profile.reset(); |
| 294 } else { |
| 295 imported_profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number); |
| 296 } |
| 297 } |
| 298 if (!fax.empty()) { |
| 299 if (!fax.ParseNumber(imported_profile->CountryCode(), |
| 300 &constructed_number)) { |
| 301 imported_profile.reset(); |
| 302 } else { |
| 303 imported_profile->SetInfo(PHONE_FAX_WHOLE_NUMBER, constructed_number); |
| 304 } |
| 305 } |
| 306 } |
| 307 // Normalize phone numbers. |
| 308 if (imported_profile.get()) { |
| 309 // Reject profile if even one of the phones is invalid. |
| 310 if (!imported_profile->NormalizePhones()) |
| 311 imported_profile.reset(); |
| 312 } |
| 313 |
| 320 // Reject the profile if minimum address and validation requirements are not | 314 // Reject the profile if minimum address and validation requirements are not |
| 321 // met. | 315 // met. |
| 322 if (imported_profile.get() && !IsValidLearnableProfile(*imported_profile)) | 316 if (imported_profile.get() && !IsValidLearnableProfile(*imported_profile)) |
| 323 imported_profile.reset(); | 317 imported_profile.reset(); |
| 324 | 318 |
| 325 // Reject the credit card if we did not detect enough filled credit card | 319 // Reject the credit card if we did not detect enough filled credit card |
| 326 // fields or if the credit card number does not seem to be valid. | 320 // fields or if the credit card number does not seem to be valid. |
| 327 if (local_imported_credit_card.get() && | 321 if (local_imported_credit_card.get() && |
| 328 (importable_credit_card_fields < kMinCreditCardImportSize || | 322 (importable_credit_card_fields < kMinCreditCardImportSize || |
| 329 !CreditCard::IsValidCreditCardNumber( | 323 !CreditCard::IsValidCreditCardNumber( |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 } | 974 } |
| 981 | 975 |
| 982 const AutofillMetrics* PersonalDataManager::metric_logger() const { | 976 const AutofillMetrics* PersonalDataManager::metric_logger() const { |
| 983 return metric_logger_.get(); | 977 return metric_logger_.get(); |
| 984 } | 978 } |
| 985 | 979 |
| 986 void PersonalDataManager::set_metric_logger( | 980 void PersonalDataManager::set_metric_logger( |
| 987 const AutofillMetrics* metric_logger) { | 981 const AutofillMetrics* metric_logger) { |
| 988 metric_logger_.reset(metric_logger); | 982 metric_logger_.reset(metric_logger); |
| 989 } | 983 } |
| OLD | NEW |