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; 89 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