| OLD | NEW |
| 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 Loading... |
| 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(); |
| 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 } |
| 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 = |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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::DidHandleKeyEvent() { |
| 511 gatekeeper_.OnGesture(); |
| 512 } |
| 513 |
| 514 void PasswordAutofillAgent::DidHandleMouseEvent( |
| 515 const blink::WebMouseEvent& event) { |
| 516 if (event.button != blink::WebMouseEvent::ButtonNone) |
| 517 gatekeeper_.OnGesture(); |
| 518 } |
| 519 |
| 520 void PasswordAutofillAgent::DidHandleTouchEvent( |
| 521 const blink::WebTouchEvent& /*event*/) { |
| 522 gatekeeper_.OnGesture(); |
| 523 } |
| 524 |
| 480 blink::WebFrame* PasswordAutofillAgent::CurrentOrChildFrameWithSavedForms( | 525 blink::WebFrame* PasswordAutofillAgent::CurrentOrChildFrameWithSavedForms( |
| 481 const blink::WebFrame* current_frame) { | 526 const blink::WebFrame* current_frame) { |
| 482 for (FrameToPasswordFormMap::const_iterator it = | 527 for (FrameToPasswordFormMap::const_iterator it = |
| 483 provisionally_saved_forms_.begin(); | 528 provisionally_saved_forms_.begin(); |
| 484 it != provisionally_saved_forms_.end(); | 529 it != provisionally_saved_forms_.end(); |
| 485 ++it) { | 530 ++it) { |
| 486 blink::WebFrame* form_frame = it->first; | 531 blink::WebFrame* form_frame = it->first; |
| 487 // The check that the returned frame is related to |current_frame| is mainly | 532 // 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 | 533 // for double-checking. There should not be any unrelated frames in |
| 489 // |provisionally_saved_forms_|, because the map is cleared after | 534 // |provisionally_saved_forms_|, because the map is cleared after |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 !password_form->password_value.empty()) { | 572 !password_form->password_value.empty()) { |
| 528 Send(new AutofillHostMsg_PasswordFormSubmitted( | 573 Send(new AutofillHostMsg_PasswordFormSubmitted( |
| 529 routing_id(), *password_form)); | 574 routing_id(), *password_form)); |
| 530 } | 575 } |
| 531 } | 576 } |
| 532 } | 577 } |
| 533 } | 578 } |
| 534 // Clear the whole map during main frame navigation. | 579 // Clear the whole map during main frame navigation. |
| 535 provisionally_saved_forms_.clear(); | 580 provisionally_saved_forms_.clear(); |
| 536 | 581 |
| 537 // We are navigating, se we need to wait for a new user gesture before | 582 // New navigation means the need to wait for a new user gesture before |
| 538 // filling in passwords. | 583 // filling in passwords. |
| 539 user_gesture_occurred_ = false; | 584 gatekeeper_.Reset(); |
| 540 gesture_handler_->clearElements(); | |
| 541 } | 585 } |
| 542 } | 586 } |
| 543 | 587 |
| 544 void PasswordAutofillAgent::OnFillPasswordForm( | 588 void PasswordAutofillAgent::OnFillPasswordForm( |
| 545 const PasswordFormFillData& form_data) { | 589 const PasswordFormFillData& form_data) { |
| 546 if (usernames_usage_ == NOTHING_TO_AUTOFILL) { | 590 if (usernames_usage_ == NOTHING_TO_AUTOFILL) { |
| 547 if (form_data.other_possible_usernames.size()) | 591 if (form_data.other_possible_usernames.size()) |
| 548 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_PRESENT; | 592 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_PRESENT; |
| 549 else if (usernames_usage_ == NOTHING_TO_AUTOFILL) | 593 else if (usernames_usage_ == NOTHING_TO_AUTOFILL) |
| 550 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_ABSENT; | 594 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_ABSENT; |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 if (set_selection) { | 809 if (set_selection) { |
| 766 username_element->setSelectionRange(current_username.length(), | 810 username_element->setSelectionRange(current_username.length(), |
| 767 username.length()); | 811 username.length()); |
| 768 } | 812 } |
| 769 } else if (current_username != username) { | 813 } else if (current_username != username) { |
| 770 // If the username can't be filled and it doesn't match a saved password | 814 // If the username can't be filled and it doesn't match a saved password |
| 771 // as is, don't autofill a password. | 815 // as is, don't autofill a password. |
| 772 return false; | 816 return false; |
| 773 } | 817 } |
| 774 | 818 |
| 775 // If a user gesture has not occurred, we setup a handler to listen for the | 819 // We wait with filling in the password until a user gesture occurred. This is |
| 776 // next user gesture, at which point we then fill in the password. This is to | 820 // 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 | 821 // believe the user is intentionally interacting with the page. |
| 778 // the user is intentionally interacting with the page. | 822 password_element->setSuggestedValue(password); |
| 779 if (!user_gesture_occurred_) { | 823 gatekeeper_.RegisterElement(*password_element); |
| 780 gesture_handler_->addElement(*password_element); | 824 |
| 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 | 825 // Note: Don't call SetElementAutofilled() here, as that dispatches an |
| 786 // onChange event in JavaScript, which is not appropriate for the password | 826 // onChange event in JavaScript, which is not appropriate for the password |
| 787 // element if a user gesture has not yet occured. | 827 // element if a user gesture has not yet occured. |
| 788 password_element->setAutofilled(true); | 828 password_element->setAutofilled(true); |
| 789 return true; | 829 return true; |
| 790 } | 830 } |
| 791 | 831 |
| 792 void PasswordAutofillAgent::PerformInlineAutocomplete( | 832 void PasswordAutofillAgent::PerformInlineAutocomplete( |
| 793 const blink::WebInputElement& username_input, | 833 const blink::WebInputElement& username_input, |
| 794 const blink::WebInputElement& password_input, | 834 const blink::WebInputElement& password_input, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 blink::WebInputElement input = element.to<blink::WebInputElement>(); | 890 blink::WebInputElement input = element.to<blink::WebInputElement>(); |
| 851 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); | 891 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); |
| 852 if (iter == login_to_password_info_.end()) | 892 if (iter == login_to_password_info_.end()) |
| 853 return false; | 893 return false; |
| 854 | 894 |
| 855 *found_input = input; | 895 *found_input = input; |
| 856 *found_password = iter->second; | 896 *found_password = iter->second; |
| 857 return true; | 897 return true; |
| 858 } | 898 } |
| 859 | 899 |
| 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 | 900 } // namespace autofill |
| OLD | NEW |