Skip to content

Commit de5f2b4

Browse files
authored
Revert "Revert "Adds fuchsia node roles to accessibility bridge updates. (flutter#20385)" (flutter#20936)" (flutter#21367)
This reverts commit 96efe39.
1 parent 1fc87c0 commit de5f2b4

File tree

6 files changed

+102
-3
lines changed

6 files changed

+102
-3
lines changed

lib/ui/semantics.dart

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,12 @@ class SemanticsFlag {
300300
static const int _kIsReadOnlyIndex = 1 << 20;
301301
static const int _kIsFocusableIndex = 1 << 21;
302302
static const int _kIsLinkIndex = 1 << 22;
303+
static const int _kIsSliderIndex = 1 << 23;
303304
// READ THIS: if you add a flag here, you MUST update the numSemanticsFlags
304-
// value in testing/dart/semantics_test.dart, or tests will fail.
305+
// value in testing/dart/semantics_test.dart, or tests will fail. Also,
306+
// please update the Flag enum in
307+
// flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java,
308+
// and the SemanticsFlag class in lib/web_ui/lib/src/ui/semantics.dart.
305309

306310
const SemanticsFlag._(this.index) : assert(index != null); // ignore: unnecessary_null_comparison
307311

@@ -355,6 +359,9 @@ class SemanticsFlag {
355359
/// affordances.
356360
static const SemanticsFlag isTextField = SemanticsFlag._(_kIsTextFieldIndex);
357361

362+
/// Whether the semantic node represents a slider.
363+
static const SemanticsFlag isSlider = SemanticsFlag._(_kIsSliderIndex);
364+
358365
/// Whether the semantic node is read only.
359366
///
360367
/// Only applicable when [isTextField] is true.
@@ -551,7 +558,8 @@ class SemanticsFlag {
551558
_kIsReadOnlyIndex: isReadOnly,
552559
_kIsFocusableIndex: isFocusable,
553560
_kIsLinkIndex: isLink,
554-
};
561+
_kIsSliderIndex: isSlider,
562+
};
555563

556564
@override
557565
String toString() {
@@ -602,6 +610,8 @@ class SemanticsFlag {
602610
return 'SemanticsFlag.isFocusable';
603611
case _kIsLinkIndex:
604612
return 'SemanticsFlag.isLink';
613+
case _kIsSliderIndex:
614+
return 'SemanticsFlag.isSlider';
605615
}
606616
assert(false, 'Unhandled index: $index');
607617
return '';

lib/ui/semantics/semantics_node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ enum class SemanticsFlags : int32_t {
7878
kIsReadOnly = 1 << 20,
7979
kIsFocusable = 1 << 21,
8080
kIsLink = 1 << 22,
81+
kIsSlider = 1 << 23,
8182
};
8283

8384
const int kScrollableSemanticsFlags =

lib/web_ui/lib/src/ui/semantics.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ class SemanticsFlag {
156156
static const int _kIsReadOnlyIndex = 1 << 20;
157157
static const int _kIsFocusableIndex = 1 << 21;
158158
static const int _kIsLinkIndex = 1 << 22;
159+
static const int _kIsSliderIndex = 1 << 23;
159160

160161
const SemanticsFlag._(this.index) : assert(index != null); // ignore: unnecessary_null_comparison
161162
final int index;
@@ -182,12 +183,14 @@ class SemanticsFlag {
182183
static const SemanticsFlag isToggled = SemanticsFlag._(_kIsToggledIndex);
183184
static const SemanticsFlag hasImplicitScrolling = SemanticsFlag._(_kHasImplicitScrollingIndex);
184185
static const SemanticsFlag isMultiline = SemanticsFlag._(_kIsMultilineIndex);
186+
static const SemanticsFlag isSlider = SemanticsFlag._(_kIsSliderIndex);
185187
static const Map<int, SemanticsFlag> values = <int, SemanticsFlag>{
186188
_kHasCheckedStateIndex: hasCheckedState,
187189
_kIsCheckedIndex: isChecked,
188190
_kIsSelectedIndex: isSelected,
189191
_kIsButtonIndex: isButton,
190192
_kIsLinkIndex: isLink,
193+
_kIsSliderIndex: isSlider,
191194
_kIsTextFieldIndex: isTextField,
192195
_kIsFocusableIndex: isFocusable,
193196
_kIsFocusedIndex: isFocused,

shell/platform/fuchsia/flutter/accessibility_bridge.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,15 @@ fuchsia::accessibility::semantics::Role AccessibilityBridge::GetNodeRole(
150150
if (node.HasFlag(flutter::SemanticsFlags::kIsButton)) {
151151
return fuchsia::accessibility::semantics::Role::BUTTON;
152152
}
153+
154+
if (node.HasFlag(flutter::SemanticsFlags::kIsTextField)) {
155+
return fuchsia::accessibility::semantics::Role::TEXT_FIELD;
156+
}
157+
158+
if (node.HasFlag(flutter::SemanticsFlags::kIsSlider)) {
159+
return fuchsia::accessibility::semantics::Role::SLIDER;
160+
}
161+
153162
if (node.HasFlag(flutter::SemanticsFlags::kIsHeader)) {
154163
return fuchsia::accessibility::semantics::Role::HEADER;
155164
}
@@ -281,6 +290,7 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
281290
.set_attributes(GetNodeAttributes(flutter_node, &this_node_size))
282291
.set_states(GetNodeStates(flutter_node, &this_node_size))
283292
.set_actions(GetNodeActions(flutter_node, &this_node_size))
293+
.set_role(GetNodeRole(flutter_node))
284294
.set_child_ids(child_ids);
285295
this_node_size +=
286296
kNodeIdSize * flutter_node.childrenInTraversalOrder.size();

shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@
1919

2020
namespace flutter_runner_test {
2121

22+
namespace {
23+
24+
void ExpectNodeHasRole(
25+
const fuchsia::accessibility::semantics::Node& node,
26+
const std::unordered_map<uint32_t, fuchsia::accessibility::semantics::Role>
27+
roles_by_node_id) {
28+
ASSERT_TRUE(node.has_node_id());
29+
ASSERT_NE(roles_by_node_id.find(node.node_id()), roles_by_node_id.end());
30+
EXPECT_TRUE(node.has_role());
31+
EXPECT_EQ(node.role(), roles_by_node_id.at(node.node_id()));
32+
}
33+
34+
} // namespace
35+
2236
class AccessibilityBridgeTestDelegate
2337
: public flutter_runner::AccessibilityBridge::Delegate {
2438
public:
@@ -89,6 +103,67 @@ TEST_F(AccessibilityBridgeTest, EnableDisable) {
89103
EXPECT_TRUE(accessibility_delegate_.enabled());
90104
}
91105

106+
TEST_F(AccessibilityBridgeTest, UpdatesNodeRoles) {
107+
flutter::SemanticsNodeUpdates updates;
108+
109+
flutter::SemanticsNode node0;
110+
node0.id = 0;
111+
node0.flags |= static_cast<int>(flutter::SemanticsFlags::kIsButton);
112+
node0.childrenInTraversalOrder = {1, 2, 3, 4};
113+
node0.childrenInHitTestOrder = {1, 2, 3, 4};
114+
updates.emplace(0, node0);
115+
116+
flutter::SemanticsNode node1;
117+
node1.id = 1;
118+
node1.flags |= static_cast<int>(flutter::SemanticsFlags::kIsHeader);
119+
node1.childrenInTraversalOrder = {};
120+
node1.childrenInHitTestOrder = {};
121+
updates.emplace(1, node1);
122+
123+
flutter::SemanticsNode node2;
124+
node2.id = 2;
125+
node2.flags |= static_cast<int>(flutter::SemanticsFlags::kIsImage);
126+
node2.childrenInTraversalOrder = {};
127+
node2.childrenInHitTestOrder = {};
128+
updates.emplace(2, node2);
129+
130+
flutter::SemanticsNode node3;
131+
node3.id = 3;
132+
node3.flags |= static_cast<int>(flutter::SemanticsFlags::kIsTextField);
133+
node3.childrenInTraversalOrder = {};
134+
node3.childrenInHitTestOrder = {};
135+
updates.emplace(3, node3);
136+
137+
flutter::SemanticsNode node4;
138+
node4.childrenInTraversalOrder = {};
139+
node4.childrenInHitTestOrder = {};
140+
node4.id = 4;
141+
node4.flags |= static_cast<int>(flutter::SemanticsFlags::kIsSlider);
142+
updates.emplace(4, node4);
143+
144+
accessibility_bridge_->AddSemanticsNodeUpdate(std::move(updates));
145+
RunLoopUntilIdle();
146+
147+
std::unordered_map<uint32_t, fuchsia::accessibility::semantics::Role>
148+
roles_by_node_id = {
149+
{0u, fuchsia::accessibility::semantics::Role::BUTTON},
150+
{1u, fuchsia::accessibility::semantics::Role::HEADER},
151+
{2u, fuchsia::accessibility::semantics::Role::IMAGE},
152+
{3u, fuchsia::accessibility::semantics::Role::TEXT_FIELD},
153+
{4u, fuchsia::accessibility::semantics::Role::SLIDER}};
154+
155+
EXPECT_EQ(0, semantics_manager_.DeleteCount());
156+
EXPECT_EQ(1, semantics_manager_.UpdateCount());
157+
EXPECT_EQ(1, semantics_manager_.CommitCount());
158+
EXPECT_EQ(5U, semantics_manager_.LastUpdatedNodes().size());
159+
for (const auto& node : semantics_manager_.LastUpdatedNodes()) {
160+
ExpectNodeHasRole(node, roles_by_node_id);
161+
}
162+
163+
EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
164+
EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
165+
}
166+
92167
TEST_F(AccessibilityBridgeTest, DeletesChildrenTransitively) {
93168
// Test that when a node is deleted, so are its transitive children.
94169
flutter::SemanticsNode node2;

testing/dart/semantics_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
99
/// Verifies Semantics flags and actions.
1010
void main() {
1111
// This must match the number of flags in lib/ui/semantics.dart
12-
const int numSemanticsFlags = 23;
12+
const int numSemanticsFlags = 24;
1313
test('SemanticsFlag.values refers to all flags.', () async {
1414
expect(SemanticsFlag.values.length, equals(numSemanticsFlags));
1515
for (int index = 0; index < numSemanticsFlags; ++index) {

0 commit comments

Comments
 (0)