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(
-          ([&notify_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((
-          [&notify_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(
-          ([&notify_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);