Revert "[Embedder API] Introduce new semantics update callback (#37129)"
This reverts commit 3d9f48580a5cdcc84c64c711980bdc9ef43429d1.
diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc
index 3511162..3e1f695 100644
--- a/shell/platform/embedder/embedder.cc
+++ b/shell/platform/embedder/embedder.cc
@@ -1253,182 +1253,6 @@
}
}
-// Translates engine semantic nodes to embedder semantic nodes.
-FlutterSemanticsNode CreateEmbedderSemanticsNode(
- const flutter::SemanticsNode& node) {
- SkMatrix transform = node.transform.asM33();
- FlutterTransformation flutter_transform{
- transform.get(SkMatrix::kMScaleX), transform.get(SkMatrix::kMSkewX),
- transform.get(SkMatrix::kMTransX), transform.get(SkMatrix::kMSkewY),
- transform.get(SkMatrix::kMScaleY), transform.get(SkMatrix::kMTransY),
- transform.get(SkMatrix::kMPersp0), transform.get(SkMatrix::kMPersp1),
- transform.get(SkMatrix::kMPersp2)};
- return {
- sizeof(FlutterSemanticsNode),
- node.id,
- static_cast<FlutterSemanticsFlag>(node.flags),
- static_cast<FlutterSemanticsAction>(node.actions),
- node.textSelectionBase,
- node.textSelectionExtent,
- node.scrollChildren,
- node.scrollIndex,
- node.scrollPosition,
- node.scrollExtentMax,
- node.scrollExtentMin,
- node.elevation,
- node.thickness,
- node.label.c_str(),
- node.hint.c_str(),
- node.value.c_str(),
- node.increasedValue.c_str(),
- node.decreasedValue.c_str(),
- static_cast<FlutterTextDirection>(node.textDirection),
- FlutterRect{node.rect.fLeft, node.rect.fTop, node.rect.fRight,
- node.rect.fBottom},
- flutter_transform,
- node.childrenInTraversalOrder.size(),
- node.childrenInTraversalOrder.data(),
- node.childrenInHitTestOrder.data(),
- node.customAccessibilityActions.size(),
- node.customAccessibilityActions.data(),
- node.platformViewId,
- };
-}
-
-// Translates engine semantic custom actions to embedder semantic custom
-// actions.
-FlutterSemanticsCustomAction CreateEmbedderSemanticsCustomAction(
- const flutter::CustomAccessibilityAction& action) {
- return {
- sizeof(FlutterSemanticsCustomAction),
- action.id,
- static_cast<FlutterSemanticsAction>(action.overrideId),
- action.label.c_str(),
- action.hint.c_str(),
- };
-}
-
-// Create a callback to notify the embedder of semantic updates
-// using the new embedder callback 'update_semantics_callback'.
-flutter::PlatformViewEmbedder::UpdateSemanticsCallback
-CreateNewEmbedderSemanticsUpdateCallback(
- FlutterUpdateSemanticsCallback update_semantics_callback,
- void* user_data) {
- return [update_semantics_callback, user_data](
- const flutter::SemanticsNodeUpdates& nodes,
- const flutter::CustomAccessibilityActionUpdates& actions) {
- std::vector<FlutterSemanticsNode> embedder_nodes;
- for (const auto& value : nodes) {
- embedder_nodes.push_back(CreateEmbedderSemanticsNode(value.second));
- }
-
- std::vector<FlutterSemanticsCustomAction> embedder_custom_actions;
- for (const auto& value : actions) {
- embedder_custom_actions.push_back(
- CreateEmbedderSemanticsCustomAction(value.second));
- }
-
- FlutterSemanticsUpdate update{
- .struct_size = sizeof(FlutterSemanticsUpdate),
- .nodes_count = embedder_nodes.size(),
- .nodes = embedder_nodes.data(),
- .custom_actions_count = embedder_custom_actions.size(),
- .custom_actions = embedder_custom_actions.data(),
- };
-
- update_semantics_callback(&update, user_data);
- };
-}
-
-// Create a callback to notify the embedder of semantic updates
-// using the legacy embedder callbacks 'update_semantics_node_callback' and
-// 'update_semantics_custom_action_callback'.
-flutter::PlatformViewEmbedder::UpdateSemanticsCallback
-CreateLegacyEmbedderSemanticsUpdateCallback(
- FlutterUpdateSemanticsNodeCallback update_semantics_node_callback,
- FlutterUpdateSemanticsCustomActionCallback
- update_semantics_custom_action_callback,
- void* user_data) {
- return [update_semantics_node_callback,
- update_semantics_custom_action_callback,
- user_data](const flutter::SemanticsNodeUpdates& nodes,
- const flutter::CustomAccessibilityActionUpdates& actions) {
- // First, queue all node and custom action updates.
- if (update_semantics_node_callback != nullptr) {
- for (const auto& value : nodes) {
- const FlutterSemanticsNode embedder_node =
- CreateEmbedderSemanticsNode(value.second);
- update_semantics_node_callback(&embedder_node, user_data);
- }
- }
-
- if (update_semantics_custom_action_callback != nullptr) {
- for (const auto& value : actions) {
- const FlutterSemanticsCustomAction embedder_action =
- CreateEmbedderSemanticsCustomAction(value.second);
- update_semantics_custom_action_callback(&embedder_action, user_data);
- }
- }
-
- // Second, mark node and action batches completed now that all
- // updates are queued.
- if (update_semantics_node_callback != nullptr) {
- const FlutterSemanticsNode batch_end_sentinel = {
- sizeof(FlutterSemanticsNode),
- kFlutterSemanticsNodeIdBatchEnd,
- };
- update_semantics_node_callback(&batch_end_sentinel, user_data);
- }
-
- if (update_semantics_custom_action_callback != nullptr) {
- const FlutterSemanticsCustomAction batch_end_sentinel = {
- sizeof(FlutterSemanticsCustomAction),
- kFlutterSemanticsCustomActionIdBatchEnd,
- };
- update_semantics_custom_action_callback(&batch_end_sentinel, user_data);
- }
- };
-}
-
-// Creates a callback that receives semantic updates from the engine
-// and notifies the embedder's callback(s). Returns null if the embedder
-// did not register any callbacks.
-flutter::PlatformViewEmbedder::UpdateSemanticsCallback
-CreateEmbedderSemanticsUpdateCallback(const FlutterProjectArgs* args,
- void* user_data) {
- // The embedder can register the new callback, or the legacy callbacks, or
- // nothing at all. Handle the case where the embedder registered the 'new'
- // callback.
- if (SAFE_ACCESS(args, update_semantics_callback, nullptr) != nullptr) {
- return CreateNewEmbedderSemanticsUpdateCallback(
- args->update_semantics_callback, user_data);
- }
-
- // Handle the case where the embedder registered 'legacy' callbacks.
- FlutterUpdateSemanticsNodeCallback update_semantics_node_callback = nullptr;
- if (SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr) {
- update_semantics_node_callback = args->update_semantics_node_callback;
- }
-
- FlutterUpdateSemanticsCustomActionCallback
- update_semantics_custom_action_callback = nullptr;
- if (SAFE_ACCESS(args, update_semantics_custom_action_callback, nullptr) !=
- nullptr) {
- update_semantics_custom_action_callback =
- args->update_semantics_custom_action_callback;
- }
-
- if (update_semantics_node_callback != nullptr ||
- update_semantics_custom_action_callback != nullptr) {
- return CreateLegacyEmbedderSemanticsUpdateCallback(
- update_semantics_node_callback, update_semantics_custom_action_callback,
- user_data);
- }
-
- // Handle the case where the embedder registered no callbacks.
- return nullptr;
-}
-
FlutterEngineResult FlutterEngineRun(size_t version,
const FlutterRendererConfig* config,
const FlutterProjectArgs* args,
@@ -1576,20 +1400,113 @@
settings.log_tag = SAFE_ACCESS(args, log_tag, nullptr);
}
- if (args->update_semantics_callback != nullptr &&
- (args->update_semantics_node_callback != nullptr ||
- args->update_semantics_custom_action_callback != nullptr)) {
- return LOG_EMBEDDER_ERROR(
- kInvalidArguments,
- "Multiple semantics update callbacks provided. "
- "Embedders should provide either `update_semantics_callback` "
- "or both `update_semantics_nodes_callback` and "
- "`update_semantics_custom_actions_callback`.");
+ FlutterUpdateSemanticsNodeCallback update_semantics_node_callback = nullptr;
+ if (SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr) {
+ update_semantics_node_callback = args->update_semantics_node_callback;
+ }
+
+ FlutterUpdateSemanticsCustomActionCallback
+ update_semantics_custom_action_callback = nullptr;
+ if (SAFE_ACCESS(args, update_semantics_custom_action_callback, nullptr) !=
+ nullptr) {
+ update_semantics_custom_action_callback =
+ args->update_semantics_custom_action_callback;
}
flutter::PlatformViewEmbedder::UpdateSemanticsCallback
- update_semantics_callback =
- CreateEmbedderSemanticsUpdateCallback(args, user_data);
+ update_semantics_callback = nullptr;
+ if (update_semantics_node_callback != nullptr ||
+ update_semantics_custom_action_callback != nullptr) {
+ update_semantics_callback =
+ [update_semantics_node_callback,
+ update_semantics_custom_action_callback,
+ user_data](const flutter::SemanticsNodeUpdates& update,
+ const flutter::CustomAccessibilityActionUpdates& actions) {
+ // First, queue all node and custom action updates.
+ if (update_semantics_node_callback != nullptr) {
+ for (const auto& value : update) {
+ const auto& node = value.second;
+ SkMatrix transform = node.transform.asM33();
+ FlutterTransformation flutter_transform{
+ transform.get(SkMatrix::kMScaleX),
+ transform.get(SkMatrix::kMSkewX),
+ transform.get(SkMatrix::kMTransX),
+ transform.get(SkMatrix::kMSkewY),
+ transform.get(SkMatrix::kMScaleY),
+ transform.get(SkMatrix::kMTransY),
+ transform.get(SkMatrix::kMPersp0),
+ transform.get(SkMatrix::kMPersp1),
+ transform.get(SkMatrix::kMPersp2)};
+ const FlutterSemanticsNode embedder_node{
+ sizeof(FlutterSemanticsNode),
+ node.id,
+ static_cast<FlutterSemanticsFlag>(node.flags),
+ static_cast<FlutterSemanticsAction>(node.actions),
+ node.textSelectionBase,
+ node.textSelectionExtent,
+ node.scrollChildren,
+ node.scrollIndex,
+ node.scrollPosition,
+ node.scrollExtentMax,
+ node.scrollExtentMin,
+ node.elevation,
+ node.thickness,
+ node.label.c_str(),
+ node.hint.c_str(),
+ node.value.c_str(),
+ node.increasedValue.c_str(),
+ node.decreasedValue.c_str(),
+ static_cast<FlutterTextDirection>(node.textDirection),
+ FlutterRect{node.rect.fLeft, node.rect.fTop, node.rect.fRight,
+ node.rect.fBottom},
+ flutter_transform,
+ node.childrenInTraversalOrder.size(),
+ node.childrenInTraversalOrder.data(),
+ node.childrenInHitTestOrder.data(),
+ node.customAccessibilityActions.size(),
+ node.customAccessibilityActions.data(),
+ node.platformViewId,
+ node.tooltip.c_str(),
+ };
+ update_semantics_node_callback(&embedder_node, user_data);
+ }
+ }
+
+ if (update_semantics_custom_action_callback != nullptr) {
+ for (const auto& value : actions) {
+ const auto& action = value.second;
+ const FlutterSemanticsCustomAction embedder_action = {
+ sizeof(FlutterSemanticsCustomAction),
+ action.id,
+ static_cast<FlutterSemanticsAction>(action.overrideId),
+ action.label.c_str(),
+ action.hint.c_str(),
+ };
+ update_semantics_custom_action_callback(&embedder_action,
+ user_data);
+ }
+ }
+
+ // Second, mark node and action batches completed now that all
+ // updates are queued.
+ if (update_semantics_node_callback != nullptr) {
+ const FlutterSemanticsNode batch_end_sentinel = {
+ sizeof(FlutterSemanticsNode),
+ kFlutterSemanticsNodeIdBatchEnd,
+ };
+ update_semantics_node_callback(&batch_end_sentinel, user_data);
+ }
+
+ if (update_semantics_custom_action_callback != nullptr) {
+ const FlutterSemanticsCustomAction batch_end_sentinel = {
+ sizeof(FlutterSemanticsCustomAction),
+ kFlutterSemanticsCustomActionIdBatchEnd,
+ };
+ update_semantics_custom_action_callback(&batch_end_sentinel,
+ user_data);
+ }
+ };
+ }
flutter::PlatformViewEmbedder::PlatformMessageResponseCallback
platform_message_response_callback = nullptr;
diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h
index 7bef2e5..c9e7bc2 100644
--- a/shell/platform/embedder/embedder.h
+++ b/shell/platform/embedder/embedder.h
@@ -1031,8 +1031,7 @@
typedef int64_t FlutterPlatformViewIdentifier;
/// `FlutterSemanticsNode` ID used as a sentinel to signal the end of a batch of
-/// semantics node updates. This is unused if using
-/// `FlutterUpdateSemanticsCallback`.
+/// semantics node updates.
FLUTTER_EXPORT
extern const int32_t kFlutterSemanticsNodeIdBatchEnd;
@@ -1041,7 +1040,7 @@
/// The semantics tree is maintained during the semantics phase of the pipeline
/// (i.e., during PipelineOwner.flushSemantics), which happens after
/// compositing. Updates are then pushed to embedders via the registered
-/// `FlutterUpdateSemanticsCallback`.
+/// `FlutterUpdateSemanticsNodeCallback`.
typedef struct {
/// The size of this struct. Must be sizeof(FlutterSemanticsNode).
size_t struct_size;
@@ -1110,8 +1109,7 @@
} FlutterSemanticsNode;
/// `FlutterSemanticsCustomAction` ID used as a sentinel to signal the end of a
-/// batch of semantics custom action updates. This is unused if using
-/// `FlutterUpdateSemanticsCallback`.
+/// batch of semantics custom action updates.
FLUTTER_EXPORT
extern const int32_t kFlutterSemanticsCustomActionIdBatchEnd;
@@ -1138,20 +1136,6 @@
const char* hint;
} FlutterSemanticsCustomAction;
-/// A batch of updates to semantics nodes and custom actions.
-typedef struct {
- /// The size of the struct. Must be sizeof(FlutterSemanticsUpdate).
- size_t struct_size;
- /// The number of semantics node updates.
- size_t nodes_count;
- // Array of semantics nodes. Has length `nodes_count`.
- FlutterSemanticsNode* nodes;
- /// The number of semantics custom action updates.
- size_t custom_actions_count;
- /// Array of semantics custom actions. Has length `custom_actions_count`.
- FlutterSemanticsCustomAction* custom_actions;
-} FlutterSemanticsUpdate;
-
typedef void (*FlutterUpdateSemanticsNodeCallback)(
const FlutterSemanticsNode* /* semantics node */,
void* /* user data */);
@@ -1160,10 +1144,6 @@
const FlutterSemanticsCustomAction* /* semantics custom action */,
void* /* user data */);
-typedef void (*FlutterUpdateSemanticsCallback)(
- const FlutterSemanticsUpdate* /* semantics update */,
- void* /* user data*/);
-
typedef struct _FlutterTaskRunner* FlutterTaskRunner;
typedef struct {
@@ -1759,32 +1739,24 @@
/// The callback invoked by the engine in root isolate scope. Called
/// immediately after the root isolate has been created and marked runnable.
VoidCallback root_isolate_create_callback;
- /// The legacy callback invoked by the engine in order to give the embedder
- /// the chance to respond to semantics node updates from the Dart application.
+ /// The callback invoked by the engine in order to give the embedder the
+ /// chance to respond to semantics node updates from the Dart application.
/// Semantics node updates are sent in batches terminated by a 'batch end'
/// callback that is passed a sentinel `FlutterSemanticsNode` whose `id` field
/// has the value `kFlutterSemanticsNodeIdBatchEnd`.
///
/// The callback will be invoked on the thread on which the `FlutterEngineRun`
/// call is made.
- ///
- /// @deprecated Prefer using `update_semantics_callback` instead. If this
- /// calback is provided, `update_semantics_callback` must not
- /// be provided.
FlutterUpdateSemanticsNodeCallback update_semantics_node_callback;
- /// The legacy callback invoked by the engine in order to give the embedder
- /// the chance to respond to updates to semantics custom actions from the Dart
- /// application. Custom action updates are sent in batches terminated by a
+ /// The callback invoked by the engine in order to give the embedder the
+ /// chance to respond to updates to semantics custom actions from the Dart
+ /// application. Custom action updates are sent in batches terminated by a
/// 'batch end' callback that is passed a sentinel
/// `FlutterSemanticsCustomAction` whose `id` field has the value
/// `kFlutterSemanticsCustomActionIdBatchEnd`.
///
/// The callback will be invoked on the thread on which the `FlutterEngineRun`
/// call is made.
- ///
- /// @deprecated Prefer using `update_semantics_callback` instead. If this
- /// calback is provided, `update_semantics_callback` must not
- /// be provided.
FlutterUpdateSemanticsCustomActionCallback
update_semantics_custom_action_callback;
/// Path to a directory used to store data that is cached across runs of a
@@ -1921,17 +1893,6 @@
//
// The first argument is the `user_data` from `FlutterEngineInitialize`.
OnPreEngineRestartCallback on_pre_engine_restart_callback;
-
- /// The callback invoked by the engine in order to give the embedder the
- /// chance to respond to updates to semantics nodes and custom actions from
- /// the Dart application.
- ///
- /// The callback will be invoked on the thread on which the `FlutterEngineRun`
- /// call is made.
- ///
- /// If this callback is provided, update_semantics_node_callback and
- /// update_semantics_custom_action_callback must not be provided.
- FlutterUpdateSemanticsCallback update_semantics_callback;
} FlutterProjectArgs;
#ifndef FLUTTER_ENGINE_NO_PROTOTYPES
@@ -2273,8 +2234,8 @@
/// @param[in] engine A running engine instance.
/// @param[in] enabled When enabled, changes to the semantic contents of the
/// window are sent via the
-/// `FlutterUpdateSemanticsCallback` registered to
-/// `update_semantics_callback` in
+/// `FlutterUpdateSemanticsNodeCallback` registered to
+/// `update_semantics_node_callback` in
/// `FlutterProjectArgs`.
///
/// @return The result of the call.
diff --git a/shell/platform/embedder/tests/embedder_a11y_unittests.cc b/shell/platform/embedder/tests/embedder_a11y_unittests.cc
index 21db35a..87f0c8f 100644
--- a/shell/platform/embedder/tests/embedder_a11y_unittests.cc
+++ b/shell/platform/embedder/tests/embedder_a11y_unittests.cc
@@ -24,21 +24,6 @@
using EmbedderA11yTest = testing::EmbedderTest;
-TEST_F(EmbedderTest, CannotProvideNewAndLegacySemanticsCallback) {
- EmbedderConfigBuilder builder(
- GetEmbedderContext(EmbedderTestContextType::kSoftwareContext));
- builder.SetSoftwareRendererConfig();
- builder.GetProjectArgs().update_semantics_callback =
- [](const FlutterSemanticsUpdate* update, void* user_data) {};
- builder.GetProjectArgs().update_semantics_node_callback =
- [](const FlutterSemanticsNode* update, void* user_data) {};
- builder.GetProjectArgs().update_semantics_custom_action_callback =
- [](const FlutterSemanticsCustomAction* update, void* user_data) {};
- auto engine = builder.InitializeEngine();
- ASSERT_FALSE(engine.is_valid());
- engine.reset();
-}
-
TEST_F(EmbedderA11yTest, A11yTreeIsConsistent) {
#if defined(OS_FUCHSIA)
GTEST_SKIP() << "This test crashes on Fuchsia. https://fxbug.dev/87493 ";
@@ -83,35 +68,6 @@
notify_semantics_action_callback(args);
})));
- fml::AutoResetWaitableEvent semantics_update_latch;
- context.SetSemanticsUpdateCallback([&](const FlutterSemanticsUpdate* update) {
- ASSERT_EQ(size_t(4), update->nodes_count);
- ASSERT_EQ(size_t(1), update->custom_actions_count);
-
- for (size_t i = 0; i < update->nodes_count; i++) {
- const FlutterSemanticsNode* node = update->nodes + i;
-
- ASSERT_EQ(1.0, node->transform.scaleX);
- ASSERT_EQ(2.0, node->transform.skewX);
- ASSERT_EQ(3.0, node->transform.transX);
- ASSERT_EQ(4.0, node->transform.skewY);
- ASSERT_EQ(5.0, node->transform.scaleY);
- ASSERT_EQ(6.0, node->transform.transY);
- ASSERT_EQ(7.0, node->transform.pers0);
- ASSERT_EQ(8.0, node->transform.pers1);
- ASSERT_EQ(9.0, node->transform.pers2);
-
- if (node->id == 128) {
- ASSERT_EQ(0x3f3, node->platform_view_id);
- } else {
- ASSERT_NE(kFlutterSemanticsNodeIdBatchEnd, node->id);
- ASSERT_EQ(0, node->platform_view_id);
- }
- }
-
- semantics_update_latch.Signal();
- });
-
EmbedderConfigBuilder builder(context);
builder.SetSoftwareRendererConfig();
builder.SetDartEntrypoint("a11y_main");
@@ -168,93 +124,6 @@
latch.Wait();
// Wait for UpdateSemantics callback on platform (current) thread.
- latch.Wait();
- fml::MessageLoop::GetCurrent().RunExpiredTasksNow();
- semantics_update_latch.Wait();
-
- // Dispatch a tap to semantics node 42. Wait for NotifySemanticsAction.
- notify_semantics_action_callback = [&](Dart_NativeArguments args) {
- int64_t node_id = 0;
- Dart_GetNativeIntegerArgument(args, 0, &node_id);
- ASSERT_EQ(42, node_id);
-
- int64_t action_id;
- auto handle = Dart_GetNativeIntegerArgument(args, 1, &action_id);
- ASSERT_FALSE(Dart_IsError(handle));
- ASSERT_EQ(static_cast<int32_t>(flutter::SemanticsAction::kTap), action_id);
-
- Dart_Handle semantic_args = Dart_GetNativeArgument(args, 2);
- int64_t data;
- Dart_Handle dart_int = Dart_ListGetAt(semantic_args, 0);
- Dart_IntegerToInt64(dart_int, &data);
- ASSERT_EQ(2, data);
-
- dart_int = Dart_ListGetAt(semantic_args, 1);
- Dart_IntegerToInt64(dart_int, &data);
- ASSERT_EQ(1, data);
- latch.Signal();
- };
- std::vector<uint8_t> bytes({2, 1});
- result = FlutterEngineDispatchSemanticsAction(
- engine.get(), 42, kFlutterSemanticsActionTap, &bytes[0], bytes.size());
- ASSERT_EQ(result, FlutterEngineResult::kSuccess);
- latch.Wait();
-
- // Disable semantics. Wait for NotifySemanticsEnabled(false).
- notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
- bool enabled = true;
- Dart_GetNativeBooleanArgument(args, 0, &enabled);
- ASSERT_FALSE(enabled);
- latch.Signal();
- };
- result = FlutterEngineUpdateSemanticsEnabled(engine.get(), false);
- ASSERT_EQ(result, FlutterEngineResult::kSuccess);
- latch.Wait();
-}
-
-TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingLegacyCallbacks) {
- auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext);
-
- fml::AutoResetWaitableEvent latch;
-
- // Called by the Dart text fixture on the UI thread to signal that the C++
- // unittest should resume.
- context.AddNativeCallback(
- "SignalNativeTest", CREATE_NATIVE_ENTRY(([&latch](Dart_NativeArguments) {
- latch.Signal();
- })));
-
- // Called by test fixture on UI thread to pass data back to this test.
- NativeEntry notify_semantics_enabled_callback;
- context.AddNativeCallback(
- "NotifySemanticsEnabled",
- CREATE_NATIVE_ENTRY(
- ([¬ify_semantics_enabled_callback](Dart_NativeArguments args) {
- ASSERT_NE(notify_semantics_enabled_callback, nullptr);
- notify_semantics_enabled_callback(args);
- })));
-
- NativeEntry notify_accessibility_features_callback;
- context.AddNativeCallback(
- "NotifyAccessibilityFeatures",
- CREATE_NATIVE_ENTRY((
- [¬ify_accessibility_features_callback](Dart_NativeArguments args) {
- ASSERT_NE(notify_accessibility_features_callback, nullptr);
- notify_accessibility_features_callback(args);
- })));
-
- NativeEntry notify_semantics_action_callback;
- context.AddNativeCallback(
- "NotifySemanticsAction",
- CREATE_NATIVE_ENTRY(
- ([¬ify_semantics_action_callback](Dart_NativeArguments args) {
- ASSERT_NE(notify_semantics_action_callback, nullptr);
- notify_semantics_action_callback(args);
- })));
-
- fml::AutoResetWaitableEvent semantics_node_latch;
- fml::AutoResetWaitableEvent semantics_action_latch;
-
int node_batch_end_count = 0;
int action_batch_end_count = 0;
@@ -262,7 +131,6 @@
context.SetSemanticsNodeCallback([&](const FlutterSemanticsNode* node) {
if (node->id == kFlutterSemanticsNodeIdBatchEnd) {
++node_batch_end_count;
- semantics_node_latch.Signal();
} else {
// Batches should be completed after all nodes are received.
ASSERT_EQ(0, node_batch_end_count);
@@ -292,7 +160,6 @@
[&](const FlutterSemanticsCustomAction* action) {
if (action->id == kFlutterSemanticsCustomActionIdBatchEnd) {
++action_batch_end_count;
- semantics_action_latch.Signal();
} else {
// Batches should be completed after all actions are received.
ASSERT_EQ(0, node_batch_end_count);
@@ -302,66 +169,8 @@
}
});
- EmbedderConfigBuilder builder(context);
- builder.SetSoftwareRendererConfig();
- builder.SetDartEntrypoint("a11y_main");
-
- auto engine = builder.LaunchEngine();
- ASSERT_TRUE(engine.is_valid());
-
- // Wait for initial NotifySemanticsEnabled(false).
- notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
- bool enabled = true;
- auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
- ASSERT_FALSE(Dart_IsError(handle));
- ASSERT_FALSE(enabled);
- latch.Signal();
- };
- latch.Wait();
-
- // Prepare to NotifyAccessibilityFeatures call
- fml::AutoResetWaitableEvent notify_features_latch;
- notify_accessibility_features_callback = [&](Dart_NativeArguments args) {
- bool enabled = true;
- auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
- ASSERT_FALSE(Dart_IsError(handle));
- ASSERT_FALSE(enabled);
- notify_features_latch.Signal();
- };
-
- // Enable semantics. Wait for NotifySemanticsEnabled(true).
- notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
- bool enabled = false;
- auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
- ASSERT_FALSE(Dart_IsError(handle));
- ASSERT_TRUE(enabled);
- latch.Signal();
- };
- auto result = FlutterEngineUpdateSemanticsEnabled(engine.get(), true);
- ASSERT_EQ(result, FlutterEngineResult::kSuccess);
- latch.Wait();
-
- // Wait for initial accessibility features (reduce_motion == false)
- notify_features_latch.Wait();
-
- // Set accessibility features: (reduce_motion == true)
- notify_accessibility_features_callback = [&](Dart_NativeArguments args) {
- bool enabled = false;
- auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
- ASSERT_FALSE(Dart_IsError(handle));
- ASSERT_TRUE(enabled);
- latch.Signal();
- };
- result = FlutterEngineUpdateAccessibilityFeatures(
- engine.get(), kFlutterAccessibilityFeatureReduceMotion);
- ASSERT_EQ(result, FlutterEngineResult::kSuccess);
- latch.Wait();
-
- // Wait for UpdateSemantics callback on platform (current) thread.
latch.Wait();
fml::MessageLoop::GetCurrent().RunExpiredTasksNow();
- semantics_node_latch.Wait();
- semantics_action_latch.Wait();
ASSERT_EQ(4, node_count);
ASSERT_EQ(1, node_batch_end_count);
ASSERT_EQ(1, action_count);
diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc
index d61b5ff..92ff07a 100644
--- a/shell/platform/embedder/tests/embedder_config_builder.cc
+++ b/shell/platform/embedder/tests/embedder_config_builder.cc
@@ -247,12 +247,10 @@
}
void EmbedderConfigBuilder::SetSemanticsCallbackHooks() {
- project_args_.update_semantics_callback =
- context_.GetUpdateSemanticsCallbackHook();
project_args_.update_semantics_node_callback =
- context_.GetUpdateSemanticsNodeCallbackHook();
+ EmbedderTestContext::GetUpdateSemanticsNodeCallbackHook();
project_args_.update_semantics_custom_action_callback =
- context_.GetUpdateSemanticsCustomActionCallbackHook();
+ EmbedderTestContext::GetUpdateSemanticsCustomActionCallbackHook();
}
void EmbedderConfigBuilder::SetLogMessageCallbackHook() {
diff --git a/shell/platform/embedder/tests/embedder_test_context.cc b/shell/platform/embedder/tests/embedder_test_context.cc
index 904eed9..261eb0f 100644
--- a/shell/platform/embedder/tests/embedder_test_context.cc
+++ b/shell/platform/embedder/tests/embedder_test_context.cc
@@ -121,11 +121,6 @@
native_resolver_->AddNativeCallback({name}, function);
}
-void EmbedderTestContext::SetSemanticsUpdateCallback(
- SemanticsUpdateCallback update_semantics_callback) {
- update_semantics_callback_ = std::move(update_semantics_callback);
-}
-
void EmbedderTestContext::SetSemanticsNodeCallback(
SemanticsNodeCallback update_semantics_node_callback) {
update_semantics_node_callback_ = std::move(update_semantics_node_callback);
@@ -154,44 +149,22 @@
log_message_callback_ = callback;
}
-FlutterUpdateSemanticsCallback
-EmbedderTestContext::GetUpdateSemanticsCallbackHook() {
- if (update_semantics_callback_ == nullptr) {
- return nullptr;
- }
-
- return [](const FlutterSemanticsUpdate* update, void* user_data) {
- auto context = reinterpret_cast<EmbedderTestContext*>(user_data);
- if (context->update_semantics_callback_) {
- context->update_semantics_callback_(update);
- }
- };
-}
-
FlutterUpdateSemanticsNodeCallback
EmbedderTestContext::GetUpdateSemanticsNodeCallbackHook() {
- if (update_semantics_node_callback_ == nullptr) {
- return nullptr;
- }
-
return [](const FlutterSemanticsNode* semantics_node, void* user_data) {
auto context = reinterpret_cast<EmbedderTestContext*>(user_data);
- if (context->update_semantics_node_callback_) {
- context->update_semantics_node_callback_(semantics_node);
+ if (auto callback = context->update_semantics_node_callback_) {
+ callback(semantics_node);
}
};
}
FlutterUpdateSemanticsCustomActionCallback
EmbedderTestContext::GetUpdateSemanticsCustomActionCallbackHook() {
- if (update_semantics_custom_action_callback_ == nullptr) {
- return nullptr;
- }
-
return [](const FlutterSemanticsCustomAction* action, void* user_data) {
auto context = reinterpret_cast<EmbedderTestContext*>(user_data);
- if (context->update_semantics_custom_action_callback_) {
- context->update_semantics_custom_action_callback_(action);
+ if (auto callback = context->update_semantics_custom_action_callback_) {
+ callback(action);
}
};
}
@@ -199,8 +172,8 @@
FlutterLogMessageCallback EmbedderTestContext::GetLogMessageCallbackHook() {
return [](const char* tag, const char* message, void* user_data) {
auto context = reinterpret_cast<EmbedderTestContext*>(user_data);
- if (context->log_message_callback_) {
- context->log_message_callback_(tag, message);
+ if (auto callback = context->log_message_callback_) {
+ callback(tag, message);
}
};
}
diff --git a/shell/platform/embedder/tests/embedder_test_context.h b/shell/platform/embedder/tests/embedder_test_context.h
index 53c1174..8577abb 100644
--- a/shell/platform/embedder/tests/embedder_test_context.h
+++ b/shell/platform/embedder/tests/embedder_test_context.h
@@ -24,8 +24,6 @@
namespace flutter {
namespace testing {
-using SemanticsUpdateCallback =
- std::function<void(const FlutterSemanticsUpdate*)>;
using SemanticsNodeCallback = std::function<void(const FlutterSemanticsNode*)>;
using SemanticsActionCallback =
std::function<void(const FlutterSemanticsCustomAction*)>;
@@ -71,8 +69,6 @@
void AddIsolateCreateCallback(const fml::closure& closure);
- void SetSemanticsUpdateCallback(SemanticsUpdateCallback update_semantics);
-
void AddNativeCallback(const char* name, Dart_NativeFunction function);
void SetSemanticsNodeCallback(SemanticsNodeCallback update_semantics_node);
@@ -124,7 +120,6 @@
UniqueAOTData aot_data_;
std::vector<fml::closure> isolate_create_callbacks_;
std::shared_ptr<TestDartNativeResolver> native_resolver_;
- SemanticsUpdateCallback update_semantics_callback_;
SemanticsNodeCallback update_semantics_node_callback_;
SemanticsActionCallback update_semantics_custom_action_callback_;
std::function<void(const FlutterPlatformMessage*)> platform_message_callback_;
@@ -136,11 +131,10 @@
static VoidCallback GetIsolateCreateCallbackHook();
- FlutterUpdateSemanticsCallback GetUpdateSemanticsCallbackHook();
+ static FlutterUpdateSemanticsNodeCallback
+ GetUpdateSemanticsNodeCallbackHook();
- FlutterUpdateSemanticsNodeCallback GetUpdateSemanticsNodeCallbackHook();
-
- FlutterUpdateSemanticsCustomActionCallback
+ static FlutterUpdateSemanticsCustomActionCallback
GetUpdateSemanticsCustomActionCallbackHook();
static FlutterLogMessageCallback GetLogMessageCallbackHook();
diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc
index 1cd2fc4..9ecdcab 100644
--- a/shell/platform/windows/flutter_windows_engine.cc
+++ b/shell/platform/windows/flutter_windows_engine.cc
@@ -321,23 +321,25 @@
auto host = static_cast<FlutterWindowsEngine*>(user_data);
host->view()->OnPreEngineRestart();
};
- args.update_semantics_callback = [](const FlutterSemanticsUpdate* update,
- void* user_data) {
+ args.update_semantics_node_callback = [](const FlutterSemanticsNode* node,
+ void* user_data) {
auto host = static_cast<FlutterWindowsEngine*>(user_data);
-
- for (size_t i = 0; i < update->nodes_count; i++) {
- const FlutterSemanticsNode* node = &update->nodes[i];
- host->accessibility_bridge_->AddFlutterSemanticsNodeUpdate(node);
+ if (!node || node->id == kFlutterSemanticsNodeIdBatchEnd) {
+ host->accessibility_bridge_->CommitUpdates();
+ return;
}
-
- for (size_t i = 0; i < update->custom_actions_count; i++) {
- const FlutterSemanticsCustomAction* action = &update->custom_actions[i];
- host->accessibility_bridge_->AddFlutterSemanticsCustomActionUpdate(
- action);
- }
-
- host->accessibility_bridge_->CommitUpdates();
+ host->accessibility_bridge_->AddFlutterSemanticsNodeUpdate(node);
};
+ args.update_semantics_custom_action_callback =
+ [](const FlutterSemanticsCustomAction* action, void* user_data) {
+ auto host = static_cast<FlutterWindowsEngine*>(user_data);
+ if (!action || action->id == kFlutterSemanticsNodeIdBatchEnd) {
+ host->accessibility_bridge_->CommitUpdates();
+ return;
+ }
+ host->accessibility_bridge_->AddFlutterSemanticsCustomActionUpdate(
+ action);
+ };
args.root_isolate_create_callback = [](void* user_data) {
auto host = static_cast<FlutterWindowsEngine*>(user_data);
if (host->root_isolate_create_callback_) {
diff --git a/shell/platform/windows/flutter_windows_engine_unittests.cc b/shell/platform/windows/flutter_windows_engine_unittests.cc
index 9714bd8..b0d63aa 100644
--- a/shell/platform/windows/flutter_windows_engine_unittests.cc
+++ b/shell/platform/windows/flutter_windows_engine_unittests.cc
@@ -77,9 +77,6 @@
EXPECT_NE(args->custom_task_runners->thread_priority_setter, nullptr);
EXPECT_EQ(args->custom_dart_entrypoint, nullptr);
EXPECT_NE(args->vsync_callback, nullptr);
- EXPECT_NE(args->update_semantics_callback, nullptr);
- EXPECT_EQ(args->update_semantics_node_callback, nullptr);
- EXPECT_EQ(args->update_semantics_custom_action_callback, nullptr);
args->custom_task_runners->thread_priority_setter(
FlutterThreadPriority::kRaster);