| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <list> | 9 #include <list> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 | 789 |
| 790 return unique_suggestions; | 790 return unique_suggestions; |
| 791 } | 791 } |
| 792 | 792 |
| 793 std::vector<Suggestion> PersonalDataManager::GetCreditCardSuggestions( | 793 std::vector<Suggestion> PersonalDataManager::GetCreditCardSuggestions( |
| 794 const AutofillType& type, | 794 const AutofillType& type, |
| 795 const base::string16& field_contents) { | 795 const base::string16& field_contents) { |
| 796 if (IsInAutofillSuggestionsDisabledExperiment()) | 796 if (IsInAutofillSuggestionsDisabledExperiment()) |
| 797 return std::vector<Suggestion>(); | 797 return std::vector<Suggestion>(); |
| 798 | 798 |
| 799 std::list<const CreditCard*> cards_to_suggest; | 799 const std::vector<CreditCard*> credit_cards = GetCreditCards(); |
| 800 | 800 std::list<const CreditCard*> cards_to_suggest(credit_cards.begin(), |
| 801 GetOrderedCardsToSuggest(type, field_contents, &cards_to_suggest); | 801 credit_cards.end()); |
| 802 | 802 |
| 803 DedupeCreditCardToSuggest(&cards_to_suggest); | 803 DedupeCreditCardToSuggest(&cards_to_suggest); |
| 804 | 804 |
| 805 return GetSuggestionsForCards(cards_to_suggest, type); | 805 // Rank the cards by frecency (see AutofillDataModel for details). All expired |
| 806 // cards should be suggested last, also by frecency. |
| 807 base::Time comparison_time = base::Time::Now(); |
| 808 cards_to_suggest.sort( |
| 809 [comparison_time](const CreditCard* a, const CreditCard* b) { |
| 810 bool a_has_valid_expiration = IsValidCreditCardExpirationDate( |
| 811 a->expiration_year(), a->expiration_month(), comparison_time); |
| 812 if (a_has_valid_expiration != |
| 813 IsValidCreditCardExpirationDate( |
| 814 b->expiration_year(), b->expiration_month(), comparison_time)) |
| 815 return a_has_valid_expiration; |
| 816 |
| 817 return a->CompareFrecency(b, comparison_time); |
| 818 }); |
| 819 |
| 820 return GetSuggestionsForCards(type, field_contents, cards_to_suggest); |
| 806 } | 821 } |
| 807 | 822 |
| 808 bool PersonalDataManager::IsAutofillEnabled() const { | 823 bool PersonalDataManager::IsAutofillEnabled() const { |
| 809 return ::autofill::IsAutofillEnabled(pref_service_); | 824 return ::autofill::IsAutofillEnabled(pref_service_); |
| 810 } | 825 } |
| 811 | 826 |
| 812 std::string PersonalDataManager::CountryCodeForCurrentTimezone() const { | 827 std::string PersonalDataManager::CountryCodeForCurrentTimezone() const { |
| 813 return base::CountryCodeForCurrentTimezone(); | 828 return base::CountryCodeForCurrentTimezone(); |
| 814 } | 829 } |
| 815 | 830 |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1417 profiles_.clear(); | 1432 profiles_.clear(); |
| 1418 profiles_.insert(profiles_.end(), web_profiles().begin(), | 1433 profiles_.insert(profiles_.end(), web_profiles().begin(), |
| 1419 web_profiles().end()); | 1434 web_profiles().end()); |
| 1420 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { | 1435 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { |
| 1421 profiles_.insert( | 1436 profiles_.insert( |
| 1422 profiles_.end(), server_profiles_.begin(), server_profiles_.end()); | 1437 profiles_.end(), server_profiles_.begin(), server_profiles_.end()); |
| 1423 } | 1438 } |
| 1424 return profiles_; | 1439 return profiles_; |
| 1425 } | 1440 } |
| 1426 | 1441 |
| 1427 void PersonalDataManager::GetOrderedCardsToSuggest( | 1442 std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards( |
| 1428 const AutofillType& type, | 1443 const AutofillType& type, |
| 1429 const base::string16& field_contents, | 1444 const base::string16& field_contents, |
| 1430 std::list<const CreditCard*>* cards_to_suggest) const { | 1445 const std::list<const CreditCard*>& cards_to_suggest) const { |
| 1446 std::vector<Suggestion> suggestions; |
| 1431 std::list<const CreditCard*> substring_matched_cards; | 1447 std::list<const CreditCard*> substring_matched_cards; |
| 1432 base::string16 field_contents_lower = base::i18n::ToLower(field_contents); | 1448 base::string16 field_contents_lower = base::i18n::ToLower(field_contents); |
| 1433 for (const CreditCard* credit_card : GetCreditCards()) { | 1449 for (const CreditCard* credit_card : cards_to_suggest) { |
| 1434 // The value of the stored data for this field type in the |credit_card|. | 1450 // The value of the stored data for this field type in the |credit_card|. |
| 1435 base::string16 creditcard_field_value = | 1451 base::string16 creditcard_field_value = |
| 1436 credit_card->GetInfo(type, app_locale_); | 1452 credit_card->GetInfo(type, app_locale_); |
| 1437 if (creditcard_field_value.empty()) | 1453 if (creditcard_field_value.empty()) |
| 1438 continue; | 1454 continue; |
| 1439 base::string16 creditcard_field_lower = | 1455 base::string16 creditcard_field_lower = |
| 1440 base::i18n::ToLower(creditcard_field_value); | 1456 base::i18n::ToLower(creditcard_field_value); |
| 1441 | 1457 |
| 1442 bool prefix_matched_suggestion; | 1458 bool prefix_matched_suggestion; |
| 1443 if (IsValidSuggestionForFieldContents( | 1459 if (IsValidSuggestionForFieldContents( |
| 1444 creditcard_field_lower, field_contents_lower, type, | 1460 creditcard_field_lower, field_contents_lower, type, |
| 1445 credit_card->record_type() == CreditCard::MASKED_SERVER_CARD, | 1461 credit_card->record_type() == CreditCard::MASKED_SERVER_CARD, |
| 1446 &prefix_matched_suggestion)) { | 1462 &prefix_matched_suggestion)) { |
| 1447 if (prefix_matched_suggestion) { | 1463 // Make a new suggestion. |
| 1448 cards_to_suggest->push_back(credit_card); | 1464 suggestions.push_back(Suggestion()); |
| 1465 Suggestion* suggestion = &suggestions.back(); |
| 1466 |
| 1467 suggestion->value = credit_card->GetInfo(type, app_locale_); |
| 1468 suggestion->icon = base::UTF8ToUTF16(credit_card->type()); |
| 1469 suggestion->backend_id = credit_card->guid(); |
| 1470 suggestion->match = prefix_matched_suggestion |
| 1471 ? Suggestion::PREFIX_MATCH |
| 1472 : Suggestion::SUBSTRING_MATCH; |
| 1473 |
| 1474 // If the value is the card number, the label is the expiration date. |
| 1475 // Otherwise the label is the card number, or if that is empty the |
| 1476 // cardholder name. The label should never repeat the value. |
| 1477 if (type.GetStorableType() == CREDIT_CARD_NUMBER) { |
| 1478 suggestion->value = credit_card->TypeAndLastFourDigits(); |
| 1479 suggestion->label = credit_card->GetInfo( |
| 1480 AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale_); |
| 1481 } else if (credit_card->number().empty()) { |
| 1482 if (type.GetStorableType() != CREDIT_CARD_NAME_FULL) { |
| 1483 suggestion->label = credit_card->GetInfo( |
| 1484 AutofillType(CREDIT_CARD_NAME_FULL), app_locale_); |
| 1485 } |
| 1449 } else { | 1486 } else { |
| 1450 substring_matched_cards.push_back(credit_card); | 1487 #if defined(OS_ANDROID) |
| 1488 // Since Android places the label on its own row, there's more |
| 1489 // horizontal |
| 1490 // space to work with. Show "Amex - 1234" rather than desktop's "*1234". |
| 1491 suggestion->label = credit_card->TypeAndLastFourDigits(); |
| 1492 #else |
| 1493 suggestion->label = base::ASCIIToUTF16("*"); |
| 1494 suggestion->label.append(credit_card->LastFourDigits()); |
| 1495 #endif |
| 1451 } | 1496 } |
| 1452 } | 1497 } |
| 1453 } | 1498 } |
| 1454 | 1499 |
| 1455 // Rank the cards by frecency (see AutofillDataModel for details). | |
| 1456 base::Time comparison_time = base::Time::Now(); | |
| 1457 cards_to_suggest->sort([comparison_time](const AutofillDataModel* a, | |
| 1458 const AutofillDataModel* b) { | |
| 1459 return a->CompareFrecency(b, comparison_time); | |
| 1460 }); | |
| 1461 | |
| 1462 // Prefix matches should precede other token matches. | 1500 // Prefix matches should precede other token matches. |
| 1463 if (IsFeatureSubstringMatchEnabled()) { | 1501 if (IsFeatureSubstringMatchEnabled()) { |
| 1464 substring_matched_cards.sort([comparison_time](const AutofillDataModel* a, | 1502 std::stable_sort(suggestions.begin(), suggestions.end(), |
| 1465 const AutofillDataModel* b) { | 1503 [](const Suggestion& a, const Suggestion& b) { |
| 1466 return a->CompareFrecency(b, comparison_time); | 1504 return a.match < b.match; |
| 1467 }); | 1505 }); |
| 1468 cards_to_suggest->insert(cards_to_suggest->end(), | |
| 1469 substring_matched_cards.begin(), | |
| 1470 substring_matched_cards.end()); | |
| 1471 } | 1506 } |
| 1472 } | |
| 1473 | 1507 |
| 1474 std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards( | |
| 1475 const std::list<const CreditCard*>& cards_to_suggest, | |
| 1476 const AutofillType& type) const { | |
| 1477 std::vector<Suggestion> suggestions; | |
| 1478 for (const CreditCard* credit_card : cards_to_suggest) { | |
| 1479 // Make a new suggestion. | |
| 1480 suggestions.push_back(Suggestion()); | |
| 1481 Suggestion* suggestion = &suggestions.back(); | |
| 1482 | |
| 1483 suggestion->value = credit_card->GetInfo(type, app_locale_); | |
| 1484 suggestion->icon = base::UTF8ToUTF16(credit_card->type()); | |
| 1485 suggestion->backend_id = credit_card->guid(); | |
| 1486 | |
| 1487 // If the value is the card number, the label is the expiration date. | |
| 1488 // Otherwise the label is the card number, or if that is empty the | |
| 1489 // cardholder name. The label should never repeat the value. | |
| 1490 if (type.GetStorableType() == CREDIT_CARD_NUMBER) { | |
| 1491 suggestion->value = credit_card->TypeAndLastFourDigits(); | |
| 1492 suggestion->label = credit_card->GetInfo( | |
| 1493 AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale_); | |
| 1494 } else if (credit_card->number().empty()) { | |
| 1495 if (type.GetStorableType() != CREDIT_CARD_NAME_FULL) { | |
| 1496 suggestion->label = credit_card->GetInfo( | |
| 1497 AutofillType(CREDIT_CARD_NAME_FULL), app_locale_); | |
| 1498 } | |
| 1499 } else { | |
| 1500 #if defined(OS_ANDROID) | |
| 1501 // Since Android places the label on its own row, there's more horizontal | |
| 1502 // space to work with. Show "Amex - 1234" rather than desktop's "*1234". | |
| 1503 suggestion->label = credit_card->TypeAndLastFourDigits(); | |
| 1504 #else | |
| 1505 suggestion->label = base::ASCIIToUTF16("*"); | |
| 1506 suggestion->label.append(credit_card->LastFourDigits()); | |
| 1507 #endif | |
| 1508 } | |
| 1509 } | |
| 1510 return suggestions; | 1508 return suggestions; |
| 1511 } | 1509 } |
| 1512 | 1510 |
| 1513 } // namespace autofill | 1511 } // namespace autofill |
| OLD | NEW |