Commit e5e417a2 authored by Vadym Doroshenko's avatar Vadym Doroshenko Committed by Commit Bot

Propagate Parser annotations to DOM.

Annotations are shown when show-autofill-type-predictions flag is on.

Bug: 949519

Change-Id: Id048339d1eb56b50c6b9516f7355e35b905dc26b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1847284
Commit-Queue: Vadym Doroshenko <dvadym@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704681}
parent c4bd7a6d
...@@ -148,7 +148,7 @@ class FakePasswordAutofillAgent ...@@ -148,7 +148,7 @@ class FakePasswordAutofillAgent
logging_state_active_(false), logging_state_active_(false),
binding_(this) {} binding_(this) {}
~FakePasswordAutofillAgent() override {} ~FakePasswordAutofillAgent() override = default;
void BindRequest(mojo::ScopedInterfaceEndpointHandle handle) { void BindRequest(mojo::ScopedInterfaceEndpointHandle handle) {
binding_.Bind(autofill::mojom::PasswordAutofillAgentAssociatedRequest( binding_.Bind(autofill::mojom::PasswordAutofillAgentAssociatedRequest(
...@@ -171,6 +171,8 @@ class FakePasswordAutofillAgent ...@@ -171,6 +171,8 @@ class FakePasswordAutofillAgent
void FillIntoFocusedField(bool is_password, void FillIntoFocusedField(bool is_password,
const base::string16& credential) override {} const base::string16& credential) override {}
void AnnotateFieldsWithParsingResult(
const autofill::ParsingResult& parsing_result) override {}
void SetLoggingState(bool active) override { void SetLoggingState(bool active) override {
called_set_logging_state_ = true; called_set_logging_state_ = true;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/test_autofill_client.h" #include "components/autofill/core/browser/test_autofill_client.h"
#include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_form.h"
#include "components/password_manager/content/browser/content_password_manager_driver.h" #include "components/password_manager/content/browser/content_password_manager_driver.h"
#include "components/password_manager/content/browser/content_password_manager_driver_factory.h" #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
...@@ -66,6 +67,7 @@ ...@@ -66,6 +67,7 @@
#include "ui/events/keycodes/keyboard_codes.h" #include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point.h"
using autofill::ParsingResult;
using base::ASCIIToUTF16; using base::ASCIIToUTF16;
using base::Feature; using base::Feature;
using testing::_; using testing::_;
...@@ -3887,5 +3889,40 @@ IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, FormDynamicallyChanged) { ...@@ -3887,5 +3889,40 @@ IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, FormDynamicallyChanged) {
WaitForElementValue("password_field", "pw"); WaitForElementValue("password_field", "pw");
} }
IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, ParserAnnotations) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
autofill::switches::kShowAutofillSignatures);
NavigateToFile("/password/password_form.html");
const char kGetAnnotation[] =
"window.domAutomationController.send("
" document.getElementById('%s').getAttribute('pm_parser_annotation'));";
std::string username_annotation;
ASSERT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractString(
RenderFrameHost(), base::StringPrintf(kGetAnnotation, "username_field"),
&username_annotation));
EXPECT_EQ("username_element", username_annotation);
std::string password_annotation;
ASSERT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractString(
RenderFrameHost(), base::StringPrintf(kGetAnnotation, "password_field"),
&password_annotation));
EXPECT_EQ("password_element", password_annotation);
std::string new_password_annotation;
ASSERT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractString(
RenderFrameHost(),
base::StringPrintf(kGetAnnotation, "chg_new_password_1"),
&new_password_annotation));
EXPECT_EQ("new_password_element", new_password_annotation);
std::string cofirmation_password_annotation;
ASSERT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractString(
RenderFrameHost(),
base::StringPrintf(kGetAnnotation, "chg_new_password_2"),
&cofirmation_password_annotation));
EXPECT_EQ("confirmation_password_element", cofirmation_password_annotation);
}
} // namespace } // namespace
} // namespace password_manager } // namespace password_manager
...@@ -94,6 +94,10 @@ interface PasswordAutofillAgent { ...@@ -94,6 +94,10 @@ interface PasswordAutofillAgent {
// Informs the renderer that the Touch To Fill sheet has been dismissed. // Informs the renderer that the Touch To Fill sheet has been dismissed.
TouchToFillDismissed(); TouchToFillDismissed();
// Annotate password related (username, password) DOM input elements with
// corresponding HTML attributes. It is used only for debugging.
AnnotateFieldsWithParsingResult(ParsingResult parsing_result);
}; };
// There is one instance of this interface per render frame in the render // There is one instance of this interface per render frame in the render
......
...@@ -72,6 +72,7 @@ using blink::WebView; ...@@ -72,6 +72,7 @@ using blink::WebView;
namespace autofill { namespace autofill {
using form_util::FindFormControlElementsByUniqueRendererId;
using form_util::IsFormControlVisible; using form_util::IsFormControlVisible;
using form_util::IsFormVisible; using form_util::IsFormVisible;
...@@ -87,6 +88,7 @@ const size_t kMaximumTextSizeForAutocomplete = 1000; ...@@ -87,6 +88,7 @@ const size_t kMaximumTextSizeForAutocomplete = 1000;
// Names of HTML attributes to show form and field signatures for debugging. // Names of HTML attributes to show form and field signatures for debugging.
const char kDebugAttributeForFormSignature[] = "form_signature"; const char kDebugAttributeForFormSignature[] = "form_signature";
const char kDebugAttributeForFieldSignature[] = "field_signature"; const char kDebugAttributeForFieldSignature[] = "field_signature";
const char kDebugAttributeForParserAnnotations[] = "pm_parser_annotation";
// Maps element names to the actual elements to simplify form filling. // Maps element names to the actual elements to simplify form filling.
typedef std::map<base::string16, WebInputElement> FormInputElementMap; typedef std::map<base::string16, WebInputElement> FormInputElementMap;
...@@ -380,6 +382,19 @@ bool FormHasNonEmptyPasswordField(const FormData& form) { ...@@ -380,6 +382,19 @@ bool FormHasNonEmptyPasswordField(const FormData& form) {
return false; return false;
} }
void AnnotateFieldWithParsingResult(WebDocument doc,
uint32_t renderer_id,
const std::string& text) {
if (renderer_id == FormData::kNotSetFormRendererId)
return;
auto element = FindFormControlElementsByUniqueRendererId(doc, renderer_id);
if (element.IsNull())
return;
element.SetAttribute(
WebString::FromASCII(kDebugAttributeForParserAnnotations),
WebString::FromASCII(text));
}
} // namespace } // namespace
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
...@@ -1177,6 +1192,28 @@ void PasswordAutofillAgent::FillPasswordForm( ...@@ -1177,6 +1192,28 @@ void PasswordAutofillAgent::FillPasswordForm(
logger.get()); logger.get());
} }
void PasswordAutofillAgent::SetLoggingState(bool active) {
logging_state_active_ = active;
}
void PasswordAutofillAgent::TouchToFillDismissed() {
should_show_touch_to_fill_ = false;
}
void PasswordAutofillAgent::AnnotateFieldsWithParsingResult(
const ParsingResult& parsing_result) {
WebDocument doc = render_frame()->GetWebFrame()->GetDocument();
AnnotateFieldWithParsingResult(doc, parsing_result.username_renderer_id,
"username_element");
AnnotateFieldWithParsingResult(doc, parsing_result.password_renderer_id,
"password_element");
AnnotateFieldWithParsingResult(doc, parsing_result.new_password_renderer_id,
"new_password_element");
AnnotateFieldWithParsingResult(doc,
parsing_result.confirm_password_renderer_id,
"confirmation_password_element");
}
void PasswordAutofillAgent::FocusedNodeHasChanged(const blink::WebNode& node) { void PasswordAutofillAgent::FocusedNodeHasChanged(const blink::WebNode& node) {
DCHECK(!node.IsNull()); DCHECK(!node.IsNull());
focused_input_element_.Reset(); focused_input_element_.Reset();
...@@ -1261,15 +1298,6 @@ PasswordAutofillAgent::GetSimplifiedPasswordFormFromUnownedInputElements() { ...@@ -1261,15 +1298,6 @@ PasswordAutofillAgent::GetSimplifiedPasswordFormFromUnownedInputElements() {
*web_frame, &field_data_manager_, &username_detector_cache_); *web_frame, &field_data_manager_, &username_detector_cache_);
} }
// mojom::PasswordAutofillAgent:
void PasswordAutofillAgent::SetLoggingState(bool active) {
logging_state_active_ = active;
}
void PasswordAutofillAgent::TouchToFillDismissed() {
should_show_touch_to_fill_ = false;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// PasswordAutofillAgent, private: // PasswordAutofillAgent, private:
......
...@@ -130,6 +130,8 @@ class PasswordAutofillAgent : public content::RenderFrameObserver, ...@@ -130,6 +130,8 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
const base::string16& credential) override; const base::string16& credential) override;
void SetLoggingState(bool active) override; void SetLoggingState(bool active) override;
void TouchToFillDismissed() override; void TouchToFillDismissed() override;
void AnnotateFieldsWithParsingResult(
const ParsingResult& parsing_result) override;
// FormTracker::Observer // FormTracker::Observer
void OnProvisionallySaveForm(const blink::WebFormElement& form, void OnProvisionallySaveForm(const blink::WebFormElement& form,
......
...@@ -294,3 +294,11 @@ struct PasswordForm { ...@@ -294,3 +294,11 @@ struct PasswordForm {
SubmissionIndicatorEvent submission_event; SubmissionIndicatorEvent submission_event;
bool only_for_fallback; bool only_for_fallback;
}; };
// autofill::ParsingResult
struct ParsingResult {
uint32 username_renderer_id;
uint32 password_renderer_id;
uint32 new_password_renderer_id;
uint32 confirm_password_renderer_id;
};
...@@ -31,6 +31,7 @@ type_mappings = [ ...@@ -31,6 +31,7 @@ type_mappings = [
"autofill.mojom.FormFieldData=::autofill::FormFieldData", "autofill.mojom.FormFieldData=::autofill::FormFieldData",
"autofill.mojom.FormFieldDataPredictions=::autofill::FormFieldDataPredictions", "autofill.mojom.FormFieldDataPredictions=::autofill::FormFieldDataPredictions",
"autofill.mojom.FormsPredictionsMap=::autofill::FormsPredictionsMap", "autofill.mojom.FormsPredictionsMap=::autofill::FormsPredictionsMap",
"autofill.mojom.ParsingResult=::autofill::ParsingResult",
"autofill.mojom.PasswordAndRealm=::autofill::PasswordAndRealm", "autofill.mojom.PasswordAndRealm=::autofill::PasswordAndRealm",
"autofill.mojom.PasswordForm=::autofill::PasswordForm", "autofill.mojom.PasswordForm=::autofill::PasswordForm",
"autofill.mojom.PasswordFormFieldPredictionMap=::autofill::PasswordFormFieldPredictionMap", "autofill.mojom.PasswordFormFieldPredictionMap=::autofill::PasswordFormFieldPredictionMap",
......
...@@ -308,4 +308,16 @@ bool StructTraits<autofill::mojom::ValueElementPairDataView, ...@@ -308,4 +308,16 @@ bool StructTraits<autofill::mojom::ValueElementPairDataView,
return true; return true;
} }
bool StructTraits<
autofill::mojom::ParsingResultDataView,
autofill::ParsingResult>::Read(autofill::mojom::ParsingResultDataView data,
autofill::ParsingResult* out) {
out->username_renderer_id = data.username_renderer_id();
out->password_renderer_id = data.password_renderer_id();
out->new_password_renderer_id = data.new_password_renderer_id();
out->confirm_password_renderer_id = data.confirm_password_renderer_id();
return true;
}
} // namespace mojo } // namespace mojo
...@@ -591,6 +591,30 @@ struct StructTraits<autofill::mojom::ValueElementPairDataView, ...@@ -591,6 +591,30 @@ struct StructTraits<autofill::mojom::ValueElementPairDataView,
autofill::ValueElementPair* out); autofill::ValueElementPair* out);
}; };
template <>
struct StructTraits<autofill::mojom::ParsingResultDataView,
autofill::ParsingResult> {
static uint32_t username_renderer_id(const autofill::ParsingResult& r) {
return r.username_renderer_id;
}
static uint32_t password_renderer_id(const autofill::ParsingResult& r) {
return r.password_renderer_id;
}
static uint32_t new_password_renderer_id(const autofill::ParsingResult& r) {
return r.new_password_renderer_id;
}
static uint32_t confirm_password_renderer_id(
const autofill::ParsingResult& r) {
return r.confirm_password_renderer_id;
}
static bool Read(autofill::mojom::ParsingResultDataView data,
autofill::ParsingResult* out);
};
} // namespace mojo } // namespace mojo
#endif // COMPONENTS_AUTOFILL_CORE_COMMON_MOJOM_AUTOFILL_TYPES_MOJOM_TRAITS_H_ #endif // COMPONENTS_AUTOFILL_CORE_COMMON_MOJOM_AUTOFILL_TYPES_MOJOM_TRAITS_H_
...@@ -13,6 +13,14 @@ ...@@ -13,6 +13,14 @@
namespace autofill { namespace autofill {
// Contains renderer ids of password related elements found by the form parser.
struct ParsingResult {
uint32_t username_renderer_id;
uint32_t password_renderer_id;
uint32_t new_password_renderer_id;
uint32_t confirm_password_renderer_id;
};
struct PasswordAndRealm { struct PasswordAndRealm {
base::string16 password; base::string16 password;
std::string realm; std::string realm;
......
...@@ -188,6 +188,11 @@ const GURL& ContentPasswordManagerDriver::GetLastCommittedURL() const { ...@@ -188,6 +188,11 @@ const GURL& ContentPasswordManagerDriver::GetLastCommittedURL() const {
return render_frame_host_->GetLastCommittedURL(); return render_frame_host_->GetLastCommittedURL();
} }
void ContentPasswordManagerDriver::AnnotateFieldsWithParsingResult(
const autofill::ParsingResult& parsing_result) {
GetPasswordAutofillAgent()->AnnotateFieldsWithParsingResult(parsing_result);
}
void ContentPasswordManagerDriver::GeneratePassword( void ContentPasswordManagerDriver::GeneratePassword(
autofill::mojom::PasswordGenerationAgent:: autofill::mojom::PasswordGenerationAgent::
UserTriggeredGeneratePasswordCallback callback) { UserTriggeredGeneratePasswordCallback callback) {
......
...@@ -77,6 +77,8 @@ class ContentPasswordManagerDriver ...@@ -77,6 +77,8 @@ class ContentPasswordManagerDriver
autofill::AutofillDriver* GetAutofillDriver() override; autofill::AutofillDriver* GetAutofillDriver() override;
bool IsMainFrame() const override; bool IsMainFrame() const override;
const GURL& GetLastCommittedURL() const override; const GURL& GetLastCommittedURL() const override;
void AnnotateFieldsWithParsingResult(
const autofill::ParsingResult& parsing_result) override;
// Notify the renderer that the user wants to generate password manually. // Notify the renderer that the user wants to generate password manually.
void GeneratePassword(autofill::mojom::PasswordGenerationAgent:: void GeneratePassword(autofill::mojom::PasswordGenerationAgent::
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
using autofill::ParsingResult;
using autofill::PasswordForm; using autofill::PasswordForm;
using autofill::PasswordFormFillData; using autofill::PasswordFormFillData;
using base::ASCIIToUTF16; using base::ASCIIToUTF16;
...@@ -82,9 +83,10 @@ class FakePasswordAutofillAgent ...@@ -82,9 +83,10 @@ class FakePasswordAutofillAgent
} }
// autofill::mojom::PasswordAutofillAgent: // autofill::mojom::PasswordAutofillAgent:
MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&)); MOCK_METHOD1(FillPasswordForm, void(const PasswordFormFillData&));
MOCK_METHOD2(FillIntoFocusedField, void(bool, const base::string16&)); MOCK_METHOD2(FillIntoFocusedField, void(bool, const base::string16&));
MOCK_METHOD0(TouchToFillDismissed, void()); MOCK_METHOD0(TouchToFillDismissed, void());
MOCK_METHOD1(AnnotateFieldsWithParsingResult, void(const ParsingResult&));
MOCK_METHOD0(BlacklistedFormFound, void()); MOCK_METHOD0(BlacklistedFormFound, void());
......
...@@ -90,6 +90,16 @@ LikelyFormFilling SendFillInformationToRenderer( ...@@ -90,6 +90,16 @@ LikelyFormFilling SendFillInformationToRenderer(
DCHECK(driver); DCHECK(driver);
DCHECK_EQ(PasswordForm::Scheme::kHtml, observed_form.scheme); DCHECK_EQ(PasswordForm::Scheme::kHtml, observed_form.scheme);
if (autofill::IsShowAutofillSignaturesEnabled()) {
driver->AnnotateFieldsWithParsingResult(
{.username_renderer_id = observed_form.username_element_renderer_id,
.password_renderer_id = observed_form.password_element_renderer_id,
.new_password_renderer_id =
observed_form.new_password_element_renderer_id,
.confirm_password_renderer_id =
observed_form.confirmation_password_element_renderer_id});
}
if (best_matches.empty()) { if (best_matches.empty()) {
driver->InformNoSavedCredentials(); driver->InformNoSavedCredentials();
metrics_recorder->RecordFillEvent( metrics_recorder->RecordFillEvent(
......
...@@ -104,6 +104,11 @@ class PasswordManagerDriver ...@@ -104,6 +104,11 @@ class PasswordManagerDriver
// Returns the last committed URL of the frame. // Returns the last committed URL of the frame.
virtual const GURL& GetLastCommittedURL() const = 0; virtual const GURL& GetLastCommittedURL() const = 0;
// Annotate password related (username, password) DOM input elements with
// corresponding HTML attributes. It is used only for debugging.
virtual void AnnotateFieldsWithParsingResult(
const autofill::ParsingResult& parsing_result) {}
private: private:
DISALLOW_COPY_AND_ASSIGN(PasswordManagerDriver); DISALLOW_COPY_AND_ASSIGN(PasswordManagerDriver);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment