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 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 LoadProfiles(); | 553 LoadProfiles(); |
554 LoadCreditCards(); | 554 LoadCreditCards(); |
555 } | 555 } |
556 | 556 |
557 void PersonalDataManager::GetProfileSuggestions( | 557 void PersonalDataManager::GetProfileSuggestions( |
558 const AutofillType& type, | 558 const AutofillType& type, |
559 const base::string16& field_contents, | 559 const base::string16& field_contents, |
560 bool field_is_autofilled, | 560 bool field_is_autofilled, |
561 const std::vector<ServerFieldType>& other_field_types, | 561 const std::vector<ServerFieldType>& other_field_types, |
562 const base::Callback<bool(const AutofillProfile&)>& filter, | 562 const base::Callback<bool(const AutofillProfile&)>& filter, |
563 std::vector<base::string16>* values, | 563 std::vector<Suggestion>* suggestions) { |
564 std::vector<base::string16>* labels, | 564 suggestions->clear(); |
565 std::vector<base::string16>* icons, | |
566 std::vector<GUIDPair>* guid_pairs) { | |
567 values->clear(); | |
568 labels->clear(); | |
569 icons->clear(); | |
570 guid_pairs->clear(); | |
571 | 565 |
572 const std::vector<AutofillProfile*>& profiles = GetProfiles(true); | |
573 std::vector<AutofillProfile*> matched_profiles; | 566 std::vector<AutofillProfile*> matched_profiles; |
574 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); | 567 for (AutofillProfile* profile : GetProfiles(true)) { |
575 iter != profiles.end(); ++iter) { | |
576 AutofillProfile* profile = *iter; | |
577 | |
578 // The value of the stored data for this field type in the |profile|. | 568 // The value of the stored data for this field type in the |profile|. |
579 std::vector<base::string16> multi_values; | 569 std::vector<base::string16> multi_values; |
580 AddressField address_field; | 570 AddressField address_field; |
581 if (i18n::FieldForType(type.GetStorableType(), &address_field) && | 571 if (i18n::FieldForType(type.GetStorableType(), &address_field) && |
582 address_field == STREET_ADDRESS) { | 572 address_field == STREET_ADDRESS) { |
583 std::string street_address_line; | 573 std::string street_address_line; |
584 GetStreetAddressLinesAsSingleLine( | 574 GetStreetAddressLinesAsSingleLine( |
585 *i18n::CreateAddressDataFromAutofillProfile(*profile, app_locale_), | 575 *i18n::CreateAddressDataFromAutofillProfile(*profile, app_locale_), |
586 &street_address_line); | 576 &street_address_line); |
587 multi_values.push_back(base::UTF8ToUTF16(street_address_line)); | 577 multi_values.push_back(base::UTF8ToUTF16(street_address_line)); |
588 } else { | 578 } else { |
589 profile->GetMultiInfo(type, app_locale_, &multi_values); | 579 profile->GetMultiInfo(type, app_locale_, &multi_values); |
590 } | 580 } |
591 | 581 |
592 for (size_t i = 0; i < multi_values.size(); ++i) { | 582 for (size_t i = 0; i < multi_values.size(); ++i) { |
593 // Newlines can be found only in a street address, which was collapsed | 583 // Newlines can be found only in a street address, which was collapsed |
594 // into a single line above. | 584 // into a single line above. |
595 DCHECK(multi_values[i].find('\n') == std::string::npos); | 585 DCHECK(multi_values[i].find('\n') == std::string::npos); |
596 | 586 |
597 if (!field_is_autofilled) { | 587 if (!field_is_autofilled) { |
598 // Suggest data that starts with what the user has typed. | 588 // Suggest data that starts with what the user has typed. |
599 if (!multi_values[i].empty() && | 589 if (!multi_values[i].empty() && |
600 StartsWith(multi_values[i], field_contents, false) && | 590 StartsWith(multi_values[i], field_contents, false) && |
601 (filter.is_null() || filter.Run(*profile))) { | 591 (filter.is_null() || filter.Run(*profile))) { |
602 matched_profiles.push_back(profile); | 592 matched_profiles.push_back(profile); |
603 values->push_back(multi_values[i]); | 593 suggestions->push_back(Suggestion(multi_values[i])); |
604 guid_pairs->push_back(GUIDPair(profile->guid(), i)); | 594 suggestions->back().backend_id.guid = profile->guid(); |
| 595 suggestions->back().backend_id.variant = i; |
605 } | 596 } |
606 } else { | 597 } else { |
607 if (multi_values[i].empty()) | 598 if (multi_values[i].empty()) |
608 continue; | 599 continue; |
609 | 600 |
610 base::string16 profile_value_lower_case( | 601 base::string16 profile_value_lower_case( |
611 base::StringToLowerASCII(multi_values[i])); | 602 base::StringToLowerASCII(multi_values[i])); |
612 base::string16 field_value_lower_case( | 603 base::string16 field_value_lower_case( |
613 base::StringToLowerASCII(field_contents)); | 604 base::StringToLowerASCII(field_contents)); |
614 // Phone numbers could be split in US forms, so field value could be | 605 // Phone numbers could be split in US forms, so field value could be |
615 // either prefix or suffix of the phone. | 606 // either prefix or suffix of the phone. |
616 bool matched_phones = false; | 607 bool matched_phones = false; |
617 if (type.GetStorableType() == PHONE_HOME_NUMBER && | 608 if (type.GetStorableType() == PHONE_HOME_NUMBER && |
618 !field_value_lower_case.empty() && | 609 !field_value_lower_case.empty() && |
619 profile_value_lower_case.find(field_value_lower_case) != | 610 profile_value_lower_case.find(field_value_lower_case) != |
620 base::string16::npos) { | 611 base::string16::npos) { |
621 matched_phones = true; | 612 matched_phones = true; |
622 } | 613 } |
623 | 614 |
624 // Suggest variants of the profile that's already been filled in. | 615 // Suggest variants of the profile that's already been filled in. |
625 if (matched_phones || | 616 if (matched_phones || |
626 profile_value_lower_case == field_value_lower_case) { | 617 profile_value_lower_case == field_value_lower_case) { |
627 for (size_t j = 0; j < multi_values.size(); ++j) { | 618 for (size_t j = 0; j < multi_values.size(); ++j) { |
628 if (!multi_values[j].empty()) { | 619 if (!multi_values[j].empty()) { |
629 values->push_back(multi_values[j]); | 620 suggestions->push_back(Suggestion(multi_values[j])); |
630 guid_pairs->push_back(GUIDPair(profile->guid(), j)); | 621 suggestions->back().backend_id.guid = profile->guid(); |
| 622 suggestions->back().backend_id.variant = j; |
631 } | 623 } |
632 } | 624 } |
633 | 625 |
634 // We've added all the values for this profile so move on to the | 626 // We've added all the values for this profile so move on to the |
635 // next. | 627 // next. |
636 break; | 628 break; |
637 } | 629 } |
638 } | 630 } |
639 } | 631 } |
640 } | 632 } |
641 | 633 |
642 if (!field_is_autofilled) { | 634 if (!field_is_autofilled) { |
| 635 // Generate labels for the profiles we discovered above. |
| 636 std::vector<base::string16> labels; |
643 AutofillProfile::CreateInferredLabels( | 637 AutofillProfile::CreateInferredLabels( |
644 matched_profiles, &other_field_types, | 638 matched_profiles, &other_field_types, |
645 type.GetStorableType(), 1, app_locale_, labels); | 639 type.GetStorableType(), 1, app_locale_, &labels); |
646 } else { | 640 DCHECK_EQ(suggestions->size(), labels.size()); |
647 // No sub-labels for previously filled fields. | 641 for (size_t i = 0; i < labels.size(); i++) |
648 labels->resize(values->size()); | 642 (*suggestions)[i].label = labels[i]; |
649 } | 643 } |
650 | |
651 // No icons for profile suggestions. | |
652 icons->resize(values->size()); | |
653 } | 644 } |
654 | 645 |
655 void PersonalDataManager::GetCreditCardSuggestions( | 646 void PersonalDataManager::GetCreditCardSuggestions( |
656 const AutofillType& type, | 647 const AutofillType& type, |
657 const base::string16& field_contents, | 648 const base::string16& field_contents, |
658 std::vector<base::string16>* values, | 649 std::vector<Suggestion>* suggestions) { |
659 std::vector<base::string16>* labels, | 650 suggestions->clear(); |
660 std::vector<base::string16>* icons, | 651 for (const CreditCard* credit_card : GetCreditCards()) { |
661 std::vector<GUIDPair>* guid_pairs) { | |
662 values->clear(); | |
663 labels->clear(); | |
664 icons->clear(); | |
665 guid_pairs->clear(); | |
666 | |
667 const std::vector<CreditCard*>& credit_cards = GetCreditCards(); | |
668 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); | |
669 iter != credit_cards.end(); ++iter) { | |
670 CreditCard* credit_card = *iter; | |
671 | |
672 // The value of the stored data for this field type in the |credit_card|. | 652 // The value of the stored data for this field type in the |credit_card|. |
673 base::string16 creditcard_field_value = | 653 base::string16 creditcard_field_value = |
674 credit_card->GetInfo(type, app_locale_); | 654 credit_card->GetInfo(type, app_locale_); |
675 if (!creditcard_field_value.empty() && | 655 if (!creditcard_field_value.empty() && |
676 (StartsWith(creditcard_field_value, field_contents, false) || | 656 (StartsWith(creditcard_field_value, field_contents, false) || |
677 (type.GetStorableType() == CREDIT_CARD_NUMBER && | 657 (type.GetStorableType() == CREDIT_CARD_NUMBER && |
678 base::string16::npos != | 658 base::string16::npos != |
679 creditcard_field_value.find(field_contents)))) { | 659 creditcard_field_value.find(field_contents)))) { |
| 660 // Make a new suggestion. |
| 661 suggestions->push_back(Suggestion()); |
| 662 Suggestion* suggestion = &suggestions->back(); |
| 663 |
680 // If the value is the card number, the label is the expiration date. | 664 // If the value is the card number, the label is the expiration date. |
681 // Otherwise the label is the card number, or if that is empty the | 665 // Otherwise the label is the card number, or if that is empty the |
682 // cardholder name. The label should never repeat the value. | 666 // cardholder name. The label should never repeat the value. |
683 base::string16 label; | |
684 if (type.GetStorableType() == CREDIT_CARD_NUMBER) { | 667 if (type.GetStorableType() == CREDIT_CARD_NUMBER) { |
685 creditcard_field_value = credit_card->ObfuscatedNumber(); | 668 creditcard_field_value = credit_card->ObfuscatedNumber(); |
686 label = credit_card->GetInfo( | 669 suggestion->label = credit_card->GetInfo( |
687 AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale_); | 670 AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale_); |
688 } else if (credit_card->number().empty()) { | 671 } else if (credit_card->number().empty()) { |
689 if (type.GetStorableType() != CREDIT_CARD_NAME) { | 672 if (type.GetStorableType() != CREDIT_CARD_NAME) { |
690 label = | 673 suggestion->label = |
691 credit_card->GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_); | 674 credit_card->GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_); |
692 } | 675 } |
693 } else { | 676 } else { |
694 label = kCreditCardPrefix; | 677 suggestion->label = kCreditCardPrefix; |
695 label.append(credit_card->LastFourDigits()); | 678 suggestion->label.append(credit_card->LastFourDigits()); |
696 } | 679 } |
697 | 680 |
698 values->push_back(creditcard_field_value); | 681 suggestion->value = creditcard_field_value; |
699 labels->push_back(label); | 682 suggestion->icon = base::UTF8ToUTF16(credit_card->type()); |
700 icons->push_back(base::UTF8ToUTF16(credit_card->type())); | 683 suggestion->backend_id.guid = credit_card->guid(); |
701 guid_pairs->push_back(GUIDPair(credit_card->guid(), 0)); | |
702 } | 684 } |
703 } | 685 } |
704 } | 686 } |
705 | 687 |
706 bool PersonalDataManager::IsAutofillEnabled() const { | 688 bool PersonalDataManager::IsAutofillEnabled() const { |
707 DCHECK(pref_service_); | 689 DCHECK(pref_service_); |
708 return pref_service_->GetBoolean(prefs::kAutofillEnabled); | 690 return pref_service_->GetBoolean(prefs::kAutofillEnabled); |
709 } | 691 } |
710 | 692 |
711 std::string PersonalDataManager::CountryCodeForCurrentTimezone() const { | 693 std::string PersonalDataManager::CountryCodeForCurrentTimezone() const { |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 // Populates |auxiliary_profiles_|. | 1099 // Populates |auxiliary_profiles_|. |
1118 LoadAuxiliaryProfiles(record_metrics); | 1100 LoadAuxiliaryProfiles(record_metrics); |
1119 | 1101 |
1120 profiles_.insert(profiles_.end(), web_profiles_.begin(), web_profiles_.end()); | 1102 profiles_.insert(profiles_.end(), web_profiles_.begin(), web_profiles_.end()); |
1121 profiles_.insert( | 1103 profiles_.insert( |
1122 profiles_.end(), auxiliary_profiles_.begin(), auxiliary_profiles_.end()); | 1104 profiles_.end(), auxiliary_profiles_.begin(), auxiliary_profiles_.end()); |
1123 return profiles_; | 1105 return profiles_; |
1124 } | 1106 } |
1125 | 1107 |
1126 } // namespace autofill | 1108 } // namespace autofill |
OLD | NEW |