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