Commit 52905e20 authored by Tess Eisenberger's avatar Tess Eisenberger Committed by Commit Bot

[fuchsia][a11y] Advertise more nodes with default action

This change expands the set of AxNodes that the bridge considers
to support default actions for the purpose of advertising that
support to the Fuchsia a11y-manager.  This will let the screen
reader interact with many more nodes.

R=lucasradaelli@google.com, sergeyu@chromium.org, yangsharon@chromium.org

Test: AccessibilityBridgeTest.PerformDefaultAction
Bug: fuchsia:57669
Change-Id: I6b0858179a6b9ff44fc3c927caa9e517f8ad47e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2459933
Commit-Queue: Tess Eisenberger <teisenbe@google.com>
Reviewed-by: default avatarSergey Ulanov <sergeyu@chromium.org>
Reviewed-by: default avatarSharon Yang <yangsharon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815397}
parent 80cc624b
...@@ -73,6 +73,16 @@ content::AXEventNotificationDetails CreateAccessibilityEventWithUpdate( ...@@ -73,6 +73,16 @@ content::AXEventNotificationDetails CreateAccessibilityEventWithUpdate(
return event; return event;
} }
// Returns whether or not the given node supports the given action.
bool HasAction(const fuchsia::accessibility::semantics::Node& node,
fuchsia::accessibility::semantics::Action action) {
for (const auto& node_action : node.actions()) {
if (node_action == action)
return true;
}
return false;
}
} // namespace } // namespace
class AccessibilityBridgeTest : public cr_fuchsia::WebEngineBrowserTest { class AccessibilityBridgeTest : public cr_fuchsia::WebEngineBrowserTest {
...@@ -250,6 +260,13 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, PerformDefaultAction) { ...@@ -250,6 +260,13 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, PerformDefaultAction) {
semantics_manager_.semantic_tree()->GetNodeFromLabel(kButtonName3); semantics_manager_.semantic_tree()->GetNodeFromLabel(kButtonName3);
EXPECT_TRUE(button3); EXPECT_TRUE(button3);
EXPECT_TRUE(
HasAction(*button1, fuchsia::accessibility::semantics::Action::DEFAULT));
EXPECT_TRUE(
HasAction(*button2, fuchsia::accessibility::semantics::Action::DEFAULT));
EXPECT_TRUE(
HasAction(*button3, fuchsia::accessibility::semantics::Action::DEFAULT));
// Perform the default action (click) on multiple buttons. // Perform the default action (click) on multiple buttons.
semantics_manager_.RequestAccessibilityAction( semantics_manager_.RequestAccessibilityAction(
button1->node_id(), fuchsia::accessibility::semantics::Action::DEFAULT); button1->node_id(), fuchsia::accessibility::semantics::Action::DEFAULT);
......
...@@ -138,7 +138,10 @@ std::vector<fuchsia::accessibility::semantics::Action> ConvertActions( ...@@ -138,7 +138,10 @@ std::vector<fuchsia::accessibility::semantics::Action> ConvertActions(
const ui::AXNodeData& node) { const ui::AXNodeData& node) {
std::vector<fuchsia::accessibility::semantics::Action> fuchsia_actions; std::vector<fuchsia::accessibility::semantics::Action> fuchsia_actions;
if (node.HasAction(ax::mojom::Action::kDoDefault)) { const bool has_default =
node.HasAction(ax::mojom::Action::kDoDefault) ||
node.GetDefaultActionVerb() != ax::mojom::DefaultActionVerb::kNone;
if (has_default) {
fuchsia_actions.push_back( fuchsia_actions.push_back(
fuchsia::accessibility::semantics::Action::DEFAULT); fuchsia::accessibility::semantics::Action::DEFAULT);
} }
......
...@@ -26,6 +26,7 @@ const char kValue1[] = "user entered value"; ...@@ -26,6 +26,7 @@ const char kValue1[] = "user entered value";
const int32_t kChildId1 = 23901; const int32_t kChildId1 = 23901;
const int32_t kChildId2 = 484345; const int32_t kChildId2 = 484345;
const int32_t kChildId3 = 4156877; const int32_t kChildId3 = 4156877;
const int32_t kRootId = 5;
const int32_t kRectX = 1; const int32_t kRectX = 1;
const int32_t kRectY = 2; const int32_t kRectY = 2;
const int32_t kRectWidth = 7; const int32_t kRectWidth = 7;
...@@ -79,29 +80,20 @@ Node CreateSemanticNode(uint32_t id, ...@@ -79,29 +80,20 @@ Node CreateSemanticNode(uint32_t id,
return node; return node;
} }
class AXTreeConverterTest : public testing::Test { // Create an AXNodeData and a Fuchsia node that represent the same information.
public: std::pair<ui::AXNodeData, Node> CreateSemanticNodeAllFieldsSet() {
AXTreeConverterTest() = default;
~AXTreeConverterTest() override = default;
DISALLOW_COPY_AND_ASSIGN(AXTreeConverterTest);
};
TEST_F(AXTreeConverterTest, AllFieldsSetAndEqual) {
ui::AXRelativeBounds relative_bounds = ui::AXRelativeBounds(); ui::AXRelativeBounds relative_bounds = ui::AXRelativeBounds();
relative_bounds.bounds = gfx::RectF(kRectX, kRectY, kRectWidth, kRectHeight); relative_bounds.bounds = gfx::RectF(kRectX, kRectY, kRectWidth, kRectHeight);
relative_bounds.transform = relative_bounds.transform =
std::make_unique<gfx::Transform>(gfx::Transform::kSkipInitialization); std::make_unique<gfx::Transform>(gfx::Transform::kSkipInitialization);
relative_bounds.transform->MakeIdentity(); relative_bounds.transform->MakeIdentity();
auto source_node_data = CreateAXNodeData( auto ax_node_data = CreateAXNodeData(
ax::mojom::Role::kButton, ax::mojom::Action::kFocus, ax::mojom::Role::kButton, ax::mojom::Action::kFocus,
std::vector<int32_t>{kChildId1, kChildId2, kChildId3}, relative_bounds, std::vector<int32_t>{kChildId1, kChildId2, kChildId3}, relative_bounds,
kLabel1, kDescription1, ax::mojom::CheckedState::kMixed); kLabel1, kDescription1, ax::mojom::CheckedState::kMixed);
source_node_data.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false); ax_node_data.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
source_node_data.RemoveState(ax::mojom::State::kIgnored); ax_node_data.RemoveState(ax::mojom::State::kIgnored);
auto converted_node = AXNodeDataToSemanticNode(source_node_data); ax_node_data.id = kChildId1;
EXPECT_EQ(static_cast<uint32_t>(source_node_data.id),
converted_node.node_id());
Attributes attributes; Attributes attributes;
attributes.set_label(kLabel1); attributes.set_label(kLabel1);
...@@ -115,12 +107,32 @@ TEST_F(AXTreeConverterTest, AllFieldsSetAndEqual) { ...@@ -115,12 +107,32 @@ TEST_F(AXTreeConverterTest, AllFieldsSetAndEqual) {
states.set_checked_state(CheckedState::MIXED); states.set_checked_state(CheckedState::MIXED);
states.set_hidden(false); states.set_hidden(false);
states.set_selected(false); states.set_selected(false);
auto expected_node = CreateSemanticNode( auto fuchsia_node = CreateSemanticNode(
static_cast<uint32_t>(source_node_data.id), Role::BUTTON, ConvertToFuchsiaNodeId(ax_node_data.id, kRootId), Role::BUTTON,
std::move(attributes), std::move(states), std::move(attributes), std::move(states),
std::vector<Action>{Action::SET_FOCUS}, std::vector<Action>{Action::SET_FOCUS},
std::vector<uint32_t>{kChildId1, kChildId2, kChildId3}, box, mat.value); std::vector<uint32_t>{kChildId1, kChildId2, kChildId3}, box, mat.value);
return std::make_pair(std::move(ax_node_data), std::move(fuchsia_node));
}
class AXTreeConverterTest : public testing::Test {
public:
AXTreeConverterTest() = default;
~AXTreeConverterTest() override = default;
DISALLOW_COPY_AND_ASSIGN(AXTreeConverterTest);
};
TEST_F(AXTreeConverterTest, AllFieldsSetAndEqual) {
auto nodes = CreateSemanticNodeAllFieldsSet();
auto& source_node_data = nodes.first;
auto& expected_node = nodes.second;
auto converted_node = AXNodeDataToSemanticNode(source_node_data);
EXPECT_EQ(ConvertToFuchsiaNodeId(source_node_data.id, kRootId),
converted_node.node_id());
EXPECT_TRUE(fidl::Equals(converted_node, expected_node)); EXPECT_TRUE(fidl::Equals(converted_node, expected_node));
} }
...@@ -204,6 +216,25 @@ TEST_F(AXTreeConverterTest, FieldMismatch) { ...@@ -204,6 +216,25 @@ TEST_F(AXTreeConverterTest, FieldMismatch) {
EXPECT_FALSE(fidl::Equals(converted_node, expected_node)); EXPECT_FALSE(fidl::Equals(converted_node, expected_node));
} }
TEST_F(AXTreeConverterTest, DefaultAction) {
auto nodes = CreateSemanticNodeAllFieldsSet();
auto& source_node_data = nodes.first;
auto& expected_node = nodes.second;
// Default action verb on an AXNodeData is equivalent to Action::DEFAULT on a
// Fuchsia semantic node.
source_node_data.SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kClick);
expected_node.mutable_actions()->insert(
expected_node.mutable_actions()->begin(),
fuchsia::accessibility::semantics::Action::DEFAULT);
auto converted_node = AXNodeDataToSemanticNode(source_node_data);
EXPECT_EQ(ConvertToFuchsiaNodeId(source_node_data.id, kRootId),
converted_node.node_id());
EXPECT_TRUE(fidl::Equals(converted_node, expected_node));
}
TEST_F(AXTreeConverterTest, ConvertToFuchsiaNodeId) { TEST_F(AXTreeConverterTest, ConvertToFuchsiaNodeId) {
// Root AxNode is 0, Fuchsia is also 0. // Root AxNode is 0, Fuchsia is also 0.
EXPECT_EQ(0u, ConvertToFuchsiaNodeId(0, 0)); EXPECT_EQ(0u, ConvertToFuchsiaNodeId(0, 0));
......
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