Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: components/autofill/core/browser/autofill_manager.cc

Issue 2730383003: Improve autofill form matching. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/autofill_manager.h" 5 #include "components/autofill/core/browser/autofill_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 #include "components/autofill/core/browser/validation.h" 53 #include "components/autofill/core/browser/validation.h"
54 #include "components/autofill/core/common/autofill_clock.h" 54 #include "components/autofill/core/common/autofill_clock.h"
55 #include "components/autofill/core/common/autofill_constants.h" 55 #include "components/autofill/core/common/autofill_constants.h"
56 #include "components/autofill/core/common/autofill_data_validation.h" 56 #include "components/autofill/core/common/autofill_data_validation.h"
57 #include "components/autofill/core/common/autofill_pref_names.h" 57 #include "components/autofill/core/common/autofill_pref_names.h"
58 #include "components/autofill/core/common/autofill_util.h" 58 #include "components/autofill/core/common/autofill_util.h"
59 #include "components/autofill/core/common/form_data.h" 59 #include "components/autofill/core/common/form_data.h"
60 #include "components/autofill/core/common/form_data_predictions.h" 60 #include "components/autofill/core/common/form_data_predictions.h"
61 #include "components/autofill/core/common/form_field_data.h" 61 #include "components/autofill/core/common/form_field_data.h"
62 #include "components/autofill/core/common/password_form_fill_data.h" 62 #include "components/autofill/core/common/password_form_fill_data.h"
63 #include "components/autofill/core/common/signatures_util.h"
63 #include "components/pref_registry/pref_registry_syncable.h" 64 #include "components/pref_registry/pref_registry_syncable.h"
64 #include "components/prefs/pref_service.h" 65 #include "components/prefs/pref_service.h"
65 #include "components/rappor/public/rappor_utils.h" 66 #include "components/rappor/public/rappor_utils.h"
66 #include "components/rappor/rappor_service_impl.h" 67 #include "components/rappor/rappor_service_impl.h"
67 #include "components/security_state/core/security_state.h" 68 #include "components/security_state/core/security_state.h"
68 #include "components/strings/grit/components_strings.h" 69 #include "components/strings/grit/components_strings.h"
69 #include "google_apis/gaia/identity_provider.h" 70 #include "google_apis/gaia/identity_provider.h"
70 #include "ui/base/l10n/l10n_util.h" 71 #include "ui/base/l10n/l10n_util.h"
71 #include "ui/gfx/geometry/rect.h" 72 #include "ui/gfx/geometry/rect.h"
72 #include "url/gurl.h" 73 #include "url/gurl.h"
(...skipping 1599 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 std::unique_ptr<FormStructure> submitted_form(new FormStructure(form)); 1673 std::unique_ptr<FormStructure> submitted_form(new FormStructure(form));
1673 if (!ShouldUploadForm(*submitted_form)) 1674 if (!ShouldUploadForm(*submitted_form))
1674 return std::unique_ptr<FormStructure>(); 1675 return std::unique_ptr<FormStructure>();
1675 1676
1676 // Ignore forms not present in our cache. These are typically forms with 1677 // Ignore forms not present in our cache. These are typically forms with
1677 // wonky JavaScript that also makes them not auto-fillable. 1678 // wonky JavaScript that also makes them not auto-fillable.
1678 FormStructure* cached_submitted_form; 1679 FormStructure* cached_submitted_form;
1679 if (!FindCachedForm(form, &cached_submitted_form)) 1680 if (!FindCachedForm(form, &cached_submitted_form))
1680 return std::unique_ptr<FormStructure>(); 1681 return std::unique_ptr<FormStructure>();
1681 1682
1682 submitted_form->UpdateFromCache(*cached_submitted_form); 1683 submitted_form->UpdateFromCache(*cached_submitted_form, false);
1683 return submitted_form; 1684 return submitted_form;
1684 } 1685 }
1685 1686
1686 bool AutofillManager::FindCachedForm(const FormData& form, 1687 bool AutofillManager::FindCachedForm(const FormData& form,
1687 FormStructure** form_structure) const { 1688 FormStructure** form_structure) const {
1688 // Find the FormStructure that corresponds to |form|. 1689 // Find the FormStructure that corresponds to |form|.
1689 // Scan backward through the cached |form_structures_|, as updated versions of 1690 // Scan backward through the cached |form_structures_|, as updated versions of
1690 // forms are added to the back of the list, whereas original versions of these 1691 // forms are added to the back of the list, whereas original versions of these
1691 // forms might appear toward the beginning of the list. The communication 1692 // forms might appear toward the beginning of the list. The communication
1692 // protocol with the crowdsourcing server does not permit us to discard the 1693 // protocol with the crowdsourcing server does not permit us to discard the
1693 // original versions of the forms. 1694 // original versions of the forms.
1694 *form_structure = NULL; 1695 *form_structure = NULL;
1696 const auto& form_signature = autofill::CalculateFormSignature(form);
1695 for (auto& cur_form : base::Reversed(form_structures_)) { 1697 for (auto& cur_form : base::Reversed(form_structures_)) {
1696 if (*cur_form == form) { 1698 if (cur_form->form_signature() == form_signature || *cur_form == form) {
1697 *form_structure = cur_form.get(); 1699 *form_structure = cur_form.get();
1698 1700
1699 // The same form might be cached with multiple field counts: in some 1701 // The same form might be cached with multiple field counts: in some
1700 // cases, non-autofillable fields are filtered out, whereas in other cases 1702 // cases, non-autofillable fields are filtered out, whereas in other cases
1701 // they are not. To avoid thrashing the cache, keep scanning until we 1703 // they are not. To avoid thrashing the cache, keep scanning until we
1702 // find a cached version with the same number of fields, if there is one. 1704 // find a cached version with the same number of fields, if there is one.
1703 if (cur_form->field_count() == form.fields.size()) 1705 if (cur_form->field_count() == form.fields.size())
1704 break; 1706 break;
1705 } 1707 }
1706 } 1708 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 FormStructure** updated_form) { 1770 FormStructure** updated_form) {
1769 bool needs_update = 1771 bool needs_update =
1770 (!cached_form || 1772 (!cached_form ||
1771 live_form.fields.size() != cached_form->field_count()); 1773 live_form.fields.size() != cached_form->field_count());
1772 for (size_t i = 0; !needs_update && i < cached_form->field_count(); ++i) 1774 for (size_t i = 0; !needs_update && i < cached_form->field_count(); ++i)
1773 needs_update = !cached_form->field(i)->SameFieldAs(live_form.fields[i]); 1775 needs_update = !cached_form->field(i)->SameFieldAs(live_form.fields[i]);
1774 1776
1775 if (!needs_update) 1777 if (!needs_update)
1776 return true; 1778 return true;
1777 1779
1778 if (form_structures_.size() >= kMaxFormCacheSize) 1780 // Note: We _must not_ remove the original version of the cached form from
1779 return false; 1781 // the list of |form_structures_|. Otherwise, we break parsing of the
1780 1782 // crowdsourcing server's response to our query.
1781 // Add the new or updated form to our cache. 1783 if (!ParseForm(live_form, false, updated_form)) {
sense (YandexTeam) 2017/03/07 07:10:28 This logic is replaced by the call to ParseForm().
1782 form_structures_.push_back(base::MakeUnique<FormStructure>(live_form)); 1784 // New form was not added, so no update was performed.
1783 *updated_form = form_structures_.rbegin()->get(); 1785 return cached_form != nullptr;
sebsg 2017/03/08 18:32:08 Can this change the return value compared to befor
sense (YandexTeam) 2017/03/09 04:56:36 Yes, this change is incorrect. We shouldn't return
1784 (*updated_form)->DetermineHeuristicTypes();
1785
1786 // If we have cached data, propagate it to the updated form.
1787 if (cached_form) {
1788 std::map<base::string16, const AutofillField*> cached_fields;
sense (YandexTeam) 2017/03/07 07:10:28 This update logic is replaced by the call to FormS
1789 for (size_t i = 0; i < cached_form->field_count(); ++i) {
1790 const AutofillField* field = cached_form->field(i);
1791 cached_fields[field->unique_name()] = field;
1792 }
1793
1794 for (size_t i = 0; i < (*updated_form)->field_count(); ++i) {
1795 AutofillField* field = (*updated_form)->field(i);
1796 auto cached_field = cached_fields.find(field->unique_name());
1797 if (cached_field != cached_fields.end()) {
1798 field->set_server_type(cached_field->second->server_type());
1799 field->is_autofilled = cached_field->second->is_autofilled;
1800 field->set_previously_autofilled(
1801 cached_field->second->previously_autofilled());
1802 }
1803 }
1804
1805 // Note: We _must not_ remove the original version of the cached form from
1806 // the list of |form_structures_|. Otherwise, we break parsing of the
1807 // crowdsourcing server's response to our query.
1808 } 1786 }
1809 1787
1788 if (cached_form)
1789 (*updated_form)->UpdateFromCache(*cached_form, true);
1790
1810 // Annotate the updated form with its predicted types. 1791 // Annotate the updated form with its predicted types.
1811 std::vector<FormStructure*> forms(1, *updated_form); 1792 driver_->SendAutofillTypePredictionsToRenderer({*updated_form});
1812 driver_->SendAutofillTypePredictionsToRenderer(forms);
1813 1793
1814 return true; 1794 return true;
1815 } 1795 }
1816 1796
1817 std::vector<Suggestion> AutofillManager::GetProfileSuggestions( 1797 std::vector<Suggestion> AutofillManager::GetProfileSuggestions(
1818 const FormStructure& form, 1798 const FormStructure& form,
1819 const FormFieldData& field, 1799 const FormFieldData& field,
1820 const AutofillField& autofill_field) const { 1800 const AutofillField& autofill_field) const {
1821 address_form_event_logger_->OnDidPollSuggestions(field); 1801 address_form_event_logger_->OnDidPollSuggestions(field);
1822 1802
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 1843
1864 void AutofillManager::ParseForms(const std::vector<FormData>& forms) { 1844 void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
1865 if (forms.empty()) 1845 if (forms.empty())
1866 return; 1846 return;
1867 1847
1868 std::vector<FormStructure*> non_queryable_forms; 1848 std::vector<FormStructure*> non_queryable_forms;
1869 std::vector<FormStructure*> queryable_forms; 1849 std::vector<FormStructure*> queryable_forms;
1870 for (const FormData& form : forms) { 1850 for (const FormData& form : forms) {
1871 const auto parse_form_start_time = base::TimeTicks::Now(); 1851 const auto parse_form_start_time = base::TimeTicks::Now();
1872 1852
1873 std::unique_ptr<FormStructure> form_structure = 1853 FormStructure* form_structure = nullptr;
1874 base::MakeUnique<FormStructure>(form); 1854 if (!ParseForm(form, true, &form_structure))
sebsg 2017/03/08 18:32:08 I'm not sure why this needs to be true here? It me
sense (YandexTeam) 2017/03/09 04:56:36 The check for duplicates is from our internal impr
1875 form_structure->ParseFieldTypesFromAutocompleteAttributes();
1876 if (!form_structure->ShouldBeParsed())
1877 continue; 1855 continue;
1856 DCHECK(form_structure);
1878 1857
1879 form_structure->DetermineHeuristicTypes(); 1858 // Set aside forms with method GET or author-specified types, so that they
1880 1859 // are not included in the query to the server.
1881 // Ownership is transferred to |form_structures_| which maintains it until 1860 if (form_structure->ShouldBeCrowdsourced())
1882 // the manager is Reset() or destroyed. It is safe to use references below 1861 queryable_forms.push_back(form_structure);
1883 // as long as receivers don't take ownership.
1884 form_structures_.push_back(std::move(form_structure));
1885
1886 if (form_structures_.back()->ShouldBeCrowdsourced())
1887 queryable_forms.push_back(form_structures_.back().get());
1888 else 1862 else
1889 non_queryable_forms.push_back(form_structures_.back().get()); 1863 non_queryable_forms.push_back(form_structure);
1890 1864
1891 AutofillMetrics::LogParseFormTiming(base::TimeTicks::Now() - 1865 AutofillMetrics::LogParseFormTiming(base::TimeTicks::Now() -
1892 parse_form_start_time); 1866 parse_form_start_time);
1893 } 1867 }
1894 1868
1895 if (!queryable_forms.empty() && download_manager_) { 1869 if (!queryable_forms.empty() && download_manager_) {
1896 // Query the server if at least one of the forms was parsed. 1870 // Query the server if at least one of the forms was parsed.
1897 download_manager_->StartQueryRequest(queryable_forms); 1871 download_manager_->StartQueryRequest(queryable_forms);
1898 } 1872 }
1899 1873
(...skipping 21 matching lines...) Expand all
1921 autofill_assistant_.ShowAssistForCreditCard(*cards.front()); 1895 autofill_assistant_.ShowAssistForCreditCard(*cards.front());
1922 } 1896 }
1923 #endif 1897 #endif
1924 1898
1925 // For the |non_queryable_forms|, we have all the field type info we're ever 1899 // For the |non_queryable_forms|, we have all the field type info we're ever
1926 // going to get about them. For the other forms, we'll wait until we get a 1900 // going to get about them. For the other forms, we'll wait until we get a
1927 // response from the server. 1901 // response from the server.
1928 driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms); 1902 driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms);
1929 } 1903 }
1930 1904
1905 bool AutofillManager::ParseForm(const FormData& form,
1906 const bool check_for_duplicates,
1907 FormStructure** parsed_form_structure) {
1908 DCHECK(parsed_form_structure);
1909 if (form_structures_.size() >= kMaxFormCacheSize)
sense (YandexTeam) 2017/03/07 07:10:28 Previously this check was only in UpdateCachedForm
1910 return false;
1911
1912 auto form_structure = base::MakeUnique<FormStructure>(form);
1913 form_structure->ParseFieldTypesFromAutocompleteAttributes();
1914 if (!form_structure->ShouldBeParsed())
1915 return false;
1916
1917 if (check_for_duplicates) {
1918 // Check if we have got this form before since the agent uses a different
1919 // form comparison method that can send us duplicates here.
1920 for (const auto& existing_form_structure : form_structures_) {
1921 // If we already got this form, skip it.
1922 if (form_structure->form_signature() ==
1923 existing_form_structure->form_signature()) {
1924 return false;
1925 }
1926 }
1927 }
1928
1929 form_structure->DetermineHeuristicTypes();
1930
1931 // Ownership is transferred to |form_structures_| which maintains it until
1932 // the manager is Reset() or destroyed. It is safe to use references below
1933 // as long as receivers don't take ownership.
1934 form_structures_.push_back(std::move(form_structure));
1935 *parsed_form_structure = form_structures_.back().get();
1936 return true;
1937 }
1938
1931 int AutofillManager::BackendIDToInt(const std::string& backend_id) const { 1939 int AutofillManager::BackendIDToInt(const std::string& backend_id) const {
1932 if (!base::IsValidGUID(backend_id)) 1940 if (!base::IsValidGUID(backend_id))
1933 return 0; 1941 return 0;
1934 1942
1935 const auto found = backend_to_int_map_.find(backend_id); 1943 const auto found = backend_to_int_map_.find(backend_id);
1936 if (found == backend_to_int_map_.end()) { 1944 if (found == backend_to_int_map_.end()) {
1937 // Unknown one, make a new entry. 1945 // Unknown one, make a new entry.
1938 int int_id = backend_to_int_map_.size() + 1; 1946 int int_id = backend_to_int_map_.size() + 1;
1939 backend_to_int_map_[backend_id] = int_id; 1947 backend_to_int_map_[backend_id] = int_id;
1940 int_to_backend_map_[int_id] = backend_id; 1948 int_to_backend_map_[int_id] = backend_id;
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 if (i > 0) 2199 if (i > 0)
2192 fputs("Next oldest form:\n", file); 2200 fputs("Next oldest form:\n", file);
2193 } 2201 }
2194 fputs("\n", file); 2202 fputs("\n", file);
2195 2203
2196 fclose(file); 2204 fclose(file);
2197 } 2205 }
2198 #endif // ENABLE_FORM_DEBUG_DUMP 2206 #endif // ENABLE_FORM_DEBUG_DUMP
2199 2207
2200 } // namespace autofill 2208 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698