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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
(...skipping 30 matching lines...) Expand all Loading... |
41 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" | 41 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" |
42 #include "third_party/WebKit/public/platform/WebVector.h" | 42 #include "third_party/WebKit/public/platform/WebVector.h" |
43 #include "third_party/WebKit/public/web/WebAutofillClient.h" | 43 #include "third_party/WebKit/public/web/WebAutofillClient.h" |
44 #include "third_party/WebKit/public/web/WebDocument.h" | 44 #include "third_party/WebKit/public/web/WebDocument.h" |
45 #include "third_party/WebKit/public/web/WebElement.h" | 45 #include "third_party/WebKit/public/web/WebElement.h" |
46 #include "third_party/WebKit/public/web/WebFormElement.h" | 46 #include "third_party/WebKit/public/web/WebFormElement.h" |
47 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 47 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
48 #include "third_party/WebKit/public/web/WebNode.h" | 48 #include "third_party/WebKit/public/web/WebNode.h" |
49 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" | 49 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" |
50 #include "third_party/WebKit/public/web/WebView.h" | 50 #include "third_party/WebKit/public/web/WebView.h" |
| 51 #include "third_party/WebKit/public/web/modules/password_manager/WebFormElementO
bserver.h" |
| 52 #include "third_party/WebKit/public/web/modules/password_manager/WebFormElementO
bserverCallback.h" |
51 #include "ui/base/page_transition_types.h" | 53 #include "ui/base/page_transition_types.h" |
52 #include "ui/events/keycodes/keyboard_codes.h" | 54 #include "ui/events/keycodes/keyboard_codes.h" |
53 #include "url/gurl.h" | 55 #include "url/gurl.h" |
54 | 56 |
55 namespace autofill { | 57 namespace autofill { |
56 namespace { | 58 namespace { |
57 | 59 |
58 // The size above which we stop triggering autocomplete. | 60 // The size above which we stop triggering autocomplete. |
59 static const size_t kMaximumTextSizeForAutocomplete = 1000; | 61 static const size_t kMaximumTextSizeForAutocomplete = 1000; |
60 | 62 |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 element.To<blink::WebFormControlElement>(); | 613 element.To<blink::WebFormControlElement>(); |
612 if (control.FormControlType() == kPassword) | 614 if (control.FormControlType() == kPassword) |
613 return true; | 615 return true; |
614 } | 616 } |
615 } | 617 } |
616 return false; | 618 return false; |
617 } | 619 } |
618 | 620 |
619 } // namespace | 621 } // namespace |
620 | 622 |
| 623 class PasswordAutofillAgent::FormElementObserverCallback |
| 624 : public blink::WebFormElementObserverCallback { |
| 625 public: |
| 626 explicit FormElementObserverCallback(PasswordAutofillAgent* agent) |
| 627 : agent_(agent) {} |
| 628 ~FormElementObserverCallback() override = default; |
| 629 |
| 630 void ElementWasHiddenOrRemoved() override { |
| 631 agent_->OnSameDocumentNavigationCompleted( |
| 632 PasswordForm::SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR); |
| 633 } |
| 634 |
| 635 private: |
| 636 PasswordAutofillAgent* agent_; |
| 637 |
| 638 DISALLOW_COPY_AND_ASSIGN(FormElementObserverCallback); |
| 639 }; |
| 640 |
621 //////////////////////////////////////////////////////////////////////////////// | 641 //////////////////////////////////////////////////////////////////////////////// |
622 // PasswordAutofillAgent, public: | 642 // PasswordAutofillAgent, public: |
623 | 643 |
624 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderFrame* render_frame) | 644 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderFrame* render_frame) |
625 : content::RenderFrameObserver(render_frame), | 645 : content::RenderFrameObserver(render_frame), |
626 logging_state_active_(false), | 646 logging_state_active_(false), |
627 was_username_autofilled_(false), | 647 was_username_autofilled_(false), |
628 was_password_autofilled_(false), | 648 was_password_autofilled_(false), |
629 sent_request_to_store_(false), | 649 sent_request_to_store_(false), |
630 checked_safe_browsing_reputation_(false), | 650 checked_safe_browsing_reputation_(false), |
631 binding_(this) { | 651 binding_(this), |
| 652 form_element_observer_(nullptr) { |
632 // PasswordAutofillAgent is guaranteed to outlive |render_frame|. | 653 // PasswordAutofillAgent is guaranteed to outlive |render_frame|. |
633 render_frame->GetInterfaceRegistry()->AddInterface( | 654 render_frame->GetInterfaceRegistry()->AddInterface( |
634 base::Bind(&PasswordAutofillAgent::BindRequest, base::Unretained(this))); | 655 base::Bind(&PasswordAutofillAgent::BindRequest, base::Unretained(this))); |
635 } | 656 } |
636 | 657 |
637 PasswordAutofillAgent::~PasswordAutofillAgent() { | 658 PasswordAutofillAgent::~PasswordAutofillAgent() { |
| 659 if (form_element_observer_) { |
| 660 form_element_observer_->Disconnect(); |
| 661 form_element_observer_ = nullptr; |
| 662 } |
638 } | 663 } |
639 | 664 |
640 void PasswordAutofillAgent::BindRequest( | 665 void PasswordAutofillAgent::BindRequest( |
641 const service_manager::BindSourceInfo& source_info, | 666 const service_manager::BindSourceInfo& source_info, |
642 mojom::PasswordAutofillAgentRequest request) { | 667 mojom::PasswordAutofillAgentRequest request) { |
643 binding_.Bind(std::move(request)); | 668 binding_.Bind(std::move(request)); |
644 } | 669 } |
645 | 670 |
646 void PasswordAutofillAgent::SetAutofillAgent(AutofillAgent* autofill_agent) { | 671 void PasswordAutofillAgent::SetAutofillAgent(AutofillAgent* autofill_agent) { |
647 autofill_agent_ = autofill_agent; | 672 autofill_agent_ = autofill_agent; |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( | 1050 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( |
1026 const blink::WebSecurityOrigin& origin) { | 1051 const blink::WebSecurityOrigin& origin) { |
1027 return origin.CanAccessPasswordManager(); | 1052 return origin.CanAccessPasswordManager(); |
1028 } | 1053 } |
1029 | 1054 |
1030 void PasswordAutofillAgent::OnDynamicFormsSeen() { | 1055 void PasswordAutofillAgent::OnDynamicFormsSeen() { |
1031 SendPasswordForms(false /* only_visible */); | 1056 SendPasswordForms(false /* only_visible */); |
1032 } | 1057 } |
1033 | 1058 |
1034 void PasswordAutofillAgent::AJAXSucceeded() { | 1059 void PasswordAutofillAgent::AJAXSucceeded() { |
1035 OnSameDocumentNavigationCompleted(false); | 1060 OnSameDocumentNavigationCompleted( |
| 1061 PasswordForm::SubmissionIndicatorEvent::XHR_SUCCEEDED); |
1036 } | 1062 } |
1037 | 1063 |
1038 void PasswordAutofillAgent::OnSameDocumentNavigationCompleted( | 1064 void PasswordAutofillAgent::OnSameDocumentNavigationCompleted( |
1039 bool is_inpage_navigation) { | 1065 PasswordForm::SubmissionIndicatorEvent event) { |
1040 if (!provisionally_saved_form_.IsPasswordValid()) | 1066 if (!provisionally_saved_form_.IsPasswordValid()) |
1041 return; | 1067 return; |
1042 | 1068 |
1043 provisionally_saved_form_.SetSubmissionIndicatorEvent( | |
1044 is_inpage_navigation | |
1045 ? PasswordForm::SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION | |
1046 : PasswordForm::SubmissionIndicatorEvent::XHR_SUCCEEDED); | |
1047 | |
1048 // Prompt to save only if the form is now gone, either invisible or | 1069 // Prompt to save only if the form is now gone, either invisible or |
1049 // removed from the DOM. | 1070 // removed from the DOM. |
1050 blink::WebFrame* frame = render_frame()->GetWebFrame(); | 1071 blink::WebFrame* frame = render_frame()->GetWebFrame(); |
1051 const auto& password_form = provisionally_saved_form_.password_form(); | 1072 const auto& password_form = provisionally_saved_form_.password_form(); |
1052 // TODO(crbug.com/720347): This method could be called often and checking form | 1073 // TODO(crbug.com/720347): This method could be called often and checking form |
1053 // visibility could be expesive. Add performance metrics for this. | 1074 // visibility could be expesive. Add performance metrics for this. |
1054 if (form_util::IsFormVisible(frame, provisionally_saved_form_.form_element(), | 1075 if (event != PasswordForm::SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR && |
1055 password_form.action, password_form.origin, | 1076 (form_util::IsFormVisible(frame, provisionally_saved_form_.form_element(), |
1056 password_form.form_data) || | 1077 password_form.action, password_form.origin, |
1057 (provisionally_saved_form_.form_element().IsNull() && | 1078 password_form.form_data) || |
1058 IsUnownedPasswordFormVisible( | 1079 (provisionally_saved_form_.form_element().IsNull() && |
1059 frame, provisionally_saved_form_.input_element(), | 1080 IsUnownedPasswordFormVisible( |
1060 password_form.action, password_form.origin, password_form.form_data, | 1081 frame, provisionally_saved_form_.input_element(), |
1061 form_predictions_))) { | 1082 password_form.action, password_form.origin, password_form.form_data, |
| 1083 form_predictions_)))) { |
| 1084 if (!form_element_observer_) { |
| 1085 std::unique_ptr<FormElementObserverCallback> callback( |
| 1086 new FormElementObserverCallback(this)); |
| 1087 if (provisionally_saved_form_.form_element().IsNull()) { |
| 1088 form_element_observer_ = blink::WebFormElementObserver::Create( |
| 1089 provisionally_saved_form_.input_element(), std::move(callback)); |
| 1090 } else { |
| 1091 form_element_observer_ = blink::WebFormElementObserver::Create( |
| 1092 provisionally_saved_form_.form_element(), std::move(callback)); |
| 1093 } |
| 1094 } |
1062 return; | 1095 return; |
1063 } | 1096 } |
1064 | 1097 |
| 1098 provisionally_saved_form_.SetSubmissionIndicatorEvent(event); |
1065 GetPasswordManagerDriver()->InPageNavigation(password_form); | 1099 GetPasswordManagerDriver()->InPageNavigation(password_form); |
| 1100 if (form_element_observer_) { |
| 1101 form_element_observer_->Disconnect(); |
| 1102 form_element_observer_ = nullptr; |
| 1103 } |
1066 provisionally_saved_form_.Reset(); | 1104 provisionally_saved_form_.Reset(); |
1067 } | 1105 } |
1068 | 1106 |
1069 void PasswordAutofillAgent::UserGestureObserved() { | 1107 void PasswordAutofillAgent::UserGestureObserved() { |
1070 gatekeeper_.OnUserGesture(); | 1108 gatekeeper_.OnUserGesture(); |
1071 } | 1109 } |
1072 | 1110 |
1073 void PasswordAutofillAgent::SendPasswordForms(bool only_visible) { | 1111 void PasswordAutofillAgent::SendPasswordForms(bool only_visible) { |
1074 std::unique_ptr<RendererSavePasswordProgressLogger> logger; | 1112 std::unique_ptr<RendererSavePasswordProgressLogger> logger; |
1075 if (logging_state_active_) { | 1113 if (logging_state_active_) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 } | 1248 } |
1211 | 1249 |
1212 void PasswordAutofillAgent::WillCommitProvisionalLoad() { | 1250 void PasswordAutofillAgent::WillCommitProvisionalLoad() { |
1213 FrameClosing(); | 1251 FrameClosing(); |
1214 } | 1252 } |
1215 | 1253 |
1216 void PasswordAutofillAgent::DidCommitProvisionalLoad( | 1254 void PasswordAutofillAgent::DidCommitProvisionalLoad( |
1217 bool is_new_navigation, | 1255 bool is_new_navigation, |
1218 bool is_same_document_navigation) { | 1256 bool is_same_document_navigation) { |
1219 if (is_same_document_navigation) { | 1257 if (is_same_document_navigation) { |
1220 OnSameDocumentNavigationCompleted(true); | 1258 OnSameDocumentNavigationCompleted( |
| 1259 PasswordForm::SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION); |
1221 } else { | 1260 } else { |
1222 checked_safe_browsing_reputation_ = false; | 1261 checked_safe_browsing_reputation_ = false; |
1223 } | 1262 } |
1224 } | 1263 } |
1225 | 1264 |
1226 void PasswordAutofillAgent::FrameDetached() { | 1265 void PasswordAutofillAgent::FrameDetached() { |
1227 // If a sub frame has been destroyed while the user was entering information | 1266 // If a sub frame has been destroyed while the user was entering information |
1228 // into a password form, try to save the data. See https://crbug.com/450806 | 1267 // into a password form, try to save the data. See https://crbug.com/450806 |
1229 // for examples of sites that perform login using this technique. | 1268 // for examples of sites that perform login using this technique. |
1230 if (render_frame()->GetWebFrame()->Parent() && | 1269 if (render_frame()->GetWebFrame()->Parent() && |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1292 submitted_form->username_value = saved_form.username_value; | 1331 submitted_form->username_value = saved_form.username_value; |
1293 submitted_form->submission_event = | 1332 submitted_form->submission_event = |
1294 PasswordForm::SubmissionIndicatorEvent::HTML_FORM_SUBMISSION; | 1333 PasswordForm::SubmissionIndicatorEvent::HTML_FORM_SUBMISSION; |
1295 } | 1334 } |
1296 | 1335 |
1297 // Some observers depend on sending this information now instead of when | 1336 // Some observers depend on sending this information now instead of when |
1298 // the frame starts loading. If there are redirects that cause a new | 1337 // the frame starts loading. If there are redirects that cause a new |
1299 // RenderView to be instantiated (such as redirects to the WebStore) | 1338 // RenderView to be instantiated (such as redirects to the WebStore) |
1300 // we will never get to finish the load. | 1339 // we will never get to finish the load. |
1301 GetPasswordManagerDriver()->PasswordFormSubmitted(*submitted_form); | 1340 GetPasswordManagerDriver()->PasswordFormSubmitted(*submitted_form); |
| 1341 if (form_element_observer_) { |
| 1342 form_element_observer_->Disconnect(); |
| 1343 form_element_observer_ = nullptr; |
| 1344 } |
1302 provisionally_saved_form_.Reset(); | 1345 provisionally_saved_form_.Reset(); |
1303 } else if (logger) { | 1346 } else if (logger) { |
1304 logger->LogMessage(Logger::STRING_FORM_IS_NOT_PASSWORD); | 1347 logger->LogMessage(Logger::STRING_FORM_IS_NOT_PASSWORD); |
1305 } | 1348 } |
1306 } | 1349 } |
1307 | 1350 |
1308 void PasswordAutofillAgent::OnDestruct() { | 1351 void PasswordAutofillAgent::OnDestruct() { |
1309 binding_.Close(); | 1352 binding_.Close(); |
1310 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); | 1353 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); |
1311 } | 1354 } |
(...skipping 27 matching lines...) Expand all Loading... |
1339 !blink::WebUserGestureIndicator::IsProcessingUserGesture()) { | 1382 !blink::WebUserGestureIndicator::IsProcessingUserGesture()) { |
1340 // If onsubmit has been called, try and save that form. | 1383 // If onsubmit has been called, try and save that form. |
1341 if (provisionally_saved_form_.IsSet()) { | 1384 if (provisionally_saved_form_.IsSet()) { |
1342 if (logger) { | 1385 if (logger) { |
1343 logger->LogPasswordForm( | 1386 logger->LogPasswordForm( |
1344 Logger::STRING_PROVISIONALLY_SAVED_FORM_FOR_FRAME, | 1387 Logger::STRING_PROVISIONALLY_SAVED_FORM_FOR_FRAME, |
1345 provisionally_saved_form_.password_form()); | 1388 provisionally_saved_form_.password_form()); |
1346 } | 1389 } |
1347 GetPasswordManagerDriver()->PasswordFormSubmitted( | 1390 GetPasswordManagerDriver()->PasswordFormSubmitted( |
1348 provisionally_saved_form_.password_form()); | 1391 provisionally_saved_form_.password_form()); |
| 1392 if (form_element_observer_) { |
| 1393 form_element_observer_->Disconnect(); |
| 1394 form_element_observer_ = nullptr; |
| 1395 } |
1349 provisionally_saved_form_.Reset(); | 1396 provisionally_saved_form_.Reset(); |
1350 } else { | 1397 } else { |
1351 std::vector<std::unique_ptr<PasswordForm>> possible_submitted_forms; | 1398 std::vector<std::unique_ptr<PasswordForm>> possible_submitted_forms; |
1352 // Loop through the forms on the page looking for one that has been | 1399 // Loop through the forms on the page looking for one that has been |
1353 // filled out. If one exists, try and save the credentials. | 1400 // filled out. If one exists, try and save the credentials. |
1354 blink::WebVector<blink::WebFormElement> forms; | 1401 blink::WebVector<blink::WebFormElement> forms; |
1355 render_frame()->GetWebFrame()->GetDocument().Forms(forms); | 1402 render_frame()->GetWebFrame()->GetDocument().Forms(forms); |
1356 | 1403 |
1357 bool password_forms_found = false; | 1404 bool password_forms_found = false; |
1358 for (size_t i = 0; i < forms.size(); ++i) { | 1405 for (size_t i = 0; i < forms.size(); ++i) { |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1622 render_frame()->GetRenderView()->ElementBoundsInWindow(user_input)); | 1669 render_frame()->GetRenderView()->ElementBoundsInWindow(user_input)); |
1623 username_query_prefix_ = username_string; | 1670 username_query_prefix_ = username_string; |
1624 return CanShowSuggestion(password_info.fill_data, username_string, show_all); | 1671 return CanShowSuggestion(password_info.fill_data, username_string, show_all); |
1625 } | 1672 } |
1626 | 1673 |
1627 void PasswordAutofillAgent::FrameClosing() { | 1674 void PasswordAutofillAgent::FrameClosing() { |
1628 for (auto const& iter : web_input_to_password_info_) { | 1675 for (auto const& iter : web_input_to_password_info_) { |
1629 password_to_username_.erase(iter.second.password_field); | 1676 password_to_username_.erase(iter.second.password_field); |
1630 } | 1677 } |
1631 web_input_to_password_info_.clear(); | 1678 web_input_to_password_info_.clear(); |
| 1679 if (form_element_observer_) { |
| 1680 form_element_observer_->Disconnect(); |
| 1681 form_element_observer_ = nullptr; |
| 1682 } |
1632 provisionally_saved_form_.Reset(); | 1683 provisionally_saved_form_.Reset(); |
1633 field_value_and_properties_map_.clear(); | 1684 field_value_and_properties_map_.clear(); |
1634 sent_request_to_store_ = false; | 1685 sent_request_to_store_ = false; |
1635 checked_safe_browsing_reputation_ = false; | 1686 checked_safe_browsing_reputation_ = false; |
1636 } | 1687 } |
1637 | 1688 |
1638 void PasswordAutofillAgent::ClearPreview( | 1689 void PasswordAutofillAgent::ClearPreview( |
1639 blink::WebInputElement* username, | 1690 blink::WebInputElement* username, |
1640 blink::WebInputElement* password) { | 1691 blink::WebInputElement* password) { |
1641 if (!username->IsNull() && !username->SuggestedValue().IsEmpty()) { | 1692 if (!username->IsNull() && !username->SuggestedValue().IsEmpty()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1673 PasswordAutofillAgent::GetPasswordManagerDriver() { | 1724 PasswordAutofillAgent::GetPasswordManagerDriver() { |
1674 if (!password_manager_driver_) { | 1725 if (!password_manager_driver_) { |
1675 render_frame()->GetRemoteInterfaces()->GetInterface( | 1726 render_frame()->GetRemoteInterfaces()->GetInterface( |
1676 mojo::MakeRequest(&password_manager_driver_)); | 1727 mojo::MakeRequest(&password_manager_driver_)); |
1677 } | 1728 } |
1678 | 1729 |
1679 return password_manager_driver_; | 1730 return password_manager_driver_; |
1680 } | 1731 } |
1681 | 1732 |
1682 } // namespace autofill | 1733 } // namespace autofill |
OLD | NEW |