// Copyright 2013 The Flutter 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 "engine.h"

#include <fuchsia/accessibility/semantics/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <zircon/status.h>
#include <zircon/types.h>
#include <memory>

#include "flutter/common/graphics/persistent_cache.h"
#include "flutter/common/task_runners.h"
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/message_loop.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/task_runner.h"
#include "flutter/runtime/dart_vm_lifecycle.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/run_configuration.h"
#include "flutter/shell/common/serialization_callbacks.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSerialProcs.h"
#include "third_party/skia/include/ports/SkFontMgr_fuchsia.h"

#include "../runtime/dart/utils/files.h"
#include "../runtime/dart/utils/root_inspect_node.h"
#include "flatland_platform_view.h"
#include "focus_delegate.h"
#include "fuchsia_intl.h"
#include "gfx_platform_view.h"
#include "software_surface_producer.h"
#include "surface.h"
#include "vsync_waiter.h"
#include "vulkan_surface_producer.h"

namespace flutter_runner {
namespace {

zx_koid_t GetKoid(const fuchsia::ui::views::ViewRef& view_ref) {
  zx_handle_t handle = view_ref.reference.get();
  zx_info_handle_basic_t info;
  zx_status_t status = zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info,
                                          sizeof(info), nullptr, nullptr);
  return status == ZX_OK ? info.koid : ZX_KOID_INVALID;
}

std::unique_ptr<flutter::PlatformMessage> MakeLocalizationPlatformMessage(
    const fuchsia::intl::Profile& intl_profile) {
  return std::make_unique<flutter::PlatformMessage>(
      "flutter/localization", MakeLocalizationPlatformMessageData(intl_profile),
      nullptr);
}

}  // namespace

flutter::ThreadHost Engine::CreateThreadHost(const std::string& name_prefix) {
  fml::Thread::SetCurrentThreadName(
      fml::Thread::ThreadConfig(name_prefix + ".platform"));
  return flutter::ThreadHost(name_prefix, flutter::ThreadHost::Type::RASTER |
                                              flutter::ThreadHost::Type::UI |
                                              flutter::ThreadHost::Type::IO);
}

Engine::Engine(Delegate& delegate,
               std::string thread_label,
               std::shared_ptr<sys::ServiceDirectory> svc,
               std::shared_ptr<sys::ServiceDirectory> runner_services,
               flutter::Settings settings,
               fuchsia::ui::views::ViewToken view_token,
               scenic::ViewRefPair view_ref_pair,
               UniqueFDIONS fdio_ns,
               fidl::InterfaceRequest<fuchsia::io::Directory> directory_request,
               FlutterRunnerProductConfiguration product_config,
               const std::vector<std::string>& dart_entrypoint_args,
               bool for_v1_component)
    : delegate_(delegate),
      thread_label_(std::move(thread_label)),
      thread_host_(CreateThreadHost(thread_label_)),
      view_token_(std::move(view_token)),
      memory_pressure_watcher_binding_(this),
      latest_memory_pressure_level_(fuchsia::memorypressure::Level::NORMAL),
      intercept_all_input_(product_config.get_intercept_all_input()),
      weak_factory_(this) {
  Initialize(/*=use_flatland*/ false, std::move(view_ref_pair), std::move(svc),
             std::move(runner_services), std::move(settings),
             std::move(fdio_ns), std::move(directory_request),
             std::move(product_config), dart_entrypoint_args, for_v1_component);
}

Engine::Engine(Delegate& delegate,
               std::string thread_label,
               std::shared_ptr<sys::ServiceDirectory> svc,
               std::shared_ptr<sys::ServiceDirectory> runner_services,
               flutter::Settings settings,
               fuchsia::ui::views::ViewCreationToken view_creation_token,
               scenic::ViewRefPair view_ref_pair,
               UniqueFDIONS fdio_ns,
               fidl::InterfaceRequest<fuchsia::io::Directory> directory_request,
               FlutterRunnerProductConfiguration product_config,
               const std::vector<std::string>& dart_entrypoint_args,
               bool for_v1_component)
    : delegate_(delegate),
      thread_label_(std::move(thread_label)),
      thread_host_(CreateThreadHost(thread_label_)),
      view_creation_token_(std::move(view_creation_token)),
      memory_pressure_watcher_binding_(this),
      latest_memory_pressure_level_(fuchsia::memorypressure::Level::NORMAL),
      intercept_all_input_(product_config.get_intercept_all_input()),
      weak_factory_(this) {
  Initialize(/*=use_flatland*/ true, std::move(view_ref_pair), std::move(svc),
             std::move(runner_services), std::move(settings),
             std::move(fdio_ns), std::move(directory_request),
             std::move(product_config), dart_entrypoint_args, for_v1_component);
}

void Engine::Initialize(
    bool use_flatland,
    scenic::ViewRefPair view_ref_pair,
    std::shared_ptr<sys::ServiceDirectory> svc,
    std::shared_ptr<sys::ServiceDirectory> runner_services,
    flutter::Settings settings,
    UniqueFDIONS fdio_ns,
    fidl::InterfaceRequest<fuchsia::io::Directory> directory_request,
    FlutterRunnerProductConfiguration product_config,
    const std::vector<std::string>& dart_entrypoint_args,
    bool for_v1_component) {
  // Flatland uses |view_creation_token_| for linking. Gfx uses |view_token_|.
  FML_CHECK((use_flatland && view_creation_token_.value.is_valid()) ||
            (!use_flatland && view_token_.value.is_valid()));

  // Get the task runners from the managed threads. The current thread will be
  // used as the "platform" thread.
  fml::RefPtr<fml::TaskRunner> platform_task_runner =
      fml::MessageLoop::GetCurrent().GetTaskRunner();

  const flutter::TaskRunners task_runners(
      thread_label_,                                // Dart thread labels
      platform_task_runner,                         // platform
      thread_host_.raster_thread->GetTaskRunner(),  // raster
      thread_host_.ui_thread->GetTaskRunner(),      // ui
      thread_host_.io_thread->GetTaskRunner()       // io
  );

  // Connect to Scenic.
  auto scenic = runner_services->Connect<fuchsia::ui::scenic::Scenic>();
  fuchsia::ui::scenic::SessionEndpoints gfx_protocols;
  fuchsia::ui::scenic::SessionHandle session;
  gfx_protocols.set_session(session.NewRequest());
  fuchsia::ui::scenic::SessionListenerHandle session_listener;
  auto session_listener_request = session_listener.NewRequest();
  gfx_protocols.set_session_listener(session_listener.Bind());
  fuchsia::ui::views::FocuserHandle focuser;
  fuchsia::ui::views::ViewRefFocusedHandle view_ref_focused;
  fuchsia::ui::pointer::TouchSourceHandle touch_source;
  fuchsia::ui::pointer::MouseSourceHandle mouse_source;

  fuchsia::ui::composition::ViewBoundProtocols flatland_view_protocols;
  if (use_flatland) {
    flatland_view_protocols.set_view_focuser(focuser.NewRequest());
    flatland_view_protocols.set_view_ref_focused(view_ref_focused.NewRequest());
    flatland_view_protocols.set_touch_source(touch_source.NewRequest());
    flatland_view_protocols.set_mouse_source(mouse_source.NewRequest());
  } else {
    gfx_protocols.set_view_focuser(focuser.NewRequest());
    gfx_protocols.set_view_ref_focused(view_ref_focused.NewRequest());
    gfx_protocols.set_touch_source(touch_source.NewRequest());
    // GFX used only on products without a mouse.
  }
  scenic->CreateSessionT(std::move(gfx_protocols), [] {});

  // Connect to Flatland.
  fuchsia::ui::composition::FlatlandHandle flatland;
  zx_status_t flatland_status =
      runner_services->Connect<fuchsia::ui::composition::Flatland>(
          flatland.NewRequest());
  if (flatland_status != ZX_OK && use_flatland) {
    FML_LOG(WARNING) << "fuchsia::ui::composition::Flatland connection failed: "
                     << zx_status_get_string(flatland_status);
  }

  // Connect to SemanticsManager service.
  fuchsia::accessibility::semantics::SemanticsManagerHandle semantics_manager;
  zx_status_t semantics_status =
      runner_services
          ->Connect<fuchsia::accessibility::semantics::SemanticsManager>(
              semantics_manager.NewRequest());
  if (semantics_status != ZX_OK) {
    FML_LOG(WARNING)
        << "fuchsia::accessibility::semantics::SemanticsManager connection "
           "failed: "
        << zx_status_get_string(semantics_status);
  }

  // Connect to ImeService service.
  fuchsia::ui::input::ImeServiceHandle ime_service;
  zx_status_t ime_status =
      runner_services->Connect<fuchsia::ui::input::ImeService>(
          ime_service.NewRequest());
  if (ime_status != ZX_OK) {
    FML_LOG(WARNING) << "fuchsia::ui::input::ImeService connection failed: "
                     << zx_status_get_string(ime_status);
  }

  // Connect to Keyboard service.
  fuchsia::ui::input3::KeyboardHandle keyboard;
  zx_status_t keyboard_status =
      runner_services->Connect<fuchsia::ui::input3::Keyboard>(
          keyboard.NewRequest());
  FML_DCHECK(keyboard_status == ZX_OK)
      << "fuchsia::ui::input3::Keyboard connection failed: "
      << zx_status_get_string(keyboard_status);

  // Connect to Pointerinjector service.
  fuchsia::ui::pointerinjector::RegistryHandle pointerinjector_registry;
  zx_status_t pointerinjector_registry_status =
      runner_services->Connect<fuchsia::ui::pointerinjector::Registry>(
          pointerinjector_registry.NewRequest());
  if (pointerinjector_registry_status != ZX_OK) {
    FML_LOG(WARNING)
        << "fuchsia::ui::pointerinjector::Registry connection failed: "
        << zx_status_get_string(pointerinjector_registry_status);
  }

  // Make clones of the `ViewRef` before sending it to various places.
  fuchsia::ui::views::ViewRef platform_view_ref;
  view_ref_pair.view_ref.Clone(&platform_view_ref);
  fuchsia::ui::views::ViewRef accessibility_view_ref;
  view_ref_pair.view_ref.Clone(&accessibility_view_ref);
  fuchsia::ui::views::ViewRef isolate_view_ref;
  view_ref_pair.view_ref.Clone(&isolate_view_ref);

  // Session is terminated on the raster thread, but we must terminate ourselves
  // on the platform thread.
  //
  // This handles the fidl error callback when the Session connection is
  // broken. The SessionListener interface also has an OnError method, which is
  // invoked on the platform thread (in PlatformView).
  fml::closure session_error_callback = [task_runner = platform_task_runner,
                                         weak = weak_factory_.GetWeakPtr()]() {
    task_runner->PostTask([weak]() {
      if (weak) {
        FML_LOG(ERROR) << "Terminating from session_error_callback";
        weak->Terminate();
      }
    });
  };

  // Set up the session connection and other Scenic helpers on the raster
  // thread. We also need to wait for the external view embedder to be set up
  // before creating the shell.
  fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
  fml::AutoResetWaitableEvent view_embedder_latch;
  auto session_inspect_node =
      dart_utils::RootInspectNode::CreateRootChild("vsync_stats");
  task_runners.GetRasterTaskRunner()->PostTask(fml::MakeCopyable(
      [this, &view_embedder_latch,
       session_inspect_node = std::move(session_inspect_node),
       session = std::move(session), flatland = std::move(flatland),
       session_error_callback = std::move(session_error_callback), use_flatland,
       view_token = std::move(view_token_),
       view_creation_token = std::move(view_creation_token_),
       flatland_view_protocols = std::move(flatland_view_protocols),
       request = parent_viewport_watcher.NewRequest(),
       view_ref_pair = std::move(view_ref_pair),
       max_frames_in_flight = product_config.get_max_frames_in_flight(),
       vsync_offset = product_config.get_vsync_offset(),
       software_rendering = product_config.software_rendering()]() mutable {
        if (use_flatland) {
          if (software_rendering) {
            surface_producer_ = std::make_shared<SoftwareSurfaceProducer>(
                /*scenic_session=*/nullptr);
          } else {
            surface_producer_ = std::make_shared<VulkanSurfaceProducer>(
                /*scenic_session=*/nullptr);
          }

          flatland_connection_ = std::make_shared<FlatlandConnection>(
              thread_label_, std::move(flatland),
              std::move(session_error_callback), [](auto) {},
              max_frames_in_flight, vsync_offset);

          fuchsia::ui::views::ViewIdentityOnCreation view_identity = {
              .view_ref = std::move(view_ref_pair.view_ref),
              .view_ref_control = std::move(view_ref_pair.control_ref)};
          flatland_view_embedder_ =
              std::make_shared<FlatlandExternalViewEmbedder>(
                  std::move(view_creation_token), std::move(view_identity),
                  std::move(flatland_view_protocols), std::move(request),
                  flatland_connection_, surface_producer_,
                  intercept_all_input_);
        } else {
          session_connection_ = std::make_shared<GfxSessionConnection>(
              thread_label_, std::move(session_inspect_node),
              std::move(session), std::move(session_error_callback),
              [](auto) {}, max_frames_in_flight, vsync_offset);

          if (software_rendering) {
            surface_producer_ = std::make_shared<SoftwareSurfaceProducer>(
                session_connection_->get());
          } else {
            surface_producer_ = std::make_shared<VulkanSurfaceProducer>(
                session_connection_->get());
          }

          external_view_embedder_ = std::make_shared<GfxExternalViewEmbedder>(
              thread_label_, std::move(view_token), std::move(view_ref_pair),
              session_connection_, surface_producer_, intercept_all_input_);
        }
        view_embedder_latch.Signal();
      }));
  view_embedder_latch.Wait();

  AccessibilityBridge::SetSemanticsEnabledCallback
      set_semantics_enabled_callback = [this](bool enabled) {
        auto platform_view = shell_->GetPlatformView();

        if (platform_view) {
          platform_view->SetSemanticsEnabled(enabled);
        }
      };

  AccessibilityBridge::DispatchSemanticsActionCallback
      dispatch_semantics_action_callback =
          [this](int32_t node_id, flutter::SemanticsAction action) {
            auto platform_view = shell_->GetPlatformView();

            if (platform_view) {
              platform_view->DispatchSemanticsAction(node_id, action, {});
            }
          };

  const std::string accessibility_inspect_name =
      std::to_string(GetKoid(accessibility_view_ref));
  accessibility_bridge_ = std::make_unique<AccessibilityBridge>(
      std::move(set_semantics_enabled_callback),
      std::move(dispatch_semantics_action_callback),
      std::move(semantics_manager), std::move(accessibility_view_ref),
      dart_utils::RootInspectNode::CreateRootChild(
          std::move(accessibility_inspect_name)));

  OnEnableWireframe on_enable_wireframe_callback = std::bind(
      &Engine::DebugWireframeSettingsChanged, this, std::placeholders::_1);

  OnCreateGfxView on_create_gfx_view_callback =
      std::bind(&Engine::CreateGfxView, this, std::placeholders::_1,
                std::placeholders::_2, std::placeholders::_3,
                std::placeholders::_4, std::placeholders::_5);

  OnCreateFlatlandView on_create_flatland_view_callback =
      std::bind(&Engine::CreateFlatlandView, this, std::placeholders::_1,
                std::placeholders::_2, std::placeholders::_3,
                std::placeholders::_4, std::placeholders::_5);

  OnUpdateView on_update_view_callback = std::bind(
      &Engine::UpdateView, this, std::placeholders::_1, std::placeholders::_2,
      std::placeholders::_3, std::placeholders::_4, use_flatland);

  OnDestroyGfxView on_destroy_gfx_view_callback =
      std::bind(&Engine::DestroyGfxView, this, std::placeholders::_1,
                std::placeholders::_2);

  OnDestroyFlatlandView on_destroy_flatland_view_callback =
      std::bind(&Engine::DestroyFlatlandView, this, std::placeholders::_1,
                std::placeholders::_2);

  OnCreateSurface on_create_surface_callback =
      std::bind(&Engine::CreateSurface, this);

  // SessionListener has a OnScenicError method; invoke this callback on the
  // platform thread when that happens. The Session itself should also be
  // disconnected when this happens, and it will also attempt to terminate.
  fit::closure on_session_listener_error_callback =
      [task_runner = platform_task_runner,
       weak = weak_factory_.GetWeakPtr()]() {
        task_runner->PostTask([weak]() {
          if (weak) {
            FML_LOG(ERROR) << "Terminating from "
                              "on_session_listener_error_callback";
            weak->Terminate();
          }
        });
      };

  // Launch the engine in the appropriate configuration.
  // Note: this initializes the Asset Manager on the global PersistantCache
  // so it must be called before WarmupSkps() is called below.
  auto run_configuration = flutter::RunConfiguration::InferFromSettings(
      settings, task_runners.GetIOTaskRunner());
  run_configuration.SetEntrypointArgs(std::move(dart_entrypoint_args));

  OnSemanticsNodeUpdate on_semantics_node_update_callback =
      [this](flutter::SemanticsNodeUpdates updates, float pixel_ratio) {
        accessibility_bridge_->AddSemanticsNodeUpdate(updates, pixel_ratio);
      };

  OnRequestAnnounce on_request_announce_callback =
      [this](const std::string& message) {
        accessibility_bridge_->RequestAnnounce(message);
      };

  // Setup the callback that will instantiate the platform view.
  flutter::Shell::CreateCallback<flutter::PlatformView>
      on_create_platform_view = fml::MakeCopyable(
          [this, use_flatland, view_ref = std::move(platform_view_ref),
           session_listener_request = std::move(session_listener_request),
           parent_viewport_watcher = std::move(parent_viewport_watcher),
           ime_service = std::move(ime_service), keyboard = std::move(keyboard),
           focuser = std::move(focuser),
           view_ref_focused = std::move(view_ref_focused),
           touch_source = std::move(touch_source),
           mouse_source = std::move(mouse_source),
           pointerinjector_registry = std::move(pointerinjector_registry),
           on_session_listener_error_callback =
               std::move(on_session_listener_error_callback),
           on_enable_wireframe_callback =
               std::move(on_enable_wireframe_callback),
           on_create_gfx_view_callback = std::move(on_create_gfx_view_callback),
           on_create_flatland_view_callback =
               std::move(on_create_flatland_view_callback),
           on_update_view_callback = std::move(on_update_view_callback),
           on_destroy_gfx_view_callback =
               std::move(on_destroy_gfx_view_callback),
           on_destroy_flatland_view_callback =
               std::move(on_destroy_flatland_view_callback),
           on_create_surface_callback = std::move(on_create_surface_callback),
           on_semantics_node_update_callback =
               std::move(on_semantics_node_update_callback),
           on_request_announce_callback =
               std::move(on_request_announce_callback),
           external_view_embedder = GetExternalViewEmbedder(),
           await_vsync_callback =
               [this, use_flatland](FireCallbackCallback cb) {
                 if (use_flatland) {
                   flatland_connection_->AwaitVsync(cb);
                 } else {
                   session_connection_->AwaitVsync(cb);
                 }
               },
           await_vsync_for_secondary_callback_callback =
               [this, use_flatland](FireCallbackCallback cb) {
                 if (use_flatland) {
                   flatland_connection_->AwaitVsyncForSecondaryCallback(cb);
                 } else {
                   session_connection_->AwaitVsyncForSecondaryCallback(cb);
                 }
               },
           product_config](flutter::Shell& shell) mutable {
            OnShaderWarmup on_shader_warmup = nullptr;
            if (product_config.enable_shader_warmup()) {
              FML_DCHECK(surface_producer_);
              if (product_config.enable_shader_warmup_dart_hooks()) {
                on_shader_warmup =
                    [this, &shell](
                        const std::vector<std::string>& skp_names,
                        std::function<void(uint32_t)> completion_callback,
                        uint64_t width, uint64_t height) {
                      WarmupSkps(
                          shell.GetDartVM()
                              ->GetConcurrentMessageLoop()
                              ->GetTaskRunner()
                              .get(),
                          shell.GetTaskRunners().GetRasterTaskRunner().get(),
                          surface_producer_, SkISize::Make(width, height),
                          flutter::PersistentCache::GetCacheForProcess()
                              ->asset_manager(),
                          skp_names, completion_callback);
                    };
              } else {
                WarmupSkps(shell.GetDartVM()
                               ->GetConcurrentMessageLoop()
                               ->GetTaskRunner()
                               .get(),
                           shell.GetTaskRunners().GetRasterTaskRunner().get(),
                           surface_producer_, SkISize::Make(1024, 600),
                           flutter::PersistentCache::GetCacheForProcess()
                               ->asset_manager(),
                           std::nullopt, std::nullopt);
              }
            }

            std::unique_ptr<flutter::PlatformView> platform_view;
            if (use_flatland) {
              platform_view =
                  std::make_unique<flutter_runner::FlatlandPlatformView>(
                      shell, shell.GetTaskRunners(), std::move(view_ref),
                      std::move(external_view_embedder), std::move(ime_service),
                      std::move(keyboard), std::move(touch_source),
                      std::move(mouse_source), std::move(focuser),
                      std::move(view_ref_focused),
                      std::move(parent_viewport_watcher),
                      std::move(pointerinjector_registry),
                      std::move(on_enable_wireframe_callback),
                      std::move(on_create_flatland_view_callback),
                      std::move(on_update_view_callback),
                      std::move(on_destroy_flatland_view_callback),
                      std::move(on_create_surface_callback),
                      std::move(on_semantics_node_update_callback),
                      std::move(on_request_announce_callback),
                      std::move(on_shader_warmup),
                      std::move(await_vsync_callback),
                      std::move(await_vsync_for_secondary_callback_callback));
            } else {
              platform_view = std::make_unique<flutter_runner::GfxPlatformView>(
                  shell, shell.GetTaskRunners(), std::move(view_ref),
                  std::move(external_view_embedder), std::move(ime_service),
                  std::move(keyboard), std::move(touch_source),
                  std::move(mouse_source), std::move(focuser),
                  std::move(view_ref_focused),
                  std::move(pointerinjector_registry),
                  std::move(session_listener_request),
                  std::move(on_session_listener_error_callback),
                  std::move(on_enable_wireframe_callback),
                  std::move(on_create_gfx_view_callback),
                  std::move(on_update_view_callback),
                  std::move(on_destroy_gfx_view_callback),
                  std::move(on_create_surface_callback),
                  std::move(on_semantics_node_update_callback),
                  std::move(on_request_announce_callback),
                  std::move(on_shader_warmup), std::move(await_vsync_callback),
                  std::move(await_vsync_for_secondary_callback_callback));
            }
            return platform_view;
          });

  // Setup the callback that will instantiate the rasterizer.
  flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer =
      [](flutter::Shell& shell) {
        return std::make_unique<flutter::Rasterizer>(shell);
      };

  settings.root_isolate_create_callback =
      std::bind(&Engine::OnMainIsolateStart, this);
  settings.root_isolate_shutdown_callback =
      std::bind([weak = weak_factory_.GetWeakPtr(),
                 runner = task_runners.GetPlatformTaskRunner()]() {
        runner->PostTask([weak = std::move(weak)] {
          if (weak) {
            weak->OnMainIsolateShutdown();
          }
        });
      });

  // Connect and set up the system font provider.
  fuchsia::fonts::ProviderSyncPtr sync_font_provider;
  runner_services->Connect(sync_font_provider.NewRequest());
  settings.font_initialization_data =
      sync_font_provider.Unbind().TakeChannel().release();

  {
    TRACE_EVENT0("flutter", "CreateShell");
    shell_ = flutter::Shell::Create(
        flutter::PlatformData(),             // default window data
        std::move(task_runners),             // host task runners
        std::move(settings),                 // shell launch settings
        std::move(on_create_platform_view),  // platform view create callback
        std::move(on_create_rasterizer)      // rasterizer create callback
    );
  }

  if (!shell_) {
    FML_LOG(ERROR) << "Could not launch the shell.";
    return;
  }

  // Shell has been created. Before we run the engine, set up the isolate
  // configurator.
  {
    fuchsia::sys::EnvironmentPtr environment;
    if (for_v1_component) {
      svc->Connect(environment.NewRequest());
    }

    isolate_configurator_ = std::make_unique<IsolateConfigurator>(
        std::move(fdio_ns),
        // v2 components do not use fuchsia.sys.Environment.
        for_v1_component ? std::move(environment) : nullptr,
        directory_request.TakeChannel(), std::move(isolate_view_ref.reference));
  }

  //  This platform does not get a separate surface platform view creation
  //  notification. Fire one eagerly.
  shell_->GetPlatformView()->NotifyCreated();

  // Connect to the memory pressure provider.  If the connection fails, the
  // initialization of the engine will simply proceed, printing a warning
  // message.  The engine will be fully functional, except that the Flutter
  // shell will not be notified when memory is low.
  {
    memory_pressure_provider_.set_error_handler([](zx_status_t status) {
      FML_LOG(WARNING)
          << "Failed to connect to " << fuchsia::memorypressure::Provider::Name_
          << ": " << zx_status_get_string(status)
          << " This is not a fatal error, but the heap will not be "
          << " compacted when memory is low.";
    });

    // Note that we're using the runner's services, not the component's.
    // The Flutter Shell should be notified when memory is low regardless of
    // whether the component has direct access to the
    // fuchsia.memorypressure.Provider service.
    ZX_ASSERT(runner_services->Connect(
                  memory_pressure_provider_.NewRequest()) == ZX_OK);

    FML_VLOG(-1) << "Registering memorypressure watcher";

    // Register for changes, which will make the request for the initial
    // memory level.
    memory_pressure_provider_->RegisterWatcher(
        memory_pressure_watcher_binding_.NewBinding());
  }

  // Connect to the intl property provider.  If the connection fails, the
  // initialization of the engine will simply proceed, printing a warning
  // message.  The engine will be fully functional, except that the user's
  // locale preferences would not be communicated to flutter engine.
  {
    intl_property_provider_.set_error_handler([](zx_status_t status) {
      FML_LOG(WARNING) << "Failed to connect to "
                       << fuchsia::intl::PropertyProvider::Name_ << ": "
                       << zx_status_get_string(status)
                       << " This is not a fatal error, but the user locale "
                       << " preferences will not be forwarded to flutter apps";
    });

    // Note that we're using the runner's services, not the component's.
    // Flutter locales should be updated regardless of whether the component has
    // direct access to the fuchsia.intl.PropertyProvider service.
    ZX_ASSERT(runner_services->Connect(intl_property_provider_.NewRequest()) ==
              ZX_OK);

    auto get_profile_callback = [weak = weak_factory_.GetWeakPtr()](
                                    const fuchsia::intl::Profile& profile) {
      if (!weak) {
        return;
      }
      if (!profile.has_locales()) {
        FML_LOG(WARNING) << "Got intl Profile without locales";
      }
      auto message = MakeLocalizationPlatformMessage(profile);
      FML_VLOG(-1) << "Sending LocalizationPlatformMessage";
      weak->shell_->GetPlatformView()->DispatchPlatformMessage(
          std::move(message));
    };

    FML_VLOG(-1) << "Requesting intl Profile";

    // Make the initial request
    intl_property_provider_->GetProfile(get_profile_callback);

    // And register for changes
    intl_property_provider_.events().OnChange = [this, runner_services,
                                                 get_profile_callback]() {
      FML_VLOG(-1) << fuchsia::intl::PropertyProvider::Name_ << ": OnChange";
      runner_services->Connect(intl_property_provider_.NewRequest());
      intl_property_provider_->GetProfile(get_profile_callback);
    };
  }

  auto on_run_failure = [weak = weak_factory_.GetWeakPtr()]() {
    // The engine could have been killed by the caller right after the
    // constructor was called but before it could run on the UI thread.
    if (weak) {
      FML_LOG(ERROR) << "Terminating from on_run_failure";
      weak->Terminate();
    }
  };

  shell_->GetTaskRunners().GetUITaskRunner()->PostTask(
      fml::MakeCopyable([engine = shell_->GetEngine(),                      //
                         run_configuration = std::move(run_configuration),  //
                         on_run_failure                                     //
  ]() mutable {
        if (!engine) {
          return;
        }

        if (engine->Run(std::move(run_configuration)) ==
            flutter::Engine::RunStatus::Failure) {
          on_run_failure();
        }
      }));
}

Engine::~Engine() {
  shell_.reset();

  // Destroy rendering objects on the raster thread.
  fml::AutoResetWaitableEvent view_embedder_latch;
  thread_host_.raster_thread->GetTaskRunner()->PostTask(
      fml::MakeCopyable([this, &view_embedder_latch]() mutable {
        if (flatland_view_embedder_ != nullptr) {
          flatland_view_embedder_.reset();
          flatland_connection_.reset();
          surface_producer_.reset();
        } else {
          external_view_embedder_.reset();
          surface_producer_.reset();
          session_connection_.reset();
        }
        view_embedder_latch.Signal();
      }));
  view_embedder_latch.Wait();
}

std::optional<uint32_t> Engine::GetEngineReturnCode() const {
  if (!shell_) {
    return std::nullopt;
  }
  std::optional<uint32_t> code;
  fml::AutoResetWaitableEvent latch;
  fml::TaskRunner::RunNowOrPostTask(
      shell_->GetTaskRunners().GetUITaskRunner(),
      [&latch, &code, engine = shell_->GetEngine()]() {
        if (engine) {
          code = engine->GetUIIsolateReturnCode();
        }
        latch.Signal();
      });
  latch.Wait();
  return code;
}

void Engine::OnMainIsolateStart() {
  if (!isolate_configurator_ ||
      !isolate_configurator_->ConfigureCurrentIsolate()) {
    FML_LOG(ERROR) << "Could not configure some native embedder bindings for a "
                      "new root isolate.";
  }
}

void Engine::OnMainIsolateShutdown() {
  Terminate();
}

void Engine::Terminate() {
  delegate_.OnEngineTerminate(this);
  // Warning. Do not do anything after this point as the delegate may have
  // collected this object.
}

void Engine::DebugWireframeSettingsChanged(bool enabled) {
  FML_CHECK(shell_);

  // TODO(fxbug.dev/116000): Investigate if we can add flatland wireframe code
  // for debugging.
  shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask([this, enabled]() {
    if (external_view_embedder_) {
      external_view_embedder_->EnableWireframe(enabled);
    }
  });
}

void Engine::CreateGfxView(int64_t view_id,
                           ViewCallback on_view_created,
                           GfxViewIdCallback on_view_bound,
                           bool hit_testable,
                           bool focusable) {
  FML_CHECK(shell_);
  shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
      [this, view_id, hit_testable, focusable,
       on_view_created = std::move(on_view_created),
       on_view_bound = std::move(on_view_bound)]() {
        FML_CHECK(external_view_embedder_);
        external_view_embedder_->CreateView(view_id, std::move(on_view_created),
                                            std::move(on_view_bound));
        external_view_embedder_->SetViewProperties(view_id, SkRect::MakeEmpty(),
                                                   hit_testable, focusable);
      });
}

void Engine::CreateFlatlandView(int64_t view_id,
                                ViewCallback on_view_created,
                                FlatlandViewCreatedCallback on_view_bound,
                                bool hit_testable,
                                bool focusable) {
  FML_CHECK(shell_);
  shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
      [this, view_id, hit_testable, focusable,
       on_view_created = std::move(on_view_created),
       on_view_bound = std::move(on_view_bound)]() {
        FML_CHECK(flatland_view_embedder_);
        flatland_view_embedder_->CreateView(view_id, std::move(on_view_created),
                                            std::move(on_view_bound));
        flatland_view_embedder_->SetViewProperties(view_id, SkRect::MakeEmpty(),
                                                   hit_testable, focusable);
      });
}

void Engine::UpdateView(int64_t view_id,
                        SkRect occlusion_hint,
                        bool hit_testable,
                        bool focusable,
                        bool use_flatland) {
  FML_CHECK(shell_);
  shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
      [this, use_flatland, view_id, occlusion_hint, hit_testable, focusable]() {
        if (use_flatland) {
          FML_CHECK(flatland_view_embedder_);
          flatland_view_embedder_->SetViewProperties(view_id, occlusion_hint,
                                                     hit_testable, focusable);
        } else {
          FML_CHECK(external_view_embedder_);
          external_view_embedder_->SetViewProperties(view_id, occlusion_hint,
                                                     hit_testable, focusable);
        }
      });
}

void Engine::DestroyGfxView(int64_t view_id,
                            GfxViewIdCallback on_view_unbound) {
  FML_CHECK(shell_);

  shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
      [this, view_id, on_view_unbound = std::move(on_view_unbound)]() {
        FML_CHECK(external_view_embedder_);
        external_view_embedder_->DestroyView(view_id,
                                             std::move(on_view_unbound));
      });
}

void Engine::DestroyFlatlandView(int64_t view_id,
                                 FlatlandViewIdCallback on_view_unbound) {
  FML_CHECK(shell_);

  shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
      [this, view_id, on_view_unbound = std::move(on_view_unbound)]() {
        FML_CHECK(flatland_view_embedder_);
        flatland_view_embedder_->DestroyView(view_id,
                                             std::move(on_view_unbound));
      });
}

std::unique_ptr<flutter::Surface> Engine::CreateSurface() {
  return std::make_unique<Surface>(thread_label_, GetExternalViewEmbedder(),
                                   surface_producer_->gr_context());
}

std::shared_ptr<flutter::ExternalViewEmbedder>
Engine::GetExternalViewEmbedder() {
  FML_CHECK(external_view_embedder_ || flatland_view_embedder_);

  if (external_view_embedder_) {
    return external_view_embedder_;
  }
  return flatland_view_embedder_;
}

#if !defined(DART_PRODUCT)
void Engine::WriteProfileToTrace() const {
  Dart_Port main_port = shell_->GetEngine()->GetUIIsolateMainPort();
  char* error = NULL;
  bool success = Dart_WriteProfileToTimeline(main_port, &error);
  if (!success) {
    FML_LOG(ERROR) << "Failed to write Dart profile to trace: " << error;
    free(error);
  }
}
#endif  // !defined(DART_PRODUCT)

void Engine::WarmupSkps(
    fml::BasicTaskRunner* concurrent_task_runner,
    fml::BasicTaskRunner* raster_task_runner,
    std::shared_ptr<SurfaceProducer> surface_producer,
    SkISize size,
    std::shared_ptr<flutter::AssetManager> asset_manager,
    std::optional<const std::vector<std::string>> skp_names,
    std::optional<std::function<void(uint32_t)>> maybe_completion_callback,
    bool synchronous) {
  // Wrap the optional validity checks up in a lambda to simplify the various
  // callsites below
  auto completion_callback = [maybe_completion_callback](uint32_t skp_count) {
    if (maybe_completion_callback.has_value() &&
        maybe_completion_callback.value()) {
      maybe_completion_callback.value()(skp_count);
    }
  };

  // We use this bizzare raw pointer to a smart pointer thing here because we
  // want to keep the surface alive until all gpu work is done and the
  // callbacks skia takes for this are function pointers so we are unable to
  // use a lambda that captures the smart pointer. We need two levels of
  // indirection because it needs to be the same across all invocations of the
  // raster task lambda from a single invocation of WarmupSkps, but be
  // different across different invocations of WarmupSkps (so we cant
  // statically initialialize it in the lambda itself). Basically the result
  // of a mashup of wierd call dynamics, multithreading, and lifecycle
  // management with C style Skia callbacks.
  std::unique_ptr<SurfaceProducerSurface>* skp_warmup_surface =
      new std::unique_ptr<SurfaceProducerSurface>(nullptr);

  // tell concurrent task runner to deserialize all skps available from
  // the asset manager
  concurrent_task_runner->PostTask([raster_task_runner, size,
                                    skp_warmup_surface, surface_producer,
                                    asset_manager, skp_names,
                                    completion_callback, synchronous]() {
    TRACE_DURATION("flutter", "DeserializeSkps");
    std::vector<std::unique_ptr<fml::Mapping>> skp_mappings;
    if (skp_names) {
      for (auto& skp_name : skp_names.value()) {
        auto skp_mapping = asset_manager->GetAsMapping(skp_name);
        if (skp_mapping) {
          skp_mappings.push_back(std::move(skp_mapping));
        } else {
          FML_LOG(ERROR) << "Failed to get mapping for " << skp_name;
        }
      }
    } else {
      skp_mappings = asset_manager->GetAsMappings(".*\\.skp$", "shaders");
    }

    if (skp_mappings.empty()) {
      FML_LOG(WARNING)
          << "Engine::WarmupSkps got zero SKP mappings, returning early";
      completion_callback(0);
      return;
    }

    size_t total_size = 0;
    for (auto& mapping : skp_mappings) {
      total_size += mapping->GetSize();
    }

    FML_LOG(INFO) << "Shader warmup got " << skp_mappings.size()
                  << " skp's with a total size of " << total_size << " bytes";

    std::vector<sk_sp<SkPicture>> pictures;
    unsigned int i = 0;
    for (auto& mapping : skp_mappings) {
      std::unique_ptr<SkMemoryStream> stream =
          SkMemoryStream::MakeDirect(mapping->GetMapping(), mapping->GetSize());
      SkDeserialProcs procs = {0};
      procs.fImageProc = flutter::DeserializeImageWithoutData;
      procs.fTypefaceProc = flutter::DeserializeTypefaceWithoutData;
      sk_sp<SkPicture> picture =
          SkPicture::MakeFromStream(stream.get(), &procs);
      if (!picture) {
        FML_LOG(ERROR) << "Failed to deserialize picture " << i;
        continue;
      }

      // Tell raster task runner to warmup have the compositor
      // context warm up the newly deserialized picture
      raster_task_runner->PostTask([picture, skp_warmup_surface, size,
                                    surface_producer, completion_callback, i,
                                    count = skp_mappings.size(), synchronous] {
        TRACE_DURATION("flutter", "WarmupSkp");
        if (*skp_warmup_surface == nullptr) {
          skp_warmup_surface->reset(
              surface_producer->ProduceOffscreenSurface(size).release());

          if (*skp_warmup_surface == nullptr) {
            FML_LOG(ERROR) << "Failed to create offscreen warmup surface";
            // Tell client that zero shaders were warmed up because warmup
            // failed.
            completion_callback(0);
            return;
          }
        }

        // Do the actual warmup
        (*skp_warmup_surface)
            ->GetSkiaSurface()
            ->getCanvas()
            ->drawPicture(picture);

        if (i == count - 1) {
          // We call this here instead of inside fFinishedProc below because
          // we want to unblock the dart animation code as soon as the
          // raster thread is free to enque work, rather than waiting for
          // the GPU work itself to finish.
          completion_callback(count);
        }

        if (surface_producer->gr_context()) {
          if (i < count - 1) {
            // For all but the last skp we fire and forget
            surface_producer->gr_context()->flushAndSubmit();
          } else {
            // For the last skp we provide a callback that frees the warmup
            // surface and calls the completion callback
            struct GrFlushInfo flush_info;
            flush_info.fFinishedContext = skp_warmup_surface;
            flush_info.fFinishedProc = [](void* skp_warmup_surface) {
              delete static_cast<std::unique_ptr<SurfaceProducerSurface>*>(
                  skp_warmup_surface);
            };

            surface_producer->gr_context()->flush(flush_info);
            surface_producer->gr_context()->submit(synchronous);
          }
        } else {
          if (i == count - 1) {
            delete skp_warmup_surface;
          }
        }
      });
      i++;
    }
  });
}

void Engine::OnLevelChanged(
    fuchsia::memorypressure::Level level,
    fuchsia::memorypressure::Watcher::OnLevelChangedCallback callback) {
  // The callback must be invoked immediately to acknowledge the message.
  // This is the "Throttle push using acknowledgements" pattern:
  // https://fuchsia.dev/fuchsia-src/concepts/api/fidl#throttle_push_using_acknowledgements
  callback();

  FML_LOG(WARNING) << "memorypressure watcher: OnLevelChanged from "
                   << static_cast<int>(latest_memory_pressure_level_) << " to "
                   << static_cast<int>(level);

  if (latest_memory_pressure_level_ == fuchsia::memorypressure::Level::NORMAL &&
      (level == fuchsia::memorypressure::Level::WARNING ||
       level == fuchsia::memorypressure::Level::CRITICAL)) {
    FML_LOG(WARNING)
        << "memorypressure watcher: notifying Flutter that memory is low";
    shell_->NotifyLowMemoryWarning();
  }
  latest_memory_pressure_level_ = level;
}

}  // namespace flutter_runner
