Flutter Engine
 
Loading...
Searching...
No Matches
flutter_platform_node_delegate_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
8#include "gtest/gtest.h"
9
11
12namespace flutter {
13namespace testing {
14
15TEST(FlutterPlatformNodeDelegateTest, NodeDelegateHasUniqueId) {
16 std::shared_ptr<TestAccessibilityBridge> bridge =
17 std::make_shared<TestAccessibilityBridge>();
18
19 // Add node 0: root.
21 std::vector<int32_t> node0_children{1};
23 node0.child_count = node0_children.size();
24 node0.children_in_traversal_order = node0_children.data();
25 node0.children_in_hit_test_order = node0_children.data();
26 node0.flags2 = &emptyFlags;
27
28 // Add node 1: text child of node 0.
30 node1.label = "prefecture";
31 node1.value = "Kyoto";
32 node1.flags2 = &emptyFlags;
33
34 bridge->AddFlutterSemanticsNodeUpdate(node0);
35 bridge->AddFlutterSemanticsNodeUpdate(node1);
36 bridge->CommitUpdates();
37
38 auto node0_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
39 auto node1_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
40 EXPECT_TRUE(node0_delegate->GetUniqueId() != node1_delegate->GetUniqueId());
41}
42
43TEST(FlutterPlatformNodeDelegateTest, canPerfomActions) {
44 std::shared_ptr<TestAccessibilityBridge> bridge =
45 std::make_shared<TestAccessibilityBridge>();
47 root.id = 0;
49 flags.is_text_field = true;
50 root.flags2 = &flags;
51 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
52 root.actions = static_cast<FlutterSemanticsAction>(0);
53 root.text_selection_base = -1;
54 root.text_selection_extent = -1;
55 root.label = "root";
56 root.hint = "";
57 root.value = "";
58 root.increased_value = "";
59 root.decreased_value = "";
60 root.tooltip = "";
61 root.child_count = 0;
63 root.identifier = "";
64 bridge->AddFlutterSemanticsNodeUpdate(root);
65
66 bridge->CommitUpdates();
67
68 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
69 // Performs an AXAction.
70 ui::AXActionData action_data;
72 accessibility->AccessibilityPerformAction(action_data);
73 EXPECT_EQ(bridge->performed_actions.size(), size_t{1});
74 EXPECT_EQ(bridge->performed_actions[0],
76
78 accessibility->AccessibilityPerformAction(action_data);
79 EXPECT_EQ(bridge->performed_actions.size(), size_t{2});
80 EXPECT_EQ(
81 bridge->performed_actions[1],
83
85 accessibility->AccessibilityPerformAction(action_data);
86 EXPECT_EQ(bridge->performed_actions.size(), size_t{3});
87 EXPECT_EQ(bridge->performed_actions[2],
89}
90
91TEST(FlutterPlatformNodeDelegateTest, canGetAXNode) {
92 // Set up a flutter accessibility node.
93 std::shared_ptr<TestAccessibilityBridge> bridge =
94 std::make_shared<TestAccessibilityBridge>();
96 root.id = 0;
98 flags.is_text_field = true;
99 root.flags2 = &flags;
100 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
101 root.actions = static_cast<FlutterSemanticsAction>(0);
102 root.text_selection_base = -1;
103 root.text_selection_extent = -1;
104 root.label = "root";
105 root.hint = "";
106 root.value = "";
107 root.increased_value = "";
108 root.decreased_value = "";
109 root.tooltip = "";
110 root.child_count = 0;
112 root.identifier = "";
113 bridge->AddFlutterSemanticsNodeUpdate(root);
114
115 bridge->CommitUpdates();
116
117 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
118 EXPECT_EQ(accessibility->GetData().id, 0);
119}
120
121TEST(FlutterPlatformNodeDelegateTest, canCalculateBoundsCorrectly) {
122 std::shared_ptr<TestAccessibilityBridge> bridge =
123 std::make_shared<TestAccessibilityBridge>();
126 root.id = 0;
127 root.label = "root";
128 root.hint = "";
129 root.value = "";
130 root.increased_value = "";
131 root.decreased_value = "";
132 root.tooltip = "";
133 root.child_count = 1;
134 root.flags2 = &flags;
135 int32_t children[] = {1};
136 root.children_in_traversal_order = children;
138 root.identifier = "";
139 root.rect = {0, 0, 100, 100}; // LTRB
140 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
141 bridge->AddFlutterSemanticsNodeUpdate(root);
142
144 child1.id = 1;
145 child1.label = "child 1";
146 child1.hint = "";
147 child1.value = "";
148 child1.increased_value = "";
149 child1.decreased_value = "";
150 child1.tooltip = "";
151 child1.child_count = 0;
152 child1.flags2 = &flags;
154 child1.identifier = "";
155 child1.rect = {0, 0, 50, 50}; // LTRB
156 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
157 bridge->AddFlutterSemanticsNodeUpdate(child1);
158
159 bridge->CommitUpdates();
160 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
162 gfx::Rect bounds =
163 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
165 EXPECT_EQ(bounds.x(), 0);
166 EXPECT_EQ(bounds.y(), 0);
167 EXPECT_EQ(bounds.width(), 25);
168 EXPECT_EQ(bounds.height(), 25);
169 EXPECT_EQ(result, ui::AXOffscreenResult::kOnscreen);
170}
171
172TEST(FlutterPlatformNodeDelegateTest, canCalculateOffScreenBoundsCorrectly) {
173 std::shared_ptr<TestAccessibilityBridge> bridge =
174 std::make_shared<TestAccessibilityBridge>();
177 root.id = 0;
178 root.label = "root";
179 root.hint = "";
180 root.value = "";
181 root.increased_value = "";
182 root.decreased_value = "";
183 root.tooltip = "";
184 root.child_count = 1;
185 root.flags2 = &flags;
186 int32_t children[] = {1};
187 root.children_in_traversal_order = children;
189 root.identifier = "";
190 root.rect = {0, 0, 100, 100}; // LTRB
191 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
192 bridge->AddFlutterSemanticsNodeUpdate(root);
193
195 child1.id = 1;
196 child1.label = "child 1";
197 child1.hint = "";
198 child1.value = "";
199 child1.increased_value = "";
200 child1.decreased_value = "";
201 child1.tooltip = "";
202 child1.child_count = 0;
203 child1.flags2 = &flags;
205 child1.identifier = "";
206 child1.rect = {90, 90, 100, 100}; // LTRB
207 child1.transform = {2, 0, 0, 0, 2, 0, 0, 0, 1};
208 bridge->AddFlutterSemanticsNodeUpdate(child1);
209
210 bridge->CommitUpdates();
211 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
213 gfx::Rect bounds =
214 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
216 EXPECT_EQ(bounds.x(), 180);
217 EXPECT_EQ(bounds.y(), 180);
218 EXPECT_EQ(bounds.width(), 20);
219 EXPECT_EQ(bounds.height(), 20);
220 EXPECT_EQ(result, ui::AXOffscreenResult::kOffscreen);
221}
222
223TEST(FlutterPlatformNodeDelegateTest, canUseOwnerBridge) {
224 std::shared_ptr<TestAccessibilityBridge> bridge =
225 std::make_shared<TestAccessibilityBridge>();
228 root.label = "root";
229 root.hint = "";
230 root.value = "";
231 root.increased_value = "";
232 root.decreased_value = "";
233 root.tooltip = "";
234 root.heading_level = 0;
235 root.child_count = 1;
236 root.flags2 = &flags;
237 int32_t children[] = {1};
238 root.children_in_traversal_order = children;
239 root.custom_accessibility_actions_count = 0;
240 root.identifier = "";
241 root.rect = {0, 0, 100, 100}; // LTRB
242 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
243 bridge->AddFlutterSemanticsNodeUpdate(root);
244
246 child1.label = "child 1";
247 child1.hint = "";
248 child1.value = "";
249 child1.increased_value = "";
250 child1.decreased_value = "";
251 child1.tooltip = "";
252 child1.heading_level = 0;
253 child1.child_count = 0;
254 child1.flags2 = &flags;
255 child1.custom_accessibility_actions_count = 0;
256 child1.identifier = "";
257 child1.rect = {0, 0, 50, 50}; // LTRB
258 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
259 bridge->AddFlutterSemanticsNodeUpdate(child1);
260
261 bridge->CommitUpdates();
262 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
263 auto owner_bridge = child1_node->GetOwnerBridge().lock();
264
265 bool result = false;
266 gfx::RectF bounds = owner_bridge->RelativeToGlobalBounds(
267 child1_node->GetAXNode(), result, true);
268 EXPECT_EQ(bounds.x(), 0);
269 EXPECT_EQ(bounds.y(), 0);
270 EXPECT_EQ(bounds.width(), 25);
271 EXPECT_EQ(bounds.height(), 25);
272 EXPECT_EQ(result, false);
273}
274
275TEST(FlutterPlatformNodeDelegateTest, selfIsLowestPlatformAncestor) {
276 std::shared_ptr<TestAccessibilityBridge> bridge =
277 std::make_shared<TestAccessibilityBridge>();
280 root.id = 0;
281 root.label = "root";
282 root.hint = "";
283 root.value = "";
284 root.increased_value = "";
285 root.decreased_value = "";
286 root.tooltip = "";
287 root.child_count = 0;
288 root.flags2 = &flags;
289 root.children_in_traversal_order = nullptr;
291 root.identifier = "";
292 bridge->AddFlutterSemanticsNodeUpdate(root);
293
294 bridge->CommitUpdates();
295 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
296 auto lowest_platform_ancestor = root_node->GetLowestPlatformAncestor();
297 EXPECT_EQ(root_node->GetNativeViewAccessible(), lowest_platform_ancestor);
298}
299
300TEST(FlutterPlatformNodeDelegateTest, canGetFromNodeID) {
301 std::shared_ptr<TestAccessibilityBridge> bridge =
302 std::make_shared<TestAccessibilityBridge>();
305 root.id = 0;
306 root.label = "root";
307 root.hint = "";
308 root.value = "";
309 root.increased_value = "";
310 root.decreased_value = "";
311 root.tooltip = "";
312 root.child_count = 1;
313 root.flags2 = &flags;
314 int32_t children[] = {1};
315 root.children_in_traversal_order = children;
317 root.identifier = "";
318 bridge->AddFlutterSemanticsNodeUpdate(root);
319
321 child1.id = 1;
322 child1.label = "child 1";
323 child1.hint = "";
324 child1.value = "";
325 child1.increased_value = "";
326 child1.decreased_value = "";
327 child1.tooltip = "";
328 child1.child_count = 0;
329 child1.flags2 = &flags;
331 child1.identifier = "";
332 bridge->AddFlutterSemanticsNodeUpdate(child1);
333
334 bridge->CommitUpdates();
335 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
336 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
337 auto node_by_id = root_node->GetFromNodeID(1);
338 EXPECT_EQ(child1_node->GetPlatformNode(), node_by_id);
339}
340
341} // namespace testing
342} // namespace flutter
constexpr float y() const
Definition rect_f.h:50
constexpr float width() const
Definition rect_f.h:53
constexpr float height() const
Definition rect_f.h:56
constexpr float x() const
Definition rect_f.h:47
constexpr int height() const
Definition rect.h:79
constexpr int y() const
Definition rect.h:69
constexpr int x() const
Definition rect.h:62
constexpr int width() const
Definition rect.h:76
FlutterSemanticsAction
Definition embedder.h:115
@ kFlutterSemanticsActionShowOnScreen
A request to fully show the semantics node on screen.
Definition embedder.h:140
@ kFlutterSemanticsActionDidGainAccessibilityFocus
Indicate that the node has gained accessibility focus.
Definition embedder.h:154
@ kFlutterSemanticsActionTap
Definition embedder.h:118
TEST(NativeAssetsManagerTest, NoAvailableAssets)
bool is_text_field
Whether the semantic node represents a text field.
Definition embedder.h:313
const char * identifier
Definition embedder.h:1714
const char * increased_value
Definition embedder.h:1650
const char * tooltip
A textual tooltip attached to the node.
Definition embedder.h:1677
size_t custom_accessibility_actions_count
The number of custom accessibility action associated with this node.
Definition embedder.h:1669
const int32_t * children_in_traversal_order
Array of child node IDs in traversal order. Has length child_count.
Definition embedder.h:1665
int32_t text_selection_extent
The position at which the text selection terminates.
Definition embedder.h:1625
FlutterSemanticsAction actions
The set of semantics actions applicable to this node.
Definition embedder.h:1621
int32_t id
The unique identifier for this node.
Definition embedder.h:1613
FlutterRect rect
The bounding box for this node in its coordinate system.
Definition embedder.h:1658
FlutterTransformation transform
Definition embedder.h:1661
size_t child_count
The number of children this node has.
Definition embedder.h:1663
const char * decreased_value
Definition embedder.h:1653
const char * label
A textual description of the node.
Definition embedder.h:1643
int32_t text_selection_base
The position at which the text selection originates.
Definition embedder.h:1623
const char * hint
A brief description of the result of performing an action on the node.
Definition embedder.h:1645
FlutterSemanticsFlags * flags2
Definition embedder.h:1705
const char * value
A textual description of the current value of the node.
Definition embedder.h:1647
ax::mojom::Action action