1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/autofill/core/browser/autofill_handler.h"
6
7 #include "base/containers/adapters.h"
8 #include "components/autofill/core/browser/form_structure.h"
9 #include "components/autofill/core/browser/logging/log_manager.h"
10 #include "components/autofill/core/common/autofill_data_validation.h"
11 #include "components/autofill/core/common/autofill_internals/log_message.h"
12 #include "components/autofill/core/common/autofill_internals/logging_scope.h"
13 #include "components/autofill/core/common/autofill_payments_features.h"
14 #include "components/autofill/core/common/autofill_tick_clock.h"
15 #include "components/autofill/core/common/signatures_util.h"
16 #include "ui/gfx/geometry/rect_f.h"
17
18 namespace autofill {
19
20 namespace {
21
22 // Set a conservative upper bound on the number of forms we are willing to
23 // cache, simply to prevent unbounded memory consumption.
24 const size_t kAutofillHandlerMaxFormCacheSize = 100;
25
26 // Returns the AutofillField* corresponding to |field| in |form| or nullptr,
27 // if not found.
FindAutofillFillField(const FormStructure & form,const FormFieldData & field)28 AutofillField* FindAutofillFillField(const FormStructure& form,
29 const FormFieldData& field) {
30 for (const auto& cur_field : form) {
31 if (cur_field->SameFieldAs(field)) {
32 return cur_field.get();
33 }
34 }
35 return nullptr;
36 }
37
38 // Returns true if |live_form| does not match |cached_form|.
CachedFormNeedsUpdate(const FormData & live_form,const FormStructure & cached_form)39 bool CachedFormNeedsUpdate(const FormData& live_form,
40 const FormStructure& cached_form) {
41 if (live_form.fields.size() != cached_form.field_count())
42 return true;
43
44 for (size_t i = 0; i < cached_form.field_count(); ++i) {
45 if (!cached_form.field(i)->SameFieldAs(live_form.fields[i]))
46 return true;
47 }
48
49 return false;
50 }
51
52 } // namespace
53
54 using base::TimeTicks;
55
AutofillHandler(AutofillDriver * driver,LogManager * log_manager)56 AutofillHandler::AutofillHandler(AutofillDriver* driver,
57 LogManager* log_manager)
58 : driver_(driver), log_manager_(log_manager) {}
59
60 AutofillHandler::~AutofillHandler() = default;
61
OnFormSubmitted(const FormData & form,bool known_success,mojom::SubmissionSource source)62 void AutofillHandler::OnFormSubmitted(const FormData& form,
63 bool known_success,
64 mojom::SubmissionSource source) {
65 if (IsValidFormData(form))
66 OnFormSubmittedImpl(form, known_success, source);
67 }
68
OnFormsSeen(const std::vector<FormData> & forms,const base::TimeTicks timestamp)69 void AutofillHandler::OnFormsSeen(const std::vector<FormData>& forms,
70 const base::TimeTicks timestamp) {
71 if (!IsValidFormDataVector(forms) || !driver_->RendererIsAvailable())
72 return;
73
74 // This should be called even forms is empty, AutofillProviderAndroid uses
75 // this event to detect form submission.
76 if (!ShouldParseForms(forms, timestamp))
77 return;
78
79 if (forms.empty())
80 return;
81
82 // Parse each of the forms. Because parsing a given FormData may invalidate
83 // and replace a form parsed before it (invalidating any pointers we might
84 // hold) we track the newly created form signatures instead of remembering
85 // the pointer values.
86 std::set<FormSignature> new_form_signatures;
87 for (const FormData& form : forms) {
88 const auto parse_form_start_time = AutofillTickClock::NowTicks();
89 FormStructure* cached_form_structure = nullptr;
90 FormStructure* form_structure = nullptr;
91 // Try to find the FormStructure that corresponds to |form| if the form
92 // contains credit card fields only.
93 // |cached_form_structure| may still be nullptr after this call.
94 ignore_result(FindCachedForm(form, &cached_form_structure));
95 if (cached_form_structure) {
96 for (const FormType& form_type : cached_form_structure->GetFormTypes()) {
97 if (form_type != CREDIT_CARD_FORM) {
98 cached_form_structure = nullptr;
99 break;
100 }
101 }
102 }
103
104 if (!ParseForm(form, cached_form_structure, &form_structure))
105 continue;
106 DCHECK(form_structure);
107 new_form_signatures.insert(form_structure->form_signature());
108 AutofillMetrics::LogParseFormTiming(AutofillTickClock::NowTicks() -
109 parse_form_start_time);
110 }
111
112 if (new_form_signatures.empty())
113 return;
114
115 // Populate the set of newly created form structures and call the
116 // OnFormsParsed handler.
117 std::vector<FormStructure*> new_form_structures;
118 new_form_structures.reserve(new_form_signatures.size());
119 for (auto signature : new_form_signatures) {
120 FormStructure* form_structure = nullptr;
121 if (FindCachedForm(signature, &form_structure) && form_structure) {
122 new_form_structures.push_back(form_structure);
123 } else {
124 NOTREACHED();
125 }
126 }
127 OnFormsParsed(new_form_structures, timestamp);
128 }
129
OnTextFieldDidChange(const FormData & form,const FormFieldData & field,const gfx::RectF & bounding_box,const TimeTicks timestamp)130 void AutofillHandler::OnTextFieldDidChange(const FormData& form,
131 const FormFieldData& field,
132 const gfx::RectF& bounding_box,
133 const TimeTicks timestamp) {
134 if (!IsValidFormData(form) || !IsValidFormFieldData(field))
135 return;
136
137 gfx::RectF transformed_box =
138 driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
139
140 OnTextFieldDidChangeImpl(form, field, transformed_box, timestamp);
141 }
142
OnTextFieldDidScroll(const FormData & form,const FormFieldData & field,const gfx::RectF & bounding_box)143 void AutofillHandler::OnTextFieldDidScroll(const FormData& form,
144 const FormFieldData& field,
145 const gfx::RectF& bounding_box) {
146 if (!IsValidFormData(form) || !IsValidFormFieldData(field))
147 return;
148
149 gfx::RectF transformed_box =
150 driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
151
152 OnTextFieldDidScrollImpl(form, field, transformed_box);
153 }
154
OnSelectControlDidChange(const FormData & form,const FormFieldData & field,const gfx::RectF & bounding_box)155 void AutofillHandler::OnSelectControlDidChange(const FormData& form,
156 const FormFieldData& field,
157 const gfx::RectF& bounding_box) {
158 if (!IsValidFormData(form) || !IsValidFormFieldData(field))
159 return;
160
161 gfx::RectF transformed_box =
162 driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
163
164 OnSelectControlDidChangeImpl(form, field, transformed_box);
165 }
166
OnQueryFormFieldAutofill(int query_id,const FormData & form,const FormFieldData & field,const gfx::RectF & bounding_box,bool autoselect_first_suggestion)167 void AutofillHandler::OnQueryFormFieldAutofill(
168 int query_id,
169 const FormData& form,
170 const FormFieldData& field,
171 const gfx::RectF& bounding_box,
172 bool autoselect_first_suggestion) {
173 if (!IsValidFormData(form) || !IsValidFormFieldData(field))
174 return;
175
176 gfx::RectF transformed_box =
177 driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
178
179 OnQueryFormFieldAutofillImpl(query_id, form, field, transformed_box,
180 autoselect_first_suggestion);
181 }
182
OnFocusOnFormField(const FormData & form,const FormFieldData & field,const gfx::RectF & bounding_box)183 void AutofillHandler::OnFocusOnFormField(const FormData& form,
184 const FormFieldData& field,
185 const gfx::RectF& bounding_box) {
186 if (!IsValidFormData(form) || !IsValidFormFieldData(field))
187 return;
188
189 gfx::RectF transformed_box =
190 driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
191
192 OnFocusOnFormFieldImpl(form, field, transformed_box);
193 }
194
SendFormDataToRenderer(int query_id,AutofillDriver::RendererFormDataAction action,const FormData & data)195 void AutofillHandler::SendFormDataToRenderer(
196 int query_id,
197 AutofillDriver::RendererFormDataAction action,
198 const FormData& data) {
199 driver_->SendFormDataToRenderer(query_id, action, data);
200 }
201
GetCachedFormAndField(const FormData & form,const FormFieldData & field,FormStructure ** form_structure,AutofillField ** autofill_field)202 bool AutofillHandler::GetCachedFormAndField(const FormData& form,
203 const FormFieldData& field,
204 FormStructure** form_structure,
205 AutofillField** autofill_field) {
206 // Maybe find an existing FormStructure that corresponds to |form|.
207 FormStructure* cached_form = nullptr;
208 if (FindCachedForm(form, &cached_form)) {
209 DCHECK(cached_form);
210 if (!CachedFormNeedsUpdate(form, *cached_form)) {
211 // There is no data to return if there are no auto-fillable fields.
212 if (!cached_form->autofill_count())
213 return false;
214
215 // Return the cached form and matching field, if any.
216 *form_structure = cached_form;
217 *autofill_field = FindAutofillFillField(**form_structure, field);
218 return *autofill_field != nullptr;
219 }
220 }
221
222 // The form is new or updated, parse it and discard |cached_form|.
223 // i.e., |cached_form| is no longer valid after this call.
224 if (!ParseForm(form, std::move(cached_form), form_structure))
225 return false;
226
227 // Annotate the updated form with its predicted types.
228 driver()->SendAutofillTypePredictionsToRenderer({*form_structure});
229
230 // There is no data to return if there are no auto-fillable fields.
231 if (!(*form_structure)->autofill_count())
232 return false;
233
234 // Find the AutofillField that corresponds to |field|.
235 *autofill_field = FindAutofillFillField(**form_structure, field);
236 return *autofill_field != nullptr;
237 }
238
FindCachedForm(FormSignature form_signature,FormStructure ** form_structure) const239 bool AutofillHandler::FindCachedForm(FormSignature form_signature,
240 FormStructure** form_structure) const {
241 auto it = form_structures_.find(form_signature);
242 if (it != form_structures_.end()) {
243 *form_structure = it->second.get();
244 return true;
245 }
246 return false;
247 }
248
FindCachedForm(const FormData & form,FormStructure ** form_structure) const249 bool AutofillHandler::FindCachedForm(const FormData& form,
250 FormStructure** form_structure) const {
251 // Find the FormStructure that corresponds to |form|.
252 if (FindCachedForm(autofill::CalculateFormSignature(form), form_structure))
253 return true;
254
255 // The form might have been modified by JavaScript which resulted in a change
256 // of form signature. Compare it to all the forms in the cache to look for a
257 // match.
258 for (const auto& it : form_structures_) {
259 if (*it.second == form) {
260 *form_structure = it.second.get();
261 return true;
262 }
263 }
264
265 *form_structure = nullptr;
266 return false;
267 }
268
ParseForm(const FormData & form,const FormStructure * cached_form,FormStructure ** parsed_form_structure)269 bool AutofillHandler::ParseForm(const FormData& form,
270 const FormStructure* cached_form,
271 FormStructure** parsed_form_structure) {
272 DCHECK(parsed_form_structure);
273 if (form_structures_.size() >= kAutofillHandlerMaxFormCacheSize) {
274 if (log_manager_) {
275 log_manager_->Log() << LoggingScope::kAbortParsing
276 << LogMessage::kAbortParsingTooManyForms << form;
277 }
278 return false;
279 }
280
281 auto form_structure = std::make_unique<FormStructure>(form);
282 form_structure->ParseFieldTypesFromAutocompleteAttributes();
283 if (!form_structure->ShouldBeParsed(log_manager_))
284 return false;
285
286 if (cached_form) {
287 // We need to keep the server data if available. We need to use them while
288 // determining the heuristics.
289 form_structure->RetrieveFromCache(*cached_form,
290 /*should_keep_cached_value=*/true,
291 /*only_server_and_autofill_state=*/true);
292 if (observer_for_testing_)
293 observer_for_testing_->OnFormParsed();
294
295 if (form_structure.get()->value_from_dynamic_change_form())
296 value_from_dynamic_change_form_ = true;
297 }
298
299 form_structure->DetermineHeuristicTypes(log_manager_);
300
301 // Hold the parsed_form_structure we intend to return. We can use this to
302 // reference the form_signature when transferring ownership below.
303 *parsed_form_structure = form_structure.get();
304
305 // Ownership is transferred to |form_structures_| which maintains it until
306 // the form is parsed again or the AutofillHandler is destroyed.
307 //
308 // Note that this insert/update takes ownership of the new form structure
309 // and also destroys the previously cached form structure.
310 form_structures_[(*parsed_form_structure)->form_signature()] =
311 std::move(form_structure);
312
313 return true;
314 }
315
Reset()316 void AutofillHandler::Reset() {
317 form_structures_.clear();
318 }
319
320 } // namespace autofill
321