summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autofill/form_structure.h
blob: 341bf19386ac98cd473ef3ab0ad2b8fa2efdbdad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_AUTOFILL_FORM_STRUCTURE_H_
#define CHROME_BROWSER_AUTOFILL_FORM_STRUCTURE_H_
#pragma once

#include <string>
#include <vector>

#include "base/memory/scoped_vector.h"
#include "chrome/browser/autofill/autofill_field.h"
#include "chrome/browser/autofill/autofill_type.h"
#include "chrome/browser/autofill/field_types.h"
#include "googleurl/src/gurl.h"
#include "webkit/glue/form_data.h"

namespace buzz {
  class XmlElement;
}  // namespace buzz

enum RequestMethod {
  GET,
  POST
};

enum UploadRequired {
  UPLOAD_NOT_REQUIRED,
  UPLOAD_REQUIRED,
  USE_UPLOAD_RATES
};

class AutofillMetrics;

// FormStructure stores a single HTML form together with the values entered
// in the fields along with additional information needed by Autofill.
class FormStructure {
 public:
  explicit FormStructure(const webkit_glue::FormData& form);
  virtual ~FormStructure();

  // Runs several heuristics against the form fields to determine their possible
  // types.
  void DetermineHeuristicTypes();

  // Encodes the XML upload request from this FormStructure.
  bool EncodeUploadRequest(bool autofill_used, std::string* encoded_xml) const;

  // Encodes the XML query request for the set of forms.
  // All fields are returned in one XML. For example, there are three forms,
  // with 2, 4, and 3 fields. The returned XML would have type info for 9
  // fields, first two of which would be for the first form, next 4 for the
  // second, and the rest is for the third.
  static bool EncodeQueryRequest(const ScopedVector<FormStructure>& forms,
                                 std::vector<std::string>* encoded_signatures,
                                 std::string* encoded_xml);

  // Parses the field types from the server query response. |forms| must be the
  // same as the one passed to EncodeQueryRequest when constructing the query.
  static void ParseQueryResponse(const std::string& response_xml,
                                 const std::vector<FormStructure*>& forms,
                                 UploadRequired* upload_required,
                                 const AutofillMetrics& metric_logger);

  // The unique signature for this form, composed of the target url domain,
  // the form name, and the form field names in a 64-bit hash.
  std::string FormSignature() const;

  // Runs a quick heuristic to rule out forms that are obviously not
  // auto-fillable, like google/yahoo/msn search, etc. The requirement that the
  // form's method be POST is only applied if |require_method_post| is true.
  bool IsAutofillable(bool require_method_post) const;

  // Resets |autofill_count_| and counts the number of auto-fillable fields.
  // This is used when we receive server data for form fields.  At that time,
  // we may have more known fields than just the number of fields we matched
  // heuristically.
  void UpdateAutofillCount();

  // Returns true if this form matches the structural requirements for Autofill.
  // The requirement that the form's method be POST is only applied if
  // |require_method_post| is true.
  bool ShouldBeParsed(bool require_method_post) const;

  // Sets the field types and experiment id to be those set for |cached_form|.
  void UpdateFromCache(const FormStructure& cached_form);

  // Logs quality metrics for |this|, which should be a user-submitted form.
  // This method should only be called after the possible field types have been
  // set for each field.
  void LogQualityMetrics(const AutofillMetrics& metric_logger) const;

  // Sets the possible types for the field at |index|.
  void set_possible_types(int index, const FieldTypeSet& types);

  const AutofillField* field(int index) const;
  size_t field_count() const;

  // Returns the number of fields that are able to be autofilled.
  size_t autofill_count() const { return autofill_count_; }

  // Used for iterating over the fields.
  std::vector<AutofillField*>::const_iterator begin() const {
    return fields_.begin();
  }
  std::vector<AutofillField*>::const_iterator end() const {
    return fields_.end();
  }

  const GURL& source_url() const { return source_url_; }

  virtual std::string server_experiment_id() const;

  bool operator==(const webkit_glue::FormData& form) const;
  bool operator!=(const webkit_glue::FormData& form) const;

 protected:
  // For tests.
  ScopedVector<AutofillField>* fields() { return &fields_; }

 private:
  friend class FormStructureTest;
  // 64-bit hash of the string - used in FormSignature and unit-tests.
  static std::string Hash64Bit(const std::string& str);

  enum EncodeRequestType {
    QUERY,
    UPLOAD,
  };

  // Associates the field with the heuristic type for each of the field views.
  void GetHeuristicFieldInfo(FieldTypeMap* field_types_map);

  // Adds form info to |encompassing_xml_element|. |request_type| indicates if
  // it is a query or upload.
  bool EncodeFormRequest(EncodeRequestType request_type,
                         buzz::XmlElement* encompassing_xml_element) const;

  // Helper for EncodeUploadRequest() that collects presense of all data in the
  // form structure and converts it to string for uploading.
  std::string ConvertPresenceBitsToString() const;

  // The name of the form.
  string16 form_name_;

  // The source URL.
  GURL source_url_;

  // The target URL.
  GURL target_url_;

  bool has_credit_card_field_;
  bool has_autofillable_field_;
  bool has_password_fields_;

  // The number of fields able to be auto-filled.
  size_t autofill_count_;

  // A vector of all the input fields in the form.  The vector is terminated by
  // a NULL entry.
  ScopedVector<AutofillField> fields_;

  // The names of the form input elements, that are part of the form signature.
  // The string starts with "&" and the names are also separated by the "&"
  // character. E.g.: "&form_input1_name&form_input2_name&...&form_inputN_name"
  std::string form_signature_field_names_;

  // The server experiment corresponding to the server types returned for this
  // form.
  std::string server_experiment_id_;

  // GET or POST.
  RequestMethod method_;

  DISALLOW_COPY_AND_ASSIGN(FormStructure);
};

#endif  // CHROME_BROWSER_AUTOFILL_FORM_STRUCTURE_H_