• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_PASSWORD_AUTOFILL_AGENT_H_
6 #define COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_AUTOFILL_AGENT_H_
7 
8 #include <map>
9 #include <vector>
10 
11 #include "base/memory/linked_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "components/autofill/core/common/password_form_fill_data.h"
14 #include "content/public/renderer/render_view_observer.h"
15 #include "third_party/WebKit/public/web/WebInputElement.h"
16 
17 namespace blink {
18 class WebInputElement;
19 class WebKeyboardEvent;
20 class WebSecurityOrigin;
21 class WebView;
22 }
23 
24 namespace autofill {
25 
26 // This class is responsible for filling password forms.
27 // There is one PasswordAutofillAgent per RenderView.
28 class PasswordAutofillAgent : public content::RenderViewObserver {
29  public:
30   explicit PasswordAutofillAgent(content::RenderView* render_view);
31   virtual ~PasswordAutofillAgent();
32 
33   // WebViewClient editor related calls forwarded by the RenderView.
34   // If they return true, it indicates the event was consumed and should not
35   // be used for any other autofill activity.
36   bool TextFieldDidEndEditing(const blink::WebInputElement& element);
37   bool TextDidChangeInTextField(const blink::WebInputElement& element);
38   bool TextFieldHandlingKeyDown(const blink::WebInputElement& element,
39                                 const blink::WebKeyboardEvent& event);
40 
41   // Fills the username and password fields of this form with the given values.
42   // Returns true if the fields were filled, false otherwise.
43   bool FillSuggestion(const blink::WebNode& node,
44                       const blink::WebString& username,
45                       const blink::WebString& password);
46 
47   // Previews the username and password fields of this form with the given
48   // values. Returns true if the fields were previewed, false otherwise.
49   bool PreviewSuggestion(const blink::WebNode& node,
50                          const blink::WebString& username,
51                          const blink::WebString& password);
52 
53   // Clears the preview for the username and password fields, restoring both to
54   // their previous filled state. Return false if no login information was
55   // found for the form.
56   bool DidClearAutofillSelection(const blink::WebNode& node);
57   // Shows an Autofill popup with username suggestions for |element|.
58   // Returns true if any suggestions were shown, false otherwise.
59   bool ShowSuggestions(const blink::WebInputElement& element);
60 
61   // Called when new form controls are inserted.
62   void OnDynamicFormsSeen(blink::WebFrame* frame);
63 
64   // Called when the user first interacts with the page after a load. This is a
65   // signal to make autofilled values of password input elements accessible to
66   // JavaScript.
67   void FirstUserGestureObserved();
68 
69  protected:
70   virtual bool OriginCanAccessPasswordManager(
71       const blink::WebSecurityOrigin& origin);
72 
73  private:
74   friend class PasswordAutofillAgentTest;
75 
76   enum OtherPossibleUsernamesUsage {
77     NOTHING_TO_AUTOFILL,
78     OTHER_POSSIBLE_USERNAMES_ABSENT,
79     OTHER_POSSIBLE_USERNAMES_PRESENT,
80     OTHER_POSSIBLE_USERNAME_SHOWN,
81     OTHER_POSSIBLE_USERNAME_SELECTED,
82     OTHER_POSSIBLE_USERNAMES_MAX
83   };
84 
85   struct PasswordInfo {
86     blink::WebInputElement password_field;
87     PasswordFormFillData fill_data;
88     bool backspace_pressed_last;
PasswordInfoPasswordInfo89     PasswordInfo() : backspace_pressed_last(false) {}
90   };
91   typedef std::map<blink::WebElement, PasswordInfo> LoginToPasswordInfoMap;
92   typedef std::map<blink::WebFrame*,
93                    linked_ptr<PasswordForm> > FrameToPasswordFormMap;
94 
95   // This class holds a vector of autofilled password input elements and makes
96   // sure the autofilled password value is not accessible to JavaScript code
97   // until the user interacts with the page.
98   class PasswordValueGatekeeper {
99    public:
100     PasswordValueGatekeeper();
101     ~PasswordValueGatekeeper();
102 
103     // Call this for every autofilled password field, so that the gatekeeper
104     // protects the value accordingly.
105     void RegisterElement(blink::WebInputElement* element);
106 
107     // Call this to notify the gatekeeper that the user interacted with the
108     // page.
109     void OnUserGesture();
110 
111     // Call this to reset the gatekeeper on a new page navigation.
112     void Reset();
113 
114    private:
115     // Make the value of |element| accessible to JavaScript code.
116     void ShowValue(blink::WebInputElement* element);
117 
118     bool was_user_gesture_seen_;
119     std::vector<blink::WebInputElement> elements_;
120 
121     DISALLOW_COPY_AND_ASSIGN(PasswordValueGatekeeper);
122   };
123 
124   // RenderViewObserver:
125   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
126   virtual void DidStartProvisionalLoad(blink::WebLocalFrame* frame) OVERRIDE;
127   virtual void DidStartLoading() OVERRIDE;
128   virtual void DidFinishDocumentLoad(blink::WebLocalFrame* frame) OVERRIDE;
129   virtual void DidFinishLoad(blink::WebLocalFrame* frame) OVERRIDE;
130   virtual void FrameDetached(blink::WebFrame* frame) OVERRIDE;
131   virtual void FrameWillClose(blink::WebFrame* frame) OVERRIDE;
132   virtual void WillSendSubmitEvent(blink::WebLocalFrame* frame,
133                                    const blink::WebFormElement& form) OVERRIDE;
134   virtual void WillSubmitForm(blink::WebLocalFrame* frame,
135                               const blink::WebFormElement& form) OVERRIDE;
136 
137   // RenderView IPC handlers:
138   void OnFillPasswordForm(const PasswordFormFillData& form_data);
139   void OnSetLoggingState(bool active);
140 
141   // Scans the given frame for password forms and sends them up to the browser.
142   // If |only_visible| is true, only forms visible in the layout are sent.
143   void SendPasswordForms(blink::WebFrame* frame, bool only_visible);
144 
145   void GetSuggestions(const PasswordFormFillData& fill_data,
146                       const base::string16& input,
147                       std::vector<base::string16>* suggestions,
148                       std::vector<base::string16>* realms);
149 
150   bool ShowSuggestionPopup(const PasswordFormFillData& fill_data,
151                            const blink::WebInputElement& user_input);
152 
153   // Attempts to fill |username_element| and |password_element| with the
154   // |fill_data|.  Will use the data corresponding to the preferred username,
155   // unless the |username_element| already has a value set.  In that case,
156   // attempts to fill the password matching the already filled username, if
157   // such a password exists.
158   void FillFormOnPasswordRecieved(const PasswordFormFillData& fill_data,
159                                   blink::WebInputElement username_element,
160                                   blink::WebInputElement password_element);
161 
162   bool FillUserNameAndPassword(blink::WebInputElement* username_element,
163                                blink::WebInputElement* password_element,
164                                const PasswordFormFillData& fill_data,
165                                bool exact_username_match,
166                                bool set_selection);
167 
168   // Fills |login_input| and |password| with the most relevant suggestion from
169   // |fill_data| and shows a popup with other suggestions.
170   void PerformInlineAutocomplete(
171       const blink::WebInputElement& username,
172       const blink::WebInputElement& password,
173       const PasswordFormFillData& fill_data);
174 
175   // Invoked when the passed frame is closing.  Gives us a chance to clear any
176   // reference we may have to elements in that frame.
177   void FrameClosing(const blink::WebFrame* frame);
178 
179   // Finds login information for a |node| that was previously filled.
180   bool FindLoginInfo(const blink::WebNode& node,
181                      blink::WebInputElement* found_input,
182                      PasswordInfo* found_password);
183 
184   // Clears the preview for the username and password fields, restoring both to
185   // their previous filled state.
186   void ClearPreview(blink::WebInputElement* username,
187                     blink::WebInputElement* password);
188 
189   // If |provisionally_saved_forms_| contains a form for |current_frame| or its
190   // children, return such frame.
191   blink::WebFrame* CurrentOrChildFrameWithSavedForms(
192       const blink::WebFrame* current_frame);
193 
194   // The logins we have filled so far with their associated info.
195   LoginToPasswordInfoMap login_to_password_info_;
196 
197   // Used for UMA stats.
198   OtherPossibleUsernamesUsage usernames_usage_;
199 
200   // Pointer to the WebView. Used to access page scale factor.
201   blink::WebView* web_view_;
202 
203   // Set if the user might be submitting a password form on the current page,
204   // but the submit may still fail (i.e. doesn't pass JavaScript validation).
205   FrameToPasswordFormMap provisionally_saved_forms_;
206 
207   PasswordValueGatekeeper gatekeeper_;
208 
209   // True indicates that user debug information should be logged.
210   bool logging_state_active_;
211 
212   // True indicates that the username field was autofilled, false otherwise.
213   bool was_username_autofilled_;
214   // True indicates that the password field was autofilled, false otherwise.
215   bool was_password_autofilled_;
216 
217   // Records original starting point of username element's selection range
218   // before preview.
219   int username_selection_start_;
220 
221   base::WeakPtrFactory<PasswordAutofillAgent> weak_ptr_factory_;
222 
223   DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgent);
224 };
225 
226 }  // namespace autofill
227 
228 #endif  // COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_AUTOFILL_AGENT_H_
229