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

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

Issue 2730383003: Improve autofill form matching. (Closed)
Patch Set: Address review issues. 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
1781 // the list of |form_structures_|. Otherwise, we break parsing of the
1782 // crowdsourcing server's response to our query.
1783 if (!ParseForm(live_form, updated_form))
1779 return false; 1784 return false;
1780 1785
1781 // Add the new or updated form to our cache. 1786 if (cached_form)
1782 form_structures_.push_back(base::MakeUnique<FormStructure>(live_form)); 1787 (*updated_form)->UpdateFromCache(*cached_form, true);
1783 *updated_form = form_structures_.rbegin()->get();
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;
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 }
1809 1788
1810 // Annotate the updated form with its predicted types. 1789 // Annotate the updated form with its predicted types.
1811 std::vector<FormStructure*> forms(1, *updated_form); 1790 driver_->SendAutofillTypePredictionsToRenderer({*updated_form});
1812 driver_->SendAutofillTypePredictionsToRenderer(forms);
1813 1791
1814 return true; 1792 return true;
1815 } 1793 }
1816 1794
1817 std::vector<Suggestion> AutofillManager::GetProfileSuggestions( 1795 std::vector<Suggestion> AutofillManager::GetProfileSuggestions(
1818 const FormStructure& form, 1796 const FormStructure& form,
1819 const FormFieldData& field, 1797 const FormFieldData& field,
1820 const AutofillField& autofill_field) const { 1798 const AutofillField& autofill_field) const {
1821 address_form_event_logger_->OnDidPollSuggestions(field); 1799 address_form_event_logger_->OnDidPollSuggestions(field);
1822 1800
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 1841
1864 void AutofillManager::ParseForms(const std::vector<FormData>& forms) { 1842 void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
1865 if (forms.empty()) 1843 if (forms.empty())
1866 return; 1844 return;
1867 1845
1868 std::vector<FormStructure*> non_queryable_forms; 1846 std::vector<FormStructure*> non_queryable_forms;
1869 std::vector<FormStructure*> queryable_forms; 1847 std::vector<FormStructure*> queryable_forms;
1870 for (const FormData& form : forms) { 1848 for (const FormData& form : forms) {
1871 const auto parse_form_start_time = base::TimeTicks::Now(); 1849 const auto parse_form_start_time = base::TimeTicks::Now();
1872 1850
1873 std::unique_ptr<FormStructure> form_structure = 1851 FormStructure* form_structure = nullptr;
1874 base::MakeUnique<FormStructure>(form); 1852 if (!ParseForm(form, &form_structure))
1875 form_structure->ParseFieldTypesFromAutocompleteAttributes();
1876 if (!form_structure->ShouldBeParsed())
1877 continue; 1853 continue;
1854 DCHECK(form_structure);
1878 1855
1879 form_structure->DetermineHeuristicTypes(); 1856 // Set aside forms with method GET or author-specified types, so that they
1880 1857 // are not included in the query to the server.
1881 // Ownership is transferred to |form_structures_| which maintains it until 1858 if (form_structure->ShouldBeCrowdsourced())
1882 // the manager is Reset() or destroyed. It is safe to use references below 1859 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 1860 else
1889 non_queryable_forms.push_back(form_structures_.back().get()); 1861 non_queryable_forms.push_back(form_structure);
1890 1862
1891 AutofillMetrics::LogParseFormTiming(base::TimeTicks::Now() - 1863 AutofillMetrics::LogParseFormTiming(base::TimeTicks::Now() -
1892 parse_form_start_time); 1864 parse_form_start_time);
1893 } 1865 }
1894 1866
1895 if (!queryable_forms.empty() && download_manager_) { 1867 if (!queryable_forms.empty() && download_manager_) {
1896 // Query the server if at least one of the forms was parsed. 1868 // Query the server if at least one of the forms was parsed.
1897 download_manager_->StartQueryRequest(queryable_forms); 1869 download_manager_->StartQueryRequest(queryable_forms);
1898 } 1870 }
1899 1871
(...skipping 21 matching lines...) Expand all
1921 autofill_assistant_.ShowAssistForCreditCard(*cards.front()); 1893 autofill_assistant_.ShowAssistForCreditCard(*cards.front());
1922 } 1894 }
1923 #endif 1895 #endif
1924 1896
1925 // For the |non_queryable_forms|, we have all the field type info we're ever 1897 // 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 1898 // going to get about them. For the other forms, we'll wait until we get a
1927 // response from the server. 1899 // response from the server.
1928 driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms); 1900 driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms);
1929 } 1901 }
1930 1902
1903 bool AutofillManager::ParseForm(const FormData& form,
1904 FormStructure** parsed_form_structure) {
1905 DCHECK(parsed_form_structure);
1906 if (form_structures_.size() >= kMaxFormCacheSize)
1907 return false;
1908
1909 auto form_structure = base::MakeUnique<FormStructure>(form);
1910 form_structure->ParseFieldTypesFromAutocompleteAttributes();
1911 if (!form_structure->ShouldBeParsed())
1912 return false;
1913
1914 form_structure->DetermineHeuristicTypes();
sebsg 2017/03/13 12:51:21 Would you mind moving this after the add like in t
1915
1916 // Ownership is transferred to |form_structures_| which maintains it until
1917 // the manager is Reset() or destroyed. It is safe to use references below
1918 // as long as receivers don't take ownership.
1919 form_structures_.push_back(std::move(form_structure));
1920 *parsed_form_structure = form_structures_.back().get();
1921 return true;
1922 }
1923
1931 int AutofillManager::BackendIDToInt(const std::string& backend_id) const { 1924 int AutofillManager::BackendIDToInt(const std::string& backend_id) const {
1932 if (!base::IsValidGUID(backend_id)) 1925 if (!base::IsValidGUID(backend_id))
1933 return 0; 1926 return 0;
1934 1927
1935 const auto found = backend_to_int_map_.find(backend_id); 1928 const auto found = backend_to_int_map_.find(backend_id);
1936 if (found == backend_to_int_map_.end()) { 1929 if (found == backend_to_int_map_.end()) {
1937 // Unknown one, make a new entry. 1930 // Unknown one, make a new entry.
1938 int int_id = backend_to_int_map_.size() + 1; 1931 int int_id = backend_to_int_map_.size() + 1;
1939 backend_to_int_map_[backend_id] = int_id; 1932 backend_to_int_map_[backend_id] = int_id;
1940 int_to_backend_map_[int_id] = backend_id; 1933 int_to_backend_map_[int_id] = backend_id;
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 if (i > 0) 2184 if (i > 0)
2192 fputs("Next oldest form:\n", file); 2185 fputs("Next oldest form:\n", file);
2193 } 2186 }
2194 fputs("\n", file); 2187 fputs("\n", file);
2195 2188
2196 fclose(file); 2189 fclose(file);
2197 } 2190 }
2198 #endif // ENABLE_FORM_DEBUG_DUMP 2191 #endif // ENABLE_FORM_DEBUG_DUMP
2199 2192
2200 } // namespace autofill 2193 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/autofill_manager.h ('k') | components/autofill/core/browser/autofill_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698