OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/autofill/autofill_manager.h" | 5 #include "chrome/browser/autofill/autofill_manager.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <limits> | 9 #include <limits> |
10 #include <map> | 10 #include <map> |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 // forms are added to the back of the list, whereas original versions of these | 811 // forms are added to the back of the list, whereas original versions of these |
812 // forms might appear toward the beginning of the list. The communication | 812 // forms might appear toward the beginning of the list. The communication |
813 // protocol with the crowdsourcing server does not permit us to discard the | 813 // protocol with the crowdsourcing server does not permit us to discard the |
814 // original versions of the forms. | 814 // original versions of the forms. |
815 *form_structure = NULL; | 815 *form_structure = NULL; |
816 for (std::vector<FormStructure*>::const_reverse_iterator iter = | 816 for (std::vector<FormStructure*>::const_reverse_iterator iter = |
817 form_structures_.rbegin(); | 817 form_structures_.rbegin(); |
818 iter != form_structures_.rend(); ++iter) { | 818 iter != form_structures_.rend(); ++iter) { |
819 if (**iter == form) { | 819 if (**iter == form) { |
820 *form_structure = *iter; | 820 *form_structure = *iter; |
821 break; | 821 |
| 822 // The same form might be cached with multiple field counts: in some |
| 823 // cases, non-autofillable fields are filtered out, whereas in other cases |
| 824 // they are not. To avoid thrashing the cache, keep scanning until we |
| 825 // find a cached version with the same number of fields, if there is one. |
| 826 if ((*iter)->field_count() == form.fields.size()) |
| 827 break; |
822 } | 828 } |
823 } | 829 } |
824 | 830 |
825 if (!(*form_structure)) | 831 if (!(*form_structure)) |
826 return false; | 832 return false; |
827 | 833 |
828 return true; | 834 return true; |
829 } | 835 } |
830 | 836 |
831 bool AutofillManager::GetCachedFormAndField(const FormData& form, | 837 bool AutofillManager::GetCachedFormAndField(const FormData& form, |
832 const FormField& field, | 838 const FormField& field, |
833 FormStructure** form_structure, | 839 FormStructure** form_structure, |
834 AutofillField** autofill_field) { | 840 AutofillField** autofill_field) { |
835 // Find the FormStructure that corresponds to |form|. | 841 // Find the FormStructure that corresponds to |form|. |
836 // If we do not have this form in our cache but it is parseable, we'll add it | 842 // If we do not have this form in our cache but it is parseable, we'll add it |
837 // in the call to |UpdateCachedForm()|. | 843 // in the call to |UpdateCachedForm()|. |
838 if (!FindCachedForm(form, form_structure) && | 844 if (!FindCachedForm(form, form_structure) && |
839 (form_structures_.size() >= kMaxFormCacheSize || | 845 !FormStructure(form).ShouldBeParsed(false)) { |
840 !FormStructure(form).ShouldBeParsed(false))) { | |
841 return false; | 846 return false; |
842 } | 847 } |
843 | 848 |
844 // Update the cached form to reflect any dynamic changes to the form data, if | 849 // Update the cached form to reflect any dynamic changes to the form data, if |
845 // necessary. | 850 // necessary. |
846 UpdateCachedForm(form, *form_structure, form_structure); | 851 if (!UpdateCachedForm(form, *form_structure, form_structure)) |
| 852 return false; |
847 | 853 |
848 // No data to return if there are no auto-fillable fields. | 854 // No data to return if there are no auto-fillable fields. |
849 if (!(*form_structure)->autofill_count()) | 855 if (!(*form_structure)->autofill_count()) |
850 return false; | 856 return false; |
851 | 857 |
852 // Find the AutofillField that corresponds to |field|. | 858 // Find the AutofillField that corresponds to |field|. |
853 *autofill_field = NULL; | 859 *autofill_field = NULL; |
854 for (std::vector<AutofillField*>::const_iterator iter = | 860 for (std::vector<AutofillField*>::const_iterator iter = |
855 (*form_structure)->begin(); | 861 (*form_structure)->begin(); |
856 iter != (*form_structure)->end(); ++iter) { | 862 iter != (*form_structure)->end(); ++iter) { |
857 if ((**iter) == field) { | 863 if ((**iter) == field) { |
858 *autofill_field = *iter; | 864 *autofill_field = *iter; |
859 break; | 865 break; |
860 } | 866 } |
861 } | 867 } |
862 | 868 |
863 // We always update the cache, so we should be guaranteed to find the field. | 869 // We always update the cache, so we should be guaranteed to find the field. |
864 DCHECK(*autofill_field); | 870 DCHECK(*autofill_field); |
865 return true; | 871 return true; |
866 } | 872 } |
867 | 873 |
868 void AutofillManager::UpdateCachedForm(const FormData& live_form, | 874 bool AutofillManager::UpdateCachedForm(const FormData& live_form, |
869 const FormStructure* cached_form, | 875 const FormStructure* cached_form, |
870 FormStructure** updated_form) { | 876 FormStructure** updated_form) { |
871 bool needs_update = | 877 bool needs_update = |
872 (!cached_form || | 878 (!cached_form || |
873 live_form.fields.size() != cached_form->field_count()); | 879 live_form.fields.size() != cached_form->field_count()); |
874 for (size_t i = 0; !needs_update && i < cached_form->field_count(); ++i) { | 880 for (size_t i = 0; !needs_update && i < cached_form->field_count(); ++i) { |
875 needs_update = *cached_form->field(i) != live_form.fields[i]; | 881 needs_update = *cached_form->field(i) != live_form.fields[i]; |
876 } | 882 } |
877 | 883 |
878 if (!needs_update) | 884 if (!needs_update) |
879 return; | 885 return true; |
| 886 |
| 887 if (form_structures_.size() >= kMaxFormCacheSize) |
| 888 return false; |
880 | 889 |
881 // Add the new or updated form to our cache. | 890 // Add the new or updated form to our cache. |
882 DCHECK(form_structures_.size() < kMaxFormCacheSize); | |
883 form_structures_.push_back(new FormStructure(live_form)); | 891 form_structures_.push_back(new FormStructure(live_form)); |
884 *updated_form = *form_structures_.rbegin(); | 892 *updated_form = *form_structures_.rbegin(); |
885 (*updated_form)->DetermineHeuristicTypes(); | 893 (*updated_form)->DetermineHeuristicTypes(); |
886 | 894 |
887 // If we have cached data, propagate it to the updated form. | 895 // If we have cached data, propagate it to the updated form. |
888 if (cached_form) { | 896 if (cached_form) { |
889 std::map<string16, const AutofillField*> cached_fields; | 897 std::map<string16, const AutofillField*> cached_fields; |
890 for (size_t i = 0; i < cached_form->field_count(); ++i) { | 898 for (size_t i = 0; i < cached_form->field_count(); ++i) { |
891 const AutofillField* field = cached_form->field(i); | 899 const AutofillField* field = cached_form->field(i); |
892 cached_fields[field->unique_name()] = field; | 900 cached_fields[field->unique_name()] = field; |
(...skipping 10 matching lines...) Expand all Loading... |
903 } | 911 } |
904 | 912 |
905 // Note: We _must not_ remove the original version of the cached form from | 913 // Note: We _must not_ remove the original version of the cached form from |
906 // the list of |form_structures_|. Otherwise, we break parsing of the | 914 // the list of |form_structures_|. Otherwise, we break parsing of the |
907 // crowdsourcing server's response to our query. | 915 // crowdsourcing server's response to our query. |
908 } | 916 } |
909 | 917 |
910 // Annotate the updated form with its predicted types. | 918 // Annotate the updated form with its predicted types. |
911 std::vector<FormStructure*> forms(1, *updated_form); | 919 std::vector<FormStructure*> forms(1, *updated_form); |
912 SendAutofillTypePredictions(forms); | 920 SendAutofillTypePredictions(forms); |
| 921 |
| 922 return true; |
913 } | 923 } |
914 | 924 |
915 void AutofillManager::GetProfileSuggestions( | 925 void AutofillManager::GetProfileSuggestions( |
916 FormStructure* form, | 926 FormStructure* form, |
917 const FormField& field, | 927 const FormField& field, |
918 AutofillFieldType type, | 928 AutofillFieldType type, |
919 std::vector<string16>* values, | 929 std::vector<string16>* values, |
920 std::vector<string16>* labels, | 930 std::vector<string16>* labels, |
921 std::vector<string16>* icons, | 931 std::vector<string16>* icons, |
922 std::vector<int>* unique_ids) const { | 932 std::vector<int>* unique_ids) const { |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 *profile_guid = IDToGUID(profile_id); | 1214 *profile_guid = IDToGUID(profile_id); |
1205 } | 1215 } |
1206 | 1216 |
1207 void AutofillManager::UpdateInitialInteractionTimestamp( | 1217 void AutofillManager::UpdateInitialInteractionTimestamp( |
1208 const TimeTicks& interaction_timestamp) { | 1218 const TimeTicks& interaction_timestamp) { |
1209 if (initial_interaction_timestamp_.is_null() || | 1219 if (initial_interaction_timestamp_.is_null() || |
1210 interaction_timestamp < initial_interaction_timestamp_) { | 1220 interaction_timestamp < initial_interaction_timestamp_) { |
1211 initial_interaction_timestamp_ = interaction_timestamp; | 1221 initial_interaction_timestamp_ = interaction_timestamp; |
1212 } | 1222 } |
1213 } | 1223 } |
OLD | NEW |