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