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
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_STRUCTURE_H_
6 #define COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_STRUCTURE_H_
7 
8 #include <stddef.h>
9 
10 #include <map>
11 #include <memory>
12 #include <set>
13 #include <string>
14 #include <utility>
15 #include <vector>
16 
17 #include "base/gtest_prod_util.h"
18 #include "base/macros.h"
19 #include "base/optional.h"
20 #include "base/strings/string_piece.h"
21 #include "components/autofill/core/browser/autofill_field.h"
22 #include "components/autofill/core/browser/autofill_metrics.h"
23 #include "components/autofill/core/browser/autofill_type.h"
24 #include "components/autofill/core/browser/field_types.h"
25 #include "components/autofill/core/browser/form_types.h"
26 #include "components/autofill/core/browser/proto/api_v1.pb.h"
27 #include "components/autofill/core/common/mojom/autofill_types.mojom.h"
28 #include "components/autofill/core/common/renderer_id.h"
29 #include "url/gurl.h"
30 #include "url/origin.h"
31 
32 enum UploadRequired { UPLOAD_NOT_REQUIRED, UPLOAD_REQUIRED, USE_UPLOAD_RATES };
33 
34 namespace base {
35 class TimeTicks;
36 }
37 
38 namespace autofill {
39 
40 class LogBuffer;
41 class LogManager;
42 
43 // Password attributes (whether a password has special symbols, numeric, etc.)
44 enum class PasswordAttribute {
45   kHasLowercaseLetter,
46   kHasSpecialSymbol,
47   kPasswordAttributesCount
48 };
49 
50 // The structure of forms and fields, represented by their signatures, on a
51 // page. These are sequence containers to reflect their order in the DOM.
52 using FormAndFieldSignatures =
53     std::vector<std::pair<FormSignature, std::vector<FieldSignature>>>;
54 
55 struct FormData;
56 struct FormDataPredictions;
57 
58 class RandomizedEncoder;
59 
60 // FormStructure stores a single HTML form together with the values entered
61 // in the fields along with additional information needed by Autofill.
62 class FormStructure {
63  public:
64   explicit FormStructure(const FormData& form);
65   virtual ~FormStructure();
66 
67   // Runs several heuristics against the form fields to determine their possible
68   // types.
69   void DetermineHeuristicTypes(LogManager* log_manager = nullptr);
70 
71   // Encodes the proto |upload| request from this FormStructure, and stores
72   // the (single) FormSignature and the signatures of the fields to be uploaded
73   // in |encoded_signatures|.
74   // In some cases, a |login_form_signature| is included as part of the upload.
75   // This field is empty when sending upload requests for non-login forms.
76   bool EncodeUploadRequest(
77       const ServerFieldTypeSet& available_field_types,
78       bool form_was_autofilled,
79       const std::string& login_form_signature,
80       bool observed_submission,
81       autofill::AutofillUploadContents* upload,
82       std::vector<FormSignature>* encoded_signatures) const;
83 
84   // Encodes the proto |query| request for the list of |forms| and their fields
85   // that are valid. The queried FormSignatures and FieldSignatures are stored
86   // in |queried_form_signatures| in the same order as in |query|. In case
87   // multiple FormStructures have the same FormSignature, only the first one is
88   // included in |query| and |queried_form_signatures|.
89   static bool EncodeQueryRequest(
90       const std::vector<FormStructure*>& forms,
91       autofill::AutofillPageQueryRequest* query,
92       std::vector<FormSignature>* queried_form_signatures);
93 
94   // Parses `payload` as AutofillQueryResponse proto and calls
95   // ProcessQueryResponse().
96   static void ParseApiQueryResponse(
97       base::StringPiece payload,
98       const std::vector<FormStructure*>& forms,
99       const std::vector<FormSignature>& queried_form_signatures,
100       AutofillMetrics::FormInteractionsUkmLogger*);
101 
102   // Returns predictions using the details from the given |form_structures| and
103   // their fields' predicted types.
104   static std::vector<FormDataPredictions> GetFieldTypePredictions(
105       const std::vector<FormStructure*>& form_structures);
106 
107   // Returns whether sending autofill field metadata to the server is enabled.
108   static bool IsAutofillFieldMetadataEnabled();
109 
110   // Creates FormStructure that has bare minimum information for uploading
111   // votes, namely form and field signatures. Warning: do not use for Autofill
112   // code, since it is likely missing some fields.
113   static std::unique_ptr<FormStructure> CreateForPasswordManagerUpload(
114       FormSignature form_signature,
115       const std::vector<FieldSignature>& field_signatures);
116 
117   // Return the form signature as string.
118   std::string FormSignatureAsStr() const;
119 
120   // Runs a quick heuristic to rule out forms that are obviously not
121   // auto-fillable, like google/yahoo/msn search, etc.
122   bool IsAutofillable() const;
123 
124   // Returns whether |this| form represents a complete Credit Card form, which
125   // consists in having at least a credit card number field and an expiration
126   // field.
127   bool IsCompleteCreditCardForm() const;
128 
129   // Resets |autofill_count_| and counts the number of auto-fillable fields.
130   // This is used when we receive server data for form fields.  At that time,
131   // we may have more known fields than just the number of fields we matched
132   // heuristically.
133   void UpdateAutofillCount();
134 
135   // Returns true if this form matches the structural requirements for Autofill.
136   bool ShouldBeParsed(LogManager* log_manager = nullptr) const;
137 
138   // Returns true if heuristic autofill type detection should be attempted for
139   // this form.
140   bool ShouldRunHeuristics() const;
141 
142   // Returns true if we should query the crowd-sourcing server to determine this
143   // form's field types. If the form includes author-specified types, this will
144   // return false unless there are password fields in the form. If there are no
145   // password fields the assumption is that the author has expressed their
146   // intent and crowdsourced data should not be used to override this. Password
147   // fields are different because there is no way to specify password generation
148   // directly.
149   bool ShouldBeQueried() const;
150 
151   // Returns true if we should upload Autofill votes for this form to the
152   // crowd-sourcing server. It is not applied for Password Manager votes.
153   bool ShouldBeUploaded() const;
154 
155   // Sets the field types to be those set for |cached_form|.
156   void RetrieveFromCache(const FormStructure& cached_form,
157                          const bool should_keep_cached_value,
158                          const bool only_server_and_autofill_state);
159 
160   // Logs quality metrics for |this|, which should be a user-submitted form.
161   // This method should only be called after the possible field types have been
162   // set for each field.  |interaction_time| should be a timestamp corresponding
163   // to the user's first interaction with the form.  |submission_time| should be
164   // a timestamp corresponding to the form's submission. |observed_submission|
165   // indicates whether this method is called as a result of observing a
166   // submission event (otherwise, it may be that an upload was triggered after
167   // a form was unfocused or a navigation occurred).
168   // TODO(sebsg): We log more than quality metrics. Maybe rename or split
169   // function?
170   void LogQualityMetrics(
171       const base::TimeTicks& load_time,
172       const base::TimeTicks& interaction_time,
173       const base::TimeTicks& submission_time,
174       AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger,
175       bool did_show_suggestions,
176       bool observed_submission) const;
177 
178   // Log the quality of the heuristics and server predictions for this form
179   // structure, if autocomplete attributes are present on the fields (they are
180   // used as golden truths).
181   void LogQualityMetricsBasedOnAutocomplete(
182       AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger)
183       const;
184 
185   // Classifies each field in |fields_| based upon its |autocomplete| attribute,
186   // if the attribute is available.  The association is stored into the field's
187   // |heuristic_type|.
188   // Fills |has_author_specified_types_| with |true| if the attribute is
189   // available and neither empty nor set to the special values "on" or "off" for
190   // at least one field.
191   // Fills |has_author_specified_sections_| with |true| if the attribute
192   // specifies a section for at least one field.
193   void ParseFieldTypesFromAutocompleteAttributes();
194 
195   // Returns the values that can be filled into the form structure for the
196   // given type. For example, there's no way to fill in a value of "The Moon"
197   // into ADDRESS_HOME_STATE if the form only has a
198   // <select autocomplete="region"> with no "The Moon" option. Returns an
199   // empty set if the form doesn't reference the given type or if all inputs
200   // are accepted (e.g., <input type="text" autocomplete="region">).
201   // All returned values are standardized to upper case.
202   std::set<base::string16> PossibleValues(ServerFieldType type);
203 
204   // Rationalize phone number fields in a given section, that is only fill
205   // the fields that are considered composing a first complete phone number.
206   void RationalizePhoneNumbersInSection(std::string section);
207 
208   // Overrides server predictions with specific heuristic predictions:
209   // * NAME_LAST_SECOND heuristic predictions are unconditionally used.
210   void OverrideServerPredictionsWithHeuristics();
211 
212   const AutofillField* field(size_t index) const;
213   AutofillField* field(size_t index);
214   size_t field_count() const;
215 
216   // Returns the number of fields that are part of the form signature and that
217   // are included in queries to the Autofill server.
218   size_t active_field_count() const;
219 
220   // Returns the number of fields that are able to be autofilled.
autofill_count()221   size_t autofill_count() const { return autofill_count_; }
222 
223   // Used for iterating over the fields.
begin()224   std::vector<std::unique_ptr<AutofillField>>::const_iterator begin() const {
225     return fields_.begin();
226   }
end()227   std::vector<std::unique_ptr<AutofillField>>::const_iterator end() const {
228     return fields_.end();
229   }
230 
form_name()231   const base::string16& form_name() const { return form_name_; }
232 
id_attribute()233   const base::string16& id_attribute() const { return id_attribute_; }
234 
name_attribute()235   const base::string16& name_attribute() const { return name_attribute_; }
236 
source_url()237   const GURL& source_url() const { return source_url_; }
238 
full_source_url()239   const GURL& full_source_url() const { return full_source_url_; }
240 
target_url()241   const GURL& target_url() const { return target_url_; }
242 
main_frame_origin()243   const url::Origin& main_frame_origin() const { return main_frame_origin_; }
244 
button_titles()245   const ButtonTitleList& button_titles() const { return button_titles_; }
246 
has_author_specified_types()247   bool has_author_specified_types() const {
248     return has_author_specified_types_;
249   }
250 
has_author_specified_upi_vpa_hint()251   bool has_author_specified_upi_vpa_hint() const {
252     return has_author_specified_upi_vpa_hint_;
253   }
254 
has_password_field()255   bool has_password_field() const { return has_password_field_; }
256 
is_form_tag()257   bool is_form_tag() const { return is_form_tag_; }
258 
set_submission_event(mojom::SubmissionIndicatorEvent submission_event)259   void set_submission_event(mojom::SubmissionIndicatorEvent submission_event) {
260     submission_event_ = submission_event;
261   }
262 
set_upload_required(UploadRequired required)263   void set_upload_required(UploadRequired required) {
264     upload_required_ = required;
265   }
upload_required()266   UploadRequired upload_required() const { return upload_required_; }
267 
form_parsed_timestamp()268   base::TimeTicks form_parsed_timestamp() const {
269     return form_parsed_timestamp_;
270   }
271 
all_fields_are_passwords()272   bool all_fields_are_passwords() const { return all_fields_are_passwords_; }
273 
form_signature()274   const FormSignature form_signature() const { return form_signature_; }
275 
set_form_signature(FormSignature signature)276   void set_form_signature(FormSignature signature) {
277     form_signature_ = signature;
278   }
279 
280   // Returns a FormData containing the data this form structure knows about.
281   FormData ToFormData() const;
282 
283   // Returns the possible form types.
284   std::set<FormType> GetFormTypes() const;
285 
passwords_were_revealed()286   bool passwords_were_revealed() const { return passwords_were_revealed_; }
set_passwords_were_revealed(bool passwords_were_revealed)287   void set_passwords_were_revealed(bool passwords_were_revealed) {
288     passwords_were_revealed_ = passwords_were_revealed;
289   }
290 
set_password_attributes_vote(const std::pair<PasswordAttribute,bool> & vote)291   void set_password_attributes_vote(
292       const std::pair<PasswordAttribute, bool>& vote) {
293     password_attributes_vote_ = vote;
294   }
295 
296   base::Optional<std::pair<PasswordAttribute, bool>>
get_password_attributes_vote()297   get_password_attributes_vote() const {
298     return password_attributes_vote_;
299   }
300 
set_password_length_vote(const size_t noisified_password_length)301   void set_password_length_vote(const size_t noisified_password_length) {
302     DCHECK(password_attributes_vote_.has_value())
303         << "|password_length_vote_| doesn't make sense if "
304            "|password_attributes_vote_| has no value.";
305     password_length_vote_ = noisified_password_length;
306   }
307 
get_password_length_vote()308   size_t get_password_length_vote() const {
309     DCHECK(password_attributes_vote_.has_value())
310         << "|password_length_vote_| doesn't make sense if "
311            "|password_attributes_vote_| has no value.";
312     return password_length_vote_;
313   }
314 
315 #if defined(UNIT_TEST)
get_submission_event_for_testing()316   mojom::SubmissionIndicatorEvent get_submission_event_for_testing() const {
317     return submission_event_;
318   }
319 
320   // Identify sections for the |fields_| for testing purposes.
identify_sections_for_testing()321   void identify_sections_for_testing() {
322     ParseFieldTypesFromAutocompleteAttributes();
323     IdentifySections(has_author_specified_sections_);
324   }
325 
326   // Set the Overall field type for |fields_[field_index]| to |type| for testing
327   // purposes.
set_overall_field_type_for_testing(size_t field_index,ServerFieldType type)328   void set_overall_field_type_for_testing(size_t field_index,
329                                           ServerFieldType type) {
330     if (field_index < fields_.size() && type > 0 && type < MAX_VALID_FIELD_TYPE)
331       fields_[field_index]->set_heuristic_type(type);
332   }
333 #endif
334 
set_password_symbol_vote(int noisified_symbol)335   void set_password_symbol_vote(int noisified_symbol) {
336     DCHECK(password_attributes_vote_.has_value())
337         << "password_symbol_vote_| doesn't make sense if "
338            "|password_attributes_vote_| has no value.";
339     password_symbol_vote_ = noisified_symbol;
340   }
341 
get_password_symbol_vote()342   int get_password_symbol_vote() const {
343     DCHECK(password_attributes_vote_.has_value())
344         << "|password_symbol_vote_| doesn't make sense if "
345            "|password_attributes_vote_| has no value";
346     return password_symbol_vote_;
347   }
348 
submission_source()349   mojom::SubmissionSource submission_source() const {
350     return submission_source_;
351   }
set_submission_source(mojom::SubmissionSource submission_source)352   void set_submission_source(mojom::SubmissionSource submission_source) {
353     submission_source_ = submission_source;
354   }
355 
356   // Returns an identifier that is used by the refill logic. Takes the first non
357   // empty of these or returns an empty string:
358   // - Form name
359   // - Name for Autofill of first field
360   base::string16 GetIdentifierForRefill() const;
361 
developer_engagement_metrics()362   int developer_engagement_metrics() { return developer_engagement_metrics_; }
363 
364   void set_randomized_encoder(std::unique_ptr<RandomizedEncoder> encoder);
365 
set_is_rich_query_enabled(bool v)366   void set_is_rich_query_enabled(bool v) { is_rich_query_enabled_ = v; }
367 
page_language()368   const std::string& page_language() const { return page_language_; }
369 
set_page_language(std::string language)370   void set_page_language(std::string language) {
371     page_language_ = std::move(language);
372   }
373 
value_from_dynamic_change_form()374   bool value_from_dynamic_change_form() const {
375     return value_from_dynamic_change_form_;
376   }
377 
set_value_from_dynamic_change_form(bool v)378   void set_value_from_dynamic_change_form(bool v) {
379     value_from_dynamic_change_form_ = v;
380   }
381 
unique_renderer_id()382   FormRendererId unique_renderer_id() const { return unique_renderer_id_; }
383 
ShouldSkipFieldVisibleForTesting(const FormFieldData & field)384   bool ShouldSkipFieldVisibleForTesting(const FormFieldData& field) const {
385     return ShouldSkipField(field);
386   }
387 
ProcessQueryResponseForTesting(const AutofillQueryResponse & response,const std::vector<FormStructure * > & forms,const std::vector<FormSignature> & queried_form_signatures,AutofillMetrics::FormInteractionsUkmLogger * form_interactions_ukm_logger)388   static void ProcessQueryResponseForTesting(
389       const AutofillQueryResponse& response,
390       const std::vector<FormStructure*>& forms,
391       const std::vector<FormSignature>& queried_form_signatures,
392       AutofillMetrics::FormInteractionsUkmLogger*
393           form_interactions_ukm_logger) {
394     ProcessQueryResponse(response, forms, queried_form_signatures,
395                          form_interactions_ukm_logger);
396   }
397 
398  private:
399   friend class AutofillMergeTest;
400   friend class FormStructureTestImpl;
401   friend class ParameterizedFormStructureTest;
402   FRIEND_TEST_ALL_PREFIXES(AutofillDownloadTest, QueryAndUploadTest);
403   FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl, FindLongestCommonPrefix);
404   FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl, FindLongestCommonAffixLength);
405   FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl, IsValidParseableName);
406   FRIEND_TEST_ALL_PREFIXES(ParameterizedFormStructureTest,
407                            RationalizePhoneNumber_RunsOncePerSection);
408 
409   class SectionedFieldsIndexes {
410    public:
411     SectionedFieldsIndexes();
412     ~SectionedFieldsIndexes();
413 
LastFieldIndex()414     size_t LastFieldIndex() const {
415       if (sectioned_indexes.empty())
416         return (size_t)-1;  // Shouldn't happen.
417       return sectioned_indexes.back().back();
418     }
419 
AddFieldIndex(const size_t index,bool is_new_section)420     void AddFieldIndex(const size_t index, bool is_new_section) {
421       if (is_new_section || Empty()) {
422         sectioned_indexes.push_back(std::vector<size_t>(1, index));
423         return;
424       }
425       sectioned_indexes.back().push_back(index);
426     }
427 
WalkForwardToTheNextSection()428     void WalkForwardToTheNextSection() { current_section_ptr++; }
429 
IsFinished()430     bool IsFinished() const {
431       return current_section_ptr >= sectioned_indexes.size();
432     }
433 
CurrentIndex()434     size_t CurrentIndex() const { return CurrentSection()[0]; }
435 
CurrentSection()436     std::vector<size_t> CurrentSection() const {
437       if (current_section_ptr < sectioned_indexes.size())
438         return sectioned_indexes[current_section_ptr];
439       return std::vector<size_t>(1, (size_t)-1);  // To handle edge cases.
440     }
441 
Reset()442     void Reset() { current_section_ptr = 0; }
443 
Empty()444     bool Empty() const { return sectioned_indexes.empty(); }
445 
446    private:
447     // A vector of sections. Each section is a vector of some of the indexes
448     // that belong to the same section. The sections and indexes are sorted by
449     // their order of appearance on the form.
450     std::vector<std::vector<size_t>> sectioned_indexes;
451     // Points to a vector of indexes that belong to the same section.
452     size_t current_section_ptr = 0;
453   };
454 
455   // Parses the field types from the server query response. |forms| must be the
456   // same as the one passed to EncodeQueryRequest when constructing the query.
457   // |form_interactions_ukm_logger| is used to provide logs to UKM and can be
458   // null in tests.
459   static void ProcessQueryResponse(
460       const AutofillQueryResponse& response,
461       const std::vector<FormStructure*>& forms,
462       const std::vector<FormSignature>& queried_form_signatures,
463       AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger);
464 
465   FormStructure(FormSignature form_signature,
466                 const std::vector<FieldSignature>& field_signatures);
467 
468   // A function to fine tune the credit cards related predictions. For example:
469   // lone credit card fields in an otherwise non-credit-card related form is
470   // unlikely to be correct, the function will override that prediction.
471   void RationalizeCreditCardFieldPredictions();
472 
473   // The rationalization is based on the visible fields, but should be applied
474   // to the hidden select fields. This is because hidden 'select' fields are
475   // also autofilled to take care of the synthetic fields.
476   void ApplyRationalizationsToHiddenSelects(
477       size_t field_index,
478       ServerFieldType new_type,
479       AutofillMetrics::FormInteractionsUkmLogger*);
480 
481   // Returns true if we can replace server predictions with the heuristics one.
482   bool HeuristicsPredictionsAreApplicable(size_t upper_index,
483                                           size_t lower_index,
484                                           ServerFieldType first_type,
485                                           ServerFieldType second_type);
486 
487   // Applies upper type to upper field, and lower type to lower field, and
488   // applies the rationalization also to hidden select fields if necessary.
489   void ApplyRationalizationsToFields(
490       size_t upper_index,
491       size_t lower_index,
492       ServerFieldType upper_type,
493       ServerFieldType lower_type,
494       AutofillMetrics::FormInteractionsUkmLogger*);
495 
496   // Returns true if the fields_[index] server type should be rationalized to
497   // ADDRESS_HOME_COUNTRY.
498   bool FieldShouldBeRationalizedToCountry(size_t index);
499 
500   // Set fields_[|field_index|] to |new_type| and log this change.
501   void ApplyRationalizationsToFieldAndLog(
502       size_t field_index,
503       ServerFieldType new_type,
504       AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger);
505 
506   // Two or three fields predicted as the whole address should be address lines
507   // 1, 2 and 3 instead.
508   void RationalizeAddressLineFields(
509       SectionedFieldsIndexes* sections_of_address_indexes,
510       AutofillMetrics::FormInteractionsUkmLogger*);
511 
512   // Rationalize state and country interdependently.
513   void RationalizeAddressStateCountry(
514       SectionedFieldsIndexes* sections_of_state_indexes,
515       SectionedFieldsIndexes* sections_of_country_indexes,
516       AutofillMetrics::FormInteractionsUkmLogger*);
517 
518   // Tunes the fields with identical predictions.
519   void RationalizeRepeatedFields(AutofillMetrics::FormInteractionsUkmLogger*);
520 
521   // Filters out fields that don't meet the relationship ruleset for their type
522   // defined in |type_relationships_rules_|.
523   void RationalizeTypeRelationships();
524 
525   // A helper function to review the predictions and do appropriate adjustments
526   // when it considers necessary.
527   void RationalizeFieldTypePredictions();
528 
529   void EncodeFormForQuery(
530       autofill::AutofillPageQueryRequest::Form* query_form,
531       std::vector<FormSignature>* queried_form_signatures) const;
532 
533   void EncodeFormForUpload(
534       autofill::AutofillUploadContents* upload,
535       std::vector<FormSignature>* encoded_signatures) const;
536 
537   // Returns true if the form has no fields, or too many.
538   bool IsMalformed() const;
539 
540   // Classifies each field in |fields_| into a logical section.
541   // Sections are identified by the heuristic (or by the heuristic and the
542   // autocomplete section attribute, if defined when feature flag
543   // kAutofillUseNewSectioningMethod is enabled) that a logical section should
544   // not include multiple fields of the same autofill type (with some
545   // exceptions, as described in the implementation). Credit card fields also,
546   // have a single separate section from address fields.
547   // If |has_author_specified_sections| is true, only the second pass --
548   // distinguishing credit card sections from non-credit card ones -- is made.
549   void IdentifySections(bool has_author_specified_sections);
550 
551   // Returns true if field should be skipped when talking to Autofill server.
552   bool ShouldSkipField(const FormFieldData& field) const;
553 
554   // Further processes the extracted |fields_|.
555   void ProcessExtractedFields();
556 
557   // Tries to set |parseable_name| fields by stripping the given offsets from
558   // both sides of the |name| fields.
559   // Sets |parseable_name| to |name| if the sum of offsets is bigger than
560   // |name|.
561   // Sets all |parseable_name| to |name| without modification and returns
562   // false if a name fails the |IsValidParseableName()| check after stripping.
563   bool SetStrippedParseableNames(size_t offset_left, size_t offset_right);
564 
565   // Returns true if |string| is a valid parseable_name. Current criterion
566   // is the |autofill::kParseableNameValidationRe| regex.
567   static bool IsValidParseableName(base::string16 string);
568 
569   // Returns the length of the longest common prefix found within |strings|
570   // if |findCommonSuffix| is false. Otherwise returns longest common suffix.
571   static size_t FindLongestCommonAffixLength(
572       const std::vector<base::StringPiece16>& strings,
573       bool findCommonSuffix = false);
574 
575   // Returns the longest common prefix found within |strings|. Strings below a
576   // threshold length defined by |kMinCommonNamePrefixLength| are excluded
577   // when performing this check; this is needed because an exceptional
578   // field may be missing a prefix which is otherwise consistently applied.
579   // For instance, a framework may only apply a prefix to those fields
580   // which are bound when POSTing.
581   //
582   // Soon to be replaced by FindLongestCommonPrefixLength
583   static base::string16 FindLongestCommonPrefix(
584       const std::vector<base::string16>& strings);
585 
586   // The language detected for this form's page, prior to any translations
587   // performed by Chrome.
588   std::string page_language_;
589 
590   // The id attribute of the form.
591   base::string16 id_attribute_;
592 
593   // The name attribute of the form.
594   base::string16 name_attribute_;
595 
596   // The name of the form.
597   base::string16 form_name_;
598 
599   // The titles of form's buttons.
600   ButtonTitleList button_titles_;
601 
602   // The type of the event that was taken as an indication that the form has
603   // been successfully submitted.
604   mojom::SubmissionIndicatorEvent submission_event_ =
605       mojom::SubmissionIndicatorEvent::NONE;
606 
607   // The source URL (excluding the query parameters and fragment identifiers).
608   GURL source_url_;
609 
610   // The full source URL including query parameters and fragment identifiers.
611   GURL full_source_url_;
612 
613   // The target URL.
614   GURL target_url_;
615 
616   // The origin of the main frame of this form.
617   url::Origin main_frame_origin_;
618 
619   // The number of fields able to be auto-filled.
620   size_t autofill_count_ = 0;
621 
622   // A vector of all the input fields in the form.
623   std::vector<std::unique_ptr<AutofillField>> fields_;
624 
625   // The number of fields that are part of the form signature and that are
626   // included in queries to the Autofill server.
627   size_t active_field_count_ = 0;
628 
629   // Whether the server expects us to always upload, never upload, or default
630   // to the stored upload rates.
631   UploadRequired upload_required_ = USE_UPLOAD_RATES;
632 
633   // Whether the form includes any field types explicitly specified by the site
634   // author, via the |autocompletetype| attribute.
635   bool has_author_specified_types_ = false;
636 
637   // Whether the form includes any sections explicitly specified by the site
638   // author, via the autocomplete attribute.
639   bool has_author_specified_sections_ = false;
640 
641   // Whether the form includes a field that explicitly sets it autocomplete
642   // type to "upi-vpa".
643   bool has_author_specified_upi_vpa_hint_ = false;
644 
645   // Whether the form was parsed for autocomplete attribute, thus assigning
646   // the real values of |has_author_specified_types_| and
647   // |has_author_specified_sections_|.
648   bool was_parsed_for_autocomplete_attributes_ = false;
649 
650   // True if the form contains at least one password field.
651   bool has_password_field_ = false;
652 
653   // True if the form is a <form>.
654   bool is_form_tag_ = true;
655 
656   // True if the form is made of unowned fields (i.e., not within a <form> tag)
657   // in what appears to be a checkout flow. This attribute is only calculated
658   // and used if features::kAutofillRestrictUnownedFieldsToFormlessCheckout is
659   // enabled, to prevent heuristics from running on formless non-checkout.
660   bool is_formless_checkout_ = false;
661 
662   // True if all form fields are password fields.
663   bool all_fields_are_passwords_ = false;
664 
665   // The unique signature for this form, composed of the target url domain,
666   // the form name, and the form field names in a 64-bit hash.
667   FormSignature form_signature_;
668 
669   // The timestamp (not wallclock time) when this form was initially parsed.
670   base::TimeTicks form_parsed_timestamp_;
671 
672   // If phone number rationalization has been performed for a given section.
673   std::map<std::string, bool> phone_rationalized_;
674 
675   // True iff the form is a password form and the user has seen the password
676   // value before accepting the prompt to save. Used for crowdsourcing.
677   bool passwords_were_revealed_ = false;
678 
679   // The vote about password attributes (e.g. whether the password has a numeric
680   // character).
681   base::Optional<std::pair<PasswordAttribute, bool>> password_attributes_vote_;
682 
683   // If |password_attribute_vote_| contains (kHasSpecialSymbol, true), this
684   // field contains nosified information about a special symbol in a
685   // user-created password stored as ASCII code. The default value of 0
686   // indicates that no symbol was set.
687   int password_symbol_vote_ = 0;
688 
689   // Noisified password length for crowdsourcing. If |password_attributes_vote_|
690   // has no value, |password_length_vote_| should be ignored.
691   size_t password_length_vote_;
692 
693   // Used to record whether developer has used autocomplete markup or
694   // UPI-VPA hints, This is a bitmask of DeveloperEngagementMetric and set in
695   // DetermineHeuristicTypes().
696   int developer_engagement_metrics_ = 0;
697 
698   mojom::SubmissionSource submission_source_ = mojom::SubmissionSource::NONE;
699 
700   // The randomized encoder to use to encode form metadata during upload.
701   // If this is nullptr, no randomized metadata will be sent.
702   std::unique_ptr<RandomizedEncoder> randomized_encoder_;
703 
704   // True iff queries encoded from this form structure should include rich
705   // form/field metadata.
706   bool is_rich_query_enabled_ = false;
707 
708   bool value_from_dynamic_change_form_ = false;
709 
710   FormRendererId unique_renderer_id_;
711 
712   DISALLOW_COPY_AND_ASSIGN(FormStructure);
713 };
714 
715 LogBuffer& operator<<(LogBuffer& buffer, const FormStructure& form);
716 std::ostream& operator<<(std::ostream& buffer, const FormStructure& form);
717 
718 }  // namespace autofill
719 
720 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_STRUCTURE_H_
721