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