blob: d3ff7bfad5dcfb854c2217df99fef13a2d76e0eb [file] [log] [blame]
[email protected]f07e4442013-06-06 23:03:481// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]679f128f2010-07-22 22:57:442// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]f07e4442013-06-06 23:03:485#include "components/autofill/content/renderer/autofill_agent.h"
[email protected]679f128f2010-07-22 22:57:446
avi4310d522015-12-25 19:37:597#include <stddef.h>
8
brettw9c68c512015-11-20 23:26:389#include <tuple>
10
rouslan6a3f8d92015-04-28 01:00:0111#include "base/auto_reset.h"
[email protected]a1cb57f2011-09-28 22:41:2912#include "base/bind.h"
[email protected]f920d6e2013-03-12 20:20:5013#include "base/command_line.h"
brettw94a2cc22015-07-01 19:26:5414#include "base/i18n/case_conversion.h"
skyostilb0daa012015-06-02 19:03:4815#include "base/location.h"
mathp4f6b0382016-04-12 20:41:1216#include "base/metrics/field_trial.h"
skyostilb0daa012015-06-02 19:03:4817#include "base/single_thread_task_runner.h"
mgiuca30f75882017-03-28 02:07:1918#include "base/strings/string_piece.h"
[email protected]1988e1c2013-02-28 20:27:4219#include "base/strings/string_split.h"
[email protected]c72674b2013-06-11 04:16:4320#include "base/strings/string_util.h"
[email protected]d2d79d52013-06-07 22:23:4821#include "base/strings/utf_string_conversions.h"
gab7966d312016-05-11 20:35:0122#include "base/threading/thread_task_runner_handle.h"
[email protected]bbd8da92013-06-28 02:12:2023#include "base/time/time.h"
avi4310d522015-12-25 19:37:5924#include "build/build_config.h"
[email protected]f07e4442013-06-06 23:03:4825#include "components/autofill/content/renderer/form_autofill_util.h"
[email protected]f07e4442013-06-06 23:03:4826#include "components/autofill/content/renderer/password_autofill_agent.h"
[email protected]3cbdf9362014-01-31 23:12:2327#include "components/autofill/content/renderer/password_generation_agent.h"
jwwfb2a1432016-06-13 22:44:1528#include "components/autofill/content/renderer/renderer_save_password_progress_logger.h"
[email protected]d04f81912013-06-18 14:52:1329#include "components/autofill/core/common/autofill_constants.h"
[email protected]d86263dcd2014-01-09 10:35:2130#include "components/autofill/core/common/autofill_data_validation.h"
[email protected]d04f81912013-06-18 14:52:1331#include "components/autofill/core/common/autofill_switches.h"
rouslanc31f81d2015-08-24 17:33:5232#include "components/autofill/core/common/autofill_util.h"
[email protected]d04f81912013-06-18 14:52:1333#include "components/autofill/core/common/form_data.h"
34#include "components/autofill/core/common/form_data_predictions.h"
35#include "components/autofill/core/common/form_field_data.h"
[email protected]e620d362013-09-09 08:01:5336#include "components/autofill/core/common/password_form.h"
jwwfb2a1432016-06-13 22:44:1537#include "components/autofill/core/common/password_form_fill_data.h"
38#include "components/autofill/core/common/save_password_progress_logger.h"
[email protected]fed9d4f2013-12-17 21:32:4739#include "content/public/common/content_switches.h"
Tao Bai88d56d42017-07-17 16:07:1640#include "content/public/common/origin_util.h"
[email protected]ca5190f2013-07-08 11:10:3141#include "content/public/common/url_constants.h"
estadeb1bc9bd2014-12-02 22:44:1142#include "content/public/renderer/render_frame.h"
[email protected]a2ef54c2011-10-10 16:20:3143#include "content/public/renderer/render_view.h"
[email protected]ca5190f2013-07-08 11:10:3144#include "net/cert/cert_status_flags.h"
rockot734fb662016-10-15 16:41:3045#include "services/service_manager/public/cpp/interface_provider.h"
dtapuskaa64845d2017-01-20 21:20:4546#include "third_party/WebKit/public/platform/WebKeyboardEvent.h"
[email protected]f07e4442013-06-06 23:03:4847#include "third_party/WebKit/public/platform/WebURLRequest.h"
[email protected]dbdd60272014-04-14 22:48:4048#include "third_party/WebKit/public/web/WebConsoleMessage.h"
[email protected]a0962a92013-06-20 18:27:3449#include "third_party/WebKit/public/web/WebDocument.h"
[email protected]961783a2014-02-07 18:38:0550#include "third_party/WebKit/public/web/WebElementCollection.h"
[email protected]a0962a92013-06-20 18:27:3451#include "third_party/WebKit/public/web/WebFormControlElement.h"
52#include "third_party/WebKit/public/web/WebFormElement.h"
[email protected]80504652014-04-18 04:41:5053#include "third_party/WebKit/public/web/WebLocalFrame.h"
[email protected]a0962a92013-06-20 18:27:3454#include "third_party/WebKit/public/web/WebNode.h"
[email protected]a0962a92013-06-20 18:27:3455#include "third_party/WebKit/public/web/WebOptionElement.h"
rouslan6a3f8d92015-04-28 01:00:0156#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
[email protected]a0962a92013-06-20 18:27:3457#include "third_party/WebKit/public/web/WebView.h"
[email protected]c051a1b2011-01-21 23:30:1758#include "ui/base/l10n/l10n_util.h"
[email protected]7e9acd082013-09-17 23:31:1659#include "ui/events/keycodes/keyboard_codes.h"
[email protected]679f128f2010-07-22 22:57:4460
[email protected]a1221aea2013-11-07 01:31:3061using blink::WebAutofillClient;
[email protected]dbdd60272014-04-14 22:48:4062using blink::WebConsoleMessage;
rouslanf7ebd8832015-01-22 01:54:1463using blink::WebDocument;
[email protected]5e7e8612014-03-20 14:43:1964using blink::WebElement;
65using blink::WebElementCollection;
[email protected]a1221aea2013-11-07 01:31:3066using blink::WebFormControlElement;
67using blink::WebFormElement;
68using blink::WebFrame;
69using blink::WebInputElement;
70using blink::WebKeyboardEvent;
[email protected]c5041c322014-04-08 05:06:4771using blink::WebLocalFrame;
[email protected]a1221aea2013-11-07 01:31:3072using blink::WebNode;
[email protected]a1221aea2013-11-07 01:31:3073using blink::WebOptionElement;
74using blink::WebString;
rouslan6a3f8d92015-04-28 01:00:0175using blink::WebUserGestureIndicator;
[email protected]5e7e8612014-03-20 14:43:1976using blink::WebVector;
[email protected]679f128f2010-07-22 22:57:4477
[email protected]d86263dcd2014-01-09 10:35:2178namespace autofill {
79
[email protected]e47aec52010-08-12 00:50:3080namespace {
81
mathp4f6b0382016-04-12 20:41:1282// Whether the "single click" autofill feature is enabled, through command-line
83// or field trial.
84bool IsSingleClickEnabled() {
85// On Android, default to showing the dropdown on field focus.
86// On desktop, require an extra click after field focus by default, unless the
87// experiment is active.
88#if defined(OS_ANDROID)
89 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
90 switches::kDisableSingleClickAutofill);
91#endif
92 const std::string group_name =
93 base::FieldTrialList::FindFullName("AutofillSingleClick");
94
95 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
96 switches::kEnableSingleClickAutofill))
97 return true;
98 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
99 switches::kDisableSingleClickAutofill))
100 return false;
101
102 return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE);
103}
104
[email protected]45a07942013-07-26 08:28:21105// Gets all the data list values (with corresponding label) for the given
106// element.
[email protected]5e7e8612014-03-20 14:43:19107void GetDataListSuggestions(const WebInputElement& element,
[email protected]45a07942013-07-26 08:28:21108 std::vector<base::string16>* values,
109 std::vector<base::string16>* labels) {
Blink Reformat1c4d759e2017-04-09 16:34:54110 for (const auto& option : element.FilteredDataListOptions()) {
111 values->push_back(option.Value().Utf16());
112 if (option.Value() != option.Label())
113 labels->push_back(option.Label().Utf16());
[email protected]bef7f9272012-04-17 10:47:49114 else
[email protected]d5ca8fb2013-04-11 17:54:31115 labels->push_back(base::string16());
[email protected]bef7f9272012-04-17 10:47:49116 }
117}
118
[email protected]ead7fb02013-07-18 18:50:12119// Trim the vector before sending it to the browser process to ensure we
[email protected]5c8de6b92012-06-08 21:24:08120// don't send too much data through the IPC.
[email protected]ead7fb02013-07-18 18:50:12121void TrimStringVectorForIPC(std::vector<base::string16>* strings) {
122 // Limit the size of the vector.
[email protected]d86263dcd2014-01-09 10:35:21123 if (strings->size() > kMaxListSize)
124 strings->resize(kMaxListSize);
[email protected]5c8de6b92012-06-08 21:24:08125
[email protected]ead7fb02013-07-18 18:50:12126 // Limit the size of the strings in the vector.
127 for (size_t i = 0; i < strings->size(); ++i) {
[email protected]d86263dcd2014-01-09 10:35:21128 if ((*strings)[i].length() > kMaxDataLength)
129 (*strings)[i].resize(kMaxDataLength);
[email protected]5c8de6b92012-06-08 21:24:08130 }
131}
132
[email protected]e47aec52010-08-12 00:50:30133} // namespace
134
brettwb505b7a2014-11-26 22:05:32135AutofillAgent::ShowSuggestionsOptions::ShowSuggestionsOptions()
136 : autofill_on_empty_values(false),
137 requires_caret_at_end(false),
brettwb505b7a2014-11-26 22:05:32138 show_full_suggestion_list(false),
139 show_password_suggestions_only(false) {
140}
141
estadeb1bc9bd2014-12-02 22:44:11142AutofillAgent::AutofillAgent(content::RenderFrame* render_frame,
[email protected]3cbdf9362014-01-31 23:12:23143 PasswordAutofillAgent* password_autofill_agent,
Ben Goodger205467b2017-08-02 19:33:55144 PasswordGenerationAgent* password_generation_agent,
145 service_manager::BinderRegistry* registry)
estadeb1bc9bd2014-12-02 22:44:11146 : content::RenderFrameObserver(render_frame),
estadeff02e6d2014-12-15 21:18:31147 form_cache_(*render_frame->GetWebFrame()),
[email protected]ad19b302013-04-03 07:42:19148 password_autofill_agent_(password_autofill_agent),
[email protected]3cbdf9362014-01-31 23:12:23149 password_generation_agent_(password_generation_agent),
[email protected]679f128f2010-07-22 22:57:44150 autofill_query_id_(0),
[email protected]d77ddc8062010-11-24 01:14:06151 was_query_node_autofilled_(false),
[email protected]90f26252013-02-15 19:48:32152 ignore_text_changes_(false),
[email protected]b648f242014-02-25 13:49:06153 is_popup_possibly_visible_(false),
gcastocdd33e0d2015-06-17 22:10:05154 is_generation_popup_possibly_visible_(false),
Tao Baie13b5ca2017-06-23 16:15:51155 is_user_gesture_required_(true),
Tao Bai88d56d42017-07-17 16:07:16156 is_secure_context_required_(false),
ekaramad27ca69b12017-04-20 18:34:29157 page_click_tracker_(new PageClickTracker(render_frame, this)),
leon.han90fd63b2016-07-26 01:23:55158 binding_(this),
[email protected]2c305252013-04-26 19:57:05159 weak_ptr_factory_(this) {
Blink Reformat1c4d759e2017-04-09 16:34:54160 render_frame->GetWebFrame()->SetAutofillClient(this);
leon.han90fd63b2016-07-26 01:23:55161 password_autofill_agent->SetAutofillAgent(this);
estade78d655f82015-01-30 01:55:08162
Ben Goodger205467b2017-08-02 19:33:55163 registry->AddInterface(
leon.hande852902016-05-04 09:16:38164 base::Bind(&AutofillAgent::BindRequest, base::Unretained(this)));
[email protected]679f128f2010-07-22 22:57:44165}
166
[email protected]a64fdc32013-07-31 09:21:13167AutofillAgent::~AutofillAgent() {}
[email protected]d2f05d02011-01-27 18:51:01168
Ben Goodger21ada1e2017-07-19 14:53:01169void AutofillAgent::BindRequest(mojom::AutofillAgentRequest request) {
leon.han90fd63b2016-07-26 01:23:55170 binding_.Bind(std::move(request));
leon.hande852902016-05-04 09:16:38171}
172
mathp692aba82015-03-06 20:55:02173bool AutofillAgent::FormDataCompare::operator()(const FormData& lhs,
174 const FormData& rhs) const {
brettw9c68c512015-11-20 23:26:38175 return std::tie(lhs.name, lhs.origin, lhs.action, lhs.is_form_tag) <
176 std::tie(rhs.name, rhs.origin, rhs.action, rhs.is_form_tag);
mathp692aba82015-03-06 20:55:02177}
178
mlamouri9ef14c22015-02-27 13:30:54179void AutofillAgent::DidCommitProvisionalLoad(bool is_new_navigation,
eugenebut5ae751e2017-03-28 17:10:37180 bool is_same_document_navigation) {
mathpffc78e22015-09-01 14:10:50181 blink::WebFrame* frame = render_frame()->GetWebFrame();
182 // TODO(dvadym): check if we need to check if it is main frame navigation
183 // http://crbug.com/443155
Blink Reformat1c4d759e2017-04-09 16:34:54184 if (frame->Parent())
mathpffc78e22015-09-01 14:10:50185 return; // Not a top-level navigation.
186
eugenebut5ae751e2017-03-28 17:10:37187 if (is_same_document_navigation) {
188 OnSameDocumentNavigationCompleted();
rouslan6f1f93c2015-10-07 22:17:30189 } else {
190 // Navigation to a new page or a page refresh.
mathpffc78e22015-09-01 14:10:50191 form_cache_.Reset();
192 submitted_forms_.clear();
Blink Reformat1c4d759e2017-04-09 16:34:54193 last_interacted_form_.Reset();
tmartino283dda12016-06-23 21:43:54194 formless_elements_user_edited_.clear();
mathpffc78e22015-09-01 14:10:50195 }
[email protected]676126f72011-01-15 00:03:51196}
197
estadeb1bc9bd2014-12-02 22:44:11198void AutofillAgent::DidFinishDocumentLoad() {
199 ProcessForms();
[email protected]3609c962014-07-11 03:18:25200}
201
mathp692aba82015-03-06 20:55:02202void AutofillAgent::WillSendSubmitEvent(const WebFormElement& form) {
tmartino1c5348c92016-05-26 18:50:56203 FireHostSubmitEvents(form, /*form_submitted=*/false);
mathp692aba82015-03-06 20:55:02204}
205
estade13da3e42014-12-18 02:10:24206void AutofillAgent::WillSubmitForm(const WebFormElement& form) {
tmartino1c5348c92016-05-26 18:50:56207 FireHostSubmitEvents(form, /*form_submitted=*/true);
[email protected]2a5b1732011-04-01 23:55:55208}
209
estade2792527072014-12-17 00:41:47210void AutofillAgent::DidChangeScrollOffset() {
rouslanc31f81d2015-08-24 17:33:52211 if (IsKeyboardAccessoryEnabled())
estadeb5efbab62015-04-28 18:07:42212 return;
rouslanc31f81d2015-08-24 17:33:52213
estadeb1bc9bd2014-12-02 22:44:11214 HidePopup();
215}
216
[email protected]5e7e8612014-03-20 14:43:19217void AutofillAgent::FocusedNodeChanged(const WebNode& node) {
ekaramad27ca69b12017-04-20 18:34:29218 page_click_tracker_->FocusedNodeChanged(node);
219
[email protected]91dcc6d32014-07-30 00:01:33220 HidePopup();
221
Blink Reformat1c4d759e2017-04-09 16:34:54222 if (node.IsNull() || !node.IsElementNode()) {
223 if (!last_interacted_form_.IsNull()) {
mathp8ac68ce2015-12-08 21:49:06224 // Focus moved away from the last interacted form to somewhere else on
225 // the page.
leon.han90fd63b2016-07-26 01:23:55226 GetAutofillDriver()->FocusNoLongerOnForm();
mathp8ac68ce2015-12-08 21:49:06227 }
estadeb1bc9bd2014-12-02 22:44:11228 return;
mathp8ac68ce2015-12-08 21:49:06229 }
estadeb1bc9bd2014-12-02 22:44:11230
Blink Reformat1c4d759e2017-04-09 16:34:54231 WebElement web_element = node.ToConst<WebElement>();
232 const WebInputElement* element = ToWebInputElement(&web_element);
mathpb4cf7b82015-12-11 16:42:24233
Blink Reformat1c4d759e2017-04-09 16:34:54234 if (!last_interacted_form_.IsNull() &&
235 (!element || last_interacted_form_ != element->Form())) {
mathp8ac68ce2015-12-08 21:49:06236 // The focused element is not part of the last interacted form (could be
237 // in a different form).
leon.han90fd63b2016-07-26 01:23:55238 GetAutofillDriver()->FocusNoLongerOnForm();
mathp8ac68ce2015-12-08 21:49:06239 return;
240 }
[email protected]f920d6e2013-03-12 20:20:50241
Blink Reformat1c4d759e2017-04-09 16:34:54242 if (!element || !element->IsEnabled() || element->IsReadOnly() ||
243 !element->IsTextField())
[email protected]f920d6e2013-03-12 20:20:50244 return;
245
[email protected]e5057a22013-04-22 12:41:39246 element_ = *element;
Tao Bai168e4fc2017-06-19 18:46:38247
248 FormData form;
249 FormFieldData field;
250 if (form_util::FindFormAndFieldForFormControlElement(element_, &form,
251 &field)) {
252 GetAutofillDriver()->FocusOnFormField(
253 form, field,
254 render_frame()->GetRenderView()->ElementBoundsInWindow(element_));
255 }
[email protected]e5057a22013-04-22 12:41:39256}
257
vabrd62bc3e2016-05-04 15:58:52258void AutofillAgent::OnDestruct() {
259 Shutdown();
260 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
261}
262
tmartino1c5348c92016-05-26 18:50:56263void AutofillAgent::FireHostSubmitEvents(const WebFormElement& form,
264 bool form_submitted) {
265 FormData form_data;
266 if (!form_util::ExtractFormData(form, &form_data))
267 return;
268
269 FireHostSubmitEvents(form_data, form_submitted);
270}
271
272void AutofillAgent::FireHostSubmitEvents(const FormData& form_data,
273 bool form_submitted) {
274 // We remember when we have fired this IPC for this form in this frame load,
275 // because forms with a submit handler may fire both WillSendSubmitEvent
276 // and WillSubmitForm, and we don't want duplicate messages.
277 if (!submitted_forms_.count(form_data)) {
leon.han90fd63b2016-07-26 01:23:55278 GetAutofillDriver()->WillSubmitForm(form_data, base::TimeTicks::Now());
tmartino1c5348c92016-05-26 18:50:56279 submitted_forms_.insert(form_data);
280 }
281
leon.han90fd63b2016-07-26 01:23:55282 if (form_submitted) {
283 GetAutofillDriver()->FormSubmitted(form_data);
284 }
tmartino1c5348c92016-05-26 18:50:56285}
286
vabrd62bc3e2016-05-04 15:58:52287void AutofillAgent::Shutdown() {
leon.han7e8c85b2016-09-08 14:24:42288 binding_.Close();
vabrd62bc3e2016-05-04 15:58:52289 weak_ptr_factory_.InvalidateWeakPtrs();
290}
291
rouslanf7ebd8832015-01-22 01:54:14292
[email protected]e9d29d392014-03-25 01:15:15293void AutofillAgent::FormControlElementClicked(
294 const WebFormControlElement& element,
295 bool was_focused) {
Blink Reformat1c4d759e2017-04-09 16:34:54296 const WebInputElement* input_element = ToWebInputElement(&element);
mathp9172c62a2015-10-08 18:51:14297 if (!input_element && !form_util::IsTextAreaElement(element))
[email protected]e9d29d392014-03-25 01:15:15298 return;
299
brettwb505b7a2014-11-26 22:05:32300 ShowSuggestionsOptions options;
301 options.autofill_on_empty_values = true;
Blink Reformat1c4d759e2017-04-09 16:34:54302 options.show_full_suggestion_list = element.IsAutofilled();
gcasto2c6462272014-11-04 01:14:11303
mathp4f6b0382016-04-12 20:41:12304 if (!IsSingleClickEnabled()) {
brettwb505b7a2014-11-26 22:05:32305 // Show full suggestions when clicking on an already-focused form field. On
306 // the initial click (not focused yet), only show password suggestions.
brettwb505b7a2014-11-26 22:05:32307 options.show_full_suggestion_list =
308 options.show_full_suggestion_list || was_focused;
309 options.show_password_suggestions_only = !was_focused;
gcasto2c6462272014-11-04 01:14:11310 }
brettwb505b7a2014-11-26 22:05:32311 ShowSuggestions(element, options);
[email protected]676126f72011-01-15 00:03:51312}
313
Blink Reformat1c4d759e2017-04-09 16:34:54314void AutofillAgent::TextFieldDidEndEditing(const WebInputElement& element) {
leon.han90fd63b2016-07-26 01:23:55315 GetAutofillDriver()->DidEndTextFieldEditing();
[email protected]676126f72011-01-15 00:03:51316}
317
Tao Baie13b5ca2017-06-23 16:15:51318void AutofillAgent::SetUserGestureRequired(bool required) {
319 is_user_gesture_required_ = required;
320}
321
Blink Reformat1c4d759e2017-04-09 16:34:54322void AutofillAgent::TextFieldDidChange(const WebFormControlElement& element) {
323 DCHECK(ToWebInputElement(&element) || form_util::IsTextAreaElement(element));
ellyjonesdb20fae12015-12-04 16:47:55324
[email protected]90f26252013-02-15 19:48:32325 if (ignore_text_changes_)
326 return;
327
ellyjonesdb20fae12015-12-04 16:47:55328 // Disregard text changes that aren't caused by user gestures or pastes. Note
329 // that pastes aren't necessarily user gestures because Blink's conception of
330 // user gestures is centered around creating new windows/tabs.
Tao Baie13b5ca2017-06-23 16:15:51331 if (is_user_gesture_required_ && !IsUserGesture() &&
332 !render_frame()->IsPasting())
[email protected]b96a1d12012-11-30 22:44:32333 return;
[email protected]b37043c2012-05-31 17:08:12334
[email protected]663bd9e2011-03-21 01:07:01335 // We post a task for doing the Autofill as the caret position is not set
[email protected]676126f72011-01-15 00:03:51336 // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and
337 // it is needed to trigger autofill.
[email protected]5219146e2013-02-28 11:42:30338 weak_ptr_factory_.InvalidateWeakPtrs();
skyostilb0daa012015-06-02 19:03:48339 base::ThreadTaskRunnerHandle::Get()->PostTask(
340 FROM_HERE, base::Bind(&AutofillAgent::TextFieldDidChangeImpl,
341 weak_ptr_factory_.GetWeakPtr(), element));
[email protected]676126f72011-01-15 00:03:51342}
343
[email protected]e9d29d392014-03-25 01:15:15344void AutofillAgent::TextFieldDidChangeImpl(
345 const WebFormControlElement& element) {
[email protected]f9af2832012-12-14 04:20:43346 // If the element isn't focused then the changes don't matter. This check is
347 // required to properly handle IME interactions.
Blink Reformat1c4d759e2017-04-09 16:34:54348 if (!element.Focused())
[email protected]f9af2832012-12-14 04:20:43349 return;
350
Blink Reformat1c4d759e2017-04-09 16:34:54351 const WebInputElement* input_element = ToWebInputElement(&element);
[email protected]e9d29d392014-03-25 01:15:15352 if (input_element) {
mathpffc78e22015-09-01 14:10:50353 // Remember the last form the user interacted with.
Blink Reformat1c4d759e2017-04-09 16:34:54354 if (element.Form().IsNull()) {
tmartino283dda12016-06-23 21:43:54355 formless_elements_user_edited_.insert(element);
356 } else {
Blink Reformat1c4d759e2017-04-09 16:34:54357 last_interacted_form_ = element.Form();
tmartino283dda12016-06-23 21:43:54358 }
mathpffc78e22015-09-01 14:10:50359
gcasto5c13d762015-06-03 23:44:45360 // |password_autofill_agent_| keeps track of all text changes even if
361 // it isn't displaying UI.
362 password_autofill_agent_->UpdateStateForTextChange(*input_element);
363
[email protected]e9d29d392014-03-25 01:15:15364 if (password_generation_agent_ &&
365 password_generation_agent_->TextDidChangeInTextField(*input_element)) {
[email protected]7e048272014-04-17 03:38:52366 is_popup_possibly_visible_ = true;
[email protected]e9d29d392014-03-25 01:15:15367 return;
368 }
[email protected]3cbdf9362014-01-31 23:12:23369
[email protected]e9d29d392014-03-25 01:15:15370 if (password_autofill_agent_->TextDidChangeInTextField(*input_element)) {
rouslan2f5993f2015-01-29 00:18:31371 is_popup_possibly_visible_ = true;
[email protected]e9d29d392014-03-25 01:15:15372 element_ = element;
373 return;
374 }
[email protected]e7e83472012-04-05 02:56:26375 }
[email protected]676126f72011-01-15 00:03:51376
brettwb505b7a2014-11-26 22:05:32377 ShowSuggestionsOptions options;
378 options.requires_caret_at_end = true;
379 ShowSuggestions(element, options);
[email protected]7d24db72011-08-26 06:02:31380
[email protected]1ecbe862012-10-05 01:29:14381 FormData form;
382 FormFieldData field;
mathp9172c62a2015-10-08 18:51:14383 if (form_util::FindFormAndFieldForFormControlElement(element, &form,
384 &field)) {
Tao Bai168e4fc2017-06-19 18:46:38385 GetAutofillDriver()->TextFieldDidChange(
386 form, field,
387 render_frame()->GetRenderView()->ElementBoundsInWindow(element),
388 base::TimeTicks::Now());
[email protected]1d14f582011-09-02 20:42:04389 }
[email protected]676126f72011-01-15 00:03:51390}
391
Blink Reformat1c4d759e2017-04-09 16:34:54392void AutofillAgent::TextFieldDidReceiveKeyDown(const WebInputElement& element,
[email protected]2fa18c22011-06-14 23:40:43393 const WebKeyboardEvent& event) {
Blink Reformat1c4d759e2017-04-09 16:34:54394 if (event.windows_key_code == ui::VKEY_DOWN ||
395 event.windows_key_code == ui::VKEY_UP) {
brettwb505b7a2014-11-26 22:05:32396 ShowSuggestionsOptions options;
397 options.autofill_on_empty_values = true;
398 options.requires_caret_at_end = true;
brettwb505b7a2014-11-26 22:05:32399 ShowSuggestions(element, options);
400 }
[email protected]efeb565f2013-12-12 17:16:41401}
402
Blink Reformat1c4d759e2017-04-09 16:34:54403void AutofillAgent::OpenTextDataListChooser(const WebInputElement& element) {
brettwb505b7a2014-11-26 22:05:32404 ShowSuggestionsOptions options;
405 options.autofill_on_empty_values = true;
brettwb505b7a2014-11-26 22:05:32406 ShowSuggestions(element, options);
[email protected]676126f72011-01-15 00:03:51407}
408
Blink Reformat1c4d759e2017-04-09 16:34:54409void AutofillAgent::DataListOptionsChanged(const WebInputElement& element) {
410 if (!is_popup_possibly_visible_ || !element.Focused())
estadedf5088a2014-12-15 02:04:07411 return;
412
413 TextFieldDidChangeImpl(element);
414}
415
vasiliifd0e8ca2017-04-12 11:11:22416void AutofillAgent::UserGestureObserved() {
417 password_autofill_agent_->UserGestureObserved();
[email protected]fc22ae52014-04-23 13:48:04418}
419
leon.han90fd63b2016-07-26 01:23:55420void AutofillAgent::DoAcceptDataListSuggestion(
[email protected]d5ca8fb2013-04-11 17:54:31421 const base::string16& suggested_value) {
Blink Reformat1c4d759e2017-04-09 16:34:54422 WebInputElement* input_element = ToWebInputElement(&element_);
[email protected]e9d29d392014-03-25 01:15:15423 DCHECK(input_element);
[email protected]d5ca8fb2013-04-11 17:54:31424 base::string16 new_value = suggested_value;
[email protected]71a90b32012-05-18 09:16:53425 // If this element takes multiple values then replace the last part with
426 // the suggestion.
Blink Reformat1c4d759e2017-04-09 16:34:54427 if (input_element->IsMultiple() && input_element->IsEmailField()) {
Matt Giuca93bc1582017-08-01 05:09:57428 base::string16 value = input_element->EditingValue().Utf16();
429 std::vector<base::StringPiece16> parts =
430 base::SplitStringPiece(value, base::ASCIIToUTF16(","),
431 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
[email protected]71a90b32012-05-18 09:16:53432 if (parts.size() == 0)
mgiuca30f75882017-03-28 02:07:19433 parts.push_back(base::StringPiece16());
[email protected]71a90b32012-05-18 09:16:53434
mgiuca30f75882017-03-28 02:07:19435 base::string16 last_part = parts.back().as_string();
[email protected]71a90b32012-05-18 09:16:53436 // We want to keep just the leading whitespace.
437 for (size_t i = 0; i < last_part.size(); ++i) {
brettwb3413062015-06-24 00:39:02438 if (!base::IsUnicodeWhitespace(last_part[i])) {
[email protected]71a90b32012-05-18 09:16:53439 last_part = last_part.substr(0, i);
440 break;
441 }
442 }
443 last_part.append(suggested_value);
thestigee1440b2016-07-08 01:06:55444 parts.back() = last_part;
[email protected]71a90b32012-05-18 09:16:53445
brettwd94a22142015-07-15 05:19:26446 new_value = base::JoinString(parts, base::ASCIIToUTF16(","));
[email protected]71a90b32012-05-18 09:16:53447 }
leon.han90fd63b2016-07-26 01:23:55448 DoFillFieldWithValue(new_value, input_element);
[email protected]63560b32014-03-04 07:06:26449}
450
leon.hande852902016-05-04 09:16:38451// mojom::AutofillAgent:
leon.han90fd63b2016-07-26 01:23:55452void AutofillAgent::FillForm(int32_t id, const FormData& form) {
mathpf43ced42016-08-04 18:28:23453 if (id != autofill_query_id_ && id != kNoQueryId)
leon.han90fd63b2016-07-26 01:23:55454 return;
455
Blink Reformat1c4d759e2017-04-09 16:34:54456 was_query_node_autofilled_ = element_.IsAutofilled();
leon.han90fd63b2016-07-26 01:23:55457 form_util::FillForm(form, element_);
Blink Reformat1c4d759e2017-04-09 16:34:54458 if (!element_.Form().IsNull())
459 last_interacted_form_ = element_.Form();
leon.han90fd63b2016-07-26 01:23:55460
461 GetAutofillDriver()->DidFillAutofillFormData(form, base::TimeTicks::Now());
[email protected]8527a78f2014-06-12 12:49:15462}
463
leon.han90fd63b2016-07-26 01:23:55464void AutofillAgent::PreviewForm(int32_t id, const FormData& form) {
465 if (id != autofill_query_id_)
[email protected]63560b32014-03-04 07:06:26466 return;
467
Blink Reformat1c4d759e2017-04-09 16:34:54468 was_query_node_autofilled_ = element_.IsAutofilled();
mathp9172c62a2015-10-08 18:51:14469 form_util::PreviewForm(form, element_);
leon.han90fd63b2016-07-26 01:23:55470
471 GetAutofillDriver()->DidPreviewAutofillFormData();
[email protected]6f001a6cf2012-02-09 15:21:53472}
473
leon.han90fd63b2016-07-26 01:23:55474void AutofillAgent::FieldTypePredictionsAvailable(
leon.han35ae41c2016-07-29 03:30:58475 const std::vector<FormDataPredictions>& forms) {
leon.han90fd63b2016-07-26 01:23:55476 for (const auto& form : forms) {
477 form_cache_.ShowPredictions(form);
478 }
479}
480
481void AutofillAgent::ClearForm() {
[email protected]bef7f9272012-04-17 10:47:49482 form_cache_.ClearFormWithElement(element_);
[email protected]6f001a6cf2012-02-09 15:21:53483}
484
leon.han90fd63b2016-07-26 01:23:55485void AutofillAgent::ClearPreviewedForm() {
Blink Reformat1c4d759e2017-04-09 16:34:54486 if (!element_.IsNull()) {
[email protected]b5b1d69f2014-01-23 23:49:32487 if (password_autofill_agent_->DidClearAutofillSelection(element_))
488 return;
489
mathp9172c62a2015-10-08 18:51:14490 form_util::ClearPreviewedFormWithElement(element_,
491 was_query_node_autofilled_);
[email protected]93f2e502013-12-20 09:47:25492 } else {
493 // TODO(isherman): There seem to be rare cases where this code *is*
494 // reachable: see [ http://crbug.com/96321#c6 ]. Ideally we would
495 // understand those cases and fix the code to avoid them. However, so far I
496 // have been unable to reproduce such a case locally. If you hit this
497 // NOTREACHED(), please file a bug against me.
498 NOTREACHED();
499 }
[email protected]6f001a6cf2012-02-09 15:21:53500}
501
leon.han35ae41c2016-07-29 03:30:58502void AutofillAgent::FillFieldWithValue(const base::string16& value) {
Blink Reformat1c4d759e2017-04-09 16:34:54503 WebInputElement* input_element = ToWebInputElement(&element_);
ziran.sunee0fd4432014-08-27 10:10:49504 if (input_element) {
leon.han35ae41c2016-07-29 03:30:58505 DoFillFieldWithValue(value, input_element);
Blink Reformat1c4d759e2017-04-09 16:34:54506 input_element->SetAutofilled(true);
ziran.sunee0fd4432014-08-27 10:10:49507 }
[email protected]ac9b92f2014-03-15 00:48:32508}
509
leon.han35ae41c2016-07-29 03:30:58510void AutofillAgent::PreviewFieldWithValue(const base::string16& value) {
Blink Reformat1c4d759e2017-04-09 16:34:54511 WebInputElement* input_element = ToWebInputElement(&element_);
[email protected]e9d29d392014-03-25 01:15:15512 if (input_element)
leon.han35ae41c2016-07-29 03:30:58513 DoPreviewFieldWithValue(value, input_element);
[email protected]6f001a6cf2012-02-09 15:21:53514}
515
leon.han35ae41c2016-07-29 03:30:58516void AutofillAgent::AcceptDataListSuggestion(const base::string16& value) {
517 DoAcceptDataListSuggestion(value);
[email protected]5c8de6b92012-06-08 21:24:08518}
519
leon.han35ae41c2016-07-29 03:30:58520void AutofillAgent::FillPasswordSuggestion(const base::string16& username,
521 const base::string16& password) {
522 bool handled =
523 password_autofill_agent_->FillSuggestion(element_, username, password);
[email protected]126b1ad2014-05-21 22:37:33524 DCHECK(handled);
525}
526
leon.han35ae41c2016-07-29 03:30:58527void AutofillAgent::PreviewPasswordSuggestion(const base::string16& username,
528 const base::string16& password) {
kinuko0073e7c82017-01-24 00:42:40529 bool handled = password_autofill_agent_->PreviewSuggestion(
Blink Reformat1c4d759e2017-04-09 16:34:54530 element_, blink::WebString::FromUTF16(username),
531 blink::WebString::FromUTF16(password));
[email protected]e7e83472012-04-05 02:56:26532 DCHECK(handled);
533}
534
leon.han90fd63b2016-07-26 01:23:55535void AutofillAgent::ShowInitialPasswordAccountSuggestions(
536 int32_t key,
jwwfb2a1432016-06-13 22:44:15537 const PasswordFormFillData& form_data) {
538 std::vector<blink::WebInputElement> elements;
539 std::unique_ptr<RendererSavePasswordProgressLogger> logger;
540 if (password_autofill_agent_->logging_state_active()) {
leon.han97e8f752016-09-06 06:13:20541 logger.reset(new RendererSavePasswordProgressLogger(
542 GetPasswordManagerDriver().get()));
jwwfb2a1432016-06-13 22:44:15543 logger->LogMessage(SavePasswordProgressLogger::
544 STRING_ON_SHOW_INITIAL_PASSWORD_ACCOUNT_SUGGESTIONS);
545 }
546 password_autofill_agent_->GetFillableElementFromFormData(
547 key, form_data, logger.get(), &elements);
548
549 // If wait_for_username is true, we don't want to initially show form options
550 // until the user types in a valid username.
551 if (form_data.wait_for_username)
552 return;
553
554 ShowSuggestionsOptions options;
555 options.autofill_on_empty_values = true;
556 options.show_full_suggestion_list = true;
557 for (auto element : elements)
558 ShowSuggestions(element, options);
559}
560
estark50592c02017-01-04 01:52:40561void AutofillAgent::ShowNotSecureWarning(
562 const blink::WebInputElement& element) {
563 if (is_generation_popup_possibly_visible_)
564 return;
estark50592c02017-01-04 01:52:40565 password_autofill_agent_->ShowNotSecureWarning(element);
566 is_popup_possibly_visible_ = true;
567}
568
eugenebut5ae751e2017-03-28 17:10:37569void AutofillAgent::OnSameDocumentNavigationCompleted() {
Blink Reformat1c4d759e2017-04-09 16:34:54570 if (last_interacted_form_.IsNull()) {
tmartino283dda12016-06-23 21:43:54571 // If no last interacted form is available (i.e., there is no form tag),
572 // we check if all the elements the user has interacted with are gone,
573 // to decide if submission has occurred.
574 if (formless_elements_user_edited_.size() == 0 ||
575 form_util::IsSomeControlElementVisible(formless_elements_user_edited_))
576 return;
577
578 FormData constructed_form;
579 if (CollectFormlessElements(&constructed_form))
580 FireHostSubmitEvents(constructed_form, /*form_submitted=*/true);
581 } else {
582 // Otherwise, assume form submission only if the form is now gone, either
583 // invisible or removed from the DOM.
tmartino1c5348c92016-05-26 18:50:56584 if (form_util::AreFormContentsVisible(last_interacted_form_))
585 return;
mathpffc78e22015-09-01 14:10:50586
tmartino1c5348c92016-05-26 18:50:56587 FireHostSubmitEvents(last_interacted_form_, /*form_submitted=*/true);
tmartino1c5348c92016-05-26 18:50:56588 }
tmartino283dda12016-06-23 21:43:54589
Blink Reformat1c4d759e2017-04-09 16:34:54590 last_interacted_form_.Reset();
tmartino283dda12016-06-23 21:43:54591 formless_elements_user_edited_.clear();
592}
593
594bool AutofillAgent::CollectFormlessElements(FormData* output) {
Blink Reformat1c4d759e2017-04-09 16:34:54595 WebDocument document = render_frame()->GetWebFrame()->GetDocument();
tmartino283dda12016-06-23 21:43:54596
597 // Build up the FormData from the unowned elements. This logic mostly
598 // mirrors the construction of the synthetic form in form_cache.cc, but
599 // happens at submit-time so we can capture the modifications the user
600 // has made, and doesn't depend on form_cache's internal state.
601 std::vector<WebElement> fieldsets;
602 std::vector<WebFormControlElement> control_elements =
Blink Reformat1c4d759e2017-04-09 16:34:54603 form_util::GetUnownedAutofillableFormFieldElements(document.All(),
tmartino283dda12016-06-23 21:43:54604 &fieldsets);
605
606 if (control_elements.size() > form_util::kMaxParseableFields)
607 return false;
608
609 const form_util::ExtractMask extract_mask =
610 static_cast<form_util::ExtractMask>(form_util::EXTRACT_VALUE |
611 form_util::EXTRACT_OPTIONS);
612
613 return form_util::UnownedCheckoutFormElementsAndFieldSetsToFormData(
614 fieldsets, control_elements, nullptr, document, extract_mask, output,
615 nullptr);
mathpffc78e22015-09-01 14:10:50616}
617
[email protected]e9d29d392014-03-25 01:15:15618void AutofillAgent::ShowSuggestions(const WebFormControlElement& element,
brettwb505b7a2014-11-26 22:05:32619 const ShowSuggestionsOptions& options) {
Blink Reformat1c4d759e2017-04-09 16:34:54620 if (!element.IsEnabled() || element.IsReadOnly())
[email protected]efeb565f2013-12-12 17:16:41621 return;
Blink Reformat1c4d759e2017-04-09 16:34:54622 if (!element.SuggestedValue().IsEmpty())
[email protected]580c38052014-07-16 07:28:09623 return;
[email protected]e9d29d392014-03-25 01:15:15624
Blink Reformat1c4d759e2017-04-09 16:34:54625 const WebInputElement* input_element = ToWebInputElement(&element);
[email protected]e9d29d392014-03-25 01:15:15626 if (input_element) {
Blink Reformat1c4d759e2017-04-09 16:34:54627 if (!input_element->IsTextField())
[email protected]e9d29d392014-03-25 01:15:15628 return;
Blink Reformat1c4d759e2017-04-09 16:34:54629 if (!input_element->SuggestedValue().IsEmpty())
[email protected]e9d29d392014-03-25 01:15:15630 return;
631 } else {
mathp9172c62a2015-10-08 18:51:14632 DCHECK(form_util::IsTextAreaElement(element));
Blink Reformat1c4d759e2017-04-09 16:34:54633 if (!element.ToConst<WebFormControlElement>().SuggestedValue().IsEmpty())
[email protected]e9d29d392014-03-25 01:15:15634 return;
635 }
[email protected]e47aec52010-08-12 00:50:30636
[email protected]1c69f8b72012-03-14 03:18:50637 // Don't attempt to autofill with values that are too large or if filling
638 // criteria are not met.
Blink Reformat1c4d759e2017-04-09 16:34:54639 WebString value = element.EditingValue();
mathp5f90bce22015-11-22 20:16:58640 if (value.length() > kMaxDataLength ||
Blink Reformat1c4d759e2017-04-09 16:34:54641 (!options.autofill_on_empty_values && value.IsEmpty()) ||
mathp5f90bce22015-11-22 20:16:58642 (options.requires_caret_at_end &&
Blink Reformat1c4d759e2017-04-09 16:34:54643 (element.SelectionStart() != element.SelectionEnd() ||
644 element.SelectionEnd() != static_cast<int>(value.length())))) {
[email protected]1c69f8b72012-03-14 03:18:50645 // Any popup currently showing is obsolete.
[email protected]b648f242014-02-25 13:49:06646 HidePopup();
[email protected]e47aec52010-08-12 00:50:30647 return;
[email protected]1c69f8b72012-03-14 03:18:50648 }
[email protected]e47aec52010-08-12 00:50:30649
[email protected]bef7f9272012-04-17 10:47:49650 element_ = element;
mathp9172c62a2015-10-08 18:51:14651 if (form_util::IsAutofillableInputElement(input_element) &&
gcastocdd33e0d2015-06-17 22:10:05652 password_autofill_agent_->ShowSuggestions(
653 *input_element, options.show_full_suggestion_list,
654 is_generation_popup_possibly_visible_)) {
[email protected]b648f242014-02-25 13:49:06655 is_popup_possibly_visible_ = true;
[email protected]c66ba982013-04-05 09:56:17656 return;
[email protected]b648f242014-02-25 13:49:06657 }
[email protected]bef7f9272012-04-17 10:47:49658
gcastocdd33e0d2015-06-17 22:10:05659 if (is_generation_popup_possibly_visible_)
660 return;
661
662 if (options.show_password_suggestions_only)
663 return;
664
jww20355072014-12-12 21:00:55665 // Password field elements should only have suggestions shown by the password
666 // autofill agent.
Blink Reformat1c4d759e2017-04-09 16:34:54667 if (input_element && input_element->IsPasswordField())
jww20355072014-12-12 21:00:55668 return;
669
mathp5f90bce22015-11-22 20:16:58670 QueryAutofillSuggestions(element);
[email protected]77bb0da2010-11-20 01:55:30671}
672
Tao Bai88d56d42017-07-17 16:07:16673void AutofillAgent::SetSecureContextRequired(bool required) {
674 is_secure_context_required_ = required;
675}
676
[email protected]e9d29d392014-03-25 01:15:15677void AutofillAgent::QueryAutofillSuggestions(
mathp5f90bce22015-11-22 20:16:58678 const WebFormControlElement& element) {
Blink Reformat1c4d759e2017-04-09 16:34:54679 if (!element.GetDocument().GetFrame())
[email protected]e69b5f72013-01-24 00:59:13680 return;
681
Blink Reformat1c4d759e2017-04-09 16:34:54682 DCHECK(ToWebInputElement(&element) || form_util::IsTextAreaElement(element));
[email protected]e9d29d392014-03-25 01:15:15683
[email protected]77bb0da2010-11-20 01:55:30684 static int query_counter = 0;
685 autofill_query_id_ = query_counter++;
estade0ee91262014-10-23 19:29:19686
[email protected]1ecbe862012-10-05 01:29:14687 FormData form;
688 FormFieldData field;
mathp9172c62a2015-10-08 18:51:14689 if (!form_util::FindFormAndFieldForFormControlElement(element, &form,
690 &field)) {
[email protected]7837be62011-01-18 23:45:08691 // If we didn't find the cached form, at least let autocomplete have a shot
692 // at providing suggestions.
kolos66b4c292016-07-29 17:54:53693 WebFormControlElementToFormField(element, nullptr, form_util::EXTRACT_VALUE,
694 &field);
[email protected]7837be62011-01-18 23:45:08695 }
[email protected]77bb0da2010-11-20 01:55:30696
Tao Bai88d56d42017-07-17 16:07:16697 if (is_secure_context_required_ &&
698 !(element.GetDocument().IsSecureContext() &&
699 content::IsOriginSecure(form.action))) {
700 LOG(WARNING) << "Autofill suggestions are disabled because the document "
701 "isn't a secure context or the form's action attribute "
702 "isn't secure.";
703 return;
704 }
705
[email protected]7d0ea5362014-05-01 23:39:43706 std::vector<base::string16> data_list_values;
707 std::vector<base::string16> data_list_labels;
Blink Reformat1c4d759e2017-04-09 16:34:54708 const WebInputElement* input_element = ToWebInputElement(&element);
[email protected]e9d29d392014-03-25 01:15:15709 if (input_element) {
710 // Find the datalist values and send them to the browser process.
[email protected]e9d29d392014-03-25 01:15:15711 GetDataListSuggestions(*input_element,
[email protected]e9d29d392014-03-25 01:15:15712 &data_list_values,
713 &data_list_labels);
714 TrimStringVectorForIPC(&data_list_values);
715 TrimStringVectorForIPC(&data_list_labels);
[email protected]e9d29d392014-03-25 01:15:15716 }
[email protected]5c8de6b92012-06-08 21:24:08717
[email protected]b648f242014-02-25 13:49:06718 is_popup_possibly_visible_ = true;
[email protected]7d0ea5362014-05-01 23:39:43719
leon.han35ae41c2016-07-29 03:30:58720 GetAutofillDriver()->SetDataList(data_list_values, data_list_labels);
leon.han90fd63b2016-07-26 01:23:55721 GetAutofillDriver()->QueryFormFieldAutofill(
722 autofill_query_id_, form, field,
723 render_frame()->GetRenderView()->ElementBoundsInWindow(element_));
[email protected]e47aec52010-08-12 00:50:30724}
725
leon.han90fd63b2016-07-26 01:23:55726void AutofillAgent::DoFillFieldWithValue(const base::string16& value,
727 WebInputElement* node) {
rouslan6a3f8d92015-04-28 01:00:01728 base::AutoReset<bool> auto_reset(&ignore_text_changes_, true);
Blink Reformat1c4d759e2017-04-09 16:34:54729 node->SetEditingValue(
730 blink::WebString::FromUTF16(value.substr(0, node->MaxLength())));
[email protected]ac9b92f2014-03-15 00:48:32731}
732
leon.han90fd63b2016-07-26 01:23:55733void AutofillAgent::DoPreviewFieldWithValue(const base::string16& value,
734 WebInputElement* node) {
Blink Reformat1c4d759e2017-04-09 16:34:54735 was_query_node_autofilled_ = element_.IsAutofilled();
736 node->SetSuggestedValue(
737 blink::WebString::FromUTF16(value.substr(0, node->MaxLength())));
738 node->SetAutofilled(true);
739 form_util::PreviewSuggestion(node->SuggestedValue().Utf16(),
740 node->Value().Utf16(), node);
[email protected]6f001a6cf2012-02-09 15:21:53741}
742
estadeb1bc9bd2014-12-02 22:44:11743void AutofillAgent::ProcessForms() {
[email protected]5193ea52014-05-14 01:10:02744 // Record timestamp of when the forms are first seen. This is used to
745 // measure the overhead of the Autofill feature.
746 base::TimeTicks forms_seen_timestamp = base::TimeTicks::Now();
747
estadeb1bc9bd2014-12-02 22:44:11748 WebLocalFrame* frame = render_frame()->GetWebFrame();
estadeff02e6d2014-12-15 21:18:31749 std::vector<FormData> forms = form_cache_.ExtractNewForms();
[email protected]5193ea52014-05-14 01:10:02750
751 // Always communicate to browser process for topmost frame.
Blink Reformat1c4d759e2017-04-09 16:34:54752 if (!forms.empty() || !frame->Parent()) {
leon.han35ae41c2016-07-29 03:30:58753 GetAutofillDriver()->FormsSeen(forms, forms_seen_timestamp);
[email protected]5193ea52014-05-14 01:10:02754 }
[email protected]5193ea52014-05-14 01:10:02755}
756
[email protected]b648f242014-02-25 13:49:06757void AutofillAgent::HidePopup() {
758 if (!is_popup_possibly_visible_)
759 return;
[email protected]b648f242014-02-25 13:49:06760 is_popup_possibly_visible_ = false;
gcastocdd33e0d2015-06-17 22:10:05761 is_generation_popup_possibly_visible_ = false;
leon.han90fd63b2016-07-26 01:23:55762
763 GetAutofillDriver()->HidePopup();
[email protected]81cd52332012-11-05 20:36:07764}
765
rouslan42b090872015-05-17 05:04:33766bool AutofillAgent::IsUserGesture() const {
Blink Reformat1c4d759e2017-04-09 16:34:54767 return WebUserGestureIndicator::IsProcessingUserGesture();
rouslan42b090872015-05-17 05:04:33768}
769
Blink Reformat1c4d759e2017-04-09 16:34:54770void AutofillAgent::DidAssociateFormControlsDynamically() {
vasilii31ba8c6c2017-04-28 21:35:08771 // If the control flow is here than the document was at least loaded. The
772 // whole page doesn't have to be loaded.
773 ProcessForms();
774 password_autofill_agent_->OnDynamicFormsSeen();
775 if (password_generation_agent_)
776 password_generation_agent_->OnDynamicFormsSeen();
[email protected]17b6be72013-04-30 21:33:08777}
778
ekaramad27ca69b12017-04-20 18:34:29779void AutofillAgent::DidCompleteFocusChangeInFrame() {
780 WebDocument doc = render_frame()->GetWebFrame()->GetDocument();
781 WebElement focused_element;
782 if (!doc.IsNull())
783 focused_element = doc.FocusedElement();
784 // PasswordGenerationAgent needs to know about focus changes, even if there is
785 // no focused element.
786 if (password_generation_agent_ &&
787 password_generation_agent_->FocusedNodeHasChanged(focused_element)) {
788 is_generation_popup_possibly_visible_ = true;
789 is_popup_possibly_visible_ = true;
790 }
791 if (!focused_element.IsNull() && password_autofill_agent_)
792 password_autofill_agent_->FocusedNodeHasChanged(focused_element);
793
794 // PageClickTracker needs to be notified after
795 // |is_generation_popup_possibly_visible_| has been updated.
796 page_click_tracker_->DidCompleteFocusChangeInFrame();
797}
798
799void AutofillAgent::DidReceiveLeftMouseDownOrGestureTapInNode(
800 const WebNode& node) {
801 page_click_tracker_->DidReceiveLeftMouseDownOrGestureTapInNode(node);
802}
803
Blink Reformat1c4d759e2017-04-09 16:34:54804void AutofillAgent::AjaxSucceeded() {
eugenebut5ae751e2017-03-28 17:10:37805 OnSameDocumentNavigationCompleted();
xunlu23ca2b572015-07-10 16:58:26806 password_autofill_agent_->AJAXSucceeded();
gcastoc21f1c4c2015-03-19 21:57:03807}
808
leon.han90fd63b2016-07-26 01:23:55809const mojom::AutofillDriverPtr& AutofillAgent::GetAutofillDriver() {
leon.han97e8f752016-09-06 06:13:20810 if (!autofill_driver_) {
leon.han90fd63b2016-07-26 01:23:55811 render_frame()->GetRemoteInterfaces()->GetInterface(
blundelle0a9f1582016-12-20 11:23:32812 mojo::MakeRequest(&autofill_driver_));
leon.han90fd63b2016-07-26 01:23:55813 }
leon.hande852902016-05-04 09:16:38814
leon.han97e8f752016-09-06 06:13:20815 return autofill_driver_;
816}
817
818const mojom::PasswordManagerDriverPtr&
819AutofillAgent::GetPasswordManagerDriver() {
820 DCHECK(password_autofill_agent_);
821 return password_autofill_agent_->GetPasswordManagerDriver();
leon.hande852902016-05-04 09:16:38822}
823
[email protected]78192082011-01-29 05:43:44824} // namespace autofill