Flutter Engine
embedder_a11y_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 
5 // Allow access to fml::MessageLoop::GetCurrent() in order to flush platform
6 // thread tasks.
7 #define FML_USED_ON_EMBEDDER
8 
9 #include <functional>
10 
11 #include "flutter/fml/macros.h"
12 #include "flutter/fml/message_loop.h"
13 #include "flutter/fml/synchronization/waitable_event.h"
14 #include "flutter/lib/ui/semantics/semantics_node.h"
15 #include "flutter/shell/platform/embedder/embedder.h"
16 #include "flutter/shell/platform/embedder/tests/embedder_config_builder.h"
17 #include "flutter/testing/testing.h"
18 
19 namespace flutter {
20 namespace testing {
21 
23 
24 // TODO(52372): De-flake and re-enable.
25 TEST_F(Embedder11yTest, DISABLED_A11yTreeIsConsistent) {
26  auto& context = GetEmbedderContext(ContextType::kOpenGLContext);
27 
29 
30  // Called by the Dart text fixture on the UI thread to signal that the C++
31  // unittest should resume.
32  context.AddNativeCallback(
33  "SignalNativeTest", CREATE_NATIVE_ENTRY(([&latch](Dart_NativeArguments) {
34  latch.Signal();
35  })));
36 
37  // Called by test fixture on UI thread to pass data back to this test.
38  NativeEntry notify_semantics_enabled_callback;
39  context.AddNativeCallback(
40  "NotifySemanticsEnabled",
42  ([&notify_semantics_enabled_callback](Dart_NativeArguments args) {
43  ASSERT_NE(notify_semantics_enabled_callback, nullptr);
44  notify_semantics_enabled_callback(args);
45  })));
46 
47  NativeEntry notify_accessibility_features_callback;
48  context.AddNativeCallback(
49  "NotifyAccessibilityFeatures",
51  [&notify_accessibility_features_callback](Dart_NativeArguments args) {
52  ASSERT_NE(notify_accessibility_features_callback, nullptr);
53  notify_accessibility_features_callback(args);
54  })));
55 
56  NativeEntry notify_semantics_action_callback;
57  context.AddNativeCallback(
58  "NotifySemanticsAction",
60  ([&notify_semantics_action_callback](Dart_NativeArguments args) {
61  ASSERT_NE(notify_semantics_action_callback, nullptr);
62  notify_semantics_action_callback(args);
63  })));
64 
65  EmbedderConfigBuilder builder(context);
66  builder.SetSoftwareRendererConfig();
67  builder.SetDartEntrypoint("a11y_main");
68 
69  auto engine = builder.LaunchEngine();
70  ASSERT_TRUE(engine.is_valid());
71 
72  // Wait for initial NotifySemanticsEnabled(false).
73  notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
74  bool enabled = true;
75  auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
76  ASSERT_FALSE(Dart_IsError(handle));
77  ASSERT_FALSE(enabled);
78  latch.Signal();
79  };
80  latch.Wait();
81 
82  // Prepare to NotifyAccessibilityFeatures call
83  fml::AutoResetWaitableEvent notify_features_latch;
84  notify_accessibility_features_callback = [&](Dart_NativeArguments args) {
85  bool enabled = true;
86  auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
87  ASSERT_FALSE(Dart_IsError(handle));
88  ASSERT_FALSE(enabled);
89  notify_features_latch.Signal();
90  };
91 
92  // Enable semantics. Wait for NotifySemanticsEnabled(true).
93  notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
94  bool enabled = false;
95  auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
96  ASSERT_FALSE(Dart_IsError(handle));
97  ASSERT_TRUE(enabled);
98  latch.Signal();
99  };
100  auto result = FlutterEngineUpdateSemanticsEnabled(engine.get(), true);
101  ASSERT_EQ(result, FlutterEngineResult::kSuccess);
102  latch.Wait();
103 
104  // Wait for initial accessibility features (reduce_motion == false)
105  notify_features_latch.Wait();
106 
107  // Set accessibility features: (reduce_motion == true)
108  notify_accessibility_features_callback = [&](Dart_NativeArguments args) {
109  bool enabled = false;
110  auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
111  ASSERT_FALSE(Dart_IsError(handle));
112  ASSERT_TRUE(enabled);
113  latch.Signal();
114  };
117  ASSERT_EQ(result, FlutterEngineResult::kSuccess);
118  latch.Wait();
119 
120  // Wait for UpdateSemantics callback on platform (current) thread.
121  int node_count = 0;
122  int node_batch_end_count = 0;
123  context.SetSemanticsNodeCallback(
124  [&node_count, &node_batch_end_count](const FlutterSemanticsNode* node) {
125  if (node->id == kFlutterSemanticsNodeIdBatchEnd) {
126  ++node_batch_end_count;
127  } else {
128  ++node_count;
129  ASSERT_EQ(1.0, node->transform.scaleX);
130  ASSERT_EQ(2.0, node->transform.skewX);
131  ASSERT_EQ(3.0, node->transform.transX);
132  ASSERT_EQ(4.0, node->transform.skewY);
133  ASSERT_EQ(5.0, node->transform.scaleY);
134  ASSERT_EQ(6.0, node->transform.transY);
135  ASSERT_EQ(7.0, node->transform.pers0);
136  ASSERT_EQ(8.0, node->transform.pers1);
137  ASSERT_EQ(9.0, node->transform.pers2);
138 
139  if (node->id == 128) {
140  ASSERT_EQ(0x3f3, node->platform_view_id);
141  } else {
142  ASSERT_EQ(0, node->platform_view_id);
143  }
144  }
145  });
146 
147  int action_count = 0;
148  int action_batch_end_count = 0;
149  context.SetSemanticsCustomActionCallback(
150  [&action_count,
151  &action_batch_end_count](const FlutterSemanticsCustomAction* action) {
153  ++action_batch_end_count;
154  } else {
155  ++action_count;
156  }
157  });
158 
159  latch.Wait();
161  ASSERT_EQ(4, node_count);
162  ASSERT_EQ(1, node_batch_end_count);
163  ASSERT_EQ(1, action_count);
164  ASSERT_EQ(1, action_batch_end_count);
165 
166  // Dispatch a tap to semantics node 42. Wait for NotifySemanticsAction.
167  notify_semantics_action_callback = [&](Dart_NativeArguments args) {
168  int64_t node_id = 0;
169  Dart_GetNativeIntegerArgument(args, 0, &node_id);
170  ASSERT_EQ(42, node_id);
171 
172  int64_t action_id;
173  auto handle = Dart_GetNativeIntegerArgument(args, 1, &action_id);
174  ASSERT_FALSE(Dart_IsError(handle));
175  ASSERT_EQ(static_cast<int32_t>(flutter::SemanticsAction::kTap), action_id);
176 
177  Dart_Handle semantic_args = Dart_GetNativeArgument(args, 2);
178  int64_t data;
179  Dart_Handle dart_int = Dart_ListGetAt(semantic_args, 0);
180  Dart_IntegerToInt64(dart_int, &data);
181  ASSERT_EQ(2, data);
182 
183  dart_int = Dart_ListGetAt(semantic_args, 1);
184  Dart_IntegerToInt64(dart_int, &data);
185  ASSERT_EQ(1, data);
186  latch.Signal();
187  };
188  std::vector<uint8_t> bytes({2, 1});
190  engine.get(), 42, kFlutterSemanticsActionTap, &bytes[0], bytes.size());
191  latch.Wait();
192 
193  // Disable semantics. Wait for NotifySemanticsEnabled(false).
194  notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
195  bool enabled = true;
196  Dart_GetNativeBooleanArgument(args, 0, &enabled);
197  ASSERT_FALSE(enabled);
198  latch.Signal();
199  };
200  result = FlutterEngineUpdateSemanticsEnabled(engine.get(), false);
201  ASSERT_EQ(result, FlutterEngineResult::kSuccess);
202  latch.Wait();
203 }
204 
205 } // namespace testing
206 } // namespace flutter
G_BEGIN_DECLS FlValue * args
int32_t id
The unique custom action or action override ID.
Definition: embedder.h:686
FlutterEngineResult FlutterEngineDispatchSemanticsAction(FLUTTER_API_SYMBOL(FlutterEngine) engine, uint64_t id, FlutterSemanticsAction action, const uint8_t *data, size_t data_length)
Dispatch a semantics action to the specified semantics node.
Definition: embedder.cc:1615
FlutterEngineResult FlutterEngineUpdateAccessibilityFeatures(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterAccessibilityFeature flags)
Sets additional accessibility features.
Definition: embedder.cc:1601
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19
FlutterEngineResult FlutterEngineUpdateSemanticsEnabled(FLUTTER_API_SYMBOL(FlutterEngine) engine, bool enabled)
Enable or disable accessibility semantics.
Definition: embedder.cc:1587
#define CREATE_NATIVE_ENTRY(native_entry)
std::function< void(Dart_NativeArguments)> NativeEntry
SemanticsAction action
int32_t id
The unique identifier for this node.
Definition: embedder.h:607
testing::EmbedderTest EmbedderTest
TEST_F(BackdropFilterLayerTest, PaintingEmptyLayerDies)
void RunExpiredTasksNow()
Definition: message_loop.cc:72
const int32_t kFlutterSemanticsNodeIdBatchEnd
Definition: embedder.cc:64
Request that certain animations be simplified and parallax effects.
Definition: embedder.h:91
const int32_t kFlutterSemanticsCustomActionIdBatchEnd
Definition: embedder.cc:65
void SetSoftwareRendererConfig(SkISize surface_size=SkISize::Make(1, 1))