Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Includes roles for links, checkboxes, and radio buttons in semantics #22061

Merged
merged 1 commit into from
Oct 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions shell/platform/fuchsia/flutter/accessibility_bridge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ fuchsia::accessibility::semantics::Role AccessibilityBridge::GetNodeRole(
return fuchsia::accessibility::semantics::Role::TEXT_FIELD;
}

if (node.HasFlag(flutter::SemanticsFlags::kIsLink)) {
return fuchsia::accessibility::semantics::Role::LINK;
}

if (node.HasFlag(flutter::SemanticsFlags::kIsSlider)) {
return fuchsia::accessibility::semantics::Role::SLIDER;
}
Expand All @@ -170,6 +174,7 @@ fuchsia::accessibility::semantics::Role AccessibilityBridge::GetNodeRole(
if (node.HasFlag(flutter::SemanticsFlags::kIsImage)) {
return fuchsia::accessibility::semantics::Role::IMAGE;
}

// If a flutter node supports the kIncrease or kDecrease actions, it can be
// treated as a slider control by assistive technology. This is important
// because users have special gestures to deal with sliders, and Fuchsia API
Expand All @@ -178,6 +183,18 @@ fuchsia::accessibility::semantics::Role AccessibilityBridge::GetNodeRole(
node.HasAction(flutter::SemanticsAction::kDecrease)) {
return fuchsia::accessibility::semantics::Role::SLIDER;
}

// If a flutter node has a checked state, then we assume it is either a
// checkbox or a radio button. We distinguish between checkboxes and
// radio buttons based on membership in a mutually exclusive group.
if (node.HasFlag(flutter::SemanticsFlags::kHasCheckedState)) {
if (node.HasFlag(flutter::SemanticsFlags::kIsInMutuallyExclusiveGroup)) {
return fuchsia::accessibility::semantics::Role::RADIO_BUTTON;
} else {
return fuchsia::accessibility::semantics::Role::CHECK_BOX;
}
}

return fuchsia::accessibility::semantics::Role::UNKNOWN;
}

Expand Down
34 changes: 30 additions & 4 deletions shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ TEST_F(AccessibilityBridgeTest, UpdatesNodeRoles) {
flutter::SemanticsNode node0;
node0.id = 0;
node0.flags |= static_cast<int>(flutter::SemanticsFlags::kIsButton);
node0.childrenInTraversalOrder = {1, 2, 3, 4};
node0.childrenInHitTestOrder = {1, 2, 3, 4};
node0.childrenInTraversalOrder = {1, 2, 3, 4, 5, 6, 7};
node0.childrenInHitTestOrder = {1, 2, 3, 4, 5, 6, 7};
updates.emplace(0, node0);

flutter::SemanticsNode node1;
Expand Down Expand Up @@ -141,6 +141,29 @@ TEST_F(AccessibilityBridgeTest, UpdatesNodeRoles) {
node4.flags |= static_cast<int>(flutter::SemanticsFlags::kIsSlider);
updates.emplace(4, node4);

flutter::SemanticsNode node5;
node5.childrenInTraversalOrder = {};
node5.childrenInHitTestOrder = {};
node5.id = 5;
node5.flags |= static_cast<int>(flutter::SemanticsFlags::kIsLink);
updates.emplace(5, node5);

flutter::SemanticsNode node6;
node6.childrenInTraversalOrder = {};
node6.childrenInHitTestOrder = {};
node6.id = 6;
node6.flags |= static_cast<int>(flutter::SemanticsFlags::kHasCheckedState);
node6.flags |=
static_cast<int>(flutter::SemanticsFlags::kIsInMutuallyExclusiveGroup);
updates.emplace(6, node6);

flutter::SemanticsNode node7;
node7.childrenInTraversalOrder = {};
node7.childrenInHitTestOrder = {};
node7.id = 7;
node7.flags |= static_cast<int>(flutter::SemanticsFlags::kHasCheckedState);
updates.emplace(7, node7);

accessibility_bridge_->AddSemanticsNodeUpdate(std::move(updates), 1.f);
RunLoopUntilIdle();

Expand All @@ -150,12 +173,15 @@ TEST_F(AccessibilityBridgeTest, UpdatesNodeRoles) {
{1u, fuchsia::accessibility::semantics::Role::HEADER},
{2u, fuchsia::accessibility::semantics::Role::IMAGE},
{3u, fuchsia::accessibility::semantics::Role::TEXT_FIELD},
{4u, fuchsia::accessibility::semantics::Role::SLIDER}};
{4u, fuchsia::accessibility::semantics::Role::SLIDER},
{5u, fuchsia::accessibility::semantics::Role::LINK},
{6u, fuchsia::accessibility::semantics::Role::RADIO_BUTTON},
{7u, fuchsia::accessibility::semantics::Role::CHECK_BOX}};

EXPECT_EQ(0, semantics_manager_.DeleteCount());
EXPECT_EQ(1, semantics_manager_.UpdateCount());
EXPECT_EQ(1, semantics_manager_.CommitCount());
EXPECT_EQ(5U, semantics_manager_.LastUpdatedNodes().size());
EXPECT_EQ(8u, semantics_manager_.LastUpdatedNodes().size());
for (const auto& node : semantics_manager_.LastUpdatedNodes()) {
ExpectNodeHasRole(node, roles_by_node_id);
}
Expand Down