Chromium Code Reviews| 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 12 matching lines...) Expand all Loading... | |
| 23 #include "components/autofill/core/browser/autofill_experiments.h" | 23 #include "components/autofill/core/browser/autofill_experiments.h" |
| 24 #include "components/autofill/core/browser/autofill_field.h" | 24 #include "components/autofill/core/browser/autofill_field.h" |
| 25 #include "components/autofill/core/browser/autofill_metrics.h" | 25 #include "components/autofill/core/browser/autofill_metrics.h" |
| 26 #include "components/autofill/core/browser/form_structure.h" | 26 #include "components/autofill/core/browser/form_structure.h" |
| 27 #include "components/autofill/core/browser/personal_data_manager_observer.h" | 27 #include "components/autofill/core/browser/personal_data_manager_observer.h" |
| 28 #include "components/autofill/core/browser/phone_number.h" | 28 #include "components/autofill/core/browser/phone_number.h" |
| 29 #include "components/autofill/core/browser/phone_number_i18n.h" | 29 #include "components/autofill/core/browser/phone_number_i18n.h" |
| 30 #include "components/autofill/core/browser/validation.h" | 30 #include "components/autofill/core/browser/validation.h" |
| 31 #include "components/autofill/core/common/autofill_pref_names.h" | 31 #include "components/autofill/core/common/autofill_pref_names.h" |
| 32 #include "components/autofill/core/common/autofill_switches.h" | 32 #include "components/autofill/core/common/autofill_switches.h" |
| 33 #include "components/autofill/core/common/autofill_util.h" | |
| 33 #include "components/signin/core/browser/account_tracker_service.h" | 34 #include "components/signin/core/browser/account_tracker_service.h" |
| 34 #include "components/signin/core/common/signin_pref_names.h" | 35 #include "components/signin/core/common/signin_pref_names.h" |
| 35 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_da ta.h" | 36 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_da ta.h" |
| 36 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_fo rmatter.h" | 37 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_fo rmatter.h" |
| 37 | 38 |
| 38 namespace autofill { | 39 namespace autofill { |
| 39 namespace { | 40 namespace { |
| 40 | 41 |
| 41 using ::i18n::addressinput::AddressField; | 42 using ::i18n::addressinput::AddressField; |
| 42 using ::i18n::addressinput::GetStreetAddressLinesAsSingleLine; | 43 using ::i18n::addressinput::GetStreetAddressLinesAsSingleLine; |
| (...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 788 | 789 |
| 789 std::vector<Suggestion> suggestions; | 790 std::vector<Suggestion> suggestions; |
| 790 // Match based on a prefix search. | 791 // Match based on a prefix search. |
| 791 std::vector<AutofillProfile*> matched_profiles; | 792 std::vector<AutofillProfile*> matched_profiles; |
| 792 for (AutofillProfile* profile : profiles) { | 793 for (AutofillProfile* profile : profiles) { |
| 793 base::string16 value = GetInfoInOneLine(profile, type, app_locale_); | 794 base::string16 value = GetInfoInOneLine(profile, type, app_locale_); |
| 794 if (value.empty()) | 795 if (value.empty()) |
| 795 continue; | 796 continue; |
| 796 base::string16 value_canon = | 797 base::string16 value_canon = |
| 797 AutofillProfile::CanonicalizeProfileString(value); | 798 AutofillProfile::CanonicalizeProfileString(value); |
| 798 if (base::StartsWith(value_canon, field_contents_canon, true)) { | 799 // CanonicalizeProfileString() returns lower-case string with separators; |
| 799 // Prefix match, add suggestion. | 800 // includes space, line and paragraph along with punctuations like dash, |
| 801 // start, end and others {U_DASH_PUNCTUATION, U_START_PUNCTUATION, | |
| 802 // U_END_PUNCTUATION, U_CONNECTOR_PUNCTUATION, U_OTHER_PUNCTUATION, | |
| 803 // U_SPACE_SEPARATOR, U_LINE_SEPARATOR, U_PARAGRAPH_SEPARATOR}; substituted | |
| 804 // by whitespaces and trims off trailing whitespace if any. Passing | |
| 805 // |value_canon| and |field_contents_canon| to ContainsTokenThatStartsWith() | |
| 806 // may lead to unexpected result, hence preferred passing |value| and | |
| 807 // |field_contents| instead. | |
|
please use gerrit instead
2015/06/30 19:06:23
I would prefer removing this comment entirely, to
Pritam Nikam
2015/07/01 17:26:00
Done.
| |
| 808 bool prefix_matched_suggestion = | |
| 809 base::StartsWith(value_canon, field_contents_canon, true); | |
| 810 if (prefix_matched_suggestion || | |
| 811 ContainsTokenThatStartsWith(value, field_contents, false)) { | |
| 800 matched_profiles.push_back(profile); | 812 matched_profiles.push_back(profile); |
| 801 suggestions.push_back(Suggestion(value)); | 813 suggestions.push_back(Suggestion(value)); |
| 802 suggestions.back().backend_id = profile->guid(); | 814 suggestions.back().backend_id = profile->guid(); |
| 815 suggestions.back().match = prefix_matched_suggestion | |
| 816 ? Suggestion::PREFIX_MATCH | |
| 817 : Suggestion::SUBSTRING_MATCH; | |
| 803 } | 818 } |
| 804 } | 819 } |
| 805 | 820 |
| 821 // Prefix matches should precede other token matches. | |
| 822 if (IsFeatureSubstringMatchEnabled()) { | |
| 823 std::stable_sort(suggestions.begin(), suggestions.end(), | |
| 824 [](const Suggestion& a, const Suggestion& b) { | |
| 825 return a.match < b.match; | |
| 826 }); | |
| 827 } | |
| 828 | |
| 806 // Don't show two suggestions if one is a subset of the other. | 829 // Don't show two suggestions if one is a subset of the other. |
| 807 std::vector<AutofillProfile*> unique_matched_profiles; | 830 std::vector<AutofillProfile*> unique_matched_profiles; |
| 808 std::vector<Suggestion> unique_suggestions; | 831 std::vector<Suggestion> unique_suggestions; |
| 809 ServerFieldTypeSet types(other_field_types.begin(), other_field_types.end()); | 832 ServerFieldTypeSet types(other_field_types.begin(), other_field_types.end()); |
| 810 for (size_t i = 0; i < matched_profiles.size(); ++i) { | 833 for (size_t i = 0; i < matched_profiles.size(); ++i) { |
| 811 bool include = true; | 834 bool include = true; |
| 812 AutofillProfile* profile_a = matched_profiles[i]; | 835 AutofillProfile* profile_a = matched_profiles[i]; |
| 813 for (size_t j = 0; j < matched_profiles.size(); ++j) { | 836 for (size_t j = 0; j < matched_profiles.size(); ++j) { |
| 814 AutofillProfile* profile_b = matched_profiles[j]; | 837 AutofillProfile* profile_b = matched_profiles[j]; |
| 815 // Check if profile A is a subset of profile B. If not, continue. | 838 // Check if profile A is a subset of profile B. If not, continue. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 847 return unique_suggestions; | 870 return unique_suggestions; |
| 848 } | 871 } |
| 849 | 872 |
| 850 std::vector<Suggestion> PersonalDataManager::GetCreditCardSuggestions( | 873 std::vector<Suggestion> PersonalDataManager::GetCreditCardSuggestions( |
| 851 const AutofillType& type, | 874 const AutofillType& type, |
| 852 const base::string16& field_contents) { | 875 const base::string16& field_contents) { |
| 853 if (IsInAutofillSuggestionsDisabledExperiment()) | 876 if (IsInAutofillSuggestionsDisabledExperiment()) |
| 854 return std::vector<Suggestion>(); | 877 return std::vector<Suggestion>(); |
| 855 | 878 |
| 856 std::list<const CreditCard*> cards_to_suggest; | 879 std::list<const CreditCard*> cards_to_suggest; |
| 880 std::list<const CreditCard*> substring_matched_cards; | |
| 857 for (const CreditCard* credit_card : GetCreditCards()) { | 881 for (const CreditCard* credit_card : GetCreditCards()) { |
| 858 // The value of the stored data for this field type in the |credit_card|. | 882 // The value of the stored data for this field type in the |credit_card|. |
| 859 base::string16 creditcard_field_value = | 883 base::string16 creditcard_field_value = |
| 860 credit_card->GetInfo(type, app_locale_); | 884 credit_card->GetInfo(type, app_locale_); |
| 861 if (creditcard_field_value.empty()) | 885 if (creditcard_field_value.empty()) |
| 862 continue; | 886 continue; |
| 863 | 887 |
| 864 // For card number fields, suggest the card if: | 888 // For card number fields, suggest the card if: |
| 865 // - the number matches any part of the card, or | 889 // - the number matches any part of the card, or |
| 866 // - it's a masked card and there are 6 or fewers typed so far. | 890 // - it's a masked card and there are 6 or fewers typed so far. |
| 867 // For other fields, require that the field contents match the beginning of | 891 // For other fields, require that the field contents match the beginning of |
| 868 // the stored data. | 892 // the stored data. |
| 869 if (type.GetStorableType() == CREDIT_CARD_NUMBER) { | 893 if (type.GetStorableType() == CREDIT_CARD_NUMBER) { |
| 870 if (creditcard_field_value.find(field_contents) == base::string16::npos && | 894 if (creditcard_field_value.find(field_contents) == base::string16::npos && |
| 871 (credit_card->record_type() != CreditCard::MASKED_SERVER_CARD || | 895 (credit_card->record_type() != CreditCard::MASKED_SERVER_CARD || |
| 872 field_contents.size() >= 6)) { | 896 field_contents.size() >= 6)) { |
| 873 continue; | 897 continue; |
| 874 } | 898 } |
| 875 } else if (!base::StartsWith(creditcard_field_value, field_contents, | 899 cards_to_suggest.push_back(credit_card); |
| 876 false)) { | 900 } else if (base::StartsWith(creditcard_field_value, field_contents, |
| 877 continue; | 901 false)) { |
| 902 cards_to_suggest.push_back(credit_card); | |
| 903 } else if (ContainsTokenThatStartsWith(creditcard_field_value, | |
| 904 field_contents, false)) { | |
| 905 substring_matched_cards.push_back(credit_card); | |
| 878 } | 906 } |
| 907 } | |
| 879 | 908 |
| 880 cards_to_suggest.push_back(credit_card); | 909 cards_to_suggest.sort(RankByMfu); |
| 910 | |
| 911 // Prefix matches should precede other token matches. | |
| 912 if (IsFeatureSubstringMatchEnabled()) { | |
| 913 substring_matched_cards.sort(RankByMfu); | |
| 914 cards_to_suggest.insert(cards_to_suggest.end(), | |
| 915 substring_matched_cards.begin(), | |
| 916 substring_matched_cards.end()); | |
| 881 } | 917 } |
| 882 | 918 |
| 883 // De-dupe card suggestions. Full server cards shadow local cards, and | 919 // De-dupe card suggestions. Full server cards shadow local cards, and |
| 884 // local cards shadow masked server cards. | 920 // local cards shadow masked server cards. |
| 885 for (auto outer_it = cards_to_suggest.begin(); | 921 for (auto outer_it = cards_to_suggest.begin(); |
| 886 outer_it != cards_to_suggest.end(); | 922 outer_it != cards_to_suggest.end(); |
| 887 ++outer_it) { | 923 ++outer_it) { |
| 888 | 924 |
| 889 if ((*outer_it)->record_type() == CreditCard::FULL_SERVER_CARD) { | 925 if ((*outer_it)->record_type() == CreditCard::FULL_SERVER_CARD) { |
| 890 for (auto inner_it = cards_to_suggest.begin(); | 926 for (auto inner_it = cards_to_suggest.begin(); |
| 891 inner_it != cards_to_suggest.end();) { | 927 inner_it != cards_to_suggest.end();) { |
| 892 auto inner_it_copy = inner_it++; | 928 auto inner_it_copy = inner_it++; |
| 893 if ((*inner_it_copy)->IsLocalDuplicateOfServerCard(**outer_it)) | 929 if ((*inner_it_copy)->IsLocalDuplicateOfServerCard(**outer_it)) |
| 894 cards_to_suggest.erase(inner_it_copy); | 930 cards_to_suggest.erase(inner_it_copy); |
| 895 } | 931 } |
| 896 } else if ((*outer_it)->record_type() == CreditCard::LOCAL_CARD) { | 932 } else if ((*outer_it)->record_type() == CreditCard::LOCAL_CARD) { |
| 897 for (auto inner_it = cards_to_suggest.begin(); | 933 for (auto inner_it = cards_to_suggest.begin(); |
| 898 inner_it != cards_to_suggest.end();) { | 934 inner_it != cards_to_suggest.end();) { |
| 899 auto inner_it_copy = inner_it++; | 935 auto inner_it_copy = inner_it++; |
| 900 if ((*inner_it_copy)->record_type() == CreditCard::MASKED_SERVER_CARD && | 936 if ((*inner_it_copy)->record_type() == CreditCard::MASKED_SERVER_CARD && |
| 901 (*outer_it)->IsLocalDuplicateOfServerCard(**inner_it_copy)) { | 937 (*outer_it)->IsLocalDuplicateOfServerCard(**inner_it_copy)) { |
| 902 cards_to_suggest.erase(inner_it_copy); | 938 cards_to_suggest.erase(inner_it_copy); |
| 903 } | 939 } |
| 904 } | 940 } |
| 905 } | 941 } |
| 906 } | 942 } |
| 907 | 943 |
| 908 cards_to_suggest.sort(RankByMfu); | |
| 909 | |
| 910 std::vector<Suggestion> suggestions; | 944 std::vector<Suggestion> suggestions; |
| 911 for (const CreditCard* credit_card : cards_to_suggest) { | 945 for (const CreditCard* credit_card : cards_to_suggest) { |
| 912 // Make a new suggestion. | 946 // Make a new suggestion. |
| 913 suggestions.push_back(Suggestion()); | 947 suggestions.push_back(Suggestion()); |
| 914 Suggestion* suggestion = &suggestions.back(); | 948 Suggestion* suggestion = &suggestions.back(); |
| 915 | 949 |
| 916 suggestion->value = credit_card->GetInfo(type, app_locale_); | 950 suggestion->value = credit_card->GetInfo(type, app_locale_); |
| 917 suggestion->icon = base::UTF8ToUTF16(credit_card->type()); | 951 suggestion->icon = base::UTF8ToUTF16(credit_card->type()); |
| 918 suggestion->backend_id = credit_card->guid(); | 952 suggestion->backend_id = credit_card->guid(); |
| 919 | 953 |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1333 } | 1367 } |
| 1334 if (IsExperimentalWalletIntegrationEnabled() && | 1368 if (IsExperimentalWalletIntegrationEnabled() && |
| 1335 pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { | 1369 pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { |
| 1336 profiles_.insert( | 1370 profiles_.insert( |
| 1337 profiles_.end(), server_profiles_.begin(), server_profiles_.end()); | 1371 profiles_.end(), server_profiles_.begin(), server_profiles_.end()); |
| 1338 } | 1372 } |
| 1339 return profiles_; | 1373 return profiles_; |
| 1340 } | 1374 } |
| 1341 | 1375 |
| 1342 } // namespace autofill | 1376 } // namespace autofill |
| OLD | NEW |