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/autofill_agent.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/command_line.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/strings/string_split.h"
     11 #include "base/strings/string_util.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "base/time/time.h"
     14 #include "components/autofill/content/renderer/form_autofill_util.h"
     15 #include "components/autofill/content/renderer/page_click_tracker.h"
     16 #include "components/autofill/content/renderer/password_autofill_agent.h"
     17 #include "components/autofill/core/common/autofill_constants.h"
     18 #include "components/autofill/core/common/autofill_messages.h"
     19 #include "components/autofill/core/common/autofill_switches.h"
     20 #include "components/autofill/core/common/form_data.h"
     21 #include "components/autofill/core/common/form_data_predictions.h"
     22 #include "components/autofill/core/common/form_field_data.h"
     23 #include "components/autofill/core/common/web_element_descriptor.h"
     24 #include "content/public/common/password_form.h"
     25 #include "content/public/common/ssl_status.h"
     26 #include "content/public/common/url_constants.h"
     27 #include "content/public/renderer/render_view.h"
     28 #include "grit/component_strings.h"
     29 #include "net/cert/cert_status_flags.h"
     30 #include "third_party/WebKit/public/platform/WebRect.h"
     31 #include "third_party/WebKit/public/platform/WebURLRequest.h"
     32 #include "third_party/WebKit/public/web/WebDataSource.h"
     33 #include "third_party/WebKit/public/web/WebDocument.h"
     34 #include "third_party/WebKit/public/web/WebFormControlElement.h"
     35 #include "third_party/WebKit/public/web/WebFormElement.h"
     36 #include "third_party/WebKit/public/web/WebFrame.h"
     37 #include "third_party/WebKit/public/web/WebInputEvent.h"
     38 #include "third_party/WebKit/public/web/WebNode.h"
     39 #include "third_party/WebKit/public/web/WebNodeCollection.h"
     40 #include "third_party/WebKit/public/web/WebOptionElement.h"
     41 #include "third_party/WebKit/public/web/WebView.h"
     42 #include "ui/base/keycodes/keyboard_codes.h"
     43 #include "ui/base/l10n/l10n_util.h"
     44 
     45 using WebKit::WebAutofillClient;
     46 using WebKit::WebFormControlElement;
     47 using WebKit::WebFormElement;
     48 using WebKit::WebFrame;
     49 using WebKit::WebInputElement;
     50 using WebKit::WebKeyboardEvent;
     51 using WebKit::WebNode;
     52 using WebKit::WebNodeCollection;
     53 using WebKit::WebOptionElement;
     54 using WebKit::WebString;
     55 
     56 namespace {
     57 
     58 // The size above which we stop triggering autofill for an input text field
     59 // (so to avoid sending long strings through IPC).
     60 const size_t kMaximumTextSizeForAutofill = 1000;
     61 
     62 // The maximum number of data list elements to send to the browser process
     63 // via IPC (to prevent long IPC messages).
     64 const size_t kMaximumDataListSizeForAutofill = 30;
     65 
     66 const int kAutocheckoutClickTimeout = 3;
     67 
     68 
     69 // Gets all the data list values (with corresponding label) for the given
     70 // element.
     71 void GetDataListSuggestions(const WebKit::WebInputElement& element,
     72                             std::vector<base::string16>* values,
     73                             std::vector<base::string16>* labels) {
     74   WebNodeCollection options = element.dataListOptions();
     75   if (options.isNull())
     76     return;
     77 
     78   base::string16 prefix = element.editingValue();
     79   if (element.isMultiple() &&
     80       element.formControlType() == WebString::fromUTF8("email")) {
     81     std::vector<base::string16> parts;
     82     base::SplitStringDontTrim(prefix, ',', &parts);
     83     if (parts.size() > 0)
     84       TrimWhitespace(parts[parts.size() - 1], TRIM_LEADING, &prefix);
     85   }
     86   for (WebOptionElement option = options.firstItem().to<WebOptionElement>();
     87        !option.isNull(); option = options.nextItem().to<WebOptionElement>()) {
     88     if (!StartsWith(option.value(), prefix, false) ||
     89         option.value() == prefix ||
     90         !element.isValidValue(option.value()))
     91       continue;
     92 
     93     values->push_back(option.value());
     94     if (option.value() != option.label())
     95       labels->push_back(option.label());
     96     else
     97       labels->push_back(base::string16());
     98   }
     99 }
    100 
    101 // Trim the vector before sending it to the browser process to ensure we
    102 // don't send too much data through the IPC.
    103 void TrimStringVectorForIPC(std::vector<base::string16>* strings) {
    104   // Limit the size of the vector.
    105   if (strings->size() > kMaximumDataListSizeForAutofill)
    106     strings->resize(kMaximumDataListSizeForAutofill);
    107 
    108   // Limit the size of the strings in the vector.
    109   for (size_t i = 0; i < strings->size(); ++i) {
    110     if ((*strings)[i].length() > kMaximumTextSizeForAutofill)
    111       (*strings)[i].resize(kMaximumTextSizeForAutofill);
    112   }
    113 }
    114 
    115 gfx::RectF GetScaledBoundingBox(float scale, WebInputElement* element) {
    116   gfx::Rect bounding_box(element->boundsInViewportSpace());
    117   return gfx::RectF(bounding_box.x() * scale,
    118                     bounding_box.y() * scale,
    119                     bounding_box.width() * scale,
    120                     bounding_box.height() * scale);
    121 }
    122 
    123 }  // namespace
    124 
    125 namespace autofill {
    126 
    127 AutofillAgent::AutofillAgent(content::RenderView* render_view,
    128                              PasswordAutofillAgent* password_autofill_agent)
    129     : content::RenderViewObserver(render_view),
    130       password_autofill_agent_(password_autofill_agent),
    131       autofill_query_id_(0),
    132       autofill_action_(AUTOFILL_NONE),
    133       topmost_frame_(NULL),
    134       web_view_(render_view->GetWebView()),
    135       display_warning_if_disabled_(false),
    136       was_query_node_autofilled_(false),
    137       has_shown_autofill_popup_for_current_edit_(false),
    138       did_set_node_text_(false),
    139       autocheckout_click_in_progress_(false),
    140       is_autocheckout_supported_(false),
    141       has_new_forms_for_browser_(false),
    142       ignore_text_changes_(false),
    143       weak_ptr_factory_(this) {
    144   render_view->GetWebView()->setAutofillClient(this);
    145 
    146   // The PageClickTracker is a RenderViewObserver, and hence will be freed when
    147   // the RenderView is destroyed.
    148   new PageClickTracker(render_view, this);
    149 }
    150 
    151 AutofillAgent::~AutofillAgent() {}
    152 
    153 bool AutofillAgent::OnMessageReceived(const IPC::Message& message) {
    154   bool handled = true;
    155   IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message)
    156     IPC_MESSAGE_HANDLER(AutofillMsg_GetAllForms, OnGetAllForms)
    157     IPC_MESSAGE_HANDLER(AutofillMsg_FormDataFilled, OnFormDataFilled)
    158     IPC_MESSAGE_HANDLER(AutofillMsg_FieldTypePredictionsAvailable,
    159                         OnFieldTypePredictionsAvailable)
    160     IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionFill,
    161                         OnSetAutofillActionFill)
    162     IPC_MESSAGE_HANDLER(AutofillMsg_ClearForm,
    163                         OnClearForm)
    164     IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionPreview,
    165                         OnSetAutofillActionPreview)
    166     IPC_MESSAGE_HANDLER(AutofillMsg_ClearPreviewedForm,
    167                         OnClearPreviewedForm)
    168     IPC_MESSAGE_HANDLER(AutofillMsg_SetNodeText,
    169                         OnSetNodeText)
    170     IPC_MESSAGE_HANDLER(AutofillMsg_AcceptDataListSuggestion,
    171                         OnAcceptDataListSuggestion)
    172     IPC_MESSAGE_HANDLER(AutofillMsg_AcceptPasswordAutofillSuggestion,
    173                         OnAcceptPasswordAutofillSuggestion)
    174     IPC_MESSAGE_HANDLER(AutofillMsg_RequestAutocompleteResult,
    175                         OnRequestAutocompleteResult)
    176     IPC_MESSAGE_HANDLER(AutofillMsg_FillFormsAndClick,
    177                         OnFillFormsAndClick)
    178     IPC_MESSAGE_HANDLER(AutofillMsg_AutocheckoutSupported,
    179                         OnAutocheckoutSupported)
    180     IPC_MESSAGE_HANDLER(AutofillMsg_PageShown,
    181                         OnPageShown)
    182     IPC_MESSAGE_UNHANDLED(handled = false)
    183   IPC_END_MESSAGE_MAP()
    184   return handled;
    185 }
    186 
    187 void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) {
    188   // Record timestamp on document load. This is used to record overhead of
    189   // Autofill feature.
    190   forms_seen_timestamp_ = base::TimeTicks::Now();
    191 
    192   // The document has now been fully loaded.  Scan for forms to be sent up to
    193   // the browser.
    194   std::vector<FormData> forms;
    195   bool has_more_forms = false;
    196   if (!frame->parent()) {
    197     topmost_frame_ = frame;
    198     form_elements_.clear();
    199     has_more_forms = form_cache_.ExtractFormsAndFormElements(
    200         *frame, kRequiredAutofillFields, &forms, &form_elements_);
    201   } else {
    202     form_cache_.ExtractForms(*frame, &forms);
    203   }
    204 
    205   autofill::FormsSeenState state = has_more_forms ?
    206       autofill::PARTIAL_FORMS_SEEN : autofill::NO_SPECIAL_FORMS_SEEN;
    207 
    208   // Always communicate to browser process for topmost frame.
    209   if (!forms.empty() || !frame->parent()) {
    210     Send(new AutofillHostMsg_FormsSeen(routing_id(), forms,
    211                                        forms_seen_timestamp_,
    212                                        state));
    213   }
    214 }
    215 
    216 void AutofillAgent::DidStartProvisionalLoad(WebFrame* frame) {
    217   if (!frame->parent()) {
    218     is_autocheckout_supported_ = false;
    219     topmost_frame_ = NULL;
    220     if (click_timer_.IsRunning()) {
    221       click_timer_.Stop();
    222       autocheckout_click_in_progress_ = true;
    223     }
    224   }
    225 }
    226 
    227 void AutofillAgent::DidFailProvisionalLoad(WebFrame* frame,
    228                                            const WebKit::WebURLError& error) {
    229   if (!frame->parent() && autocheckout_click_in_progress_) {
    230     autocheckout_click_in_progress_ = false;
    231     ClickFailed();
    232   }
    233 }
    234 
    235 void AutofillAgent::DidCommitProvisionalLoad(WebFrame* frame,
    236                                              bool is_new_navigation) {
    237   in_flight_request_form_.reset();
    238   if (!frame->parent() && autocheckout_click_in_progress_) {
    239     autocheckout_click_in_progress_ = false;
    240     CompleteAutocheckoutPage(SUCCESS);
    241   }
    242 }
    243 
    244 void AutofillAgent::FrameDetached(WebFrame* frame) {
    245   form_cache_.ResetFrame(*frame);
    246   if (!frame->parent()) {
    247     // |frame| is about to be destroyed so we need to clear |top_most_frame_|.
    248     topmost_frame_ = NULL;
    249     click_timer_.Stop();
    250   }
    251 }
    252 
    253 void AutofillAgent::WillSubmitForm(WebFrame* frame,
    254                                    const WebFormElement& form) {
    255   FormData form_data;
    256   if (WebFormElementToFormData(form,
    257                                WebFormControlElement(),
    258                                REQUIRE_AUTOCOMPLETE,
    259                                static_cast<ExtractMask>(
    260                                    EXTRACT_VALUE | EXTRACT_OPTION_TEXT),
    261                                &form_data,
    262                                NULL)) {
    263     Send(new AutofillHostMsg_FormSubmitted(routing_id(), form_data,
    264                                            base::TimeTicks::Now()));
    265   }
    266 }
    267 
    268 void AutofillAgent::ZoomLevelChanged() {
    269   // Any time the zoom level changes, the page's content moves, so any Autofill
    270   // popups should be hidden. This is only needed for the new Autofill UI
    271   // because WebKit already knows to hide the old UI when this occurs.
    272   HideAutofillUI();
    273 }
    274 
    275 void AutofillAgent::FocusedNodeChanged(const WebKit::WebNode& node) {
    276   if (node.isNull() || !node.isElementNode())
    277     return;
    278 
    279   WebKit::WebElement web_element = node.toConst<WebKit::WebElement>();
    280 
    281   if (!web_element.document().frame())
    282       return;
    283 
    284   const WebInputElement* element = toWebInputElement(&web_element);
    285 
    286   if (!element || !element->isEnabled() || element->isReadOnly() ||
    287       !element->isTextField() || element->isPasswordField())
    288     return;
    289 
    290   element_ = *element;
    291 
    292   MaybeShowAutocheckoutBubble();
    293 }
    294 
    295 void AutofillAgent::MaybeShowAutocheckoutBubble() {
    296   if (element_.isNull() || !element_.focused())
    297     return;
    298 
    299   FormData form;
    300   FormFieldData field;
    301   // This must be called to short circuit this method if it fails.
    302   if (!FindFormAndFieldForInputElement(element_, &form, &field, REQUIRE_NONE))
    303     return;
    304 
    305   Send(new AutofillHostMsg_MaybeShowAutocheckoutBubble(
    306       routing_id(),
    307       form,
    308       GetScaledBoundingBox(web_view_->pageScaleFactor(), &element_)));
    309 }
    310 
    311 void AutofillAgent::DidChangeScrollOffset(WebKit::WebFrame*) {
    312   HideAutofillUI();
    313 }
    314 
    315 void AutofillAgent::didRequestAutocomplete(WebKit::WebFrame* frame,
    316                                            const WebFormElement& form) {
    317   GURL url(frame->document().url());
    318   content::SSLStatus ssl_status = render_view()->GetSSLStatusOfFrame(frame);
    319   FormData form_data;
    320   if (!in_flight_request_form_.isNull() ||
    321       (url.SchemeIs(chrome::kHttpsScheme) &&
    322        (net::IsCertStatusError(ssl_status.cert_status) ||
    323         net::IsCertStatusMinorError(ssl_status.cert_status))) ||
    324       !WebFormElementToFormData(form,
    325                                 WebFormControlElement(),
    326                                 REQUIRE_AUTOCOMPLETE,
    327                                 EXTRACT_OPTIONS,
    328                                 &form_data,
    329                                 NULL)) {
    330     WebFormElement(form).finishRequestAutocomplete(
    331         WebFormElement::AutocompleteResultErrorDisabled);
    332     return;
    333   }
    334 
    335   // Cancel any pending Autofill requests and hide any currently showing popups.
    336   ++autofill_query_id_;
    337   HideAutofillUI();
    338 
    339   in_flight_request_form_ = form;
    340   Send(new AutofillHostMsg_RequestAutocomplete(routing_id(), form_data, url));
    341 }
    342 
    343 void AutofillAgent::setIgnoreTextChanges(bool ignore) {
    344   ignore_text_changes_ = ignore;
    345 }
    346 
    347 void AutofillAgent::InputElementClicked(const WebInputElement& element,
    348                                         bool was_focused,
    349                                         bool is_focused) {
    350   if (was_focused)
    351     ShowSuggestions(element, true, false, true);
    352 }
    353 
    354 void AutofillAgent::InputElementLostFocus() {
    355   HideAutofillUI();
    356 }
    357 
    358 void AutofillAgent::didClearAutofillSelection(const WebNode& node) {
    359   if (password_autofill_agent_->DidClearAutofillSelection(node))
    360     return;
    361 
    362   if (!element_.isNull() && node == element_) {
    363     ClearPreviewedFormWithElement(element_, was_query_node_autofilled_);
    364   } else {
    365     // TODO(isherman): There seem to be rare cases where this code *is*
    366     // reachable: see [ http://crbug.com/96321#c6 ].  Ideally we would
    367     // understand those cases and fix the code to avoid them.  However, so far I
    368     // have been unable to reproduce such a case locally.  If you hit this
    369     // NOTREACHED(), please file a bug against me.
    370     NOTREACHED();
    371   }
    372 }
    373 
    374 void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) {
    375   password_autofill_agent_->TextFieldDidEndEditing(element);
    376   has_shown_autofill_popup_for_current_edit_ = false;
    377   Send(new AutofillHostMsg_DidEndTextFieldEditing(routing_id()));
    378 }
    379 
    380 void AutofillAgent::textFieldDidChange(const WebInputElement& element) {
    381   if (ignore_text_changes_)
    382     return;
    383 
    384   if (did_set_node_text_) {
    385     did_set_node_text_ = false;
    386     return;
    387   }
    388 
    389   // We post a task for doing the Autofill as the caret position is not set
    390   // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and
    391   // it is needed to trigger autofill.
    392   weak_ptr_factory_.InvalidateWeakPtrs();
    393   base::MessageLoop::current()->PostTask(
    394       FROM_HERE,
    395       base::Bind(&AutofillAgent::TextFieldDidChangeImpl,
    396                  weak_ptr_factory_.GetWeakPtr(),
    397                  element));
    398 }
    399 
    400 void AutofillAgent::TextFieldDidChangeImpl(const WebInputElement& element) {
    401   // If the element isn't focused then the changes don't matter. This check is
    402   // required to properly handle IME interactions.
    403   if (!element.focused())
    404     return;
    405 
    406   if (password_autofill_agent_->TextDidChangeInTextField(element)) {
    407     element_ = element;
    408     return;
    409   }
    410 
    411   ShowSuggestions(element, false, true, false);
    412 
    413   FormData form;
    414   FormFieldData field;
    415   if (FindFormAndFieldForInputElement(element, &form, &field, REQUIRE_NONE)) {
    416     Send(new AutofillHostMsg_TextFieldDidChange(routing_id(), form, field,
    417                                                 base::TimeTicks::Now()));
    418   }
    419 }
    420 
    421 void AutofillAgent::textFieldDidReceiveKeyDown(const WebInputElement& element,
    422                                                const WebKeyboardEvent& event) {
    423   if (password_autofill_agent_->TextFieldHandlingKeyDown(element, event)) {
    424     element_ = element;
    425     return;
    426   }
    427 
    428   if (event.windowsKeyCode == ui::VKEY_DOWN ||
    429       event.windowsKeyCode == ui::VKEY_UP)
    430     ShowSuggestions(element, true, true, true);
    431 }
    432 
    433 void AutofillAgent::AcceptDataListSuggestion(
    434     const base::string16& suggested_value) {
    435   base::string16 new_value = suggested_value;
    436   // If this element takes multiple values then replace the last part with
    437   // the suggestion.
    438   if (element_.isMultiple() &&
    439       element_.formControlType() == WebString::fromUTF8("email")) {
    440     std::vector<base::string16> parts;
    441 
    442     base::SplitStringDontTrim(element_.editingValue(), ',', &parts);
    443     if (parts.size() == 0)
    444       parts.push_back(base::string16());
    445 
    446     base::string16 last_part = parts.back();
    447     // We want to keep just the leading whitespace.
    448     for (size_t i = 0; i < last_part.size(); ++i) {
    449       if (!IsWhitespace(last_part[i])) {
    450         last_part = last_part.substr(0, i);
    451         break;
    452       }
    453     }
    454     last_part.append(suggested_value);
    455     parts[parts.size() - 1] = last_part;
    456 
    457     new_value = JoinString(parts, ',');
    458   }
    459   SetNodeText(new_value, &element_);
    460 }
    461 
    462 void AutofillAgent::OnFormDataFilled(int query_id,
    463                                      const FormData& form) {
    464   if (!render_view()->GetWebView() || query_id != autofill_query_id_)
    465     return;
    466 
    467   was_query_node_autofilled_ = element_.isAutofilled();
    468 
    469   switch (autofill_action_) {
    470     case AUTOFILL_FILL:
    471       FillForm(form, element_);
    472       Send(new AutofillHostMsg_DidFillAutofillFormData(routing_id(),
    473                                                        base::TimeTicks::Now()));
    474       break;
    475     case AUTOFILL_PREVIEW:
    476       PreviewForm(form, element_);
    477       Send(new AutofillHostMsg_DidPreviewAutofillFormData(routing_id()));
    478       break;
    479     default:
    480       NOTREACHED();
    481   }
    482   autofill_action_ = AUTOFILL_NONE;
    483 }
    484 
    485 void AutofillAgent::OnFieldTypePredictionsAvailable(
    486     const std::vector<FormDataPredictions>& forms) {
    487   for (size_t i = 0; i < forms.size(); ++i) {
    488     form_cache_.ShowPredictions(forms[i]);
    489   }
    490 }
    491 
    492 void AutofillAgent::OnSetAutofillActionFill() {
    493   autofill_action_ = AUTOFILL_FILL;
    494 }
    495 
    496 void AutofillAgent::OnClearForm() {
    497   form_cache_.ClearFormWithElement(element_);
    498 }
    499 
    500 void AutofillAgent::OnSetAutofillActionPreview() {
    501   autofill_action_ = AUTOFILL_PREVIEW;
    502 }
    503 
    504 void AutofillAgent::OnClearPreviewedForm() {
    505   didClearAutofillSelection(element_);
    506 }
    507 
    508 void AutofillAgent::OnSetNodeText(const base::string16& value) {
    509   SetNodeText(value, &element_);
    510 }
    511 
    512 void AutofillAgent::OnAcceptDataListSuggestion(const base::string16& value) {
    513   AcceptDataListSuggestion(value);
    514 }
    515 
    516 void AutofillAgent::OnAcceptPasswordAutofillSuggestion(
    517     const base::string16& value) {
    518   // We need to make sure this is handled here because the browser process
    519   // skipped it handling because it believed it would be handled here. If it
    520   // isn't handled here then the browser logic needs to be updated.
    521   bool handled = password_autofill_agent_->DidAcceptAutofillSuggestion(
    522       element_,
    523       value);
    524   DCHECK(handled);
    525 }
    526 
    527 void AutofillAgent::OnGetAllForms() {
    528   form_elements_.clear();
    529 
    530   // Force fetch all non empty forms.
    531   std::vector<FormData> forms;
    532   form_cache_.ExtractFormsAndFormElements(
    533       *topmost_frame_, 0, &forms, &form_elements_);
    534 
    535   // OnGetAllForms should only be called if AutofillAgent reported to
    536   // AutofillManager that there are more forms
    537   DCHECK(!forms.empty());
    538 
    539   // Report to AutofillManager that all forms are being sent.
    540   Send(new AutofillHostMsg_FormsSeen(routing_id(), forms,
    541                                      forms_seen_timestamp_,
    542                                      NO_SPECIAL_FORMS_SEEN));
    543 }
    544 
    545 void AutofillAgent::OnRequestAutocompleteResult(
    546     WebFormElement::AutocompleteResult result, const FormData& form_data) {
    547   if (in_flight_request_form_.isNull())
    548     return;
    549 
    550   if (result == WebFormElement::AutocompleteResultSuccess) {
    551     FillFormIncludingNonFocusableElements(form_data, in_flight_request_form_);
    552     if (!in_flight_request_form_.checkValidityWithoutDispatchingEvents())
    553       result = WebFormElement::AutocompleteResultErrorInvalid;
    554   }
    555 
    556   in_flight_request_form_.finishRequestAutocomplete(result);
    557   in_flight_request_form_.reset();
    558 }
    559 
    560 void AutofillAgent::OnFillFormsAndClick(
    561     const std::vector<FormData>& forms,
    562     const std::vector<WebElementDescriptor>& click_elements_before_form_fill,
    563     const std::vector<WebElementDescriptor>& click_elements_after_form_fill,
    564     const WebElementDescriptor& click_element_descriptor) {
    565   DCHECK_EQ(forms.size(), form_elements_.size());
    566 
    567   // Click elements in click_elements_before_form_fill.
    568   for (size_t i = 0; i < click_elements_before_form_fill.size(); ++i) {
    569     if (!ClickElement(topmost_frame_->document(),
    570                       click_elements_before_form_fill[i])) {
    571       CompleteAutocheckoutPage(MISSING_CLICK_ELEMENT_BEFORE_FORM_FILLING);
    572       return;
    573     }
    574   }
    575 
    576   // Fill the form.
    577   for (size_t i = 0; i < forms.size(); ++i)
    578     FillFormForAllElements(forms[i], form_elements_[i]);
    579 
    580   // Click elements in click_elements_after_form_fill.
    581   for (size_t i = 0; i < click_elements_after_form_fill.size(); ++i) {
    582     if (!ClickElement(topmost_frame_->document(),
    583                       click_elements_after_form_fill[i])) {
    584       CompleteAutocheckoutPage(MISSING_CLICK_ELEMENT_AFTER_FORM_FILLING);
    585       return;
    586     }
    587   }
    588 
    589   // Exit early if there is nothing to click.
    590   if (click_element_descriptor.retrieval_method == WebElementDescriptor::NONE) {
    591     CompleteAutocheckoutPage(SUCCESS);
    592     return;
    593   }
    594 
    595   // It's possible that clicking the element to proceed in an Autocheckout
    596   // flow will not actually proceed to the next step in the flow, e.g. there
    597   // is a new required field that Autocheckout does not know how to fill.  In
    598   // order to capture this case and present the user with an error a timer is
    599   // set that informs the browser of the error. |click_timer_| has to be started
    600   // before clicking so it can start before DidStartProvisionalLoad started.
    601   click_timer_.Start(FROM_HERE,
    602                      base::TimeDelta::FromSeconds(kAutocheckoutClickTimeout),
    603                      this,
    604                      &AutofillAgent::ClickFailed);
    605   if (!ClickElement(topmost_frame_->document(),
    606                     click_element_descriptor)) {
    607     CompleteAutocheckoutPage(MISSING_ADVANCE);
    608   }
    609 }
    610 
    611 void AutofillAgent::OnAutocheckoutSupported() {
    612   is_autocheckout_supported_ = true;
    613   if (has_new_forms_for_browser_)
    614     MaybeSendDynamicFormsSeen();
    615   MaybeShowAutocheckoutBubble();
    616 }
    617 
    618 void AutofillAgent::OnPageShown() {
    619   if (is_autocheckout_supported_)
    620     MaybeShowAutocheckoutBubble();
    621 }
    622 
    623 void AutofillAgent::CompleteAutocheckoutPage(
    624     autofill::AutocheckoutStatus status) {
    625   click_timer_.Stop();
    626   Send(new AutofillHostMsg_AutocheckoutPageCompleted(routing_id(), status));
    627 }
    628 
    629 void AutofillAgent::ClickFailed() {
    630   CompleteAutocheckoutPage(CANNOT_PROCEED);
    631 }
    632 
    633 void AutofillAgent::ShowSuggestions(const WebInputElement& element,
    634                                     bool autofill_on_empty_values,
    635                                     bool requires_caret_at_end,
    636                                     bool display_warning_if_disabled) {
    637   if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() ||
    638       element.isPasswordField() || !element.suggestedValue().isEmpty())
    639     return;
    640 
    641   // Don't attempt to autofill with values that are too large or if filling
    642   // criteria are not met.
    643   WebString value = element.editingValue();
    644   if (value.length() > kMaximumTextSizeForAutofill ||
    645       (!autofill_on_empty_values && value.isEmpty()) ||
    646       (requires_caret_at_end &&
    647        (element.selectionStart() != element.selectionEnd() ||
    648         element.selectionEnd() != static_cast<int>(value.length())))) {
    649     // Any popup currently showing is obsolete.
    650     HideAutofillUI();
    651     return;
    652   }
    653 
    654   element_ = element;
    655   if (password_autofill_agent_->ShowSuggestions(element))
    656     return;
    657 
    658   // If autocomplete is disabled at the field level, ensure that the native
    659   // UI won't try to show a warning, since that may conflict with a custom
    660   // popup. Note that we cannot use the WebKit method element.autoComplete()
    661   // as it does not allow us to distinguish the case where autocomplete is
    662   // disabled for *both* the element and for the form.
    663   const base::string16 autocomplete_attribute =
    664       element.getAttribute("autocomplete");
    665   if (LowerCaseEqualsASCII(autocomplete_attribute, "off"))
    666     display_warning_if_disabled = false;
    667 
    668   QueryAutofillSuggestions(element, display_warning_if_disabled);
    669 }
    670 
    671 void AutofillAgent::QueryAutofillSuggestions(const WebInputElement& element,
    672                                              bool display_warning_if_disabled) {
    673   if (!element.document().frame())
    674     return;
    675 
    676   static int query_counter = 0;
    677   autofill_query_id_ = query_counter++;
    678   display_warning_if_disabled_ = display_warning_if_disabled;
    679 
    680   // If autocomplete is disabled at the form level, we want to see if there
    681   // would have been any suggestions were it enabled, so that we can show a
    682   // warning.  Otherwise, we want to ignore fields that disable autocomplete, so
    683   // that the suggestions list does not include suggestions for these form
    684   // fields -- see comment 1 on http://crbug.com/69914
    685   const RequirementsMask requirements =
    686       element.autoComplete() ? REQUIRE_AUTOCOMPLETE : REQUIRE_NONE;
    687 
    688   FormData form;
    689   FormFieldData field;
    690   if (!FindFormAndFieldForInputElement(element, &form, &field, requirements)) {
    691     // If we didn't find the cached form, at least let autocomplete have a shot
    692     // at providing suggestions.
    693     WebFormControlElementToFormField(element, EXTRACT_VALUE, &field);
    694   }
    695 
    696   gfx::RectF bounding_box_scaled =
    697       GetScaledBoundingBox(web_view_->pageScaleFactor(), &element_);
    698 
    699   // Find the datalist values and send them to the browser process.
    700   std::vector<base::string16> data_list_values;
    701   std::vector<base::string16> data_list_labels;
    702   GetDataListSuggestions(element_, &data_list_values, &data_list_labels);
    703   TrimStringVectorForIPC(&data_list_values);
    704   TrimStringVectorForIPC(&data_list_labels);
    705 
    706   Send(new AutofillHostMsg_SetDataList(routing_id(),
    707                                        data_list_values,
    708                                        data_list_labels));
    709 
    710   Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(),
    711                                                   autofill_query_id_,
    712                                                   form,
    713                                                   field,
    714                                                   bounding_box_scaled,
    715                                                   display_warning_if_disabled));
    716 }
    717 
    718 void AutofillAgent::FillAutofillFormData(const WebNode& node,
    719                                          int unique_id,
    720                                          AutofillAction action) {
    721   DCHECK_GT(unique_id, 0);
    722 
    723   static int query_counter = 0;
    724   autofill_query_id_ = query_counter++;
    725 
    726   FormData form;
    727   FormFieldData field;
    728   if (!FindFormAndFieldForInputElement(node.toConst<WebInputElement>(), &form,
    729                                        &field, REQUIRE_AUTOCOMPLETE)) {
    730     return;
    731   }
    732 
    733   autofill_action_ = action;
    734   Send(new AutofillHostMsg_FillAutofillFormData(
    735       routing_id(), autofill_query_id_, form, field, unique_id));
    736 }
    737 
    738 void AutofillAgent::SetNodeText(const base::string16& value,
    739                                 WebKit::WebInputElement* node) {
    740   did_set_node_text_ = true;
    741   base::string16 substring = value;
    742   substring = substring.substr(0, node->maxLength());
    743 
    744   node->setEditingValue(substring);
    745 }
    746 
    747 void AutofillAgent::HideAutofillUI() {
    748   Send(new AutofillHostMsg_HideAutofillUI(routing_id()));
    749 }
    750 
    751 void AutofillAgent::didAssociateFormControls(
    752     const WebKit::WebVector<WebKit::WebNode>& nodes) {
    753   for (size_t i = 0; i < nodes.size(); ++i) {
    754     WebKit::WebNode node = nodes[i];
    755     if (node.document().frame() == topmost_frame_) {
    756       forms_seen_timestamp_ = base::TimeTicks::Now();
    757       has_new_forms_for_browser_ = true;
    758       break;
    759     }
    760   }
    761 
    762   if (has_new_forms_for_browser_ && is_autocheckout_supported_)
    763     MaybeSendDynamicFormsSeen();
    764 }
    765 
    766 void AutofillAgent::MaybeSendDynamicFormsSeen() {
    767   has_new_forms_for_browser_ = false;
    768   form_elements_.clear();
    769   std::vector<FormData> forms;
    770   // This will only be called for Autocheckout flows, so send all forms to
    771   // save an IPC.
    772   form_cache_.ExtractFormsAndFormElements(
    773       *topmost_frame_, 0, &forms, &form_elements_);
    774   autofill::FormsSeenState state = autofill::DYNAMIC_FORMS_SEEN;
    775 
    776   if (!forms.empty()) {
    777     if (click_timer_.IsRunning())
    778       click_timer_.Stop();
    779     Send(new AutofillHostMsg_FormsSeen(routing_id(), forms,
    780                                        forms_seen_timestamp_,
    781                                        state));
    782   }
    783 }
    784 
    785 }  // namespace autofill
    786