[flutter][a11y]Wire up ViewRef and initialize SemanticsManager

A subsequent CL will introduce the AccessibilityManager,
which will consume the FuchsiaAccessibility object. This
object exists to make Flutter's AccessibiltyManager more
testable.

Eventually, the ViewRef will have to be cloned to the GPU
thread and passed to Scenic as well, but that API is still
WIP from what I understand.

MI4-2490 # Track where view_ref and view_ref_control come from

Change-Id: I9be51c3de73f689a80039f0fa1cac57892cc6810
diff --git a/runtime/flutter_runner/BUILD.gn b/runtime/flutter_runner/BUILD.gn
index 2a39471..51a94d1 100644
--- a/runtime/flutter_runner/BUILD.gn
+++ b/runtime/flutter_runner/BUILD.gn
@@ -70,6 +70,8 @@
       "context_writer_bridge.h",
       "engine.cc",
       "engine.h",
+      "fuchsia_accessibility.cc",
+      "fuchsia_accessibility.h",
       "fuchsia_font_manager.cc",
       "fuchsia_font_manager.h",
       "isolate_configurator.cc",
@@ -435,6 +437,9 @@
   output_name = "flutter_runner_tests"
 
   sources = [
+    "fuchsia_accessibility.cc",
+    "fuchsia_accessibility.h",
+    "fuchsia_accessibility_unittest.cc",
     "fuchsia_font_manager.cc",
     "fuchsia_font_manager.h",
     "fuchsia_font_manager_unittest.cc",
@@ -443,9 +448,11 @@
 
   deps = [
     "//garnet/public/lib/gtest",
+    "//sdk/fidl/fuchsia.accessibility",
     "//sdk/fidl/fuchsia.fonts",
     "//sdk/fidl/fuchsia.sys",
     "//sdk/lib/sys/cpp",
+    "//sdk/lib/sys/cpp/testing:unit",
     "//third_party/googletest:gtest_main",
     "//third_party/icu",
     "//third_party/skia",
diff --git a/runtime/flutter_runner/component.cc b/runtime/flutter_runner/component.cc
index f4dafac..05582ea 100644
--- a/runtime/flutter_runner/component.cc
+++ b/runtime/flutter_runner/component.cc
@@ -496,15 +496,28 @@
            "create a shell for a view provider request.";
     return;
   }
+  // TODO(MI4-2490): remove once ViewRefControl and ViewRef come as a parameters
+  // to CreateView
+  fuchsia::ui::views::ViewRefControl view_ref_control;
+  fuchsia::ui::views::ViewRef view_ref;
+  zx_status_t status = zx::eventpair::create(
+      /*flags*/ 0u, &view_ref_control.reference, &view_ref.reference);
+  FML_DCHECK(status == ZX_OK);
+
+  status = view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
+  FML_DCHECK(status == ZX_OK);
 
   shell_holders_.emplace(std::make_unique<Engine>(
       *this,                         // delegate
       debug_label_,                  // thread label
       svc_,                          // Component incoming services
+      runner_incoming_services_,     // Runner incoming services
       settings_,                     // settings
       std::move(isolate_snapshot_),  // isolate snapshot
       std::move(shared_snapshot_),   // shared snapshot
       scenic::ToViewToken(std::move(view_token)),  // view token
+      std::move(view_ref_control),                 // view ref control
+      std::move(view_ref),                         // view ref
       std::move(fdio_ns_),                         // FDIO namespace
       std::move(directory_request_)                // outgoing request
       ));
diff --git a/runtime/flutter_runner/engine.cc b/runtime/flutter_runner/engine.cc
index f238cb8..9cf1435 100644
--- a/runtime/flutter_runner/engine.cc
+++ b/runtime/flutter_runner/engine.cc
@@ -5,6 +5,7 @@
 #include "engine.h"
 
 #include <lib/async/cpp/task.h>
+
 #include <sstream>
 
 #include "flutter/common/task_runners.h"
@@ -13,13 +14,12 @@
 #include "flutter/fml/task_runner.h"
 #include "flutter/shell/common/rasterizer.h"
 #include "flutter/shell/common/run_configuration.h"
-#include "third_party/flutter/runtime/dart_vm_lifecycle.h"
-#include "topaz/runtime/dart/utils/files.h"
-
 #include "fuchsia_font_manager.h"
 #include "platform_view.h"
 #include "task_runner_adapter.h"
+#include "third_party/flutter/runtime/dart_vm_lifecycle.h"
 #include "thread.h"
+#include "topaz/runtime/dart/utils/files.h"
 
 namespace flutter_runner {
 
@@ -42,10 +42,13 @@
 
 Engine::Engine(Delegate& delegate, std::string thread_label,
                std::shared_ptr<sys::ServiceDirectory> svc,
+               std::shared_ptr<sys::ServiceDirectory> runner_services,
                flutter::Settings settings,
                fml::RefPtr<const flutter::DartSnapshot> isolate_snapshot,
                fml::RefPtr<const flutter::DartSnapshot> shared_snapshot,
-               fuchsia::ui::views::ViewToken view_token, UniqueFDIONS fdio_ns,
+               fuchsia::ui::views::ViewToken view_token,
+               fuchsia::ui::views::ViewRefControl view_ref_control,
+               fuchsia::ui::views::ViewRef view_ref, UniqueFDIONS fdio_ns,
                fidl::InterfaceRequest<fuchsia::io::Directory> directory_request)
     : delegate_(delegate),
       thread_label_(std::move(thread_label)),
@@ -106,36 +109,41 @@
       };
 
   // Setup the callback that will instantiate the platform view.
-  flutter::Shell::CreateCallback<flutter::PlatformView> on_create_platform_view =
-      fml::MakeCopyable([debug_label = thread_label_,
-                         parent_environment_service_provider =
-                             std::move(parent_environment_service_provider),
-                         session_listener_request =
-                             std::move(session_listener_request),
-                         on_session_listener_error_callback =
-                             std::move(on_session_listener_error_callback),
-                         on_session_metrics_change_callback =
-                             std::move(on_session_metrics_change_callback),
-                         on_session_size_change_hint_callback =
-                             std::move(on_session_size_change_hint_callback),
-                         accessibility_context_writer =
-                             std::move(accessibility_context_writer),
-                         vsync_handle =
-                             vsync_event_.get()](flutter::Shell& shell) mutable {
-        return std::make_unique<flutter_runner::PlatformView>(
-            shell,                                           // delegate
-            debug_label,                                     // debug label
-            shell.GetTaskRunners(),                          // task runners
-            std::move(parent_environment_service_provider),  // services
-            std::move(session_listener_request),             // session listener
-            std::move(on_session_listener_error_callback),
-            std::move(on_session_metrics_change_callback),
-            std::move(on_session_size_change_hint_callback),
-            std::move(
-                accessibility_context_writer),  // accessibility context writer
-            vsync_handle                        // vsync handle
-        );
-      });
+  flutter::Shell::CreateCallback<flutter::PlatformView>
+      on_create_platform_view = fml::MakeCopyable(
+          [debug_label = thread_label_,
+           view_ref_control = std::move(view_ref_control),
+           view_ref = std::move(view_ref),
+           runner_services = std::move(runner_services),
+           parent_environment_service_provider =
+               std::move(parent_environment_service_provider),
+           session_listener_request = std::move(session_listener_request),
+           on_session_listener_error_callback =
+               std::move(on_session_listener_error_callback),
+           on_session_metrics_change_callback =
+               std::move(on_session_metrics_change_callback),
+           on_session_size_change_hint_callback =
+               std::move(on_session_size_change_hint_callback),
+           accessibility_context_writer =
+               std::move(accessibility_context_writer),
+           vsync_handle = vsync_event_.get()](flutter::Shell& shell) mutable {
+            return std::make_unique<flutter_runner::PlatformView>(
+                shell,                        // delegate
+                debug_label,                  // debug label
+                std::move(view_ref_control),  // view control ref
+                std::move(view_ref),          // view ref
+                shell.GetTaskRunners(),       // task runners
+                std::move(runner_services),
+                std::move(parent_environment_service_provider),  // services
+                std::move(session_listener_request),  // session listener
+                std::move(on_session_listener_error_callback),
+                std::move(on_session_metrics_change_callback),
+                std::move(on_session_size_change_hint_callback),
+                std::move(accessibility_context_writer),  // accessibility
+                                                          // context writer
+                vsync_handle                              // vsync handle
+            );
+          });
 
   // Session can be terminated on the GPU thread, but we must terminate
   // ourselves on the platform thread.
@@ -182,9 +190,9 @@
   const flutter::TaskRunners task_runners(
       thread_label_,  // Dart thread labels
       CreateFMLTaskRunner(async_get_default_dispatcher()),  // platform
-      CreateFMLTaskRunner(threads_[0]->dispatcher()),    // gpu
-      CreateFMLTaskRunner(threads_[1]->dispatcher()),    // ui
-      CreateFMLTaskRunner(threads_[2]->dispatcher())     // io
+      CreateFMLTaskRunner(threads_[0]->dispatcher()),       // gpu
+      CreateFMLTaskRunner(threads_[1]->dispatcher()),       // ui
+      CreateFMLTaskRunner(threads_[2]->dispatcher())        // io
   );
 
   UpdateNativeThreadLabelNames(thread_label_, task_runners);
@@ -429,9 +437,8 @@
       [rasterizer = shell_->GetRasterizer(), width_change_factor,
        height_change_factor]() {
         if (rasterizer) {
-          auto compositor_context =
-              reinterpret_cast<CompositorContext*>(
-                  rasterizer->compositor_context());
+          auto compositor_context = reinterpret_cast<CompositorContext*>(
+              rasterizer->compositor_context());
 
           compositor_context->OnSessionSizeChangeHint(width_change_factor,
                                                       height_change_factor);
diff --git a/runtime/flutter_runner/engine.h b/runtime/flutter_runner/engine.h
index b6cdc7f..7301a0c 100644
--- a/runtime/flutter_runner/engine.h
+++ b/runtime/flutter_runner/engine.h
@@ -29,10 +29,14 @@
   };
 
   Engine(Delegate& delegate, std::string thread_label,
-         std::shared_ptr<sys::ServiceDirectory> svc, flutter::Settings settings,
+         std::shared_ptr<sys::ServiceDirectory> svc,
+         std::shared_ptr<sys::ServiceDirectory> runner_services,
+         flutter::Settings settings,
          fml::RefPtr<const flutter::DartSnapshot> isolate_snapshot,
          fml::RefPtr<const flutter::DartSnapshot> shared_snapshot,
-         fuchsia::ui::views::ViewToken view_token, UniqueFDIONS fdio_ns,
+         fuchsia::ui::views::ViewToken view_token,
+         fuchsia::ui::views::ViewRefControl view_ref_control,
+         fuchsia::ui::views::ViewRef view_ref, UniqueFDIONS fdio_ns,
          fidl::InterfaceRequest<fuchsia::io::Directory> directory_request);
   ~Engine();
 
diff --git a/runtime/flutter_runner/fuchsia_accessibility.cc b/runtime/flutter_runner/fuchsia_accessibility.cc
new file mode 100644
index 0000000..0589be5
--- /dev/null
+++ b/runtime/flutter_runner/fuchsia_accessibility.cc
@@ -0,0 +1,70 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fuchsia_accessibility.h"
+
+#include <src/lib/fxl/logging.h>
+#include <zircon/status.h>
+
+#include "fuchsia/accessibility/semantics/cpp/fidl.h"
+
+namespace flutter_runner {
+namespace {
+class FuchsiaAccessibilityImpl
+    : public FuchsiaAccessibility,
+      public fuchsia::accessibility::semantics::SemanticActionListener {
+ public:
+  FuchsiaAccessibilityImpl(std::shared_ptr<sys::ServiceDirectory> services,
+                           fuchsia::ui::views::ViewRef view_ref)
+      : binding_(this), view_ref_(std::move(view_ref)) {
+    services->Connect(
+        fuchsia::accessibility::semantics::SemanticsManager::Name_,
+        manager_.NewRequest().TakeChannel());
+    manager_.set_error_handler([this](zx_status_t status) {
+      FXL_LOG(ERROR)
+          << "Flutter cannot connect to SemanticsManager with status: "
+          << zx_status_get_string(status) << ".";
+    });
+    fidl::InterfaceHandle<
+        fuchsia::accessibility::semantics::SemanticActionListener>
+        listener_handle;
+    binding_.Bind(listener_handle.NewRequest());
+    manager_->RegisterView(std::move(view_ref_), std::move(listener_handle),
+                           tree_ptr_.NewRequest());
+  }
+
+  ~FuchsiaAccessibilityImpl() override = default;
+
+  void UpdateSemanticNodes(
+      std::vector<fuchsia::accessibility::semantics::Node> nodes) override {}
+  void DeleteSemanticNodes(std::vector<uint32_t> node_ids) override {}
+  void Commit() override {}
+
+ private:
+  // |fuchsia::accessibility::semantics::SemanticActionListener|
+  void OnAccessibilityActionRequested(
+      uint32_t node_id, fuchsia::accessibility::semantics::Action action,
+      fuchsia::accessibility::semantics::SemanticActionListener::
+          OnAccessibilityActionRequestedCallback callback) override {}
+
+  fuchsia::accessibility::semantics::SemanticsManagerPtr manager_;
+  fuchsia::accessibility::semantics::SemanticTreePtr tree_ptr_;
+  fidl::Binding<fuchsia::accessibility::semantics::SemanticActionListener>
+      binding_;
+  fuchsia::ui::views::ViewRef view_ref_;
+
+  FXL_DISALLOW_COPY_AND_ASSIGN(FuchsiaAccessibilityImpl);
+};
+
+}  // namespace
+
+// static
+std::unique_ptr<FuchsiaAccessibility> FuchsiaAccessibility::Create(
+    std::shared_ptr<sys::ServiceDirectory> services,
+    fuchsia::ui::views::ViewRef view_ref) {
+  return std::make_unique<FuchsiaAccessibilityImpl>(std::move(services),
+                                                    std::move(view_ref));
+}
+
+}  // namespace flutter_runner
diff --git a/runtime/flutter_runner/fuchsia_accessibility.h b/runtime/flutter_runner/fuchsia_accessibility.h
new file mode 100644
index 0000000..162e0d7
--- /dev/null
+++ b/runtime/flutter_runner/fuchsia_accessibility.h
@@ -0,0 +1,40 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOPAZ_RUNTIME_FLUTTER_RUNNER_FUCHSIA_ACCESSIBILITY_H_
+#define TOPAZ_RUNTIME_FLUTTER_RUNNER_FUCHSIA_ACCESSIBILITY_H_
+
+#include <fuchsia/accessibility/semantics/cpp/fidl.h>
+#include <fuchsia/sys/cpp/fidl.h>
+#include <fuchsia/ui/views/cpp/fidl.h>
+#include <lib/fidl/cpp/binding_set.h>
+#include <lib/sys/cpp/service_directory.h>
+
+#include <memory>
+
+namespace flutter_runner {
+
+// Host platform accessibility API wrapper. Called by |AccessibilityBridge|.
+//
+// This provides an abstraction of the full set of host platform calls that
+// |AccessibilityBridge| needs to call. Implemented as an abstract base class
+// in order to allow passing a fake implementation to |AccessibilityBridge|
+// unit tests.
+class FuchsiaAccessibility {
+ public:
+  static std::unique_ptr<FuchsiaAccessibility> Create(
+      std::shared_ptr<sys::ServiceDirectory> services,
+      fuchsia::ui::views::ViewRef view_ref);
+
+  virtual ~FuchsiaAccessibility() = default;
+
+  virtual void UpdateSemanticNodes(
+      std::vector<fuchsia::accessibility::semantics::Node> nodes) = 0;
+  virtual void DeleteSemanticNodes(std::vector<uint32_t> node_ids) = 0;
+  virtual void Commit() = 0;
+};
+
+}  // namespace flutter_runner
+
+#endif  // TOPAZ_RUNTIME_FLUTTER_RUNNER_FUCHSIA_ACCESSIBILITY_H_
diff --git a/runtime/flutter_runner/fuchsia_accessibility_unittest.cc b/runtime/flutter_runner/fuchsia_accessibility_unittest.cc
new file mode 100644
index 0000000..1fcfaf4
--- /dev/null
+++ b/runtime/flutter_runner/fuchsia_accessibility_unittest.cc
@@ -0,0 +1,63 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "topaz/runtime/flutter_runner/fuchsia_accessibility.h"
+
+#include <gtest/gtest.h>
+#include <lib/async-loop/cpp/loop.h>
+#include <lib/fidl/cpp/binding_set.h>
+#include <lib/fidl/cpp/interface_request.h>
+#include <lib/gtest/real_loop_fixture.h>
+#include <lib/sys/cpp/testing/service_directory_provider.h>
+
+namespace flutter_runner_a11y_test {
+using fuchsia::accessibility::semantics::SemanticsManager;
+using FuchsiaAccessibilityTests = gtest::RealLoopFixture;
+
+class MockSemanticsManager : public SemanticsManager {
+ public:
+  MockSemanticsManager() = default;
+  ~MockSemanticsManager() = default;
+
+  // |fuchsia::accessibility::semantics::SemanticsManager|:
+  void RegisterView(
+      fuchsia::ui::views::ViewRef view_ref,
+      fidl::InterfaceHandle<
+          fuchsia::accessibility::semantics::SemanticActionListener>
+          handle,
+      fidl::InterfaceRequest<fuchsia::accessibility::semantics::SemanticTree>
+          semantic_tree) override {
+    has_view_ref_ = true;
+  }
+
+  fidl::InterfaceRequestHandler<SemanticsManager> GetHandler(
+      async_dispatcher_t* dispatcher) {
+    return bindings_.GetHandler(this, dispatcher);
+  }
+
+  bool RegisterViewCalled() { return has_view_ref_; }
+
+ private:
+  bool has_view_ref_ = false;
+  fidl::BindingSet<SemanticsManager> bindings_;
+};
+
+TEST_F(FuchsiaAccessibilityTests, RegisterViewRef) {
+  MockSemanticsManager semantics_manager;
+  sys::testing::ServiceDirectoryProvider services_provider(dispatcher());
+  services_provider.AddService(semantics_manager.GetHandler(dispatcher()),
+                               SemanticsManager::Name_);
+  zx::eventpair a, b;
+  zx::eventpair::create(/* flags */ 0u, &a, &b);
+  auto view_ref = fuchsia::ui::views::ViewRef({
+      .reference = std::move(a),
+  });
+  auto fuchsia_accessibility = flutter_runner::FuchsiaAccessibility::Create(
+      services_provider.service_directory(), std::move(view_ref));
+
+  RunLoopUntilIdle();
+  EXPECT_TRUE(semantics_manager.RegisterViewCalled());
+}
+
+}  // namespace flutter_runner_a11y_test
diff --git a/runtime/flutter_runner/meta/flutter_aot_product_runner.cmx b/runtime/flutter_runner/meta/flutter_aot_product_runner.cmx
index d7bb132..ceb23a5 100644
--- a/runtime/flutter_runner/meta/flutter_aot_product_runner.cmx
+++ b/runtime/flutter_runner/meta/flutter_aot_product_runner.cmx
@@ -8,6 +8,8 @@
             "vulkan"
         ],
         "services": [
+            "fuchsia.accessibility.SettingsManager",
+            "fuchsia.accessibility.semantics.SemanticsManager",
             "fuchsia.crash.Analyzer",
             "fuchsia.fonts.Provider",
             "fuchsia.net.SocketProvider",
diff --git a/runtime/flutter_runner/meta/flutter_aot_runner.cmx b/runtime/flutter_runner/meta/flutter_aot_runner.cmx
index d7bb132..ceb23a5 100644
--- a/runtime/flutter_runner/meta/flutter_aot_runner.cmx
+++ b/runtime/flutter_runner/meta/flutter_aot_runner.cmx
@@ -8,6 +8,8 @@
             "vulkan"
         ],
         "services": [
+            "fuchsia.accessibility.SettingsManager",
+            "fuchsia.accessibility.semantics.SemanticsManager",
             "fuchsia.crash.Analyzer",
             "fuchsia.fonts.Provider",
             "fuchsia.net.SocketProvider",
diff --git a/runtime/flutter_runner/meta/flutter_jit_product_runner.cmx b/runtime/flutter_runner/meta/flutter_jit_product_runner.cmx
index d7bb132..ceb23a5 100644
--- a/runtime/flutter_runner/meta/flutter_jit_product_runner.cmx
+++ b/runtime/flutter_runner/meta/flutter_jit_product_runner.cmx
@@ -8,6 +8,8 @@
             "vulkan"
         ],
         "services": [
+            "fuchsia.accessibility.SettingsManager",
+            "fuchsia.accessibility.semantics.SemanticsManager",
             "fuchsia.crash.Analyzer",
             "fuchsia.fonts.Provider",
             "fuchsia.net.SocketProvider",
diff --git a/runtime/flutter_runner/meta/flutter_jit_runner.cmx b/runtime/flutter_runner/meta/flutter_jit_runner.cmx
index d7bb132..ceb23a5 100644
--- a/runtime/flutter_runner/meta/flutter_jit_runner.cmx
+++ b/runtime/flutter_runner/meta/flutter_jit_runner.cmx
@@ -8,6 +8,8 @@
             "vulkan"
         ],
         "services": [
+            "fuchsia.accessibility.SettingsManager",
+            "fuchsia.accessibility.semantics.SemanticsManager",
             "fuchsia.crash.Analyzer",
             "fuchsia.fonts.Provider",
             "fuchsia.net.SocketProvider",
diff --git a/runtime/flutter_runner/meta/flutter_runner_tests.cmx b/runtime/flutter_runner/meta/flutter_runner_tests.cmx
index c66080b..80a31b3 100644
--- a/runtime/flutter_runner/meta/flutter_runner_tests.cmx
+++ b/runtime/flutter_runner/meta/flutter_runner_tests.cmx
@@ -4,6 +4,8 @@
     },
     "sandbox": {
         "services": [
+            "fuchsia.accessibility.SettingsManager",
+            "fuchsia.accessibility.semantics.SemanticsManager",
             "fuchsia.sys.Launcher"
         ]
     }
diff --git a/runtime/flutter_runner/platform_view.cc b/runtime/flutter_runner/platform_view.cc
index e2ea035..f1cf017 100644
--- a/runtime/flutter_runner/platform_view.cc
+++ b/runtime/flutter_runner/platform_view.cc
@@ -13,6 +13,7 @@
 #include "flutter/fml/logging.h"
 #include "flutter/lib/ui/compositing/scene_host.h"
 #include "flutter/lib/ui/window/pointer_data.h"
+#include "fuchsia/ui/views/cpp/fidl.h"
 #include "rapidjson/document.h"
 #include "rapidjson/stringbuffer.h"
 #include "rapidjson/writer.h"
@@ -79,7 +80,9 @@
 
 PlatformView::PlatformView(
     PlatformView::Delegate& delegate, std::string debug_label,
-    flutter::TaskRunners task_runners,
+    fuchsia::ui::views::ViewRefControl view_ref_control,
+    fuchsia::ui::views::ViewRef view_ref, flutter::TaskRunners task_runners,
+    std::shared_ptr<sys::ServiceDirectory> runner_services,
     fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
         parent_environment_service_provider_handle,
     fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener>
@@ -92,6 +95,8 @@
     zx_handle_t vsync_event_handle)
     : flutter::PlatformView(delegate, std::move(task_runners)),
       debug_label_(std::move(debug_label)),
+      view_ref_control_(std::move(view_ref_control)),
+      view_ref_(std::move(view_ref)),
       session_listener_binding_(this, std::move(session_listener_request)),
       session_listener_error_callback_(
           std::move(session_listener_error_callback)),
@@ -122,10 +127,10 @@
   // Finally! Register the native platform message handlers.
   RegisterPlatformMessageHandlers();
 
-  // TODO(SCN-975): Re-enable.  Likely that Engine should clone the ViewToken
-  // and pass the clone in here.
-  //   view_->GetToken(std::bind(&PlatformView::ConnectSemanticsProvider, this,
-  //                             std::placeholders::_1));
+  fuchsia::ui::views::ViewRef accessibility_view_ref;
+  view_ref_.Clone(&accessibility_view_ref);
+  accessibility_holder_ = FuchsiaAccessibility::Create(
+      std::move(runner_services), std::move(accessibility_view_ref));
 }
 
 PlatformView::~PlatformView() = default;
diff --git a/runtime/flutter_runner/platform_view.h b/runtime/flutter_runner/platform_view.h
index 9a03d0a..6af1d58 100644
--- a/runtime/flutter_runner/platform_view.h
+++ b/runtime/flutter_runner/platform_view.h
@@ -5,23 +5,25 @@
 #ifndef TOPAZ_RUNTIME_FLUTTER_RUNNER_PLATFORM_VIEW_H_
 #define TOPAZ_RUNTIME_FLUTTER_RUNNER_PLATFORM_VIEW_H_
 
-#include <map>
-#include <set>
-
 #include <fuchsia/accessibility/cpp/fidl.h>
 #include <fuchsia/modular/cpp/fidl.h>
 #include <fuchsia/ui/gfx/cpp/fidl.h>
 #include <fuchsia/ui/input/cpp/fidl.h>
 #include <fuchsia/ui/scenic/cpp/fidl.h>
+#include <fuchsia/ui/views/cpp/fidl.h>
 #include <lib/fit/function.h>
+#include <lib/sys/cpp/service_directory.h>
 
+#include <map>
+#include <set>
+
+#include "context_writer_bridge.h"
 #include "flutter/fml/macros.h"
 #include "flutter/lib/ui/window/viewport_metrics.h"
 #include "flutter/shell/common/platform_view.h"
+#include "fuchsia_accessibility.h"
 #include "lib/fidl/cpp/binding.h"
 #include "lib/ui/scenic/cpp/id.h"
-
-#include "context_writer_bridge.h"
 #include "surface.h"
 
 namespace flutter_runner {
@@ -41,7 +43,10 @@
                            public fuchsia::ui::input::InputMethodEditorClient {
  public:
   PlatformView(PlatformView::Delegate& delegate, std::string debug_label,
+               fuchsia::ui::views::ViewRefControl view_ref_control,
+               fuchsia::ui::views::ViewRef view_ref,
                flutter::TaskRunners task_runners,
+               std::shared_ptr<sys::ServiceDirectory> runner_services,
                fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
                    parent_environment_service_provider,
                fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener>
@@ -66,6 +71,11 @@
 
  private:
   const std::string debug_label_;
+  // TODO(MI4-2490): remove once ViewRefControl is passed to Scenic and kept
+  // alive there
+  const fuchsia::ui::views::ViewRefControl view_ref_control_;
+  const fuchsia::ui::views::ViewRef view_ref_;
+  std::unique_ptr<FuchsiaAccessibility> accessibility_holder_;
 
   fidl::Binding<fuchsia::ui::scenic::SessionListener> session_listener_binding_;
   fit::closure session_listener_error_callback_;