// 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.

#define FML_USED_ON_EMBEDDER
#define RAPIDJSON_HAS_STDSTRING 1

#include <cstring>
#include <iostream>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "flutter/fml/build_config.h"
#include "flutter/fml/closure.h"
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/native_library.h"
#include "third_party/dart/runtime/bin/elf_loader.h"
#include "third_party/dart/runtime/include/dart_native_api.h"

#if !defined(FLUTTER_NO_EXPORT)
#if OS_WIN
#define FLUTTER_EXPORT __declspec(dllexport)
#else  // OS_WIN
#define FLUTTER_EXPORT __attribute__((visibility("default")))
#endif  // OS_WIN
#endif  // !FLUTTER_NO_EXPORT

extern "C" {
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
// Used for debugging dart:* sources.
extern const uint8_t kPlatformStrongDill[];
extern const intptr_t kPlatformStrongDillSize;
#endif  // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
}

#include "flutter/assets/directory_asset_bundle.h"
#include "flutter/common/task_runners.h"
#include "flutter/fml/command_line.h"
#include "flutter/fml/file.h"
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/message_loop.h"
#include "flutter/fml/paths.h"
#include "flutter/fml/trace_event.h"
#include "flutter/shell/common/persistent_cache.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/embedder_engine.h"
#include "flutter/shell/platform/embedder/embedder_platform_message_response.h"
#include "flutter/shell/platform/embedder/embedder_render_target.h"
#include "flutter/shell/platform/embedder/embedder_struct_macros.h"
#include "flutter/shell/platform/embedder/embedder_task_runner.h"
#include "flutter/shell/platform/embedder/embedder_thread_host.h"
#include "flutter/shell/platform/embedder/platform_view_embedder.h"
#include "rapidjson/rapidjson.h"
#include "rapidjson/writer.h"

#ifdef SHELL_ENABLE_GL
#include "flutter/shell/platform/embedder/embedder_external_texture_gl.h"
#endif

const int32_t kFlutterSemanticsNodeIdBatchEnd = -1;
const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1;

static FlutterEngineResult LogEmbedderError(FlutterEngineResult code,
                                            const char* reason,
                                            const char* code_name,
                                            const char* function,
                                            const char* file,
                                            int line) {
#if OS_WIN
  constexpr char kSeparator = '\\';
#else
  constexpr char kSeparator = '/';
#endif
  const auto file_base =
      (::strrchr(file, kSeparator) ? strrchr(file, kSeparator) + 1 : file);
  char error[256] = {};
  snprintf(error, (sizeof(error) / sizeof(char)),
           "%s (%d): '%s' returned '%s'. %s", file_base, line, function,
           code_name, reason);
  std::cerr << error << std::endl;
  return code;
}

#define LOG_EMBEDDER_ERROR(code, reason) \
  LogEmbedderError(code, reason, #code, __FUNCTION__, __FILE__, __LINE__)

static bool IsOpenGLRendererConfigValid(const FlutterRendererConfig* config) {
  if (config->type != kOpenGL) {
    return false;
  }

  const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;

  if (!SAFE_EXISTS(open_gl_config, make_current) ||
      !SAFE_EXISTS(open_gl_config, clear_current) ||
      !SAFE_EXISTS_ONE_OF(open_gl_config, fbo_callback,
                          fbo_with_frame_info_callback) ||
      !SAFE_EXISTS_ONE_OF(open_gl_config, present, present_with_info)) {
    return false;
  }

  return true;
}

static bool IsSoftwareRendererConfigValid(const FlutterRendererConfig* config) {
  if (config->type != kSoftware) {
    return false;
  }

  const FlutterSoftwareRendererConfig* software_config = &config->software;

  if (SAFE_ACCESS(software_config, surface_present_callback, nullptr) ==
      nullptr) {
    return false;
  }

  return true;
}

static bool IsRendererValid(const FlutterRendererConfig* config) {
  if (config == nullptr) {
    return false;
  }

  switch (config->type) {
    case kOpenGL:
      return IsOpenGLRendererConfigValid(config);
    case kSoftware:
      return IsSoftwareRendererConfigValid(config);
    default:
      return false;
  }

  return false;
}

#if OS_LINUX || OS_WIN
static void* DefaultGLProcResolver(const char* name) {
  static fml::RefPtr<fml::NativeLibrary> proc_library =
#if OS_LINUX
      fml::NativeLibrary::CreateForCurrentProcess();
#elif OS_WIN  // OS_LINUX
      fml::NativeLibrary::Create("opengl32.dll");
#endif        // OS_WIN
  return static_cast<void*>(
      const_cast<uint8_t*>(proc_library->ResolveSymbol(name)));
}
#endif  // OS_LINUX || OS_WIN

static flutter::Shell::CreateCallback<flutter::PlatformView>
InferOpenGLPlatformViewCreationCallback(
    const FlutterRendererConfig* config,
    void* user_data,
    flutter::PlatformViewEmbedder::PlatformDispatchTable
        platform_dispatch_table,
    std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
        external_view_embedder) {
#ifdef SHELL_ENABLE_GL
  if (config->type != kOpenGL) {
    return nullptr;
  }

  auto gl_make_current = [ptr = config->open_gl.make_current,
                          user_data]() -> bool { return ptr(user_data); };

  auto gl_clear_current = [ptr = config->open_gl.clear_current,
                           user_data]() -> bool { return ptr(user_data); };

  auto gl_present = [present = config->open_gl.present,
                     present_with_info = config->open_gl.present_with_info,
                     user_data](uint32_t fbo_id) -> bool {
    if (present) {
      return present(user_data);
    } else {
      FlutterPresentInfo present_info = {};
      present_info.struct_size = sizeof(FlutterPresentInfo);
      present_info.fbo_id = fbo_id;
      return present_with_info(user_data, &present_info);
    }
  };

  auto gl_fbo_callback =
      [fbo_callback = config->open_gl.fbo_callback,
       fbo_with_frame_info_callback =
           config->open_gl.fbo_with_frame_info_callback,
       user_data](flutter::GLFrameInfo gl_frame_info) -> intptr_t {
    if (fbo_callback) {
      return fbo_callback(user_data);
    } else {
      FlutterFrameInfo frame_info = {};
      frame_info.struct_size = sizeof(FlutterFrameInfo);
      frame_info.size = {gl_frame_info.width, gl_frame_info.height};
      return fbo_with_frame_info_callback(user_data, &frame_info);
    }
  };

  const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
  std::function<bool()> gl_make_resource_current_callback = nullptr;
  if (SAFE_ACCESS(open_gl_config, make_resource_current, nullptr) != nullptr) {
    gl_make_resource_current_callback =
        [ptr = config->open_gl.make_resource_current, user_data]() {
          return ptr(user_data);
        };
  }

  std::function<SkMatrix(void)> gl_surface_transformation_callback = nullptr;
  if (SAFE_ACCESS(open_gl_config, surface_transformation, nullptr) != nullptr) {
    gl_surface_transformation_callback =
        [ptr = config->open_gl.surface_transformation, user_data]() {
          FlutterTransformation transformation = ptr(user_data);
          return SkMatrix::MakeAll(transformation.scaleX,  //
                                   transformation.skewX,   //
                                   transformation.transX,  //
                                   transformation.skewY,   //
                                   transformation.scaleY,  //
                                   transformation.transY,  //
                                   transformation.pers0,   //
                                   transformation.pers1,   //
                                   transformation.pers2    //
          );
        };

    // If there is an external view embedder, ask it to apply the surface
    // transformation to its surfaces as well.
    if (external_view_embedder) {
      external_view_embedder->SetSurfaceTransformationCallback(
          gl_surface_transformation_callback);
    }
  }

  flutter::GPUSurfaceGLDelegate::GLProcResolver gl_proc_resolver = nullptr;
  if (SAFE_ACCESS(open_gl_config, gl_proc_resolver, nullptr) != nullptr) {
    gl_proc_resolver = [ptr = config->open_gl.gl_proc_resolver,
                        user_data](const char* gl_proc_name) {
      return ptr(user_data, gl_proc_name);
    };
  } else {
#if OS_LINUX || OS_WIN
    gl_proc_resolver = DefaultGLProcResolver;
#endif
  }

  bool fbo_reset_after_present =
      SAFE_ACCESS(open_gl_config, fbo_reset_after_present, false);

  flutter::EmbedderSurfaceGL::GLDispatchTable gl_dispatch_table = {
      gl_make_current,                     // gl_make_current_callback
      gl_clear_current,                    // gl_clear_current_callback
      gl_present,                          // gl_present_callback
      gl_fbo_callback,                     // gl_fbo_callback
      gl_make_resource_current_callback,   // gl_make_resource_current_callback
      gl_surface_transformation_callback,  // gl_surface_transformation_callback
      gl_proc_resolver,                    // gl_proc_resolver
  };

  return fml::MakeCopyable(
      [gl_dispatch_table, fbo_reset_after_present, platform_dispatch_table,
       external_view_embedder =
           std::move(external_view_embedder)](flutter::Shell& shell) mutable {
        return std::make_unique<flutter::PlatformViewEmbedder>(
            shell,                    // delegate
            shell.GetTaskRunners(),   // task runners
            gl_dispatch_table,        // embedder GL dispatch table
            fbo_reset_after_present,  // fbo reset after present
            platform_dispatch_table,  // embedder platform dispatch table
            std::move(external_view_embedder)  // external view embedder
        );
      });
#else
  return nullptr;
#endif
}

static flutter::Shell::CreateCallback<flutter::PlatformView>
InferSoftwarePlatformViewCreationCallback(
    const FlutterRendererConfig* config,
    void* user_data,
    flutter::PlatformViewEmbedder::PlatformDispatchTable
        platform_dispatch_table,
    std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
        external_view_embedder) {
  if (config->type != kSoftware) {
    return nullptr;
  }

  auto software_present_backing_store =
      [ptr = config->software.surface_present_callback, user_data](
          const void* allocation, size_t row_bytes, size_t height) -> bool {
    return ptr(user_data, allocation, row_bytes, height);
  };

  flutter::EmbedderSurfaceSoftware::SoftwareDispatchTable
      software_dispatch_table = {
          software_present_backing_store,  // required
      };

  return fml::MakeCopyable(
      [software_dispatch_table, platform_dispatch_table,
       external_view_embedder =
           std::move(external_view_embedder)](flutter::Shell& shell) mutable {
        return std::make_unique<flutter::PlatformViewEmbedder>(
            shell,                             // delegate
            shell.GetTaskRunners(),            // task runners
            software_dispatch_table,           // software dispatch table
            platform_dispatch_table,           // platform dispatch table
            std::move(external_view_embedder)  // external view embedder
        );
      });
}

static flutter::Shell::CreateCallback<flutter::PlatformView>
InferPlatformViewCreationCallback(
    const FlutterRendererConfig* config,
    void* user_data,
    flutter::PlatformViewEmbedder::PlatformDispatchTable
        platform_dispatch_table,
    std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
        external_view_embedder) {
  if (config == nullptr) {
    return nullptr;
  }

  switch (config->type) {
    case kOpenGL:
      return InferOpenGLPlatformViewCreationCallback(
          config, user_data, platform_dispatch_table,
          std::move(external_view_embedder));
    case kSoftware:
      return InferSoftwarePlatformViewCreationCallback(
          config, user_data, platform_dispatch_table,
          std::move(external_view_embedder));
    default:
      return nullptr;
  }
  return nullptr;
}

static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
    GrDirectContext* context,
    const FlutterBackingStoreConfig& config,
    const FlutterOpenGLTexture* texture) {
#ifdef SHELL_ENABLE_GL
  GrGLTextureInfo texture_info;
  texture_info.fTarget = texture->target;
  texture_info.fID = texture->name;
  texture_info.fFormat = texture->format;

  GrBackendTexture backend_texture(config.size.width,   //
                                   config.size.height,  //
                                   GrMipMapped::kNo,    //
                                   texture_info         //
  );

  SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);

  auto surface = SkSurface::MakeFromBackendTexture(
      context,                      // context
      backend_texture,              // back-end texture
      kBottomLeft_GrSurfaceOrigin,  // surface origin
      1,                            // sample count
      kN32_SkColorType,             // color type
      SkColorSpace::MakeSRGB(),     // color space
      &surface_properties,          // surface properties
      static_cast<SkSurface::TextureReleaseProc>(
          texture->destruction_callback),  // release proc
      texture->user_data                   // release context
  );

  if (!surface) {
    FML_LOG(ERROR) << "Could not wrap embedder supplied render texture.";
    texture->destruction_callback(texture->user_data);
    return nullptr;
  }

  return surface;
#else
  return nullptr;
#endif
}

static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
    GrDirectContext* context,
    const FlutterBackingStoreConfig& config,
    const FlutterOpenGLFramebuffer* framebuffer) {
#ifdef SHELL_ENABLE_GL
  GrGLFramebufferInfo framebuffer_info = {};
  framebuffer_info.fFormat = framebuffer->target;
  framebuffer_info.fFBOID = framebuffer->name;

  GrBackendRenderTarget backend_render_target(
      config.size.width,   // width
      config.size.height,  // height
      1,                   // sample count
      0,                   // stencil bits
      framebuffer_info     // framebuffer info
  );

  SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);

  auto surface = SkSurface::MakeFromBackendRenderTarget(
      context,                      //  context
      backend_render_target,        // backend render target
      kBottomLeft_GrSurfaceOrigin,  // surface origin
      kN32_SkColorType,             // color type
      SkColorSpace::MakeSRGB(),     // color space
      &surface_properties,          // surface properties
      static_cast<SkSurface::RenderTargetReleaseProc>(
          framebuffer->destruction_callback),  // release proc
      framebuffer->user_data                   // release context
  );

  if (!surface) {
    FML_LOG(ERROR) << "Could not wrap embedder supplied frame-buffer.";
    framebuffer->destruction_callback(framebuffer->user_data);
    return nullptr;
  }
  return surface;
#else
  return nullptr;
#endif
}

static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
    GrDirectContext* context,
    const FlutterBackingStoreConfig& config,
    const FlutterSoftwareBackingStore* software) {
  const auto image_info =
      SkImageInfo::MakeN32Premul(config.size.width, config.size.height);

  struct Captures {
    VoidCallback destruction_callback;
    void* user_data;
  };
  auto captures = std::make_unique<Captures>();
  captures->destruction_callback = software->destruction_callback;
  captures->user_data = software->user_data;
  auto release_proc = [](void* pixels, void* context) {
    auto captures = reinterpret_cast<Captures*>(context);
    captures->destruction_callback(captures->user_data);
  };

  auto surface = SkSurface::MakeRasterDirectReleaseProc(
      image_info,                               // image info
      const_cast<void*>(software->allocation),  // pixels
      software->row_bytes,                      // row bytes
      release_proc,                             // release proc
      captures.release()                        // release context
  );

  if (!surface) {
    FML_LOG(ERROR)
        << "Could not wrap embedder supplied software render buffer.";
    software->destruction_callback(software->user_data);
    return nullptr;
  }
  return surface;
}

static std::unique_ptr<flutter::EmbedderRenderTarget>
CreateEmbedderRenderTarget(const FlutterCompositor* compositor,
                           const FlutterBackingStoreConfig& config,
                           GrDirectContext* context) {
  FlutterBackingStore backing_store = {};
  backing_store.struct_size = sizeof(backing_store);

  // Safe access checks on the compositor struct have been performed in
  // InferExternalViewEmbedderFromArgs and are not necessary here.
  auto c_create_callback = compositor->create_backing_store_callback;
  auto c_collect_callback = compositor->collect_backing_store_callback;

  {
    TRACE_EVENT0("flutter", "FlutterCompositorCreateBackingStore");
    if (!c_create_callback(&config, &backing_store, compositor->user_data)) {
      FML_LOG(ERROR) << "Could not create the embedder backing store.";
      return nullptr;
    }
  }

  if (backing_store.struct_size != sizeof(backing_store)) {
    FML_LOG(ERROR) << "Embedder modified the backing store struct size.";
    return nullptr;
  }

  // In case we return early without creating an embedder render target, the
  // embedder has still given us ownership of its baton which we must return
  // back to it. If this method is successful, the closure is released when the
  // render target is eventually released.
  fml::ScopedCleanupClosure collect_callback(
      [c_collect_callback, backing_store, user_data = compositor->user_data]() {
        TRACE_EVENT0("flutter", "FlutterCompositorCollectBackingStore");
        c_collect_callback(&backing_store, user_data);
      });

  // No safe access checks on the renderer are necessary since we allocated
  // the struct.

  sk_sp<SkSurface> render_surface;

  switch (backing_store.type) {
    case kFlutterBackingStoreTypeOpenGL:
      switch (backing_store.open_gl.type) {
        case kFlutterOpenGLTargetTypeTexture:
          render_surface = MakeSkSurfaceFromBackingStore(
              context, config, &backing_store.open_gl.texture);
          break;
        case kFlutterOpenGLTargetTypeFramebuffer:
          render_surface = MakeSkSurfaceFromBackingStore(
              context, config, &backing_store.open_gl.framebuffer);
          break;
      }
      break;
    case kFlutterBackingStoreTypeSoftware:
      render_surface = MakeSkSurfaceFromBackingStore(context, config,
                                                     &backing_store.software);
      break;
  };

  if (!render_surface) {
    FML_LOG(ERROR) << "Could not create a surface from an embedder provided "
                      "render target.";
    return nullptr;
  }

  return std::make_unique<flutter::EmbedderRenderTarget>(
      backing_store, std::move(render_surface), collect_callback.Release());
}

static std::pair<std::unique_ptr<flutter::EmbedderExternalViewEmbedder>,
                 bool /* halt engine launch if true */>
InferExternalViewEmbedderFromArgs(const FlutterCompositor* compositor) {
  if (compositor == nullptr) {
    return {nullptr, false};
  }

  auto c_create_callback =
      SAFE_ACCESS(compositor, create_backing_store_callback, nullptr);
  auto c_collect_callback =
      SAFE_ACCESS(compositor, collect_backing_store_callback, nullptr);
  auto c_present_callback =
      SAFE_ACCESS(compositor, present_layers_callback, nullptr);

  // Make sure the required callbacks are present
  if (!c_create_callback || !c_collect_callback || !c_present_callback) {
    FML_LOG(ERROR) << "Required compositor callbacks absent.";
    return {nullptr, true};
  }

  FlutterCompositor captured_compositor = *compositor;

  flutter::EmbedderExternalViewEmbedder::CreateRenderTargetCallback
      create_render_target_callback =
          [captured_compositor](GrDirectContext* context, const auto& config) {
            return CreateEmbedderRenderTarget(&captured_compositor, config,
                                              context);
          };

  flutter::EmbedderExternalViewEmbedder::PresentCallback present_callback =
      [c_present_callback,
       user_data = compositor->user_data](const auto& layers) {
        TRACE_EVENT0("flutter", "FlutterCompositorPresentLayers");
        return c_present_callback(
            const_cast<const FlutterLayer**>(layers.data()), layers.size(),
            user_data);
      };

  return {std::make_unique<flutter::EmbedderExternalViewEmbedder>(
              create_render_target_callback, present_callback),
          false};
}

struct _FlutterPlatformMessageResponseHandle {
  fml::RefPtr<flutter::PlatformMessage> message;
};

struct LoadedElfDeleter {
  void operator()(Dart_LoadedElf* elf) {
    if (elf) {
      ::Dart_UnloadELF(elf);
    }
  }
};

using UniqueLoadedElf = std::unique_ptr<Dart_LoadedElf, LoadedElfDeleter>;

struct _FlutterEngineAOTData {
  UniqueLoadedElf loaded_elf = nullptr;
  const uint8_t* vm_snapshot_data = nullptr;
  const uint8_t* vm_snapshot_instrs = nullptr;
  const uint8_t* vm_isolate_data = nullptr;
  const uint8_t* vm_isolate_instrs = nullptr;
};

FlutterEngineResult FlutterEngineCreateAOTData(
    const FlutterEngineAOTDataSource* source,
    FlutterEngineAOTData* data_out) {
  if (!flutter::DartVM::IsRunningPrecompiledCode()) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "AOT data can only be created in AOT mode.");
  } else if (!source) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null source specified.");
  } else if (!data_out) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null data_out specified.");
  }

  switch (source->type) {
    case kFlutterEngineAOTDataSourceTypeElfPath: {
      if (!source->elf_path || !fml::IsFile(source->elf_path)) {
        return LOG_EMBEDDER_ERROR(kInvalidArguments,
                                  "Invalid ELF path specified.");
      }

      auto aot_data = std::make_unique<_FlutterEngineAOTData>();
      const char* error = nullptr;

#if OS_FUCHSIA
      // TODO(gw280): https://github.com/flutter/flutter/issues/50285
      // Dart doesn't implement Dart_LoadELF on Fuchsia
      Dart_LoadedElf* loaded_elf = nullptr;
#else
      Dart_LoadedElf* loaded_elf = Dart_LoadELF(
          source->elf_path,               // file path
          0,                              // file offset
          &error,                         // error (out)
          &aot_data->vm_snapshot_data,    // vm snapshot data (out)
          &aot_data->vm_snapshot_instrs,  // vm snapshot instr (out)
          &aot_data->vm_isolate_data,     // vm isolate data (out)
          &aot_data->vm_isolate_instrs    // vm isolate instr (out)
      );
#endif

      if (loaded_elf == nullptr) {
        return LOG_EMBEDDER_ERROR(kInvalidArguments, error);
      }

      aot_data->loaded_elf.reset(loaded_elf);

      *data_out = aot_data.release();
      return kSuccess;
    }
  }

  return LOG_EMBEDDER_ERROR(
      kInvalidArguments,
      "Invalid FlutterEngineAOTDataSourceType type specified.");
}

FlutterEngineResult FlutterEngineCollectAOTData(FlutterEngineAOTData data) {
  if (!data) {
    // Deleting a null object should be a no-op.
    return kSuccess;
  }

  // Created in a unique pointer in `FlutterEngineCreateAOTData`.
  delete data;
  return kSuccess;
}

void PopulateSnapshotMappingCallbacks(
    const FlutterProjectArgs* args,
    flutter::Settings& settings) {  // NOLINT(google-runtime-references)
  // There are no ownership concerns here as all mappings are owned by the
  // embedder and not the engine.
  auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
    return [mapping, size]() {
      return std::make_unique<fml::NonOwnedMapping>(mapping, size);
    };
  };

  if (flutter::DartVM::IsRunningPrecompiledCode()) {
    if (SAFE_ACCESS(args, aot_data, nullptr) != nullptr) {
      settings.vm_snapshot_data =
          make_mapping_callback(args->aot_data->vm_snapshot_data, 0);

      settings.vm_snapshot_instr =
          make_mapping_callback(args->aot_data->vm_snapshot_instrs, 0);

      settings.isolate_snapshot_data =
          make_mapping_callback(args->aot_data->vm_isolate_data, 0);

      settings.isolate_snapshot_instr =
          make_mapping_callback(args->aot_data->vm_isolate_instrs, 0);
    }

    if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) != nullptr) {
      settings.vm_snapshot_data = make_mapping_callback(
          args->vm_snapshot_data, SAFE_ACCESS(args, vm_snapshot_data_size, 0));
    }

    if (SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) != nullptr) {
      settings.vm_snapshot_instr = make_mapping_callback(
          args->vm_snapshot_instructions,
          SAFE_ACCESS(args, vm_snapshot_instructions_size, 0));
    }

    if (SAFE_ACCESS(args, isolate_snapshot_data, nullptr) != nullptr) {
      settings.isolate_snapshot_data = make_mapping_callback(
          args->isolate_snapshot_data,
          SAFE_ACCESS(args, isolate_snapshot_data_size, 0));
    }

    if (SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr) != nullptr) {
      settings.isolate_snapshot_instr = make_mapping_callback(
          args->isolate_snapshot_instructions,
          SAFE_ACCESS(args, isolate_snapshot_instructions_size, 0));
    }
  }

#if !OS_FUCHSIA && (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
  settings.dart_library_sources_kernel =
      make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize);
#endif  // !OS_FUCHSIA && (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
}

FlutterEngineResult FlutterEngineRun(size_t version,
                                     const FlutterRendererConfig* config,
                                     const FlutterProjectArgs* args,
                                     void* user_data,
                                     FLUTTER_API_SYMBOL(FlutterEngine) *
                                         engine_out) {
  auto result =
      FlutterEngineInitialize(version, config, args, user_data, engine_out);

  if (result != kSuccess) {
    return result;
  }

  return FlutterEngineRunInitialized(*engine_out);
}

FlutterEngineResult FlutterEngineInitialize(size_t version,
                                            const FlutterRendererConfig* config,
                                            const FlutterProjectArgs* args,
                                            void* user_data,
                                            FLUTTER_API_SYMBOL(FlutterEngine) *
                                                engine_out) {
  // Step 0: Figure out arguments for shell creation.
  if (version != FLUTTER_ENGINE_VERSION) {
    return LOG_EMBEDDER_ERROR(
        kInvalidLibraryVersion,
        "Flutter embedder version mismatch. There has been a breaking change. "
        "Please consult the changelog and update the embedder.");
  }

  if (engine_out == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "The engine out parameter was missing.");
  }

  if (args == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "The Flutter project arguments were missing.");
  }

  if (SAFE_ACCESS(args, assets_path, nullptr) == nullptr) {
    return LOG_EMBEDDER_ERROR(
        kInvalidArguments,
        "The assets path in the Flutter project arguments was missing.");
  }

  if (SAFE_ACCESS(args, main_path__unused__, nullptr) != nullptr) {
    FML_LOG(WARNING)
        << "FlutterProjectArgs.main_path is deprecated and should be set null.";
  }

  if (SAFE_ACCESS(args, packages_path__unused__, nullptr) != nullptr) {
    FML_LOG(WARNING) << "FlutterProjectArgs.packages_path is deprecated and "
                        "should be set null.";
  }

  if (!IsRendererValid(config)) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "The renderer configuration was invalid.");
  }

  std::string icu_data_path;
  if (SAFE_ACCESS(args, icu_data_path, nullptr) != nullptr) {
    icu_data_path = SAFE_ACCESS(args, icu_data_path, nullptr);
  }

  if (SAFE_ACCESS(args, persistent_cache_path, nullptr) != nullptr) {
    std::string persistent_cache_path =
        SAFE_ACCESS(args, persistent_cache_path, nullptr);
    flutter::PersistentCache::SetCacheDirectoryPath(persistent_cache_path);
  }

  if (SAFE_ACCESS(args, is_persistent_cache_read_only, false)) {
    flutter::PersistentCache::gIsReadOnly = true;
  }

  fml::CommandLine command_line;
  if (SAFE_ACCESS(args, command_line_argc, 0) != 0 &&
      SAFE_ACCESS(args, command_line_argv, nullptr) != nullptr) {
    command_line = fml::CommandLineFromArgcArgv(
        SAFE_ACCESS(args, command_line_argc, 0),
        SAFE_ACCESS(args, command_line_argv, nullptr));
  }

  flutter::Settings settings = flutter::SettingsFromCommandLine(command_line);

  if (SAFE_ACCESS(args, aot_data, nullptr)) {
    if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) ||
        SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) ||
        SAFE_ACCESS(args, isolate_snapshot_data, nullptr) ||
        SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr)) {
      return LOG_EMBEDDER_ERROR(
          kInvalidArguments,
          "Multiple AOT sources specified. Embedders should provide either "
          "*_snapshot_* buffers or aot_data, not both.");
    }
  }

  PopulateSnapshotMappingCallbacks(args, settings);

  settings.icu_data_path = icu_data_path;
  settings.assets_path = args->assets_path;
  settings.leak_vm = !SAFE_ACCESS(args, shutdown_dart_vm_when_done, false);
  settings.old_gen_heap_size = SAFE_ACCESS(args, dart_old_gen_heap_size, -1);

  if (!flutter::DartVM::IsRunningPrecompiledCode()) {
    // Verify the assets path contains Dart 2 kernel assets.
    const std::string kApplicationKernelSnapshotFileName = "kernel_blob.bin";
    std::string application_kernel_path = fml::paths::JoinPaths(
        {settings.assets_path, kApplicationKernelSnapshotFileName});
    if (!fml::IsFile(application_kernel_path)) {
      return LOG_EMBEDDER_ERROR(
          kInvalidArguments,
          "Not running in AOT mode but could not resolve the kernel binary.");
    }
    settings.application_kernel_asset = kApplicationKernelSnapshotFileName;
  }

  settings.task_observer_add = [](intptr_t key, fml::closure callback) {
    fml::MessageLoop::GetCurrent().AddTaskObserver(key, std::move(callback));
  };
  settings.task_observer_remove = [](intptr_t key) {
    fml::MessageLoop::GetCurrent().RemoveTaskObserver(key);
  };
  if (SAFE_ACCESS(args, root_isolate_create_callback, nullptr) != nullptr) {
    VoidCallback callback =
        SAFE_ACCESS(args, root_isolate_create_callback, nullptr);
    settings.root_isolate_create_callback =
        [callback, user_data](const auto& isolate) { callback(user_data); };
  }

  flutter::PlatformViewEmbedder::UpdateSemanticsNodesCallback
      update_semantics_nodes_callback = nullptr;
  if (SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr) {
    update_semantics_nodes_callback =
        [ptr = args->update_semantics_node_callback,
         user_data](flutter::SemanticsNodeUpdates update) {
          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[0],
                &node.childrenInHitTestOrder[0],
                node.customAccessibilityActions.size(),
                &node.customAccessibilityActions[0],
                node.platformViewId,
            };
            ptr(&embedder_node, user_data);
          }
          const FlutterSemanticsNode batch_end_sentinel = {
              sizeof(FlutterSemanticsNode),
              kFlutterSemanticsNodeIdBatchEnd,
          };
          ptr(&batch_end_sentinel, user_data);
        };
  }

  flutter::PlatformViewEmbedder::UpdateSemanticsCustomActionsCallback
      update_semantics_custom_actions_callback = nullptr;
  if (SAFE_ACCESS(args, update_semantics_custom_action_callback, nullptr) !=
      nullptr) {
    update_semantics_custom_actions_callback =
        [ptr = args->update_semantics_custom_action_callback,
         user_data](flutter::CustomAccessibilityActionUpdates actions) {
          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(),
            };
            ptr(&embedder_action, user_data);
          }
          const FlutterSemanticsCustomAction batch_end_sentinel = {
              sizeof(FlutterSemanticsCustomAction),
              kFlutterSemanticsCustomActionIdBatchEnd,
          };
          ptr(&batch_end_sentinel, user_data);
        };
  }

  flutter::PlatformViewEmbedder::PlatformMessageResponseCallback
      platform_message_response_callback = nullptr;
  if (SAFE_ACCESS(args, platform_message_callback, nullptr) != nullptr) {
    platform_message_response_callback =
        [ptr = args->platform_message_callback,
         user_data](fml::RefPtr<flutter::PlatformMessage> message) {
          auto handle = new FlutterPlatformMessageResponseHandle();
          const FlutterPlatformMessage incoming_message = {
              sizeof(FlutterPlatformMessage),  // struct_size
              message->channel().c_str(),      // channel
              message->data().data(),          // message
              message->data().size(),          // message_size
              handle,                          // response_handle
          };
          handle->message = std::move(message);
          return ptr(&incoming_message, user_data);
        };
  }

  flutter::VsyncWaiterEmbedder::VsyncCallback vsync_callback = nullptr;
  if (SAFE_ACCESS(args, vsync_callback, nullptr) != nullptr) {
    vsync_callback = [ptr = args->vsync_callback, user_data](intptr_t baton) {
      return ptr(user_data, baton);
    };
  }

  flutter::PlatformViewEmbedder::ComputePlatformResolvedLocaleCallback
      compute_platform_resolved_locale_callback = nullptr;
  if (SAFE_ACCESS(args, compute_platform_resolved_locale_callback, nullptr) !=
      nullptr) {
    compute_platform_resolved_locale_callback =
        [ptr = args->compute_platform_resolved_locale_callback](
            const std::vector<std::string>& supported_locales_data) {
          const size_t number_of_strings_per_locale = 3;
          size_t locale_count =
              supported_locales_data.size() / number_of_strings_per_locale;
          std::vector<FlutterLocale> supported_locales;
          std::vector<const FlutterLocale*> supported_locales_ptr;
          for (size_t i = 0; i < locale_count; ++i) {
            supported_locales.push_back(
                {.struct_size = sizeof(FlutterLocale),
                 .language_code =
                     supported_locales_data[i * number_of_strings_per_locale +
                                            0]
                         .c_str(),
                 .country_code =
                     supported_locales_data[i * number_of_strings_per_locale +
                                            1]
                         .c_str(),
                 .script_code =
                     supported_locales_data[i * number_of_strings_per_locale +
                                            2]
                         .c_str(),
                 .variant_code = nullptr});
            supported_locales_ptr.push_back(&supported_locales[i]);
          }

          const FlutterLocale* result =
              ptr(supported_locales_ptr.data(), locale_count);

          std::unique_ptr<std::vector<std::string>> out =
              std::make_unique<std::vector<std::string>>();
          if (result) {
            std::string language_code(SAFE_ACCESS(result, language_code, ""));
            if (language_code != "") {
              out->push_back(language_code);
              out->emplace_back(SAFE_ACCESS(result, country_code, ""));
              out->emplace_back(SAFE_ACCESS(result, script_code, ""));
            }
          }
          return out;
        };
  }

  auto external_view_embedder_result =
      InferExternalViewEmbedderFromArgs(SAFE_ACCESS(args, compositor, nullptr));
  if (external_view_embedder_result.second) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "Compositor arguments were invalid.");
  }

  flutter::PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table =
      {
          update_semantics_nodes_callback,            //
          update_semantics_custom_actions_callback,   //
          platform_message_response_callback,         //
          vsync_callback,                             //
          compute_platform_resolved_locale_callback,  //
      };

  auto on_create_platform_view = InferPlatformViewCreationCallback(
      config, user_data, platform_dispatch_table,
      std::move(external_view_embedder_result.first));

  if (!on_create_platform_view) {
    return LOG_EMBEDDER_ERROR(
        kInternalInconsistency,
        "Could not infer platform view creation callback.");
  }

  flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer =
      [](flutter::Shell& shell) {
        return std::make_unique<flutter::Rasterizer>(shell);
      };

#ifdef SHELL_ENABLE_GL
  // TODO(chinmaygarde): This is the wrong spot for this. It belongs in the
  // platform view jump table.
  flutter::EmbedderExternalTextureGL::ExternalTextureCallback
      external_texture_callback;
  if (config->type == kOpenGL) {
    const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
    if (SAFE_ACCESS(open_gl_config, gl_external_texture_frame_callback,
                    nullptr) != nullptr) {
      external_texture_callback =
          [ptr = open_gl_config->gl_external_texture_frame_callback, user_data](
              int64_t texture_identifier, GrDirectContext* context,
              const SkISize& size) -> sk_sp<SkImage> {
        FlutterOpenGLTexture texture = {};

        if (!ptr(user_data, texture_identifier, size.width(), size.height(),
                 &texture)) {
          return nullptr;
        }

        GrGLTextureInfo gr_texture_info = {texture.target, texture.name,
                                           texture.format};

        size_t width = size.width();
        size_t height = size.height();

        if (texture.width != 0 && texture.height != 0) {
          width = texture.width;
          height = texture.height;
        }

        GrBackendTexture gr_backend_texture(width, height, GrMipMapped::kNo,
                                            gr_texture_info);
        SkImage::TextureReleaseProc release_proc = texture.destruction_callback;
        auto image = SkImage::MakeFromTexture(
            context,                   // context
            gr_backend_texture,        // texture handle
            kTopLeft_GrSurfaceOrigin,  // origin
            kRGBA_8888_SkColorType,    // color type
            kPremul_SkAlphaType,       // alpha type
            nullptr,                   // colorspace
            release_proc,              // texture release proc
            texture.user_data          // texture release context
        );

        if (!image) {
          // In case Skia rejects the image, call the release proc so that
          // embedders can perform collection of intermediates.
          if (release_proc) {
            release_proc(texture.user_data);
          }
          FML_LOG(ERROR) << "Could not create external texture.";
          return nullptr;
        }

        return image;
      };
    }
  }
#endif

  auto thread_host =
      flutter::EmbedderThreadHost::CreateEmbedderOrEngineManagedThreadHost(
          SAFE_ACCESS(args, custom_task_runners, nullptr));

  if (!thread_host || !thread_host->IsValid()) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "Could not setup or infer thread configuration "
                              "to run the Flutter engine on.");
  }

  auto task_runners = thread_host->GetTaskRunners();

  if (!task_runners.IsValid()) {
    return LOG_EMBEDDER_ERROR(kInternalInconsistency,
                              "Task runner configuration was invalid.");
  }

  auto run_configuration =
      flutter::RunConfiguration::InferFromSettings(settings);

  if (SAFE_ACCESS(args, custom_dart_entrypoint, nullptr) != nullptr) {
    auto dart_entrypoint = std::string{args->custom_dart_entrypoint};
    if (dart_entrypoint.size() != 0) {
      run_configuration.SetEntrypoint(std::move(dart_entrypoint));
    }
  }

  if (SAFE_ACCESS(args, dart_entrypoint_argc, 0) > 0) {
    if (SAFE_ACCESS(args, dart_entrypoint_argv, nullptr) == nullptr) {
      return LOG_EMBEDDER_ERROR(kInvalidArguments,
                                "Could not determine Dart entrypoint arguments "
                                "as dart_entrypoint_argc "
                                "was set, but dart_entrypoint_argv was null.");
    }
    std::vector<std::string> arguments(args->dart_entrypoint_argc);
    for (int i = 0; i < args->dart_entrypoint_argc; ++i) {
      arguments[i] = std::string{args->dart_entrypoint_argv[i]};
    }
    settings.dart_entrypoint_args = std::move(arguments);
  }

  if (!run_configuration.IsValid()) {
    return LOG_EMBEDDER_ERROR(
        kInvalidArguments,
        "Could not infer the Flutter project to run from given arguments.");
  }

  // Create the engine but don't launch the shell or run the root isolate.
  auto embedder_engine = std::make_unique<flutter::EmbedderEngine>(
      std::move(thread_host),        //
      std::move(task_runners),       //
      std::move(settings),           //
      std::move(run_configuration),  //
      on_create_platform_view,       //
      on_create_rasterizer           //
#ifdef SHELL_ENABLE_GL
      ,
      external_texture_callback  //
#endif
  );

  // Release the ownership of the embedder engine to the caller.
  *engine_out = reinterpret_cast<FLUTTER_API_SYMBOL(FlutterEngine)>(
      embedder_engine.release());
  return kSuccess;
}

FlutterEngineResult FlutterEngineRunInitialized(
    FLUTTER_API_SYMBOL(FlutterEngine) engine) {
  if (!engine) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
  }

  auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);

  // The engine must not already be running. Initialize may only be called
  // once on an engine instance.
  if (embedder_engine->IsValid()) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
  }

  // Step 1: Launch the shell.
  if (!embedder_engine->LaunchShell()) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "Could not launch the engine using supplied "
                              "initialization arguments.");
  }

  // Step 2: Tell the platform view to initialize itself.
  if (!embedder_engine->NotifyCreated()) {
    return LOG_EMBEDDER_ERROR(kInternalInconsistency,
                              "Could not create platform view components.");
  }

  // Step 3: Launch the root isolate.
  if (!embedder_engine->RunRootIsolate()) {
    return LOG_EMBEDDER_ERROR(
        kInvalidArguments,
        "Could not run the root isolate of the Flutter application using the "
        "project arguments specified.");
  }

  return kSuccess;
}

FLUTTER_EXPORT
FlutterEngineResult FlutterEngineDeinitialize(FLUTTER_API_SYMBOL(FlutterEngine)
                                                  engine) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
  }

  auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
  embedder_engine->NotifyDestroyed();
  embedder_engine->CollectShell();
  return kSuccess;
}

FlutterEngineResult FlutterEngineShutdown(FLUTTER_API_SYMBOL(FlutterEngine)
                                              engine) {
  auto result = FlutterEngineDeinitialize(engine);
  if (result != kSuccess) {
    return result;
  }
  auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
  delete embedder_engine;
  return kSuccess;
}

FlutterEngineResult FlutterEngineSendWindowMetricsEvent(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    const FlutterWindowMetricsEvent* flutter_metrics) {
  if (engine == nullptr || flutter_metrics == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
  }

  flutter::ViewportMetrics metrics;

  metrics.physical_width = SAFE_ACCESS(flutter_metrics, width, 0.0);
  metrics.physical_height = SAFE_ACCESS(flutter_metrics, height, 0.0);
  metrics.device_pixel_ratio = SAFE_ACCESS(flutter_metrics, pixel_ratio, 1.0);

  if (metrics.device_pixel_ratio <= 0.0) {
    return LOG_EMBEDDER_ERROR(
        kInvalidArguments,
        "Device pixel ratio was invalid. It must be greater than zero.");
  }

  return reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetViewportMetrics(
             std::move(metrics))
             ? kSuccess
             : LOG_EMBEDDER_ERROR(kInvalidArguments,
                                  "Viewport metrics were invalid.");
}

// Returns the flutter::PointerData::Change for the given FlutterPointerPhase.
inline flutter::PointerData::Change ToPointerDataChange(
    FlutterPointerPhase phase) {
  switch (phase) {
    case kCancel:
      return flutter::PointerData::Change::kCancel;
    case kUp:
      return flutter::PointerData::Change::kUp;
    case kDown:
      return flutter::PointerData::Change::kDown;
    case kMove:
      return flutter::PointerData::Change::kMove;
    case kAdd:
      return flutter::PointerData::Change::kAdd;
    case kRemove:
      return flutter::PointerData::Change::kRemove;
    case kHover:
      return flutter::PointerData::Change::kHover;
  }
  return flutter::PointerData::Change::kCancel;
}

// Returns the flutter::PointerData::DeviceKind for the given
// FlutterPointerDeviceKind.
inline flutter::PointerData::DeviceKind ToPointerDataKind(
    FlutterPointerDeviceKind device_kind) {
  switch (device_kind) {
    case kFlutterPointerDeviceKindMouse:
      return flutter::PointerData::DeviceKind::kMouse;
    case kFlutterPointerDeviceKindTouch:
      return flutter::PointerData::DeviceKind::kTouch;
  }
  return flutter::PointerData::DeviceKind::kMouse;
}

// Returns the flutter::PointerData::SignalKind for the given
// FlutterPointerSignaKind.
inline flutter::PointerData::SignalKind ToPointerDataSignalKind(
    FlutterPointerSignalKind kind) {
  switch (kind) {
    case kFlutterPointerSignalKindNone:
      return flutter::PointerData::SignalKind::kNone;
    case kFlutterPointerSignalKindScroll:
      return flutter::PointerData::SignalKind::kScroll;
  }
  return flutter::PointerData::SignalKind::kNone;
}

// Returns the buttons to synthesize for a PointerData from a
// FlutterPointerEvent with no type or buttons set.
inline int64_t PointerDataButtonsForLegacyEvent(
    flutter::PointerData::Change change) {
  switch (change) {
    case flutter::PointerData::Change::kDown:
    case flutter::PointerData::Change::kMove:
      // These kinds of change must have a non-zero `buttons`, otherwise
      // gesture recognizers will ignore these events.
      return flutter::kPointerButtonMousePrimary;
    case flutter::PointerData::Change::kCancel:
    case flutter::PointerData::Change::kAdd:
    case flutter::PointerData::Change::kRemove:
    case flutter::PointerData::Change::kHover:
    case flutter::PointerData::Change::kUp:
      return 0;
  }
  return 0;
}

FlutterEngineResult FlutterEngineSendPointerEvent(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    const FlutterPointerEvent* pointers,
    size_t events_count) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
  }

  if (pointers == nullptr || events_count == 0) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid pointer events.");
  }

  auto packet = std::make_unique<flutter::PointerDataPacket>(events_count);

  const FlutterPointerEvent* current = pointers;

  for (size_t i = 0; i < events_count; ++i) {
    flutter::PointerData pointer_data;
    pointer_data.Clear();
    // this is currely in use only on android embedding.
    pointer_data.embedder_id = 0;
    pointer_data.time_stamp = SAFE_ACCESS(current, timestamp, 0);
    pointer_data.change = ToPointerDataChange(
        SAFE_ACCESS(current, phase, FlutterPointerPhase::kCancel));
    pointer_data.physical_x = SAFE_ACCESS(current, x, 0.0);
    pointer_data.physical_y = SAFE_ACCESS(current, y, 0.0);
    // Delta will be generated in pointer_data_packet_converter.cc.
    pointer_data.physical_delta_x = 0.0;
    pointer_data.physical_delta_y = 0.0;
    pointer_data.device = SAFE_ACCESS(current, device, 0);
    // Pointer identifier will be generated in
    // pointer_data_packet_converter.cc.
    pointer_data.pointer_identifier = 0;
    pointer_data.signal_kind = ToPointerDataSignalKind(
        SAFE_ACCESS(current, signal_kind, kFlutterPointerSignalKindNone));
    pointer_data.scroll_delta_x = SAFE_ACCESS(current, scroll_delta_x, 0.0);
    pointer_data.scroll_delta_y = SAFE_ACCESS(current, scroll_delta_y, 0.0);
    FlutterPointerDeviceKind device_kind = SAFE_ACCESS(current, device_kind, 0);
    // For backwards compatibility with embedders written before the device
    // kind and buttons were exposed, if the device kind is not set treat it
    // as a mouse, with a synthesized primary button state based on the phase.
    if (device_kind == 0) {
      pointer_data.kind = flutter::PointerData::DeviceKind::kMouse;
      pointer_data.buttons =
          PointerDataButtonsForLegacyEvent(pointer_data.change);

    } else {
      pointer_data.kind = ToPointerDataKind(device_kind);
      if (pointer_data.kind == flutter::PointerData::DeviceKind::kTouch) {
        // For touch events, set the button internally rather than requiring
        // it at the API level, since it's a confusing construction to expose.
        if (pointer_data.change == flutter::PointerData::Change::kDown ||
            pointer_data.change == flutter::PointerData::Change::kMove) {
          pointer_data.buttons = flutter::kPointerButtonTouchContact;
        }
      } else {
        // Buttons use the same mask values, so pass them through directly.
        pointer_data.buttons = SAFE_ACCESS(current, buttons, 0);
      }
    }
    packet->SetPointerData(i, pointer_data);
    current = reinterpret_cast<const FlutterPointerEvent*>(
        reinterpret_cast<const uint8_t*>(current) + current->struct_size);
  }

  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
                 ->DispatchPointerDataPacket(std::move(packet))
             ? kSuccess
             : LOG_EMBEDDER_ERROR(kInternalInconsistency,
                                  "Could not dispatch pointer events to the "
                                  "running Flutter application.");
}

FlutterEngineResult FlutterEngineSendPlatformMessage(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    const FlutterPlatformMessage* flutter_message) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }

  if (flutter_message == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid message argument.");
  }

  if (SAFE_ACCESS(flutter_message, channel, nullptr) == nullptr) {
    return LOG_EMBEDDER_ERROR(
        kInvalidArguments, "Message argument did not specify a valid channel.");
  }

  size_t message_size = SAFE_ACCESS(flutter_message, message_size, 0);
  const uint8_t* message_data = SAFE_ACCESS(flutter_message, message, nullptr);

  if (message_size != 0 && message_data == nullptr) {
    return LOG_EMBEDDER_ERROR(
        kInvalidArguments,
        "Message size was non-zero but the message data was nullptr.");
  }

  const FlutterPlatformMessageResponseHandle* response_handle =
      SAFE_ACCESS(flutter_message, response_handle, nullptr);

  fml::RefPtr<flutter::PlatformMessageResponse> response;
  if (response_handle && response_handle->message) {
    response = response_handle->message->response();
  }

  fml::RefPtr<flutter::PlatformMessage> message;
  if (message_size == 0) {
    message = fml::MakeRefCounted<flutter::PlatformMessage>(
        flutter_message->channel, response);
  } else {
    message = fml::MakeRefCounted<flutter::PlatformMessage>(
        flutter_message->channel,
        std::vector<uint8_t>(message_data, message_data + message_size),
        response);
  }

  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
                 ->SendPlatformMessage(std::move(message))
             ? kSuccess
             : LOG_EMBEDDER_ERROR(kInternalInconsistency,
                                  "Could not send a message to the running "
                                  "Flutter application.");
}

FlutterEngineResult FlutterPlatformMessageCreateResponseHandle(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    FlutterDataCallback data_callback,
    void* user_data,
    FlutterPlatformMessageResponseHandle** response_out) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
  }

  if (data_callback == nullptr || response_out == nullptr) {
    return LOG_EMBEDDER_ERROR(
        kInvalidArguments, "Data callback or the response handle was invalid.");
  }

  flutter::EmbedderPlatformMessageResponse::Callback response_callback =
      [user_data, data_callback](const uint8_t* data, size_t size) {
        data_callback(data, size, user_data);
      };

  auto platform_task_runner = reinterpret_cast<flutter::EmbedderEngine*>(engine)
                                  ->GetTaskRunners()
                                  .GetPlatformTaskRunner();

  auto handle = new FlutterPlatformMessageResponseHandle();

  handle->message = fml::MakeRefCounted<flutter::PlatformMessage>(
      "",  // The channel is empty and unused as the response handle is going
           // to referenced directly in the |FlutterEngineSendPlatformMessage|
           // with the container message discarded.
      fml::MakeRefCounted<flutter::EmbedderPlatformMessageResponse>(
          std::move(platform_task_runner), response_callback));
  *response_out = handle;
  return kSuccess;
}

FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    FlutterPlatformMessageResponseHandle* response) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }

  if (response == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid response handle.");
  }
  delete response;
  return kSuccess;
}

FlutterEngineResult FlutterEngineSendPlatformMessageResponse(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    const FlutterPlatformMessageResponseHandle* handle,
    const uint8_t* data,
    size_t data_length) {
  if (data_length != 0 && data == nullptr) {
    return LOG_EMBEDDER_ERROR(
        kInvalidArguments,
        "Data size was non zero but the pointer to the data was null.");
  }

  auto response = handle->message->response();

  if (response) {
    if (data_length == 0) {
      response->CompleteEmpty();
    } else {
      response->Complete(std::make_unique<fml::DataMapping>(
          std::vector<uint8_t>({data, data + data_length})));
    }
  }

  delete handle;

  return kSuccess;
}

FlutterEngineResult __FlutterEngineFlushPendingTasksNow() {
  fml::MessageLoop::GetCurrent().RunExpiredTasksNow();
  return kSuccess;
}

FlutterEngineResult FlutterEngineRegisterExternalTexture(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    int64_t texture_identifier) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
  }

  if (texture_identifier == 0) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "Texture identifier was invalid.");
  }
  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->RegisterTexture(
          texture_identifier)) {
    return LOG_EMBEDDER_ERROR(kInternalInconsistency,
                              "Could not register the specified texture.");
  }
  return kSuccess;
}

FlutterEngineResult FlutterEngineUnregisterExternalTexture(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    int64_t texture_identifier) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
  }

  if (texture_identifier == 0) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "Texture identifier was invalid.");
  }

  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->UnregisterTexture(
          texture_identifier)) {
    return LOG_EMBEDDER_ERROR(kInternalInconsistency,
                              "Could not un-register the specified texture.");
  }

  return kSuccess;
}

FlutterEngineResult FlutterEngineMarkExternalTextureFrameAvailable(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    int64_t texture_identifier) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }
  if (texture_identifier == 0) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid texture identifier.");
  }
  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
           ->MarkTextureFrameAvailable(texture_identifier)) {
    return LOG_EMBEDDER_ERROR(
        kInternalInconsistency,
        "Could not mark the texture frame as being available.");
  }
  return kSuccess;
}

FlutterEngineResult FlutterEngineUpdateSemanticsEnabled(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    bool enabled) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }
  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetSemanticsEnabled(
          enabled)) {
    return LOG_EMBEDDER_ERROR(kInternalInconsistency,
                              "Could not update semantics state.");
  }
  return kSuccess;
}

FlutterEngineResult FlutterEngineUpdateAccessibilityFeatures(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    FlutterAccessibilityFeature flags) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }
  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
           ->SetAccessibilityFeatures(flags)) {
    return LOG_EMBEDDER_ERROR(kInternalInconsistency,
                              "Could not update accessibility features.");
  }
  return kSuccess;
}

FlutterEngineResult FlutterEngineDispatchSemanticsAction(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    uint64_t id,
    FlutterSemanticsAction action,
    const uint8_t* data,
    size_t data_length) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }
  auto engine_action = static_cast<flutter::SemanticsAction>(action);
  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
           ->DispatchSemanticsAction(
               id, engine_action,
               std::vector<uint8_t>({data, data + data_length}))) {
    return LOG_EMBEDDER_ERROR(kInternalInconsistency,
                              "Could not dispatch semantics action.");
  }
  return kSuccess;
}

FlutterEngineResult FlutterEngineOnVsync(FLUTTER_API_SYMBOL(FlutterEngine)
                                             engine,
                                         intptr_t baton,
                                         uint64_t frame_start_time_nanos,
                                         uint64_t frame_target_time_nanos) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }

  TRACE_EVENT0("flutter", "FlutterEngineOnVsync");

  auto start_time = fml::TimePoint::FromEpochDelta(
      fml::TimeDelta::FromNanoseconds(frame_start_time_nanos));

  auto target_time = fml::TimePoint::FromEpochDelta(
      fml::TimeDelta::FromNanoseconds(frame_target_time_nanos));

  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->OnVsyncEvent(
          baton, start_time, target_time)) {
    return LOG_EMBEDDER_ERROR(
        kInternalInconsistency,
        "Could not notify the running engine instance of a Vsync event.");
  }

  return kSuccess;
}

FlutterEngineResult FlutterEngineReloadSystemFonts(
    FLUTTER_API_SYMBOL(FlutterEngine) engine) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }

  TRACE_EVENT0("flutter", "FlutterEngineReloadSystemFonts");

  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
           ->ReloadSystemFonts()) {
    return LOG_EMBEDDER_ERROR(kInternalInconsistency,
                              "Could not reload system fonts.");
  }

  return kSuccess;
}

void FlutterEngineTraceEventDurationBegin(const char* name) {
  fml::tracing::TraceEvent0("flutter", name);
}

void FlutterEngineTraceEventDurationEnd(const char* name) {
  fml::tracing::TraceEventEnd(name);
}

void FlutterEngineTraceEventInstant(const char* name) {
  fml::tracing::TraceEventInstant0("flutter", name);
}

FlutterEngineResult FlutterEnginePostRenderThreadTask(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    VoidCallback callback,
    void* baton) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }

  if (callback == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "Render thread callback was null.");
  }

  auto task = [callback, baton]() { callback(baton); };

  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
                 ->PostRenderThreadTask(task)
             ? kSuccess
             : LOG_EMBEDDER_ERROR(kInternalInconsistency,
                                  "Could not post the render thread task.");
}

uint64_t FlutterEngineGetCurrentTime() {
  return fml::TimePoint::Now().ToEpochDelta().ToNanoseconds();
}

FlutterEngineResult FlutterEngineRunTask(FLUTTER_API_SYMBOL(FlutterEngine)
                                             engine,
                                         const FlutterTask* task) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }

  return reinterpret_cast<flutter::EmbedderEngine*>(engine)->RunTask(task)
             ? kSuccess
             : LOG_EMBEDDER_ERROR(kInvalidArguments,
                                  "Could not run the specified task.");
}

static bool DispatchJSONPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine)
                                            engine,
                                        rapidjson::Document document,
                                        const std::string& channel_name) {
  if (channel_name.size() == 0) {
    return false;
  }

  rapidjson::StringBuffer buffer;
  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);

  if (!document.Accept(writer)) {
    return false;
  }

  const char* message = buffer.GetString();

  if (message == nullptr || buffer.GetSize() == 0) {
    return false;
  }

  auto platform_message = fml::MakeRefCounted<flutter::PlatformMessage>(
      channel_name.c_str(),                                       // channel
      std::vector<uint8_t>{message, message + buffer.GetSize()},  // message
      nullptr                                                     // response
  );

  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
      ->SendPlatformMessage(std::move(platform_message));
}

FlutterEngineResult FlutterEngineUpdateLocales(FLUTTER_API_SYMBOL(FlutterEngine)
                                                   engine,
                                               const FlutterLocale** locales,
                                               size_t locales_count) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }

  if (locales_count == 0) {
    return kSuccess;
  }

  if (locales == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "No locales were specified.");
  }

  rapidjson::Document document;
  auto& allocator = document.GetAllocator();

  document.SetObject();
  document.AddMember("method", "setLocale", allocator);

  rapidjson::Value args(rapidjson::kArrayType);
  args.Reserve(locales_count * 4, allocator);
  for (size_t i = 0; i < locales_count; ++i) {
    const FlutterLocale* locale = locales[i];
    const char* language_code_str = SAFE_ACCESS(locale, language_code, nullptr);
    if (language_code_str == nullptr || ::strlen(language_code_str) == 0) {
      return LOG_EMBEDDER_ERROR(
          kInvalidArguments,
          "Language code is required but not present in FlutterLocale.");
    }

    const char* country_code_str = SAFE_ACCESS(locale, country_code, "");
    const char* script_code_str = SAFE_ACCESS(locale, script_code, "");
    const char* variant_code_str = SAFE_ACCESS(locale, variant_code, "");

    rapidjson::Value language_code, country_code, script_code, variant_code;

    language_code.SetString(language_code_str, allocator);
    country_code.SetString(country_code_str ? country_code_str : "", allocator);
    script_code.SetString(script_code_str ? script_code_str : "", allocator);
    variant_code.SetString(variant_code_str ? variant_code_str : "", allocator);

    // Required.
    args.PushBack(language_code, allocator);
    args.PushBack(country_code, allocator);
    args.PushBack(script_code, allocator);
    args.PushBack(variant_code, allocator);
  }
  document.AddMember("args", args, allocator);

  return DispatchJSONPlatformMessage(engine, std::move(document),
                                     "flutter/localization")
             ? kSuccess
             : LOG_EMBEDDER_ERROR(kInternalInconsistency,
                                  "Could not send message to update locale of "
                                  "a running Flutter application.");
}

bool FlutterEngineRunsAOTCompiledDartCode(void) {
  return flutter::DartVM::IsRunningPrecompiledCode();
}

FlutterEngineResult FlutterEnginePostDartObject(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    FlutterEngineDartPort port,
    const FlutterEngineDartObject* object) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }

  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->IsValid()) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine not running.");
  }

  if (port == ILLEGAL_PORT) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "Attempted to post to an illegal port.");
  }

  if (object == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "Invalid Dart object to post.");
  }

  Dart_CObject dart_object = {};
  fml::ScopedCleanupClosure typed_data_finalizer;

  switch (object->type) {
    case kFlutterEngineDartObjectTypeNull:
      dart_object.type = Dart_CObject_kNull;
      break;
    case kFlutterEngineDartObjectTypeBool:
      dart_object.type = Dart_CObject_kBool;
      dart_object.value.as_bool = object->bool_value;
      break;
    case kFlutterEngineDartObjectTypeInt32:
      dart_object.type = Dart_CObject_kInt32;
      dart_object.value.as_int32 = object->int32_value;
      break;
    case kFlutterEngineDartObjectTypeInt64:
      dart_object.type = Dart_CObject_kInt64;
      dart_object.value.as_int64 = object->int64_value;
      break;
    case kFlutterEngineDartObjectTypeDouble:
      dart_object.type = Dart_CObject_kDouble;
      dart_object.value.as_double = object->double_value;
      break;
    case kFlutterEngineDartObjectTypeString:
      if (object->string_value == nullptr) {
        return LOG_EMBEDDER_ERROR(kInvalidArguments,
                                  "kFlutterEngineDartObjectTypeString must be "
                                  "a null terminated string but was null.");
      }
      dart_object.type = Dart_CObject_kString;
      dart_object.value.as_string = const_cast<char*>(object->string_value);
      break;
    case kFlutterEngineDartObjectTypeBuffer: {
      auto* buffer = SAFE_ACCESS(object->buffer_value, buffer, nullptr);
      if (buffer == nullptr) {
        return LOG_EMBEDDER_ERROR(kInvalidArguments,
                                  "kFlutterEngineDartObjectTypeBuffer must "
                                  "specify a buffer but found nullptr.");
      }
      auto buffer_size = SAFE_ACCESS(object->buffer_value, buffer_size, 0);
      auto callback =
          SAFE_ACCESS(object->buffer_value, buffer_collect_callback, nullptr);
      auto user_data = SAFE_ACCESS(object->buffer_value, user_data, nullptr);

      // The user has provided a callback, let them manage the lifecycle of
      // the underlying data. If not, copy it out from the provided buffer.

      if (callback == nullptr) {
        dart_object.type = Dart_CObject_kTypedData;
        dart_object.value.as_typed_data.type = Dart_TypedData_kUint8;
        dart_object.value.as_typed_data.length = buffer_size;
        dart_object.value.as_typed_data.values = buffer;
      } else {
        struct ExternalTypedDataPeer {
          void* user_data = nullptr;
          VoidCallback trampoline = nullptr;
        };
        auto peer = new ExternalTypedDataPeer();
        peer->user_data = user_data;
        peer->trampoline = callback;
        // This finalizer is set so that in case of failure of the
        // Dart_PostCObject below, we collect the peer. The embedder is still
        // responsible for collecting the buffer in case of non-kSuccess
        // returns from this method. This finalizer must be released in case
        // of kSuccess returns from this method.
        typed_data_finalizer.SetClosure([peer]() {
          // This is the tiny object we use as the peer to the Dart call so
          // that we can attach the a trampoline to the embedder supplied
          // callback. In case of error, we need to collect this object lest
          // we introduce a tiny leak.
          delete peer;
        });
        dart_object.type = Dart_CObject_kExternalTypedData;
        dart_object.value.as_external_typed_data.type = Dart_TypedData_kUint8;
        dart_object.value.as_external_typed_data.length = buffer_size;
        dart_object.value.as_external_typed_data.data = buffer;
        dart_object.value.as_external_typed_data.peer = peer;
        dart_object.value.as_external_typed_data.callback =
            +[](void* unused_isolate_callback_data, void* peer) {
              auto typed_peer = reinterpret_cast<ExternalTypedDataPeer*>(peer);
              typed_peer->trampoline(typed_peer->user_data);
              delete typed_peer;
            };
      }
    } break;
    default:
      return LOG_EMBEDDER_ERROR(
          kInvalidArguments,
          "Invalid FlutterEngineDartObjectType type specified.");
  }

  if (!Dart_PostCObject(port, &dart_object)) {
    return LOG_EMBEDDER_ERROR(kInternalInconsistency,
                              "Could not post the object to the Dart VM.");
  }

  // On a successful call, the VM takes ownership of and is responsible for
  // invoking the finalizer.
  typed_data_finalizer.Release();
  return kSuccess;
}

FlutterEngineResult FlutterEngineNotifyLowMemoryWarning(
    FLUTTER_API_SYMBOL(FlutterEngine) raw_engine) {
  auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);
  if (engine == nullptr || !engine->IsValid()) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine was invalid.");
  }

  engine->GetShell().NotifyLowMemoryWarning();

  rapidjson::Document document;
  auto& allocator = document.GetAllocator();

  document.SetObject();
  document.AddMember("type", "memoryPressure", allocator);

  return DispatchJSONPlatformMessage(raw_engine, std::move(document),
                                     "flutter/system")
             ? kSuccess
             : LOG_EMBEDDER_ERROR(
                   kInternalInconsistency,
                   "Could not dispatch the low memory notification message.");
}

FlutterEngineResult FlutterEnginePostCallbackOnAllNativeThreads(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    FlutterNativeThreadCallback callback,
    void* user_data) {
  if (engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }

  if (callback == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments,
                              "Invalid native thread callback.");
  }

  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
                 ->PostTaskOnEngineManagedNativeThreads(
                     [callback, user_data](FlutterNativeThreadType type) {
                       callback(type, user_data);
                     })
             ? kSuccess
             : LOG_EMBEDDER_ERROR(kInvalidArguments,
                                  "Internal error while attempting to post "
                                  "tasks to all threads.");
}

namespace {
static bool ValidDisplayConfiguration(const FlutterEngineDisplay* displays,
                                      size_t display_count) {
  std::set<FlutterEngineDisplayId> display_ids;
  for (size_t i = 0; i < display_count; i++) {
    if (displays[i].single_display && display_count != 1) {
      return false;
    }
    display_ids.insert(displays[i].display_id);
  }

  return display_ids.size() == display_count;
}
}  // namespace

FlutterEngineResult FlutterEngineNotifyDisplayUpdate(
    FLUTTER_API_SYMBOL(FlutterEngine) raw_engine,
    const FlutterEngineDisplaysUpdateType update_type,
    const FlutterEngineDisplay* embedder_displays,
    size_t display_count) {
  if (raw_engine == nullptr) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
  }

  if (!ValidDisplayConfiguration(embedder_displays, display_count)) {
    return LOG_EMBEDDER_ERROR(
        kInvalidArguments,
        "Invalid FlutterEngineDisplay configuration specified.");
  }

  auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);

  switch (update_type) {
    case kFlutterEngineDisplaysUpdateTypeStartup: {
      std::vector<flutter::Display> displays;
      for (size_t i = 0; i < display_count; i++) {
        flutter::Display display =
            flutter::Display(embedder_displays[i].refresh_rate);
        if (!embedder_displays[i].single_display) {
          display = flutter::Display(embedder_displays[i].display_id,
                                     embedder_displays[i].refresh_rate);
        }
        displays.push_back(display);
      }
      engine->GetShell().OnDisplayUpdates(flutter::DisplayUpdateType::kStartup,
                                          displays);
      return kSuccess;
    }
    default:
      return LOG_EMBEDDER_ERROR(
          kInvalidArguments,
          "Invalid FlutterEngineDisplaysUpdateType type specified.");
  }
}

FlutterEngineResult FlutterEngineGetProcAddresses(
    FlutterEngineProcTable* table) {
  if (!table) {
    return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null table specified.");
  }
#define SET_PROC(member, function)        \
  if (STRUCT_HAS_MEMBER(table, member)) { \
    table->member = &function;            \
  }

  SET_PROC(CreateAOTData, FlutterEngineCreateAOTData);
  SET_PROC(CollectAOTData, FlutterEngineCollectAOTData);
  SET_PROC(Run, FlutterEngineRun);
  SET_PROC(Shutdown, FlutterEngineShutdown);
  SET_PROC(Initialize, FlutterEngineInitialize);
  SET_PROC(Deinitialize, FlutterEngineDeinitialize);
  SET_PROC(RunInitialized, FlutterEngineRunInitialized);
  SET_PROC(SendWindowMetricsEvent, FlutterEngineSendWindowMetricsEvent);
  SET_PROC(SendPointerEvent, FlutterEngineSendPointerEvent);
  SET_PROC(SendPlatformMessage, FlutterEngineSendPlatformMessage);
  SET_PROC(PlatformMessageCreateResponseHandle,
           FlutterPlatformMessageCreateResponseHandle);
  SET_PROC(PlatformMessageReleaseResponseHandle,
           FlutterPlatformMessageReleaseResponseHandle);
  SET_PROC(SendPlatformMessageResponse,
           FlutterEngineSendPlatformMessageResponse);
  SET_PROC(RegisterExternalTexture, FlutterEngineRegisterExternalTexture);
  SET_PROC(UnregisterExternalTexture, FlutterEngineUnregisterExternalTexture);
  SET_PROC(MarkExternalTextureFrameAvailable,
           FlutterEngineMarkExternalTextureFrameAvailable);
  SET_PROC(UpdateSemanticsEnabled, FlutterEngineUpdateSemanticsEnabled);
  SET_PROC(UpdateAccessibilityFeatures,
           FlutterEngineUpdateAccessibilityFeatures);
  SET_PROC(DispatchSemanticsAction, FlutterEngineDispatchSemanticsAction);
  SET_PROC(OnVsync, FlutterEngineOnVsync);
  SET_PROC(ReloadSystemFonts, FlutterEngineReloadSystemFonts);
  SET_PROC(TraceEventDurationBegin, FlutterEngineTraceEventDurationBegin);
  SET_PROC(TraceEventDurationEnd, FlutterEngineTraceEventDurationEnd);
  SET_PROC(TraceEventInstant, FlutterEngineTraceEventInstant);
  SET_PROC(PostRenderThreadTask, FlutterEnginePostRenderThreadTask);
  SET_PROC(GetCurrentTime, FlutterEngineGetCurrentTime);
  SET_PROC(RunTask, FlutterEngineRunTask);
  SET_PROC(UpdateLocales, FlutterEngineUpdateLocales);
  SET_PROC(RunsAOTCompiledDartCode, FlutterEngineRunsAOTCompiledDartCode);
  SET_PROC(PostDartObject, FlutterEnginePostDartObject);
  SET_PROC(NotifyLowMemoryWarning, FlutterEngineNotifyLowMemoryWarning);
  SET_PROC(PostCallbackOnAllNativeThreads,
           FlutterEnginePostCallbackOnAllNativeThreads);
  SET_PROC(NotifyDisplayUpdate, FlutterEngineNotifyDisplayUpdate);
#undef SET_PROC

  return kSuccess;
}
