| 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 |