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

Commit 4a55b4f

Browse files
authored
Modifies accessibility bridge to populate new node fields in semantic… (#15116)
1 parent cb9d1bf commit 4a55b4f

3 files changed

Lines changed: 177 additions & 7 deletions

File tree

shell/platform/fuchsia/flutter/accessibility_bridge.cc

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,38 @@ AccessibilityBridge::GetNodeAttributes(const flutter::SemanticsNode& node,
8080
}
8181

8282
fuchsia::accessibility::semantics::States AccessibilityBridge::GetNodeStates(
83-
const flutter::SemanticsNode& node) const {
83+
const flutter::SemanticsNode& node,
84+
size_t* additional_size) const {
8485
fuchsia::accessibility::semantics::States states;
85-
if (node.HasFlag(flutter::SemanticsFlags::kHasCheckedState)) {
86-
states.set_checked(node.HasFlag(flutter::SemanticsFlags::kIsChecked));
86+
(*additional_size) += sizeof(fuchsia::accessibility::semantics::States);
87+
88+
// Set checked state.
89+
if (!node.HasFlag(flutter::SemanticsFlags::kHasCheckedState)) {
90+
states.set_checked_state(
91+
fuchsia::accessibility::semantics::CheckedState::NONE);
92+
} else {
93+
states.set_checked_state(
94+
node.HasFlag(flutter::SemanticsFlags::kIsChecked)
95+
? fuchsia::accessibility::semantics::CheckedState::CHECKED
96+
: fuchsia::accessibility::semantics::CheckedState::UNCHECKED);
8797
}
98+
99+
// Set selected state.
100+
states.set_selected(node.HasFlag(flutter::SemanticsFlags::kIsSelected));
101+
102+
// Set hidden state.
103+
states.set_hidden(node.HasFlag(flutter::SemanticsFlags::kIsHidden));
104+
105+
// Set value.
106+
if (node.value.size() > fuchsia::accessibility::semantics::MAX_VALUE_SIZE) {
107+
states.set_value(node.value.substr(
108+
0, fuchsia::accessibility::semantics::MAX_VALUE_SIZE));
109+
(*additional_size) += fuchsia::accessibility::semantics::MAX_VALUE_SIZE;
110+
} else {
111+
states.set_value(node.value);
112+
(*additional_size) += node.value.size();
113+
}
114+
88115
return states;
89116
}
90117

@@ -199,7 +226,7 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
199226
.set_location(GetNodeLocation(flutter_node))
200227
.set_transform(GetNodeTransform(flutter_node))
201228
.set_attributes(GetNodeAttributes(flutter_node, &this_node_size))
202-
.set_states(GetNodeStates(flutter_node))
229+
.set_states(GetNodeStates(flutter_node, &this_node_size))
203230
.set_child_ids(child_ids);
204231
this_node_size +=
205232
kNodeIdSize * flutter_node.childrenInTraversalOrder.size();

shell/platform/fuchsia/flutter/accessibility_bridge.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ class AccessibilityBridge
133133
// Derives the states for a Fuchsia semantics node from a Flutter semantics
134134
// node.
135135
fuchsia::accessibility::semantics::States GetNodeStates(
136-
const flutter::SemanticsNode& node) const;
136+
const flutter::SemanticsNode& node,
137+
size_t* additional_size) const;
137138

138139
// Gets the set of reachable descendants from the given node id.
139140
std::unordered_set<int32_t> GetDescendants(int32_t node_id) const;

shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,106 @@ TEST_F(AccessibilityBridgeTest, DeletesChildrenTransitively) {
130130
EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
131131
}
132132

133+
TEST_F(AccessibilityBridgeTest, PopulatesCheckedState) {
134+
flutter::SemanticsNode node0;
135+
node0.id = 0;
136+
// HasCheckedState = true
137+
// IsChecked = true
138+
// IsSelected = false
139+
// IsHidden = false
140+
node0.flags |= static_cast<int>(flutter::SemanticsFlags::kHasCheckedState);
141+
node0.flags |= static_cast<int>(flutter::SemanticsFlags::kIsChecked);
142+
node0.value = "value";
143+
144+
accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}});
145+
RunLoopUntilIdle();
146+
147+
EXPECT_EQ(0, semantics_manager_.DeleteCount());
148+
EXPECT_EQ(1, semantics_manager_.UpdateCount());
149+
EXPECT_EQ(1, semantics_manager_.CommitCount());
150+
EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
151+
const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
152+
EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
153+
EXPECT_TRUE(fuchsia_node.has_states());
154+
const auto& states = fuchsia_node.states();
155+
EXPECT_TRUE(states.has_checked_state());
156+
EXPECT_EQ(states.checked_state(),
157+
fuchsia::accessibility::semantics::CheckedState::CHECKED);
158+
EXPECT_TRUE(states.has_selected());
159+
EXPECT_FALSE(states.selected());
160+
EXPECT_TRUE(states.has_hidden());
161+
EXPECT_FALSE(states.hidden());
162+
EXPECT_TRUE(states.has_value());
163+
EXPECT_EQ(states.value(), node0.value);
164+
165+
EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
166+
EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
167+
}
168+
169+
TEST_F(AccessibilityBridgeTest, PopulatesSelectedState) {
170+
flutter::SemanticsNode node0;
171+
node0.id = 0;
172+
// HasCheckedState = false
173+
// IsChecked = false
174+
// IsSelected = true
175+
// IsHidden = false
176+
node0.flags = static_cast<int>(flutter::SemanticsFlags::kIsSelected);
177+
178+
accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}});
179+
RunLoopUntilIdle();
180+
181+
EXPECT_EQ(0, semantics_manager_.DeleteCount());
182+
EXPECT_EQ(1, semantics_manager_.UpdateCount());
183+
EXPECT_EQ(1, semantics_manager_.CommitCount());
184+
EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
185+
const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
186+
EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
187+
EXPECT_TRUE(fuchsia_node.has_states());
188+
const auto& states = fuchsia_node.states();
189+
EXPECT_TRUE(states.has_checked_state());
190+
EXPECT_EQ(states.checked_state(),
191+
fuchsia::accessibility::semantics::CheckedState::NONE);
192+
EXPECT_TRUE(states.has_selected());
193+
EXPECT_TRUE(states.selected());
194+
EXPECT_TRUE(states.has_hidden());
195+
EXPECT_FALSE(states.hidden());
196+
197+
EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
198+
EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
199+
}
200+
201+
TEST_F(AccessibilityBridgeTest, PopulatesHiddenState) {
202+
flutter::SemanticsNode node0;
203+
node0.id = 0;
204+
// HasCheckedState = false
205+
// IsChecked = false
206+
// IsSelected = false
207+
// IsHidden = true
208+
node0.flags = static_cast<int>(flutter::SemanticsFlags::kIsHidden);
209+
210+
accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}});
211+
RunLoopUntilIdle();
212+
213+
EXPECT_EQ(0, semantics_manager_.DeleteCount());
214+
EXPECT_EQ(1, semantics_manager_.UpdateCount());
215+
EXPECT_EQ(1, semantics_manager_.CommitCount());
216+
EXPECT_EQ(1u, semantics_manager_.LastUpdatedNodes().size());
217+
const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
218+
EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
219+
EXPECT_TRUE(fuchsia_node.has_states());
220+
const auto& states = fuchsia_node.states();
221+
EXPECT_TRUE(states.has_checked_state());
222+
EXPECT_EQ(states.checked_state(),
223+
fuchsia::accessibility::semantics::CheckedState::NONE);
224+
EXPECT_TRUE(states.has_selected());
225+
EXPECT_FALSE(states.selected());
226+
EXPECT_TRUE(states.has_hidden());
227+
EXPECT_TRUE(states.hidden());
228+
229+
EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
230+
EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
231+
}
232+
133233
TEST_F(AccessibilityBridgeTest, TruncatesLargeLabel) {
134234
// Test that labels which are too long are truncated.
135235
flutter::SemanticsNode node0;
@@ -174,6 +274,48 @@ TEST_F(AccessibilityBridgeTest, TruncatesLargeLabel) {
174274
EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
175275
}
176276

277+
TEST_F(AccessibilityBridgeTest, TruncatesLargeValue) {
278+
// Test that values which are too long are truncated.
279+
flutter::SemanticsNode node0;
280+
node0.id = 0;
281+
282+
flutter::SemanticsNode node1;
283+
node1.id = 1;
284+
285+
flutter::SemanticsNode bad_node;
286+
bad_node.id = 2;
287+
bad_node.value =
288+
std::string(fuchsia::accessibility::semantics::MAX_VALUE_SIZE + 1, '2');
289+
290+
node0.childrenInTraversalOrder = {1, 2};
291+
292+
accessibility_bridge_->AddSemanticsNodeUpdate({
293+
{0, node0},
294+
{1, node1},
295+
{2, bad_node},
296+
});
297+
RunLoopUntilIdle();
298+
299+
EXPECT_EQ(0, semantics_manager_.DeleteCount());
300+
EXPECT_EQ(1, semantics_manager_.UpdateCount());
301+
EXPECT_EQ(1, semantics_manager_.CommitCount());
302+
EXPECT_EQ(3U, semantics_manager_.LastUpdatedNodes().size());
303+
auto trimmed_node =
304+
std::find_if(semantics_manager_.LastUpdatedNodes().begin(),
305+
semantics_manager_.LastUpdatedNodes().end(),
306+
[id = static_cast<uint32_t>(bad_node.id)](
307+
fuchsia::accessibility::semantics::Node const& node) {
308+
return node.node_id() == id;
309+
});
310+
ASSERT_NE(trimmed_node, semantics_manager_.LastUpdatedNodes().end());
311+
ASSERT_TRUE(trimmed_node->has_states());
312+
EXPECT_EQ(
313+
trimmed_node->states().value(),
314+
std::string(fuchsia::accessibility::semantics::MAX_VALUE_SIZE, '2'));
315+
EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
316+
EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
317+
}
318+
177319
TEST_F(AccessibilityBridgeTest, SplitsLargeUpdates) {
178320
// Test that labels which are too long are truncated.
179321
flutter::SemanticsNode node0;
@@ -194,8 +336,8 @@ TEST_F(AccessibilityBridgeTest, SplitsLargeUpdates) {
194336

195337
flutter::SemanticsNode node4;
196338
node4.id = 4;
197-
node4.label =
198-
std::string(fuchsia::accessibility::semantics::MAX_LABEL_SIZE, '4');
339+
node4.value =
340+
std::string(fuchsia::accessibility::semantics::MAX_VALUE_SIZE, '4');
199341

200342
node0.childrenInTraversalOrder = {1, 2};
201343
node0.childrenInHitTestOrder = {1, 2};

0 commit comments

Comments
 (0)