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 #include "components/autofill/content/renderer/password_autofill_agent.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/metrics/histogram.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "components/autofill/content/renderer/form_autofill_util.h"
     13 #include "components/autofill/core/common/autofill_messages.h"
     14 #include "components/autofill/core/common/form_field_data.h"
     15 #include "components/autofill/core/common/password_form_fill_data.h"
     16 #include "content/public/common/password_form.h"
     17 #include "content/public/renderer/password_form_conversion_utils.h"
     18 #include "content/public/renderer/render_view.h"
     19 #include "third_party/WebKit/public/platform/WebVector.h"
     20 #include "third_party/WebKit/public/web/WebAutofillClient.h"
     21 #include "third_party/WebKit/public/web/WebDocument.h"
     22 #include "third_party/WebKit/public/web/WebElement.h"
     23 #include "third_party/WebKit/public/web/WebFormElement.h"
     24 #include "third_party/WebKit/public/web/WebFrame.h"
     25 #include "third_party/WebKit/public/web/WebInputEvent.h"
     26 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
     27 #include "third_party/WebKit/public/web/WebView.h"
     28 #include "ui/base/keycodes/keyboard_codes.h"
     29 
     30 namespace autofill {
     31 namespace {
     32 
     33 // The size above which we stop triggering autocomplete.
     34 static const size_t kMaximumTextSizeForAutocomplete = 1000;
     35 
     36 // Maps element names to the actual elements to simplify form filling.
     37 typedef std::map<base::string16, WebKit::WebInputElement>
     38     FormInputElementMap;
     39 
     40 // Utility struct for form lookup and autofill. When we parse the DOM to look up
     41 // a form, in addition to action and origin URL's we have to compare all
     42 // necessary form elements. To avoid having to look these up again when we want
     43 // to fill the form, the FindFormElements function stores the pointers
     44 // in a FormElements* result, referenced to ensure they are safe to use.
     45 struct FormElements {
     46   WebKit::WebFormElement form_element;
     47   FormInputElementMap input_elements;
     48 };
     49 
     50 typedef std::vector<FormElements*> FormElementsList;
     51 
     52 // Helper to search the given form element for the specified input elements
     53 // in |data|, and add results to |result|.
     54 static bool FindFormInputElements(WebKit::WebFormElement* fe,
     55                                   const FormData& data,
     56                                   FormElements* result) {
     57   // Loop through the list of elements we need to find on the form in order to
     58   // autofill it. If we don't find any one of them, abort processing this
     59   // form; it can't be the right one.
     60   for (size_t j = 0; j < data.fields.size(); j++) {
     61     WebKit::WebVector<WebKit::WebNode> temp_elements;
     62     fe->getNamedElements(data.fields[j].name, temp_elements);
     63 
     64     // Match the first input element, if any.
     65     // |getNamedElements| may return non-input elements where the names match,
     66     // so the results are filtered for input elements.
     67     // If more than one match is made, then we have ambiguity (due to misuse
     68     // of "name" attribute) so is it considered not found.
     69     bool found_input = false;
     70     for (size_t i = 0; i < temp_elements.size(); ++i) {
     71       if (temp_elements[i].to<WebKit::WebElement>().hasTagName("input")) {
     72         // Check for a non-unique match.
     73         if (found_input) {
     74           found_input = false;
     75           break;
     76         }
     77 
     78         // Only fill saved passwords into password fields and usernames into
     79         // text fields.
     80         WebKit::WebInputElement input_element =
     81             temp_elements[i].to<WebKit::WebInputElement>();
     82         if (input_element.isPasswordField() !=
     83             (data.fields[j].form_control_type == "password"))
     84           continue;
     85 
     86         // This element matched, add it to our temporary result. It's possible
     87         // there are multiple matches, but for purposes of identifying the form
     88         // one suffices and if some function needs to deal with multiple
     89         // matching elements it can get at them through the FormElement*.
     90         // Note: This assignment adds a reference to the InputElement.
     91         result->input_elements[data.fields[j].name] = input_element;
     92         found_input = true;
     93       }
     94     }
     95 
     96     // A required element was not found. This is not the right form.
     97     // Make sure no input elements from a partially matched form in this
     98     // iteration remain in the result set.
     99     // Note: clear will remove a reference from each InputElement.
    100     if (!found_input) {
    101       result->input_elements.clear();
    102       return false;
    103     }
    104   }
    105   return true;
    106 }
    107 
    108 // Helper to locate form elements identified by |data|.
    109 void FindFormElements(WebKit::WebView* view,
    110                       const FormData& data,
    111                       FormElementsList* results) {
    112   DCHECK(view);
    113   DCHECK(results);
    114   WebKit::WebFrame* main_frame = view->mainFrame();
    115   if (!main_frame)
    116     return;
    117 
    118   GURL::Replacements rep;
    119   rep.ClearQuery();
    120   rep.ClearRef();
    121 
    122   // Loop through each frame.
    123   for (WebKit::WebFrame* f = main_frame; f; f = f->traverseNext(false)) {
    124     WebKit::WebDocument doc = f->document();
    125     if (!doc.isHTMLDocument())
    126       continue;
    127 
    128     GURL full_origin(doc.url());
    129     if (data.origin != full_origin.ReplaceComponents(rep))
    130       continue;
    131 
    132     WebKit::WebVector<WebKit::WebFormElement> forms;
    133     doc.forms(forms);
    134 
    135     for (size_t i = 0; i < forms.size(); ++i) {
    136       WebKit::WebFormElement fe = forms[i];
    137 
    138       GURL full_action(f->document().completeURL(fe.action()));
    139       if (full_action.is_empty()) {
    140         // The default action URL is the form's origin.
    141         full_action = full_origin;
    142       }
    143 
    144       // Action URL must match.
    145       if (data.action != full_action.ReplaceComponents(rep))
    146         continue;
    147 
    148       scoped_ptr<FormElements> curr_elements(new FormElements);
    149       if (!FindFormInputElements(&fe, data, curr_elements.get()))
    150         continue;
    151 
    152       // We found the right element.
    153       // Note: this assignment adds a reference to |fe|.
    154       curr_elements->form_element = fe;
    155       results->push_back(curr_elements.release());
    156     }
    157   }
    158 }
    159 
    160 bool IsElementEditable(const WebKit::WebInputElement& element) {
    161   return element.isEnabled() && !element.isReadOnly();
    162 }
    163 
    164 void FillForm(FormElements* fe, const FormData& data) {
    165   if (!fe->form_element.autoComplete())
    166     return;
    167 
    168   std::map<base::string16, base::string16> data_map;
    169   for (size_t i = 0; i < data.fields.size(); i++)
    170     data_map[data.fields[i].name] = data.fields[i].value;
    171 
    172   for (FormInputElementMap::iterator it = fe->input_elements.begin();
    173        it != fe->input_elements.end(); ++it) {
    174     WebKit::WebInputElement element = it->second;
    175     // Don't fill a form that has pre-filled values distinct from the ones we
    176     // want to fill with.
    177     if (!element.value().isEmpty() && element.value() != data_map[it->first])
    178       return;
    179 
    180     // Don't fill forms with uneditable fields or fields with autocomplete
    181     // disabled.
    182     if (!IsElementEditable(element) || !element.autoComplete())
    183       return;
    184   }
    185 
    186   for (FormInputElementMap::iterator it = fe->input_elements.begin();
    187        it != fe->input_elements.end(); ++it) {
    188     WebKit::WebInputElement element = it->second;
    189 
    190     // TODO(tkent): Check maxlength and pattern.
    191     element.setValue(data_map[it->first]);
    192     element.setAutofilled(true);
    193     element.dispatchFormControlChangeEvent();
    194   }
    195 }
    196 
    197 void SetElementAutofilled(WebKit::WebInputElement* element, bool autofilled) {
    198   if (element->isAutofilled() == autofilled)
    199     return;
    200   element->setAutofilled(autofilled);
    201   // Notify any changeEvent listeners.
    202   element->dispatchFormControlChangeEvent();
    203 }
    204 
    205 bool DoUsernamesMatch(const base::string16& username1,
    206                       const base::string16& username2,
    207                       bool exact_match) {
    208   if (exact_match)
    209     return username1 == username2;
    210   return StartsWith(username1, username2, true);
    211 }
    212 
    213 }  // namespace
    214 
    215 ////////////////////////////////////////////////////////////////////////////////
    216 // PasswordAutofillAgent, public:
    217 
    218 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderView* render_view)
    219     : content::RenderViewObserver(render_view),
    220       usernames_usage_(NOTHING_TO_AUTOFILL),
    221       web_view_(render_view->GetWebView()),
    222       weak_ptr_factory_(this) {
    223 }
    224 
    225 PasswordAutofillAgent::~PasswordAutofillAgent() {
    226 }
    227 
    228 bool PasswordAutofillAgent::TextFieldDidEndEditing(
    229     const WebKit::WebInputElement& element) {
    230   LoginToPasswordInfoMap::const_iterator iter =
    231       login_to_password_info_.find(element);
    232   if (iter == login_to_password_info_.end())
    233     return false;
    234 
    235   const PasswordFormFillData& fill_data =
    236       iter->second.fill_data;
    237 
    238   // If wait_for_username is false, we should have filled when the text changed.
    239   if (!fill_data.wait_for_username)
    240     return false;
    241 
    242   WebKit::WebInputElement password = iter->second.password_field;
    243   if (!IsElementEditable(password))
    244     return false;
    245 
    246   WebKit::WebInputElement username = element;  // We need a non-const.
    247 
    248   // Do not set selection when ending an editing session, otherwise it can
    249   // mess with focus.
    250   FillUserNameAndPassword(&username, &password, fill_data, true, false);
    251   return true;
    252 }
    253 
    254 bool PasswordAutofillAgent::TextDidChangeInTextField(
    255     const WebKit::WebInputElement& element) {
    256   LoginToPasswordInfoMap::const_iterator iter =
    257       login_to_password_info_.find(element);
    258   if (iter == login_to_password_info_.end())
    259     return false;
    260 
    261   // The input text is being changed, so any autofilled password is now
    262   // outdated.
    263   WebKit::WebInputElement username = element;  // We need a non-const.
    264   WebKit::WebInputElement password = iter->second.password_field;
    265   SetElementAutofilled(&username, false);
    266   if (password.isAutofilled()) {
    267     password.setValue(base::string16());
    268     SetElementAutofilled(&password, false);
    269   }
    270 
    271   // If wait_for_username is true we will fill when the username loses focus.
    272   if (iter->second.fill_data.wait_for_username)
    273     return false;
    274 
    275   if (!IsElementEditable(element) ||
    276       !element.isText() ||
    277       !element.autoComplete()) {
    278     return false;
    279   }
    280 
    281   // Don't inline autocomplete if the user is deleting, that would be confusing.
    282   // But refresh the popup.  Note, since this is ours, return true to signal
    283   // no further processing is required.
    284   if (iter->second.backspace_pressed_last) {
    285     ShowSuggestionPopup(iter->second.fill_data, username);
    286     return true;
    287   }
    288 
    289   WebKit::WebString name = element.nameForAutofill();
    290   if (name.isEmpty())
    291     return false;  // If the field has no name, then we won't have values.
    292 
    293   // Don't attempt to autofill with values that are too large.
    294   if (element.value().length() > kMaximumTextSizeForAutocomplete)
    295     return false;
    296 
    297   // The caret position should have already been updated.
    298   PerformInlineAutocomplete(element, password, iter->second.fill_data);
    299   return true;
    300 }
    301 
    302 bool PasswordAutofillAgent::TextFieldHandlingKeyDown(
    303     const WebKit::WebInputElement& element,
    304     const WebKit::WebKeyboardEvent& event) {
    305   // If using the new Autofill UI that lives in the browser, it will handle
    306   // keypresses before this function. This is not currently an issue but if
    307   // the keys handled there or here change, this issue may appear.
    308 
    309   LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(element);
    310   if (iter == login_to_password_info_.end())
    311     return false;
    312 
    313   int win_key_code = event.windowsKeyCode;
    314   iter->second.backspace_pressed_last =
    315       (win_key_code == ui::VKEY_BACK || win_key_code == ui::VKEY_DELETE);
    316   return true;
    317 }
    318 
    319 bool PasswordAutofillAgent::DidAcceptAutofillSuggestion(
    320     const WebKit::WebNode& node,
    321     const WebKit::WebString& value) {
    322   WebKit::WebInputElement input;
    323   PasswordInfo password;
    324   if (!FindLoginInfo(node, &input, &password))
    325     return false;
    326 
    327   // Set the incoming |value| in the text field and |FillUserNameAndPassword|
    328   // will do the rest.
    329   input.setValue(value, true);
    330   return FillUserNameAndPassword(&input, &password.password_field,
    331                                  password.fill_data, true, true);
    332 }
    333 
    334 bool PasswordAutofillAgent::DidClearAutofillSelection(
    335     const WebKit::WebNode& node) {
    336   WebKit::WebInputElement input;
    337   PasswordInfo password;
    338   return FindLoginInfo(node, &input, &password);
    339 }
    340 
    341 bool PasswordAutofillAgent::ShowSuggestions(
    342     const WebKit::WebInputElement& element) {
    343   LoginToPasswordInfoMap::const_iterator iter =
    344       login_to_password_info_.find(element);
    345   if (iter == login_to_password_info_.end())
    346     return false;
    347 
    348   return ShowSuggestionPopup(iter->second.fill_data, element);
    349 }
    350 
    351 void PasswordAutofillAgent::SendPasswordForms(WebKit::WebFrame* frame,
    352                                                 bool only_visible) {
    353   // Make sure that this security origin is allowed to use password manager.
    354   WebKit::WebSecurityOrigin origin = frame->document().securityOrigin();
    355   if (!origin.canAccessPasswordManager())
    356     return;
    357 
    358   WebKit::WebVector<WebKit::WebFormElement> forms;
    359   frame->document().forms(forms);
    360 
    361   std::vector<content::PasswordForm> password_forms;
    362   for (size_t i = 0; i < forms.size(); ++i) {
    363     const WebKit::WebFormElement& form = forms[i];
    364 
    365     // If requested, ignore non-rendered forms, e.g. those styled with
    366     // display:none.
    367     if (only_visible && !form.hasNonEmptyBoundingBox())
    368       continue;
    369 
    370     scoped_ptr<content::PasswordForm> password_form(
    371         content::CreatePasswordForm(form));
    372     if (password_form.get())
    373       password_forms.push_back(*password_form);
    374   }
    375 
    376   if (password_forms.empty() && !only_visible) {
    377     // We need to send the PasswordFormsRendered message regardless of whether
    378     // there are any forms visible, as this is also the code path that triggers
    379     // showing the infobar.
    380     return;
    381   }
    382 
    383   if (only_visible) {
    384     Send(new AutofillHostMsg_PasswordFormsRendered(
    385         routing_id(), password_forms));
    386   } else {
    387     Send(new AutofillHostMsg_PasswordFormsParsed(routing_id(), password_forms));
    388   }
    389 }
    390 
    391 bool PasswordAutofillAgent::OnMessageReceived(const IPC::Message& message) {
    392   bool handled = true;
    393   IPC_BEGIN_MESSAGE_MAP(PasswordAutofillAgent, message)
    394     IPC_MESSAGE_HANDLER(AutofillMsg_FillPasswordForm, OnFillPasswordForm)
    395     IPC_MESSAGE_UNHANDLED(handled = false)
    396   IPC_END_MESSAGE_MAP()
    397   return handled;
    398 }
    399 
    400 void PasswordAutofillAgent::DidStartLoading() {
    401   if (usernames_usage_ != NOTHING_TO_AUTOFILL) {
    402     UMA_HISTOGRAM_ENUMERATION("PasswordManager.OtherPossibleUsernamesUsage",
    403                               usernames_usage_, OTHER_POSSIBLE_USERNAMES_MAX);
    404     usernames_usage_ = NOTHING_TO_AUTOFILL;
    405   }
    406 }
    407 
    408 void PasswordAutofillAgent::DidFinishDocumentLoad(WebKit::WebFrame* frame) {
    409   // The |frame| contents have been parsed, but not yet rendered.  Let the
    410   // PasswordManager know that forms are loaded, even though we can't yet tell
    411   // whether they're visible.
    412   SendPasswordForms(frame, false);
    413 }
    414 
    415 void PasswordAutofillAgent::DidFinishLoad(WebKit::WebFrame* frame) {
    416   // The |frame| contents have been rendered.  Let the PasswordManager know
    417   // which of the loaded frames are actually visible to the user.  This also
    418   // triggers the "Save password?" infobar if the user just submitted a password
    419   // form.
    420   SendPasswordForms(frame, true);
    421 }
    422 
    423 void PasswordAutofillAgent::FrameDetached(WebKit::WebFrame* frame) {
    424   FrameClosing(frame);
    425 }
    426 
    427 void PasswordAutofillAgent::FrameWillClose(WebKit::WebFrame* frame) {
    428   FrameClosing(frame);
    429 }
    430 
    431 void PasswordAutofillAgent::OnFillPasswordForm(
    432     const PasswordFormFillData& form_data) {
    433   if (usernames_usage_ == NOTHING_TO_AUTOFILL) {
    434     if (form_data.other_possible_usernames.size())
    435       usernames_usage_ = OTHER_POSSIBLE_USERNAMES_PRESENT;
    436     else if (usernames_usage_ == NOTHING_TO_AUTOFILL)
    437       usernames_usage_ = OTHER_POSSIBLE_USERNAMES_ABSENT;
    438   }
    439 
    440   FormElementsList forms;
    441   // We own the FormElements* in forms.
    442   FindFormElements(render_view()->GetWebView(), form_data.basic_data, &forms);
    443   FormElementsList::iterator iter;
    444   for (iter = forms.begin(); iter != forms.end(); ++iter) {
    445     scoped_ptr<FormElements> form_elements(*iter);
    446 
    447     // If wait_for_username is true, we don't want to initially fill the form
    448     // until the user types in a valid username.
    449     if (!form_data.wait_for_username)
    450       FillForm(form_elements.get(), form_data.basic_data);
    451 
    452     // Attach autocomplete listener to enable selecting alternate logins.
    453     // First, get pointers to username element.
    454     WebKit::WebInputElement username_element =
    455         form_elements->input_elements[form_data.basic_data.fields[0].name];
    456 
    457     // Get pointer to password element. (We currently only support single
    458     // password forms).
    459     WebKit::WebInputElement password_element =
    460         form_elements->input_elements[form_data.basic_data.fields[1].name];
    461 
    462     // We might have already filled this form if there are two <form> elements
    463     // with identical markup.
    464     if (login_to_password_info_.find(username_element) !=
    465         login_to_password_info_.end())
    466       continue;
    467 
    468     PasswordInfo password_info;
    469     password_info.fill_data = form_data;
    470     password_info.password_field = password_element;
    471     login_to_password_info_[username_element] = password_info;
    472 
    473     FormData form;
    474     FormFieldData field;
    475     FindFormAndFieldForInputElement(
    476         username_element, &form, &field, REQUIRE_NONE);
    477     Send(new AutofillHostMsg_AddPasswordFormMapping(
    478         routing_id(),
    479         field,
    480         form_data));
    481   }
    482 }
    483 
    484 ////////////////////////////////////////////////////////////////////////////////
    485 // PasswordAutofillAgent, private:
    486 
    487 void PasswordAutofillAgent::GetSuggestions(
    488     const PasswordFormFillData& fill_data,
    489     const base::string16& input,
    490     std::vector<base::string16>* suggestions,
    491     std::vector<base::string16>* realms) {
    492   if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) {
    493     suggestions->push_back(fill_data.basic_data.fields[0].value);
    494     realms->push_back(UTF8ToUTF16(fill_data.preferred_realm));
    495   }
    496 
    497   for (PasswordFormFillData::LoginCollection::const_iterator iter =
    498            fill_data.additional_logins.begin();
    499        iter != fill_data.additional_logins.end(); ++iter) {
    500     if (StartsWith(iter->first, input, false)) {
    501       suggestions->push_back(iter->first);
    502       realms->push_back(UTF8ToUTF16(iter->second.realm));
    503     }
    504   }
    505 
    506   for (PasswordFormFillData::UsernamesCollection::const_iterator iter =
    507            fill_data.other_possible_usernames.begin();
    508        iter != fill_data.other_possible_usernames.end(); ++iter) {
    509     for (size_t i = 0; i < iter->second.size(); ++i) {
    510       if (StartsWith(iter->second[i], input, false)) {
    511         usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN;
    512         suggestions->push_back(iter->second[i]);
    513         realms->push_back(UTF8ToUTF16(iter->first.realm));
    514       }
    515     }
    516   }
    517 }
    518 
    519 bool PasswordAutofillAgent::ShowSuggestionPopup(
    520     const PasswordFormFillData& fill_data,
    521     const WebKit::WebInputElement& user_input) {
    522   WebKit::WebFrame* frame = user_input.document().frame();
    523   if (!frame)
    524     return false;
    525 
    526   WebKit::WebView* webview = frame->view();
    527   if (!webview)
    528     return false;
    529 
    530   std::vector<base::string16> suggestions;
    531   std::vector<base::string16> realms;
    532   GetSuggestions(fill_data, user_input.value(), &suggestions, &realms);
    533   DCHECK_EQ(suggestions.size(), realms.size());
    534 
    535   FormData form;
    536   FormFieldData field;
    537   FindFormAndFieldForInputElement(
    538       user_input, &form, &field, REQUIRE_NONE);
    539 
    540   WebKit::WebInputElement selected_element = user_input;
    541   gfx::Rect bounding_box(selected_element.boundsInViewportSpace());
    542 
    543   float scale = web_view_->pageScaleFactor();
    544   gfx::RectF bounding_box_scaled(bounding_box.x() * scale,
    545                                  bounding_box.y() * scale,
    546                                  bounding_box.width() * scale,
    547                                  bounding_box.height() * scale);
    548   Send(new AutofillHostMsg_ShowPasswordSuggestions(routing_id(),
    549                                                    field,
    550                                                    bounding_box_scaled,
    551                                                    suggestions,
    552                                                    realms));
    553   return !suggestions.empty();
    554 }
    555 
    556 bool PasswordAutofillAgent::FillUserNameAndPassword(
    557     WebKit::WebInputElement* username_element,
    558     WebKit::WebInputElement* password_element,
    559     const PasswordFormFillData& fill_data,
    560     bool exact_username_match,
    561     bool set_selection) {
    562   base::string16 current_username = username_element->value();
    563   // username and password will contain the match found if any.
    564   base::string16 username;
    565   base::string16 password;
    566 
    567   // Look for any suitable matches to current field text.
    568   if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, current_username,
    569                        exact_username_match)) {
    570     username = fill_data.basic_data.fields[0].value;
    571     password = fill_data.basic_data.fields[1].value;
    572   } else {
    573     // Scan additional logins for a match.
    574     PasswordFormFillData::LoginCollection::const_iterator iter;
    575     for (iter = fill_data.additional_logins.begin();
    576          iter != fill_data.additional_logins.end(); ++iter) {
    577       if (DoUsernamesMatch(iter->first, current_username,
    578                            exact_username_match)) {
    579         username = iter->first;
    580         password = iter->second.password;
    581         break;
    582       }
    583     }
    584 
    585     // Check possible usernames.
    586     if (username.empty() && password.empty()) {
    587       for (PasswordFormFillData::UsernamesCollection::const_iterator iter =
    588                fill_data.other_possible_usernames.begin();
    589            iter != fill_data.other_possible_usernames.end(); ++iter) {
    590         for (size_t i = 0; i < iter->second.size(); ++i) {
    591           if (DoUsernamesMatch(iter->second[i], current_username,
    592                                exact_username_match)) {
    593             usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED;
    594             username = iter->second[i];
    595             password = iter->first.password;
    596             break;
    597           }
    598         }
    599         if (!username.empty() && !password.empty())
    600           break;
    601       }
    602     }
    603   }
    604   if (password.empty())
    605     return false;  // No match was found.
    606 
    607   // Input matches the username, fill in required values.
    608   username_element->setValue(username);
    609 
    610   if (set_selection) {
    611     username_element->setSelectionRange(current_username.length(),
    612                                         username.length());
    613   }
    614 
    615   SetElementAutofilled(username_element, true);
    616   if (IsElementEditable(*password_element))
    617     password_element->setValue(password);
    618   SetElementAutofilled(password_element, true);
    619   return true;
    620 }
    621 
    622 void PasswordAutofillAgent::PerformInlineAutocomplete(
    623     const WebKit::WebInputElement& username_input,
    624     const WebKit::WebInputElement& password_input,
    625     const PasswordFormFillData& fill_data) {
    626   DCHECK(!fill_data.wait_for_username);
    627 
    628   // We need non-const versions of the username and password inputs.
    629   WebKit::WebInputElement username = username_input;
    630   WebKit::WebInputElement password = password_input;
    631 
    632   // Don't inline autocomplete if the caret is not at the end.
    633   // TODO(jcivelli): is there a better way to test the caret location?
    634   if (username.selectionStart() != username.selectionEnd() ||
    635       username.selectionEnd() != static_cast<int>(username.value().length())) {
    636     return;
    637   }
    638 
    639   // Show the popup with the list of available usernames.
    640   ShowSuggestionPopup(fill_data, username);
    641 
    642 
    643 #if !defined(OS_ANDROID)
    644   // Fill the user and password field with the most relevant match. Android
    645   // only fills in the fields after the user clicks on the suggestion popup.
    646   FillUserNameAndPassword(&username, &password, fill_data, false, true);
    647 #endif
    648 }
    649 
    650 void PasswordAutofillAgent::FrameClosing(const WebKit::WebFrame* frame) {
    651   for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin();
    652        iter != login_to_password_info_.end();) {
    653     if (iter->first.document().frame() == frame)
    654       login_to_password_info_.erase(iter++);
    655     else
    656       ++iter;
    657   }
    658 }
    659 
    660 bool PasswordAutofillAgent::FindLoginInfo(const WebKit::WebNode& node,
    661                                           WebKit::WebInputElement* found_input,
    662                                           PasswordInfo* found_password) {
    663   if (!node.isElementNode())
    664     return false;
    665 
    666   WebKit::WebElement element = node.toConst<WebKit::WebElement>();
    667   if (!element.hasTagName("input"))
    668     return false;
    669 
    670   WebKit::WebInputElement input = element.to<WebKit::WebInputElement>();
    671   LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input);
    672   if (iter == login_to_password_info_.end())
    673     return false;
    674 
    675   *found_input = input;
    676   *found_password = iter->second;
    677   return true;
    678 }
    679 
    680 }  // namespace autofill
    681