| Index: components/autofill/core/browser/autofill_manager.cc
|
| diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
|
| index 056793fe09bcc2edb95ba684a8204bdbcd5873cf..3b646f2afdcfa316aba2b12dac6af230c7f5b4cd 100644
|
| --- a/components/autofill/core/browser/autofill_manager.cc
|
| +++ b/components/autofill/core/browser/autofill_manager.cc
|
| @@ -60,6 +60,7 @@
|
| #include "components/autofill/core/common/form_data_predictions.h"
|
| #include "components/autofill/core/common/form_field_data.h"
|
| #include "components/autofill/core/common/password_form_fill_data.h"
|
| +#include "components/autofill/core/common/signatures_util.h"
|
| #include "components/pref_registry/pref_registry_syncable.h"
|
| #include "components/prefs/pref_service.h"
|
| #include "components/rappor/public/rappor_utils.h"
|
| @@ -1689,7 +1690,7 @@ std::unique_ptr<FormStructure> AutofillManager::ValidateSubmittedForm(
|
| if (!FindCachedForm(form, &cached_submitted_form))
|
| return std::unique_ptr<FormStructure>();
|
|
|
| - submitted_form->UpdateFromCache(*cached_submitted_form);
|
| + submitted_form->UpdateFromCache(*cached_submitted_form, false);
|
| return submitted_form;
|
| }
|
|
|
| @@ -1702,8 +1703,9 @@ bool AutofillManager::FindCachedForm(const FormData& form,
|
| // protocol with the crowdsourcing server does not permit us to discard the
|
| // original versions of the forms.
|
| *form_structure = NULL;
|
| + const auto& form_signature = autofill::CalculateFormSignature(form);
|
| for (auto& cur_form : base::Reversed(form_structures_)) {
|
| - if (*cur_form == form) {
|
| + if (cur_form->form_signature() == form_signature || *cur_form == form) {
|
| *form_structure = cur_form.get();
|
|
|
| // The same form might be cached with multiple field counts: in some
|
| @@ -1785,41 +1787,17 @@ bool AutofillManager::UpdateCachedForm(const FormData& live_form,
|
| if (!needs_update)
|
| return true;
|
|
|
| - if (form_structures_.size() >= kMaxFormCacheSize)
|
| + // Note: We _must not_ remove the original version of the cached form from
|
| + // the list of |form_structures_|. Otherwise, we break parsing of the
|
| + // crowdsourcing server's response to our query.
|
| + if (!ParseForm(live_form, updated_form))
|
| return false;
|
|
|
| - // Add the new or updated form to our cache.
|
| - form_structures_.push_back(base::MakeUnique<FormStructure>(live_form));
|
| - *updated_form = form_structures_.rbegin()->get();
|
| - (*updated_form)->DetermineHeuristicTypes();
|
| -
|
| - // If we have cached data, propagate it to the updated form.
|
| - if (cached_form) {
|
| - std::map<base::string16, const AutofillField*> cached_fields;
|
| - for (size_t i = 0; i < cached_form->field_count(); ++i) {
|
| - const AutofillField* field = cached_form->field(i);
|
| - cached_fields[field->unique_name()] = field;
|
| - }
|
| -
|
| - for (size_t i = 0; i < (*updated_form)->field_count(); ++i) {
|
| - AutofillField* field = (*updated_form)->field(i);
|
| - auto cached_field = cached_fields.find(field->unique_name());
|
| - if (cached_field != cached_fields.end()) {
|
| - field->set_server_type(cached_field->second->server_type());
|
| - field->is_autofilled = cached_field->second->is_autofilled;
|
| - field->set_previously_autofilled(
|
| - cached_field->second->previously_autofilled());
|
| - }
|
| - }
|
| -
|
| - // Note: We _must not_ remove the original version of the cached form from
|
| - // the list of |form_structures_|. Otherwise, we break parsing of the
|
| - // crowdsourcing server's response to our query.
|
| - }
|
| + if (cached_form)
|
| + (*updated_form)->UpdateFromCache(*cached_form, true);
|
|
|
| // Annotate the updated form with its predicted types.
|
| - std::vector<FormStructure*> forms(1, *updated_form);
|
| - driver_->SendAutofillTypePredictionsToRenderer(forms);
|
| + driver_->SendAutofillTypePredictionsToRenderer({*updated_form});
|
|
|
| return true;
|
| }
|
| @@ -1880,23 +1858,17 @@ void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
|
| for (const FormData& form : forms) {
|
| const auto parse_form_start_time = base::TimeTicks::Now();
|
|
|
| - std::unique_ptr<FormStructure> form_structure =
|
| - base::MakeUnique<FormStructure>(form);
|
| - form_structure->ParseFieldTypesFromAutocompleteAttributes();
|
| - if (!form_structure->ShouldBeParsed())
|
| + FormStructure* form_structure = nullptr;
|
| + if (!ParseForm(form, &form_structure))
|
| continue;
|
| + DCHECK(form_structure);
|
|
|
| - form_structure->DetermineHeuristicTypes();
|
| -
|
| - // Ownership is transferred to |form_structures_| which maintains it until
|
| - // the manager is Reset() or destroyed. It is safe to use references below
|
| - // as long as receivers don't take ownership.
|
| - form_structures_.push_back(std::move(form_structure));
|
| -
|
| - if (form_structures_.back()->ShouldBeCrowdsourced())
|
| - queryable_forms.push_back(form_structures_.back().get());
|
| + // Set aside forms with method GET or author-specified types, so that they
|
| + // are not included in the query to the server.
|
| + if (form_structure->ShouldBeCrowdsourced())
|
| + queryable_forms.push_back(form_structure);
|
| else
|
| - non_queryable_forms.push_back(form_structures_.back().get());
|
| + non_queryable_forms.push_back(form_structure);
|
|
|
| AutofillMetrics::LogParseFormTiming(base::TimeTicks::Now() -
|
| parse_form_start_time);
|
| @@ -1938,6 +1910,26 @@ void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
|
| driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms);
|
| }
|
|
|
| +bool AutofillManager::ParseForm(const FormData& form,
|
| + FormStructure** parsed_form_structure) {
|
| + DCHECK(parsed_form_structure);
|
| + if (form_structures_.size() >= kMaxFormCacheSize)
|
| + return false;
|
| +
|
| + auto form_structure = base::MakeUnique<FormStructure>(form);
|
| + form_structure->ParseFieldTypesFromAutocompleteAttributes();
|
| + if (!form_structure->ShouldBeParsed())
|
| + return false;
|
| +
|
| + // Ownership is transferred to |form_structures_| which maintains it until
|
| + // the manager is Reset() or destroyed. It is safe to use references below
|
| + // as long as receivers don't take ownership.
|
| + form_structures_.push_back(std::move(form_structure));
|
| + *parsed_form_structure = form_structures_.back().get();
|
| + (*parsed_form_structure)->DetermineHeuristicTypes();
|
| + return true;
|
| +}
|
| +
|
| int AutofillManager::BackendIDToInt(const std::string& backend_id) const {
|
| if (!base::IsValidGUID(backend_id))
|
| return 0;
|
|
|