autofill_agent.h revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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/content/renderer/form_cache.h"
17#include "components/autofill/content/renderer/page_click_listener.h"
18#include "components/autofill/core/common/forms_seen_state.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(
143      const std::vector<FormData>& form_data,
144      const std::vector<WebElementDescriptor>& click_elements_before_form_fill,
145      const std::vector<WebElementDescriptor>& click_elements_after_form_fill,
146      const WebElementDescriptor& element_descriptor);
147
148  // Called when |topmost_frame_| is supported for Autocheckout.
149  void OnAutocheckoutSupported();
150
151  // Called when clicking an Autocheckout proceed element fails to do anything.
152  void ClickFailed();
153
154  // Called in a posted task by textFieldDidChange() to work-around a WebKit bug
155  // http://bugs.webkit.org/show_bug.cgi?id=16976
156  void TextFieldDidChangeImpl(const WebKit::WebInputElement& element);
157
158  // Shows the autofill suggestions for |element|.
159  // This call is asynchronous and may or may not lead to the showing of a
160  // suggestion popup (no popup is shown if there are no available suggestions).
161  // |autofill_on_empty_values| specifies whether suggestions should be shown
162  // when |element| contains no text.
163  // |requires_caret_at_end| specifies whether suggestions should be shown when
164  // the caret is not after the last character in |element|.
165  // |display_warning_if_disabled| specifies whether a warning should be
166  // displayed to the user if Autofill has suggestions available, but cannot
167  // fill them because it is disabled (e.g. when trying to fill a credit card
168  // form on a non-secure website).
169  void ShowSuggestions(const WebKit::WebInputElement& element,
170                       bool autofill_on_empty_values,
171                       bool requires_caret_at_end,
172                       bool display_warning_if_disabled);
173
174  // Queries the browser for Autocomplete and Autofill suggestions for the given
175  // |element|.
176  void QueryAutofillSuggestions(const WebKit::WebInputElement& element,
177                                bool display_warning_if_disabled);
178
179  // Combines DataList suggestion entries with the autofill ones and show them
180  // to the user.
181  void CombineDataListEntriesAndShow(const WebKit::WebInputElement& element,
182                                     const std::vector<base::string16>& values,
183                                     const std::vector<base::string16>& labels,
184                                     const std::vector<base::string16>& icons,
185                                     const std::vector<int>& item_ids,
186                                     bool has_autofill_item);
187
188  // Sets the element value to reflect the selected |suggested_value|.
189  void AcceptDataListSuggestion(const base::string16& suggested_value);
190
191  // Queries the AutofillManager for form data for the form containing |node|.
192  // |value| is the current text in the field, and |unique_id| is the selected
193  // profile's unique ID.  |action| specifies whether to Fill or Preview the
194  // values returned from the AutofillManager.
195  void FillAutofillFormData(const WebKit::WebNode& node,
196                            int unique_id,
197                            AutofillAction action);
198
199  // Fills |form| and |field| with the FormData and FormField corresponding to
200  // |node|. Returns true if the data was found; and false otherwise.
201  bool FindFormAndFieldForNode(
202      const WebKit::WebNode& node,
203      FormData* form,
204      FormFieldData* field) WARN_UNUSED_RESULT;
205
206  // Set |node| to display the given |value|.
207  void SetNodeText(const base::string16& value, WebKit::WebInputElement* node);
208
209  // Hides any currently showing Autofill UI in the renderer or browser.
210  void HideAutofillUi();
211
212  // Hides any currently showing Autofill UI in the browser only.
213  void HideHostAutofillUi();
214
215  void MaybeSendDynamicFormsSeen();
216
217  // Send |AutofillHostMsg_MaybeShowAutocheckoutBubble| to browser if needed.
218  void MaybeShowAutocheckoutBubble();
219
220  FormCache form_cache_;
221
222  PasswordAutofillAgent* password_autofill_agent_;  // WEAK reference.
223
224  // The ID of the last request sent for form field Autofill.  Used to ignore
225  // out of date responses.
226  int autofill_query_id_;
227
228  // The element corresponding to the last request sent for form field Autofill.
229  WebKit::WebInputElement element_;
230
231  // The form element currently requesting an interactive autocomplete.
232  WebKit::WebFormElement in_flight_request_form_;
233
234  // All the form elements seen in the top frame.
235  std::vector<WebKit::WebFormElement> form_elements_;
236
237  // The action to take when receiving Autofill data from the AutofillManager.
238  AutofillAction autofill_action_;
239
240  // Pointer to the current topmost frame.  Used in autocheckout flows so
241  // elements can be clicked.
242  WebKit::WebFrame* topmost_frame_;
243
244  // Pointer to the WebView. Used to access page scale factor.
245  WebKit::WebView* web_view_;
246
247  // Should we display a warning if autofill is disabled?
248  bool display_warning_if_disabled_;
249
250  // Was the query node autofilled prior to previewing the form?
251  bool was_query_node_autofilled_;
252
253  // Have we already shown Autofill suggestions for the field the user is
254  // currently editing?  Used to keep track of state for metrics logging.
255  bool has_shown_autofill_popup_for_current_edit_;
256
257  // If true we just set the node text so we shouldn't show the popup.
258  bool did_set_node_text_;
259
260  // Watchdog timer for clicking in Autocheckout flows.
261  base::OneShotTimer<AutofillAgent> click_timer_;
262
263  // Used to signal that we need to watch for loading failures in an
264  // Autocheckout flow.
265  bool autocheckout_click_in_progress_;
266
267  // Whether or not |topmost_frame_| is whitelisted for Autocheckout.
268  bool is_autocheckout_supported_;
269
270  // Whether or not new forms/fields have been dynamically added
271  // since the last loaded forms were sent to the browser process.
272  bool has_new_forms_for_browser_;
273
274  // Whether or not to ignore text changes.  Useful for when we're committing
275  // a composition when we are defocusing the WebView and we don't want to
276  // trigger an autofill popup to show.
277  bool ignore_text_changes_;
278
279  // Timestamp of first time forms are seen.
280  base::TimeTicks forms_seen_timestamp_;
281
282  base::WeakPtrFactory<AutofillAgent> weak_ptr_factory_;
283
284  friend class PasswordAutofillAgentTest;
285  FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, FillFormElement);
286  FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, SendForms);
287  FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, SendDynamicForms);
288  FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, ShowAutofillWarning);
289  FRIEND_TEST_ALL_PREFIXES(PasswordAutofillAgentTest, WaitUsername);
290  FRIEND_TEST_ALL_PREFIXES(PasswordAutofillAgentTest, SuggestionAccept);
291  FRIEND_TEST_ALL_PREFIXES(PasswordAutofillAgentTest, SuggestionSelect);
292
293  DISALLOW_COPY_AND_ASSIGN(AutofillAgent);
294};
295
296}  // namespace autofill
297
298#endif  // COMPONENTS_AUTOFILL_CONTENT_RENDERER_AUTOFILL_AGENT_H_
299