Home | History | Annotate | Download | only in renderer
      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