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