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.
5 #ifndef COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_AUTOFILL_AGENT_H_
6 #define COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_AUTOFILL_AGENT_H_
11 #include "base/gtest_prod_util.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "components/autofill/content/renderer/password_form_conversion_utils.h"
15 #include "components/autofill/core/common/form_data_predictions.h"
16 #include "components/autofill/core/common/password_form_field_prediction_map.h"
17 #include "components/autofill/core/common/password_form_fill_data.h"
18 #include "content/public/renderer/render_frame_observer.h"
19 #include "content/public/renderer/render_view_observer.h"
20 #include "third_party/WebKit/public/web/WebInputElement.h"
23 class WebInputElement
;
24 class WebKeyboardEvent
;
25 class WebSecurityOrigin
;
30 // This class is responsible for filling password forms.
31 class PasswordAutofillAgent
: public content::RenderFrameObserver
{
33 explicit PasswordAutofillAgent(content::RenderFrame
* render_frame
);
34 ~PasswordAutofillAgent() override
;
36 // WebFrameClient editor related calls forwarded by AutofillAgent.
37 // If they return true, it indicates the event was consumed and should not
38 // be used for any other autofill activity.
39 bool TextFieldDidEndEditing(const blink::WebInputElement
& element
);
40 bool TextDidChangeInTextField(const blink::WebInputElement
& element
);
42 // Function that should be called whenever the value of |element| changes due
43 // to user input. This is separate from TextDidChangeInTextField() as that
44 // function may trigger UI and should only be called when other UI won't be
46 void UpdateStateForTextChange(const blink::WebInputElement
& element
);
48 // Fills the username and password fields of this form with the given values.
49 // Returns true if the fields were filled, false otherwise.
50 bool FillSuggestion(const blink::WebNode
& node
,
51 const blink::WebString
& username
,
52 const blink::WebString
& password
);
54 // Previews the username and password fields of this form with the given
55 // values. Returns true if the fields were previewed, false otherwise.
56 bool PreviewSuggestion(const blink::WebNode
& node
,
57 const blink::WebString
& username
,
58 const blink::WebString
& password
);
60 // Clears the preview for the username and password fields, restoring both to
61 // their previous filled state. Return false if no login information was
62 // found for the form.
63 bool DidClearAutofillSelection(const blink::WebNode
& node
);
65 // Shows an Autofill popup with username suggestions for |element|. If
66 // |show_all| is |true|, will show all possible suggestions for that element,
67 // otherwise shows suggestions based on current value of |element|.
68 // If |generation_popup_showing| is true, this function will return false
69 // as both UIs should not be shown at the same time. This function should
70 // still be called in this situation so that UMA stats can be logged.
71 // Returns true if any suggestions were shown, false otherwise.
72 bool ShowSuggestions(const blink::WebInputElement
& element
,
74 bool generation_popup_showing
);
76 // Called when new form controls are inserted.
77 void OnDynamicFormsSeen();
79 // Called when an AJAX has succesfully completed. Used to determine if
80 // a form has been submitted by AJAX without navigation.
83 // Called when the user first interacts with the page after a load. This is a
84 // signal to make autofilled values of password input elements accessible to
86 void FirstUserGestureObserved();
89 virtual bool OriginCanAccessPasswordManager(
90 const blink::WebSecurityOrigin
& origin
);
93 // Ways to restrict which passwords are saved in ProvisionallySavePassword.
94 enum ProvisionallySaveRestriction
{
96 RESTRICTION_NON_EMPTY_PASSWORD
100 blink::WebInputElement password_field
;
101 PasswordFormFillData fill_data
;
102 // The user manually edited the password more recently than the username was
104 bool password_was_edited_last
;
105 // The user edited the username field after page loading.
106 bool username_was_edited
;
109 typedef std::map
<blink::WebInputElement
, PasswordInfo
> LoginToPasswordInfoMap
;
110 typedef std::map
<blink::WebElement
, int> LoginToPasswordInfoKeyMap
;
111 typedef std::map
<blink::WebInputElement
, blink::WebInputElement
>
114 // This class keeps track of autofilled password input elements and makes sure
115 // the autofilled password value is not accessible to JavaScript code until
116 // the user interacts with the page.
117 class PasswordValueGatekeeper
{
119 PasswordValueGatekeeper();
120 ~PasswordValueGatekeeper();
122 // Call this for every autofilled password field, so that the gatekeeper
123 // protects the value accordingly.
124 void RegisterElement(blink::WebInputElement
* element
);
126 // Call this to notify the gatekeeper that the user interacted with the
128 void OnUserGesture();
130 // Call this to reset the gatekeeper on a new page navigation.
134 // Make the value of |element| accessible to JavaScript code.
135 void ShowValue(blink::WebInputElement
* element
);
137 bool was_user_gesture_seen_
;
138 std::vector
<blink::WebInputElement
> elements_
;
140 DISALLOW_COPY_AND_ASSIGN(PasswordValueGatekeeper
);
143 // Thunk class for RenderViewObserver methods that haven't yet been migrated
144 // to RenderFrameObserver. Should eventually be removed.
145 // http://crbug.com/433486
146 class LegacyPasswordAutofillAgent
: public content::RenderViewObserver
{
148 LegacyPasswordAutofillAgent(content::RenderView
* render_view
,
149 PasswordAutofillAgent
* agent
);
150 ~LegacyPasswordAutofillAgent() override
;
152 // RenderViewObserver:
153 void OnDestruct() override
;
154 void DidStartLoading() override
;
155 void DidStopLoading() override
;
156 void DidStartProvisionalLoad(blink::WebLocalFrame
* frame
) override
;
159 PasswordAutofillAgent
* agent_
;
161 DISALLOW_COPY_AND_ASSIGN(LegacyPasswordAutofillAgent
);
163 friend class LegacyPasswordAutofillAgent
;
165 // RenderFrameObserver:
166 bool OnMessageReceived(const IPC::Message
& message
) override
;
167 void DidFinishDocumentLoad() override
;
168 void DidFinishLoad() override
;
169 void FrameDetached() override
;
170 void FrameWillClose() override
;
171 void DidCommitProvisionalLoad(bool is_new_navigation
,
172 bool is_same_page_navigation
) override
;
173 void WillSendSubmitEvent(const blink::WebFormElement
& form
) override
;
174 void WillSubmitForm(const blink::WebFormElement
& form
) override
;
176 // Legacy RenderViewObserver:
177 void DidStartLoading();
178 void DidStopLoading();
179 void LegacyDidStartProvisionalLoad(blink::WebLocalFrame
* frame
);
181 // RenderView IPC handlers:
182 void OnFillPasswordForm(int key
, const PasswordFormFillData
& form_data
);
183 void OnSetLoggingState(bool active
);
184 void OnAutofillUsernameAndPasswordDataReceived(
185 const FormsPredictionsMap
& predictions
);
186 void OnFindFocusedPasswordForm();
188 // Scans the given frame for password forms and sends them up to the browser.
189 // If |only_visible| is true, only forms visible in the layout are sent.
190 void SendPasswordForms(bool only_visible
);
192 // Instructs the browser to show a pop-up suggesting which credentials could
193 // be filled. |show_in_password_field| should indicate whether the pop-up is
194 // to be shown on the password field instead of on the username field. If the
195 // username exists, it should be passed as |user_input|. If there is no
196 // username, pass the password field in |user_input|. In the latter case, no
197 // username value will be shown in the pop-up.
198 bool ShowSuggestionPopup(const PasswordFormFillData
& fill_data
,
199 const blink::WebInputElement
& user_input
,
201 bool show_on_password_field
);
203 // Finds the PasswordInfo that corresponds to the passed in element. The
204 // passed in element can be either a username element or a password element.
205 // If a PasswordInfo was found, returns |true| and also assigns the
206 // corresponding username WebInputElement and PasswordInfo into
207 // username_element and pasword_info, respectively. Note, that
208 // |username_element->isNull()| can be true for forms without a username
210 bool FindPasswordInfoForElement(
211 const blink::WebInputElement
& element
,
212 const blink::WebInputElement
** username_element
,
213 PasswordInfo
** password_info
);
215 // Invoked when the frame is closing.
218 // Finds login information for a |node| that was previously filled.
219 bool FindLoginInfo(const blink::WebNode
& node
,
220 blink::WebInputElement
* found_input
,
221 PasswordInfo
** found_password
);
223 // Clears the preview for the username and password fields, restoring both to
224 // their previous filled state.
225 void ClearPreview(blink::WebInputElement
* username
,
226 blink::WebInputElement
* password
);
228 // Saves |password_form| in |provisionally_saved_form_|, as long as it
229 // satisfies |restriction|.
230 void ProvisionallySavePassword(scoped_ptr
<PasswordForm
> password_form
,
231 ProvisionallySaveRestriction restriction
);
233 // Returns true if |provisionally_saved_form_| has enough information that
234 // it is likely filled out.
235 bool ProvisionallySavedPasswordIsValid();
237 // Helper function called when in-page navigation completed
238 void OnSamePageNavigationCompleted();
240 // Passes through |RenderViewObserver| method to |this|.
241 LegacyPasswordAutofillAgent legacy_
;
243 // The logins we have filled so far with their associated info.
244 LoginToPasswordInfoMap login_to_password_info_
;
245 // And the keys under which PasswordAutofillManager can find the same info.
246 LoginToPasswordInfoKeyMap login_to_password_info_key_
;
247 // A (sort-of) reverse map to |login_to_password_info_|.
248 PasswordToLoginMap password_to_username_
;
250 // Set if the user might be submitting a password form on the current page,
251 // but the submit may still fail (i.e. doesn't pass JavaScript validation).
252 scoped_ptr
<PasswordForm
> provisionally_saved_form_
;
254 // Contains the most recent text that user typed or PasswordManager autofilled
255 // in input elements. Used for storing username/password before JavaScript
257 ModifiedValues nonscript_modified_values_
;
259 PasswordValueGatekeeper gatekeeper_
;
261 // True indicates that user debug information should be logged.
262 bool logging_state_active_
;
264 // True indicates that the username field was autofilled, false otherwise.
265 bool was_username_autofilled_
;
266 // True indicates that the password field was autofilled, false otherwise.
267 bool was_password_autofilled_
;
269 // Records the username typed before suggestions preview.
270 base::string16 username_query_prefix_
;
272 // True indicates that all frames in a page have been rendered.
273 bool did_stop_loading_
;
275 // Contains server predictions for username, password and/or new password
276 // fields for individual forms.
277 FormsPredictionsMap form_predictions_
;
279 base::WeakPtrFactory
<PasswordAutofillAgent
> weak_ptr_factory_
;
281 DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgent
);
284 } // namespace autofill
286 #endif // COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_AUTOFILL_AGENT_H_