blob: 9236246c18d25be7308a840148c3cb1f47dc1258 [file] [log] [blame]
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01001// 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"
Ben Murdocheb525c52013-07-10 11:40:50 +010014#include "base/time/time.h"
15#include "base/timer/timer.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010016#include "components/autofill/content/renderer/form_cache.h"
17#include "components/autofill/content/renderer/page_click_listener.h"
Ben Murdochca12bfa2013-07-23 11:17:05 +010018#include "components/autofill/core/common/autocheckout_status.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010019#include "components/autofill/core/common/forms_seen_state.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010020#include "content/public/renderer/render_view_observer.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010021#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"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010024
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:
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010084 virtual void didClearAutofillSelection(const WebKit::WebNode& node) OVERRIDE;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010085 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
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010099 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.
Torne (Richard Coles)5e3f23d2013-06-11 16:24:11 +0100126 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);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100131
132 // Called when |topmost_frame_| is supported for Autocheckout.
133 void OnAutocheckoutSupported();
134
Ben Murdochbb1529c2013-08-08 10:24:53 +0100135 // Called when the page is actually shown in the browser, as opposed to simply
136 // being preloaded.
137 void OnPageShown();
138
Ben Murdochca12bfa2013-07-23 11:17:05 +0100139 // Called when an Autocheckout page is completed by the renderer.
140 void CompleteAutocheckoutPage(autofill::AutocheckoutStatus status);
141
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100142 // 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
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100170 // 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
Ben Murdochca12bfa2013-07-23 11:17:05 +0100191 // Hides any currently showing Autofill UI.
192 void HideAutofillUI();
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100193
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_