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