Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Side by Side Diff: components/autofill/content/renderer/password_autofill_agent.cc

Issue 163843002: Fix check for user gesture on password autofill (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: New implementation using isUserGestureEventType Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/autofill/content/renderer/password_autofill_agent.h" 5 #include "components/autofill/content/renderer/password_autofill_agent.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 194
195 } // namespace 195 } // namespace
196 196
197 //////////////////////////////////////////////////////////////////////////////// 197 ////////////////////////////////////////////////////////////////////////////////
198 // PasswordAutofillAgent, public: 198 // PasswordAutofillAgent, public:
199 199
200 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderView* render_view) 200 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderView* render_view)
201 : content::RenderViewObserver(render_view), 201 : content::RenderViewObserver(render_view),
202 usernames_usage_(NOTHING_TO_AUTOFILL), 202 usernames_usage_(NOTHING_TO_AUTOFILL),
203 web_view_(render_view->GetWebView()), 203 web_view_(render_view->GetWebView()),
204 gesture_handler_(new AutofillWebUserGestureHandler(this)),
205 user_gesture_occurred_(false),
206 weak_ptr_factory_(this) { 204 weak_ptr_factory_(this) {
207 blink::WebUserGestureIndicator::setHandler(gesture_handler_.get());
208 } 205 }
209 206
210 PasswordAutofillAgent::~PasswordAutofillAgent() { 207 PasswordAutofillAgent::~PasswordAutofillAgent() {}
211 DCHECK(gesture_handler_.get()); 208
212 blink::WebUserGestureIndicator::setHandler(NULL); 209 PasswordAutofillAgent::PasswordValueGatekeeper::PasswordValueGatekeeper()
210 : was_user_gesture_seen_(false) {}
211
212 PasswordAutofillAgent::PasswordValueGatekeeper::~PasswordValueGatekeeper() {}
213
214 void PasswordAutofillAgent::PasswordValueGatekeeper::RegisterElement(
215 blink::WebInputElement& element) {
216 if (was_user_gesture_seen_)
217 ShowValue(element);
218 else
219 elements_.push_back(element);
220 }
221
222 void PasswordAutofillAgent::PasswordValueGatekeeper::ShowValue(
223 blink::WebInputElement& element) {
224 if (!element.isNull() && !element.suggestedValue().isNull())
225 element.setValue(element.suggestedValue(), true);
226 }
227
228 void PasswordAutofillAgent::PasswordValueGatekeeper::OnGesture() {
229 was_user_gesture_seen_ = true;
230
231 for (std::vector<blink::WebInputElement>::iterator iter = elements_.begin();
Ilya Sherman 2014/02/14 23:07:33 Optional nit: "iter" -> "it" (for consistency with
vabr (Chromium) 2014/02/17 14:24:56 Done.
232 iter != elements_.end();
233 ++iter) {
234 ShowValue(*iter);
235 }
236
237 elements_.clear();
238 }
239
240 void PasswordAutofillAgent::PasswordValueGatekeeper::Reset() {
241 was_user_gesture_seen_ = false;
242 elements_.clear();
213 } 243 }
Ilya Sherman 2014/02/14 23:07:33 nit: Please order the implementation code within t
vabr (Chromium) 2014/02/17 14:24:56 Done for the definitions of the added methods (the
214 244
215 bool PasswordAutofillAgent::TextFieldDidEndEditing( 245 bool PasswordAutofillAgent::TextFieldDidEndEditing(
216 const blink::WebInputElement& element) { 246 const blink::WebInputElement& element) {
217 LoginToPasswordInfoMap::const_iterator iter = 247 LoginToPasswordInfoMap::const_iterator iter =
218 login_to_password_info_.find(element); 248 login_to_password_info_.find(element);
219 if (iter == login_to_password_info_.end()) 249 if (iter == login_to_password_info_.end())
220 return false; 250 return false;
221 251
222 const PasswordFormFillData& fill_data = 252 const PasswordFormFillData& fill_data =
223 iter->second.fill_data; 253 iter->second.fill_data;
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 // the frame starts loading. If there are redirects that cause a new 500 // the frame starts loading. If there are redirects that cause a new
471 // RenderView to be instantiated (such as redirects to the WebStore) 501 // RenderView to be instantiated (such as redirects to the WebStore)
472 // we will never get to finish the load. 502 // we will never get to finish the load.
473 Send(new AutofillHostMsg_PasswordFormSubmitted(routing_id(), 503 Send(new AutofillHostMsg_PasswordFormSubmitted(routing_id(),
474 *submitted_form)); 504 *submitted_form));
475 // Remove reference since we have already submitted this form. 505 // Remove reference since we have already submitted this form.
476 provisionally_saved_forms_.erase(frame); 506 provisionally_saved_forms_.erase(frame);
477 } 507 }
478 } 508 }
479 509
510 void PasswordAutofillAgent::ProcessingUserGestureEvent() {
511 gatekeeper_.OnGesture();
512 }
513
480 blink::WebFrame* PasswordAutofillAgent::CurrentOrChildFrameWithSavedForms( 514 blink::WebFrame* PasswordAutofillAgent::CurrentOrChildFrameWithSavedForms(
481 const blink::WebFrame* current_frame) { 515 const blink::WebFrame* current_frame) {
482 for (FrameToPasswordFormMap::const_iterator it = 516 for (FrameToPasswordFormMap::const_iterator it =
483 provisionally_saved_forms_.begin(); 517 provisionally_saved_forms_.begin();
484 it != provisionally_saved_forms_.end(); 518 it != provisionally_saved_forms_.end();
485 ++it) { 519 ++it) {
486 blink::WebFrame* form_frame = it->first; 520 blink::WebFrame* form_frame = it->first;
487 // The check that the returned frame is related to |current_frame| is mainly 521 // The check that the returned frame is related to |current_frame| is mainly
488 // for double-checking. There should not be any unrelated frames in 522 // for double-checking. There should not be any unrelated frames in
489 // |provisionally_saved_forms_|, because the map is cleared after 523 // |provisionally_saved_forms_|, because the map is cleared after
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 !password_form->password_value.empty()) { 561 !password_form->password_value.empty()) {
528 Send(new AutofillHostMsg_PasswordFormSubmitted( 562 Send(new AutofillHostMsg_PasswordFormSubmitted(
529 routing_id(), *password_form)); 563 routing_id(), *password_form));
530 } 564 }
531 } 565 }
532 } 566 }
533 } 567 }
534 // Clear the whole map during main frame navigation. 568 // Clear the whole map during main frame navigation.
535 provisionally_saved_forms_.clear(); 569 provisionally_saved_forms_.clear();
536 570
537 // We are navigating, se we need to wait for a new user gesture before 571 // New navigation means the need to wait for a new user gesture before
Ilya Sherman 2014/02/14 23:07:33 nit: Suggested rephrasing: "This is a new navigati
vabr (Chromium) 2014/02/17 14:24:56 Done.
538 // filling in passwords. 572 // filling in passwords.
539 user_gesture_occurred_ = false; 573 gatekeeper_.Reset();
540 gesture_handler_->clearElements();
541 } 574 }
542 } 575 }
543 576
544 void PasswordAutofillAgent::OnFillPasswordForm( 577 void PasswordAutofillAgent::OnFillPasswordForm(
545 const PasswordFormFillData& form_data) { 578 const PasswordFormFillData& form_data) {
546 if (usernames_usage_ == NOTHING_TO_AUTOFILL) { 579 if (usernames_usage_ == NOTHING_TO_AUTOFILL) {
547 if (form_data.other_possible_usernames.size()) 580 if (form_data.other_possible_usernames.size())
548 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_PRESENT; 581 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_PRESENT;
549 else if (usernames_usage_ == NOTHING_TO_AUTOFILL) 582 else if (usernames_usage_ == NOTHING_TO_AUTOFILL)
550 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_ABSENT; 583 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_ABSENT;
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 if (set_selection) { 798 if (set_selection) {
766 username_element->setSelectionRange(current_username.length(), 799 username_element->setSelectionRange(current_username.length(),
767 username.length()); 800 username.length());
768 } 801 }
769 } else if (current_username != username) { 802 } else if (current_username != username) {
770 // If the username can't be filled and it doesn't match a saved password 803 // If the username can't be filled and it doesn't match a saved password
771 // as is, don't autofill a password. 804 // as is, don't autofill a password.
772 return false; 805 return false;
773 } 806 }
774 807
775 // If a user gesture has not occurred, we setup a handler to listen for the 808 // We wait with filling in the password until a user gesture occurred. This is
Ilya Sherman 2014/02/14 23:07:33 nit: "We wait with filling in" -> "Wait to fill in
Ilya Sherman 2014/02/14 23:07:33 nit: "occurred" -> "occurs"
vabr (Chromium) 2014/02/17 14:24:56 Done.
vabr (Chromium) 2014/02/17 14:24:56 Done.
776 // next user gesture, at which point we then fill in the password. This is to 809 // to make sure that we do not fill in the DOM with a password until we
777 // make sure that we do not fill in the DOM with a password until we believe 810 // believe the user is intentionally interacting with the page.
778 // the user is intentionally interacting with the page. 811 password_element->setSuggestedValue(password);
779 if (!user_gesture_occurred_) { 812 gatekeeper_.RegisterElement(*password_element);
780 gesture_handler_->addElement(*password_element); 813
781 password_element->setSuggestedValue(password);
782 } else {
783 password_element->setValue(password, true);
784 }
785 // Note: Don't call SetElementAutofilled() here, as that dispatches an 814 // Note: Don't call SetElementAutofilled() here, as that dispatches an
786 // onChange event in JavaScript, which is not appropriate for the password 815 // onChange event in JavaScript, which is not appropriate for the password
787 // element if a user gesture has not yet occured. 816 // element if a user gesture has not yet occured.
788 password_element->setAutofilled(true); 817 password_element->setAutofilled(true);
789 return true; 818 return true;
790 } 819 }
791 820
792 void PasswordAutofillAgent::PerformInlineAutocomplete( 821 void PasswordAutofillAgent::PerformInlineAutocomplete(
793 const blink::WebInputElement& username_input, 822 const blink::WebInputElement& username_input,
794 const blink::WebInputElement& password_input, 823 const blink::WebInputElement& password_input,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 blink::WebInputElement input = element.to<blink::WebInputElement>(); 879 blink::WebInputElement input = element.to<blink::WebInputElement>();
851 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); 880 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input);
852 if (iter == login_to_password_info_.end()) 881 if (iter == login_to_password_info_.end())
853 return false; 882 return false;
854 883
855 *found_input = input; 884 *found_input = input;
856 *found_password = iter->second; 885 *found_password = iter->second;
857 return true; 886 return true;
858 } 887 }
859 888
860 void PasswordAutofillAgent::AutofillWebUserGestureHandler::onGesture() {
861 agent_->set_user_gesture_occurred(true);
862
863 std::vector<blink::WebInputElement>::iterator iter;
864 for (iter = elements_.begin(); iter != elements_.end(); ++iter) {
865 if (!iter->isNull() && !iter->suggestedValue().isNull())
866 iter->setValue(iter->suggestedValue(), true);
867 }
868
869 elements_.clear();
870 }
871
872 PasswordAutofillAgent::AutofillWebUserGestureHandler::
873 AutofillWebUserGestureHandler(PasswordAutofillAgent* agent)
874 : agent_(agent) {}
875
876 PasswordAutofillAgent::AutofillWebUserGestureHandler::
877 ~AutofillWebUserGestureHandler() {}
878
879 } // namespace autofill 889 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698