autofill_agent.h revision 868fa2fe829687343ffae624259930155e16dbd8
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_CONTENT_RENDERER_AUTOFILL_AGENT_H_
6#define COMPONENTS_AUTOFILL_CONTENT_RENDERER_AUTOFILL_AGENT_H_
7
8#include <vector>
9
10#include "base/basictypes.h"
11#include "base/compiler_specific.h"
12#include "base/gtest_prod_util.h"
13#include "base/memory/weak_ptr.h"
14#include "base/time.h"
15#include "base/timer.h"
16#include "components/autofill/common/forms_seen_state.h"
17#include "components/autofill/content/renderer/form_cache.h"
18#include "components/autofill/content/renderer/page_click_listener.h"
19#include "content/public/renderer/render_view_observer.h"
20#include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h"
21#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h"
22#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
23
24namespace WebKit {
25class WebNode;
26class WebView;
27}
28
29namespace autofill {
30
31struct FormData;
32struct FormFieldData;
33struct WebElementDescriptor;
34class PasswordAutofillAgent;
35
36// AutofillAgent deals with Autofill related communications between WebKit and
37// the browser.  There is one AutofillAgent per RenderView.
38// This code was originally part of RenderView.
39// Note that Autofill encompasses:
40// - single text field suggestions, that we usually refer to as Autocomplete,
41// - password form fill, refered to as Password Autofill, and
42// - entire form fill based on one field entry, referred to as Form Autofill.
43
44class AutofillAgent : public content::RenderViewObserver,
45                      public PageClickListener,
46                      public WebKit::WebAutofillClient {
47 public:
48  // PasswordAutofillAgent is guaranteed to outlive AutofillAgent.
49  AutofillAgent(content::RenderView* render_view,
50                PasswordAutofillAgent* password_autofill_manager);
51  virtual ~AutofillAgent();
52
53 private:
54  enum AutofillAction {
55    AUTOFILL_NONE,     // No state set.
56    AUTOFILL_FILL,     // Fill the Autofill form data.
57    AUTOFILL_PREVIEW,  // Preview the Autofill form data.
58  };
59
60  // RenderView::Observer:
61  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
62  virtual void DidFinishDocumentLoad(WebKit::WebFrame* frame) OVERRIDE;
63  virtual void DidStartProvisionalLoad(WebKit::WebFrame* frame) OVERRIDE;
64  virtual void DidFailProvisionalLoad(
65      WebKit::WebFrame* frame,
66      const WebKit::WebURLError& error) OVERRIDE;
67  virtual void DidCommitProvisionalLoad(WebKit::WebFrame* frame,
68                                        bool is_new_navigation) OVERRIDE;
69  virtual void FrameDetached(WebKit::WebFrame* frame) OVERRIDE;
70  virtual void WillSubmitForm(WebKit::WebFrame* frame,
71                              const WebKit::WebFormElement& form) OVERRIDE;
72  virtual void ZoomLevelChanged() OVERRIDE;
73  virtual void DidChangeScrollOffset(WebKit::WebFrame* frame) OVERRIDE;
74  virtual void FocusedNodeChanged(const WebKit::WebNode& node) OVERRIDE;
75
76  // PageClickListener:
77  virtual void InputElementClicked(const WebKit::WebInputElement& element,
78                                   bool was_focused,
79                                   bool is_focused) OVERRIDE;
80  virtual void InputElementLostFocus() OVERRIDE;
81
82  // WebKit::WebAutofillClient:
83  virtual void didAcceptAutofillSuggestion(const WebKit::WebNode& node,
84                                           const WebKit::WebString& value,
85                                           const WebKit::WebString& label,
86                                           int item_id,
87                                           unsigned index) OVERRIDE;
88  virtual void didSelectAutofillSuggestion(const WebKit::WebNode& node,
89                                           const WebKit::WebString& value,
90                                           const WebKit::WebString& label,
91                                           int item_id) OVERRIDE;
92  virtual void didClearAutofillSelection(const WebKit::WebNode& node) OVERRIDE;
93  virtual void removeAutocompleteSuggestion(
94      const WebKit::WebString& name,
95      const WebKit::WebString& value) OVERRIDE;
96  virtual void textFieldDidEndEditing(
97      const WebKit::WebInputElement& element) OVERRIDE;
98  virtual void textFieldDidChange(
99      const WebKit::WebInputElement& element) OVERRIDE;
100  virtual void textFieldDidReceiveKeyDown(
101      const WebKit::WebInputElement& element,
102      const WebKit::WebKeyboardEvent& event) OVERRIDE;
103  virtual void didRequestAutocomplete(
104      WebKit::WebFrame* frame,
105      const WebKit::WebFormElement& form) OVERRIDE;
106  virtual void setIgnoreTextChanges(bool ignore) OVERRIDE;
107  virtual void didAssociateFormControls(
108      const WebKit::WebVector<WebKit::WebNode>& nodes) OVERRIDE;
109
110  void OnSuggestionsReturned(int query_id,
111                             const std::vector<base::string16>& values,
112                             const std::vector<base::string16>& labels,
113                             const std::vector<base::string16>& icons,
114                             const std::vector<int>& unique_ids);
115  void OnFormDataFilled(int query_id, const FormData& form);
116  void OnFieldTypePredictionsAvailable(
117      const std::vector<FormDataPredictions>& forms);
118
119  // For external Autofill selection.
120  void OnSetAutofillActionFill();
121  void OnClearForm();
122  void OnSetAutofillActionPreview();
123  void OnClearPreviewedForm();
124  void OnSetNodeText(const base::string16& value);
125  void OnAcceptDataListSuggestion(const base::string16& value);
126  void OnAcceptPasswordAutofillSuggestion(const base::string16& value);
127  void OnGetAllForms();
128
129  // Called when interactive autocomplete finishes.
130  void OnRequestAutocompleteResult(
131      WebKit::WebFormElement::AutocompleteResult result,
132      const FormData& form_data);
133
134  // Called when an autocomplete request succeeds or fails with the |result|.
135  void FinishAutocompleteRequest(
136      WebKit::WebFormElement::AutocompleteResult result);
137
138  // Called when the Autofill server hints that this page should be filled using
139  // Autocheckout. All the relevant form fields in |form_data| will be filled
140  // and then element specified by |element_descriptor| will be clicked to
141  // proceed to the next step of the form.
142  void OnFillFormsAndClick(const std::vector<FormData>& form_data,
143                           const WebElementDescriptor& element_descriptor);
144
145  // Called when |topmost_frame_| is supported for Autocheckout.
146  void OnAutocheckoutSupported();
147
148  // Called when clicking an Autocheckout proceed element fails to do anything.
149  void ClickFailed();
150
151  // Called in a posted task by textFieldDidChange() to work-around a WebKit bug
152  // http://bugs.webkit.org/show_bug.cgi?id=16976
153  void TextFieldDidChangeImpl(const WebKit::WebInputElement& element);
154
155  // Shows the autofill suggestions for |element|.
156  // This call is asynchronous and may or may not lead to the showing of a
157  // suggestion popup (no popup is shown if there are no available suggestions).
158  // |autofill_on_empty_values| specifies whether suggestions should be shown
159  // when |element| contains no text.
160  // |requires_caret_at_end| specifies whether suggestions should be shown when
161  // the caret is not after the last character in |element|.
162  // |display_warning_if_disabled| specifies whether a warning should be
163  // displayed to the user if Autofill has suggestions available, but cannot
164  // fill them because it is disabled (e.g. when trying to fill a credit card
165  // form on a non-secure website).
166  void ShowSuggestions(const WebKit::WebInputElement& element,
167                       bool autofill_on_empty_values,
168                       bool requires_caret_at_end,
169                       bool display_warning_if_disabled);
170
171  // Queries the browser for Autocomplete and Autofill suggestions for the given
172  // |element|.
173  void QueryAutofillSuggestions(const WebKit::WebInputElement& element,
174                                bool display_warning_if_disabled);
175
176  // Combines DataList suggestion entries with the autofill ones and show them
177  // to the user.
178  void CombineDataListEntriesAndShow(const WebKit::WebInputElement& element,
179                                     const std::vector<base::string16>& values,
180                                     const std::vector<base::string16>& labels,
181                                     const std::vector<base::string16>& icons,
182                                     const std::vector<int>& item_ids,
183                                     bool has_autofill_item);
184
185  // Sets the element value to reflect the selected |suggested_value|.
186  void AcceptDataListSuggestion(const base::string16& suggested_value);
187
188  // Queries the AutofillManager for form data for the form containing |node|.
189  // |value| is the current text in the field, and |unique_id| is the selected
190  // profile's unique ID.  |action| specifies whether to Fill or Preview the
191  // values returned from the AutofillManager.
192  void FillAutofillFormData(const WebKit::WebNode& node,
193                            int unique_id,
194                            AutofillAction action);
195
196  // Fills |form| and |field| with the FormData and FormField corresponding to
197  // |node|. Returns true if the data was found; and false otherwise.
198  bool FindFormAndFieldForNode(
199      const WebKit::WebNode& node,
200      FormData* form,
201      FormFieldData* field) WARN_UNUSED_RESULT;
202
203  // Set |node| to display the given |value|.
204  void SetNodeText(const base::string16& value, WebKit::WebInputElement* node);
205
206  // Hides any currently showing Autofill UI in the renderer or browser.
207  void HideAutofillUi();
208
209  // Hides any currently showing Autofill UI in the browser only.
210  void HideHostAutofillUi();
211
212  void MaybeSendDynamicFormsSeen();
213
214  // Send |AutofillHostMsg_MaybeShowAutocheckoutBubble| to browser if needed.
215  void MaybeShowAutocheckoutBubble();
216
217  FormCache form_cache_;
218
219  PasswordAutofillAgent* password_autofill_agent_;  // WEAK reference.
220
221  // The ID of the last request sent for form field Autofill.  Used to ignore
222  // out of date responses.
223  int autofill_query_id_;
224
225  // The element corresponding to the last request sent for form field Autofill.
226  WebKit::WebInputElement element_;
227
228  // The form element currently requesting an interactive autocomplete.
229  WebKit::WebFormElement in_flight_request_form_;
230
231  // All the form elements seen in the top frame.
232  std::vector<WebKit::WebFormElement> form_elements_;
233
234  // The action to take when receiving Autofill data from the AutofillManager.
235  AutofillAction autofill_action_;
236
237  // Pointer to the current topmost frame.  Used in autocheckout flows so
238  // elements can be clicked.
239  WebKit::WebFrame* topmost_frame_;
240
241  // Pointer to the WebView. Used to access page scale factor.
242  WebKit::WebView* web_view_;
243
244  // Should we display a warning if autofill is disabled?
245  bool display_warning_if_disabled_;
246
247  // Was the query node autofilled prior to previewing the form?
248  bool was_query_node_autofilled_;
249
250  // Have we already shown Autofill suggestions for the field the user is
251  // currently editing?  Used to keep track of state for metrics logging.
252  bool has_shown_autofill_popup_for_current_edit_;
253
254  // If true we just set the node text so we shouldn't show the popup.
255  bool did_set_node_text_;
256
257  // Watchdog timer for clicking in Autocheckout flows.
258  base::OneShotTimer<AutofillAgent> click_timer_;
259
260  // Used to signal that we need to watch for loading failures in an
261  // Autocheckout flow.
262  bool autocheckout_click_in_progress_;
263
264  // Whether or not |topmost_frame_| is whitelisted for Autocheckout.
265  bool is_autocheckout_supported_;
266
267  // Whether or not new forms/fields have been dynamically added
268  // since the last loaded forms were sent to the browser process.
269  bool has_new_forms_for_browser_;
270
271  // Whether or not to ignore text changes.  Useful for when we're committing
272  // a composition when we are defocusing the WebView and we don't want to
273  // trigger an autofill popup to show.
274  bool ignore_text_changes_;
275
276  // Timestamp of first time forms are seen.
277  base::TimeTicks forms_seen_timestamp_;
278
279  base::WeakPtrFactory<AutofillAgent> weak_ptr_factory_;
280
281  friend class PasswordAutofillAgentTest;
282  FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, FillFormElement);
283  FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, SendForms);
284  FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, SendDynamicForms);
285  FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, ShowAutofillWarning);
286  FRIEND_TEST_ALL_PREFIXES(PasswordAutofillAgentTest, WaitUsername);
287  FRIEND_TEST_ALL_PREFIXES(PasswordAutofillAgentTest, SuggestionAccept);
288  FRIEND_TEST_ALL_PREFIXES(PasswordAutofillAgentTest, SuggestionSelect);
289
290  DISALLOW_COPY_AND_ASSIGN(AutofillAgent);
291};
292
293}  // namespace autofill
294
295#endif  // COMPONENTS_AUTOFILL_CONTENT_RENDERER_AUTOFILL_AGENT_H_
296