summaryrefslogtreecommitdiffstats
path: root/components/autofill/content/renderer/autofill_agent.h
blob: c75d5d6f443a51555e923adf712f5de57a76ed2a (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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
// Copyright 2013 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 COMPONENTS_AUTOFILL_CONTENT_RENDERER_AUTOFILL_AGENT_H_
#define COMPONENTS_AUTOFILL_CONTENT_RENDERER_AUTOFILL_AGENT_H_

#include <set>
#include <vector>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "components/autofill/content/renderer/form_cache.h"
#include "components/autofill/content/renderer/page_click_listener.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_view_observer.h"
#include "third_party/WebKit/public/web/WebAutofillClient.h"
#include "third_party/WebKit/public/web/WebFormControlElement.h"
#include "third_party/WebKit/public/web/WebFormElement.h"
#include "third_party/WebKit/public/web/WebInputElement.h"

namespace blink {
class WebNode;
class WebView;
}

namespace autofill {

struct FormData;
struct FormFieldData;
struct WebElementDescriptor;
class PasswordAutofillAgent;
class PasswordGenerationAgent;

// AutofillAgent deals with Autofill related communications between WebKit and
// the browser.  There is one AutofillAgent per RenderFrame.
// Note that Autofill encompasses:
// - single text field suggestions, that we usually refer to as Autocomplete,
// - password form fill, refered to as Password Autofill, and
// - entire form fill based on one field entry, referred to as Form Autofill.

class AutofillAgent : public content::RenderFrameObserver,
                      public PageClickListener,
                      public blink::WebAutofillClient {
 public:
  // PasswordAutofillAgent is guaranteed to outlive AutofillAgent.
  // PasswordGenerationAgent may be NULL. If it is not, then it is also
  // guaranteed to outlive AutofillAgent.
  AutofillAgent(content::RenderFrame* render_frame,
                PasswordAutofillAgent* password_autofill_manager,
                PasswordGenerationAgent* password_generation_agent);
  virtual ~AutofillAgent();

 private:
  // Functor used as a simplified comparison function for FormData.
  struct FormDataCompare {
    bool operator()(const FormData& lhs, const FormData& rhs) const;
  };

  // Thunk class for RenderViewObserver methods that haven't yet been migrated
  // to RenderFrameObserver. Should eventually be removed.
  // http://crbug.com/433486
  class LegacyAutofillAgent : public content::RenderViewObserver {
   public:
    LegacyAutofillAgent(content::RenderView* render_view, AutofillAgent* agent);
    ~LegacyAutofillAgent() override;

   private:
    // content::RenderViewObserver:
    void OnDestruct() override;
    void FocusChangeComplete() override;

    AutofillAgent* agent_;

    DISALLOW_COPY_AND_ASSIGN(LegacyAutofillAgent);
  };
  friend class LegacyAutofillAgent;

  // Flags passed to ShowSuggestions.
  struct ShowSuggestionsOptions {
    // All fields are default initialized to false.
    ShowSuggestionsOptions();

    // Specifies that suggestions should be shown when |element| contains no
    // text.
    bool autofill_on_empty_values;

    // Specifies that suggestions should be shown when the caret is not
    // after the last character in the element.
    bool requires_caret_at_end;

    // Specifies that all of <datalist> suggestions and no autofill suggestions
    // are shown. |autofill_on_empty_values| and |requires_caret_at_end| are
    // ignored if |datalist_only| is true.
    bool datalist_only;

    // Specifies that all autofill suggestions should be shown and none should
    // be elided because of the current value of |element| (relevant for inline
    // autocomplete).
    bool show_full_suggestion_list;

    // Specifies that only show a suggestions box if |element| is part of a
    // password form, otherwise show no suggestions.
    bool show_password_suggestions_only;
  };

  // content::RenderFrameObserver:
  bool OnMessageReceived(const IPC::Message& message) override;
  void DidCommitProvisionalLoad(bool is_new_navigation,
                                bool is_same_page_navigation) override;
  void DidFinishDocumentLoad() override;
  void WillSendSubmitEvent(const blink::WebFormElement& form) override;
  void WillSubmitForm(const blink::WebFormElement& form) override;
  void DidChangeScrollOffset() override;
  void FocusedNodeChanged(const blink::WebNode& node) override;

  // Pass-through from LegacyAutofillAgent. This correlates with the
  // RenderViewObserver method.
  void FocusChangeComplete();

  // PageClickListener:
  void FormControlElementClicked(const blink::WebFormControlElement& element,
                                 bool was_focused) override;

  // blink::WebAutofillClient:
  virtual void textFieldDidEndEditing(
      const blink::WebInputElement& element);
  virtual void textFieldDidChange(
      const blink::WebFormControlElement& element);
  virtual void textFieldDidReceiveKeyDown(
      const blink::WebInputElement& element,
      const blink::WebKeyboardEvent& event);
  virtual void didRequestAutocomplete(
      const blink::WebFormElement& form);
  virtual void setIgnoreTextChanges(bool ignore);
  virtual void didAssociateFormControls(
      const blink::WebVector<blink::WebNode>& nodes);
  virtual void openTextDataListChooser(const blink::WebInputElement& element);
  virtual void dataListOptionsChanged(const blink::WebInputElement& element);
  virtual void firstUserGestureObserved();
  virtual void xhrSucceeded();

  void OnFieldTypePredictionsAvailable(
      const std::vector<FormDataPredictions>& forms);
  void OnFillForm(int query_id, const FormData& form);
  void OnFirstUserGestureObservedInTab();
  void OnPing();
  void OnPreviewForm(int query_id, const FormData& form);

  // For external Autofill selection.
  void OnClearForm();
  void OnClearPreviewedForm();
  void OnFillFieldWithValue(const base::string16& value);
  void OnPreviewFieldWithValue(const base::string16& value);
  void OnAcceptDataListSuggestion(const base::string16& value);
  void OnFillPasswordSuggestion(const base::string16& username,
                                const base::string16& password);
  void OnPreviewPasswordSuggestion(const base::string16& username,
                                   const base::string16& password);

  // Called when interactive autocomplete finishes. |message| is printed to
  // the console if non-empty.
  void OnRequestAutocompleteResult(
      blink::WebFormElement::AutocompleteResult result,
      const base::string16& message,
      const FormData& form_data);

  // Called when an autocomplete request succeeds or fails with the |result|.
  void FinishAutocompleteRequest(
      blink::WebFormElement::AutocompleteResult result);

  // Called in a posted task by textFieldDidChange() to work-around a WebKit bug
  // http://bugs.webkit.org/show_bug.cgi?id=16976
  void TextFieldDidChangeImpl(const blink::WebFormControlElement& element);

  // Shows the autofill suggestions for |element|. This call is asynchronous
  // and may or may not lead to the showing of a suggestion popup (no popup is
  // shown if there are no available suggestions).
  void ShowSuggestions(const blink::WebFormControlElement& element,
                       const ShowSuggestionsOptions& options);

  // Queries the browser for Autocomplete and Autofill suggestions for the given
  // |element|.
  void QueryAutofillSuggestions(const blink::WebFormControlElement& element,
                                bool datalist_only);

  // Sets the element value to reflect the selected |suggested_value|.
  void AcceptDataListSuggestion(const base::string16& suggested_value);

  // Fills |form| and |field| with the FormData and FormField corresponding to
  // |node|. Returns true if the data was found; and false otherwise.
  bool FindFormAndFieldForNode(
      const blink::WebNode& node,
      FormData* form,
      FormFieldData* field) WARN_UNUSED_RESULT;

  // Set |node| to display the given |value|.
  void FillFieldWithValue(const base::string16& value,
                          blink::WebInputElement* node);

  // Set |node| to display the given |value| as a preview.  The preview is
  // visible on screen to the user, but not visible to the page via the DOM or
  // JavaScript.
  void PreviewFieldWithValue(const base::string16& value,
                             blink::WebInputElement* node);

  // Notifies browser of new fillable forms in |render_frame|.
  void ProcessForms();

  // Sends a message to the browser that the form is about to be submitted,
  // only if the particular message has not been previously submitted for the
  // form in the current frame.
  // Additionally, depending on |send_submitted_event| a message is sent to the
  // browser that the form was submitted.
  void SendFormEvents(const blink::WebFormElement& form,
                      bool send_submitted_event);

  // Hides any currently showing Autofill popup.
  void HidePopup();

  // Returns true if the text field change is due to a user gesture. Can be
  // overriden in tests.
  virtual bool IsUserGesture() const;

  // Formerly cached forms for all frames, now only caches forms for the current
  // frame.
  FormCache form_cache_;

  // Keeps track of the forms for which a "will submit" message has been sent in
  // this frame's current load. We use a simplified comparison function.
  std::set<FormData, FormDataCompare> submitted_forms_;

  PasswordAutofillAgent* password_autofill_agent_;  // Weak reference.
  PasswordGenerationAgent* password_generation_agent_;  // Weak reference.

  // Passes through RenderViewObserver methods to |this|.
  LegacyAutofillAgent legacy_;

  // The ID of the last request sent for form field Autofill.  Used to ignore
  // out of date responses.
  int autofill_query_id_;

  // The element corresponding to the last request sent for form field Autofill.
  blink::WebFormControlElement element_;

  // The form element currently requesting an interactive autocomplete.
  blink::WebFormElement in_flight_request_form_;

  // Was the query node autofilled prior to previewing the form?
  bool was_query_node_autofilled_;

  // Have we already shown Autofill suggestions for the field the user is
  // currently editing?  Used to keep track of state for metrics logging.
  bool has_shown_autofill_popup_for_current_edit_;

  // Whether or not to ignore text changes.  Useful for when we're committing
  // a composition when we are defocusing the WebView and we don't want to
  // trigger an autofill popup to show.
  bool ignore_text_changes_;

  // Whether the Autofill popup is possibly visible.  This is tracked as a
  // performance improvement, so that the IPC channel isn't flooded with
  // messages to close the Autofill popup when it can't possibly be showing.
  bool is_popup_possibly_visible_;

  base::WeakPtrFactory<AutofillAgent> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(AutofillAgent);
};

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_CONTENT_RENDERER_AUTOFILL_AGENT_H_