[a11y][annotation] Adds node descriptor utterances to screen reader.
This change adds descriptors for nodes of various roles to screen reader
output.
TEST: fx test a11y_lib_tests
Change-Id: I7e500bc3615d520fed59cbdc7287aedd37b8d11f
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/402966
Testability-Review: Alexander Brusher <abrusher@google.com>
Commit-Queue: Alexander Brusher <abrusher@google.com>
Reviewed-by: Lucas Radaelli <lucasradaelli@google.com>
diff --git a/src/ui/a11y/lib/screen_reader/node_describer.cc b/src/ui/a11y/lib/screen_reader/node_describer.cc
index 1b77a37..8ac63db 100644
--- a/src/ui/a11y/lib/screen_reader/node_describer.cc
+++ b/src/ui/a11y/lib/screen_reader/node_describer.cc
@@ -27,6 +27,26 @@
return utterance;
}
+// Returns a message that describes a node where Role == HEADER.
+NodeDescriber::UtteranceAndContext DescribeHeader(a11y::i18n::MessageFormatter* formatter) {
+ NodeDescriber::UtteranceAndContext utterance;
+ auto message = formatter->FormatStringById(static_cast<uint64_t>(MessageIds::ROLE_HEADER));
+ FX_DCHECK(message);
+ utterance.utterance.set_message(std::move(*message));
+ utterance.delay = kDefaultDelay;
+ return utterance;
+}
+
+// Returns a message that describes a node where Role == IMAGE.
+NodeDescriber::UtteranceAndContext DescribeImage(a11y::i18n::MessageFormatter* formatter) {
+ NodeDescriber::UtteranceAndContext utterance;
+ auto message = formatter->FormatStringById(static_cast<uint64_t>(MessageIds::ROLE_IMAGE));
+ FX_DCHECK(message);
+ utterance.utterance.set_message(std::move(*message));
+ utterance.delay = kDefaultDelay;
+ return utterance;
+}
+
} // namespace
NodeDescriber::NodeDescriber(std::unique_ptr<i18n::MessageFormatter> message_formatter)
@@ -51,6 +71,10 @@
if (node->has_role()) {
if (node->role() == Role::BUTTON) {
description.emplace_back(DescribeButton(message_formatter_.get()));
+ } else if (node->role() == Role::HEADER) {
+ description.emplace_back(DescribeHeader(message_formatter_.get()));
+ } else if (node->role() == Role::IMAGE) {
+ description.emplace_back(DescribeImage(message_formatter_.get()));
}
}
}
diff --git a/src/ui/a11y/lib/screen_reader/tests/node_describer_unittest.cc b/src/ui/a11y/lib/screen_reader/tests/node_describer_unittest.cc
index 44dd2c5..b8ed773 100644
--- a/src/ui/a11y/lib/screen_reader/tests/node_describer_unittest.cc
+++ b/src/ui/a11y/lib/screen_reader/tests/node_describer_unittest.cc
@@ -64,5 +64,33 @@
ASSERT_EQ(result[1].utterance.message(), "button");
}
+TEST_F(NodeDescriberTest, NodeHeader) {
+ Node node;
+ node.mutable_attributes()->set_label("foo");
+ node.set_role(Role::HEADER);
+ mock_message_formatter_ptr_->SetMessageForId(static_cast<uint64_t>(MessageIds::ROLE_HEADER),
+ "header");
+ auto result = node_describer_->DescribeNode(&node);
+ ASSERT_EQ(result.size(), 2u);
+ ASSERT_TRUE(result[0].utterance.has_message());
+ ASSERT_EQ(result[0].utterance.message(), "foo");
+ ASSERT_TRUE(result[1].utterance.has_message());
+ ASSERT_EQ(result[1].utterance.message(), "header");
+}
+
+TEST_F(NodeDescriberTest, NodeImage) {
+ Node node;
+ node.mutable_attributes()->set_label("foo");
+ node.set_role(Role::IMAGE);
+ mock_message_formatter_ptr_->SetMessageForId(static_cast<uint64_t>(MessageIds::ROLE_IMAGE),
+ "image");
+ auto result = node_describer_->DescribeNode(&node);
+ ASSERT_EQ(result.size(), 2u);
+ ASSERT_TRUE(result[0].utterance.has_message());
+ ASSERT_EQ(result[0].utterance.message(), "foo");
+ ASSERT_TRUE(result[1].utterance.has_message());
+ ASSERT_EQ(result[1].utterance.message(), "image");
+}
+
} // namespace
} // namespace accessibility_test