OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/core/browser/personal_data_manager.h" | 5 #include "components/autofill/core/browser/personal_data_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <iterator> | 9 #include <iterator> |
10 | 10 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 return false; | 102 return false; |
103 | 103 |
104 if (country.requires_zip() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty()) | 104 if (country.requires_zip() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty()) |
105 return false; | 105 return false; |
106 | 106 |
107 return true; | 107 return true; |
108 } | 108 } |
109 | 109 |
110 // Return true if the |field_type| and |value| are valid within the context | 110 // Return true if the |field_type| and |value| are valid within the context |
111 // of importing a form. | 111 // of importing a form. |
112 bool IsValidFieldTypeAndValue(const std::set<AutofillFieldType>& types_seen, | 112 bool IsValidFieldTypeAndValue(const std::set<ServerFieldType>& types_seen, |
113 AutofillFieldType field_type, | 113 ServerFieldType field_type, |
114 const base::string16& value) { | 114 const base::string16& value) { |
115 // Abandon the import if two fields of the same type are encountered. | 115 // Abandon the import if two fields of the same type are encountered. |
116 // This indicates ambiguous data or miscategorization of types. | 116 // This indicates ambiguous data or miscategorization of types. |
117 // Make an exception for PHONE_HOME_NUMBER however as both prefix and | 117 // Make an exception for PHONE_HOME_NUMBER however as both prefix and |
118 // suffix are stored against this type, and for EMAIL_ADDRESS because it is | 118 // suffix are stored against this type, and for EMAIL_ADDRESS because it is |
119 // common to see second 'confirm email address' fields on forms. | 119 // common to see second 'confirm email address' fields on forms. |
120 if (types_seen.count(field_type) && field_type != PHONE_HOME_NUMBER && | 120 if (types_seen.count(field_type) && |
| 121 field_type != PHONE_HOME_NUMBER && |
121 field_type != EMAIL_ADDRESS) | 122 field_type != EMAIL_ADDRESS) |
122 return false; | 123 return false; |
123 | 124 |
124 // Abandon the import if an email address value shows up in a field that is | 125 // Abandon the import if an email address value shows up in a field that is |
125 // not an email address. | 126 // not an email address. |
126 if (field_type != EMAIL_ADDRESS && autofill::IsValidEmailAddress(value)) | 127 if (field_type != EMAIL_ADDRESS && IsValidEmailAddress(value)) |
127 return false; | 128 return false; |
128 | 129 |
129 return true; | 130 return true; |
130 } | 131 } |
131 | 132 |
132 } // namespace | 133 } // namespace |
133 | 134 |
134 PersonalDataManager::PersonalDataManager(const std::string& app_locale) | 135 PersonalDataManager::PersonalDataManager(const std::string& app_locale) |
135 : browser_context_(NULL), | 136 : browser_context_(NULL), |
136 is_data_loaded_(false), | 137 is_data_loaded_(false), |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 | 234 |
234 const std::string origin = form.source_url().spec(); | 235 const std::string origin = form.source_url().spec(); |
235 imported_profile->set_origin(origin); | 236 imported_profile->set_origin(origin); |
236 local_imported_credit_card->set_origin(origin); | 237 local_imported_credit_card->set_origin(origin); |
237 | 238 |
238 // Parse the form and construct a profile based on the information that is | 239 // Parse the form and construct a profile based on the information that is |
239 // possible to import. | 240 // possible to import. |
240 int importable_credit_card_fields = 0; | 241 int importable_credit_card_fields = 0; |
241 | 242 |
242 // Detect and discard forms with multiple fields of the same type. | 243 // Detect and discard forms with multiple fields of the same type. |
243 std::set<AutofillFieldType> types_seen; | 244 // TODO(isherman): Some types are overlapping but not equal, e.g. phone number |
| 245 // parts, address parts. |
| 246 std::set<ServerFieldType> types_seen; |
244 | 247 |
245 // We only set complete phone, so aggregate phone parts in these vars and set | 248 // We only set complete phone, so aggregate phone parts in these vars and set |
246 // complete at the end. | 249 // complete at the end. |
247 PhoneNumber::PhoneCombineHelper home; | 250 PhoneNumber::PhoneCombineHelper home; |
248 | 251 |
249 for (size_t i = 0; i < form.field_count(); ++i) { | 252 for (size_t i = 0; i < form.field_count(); ++i) { |
250 const AutofillField* field = form.field(i); | 253 const AutofillField* field = form.field(i); |
251 base::string16 value = CollapseWhitespace(field->value, false); | 254 base::string16 value = CollapseWhitespace(field->value, false); |
252 | 255 |
253 // If we don't know the type of the field, or the user hasn't entered any | 256 // If we don't know the type of the field, or the user hasn't entered any |
254 // information into the field, then skip it. | 257 // information into the field, then skip it. |
255 if (!field->IsFieldFillable() || value.empty()) | 258 if (!field->IsFieldFillable() || value.empty()) |
256 continue; | 259 continue; |
257 | 260 |
258 AutofillFieldType field_type = field->type(); | 261 AutofillType field_type = field->Type(); |
259 FieldTypeGroup group(AutofillType(field_type).group()); | 262 ServerFieldType server_field_type = field_type.server_type(); |
| 263 FieldTypeGroup group(field_type.group()); |
260 | 264 |
261 // There can be multiple email fields (e.g. in the case of 'confirm email' | 265 // There can be multiple email fields (e.g. in the case of 'confirm email' |
262 // fields) but they must all contain the same value, else the profile is | 266 // fields) but they must all contain the same value, else the profile is |
263 // invalid. | 267 // invalid. |
264 if (field_type == EMAIL_ADDRESS) { | 268 if (server_field_type == EMAIL_ADDRESS) { |
265 if (types_seen.count(field_type) && | 269 if (types_seen.count(server_field_type) && |
266 imported_profile->GetRawInfo(field_type) != value) { | 270 imported_profile->GetRawInfo(EMAIL_ADDRESS) != value) { |
267 imported_profile.reset(); | 271 imported_profile.reset(); |
268 break; | 272 break; |
269 } | 273 } |
270 } | 274 } |
271 | 275 |
272 // If the |field_type| and |value| don't pass basic validity checks then | 276 // If the |field_type| and |value| don't pass basic validity checks then |
273 // abandon the import. | 277 // abandon the import. |
274 if (!IsValidFieldTypeAndValue(types_seen, field_type, value)) { | 278 if (!IsValidFieldTypeAndValue(types_seen, server_field_type, value)) { |
275 imported_profile.reset(); | 279 imported_profile.reset(); |
276 local_imported_credit_card.reset(); | 280 local_imported_credit_card.reset(); |
277 break; | 281 break; |
278 } | 282 } |
279 | 283 |
280 types_seen.insert(field_type); | 284 types_seen.insert(server_field_type); |
281 | 285 |
282 if (group == CREDIT_CARD) { | 286 if (group == CREDIT_CARD) { |
283 if (LowerCaseEqualsASCII(field->form_control_type, "month")) { | 287 if (LowerCaseEqualsASCII(field->form_control_type, "month")) { |
284 DCHECK_EQ(CREDIT_CARD_EXP_MONTH, field_type); | 288 DCHECK_EQ(CREDIT_CARD_EXP_MONTH, server_field_type); |
285 local_imported_credit_card->SetInfoForMonthInputType(value); | 289 local_imported_credit_card->SetInfoForMonthInputType(value); |
286 } else { | 290 } else { |
287 local_imported_credit_card->SetInfo(field_type, value, app_locale_); | 291 local_imported_credit_card->SetInfo(field_type, value, app_locale_); |
288 } | 292 } |
289 ++importable_credit_card_fields; | 293 ++importable_credit_card_fields; |
290 } else { | 294 } else { |
291 // We need to store phone data in the variables, before building the whole | 295 // We need to store phone data in the variables, before building the whole |
292 // number at the end. The rest of the fields are set "as is". | 296 // number at the end. The rest of the fields are set "as is". |
293 // If the fields are not the phone fields in question home.SetInfo() is | 297 // If the fields are not the phone fields in question home.SetInfo() is |
294 // going to return false. | 298 // going to return false. |
295 if (!home.SetInfo(field_type, value)) | 299 if (!home.SetInfo(field_type, value)) |
296 imported_profile->SetInfo(field_type, value, app_locale_); | 300 imported_profile->SetInfo(field_type, value, app_locale_); |
297 | 301 |
298 // Reject profiles with invalid country information. | 302 // Reject profiles with invalid country information. |
299 if (field_type == ADDRESS_HOME_COUNTRY && | 303 if (server_field_type == ADDRESS_HOME_COUNTRY && |
300 !value.empty() && | 304 !value.empty() && |
301 imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) { | 305 imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) { |
302 imported_profile.reset(); | 306 imported_profile.reset(); |
303 break; | 307 break; |
304 } | 308 } |
305 } | 309 } |
306 } | 310 } |
307 | 311 |
308 // Construct the phone number. Reject the profile if the number is invalid. | 312 // Construct the phone number. Reject the profile if the number is invalid. |
309 if (imported_profile.get() && !home.IsEmpty()) { | 313 if (imported_profile.get() && !home.IsEmpty()) { |
310 base::string16 constructed_number; | 314 base::string16 constructed_number; |
311 if (!home.ParseNumber(*imported_profile, app_locale_, | 315 if (!home.ParseNumber(*imported_profile, app_locale_, |
312 &constructed_number) || | 316 &constructed_number) || |
313 !imported_profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number, | 317 !imported_profile->SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), |
| 318 constructed_number, |
314 app_locale_)) { | 319 app_locale_)) { |
315 imported_profile.reset(); | 320 imported_profile.reset(); |
316 } | 321 } |
317 } | 322 } |
318 | 323 |
319 // Reject the profile if minimum address and validation requirements are not | 324 // Reject the profile if minimum address and validation requirements are not |
320 // met. | 325 // met. |
321 if (imported_profile.get() && | 326 if (imported_profile.get() && |
322 !IsValidLearnableProfile(*imported_profile, app_locale_)) | 327 !IsValidLearnableProfile(*imported_profile, app_locale_)) |
323 imported_profile.reset(); | 328 imported_profile.reset(); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 const std::vector<CreditCard*>& credit_cards = GetCreditCards(); | 519 const std::vector<CreditCard*>& credit_cards = GetCreditCards(); |
515 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); | 520 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); |
516 iter != credit_cards.end(); ++iter) { | 521 iter != credit_cards.end(); ++iter) { |
517 if ((*iter)->guid() == guid) | 522 if ((*iter)->guid() == guid) |
518 return *iter; | 523 return *iter; |
519 } | 524 } |
520 return NULL; | 525 return NULL; |
521 } | 526 } |
522 | 527 |
523 void PersonalDataManager::GetNonEmptyTypes( | 528 void PersonalDataManager::GetNonEmptyTypes( |
524 FieldTypeSet* non_empty_types) { | 529 ServerFieldTypeSet* non_empty_types) { |
525 const std::vector<AutofillProfile*>& profiles = GetProfiles(); | 530 const std::vector<AutofillProfile*>& profiles = GetProfiles(); |
526 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); | 531 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); |
527 iter != profiles.end(); ++iter) { | 532 iter != profiles.end(); ++iter) { |
528 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types); | 533 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types); |
529 } | 534 } |
530 | 535 |
531 for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin(); | 536 for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin(); |
532 iter != credit_cards_.end(); ++iter) { | 537 iter != credit_cards_.end(); ++iter) { |
533 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types); | 538 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types); |
534 } | 539 } |
(...skipping 27 matching lines...) Expand all Loading... |
562 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { | 567 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { |
563 return credit_cards_.get(); | 568 return credit_cards_.get(); |
564 } | 569 } |
565 | 570 |
566 void PersonalDataManager::Refresh() { | 571 void PersonalDataManager::Refresh() { |
567 LoadProfiles(); | 572 LoadProfiles(); |
568 LoadCreditCards(); | 573 LoadCreditCards(); |
569 } | 574 } |
570 | 575 |
571 void PersonalDataManager::GetProfileSuggestions( | 576 void PersonalDataManager::GetProfileSuggestions( |
572 AutofillFieldType type, | 577 const AutofillType& type, |
573 const base::string16& field_contents, | 578 const base::string16& field_contents, |
574 bool field_is_autofilled, | 579 bool field_is_autofilled, |
575 std::vector<AutofillFieldType> other_field_types, | 580 std::vector<ServerFieldType> other_field_types, |
576 std::vector<base::string16>* values, | 581 std::vector<base::string16>* values, |
577 std::vector<base::string16>* labels, | 582 std::vector<base::string16>* labels, |
578 std::vector<base::string16>* icons, | 583 std::vector<base::string16>* icons, |
579 std::vector<GUIDPair>* guid_pairs) { | 584 std::vector<GUIDPair>* guid_pairs) { |
580 values->clear(); | 585 values->clear(); |
581 labels->clear(); | 586 labels->clear(); |
582 icons->clear(); | 587 icons->clear(); |
583 guid_pairs->clear(); | 588 guid_pairs->clear(); |
584 | 589 |
585 const std::vector<AutofillProfile*>& profiles = GetProfiles(); | 590 const std::vector<AutofillProfile*>& profiles = GetProfiles(); |
(...skipping 19 matching lines...) Expand all Loading... |
605 if (multi_values[i].empty()) | 610 if (multi_values[i].empty()) |
606 continue; | 611 continue; |
607 | 612 |
608 base::string16 profile_value_lower_case( | 613 base::string16 profile_value_lower_case( |
609 StringToLowerASCII(multi_values[i])); | 614 StringToLowerASCII(multi_values[i])); |
610 base::string16 field_value_lower_case( | 615 base::string16 field_value_lower_case( |
611 StringToLowerASCII(field_contents)); | 616 StringToLowerASCII(field_contents)); |
612 // Phone numbers could be split in US forms, so field value could be | 617 // Phone numbers could be split in US forms, so field value could be |
613 // either prefix or suffix of the phone. | 618 // either prefix or suffix of the phone. |
614 bool matched_phones = false; | 619 bool matched_phones = false; |
615 if (type == PHONE_HOME_NUMBER && !field_value_lower_case.empty() && | 620 if ((type.server_type() == PHONE_HOME_NUMBER || |
616 (profile_value_lower_case.find(field_value_lower_case) != | 621 type.server_type() == PHONE_BILLING_NUMBER) && |
617 base::string16::npos)) { | 622 !field_value_lower_case.empty() && |
| 623 profile_value_lower_case.find(field_value_lower_case) != |
| 624 base::string16::npos) { |
618 matched_phones = true; | 625 matched_phones = true; |
619 } | 626 } |
620 | 627 |
621 // Suggest variants of the profile that's already been filled in. | 628 // Suggest variants of the profile that's already been filled in. |
622 if (matched_phones || | 629 if (matched_phones || |
623 profile_value_lower_case == field_value_lower_case) { | 630 profile_value_lower_case == field_value_lower_case) { |
624 for (size_t j = 0; j < multi_values.size(); ++j) { | 631 for (size_t j = 0; j < multi_values.size(); ++j) { |
625 if (!multi_values[j].empty()) { | 632 if (!multi_values[j].empty()) { |
626 values->push_back(multi_values[j]); | 633 values->push_back(multi_values[j]); |
627 guid_pairs->push_back(GUIDPair(profile->guid(), j)); | 634 guid_pairs->push_back(GUIDPair(profile->guid(), j)); |
628 } | 635 } |
629 } | 636 } |
630 | 637 |
631 // We've added all the values for this profile so move on to the | 638 // We've added all the values for this profile so move on to the |
632 // next. | 639 // next. |
633 break; | 640 break; |
634 } | 641 } |
635 } | 642 } |
636 } | 643 } |
637 } | 644 } |
638 | 645 |
639 if (!field_is_autofilled) { | 646 if (!field_is_autofilled) { |
640 AutofillProfile::CreateInferredLabels( | 647 AutofillProfile::CreateInferredLabels( |
641 &matched_profiles, &other_field_types, | 648 &matched_profiles, &other_field_types, |
642 type, 1, labels); | 649 type.server_type(), 1, labels); |
643 } else { | 650 } else { |
644 // No sub-labels for previously filled fields. | 651 // No sub-labels for previously filled fields. |
645 labels->resize(values->size()); | 652 labels->resize(values->size()); |
646 } | 653 } |
647 | 654 |
648 // No icons for profile suggestions. | 655 // No icons for profile suggestions. |
649 icons->resize(values->size()); | 656 icons->resize(values->size()); |
650 } | 657 } |
651 | 658 |
652 void PersonalDataManager::GetCreditCardSuggestions( | 659 void PersonalDataManager::GetCreditCardSuggestions( |
653 AutofillFieldType type, | 660 const AutofillType& type, |
654 const base::string16& field_contents, | 661 const base::string16& field_contents, |
655 std::vector<base::string16>* values, | 662 std::vector<base::string16>* values, |
656 std::vector<base::string16>* labels, | 663 std::vector<base::string16>* labels, |
657 std::vector<base::string16>* icons, | 664 std::vector<base::string16>* icons, |
658 std::vector<GUIDPair>* guid_pairs) { | 665 std::vector<GUIDPair>* guid_pairs) { |
659 values->clear(); | 666 values->clear(); |
660 labels->clear(); | 667 labels->clear(); |
661 icons->clear(); | 668 icons->clear(); |
662 guid_pairs->clear(); | 669 guid_pairs->clear(); |
663 | 670 |
664 const std::vector<CreditCard*>& credit_cards = GetCreditCards(); | 671 const std::vector<CreditCard*>& credit_cards = GetCreditCards(); |
665 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); | 672 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); |
666 iter != credit_cards.end(); ++iter) { | 673 iter != credit_cards.end(); ++iter) { |
667 CreditCard* credit_card = *iter; | 674 CreditCard* credit_card = *iter; |
668 | 675 |
669 // The value of the stored data for this field type in the |credit_card|. | 676 // The value of the stored data for this field type in the |credit_card|. |
670 base::string16 creditcard_field_value = | 677 base::string16 creditcard_field_value = |
671 credit_card->GetInfo(type, app_locale_); | 678 credit_card->GetInfo(type, app_locale_); |
672 if (!creditcard_field_value.empty() && | 679 if (!creditcard_field_value.empty() && |
673 StartsWith(creditcard_field_value, field_contents, false)) { | 680 StartsWith(creditcard_field_value, field_contents, false)) { |
674 if (type == CREDIT_CARD_NUMBER) | 681 if (type.server_type() == CREDIT_CARD_NUMBER) |
675 creditcard_field_value = credit_card->ObfuscatedNumber(); | 682 creditcard_field_value = credit_card->ObfuscatedNumber(); |
676 | 683 |
677 base::string16 label; | 684 base::string16 label; |
678 if (credit_card->number().empty()) { | 685 if (credit_card->number().empty()) { |
679 // If there is no CC number, return name to show something. | 686 // If there is no CC number, return name to show something. |
680 label = credit_card->GetInfo(CREDIT_CARD_NAME, app_locale_); | 687 label = |
| 688 credit_card->GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_); |
681 } else { | 689 } else { |
682 label = kCreditCardPrefix; | 690 label = kCreditCardPrefix; |
683 label.append(credit_card->LastFourDigits()); | 691 label.append(credit_card->LastFourDigits()); |
684 } | 692 } |
685 | 693 |
686 values->push_back(creditcard_field_value); | 694 values->push_back(creditcard_field_value); |
687 labels->push_back(label); | 695 labels->push_back(label); |
688 icons->push_back(UTF8ToUTF16(credit_card->type())); | 696 icons->push_back(UTF8ToUTF16(credit_card->type())); |
689 guid_pairs->push_back(GUIDPair(credit_card->guid(), 0)); | 697 guid_pairs->push_back(GUIDPair(credit_card->guid(), 0)); |
690 } | 698 } |
691 } | 699 } |
692 } | 700 } |
693 | 701 |
694 bool PersonalDataManager::IsAutofillEnabled() const { | 702 bool PersonalDataManager::IsAutofillEnabled() const { |
695 return user_prefs::UserPrefs::Get(browser_context_)->GetBoolean( | 703 return user_prefs::UserPrefs::Get(browser_context_)->GetBoolean( |
696 prefs::kAutofillEnabled); | 704 prefs::kAutofillEnabled); |
697 } | 705 } |
698 | 706 |
699 // static | 707 // static |
700 bool PersonalDataManager::IsValidLearnableProfile( | 708 bool PersonalDataManager::IsValidLearnableProfile( |
701 const AutofillProfile& profile, | 709 const AutofillProfile& profile, |
702 const std::string& app_locale) { | 710 const std::string& app_locale) { |
703 if (!IsMinimumAddress(profile, app_locale)) | 711 if (!IsMinimumAddress(profile, app_locale)) |
704 return false; | 712 return false; |
705 | 713 |
706 base::string16 email = profile.GetRawInfo(EMAIL_ADDRESS); | 714 base::string16 email = profile.GetRawInfo(EMAIL_ADDRESS); |
707 if (!email.empty() && !autofill::IsValidEmailAddress(email)) | 715 if (!email.empty() && !IsValidEmailAddress(email)) |
708 return false; | 716 return false; |
709 | 717 |
710 // Reject profiles with invalid US state information. | 718 // Reject profiles with invalid US state information. |
711 if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE)) | 719 if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE)) |
712 return false; | 720 return false; |
713 | 721 |
714 // Reject profiles with invalid US zip information. | 722 // Reject profiles with invalid US zip information. |
715 if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP)) | 723 if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP)) |
716 return false; | 724 return false; |
717 | 725 |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 const AutofillMetrics* metric_logger) { | 1025 const AutofillMetrics* metric_logger) { |
1018 metric_logger_.reset(metric_logger); | 1026 metric_logger_.reset(metric_logger); |
1019 } | 1027 } |
1020 | 1028 |
1021 void PersonalDataManager::set_browser_context( | 1029 void PersonalDataManager::set_browser_context( |
1022 content::BrowserContext* context) { | 1030 content::BrowserContext* context) { |
1023 browser_context_ = context; | 1031 browser_context_ = context; |
1024 } | 1032 } |
1025 | 1033 |
1026 } // namespace autofill | 1034 } // namespace autofill |
OLD | NEW |