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

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

Issue 2730383003: Improve autofill form matching. (Closed)
Patch Set: Move DetermineHeuristicTypes after the add. Rebase. 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 1609 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 std::unique_ptr<FormStructure> submitted_form(new FormStructure(form)); 1683 std::unique_ptr<FormStructure> submitted_form(new FormStructure(form));
1683 if (!ShouldUploadForm(*submitted_form)) 1684 if (!ShouldUploadForm(*submitted_form))
1684 return std::unique_ptr<FormStructure>(); 1685 return std::unique_ptr<FormStructure>();
1685 1686
1686 // Ignore forms not present in our cache. These are typically forms with 1687 // Ignore forms not present in our cache. These are typically forms with
1687 // wonky JavaScript that also makes them not auto-fillable. 1688 // wonky JavaScript that also makes them not auto-fillable.
1688 FormStructure* cached_submitted_form; 1689 FormStructure* cached_submitted_form;
1689 if (!FindCachedForm(form, &cached_submitted_form)) 1690 if (!FindCachedForm(form, &cached_submitted_form))
1690 return std::unique_ptr<FormStructure>(); 1691 return std::unique_ptr<FormStructure>();
1691 1692
1692 submitted_form->UpdateFromCache(*cached_submitted_form); 1693 submitted_form->UpdateFromCache(*cached_submitted_form, false);
1693 return submitted_form; 1694 return submitted_form;
1694 } 1695 }
1695 1696
1696 bool AutofillManager::FindCachedForm(const FormData& form, 1697 bool AutofillManager::FindCachedForm(const FormData& form,
1697 FormStructure** form_structure) const { 1698 FormStructure** form_structure) const {
1698 // Find the FormStructure that corresponds to |form|. 1699 // Find the FormStructure that corresponds to |form|.
1699 // Scan backward through the cached |form_structures_|, as updated versions of 1700 // Scan backward through the cached |form_structures_|, as updated versions of
1700 // forms are added to the back of the list, whereas original versions of these 1701 // forms are added to the back of the list, whereas original versions of these
1701 // forms might appear toward the beginning of the list. The communication 1702 // forms might appear toward the beginning of the list. The communication
1702 // protocol with the crowdsourcing server does not permit us to discard the 1703 // protocol with the crowdsourcing server does not permit us to discard the
1703 // original versions of the forms. 1704 // original versions of the forms.
1704 *form_structure = NULL; 1705 *form_structure = NULL;
1706 const auto& form_signature = autofill::CalculateFormSignature(form);
1705 for (auto& cur_form : base::Reversed(form_structures_)) { 1707 for (auto& cur_form : base::Reversed(form_structures_)) {
1706 if (*cur_form == form) { 1708 if (cur_form->form_signature() == form_signature || *cur_form == form) {
1707 *form_structure = cur_form.get(); 1709 *form_structure = cur_form.get();
1708 1710
1709 // The same form might be cached with multiple field counts: in some 1711 // The same form might be cached with multiple field counts: in some
1710 // cases, non-autofillable fields are filtered out, whereas in other cases 1712 // cases, non-autofillable fields are filtered out, whereas in other cases
1711 // they are not. To avoid thrashing the cache, keep scanning until we 1713 // they are not. To avoid thrashing the cache, keep scanning until we
1712 // find a cached version with the same number of fields, if there is one. 1714 // find a cached version with the same number of fields, if there is one.
1713 if (cur_form->field_count() == form.fields.size()) 1715 if (cur_form->field_count() == form.fields.size())
1714 break; 1716 break;
1715 } 1717 }
1716 } 1718 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1778 FormStructure** updated_form) { 1780 FormStructure** updated_form) {
1779 bool needs_update = 1781 bool needs_update =
1780 (!cached_form || 1782 (!cached_form ||
1781 live_form.fields.size() != cached_form->field_count()); 1783 live_form.fields.size() != cached_form->field_count());
1782 for (size_t i = 0; !needs_update && i < cached_form->field_count(); ++i) 1784 for (size_t i = 0; !needs_update && i < cached_form->field_count(); ++i)
1783 needs_update = !cached_form->field(i)->SameFieldAs(live_form.fields[i]); 1785 needs_update = !cached_form->field(i)->SameFieldAs(live_form.fields[i]);
1784 1786
1785 if (!needs_update) 1787 if (!needs_update)
1786 return true; 1788 return true;
1787 1789
1788 if (form_structures_.size() >= kMaxFormCacheSize) 1790 // Note: We _must not_ remove the original version of the cached form from
1791 // the list of |form_structures_|. Otherwise, we break parsing of the
1792 // crowdsourcing server's response to our query.
1793 if (!ParseForm(live_form, updated_form))
1789 return false; 1794 return false;
1790 1795
1791 // Add the new or updated form to our cache. 1796 if (cached_form)
1792 form_structures_.push_back(base::MakeUnique<FormStructure>(live_form)); 1797 (*updated_form)->UpdateFromCache(*cached_form, true);
1793 *updated_form = form_structures_.rbegin()->get();
1794 (*updated_form)->DetermineHeuristicTypes();
1795
1796 // If we have cached data, propagate it to the updated form.
1797 if (cached_form) {
1798 std::map<base::string16, const AutofillField*> cached_fields;
1799 for (size_t i = 0; i < cached_form->field_count(); ++i) {
1800 const AutofillField* field = cached_form->field(i);
1801 cached_fields[field->unique_name()] = field;
1802 }
1803
1804 for (size_t i = 0; i < (*updated_form)->field_count(); ++i) {
1805 AutofillField* field = (*updated_form)->field(i);
1806 auto cached_field = cached_fields.find(field->unique_name());
1807 if (cached_field != cached_fields.end()) {
1808 field->set_server_type(cached_field->second->server_type());
1809 field->is_autofilled = cached_field->second->is_autofilled;
1810 field->set_previously_autofilled(
1811 cached_field->second->previously_autofilled());
1812 }
1813 }
1814
1815 // Note: We _must not_ remove the original version of the cached form from
1816 // the list of |form_structures_|. Otherwise, we break parsing of the
1817 // crowdsourcing server's response to our query.
1818 }
1819 1798
1820 // Annotate the updated form with its predicted types. 1799 // Annotate the updated form with its predicted types.
1821 std::vector<FormStructure*> forms(1, *updated_form); 1800 driver_->SendAutofillTypePredictionsToRenderer({*updated_form});
1822 driver_->SendAutofillTypePredictionsToRenderer(forms);
1823 1801
1824 return true; 1802 return true;
1825 } 1803 }
1826 1804
1827 std::vector<Suggestion> AutofillManager::GetProfileSuggestions( 1805 std::vector<Suggestion> AutofillManager::GetProfileSuggestions(
1828 const FormStructure& form, 1806 const FormStructure& form,
1829 const FormFieldData& field, 1807 const FormFieldData& field,
1830 const AutofillField& autofill_field) const { 1808 const AutofillField& autofill_field) const {
1831 address_form_event_logger_->OnDidPollSuggestions(field); 1809 address_form_event_logger_->OnDidPollSuggestions(field);
1832 1810
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 1851
1874 void AutofillManager::ParseForms(const std::vector<FormData>& forms) { 1852 void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
1875 if (forms.empty()) 1853 if (forms.empty())
1876 return; 1854 return;
1877 1855
1878 std::vector<FormStructure*> non_queryable_forms; 1856 std::vector<FormStructure*> non_queryable_forms;
1879 std::vector<FormStructure*> queryable_forms; 1857 std::vector<FormStructure*> queryable_forms;
1880 for (const FormData& form : forms) { 1858 for (const FormData& form : forms) {
1881 const auto parse_form_start_time = base::TimeTicks::Now(); 1859 const auto parse_form_start_time = base::TimeTicks::Now();
1882 1860
1883 std::unique_ptr<FormStructure> form_structure = 1861 FormStructure* form_structure = nullptr;
1884 base::MakeUnique<FormStructure>(form); 1862 if (!ParseForm(form, &form_structure))
1885 form_structure->ParseFieldTypesFromAutocompleteAttributes();
1886 if (!form_structure->ShouldBeParsed())
1887 continue; 1863 continue;
1864 DCHECK(form_structure);
1888 1865
1889 form_structure->DetermineHeuristicTypes(); 1866 // Set aside forms with method GET or author-specified types, so that they
1890 1867 // are not included in the query to the server.
1891 // Ownership is transferred to |form_structures_| which maintains it until 1868 if (form_structure->ShouldBeCrowdsourced())
1892 // the manager is Reset() or destroyed. It is safe to use references below 1869 queryable_forms.push_back(form_structure);
1893 // as long as receivers don't take ownership.
1894 form_structures_.push_back(std::move(form_structure));
1895
1896 if (form_structures_.back()->ShouldBeCrowdsourced())
1897 queryable_forms.push_back(form_structures_.back().get());
1898 else 1870 else
1899 non_queryable_forms.push_back(form_structures_.back().get()); 1871 non_queryable_forms.push_back(form_structure);
1900 1872
1901 AutofillMetrics::LogParseFormTiming(base::TimeTicks::Now() - 1873 AutofillMetrics::LogParseFormTiming(base::TimeTicks::Now() -
1902 parse_form_start_time); 1874 parse_form_start_time);
1903 } 1875 }
1904 1876
1905 if (!queryable_forms.empty() && download_manager_) { 1877 if (!queryable_forms.empty() && download_manager_) {
1906 // Query the server if at least one of the forms was parsed. 1878 // Query the server if at least one of the forms was parsed.
1907 download_manager_->StartQueryRequest(queryable_forms); 1879 download_manager_->StartQueryRequest(queryable_forms);
1908 } 1880 }
1909 1881
(...skipping 21 matching lines...) Expand all
1931 autofill_assistant_.ShowAssistForCreditCard(*cards.front()); 1903 autofill_assistant_.ShowAssistForCreditCard(*cards.front());
1932 } 1904 }
1933 #endif 1905 #endif
1934 1906
1935 // For the |non_queryable_forms|, we have all the field type info we're ever 1907 // For the |non_queryable_forms|, we have all the field type info we're ever
1936 // going to get about them. For the other forms, we'll wait until we get a 1908 // going to get about them. For the other forms, we'll wait until we get a
1937 // response from the server. 1909 // response from the server.
1938 driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms); 1910 driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms);
1939 } 1911 }
1940 1912
1913 bool AutofillManager::ParseForm(const FormData& form,
1914 FormStructure** parsed_form_structure) {
1915 DCHECK(parsed_form_structure);
1916 if (form_structures_.size() >= kMaxFormCacheSize)
1917 return false;
1918
1919 auto form_structure = base::MakeUnique<FormStructure>(form);
1920 form_structure->ParseFieldTypesFromAutocompleteAttributes();
1921 if (!form_structure->ShouldBeParsed())
1922 return false;
1923
1924 // Ownership is transferred to |form_structures_| which maintains it until
1925 // the manager is Reset() or destroyed. It is safe to use references below
1926 // as long as receivers don't take ownership.
1927 form_structures_.push_back(std::move(form_structure));
1928 *parsed_form_structure = form_structures_.back().get();
1929 (*parsed_form_structure)->DetermineHeuristicTypes();
1930 return true;
1931 }
1932
1941 int AutofillManager::BackendIDToInt(const std::string& backend_id) const { 1933 int AutofillManager::BackendIDToInt(const std::string& backend_id) const {
1942 if (!base::IsValidGUID(backend_id)) 1934 if (!base::IsValidGUID(backend_id))
1943 return 0; 1935 return 0;
1944 1936
1945 const auto found = backend_to_int_map_.find(backend_id); 1937 const auto found = backend_to_int_map_.find(backend_id);
1946 if (found == backend_to_int_map_.end()) { 1938 if (found == backend_to_int_map_.end()) {
1947 // Unknown one, make a new entry. 1939 // Unknown one, make a new entry.
1948 int int_id = backend_to_int_map_.size() + 1; 1940 int int_id = backend_to_int_map_.size() + 1;
1949 backend_to_int_map_[backend_id] = int_id; 1941 backend_to_int_map_[backend_id] = int_id;
1950 int_to_backend_map_[int_id] = backend_id; 1942 int_to_backend_map_[int_id] = backend_id;
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
2207 } 2199 }
2208 #endif // ENABLE_FORM_DEBUG_DUMP 2200 #endif // ENABLE_FORM_DEBUG_DUMP
2209 2201
2210 void AutofillManager::LogCardUploadDecisionUkm( 2202 void AutofillManager::LogCardUploadDecisionUkm(
2211 AutofillMetrics::CardUploadDecisionMetric upload_decision) { 2203 AutofillMetrics::CardUploadDecisionMetric upload_decision) {
2212 AutofillMetrics::LogCardUploadDecisionUkm( 2204 AutofillMetrics::LogCardUploadDecisionUkm(
2213 client_->GetUkmService(), pending_upload_request_url_, upload_decision); 2205 client_->GetUkmService(), pending_upload_request_url_, upload_decision);
2214 } 2206 }
2215 2207
2216 } // namespace autofill 2208 } // 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