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 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
753 | 754 |
754 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { | 755 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { |
755 credit_cards_.clear(); | 756 credit_cards_.clear(); |
756 credit_cards_.insert(credit_cards_.end(), local_credit_cards_.begin(), | 757 credit_cards_.insert(credit_cards_.end(), local_credit_cards_.begin(), |
757 local_credit_cards_.end()); | 758 local_credit_cards_.end()); |
758 if (IsExperimentalWalletIntegrationEnabled() && | 759 if (IsExperimentalWalletIntegrationEnabled() && |
759 pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { | 760 pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { |
760 credit_cards_.insert(credit_cards_.end(), server_credit_cards_.begin(), | 761 credit_cards_.insert(credit_cards_.end(), server_credit_cards_.begin(), |
761 server_credit_cards_.end()); | 762 server_credit_cards_.end()); |
762 } | 763 } |
764 | |
763 return credit_cards_; | 765 return credit_cards_; |
764 } | 766 } |
765 | 767 |
766 bool PersonalDataManager::HasServerData() const { | 768 bool PersonalDataManager::HasServerData() const { |
767 return !server_credit_cards_.empty() || !server_profiles_.empty(); | 769 return !server_credit_cards_.empty() || !server_profiles_.empty(); |
768 } | 770 } |
769 | 771 |
770 void PersonalDataManager::Refresh() { | 772 void PersonalDataManager::Refresh() { |
771 LoadProfiles(); | 773 LoadProfiles(); |
772 LoadCreditCards(); | 774 LoadCreditCards(); |
(...skipping 12 matching lines...) Expand all Loading... | |
785 | 787 |
786 std::vector<Suggestion> suggestions; | 788 std::vector<Suggestion> suggestions; |
787 // Match based on a prefix search. | 789 // Match based on a prefix search. |
788 std::vector<AutofillProfile*> matched_profiles; | 790 std::vector<AutofillProfile*> matched_profiles; |
789 for (AutofillProfile* profile : profiles) { | 791 for (AutofillProfile* profile : profiles) { |
790 base::string16 value = GetInfoInOneLine(profile, type, app_locale_); | 792 base::string16 value = GetInfoInOneLine(profile, type, app_locale_); |
791 if (value.empty()) | 793 if (value.empty()) |
792 continue; | 794 continue; |
793 base::string16 value_canon = | 795 base::string16 value_canon = |
794 AutofillProfile::CanonicalizeProfileString(value); | 796 AutofillProfile::CanonicalizeProfileString(value); |
795 if (StartsWith(value_canon, field_contents_canon, true)) { | 797 // CanonicalizeProfileString() returns lower-case string with all |
796 // Prefix match, add suggestion. | 798 // separator substituted by whitespaces and trims off trailing whitespace |
799 // if any. Passing |value_canon| and |field_contents_canon| to | |
800 // ContainsTokenThatStartsWith() may lead to unexpected result, hence | |
801 // preferred passing |values[i]| and |field_contents| instead. | |
802 bool substring_matched_suggestion = false; | |
803 if (StartsWith(value_canon, field_contents_canon, true) || | |
804 (substring_matched_suggestion = | |
805 ContainsTokenThatStartsWith(value, field_contents, false))) { | |
797 matched_profiles.push_back(profile); | 806 matched_profiles.push_back(profile); |
798 suggestions.push_back(Suggestion(value)); | 807 suggestions.push_back(Suggestion(value)); |
799 suggestions.back().backend_id = profile->guid(); | 808 suggestions.back().backend_id = profile->guid(); |
809 suggestions.back().match = substring_matched_suggestion | |
810 ? Suggestion::SUBSTRING_MATCH | |
811 : Suggestion::PREFIX_MATCH; | |
800 } | 812 } |
801 } | 813 } |
802 | 814 |
815 // Prefix matches should precede other token matches. | |
816 if (IsFeatureSubstringMatchEnabled()) | |
817 OrderPrefixBeforeSubstring(&suggestions); | |
818 | |
803 // Don't show two suggestions if one is a subset of the other. | 819 // Don't show two suggestions if one is a subset of the other. |
804 std::vector<AutofillProfile*> unique_matched_profiles; | 820 std::vector<AutofillProfile*> unique_matched_profiles; |
805 std::vector<Suggestion> unique_suggestions; | 821 std::vector<Suggestion> unique_suggestions; |
806 ServerFieldTypeSet types(other_field_types.begin(), other_field_types.end()); | 822 ServerFieldTypeSet types(other_field_types.begin(), other_field_types.end()); |
807 for (size_t i = 0; i < matched_profiles.size(); ++i) { | 823 for (size_t i = 0; i < matched_profiles.size(); ++i) { |
808 bool include = true; | 824 bool include = true; |
809 AutofillProfile* profile_a = matched_profiles[i]; | 825 AutofillProfile* profile_a = matched_profiles[i]; |
810 for (size_t j = 0; j < matched_profiles.size(); ++j) { | 826 for (size_t j = 0; j < matched_profiles.size(); ++j) { |
811 AutofillProfile* profile_b = matched_profiles[j]; | 827 AutofillProfile* profile_b = matched_profiles[j]; |
812 // Check if profile A is a subset of profile B. If not, continue. | 828 // Check if profile A is a subset of profile B. If not, continue. |
(...skipping 28 matching lines...) Expand all Loading... | |
841 for (size_t i = 0; i < labels.size(); i++) | 857 for (size_t i = 0; i < labels.size(); i++) |
842 unique_suggestions[i].label = labels[i]; | 858 unique_suggestions[i].label = labels[i]; |
843 | 859 |
844 return unique_suggestions; | 860 return unique_suggestions; |
845 } | 861 } |
846 | 862 |
847 std::vector<Suggestion> PersonalDataManager::GetCreditCardSuggestions( | 863 std::vector<Suggestion> PersonalDataManager::GetCreditCardSuggestions( |
848 const AutofillType& type, | 864 const AutofillType& type, |
849 const base::string16& field_contents) { | 865 const base::string16& field_contents) { |
850 std::list<const CreditCard*> cards_to_suggest; | 866 std::list<const CreditCard*> cards_to_suggest; |
867 std::list<const CreditCard*> substring_matched_suggestions; | |
851 for (const CreditCard* credit_card : GetCreditCards()) { | 868 for (const CreditCard* credit_card : GetCreditCards()) { |
852 // The value of the stored data for this field type in the |credit_card|. | 869 // The value of the stored data for this field type in the |credit_card|. |
853 base::string16 creditcard_field_value = | 870 base::string16 creditcard_field_value = |
854 credit_card->GetInfo(type, app_locale_); | 871 credit_card->GetInfo(type, app_locale_); |
855 if (creditcard_field_value.empty()) | 872 if (creditcard_field_value.empty()) |
856 continue; | 873 continue; |
857 | 874 |
858 // For card number fields, suggest the card if: | 875 // For card number fields, suggest the card if: |
859 // - the number matches any part of the card, or | 876 // - the number matches any part of the card, or |
860 // - it's a masked card and there are 6 or fewers typed so far. | 877 // - it's a masked card and there are 6 or fewers typed so far. |
861 // For other fields, require that the field contents match the beginning of | 878 // For other fields, require that the field contents match the beginning of |
862 // the stored data. | 879 // the stored data. |
863 if (type.GetStorableType() == CREDIT_CARD_NUMBER) { | 880 if (type.GetStorableType() == CREDIT_CARD_NUMBER) { |
864 if (creditcard_field_value.find(field_contents) == base::string16::npos && | 881 if (creditcard_field_value.find(field_contents) == base::string16::npos && |
865 (credit_card->record_type() != CreditCard::MASKED_SERVER_CARD || | 882 (credit_card->record_type() != CreditCard::MASKED_SERVER_CARD || |
866 field_contents.size() >= 6)) { | 883 field_contents.size() >= 6)) { |
867 continue; | 884 continue; |
868 } | 885 } |
869 } else if (!StartsWith(creditcard_field_value, field_contents, false)) { | 886 cards_to_suggest.push_back(credit_card); |
870 continue; | 887 } else if (StartsWith(creditcard_field_value, field_contents, false)) { |
888 cards_to_suggest.push_back(credit_card); | |
889 } else if (ContainsTokenThatStartsWith(creditcard_field_value, | |
890 field_contents, false)) { | |
891 substring_matched_suggestions.push_back(credit_card); | |
871 } | 892 } |
893 } | |
872 | 894 |
873 cards_to_suggest.push_back(credit_card); | 895 cards_to_suggest.sort(RankByMfu); |
896 | |
897 // Prefix matches should precede other token matches. | |
898 if (IsFeatureSubstringMatchEnabled()) { | |
899 cards_to_suggest.insert(cards_to_suggest.end(), | |
Evan Stade
2015/06/08 23:23:38
so it seems the substring matches are not ranked i
Pritam Nikam
2015/06/09 11:39:06
Done.
| |
900 substring_matched_suggestions.begin(), | |
901 substring_matched_suggestions.end()); | |
874 } | 902 } |
875 | 903 |
876 // De-dupe card suggestions. Full server cards shadow local cards, and | 904 // De-dupe card suggestions. Full server cards shadow local cards, and |
877 // local cards shadow masked server cards. | 905 // local cards shadow masked server cards. |
878 for (auto outer_it = cards_to_suggest.begin(); | 906 for (auto outer_it = cards_to_suggest.begin(); |
879 outer_it != cards_to_suggest.end(); | 907 outer_it != cards_to_suggest.end(); |
880 ++outer_it) { | 908 ++outer_it) { |
881 | 909 |
882 if ((*outer_it)->record_type() == CreditCard::FULL_SERVER_CARD) { | 910 if ((*outer_it)->record_type() == CreditCard::FULL_SERVER_CARD) { |
883 for (auto inner_it = cards_to_suggest.begin(); | 911 for (auto inner_it = cards_to_suggest.begin(); |
884 inner_it != cards_to_suggest.end();) { | 912 inner_it != cards_to_suggest.end();) { |
885 auto inner_it_copy = inner_it++; | 913 auto inner_it_copy = inner_it++; |
886 if ((*inner_it_copy)->IsLocalDuplicateOfServerCard(**outer_it)) | 914 if ((*inner_it_copy)->IsLocalDuplicateOfServerCard(**outer_it)) |
887 cards_to_suggest.erase(inner_it_copy); | 915 cards_to_suggest.erase(inner_it_copy); |
888 } | 916 } |
889 } else if ((*outer_it)->record_type() == CreditCard::LOCAL_CARD) { | 917 } else if ((*outer_it)->record_type() == CreditCard::LOCAL_CARD) { |
890 for (auto inner_it = cards_to_suggest.begin(); | 918 for (auto inner_it = cards_to_suggest.begin(); |
891 inner_it != cards_to_suggest.end();) { | 919 inner_it != cards_to_suggest.end();) { |
892 auto inner_it_copy = inner_it++; | 920 auto inner_it_copy = inner_it++; |
893 if ((*inner_it_copy)->record_type() == CreditCard::MASKED_SERVER_CARD && | 921 if ((*inner_it_copy)->record_type() == CreditCard::MASKED_SERVER_CARD && |
894 (*outer_it)->IsLocalDuplicateOfServerCard(**inner_it_copy)) { | 922 (*outer_it)->IsLocalDuplicateOfServerCard(**inner_it_copy)) { |
895 cards_to_suggest.erase(inner_it_copy); | 923 cards_to_suggest.erase(inner_it_copy); |
896 } | 924 } |
897 } | 925 } |
898 } | 926 } |
899 } | 927 } |
900 | 928 |
901 cards_to_suggest.sort(RankByMfu); | |
902 | |
903 std::vector<Suggestion> suggestions; | 929 std::vector<Suggestion> suggestions; |
904 for (const CreditCard* credit_card : cards_to_suggest) { | 930 for (const CreditCard* credit_card : cards_to_suggest) { |
905 // Make a new suggestion. | 931 // Make a new suggestion. |
906 suggestions.push_back(Suggestion()); | 932 suggestions.push_back(Suggestion()); |
907 Suggestion* suggestion = &suggestions.back(); | 933 Suggestion* suggestion = &suggestions.back(); |
908 | 934 |
909 suggestion->value = credit_card->GetInfo(type, app_locale_); | 935 suggestion->value = credit_card->GetInfo(type, app_locale_); |
910 suggestion->icon = base::UTF8ToUTF16(credit_card->type()); | 936 suggestion->icon = base::UTF8ToUTF16(credit_card->type()); |
911 suggestion->backend_id = credit_card->guid(); | 937 suggestion->backend_id = credit_card->guid(); |
912 | 938 |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1331 } | 1357 } |
1332 if (IsExperimentalWalletIntegrationEnabled() && | 1358 if (IsExperimentalWalletIntegrationEnabled() && |
1333 pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { | 1359 pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { |
1334 profiles_.insert( | 1360 profiles_.insert( |
1335 profiles_.end(), server_profiles_.begin(), server_profiles_.end()); | 1361 profiles_.end(), server_profiles_.begin(), server_profiles_.end()); |
1336 } | 1362 } |
1337 return profiles_; | 1363 return profiles_; |
1338 } | 1364 } |
1339 | 1365 |
1340 } // namespace autofill | 1366 } // namespace autofill |
OLD | NEW |