// 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 "gfx_platform_view.h"

#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/input/cpp/fidl.h>
#include <fuchsia/ui/input3/cpp/fidl.h>
#include <fuchsia/ui/input3/cpp/fidl_test_base.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/default.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>

#include <memory>
#include <ostream>
#include <string>
#include <vector>

#include "flutter/flow/embedded_views.h"
#include "flutter/lib/ui/window/platform_message.h"
#include "flutter/lib/ui/window/pointer_data.h"
#include "flutter/lib/ui/window/viewport_metrics.h"
#include "flutter/shell/common/context_options.h"
#include "flutter/shell/platform/fuchsia/flutter/gfx_platform_view.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "platform/assert.h"
#include "surface.h"
#include "task_runner_adapter.h"
#include "tests/fakes/focuser.h"
#include "tests/fakes/platform_message.h"
#include "tests/fakes/touch_source.h"
#include "tests/fakes/view_ref_focused.h"
#include "tests/pointer_event_utility.h"

namespace flutter_runner::testing {
namespace {

class MockExternalViewEmbedder : public flutter::ExternalViewEmbedder {
 public:
  SkCanvas* GetRootCanvas() override { return nullptr; }
  std::vector<SkCanvas*> GetCurrentCanvases() override {
    return std::vector<SkCanvas*>();
  }

  void CancelFrame() override {}
  void BeginFrame(
      SkISize frame_size,
      GrDirectContext* context,
      double device_pixel_ratio,
      fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override {}
  void SubmitFrame(GrDirectContext* context,
                   std::unique_ptr<flutter::SurfaceFrame> frame) override {
    return;
  }

  void PrerollCompositeEmbeddedView(
      int view_id,
      std::unique_ptr<flutter::EmbeddedViewParams> params) override {}
  SkCanvas* CompositeEmbeddedView(int view_id) override { return nullptr; }
};

class MockPlatformViewDelegate : public flutter::PlatformView::Delegate {
 public:
  void Reset() {
    message_ = nullptr;
    metrics_ = flutter::ViewportMetrics{};
    semantics_features_ = 0;
    semantics_enabled_ = false;
    pointer_packets_.clear();
  }

  // |flutter::PlatformView::Delegate|
  void OnPlatformViewCreated(std::unique_ptr<flutter::Surface> surface) {
    ASSERT_EQ(surface_.get(), nullptr);

    surface_ = std::move(surface);
  }
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewDestroyed() {}
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {}
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewSetViewportMetrics(
      const flutter::ViewportMetrics& metrics) {
    metrics_ = metrics;
  }
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewDispatchPlatformMessage(
      std::unique_ptr<flutter::PlatformMessage> message) {
    message_ = std::move(message);
  }
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewDispatchPointerDataPacket(
      std::unique_ptr<flutter::PointerDataPacket> packet) {
    pointer_packets_.push_back(std::move(packet));
  }
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewDispatchSemanticsAction(int32_t id,
                                             flutter::SemanticsAction action,
                                             fml::MallocMapping args) {}
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewSetSemanticsEnabled(bool enabled) {
    semantics_enabled_ = enabled;
  }
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewSetAccessibilityFeatures(int32_t flags) {
    semantics_features_ = flags;
  }
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewRegisterTexture(
      std::shared_ptr<flutter::Texture> texture) {}
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewUnregisterTexture(int64_t texture_id) {}
  // |flutter::PlatformView::Delegate|
  void OnPlatformViewMarkTextureFrameAvailable(int64_t texture_id) {}
  // |flutter::PlatformView::Delegate|
  std::unique_ptr<std::vector<std::string>> ComputePlatformViewResolvedLocale(
      const std::vector<std::string>& supported_locale_data) {
    return nullptr;
  }
  // |flutter::PlatformView::Delegate|
  void LoadDartDeferredLibrary(
      intptr_t loading_unit_id,
      std::unique_ptr<const fml::Mapping> snapshot_data,
      std::unique_ptr<const fml::Mapping> snapshot_instructions) {}
  // |flutter::PlatformView::Delegate|
  void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
                                    const std::string error_message,
                                    bool transient) {}
  // |flutter::PlatformView::Delegate|
  void UpdateAssetResolverByType(
      std::unique_ptr<flutter::AssetResolver> updated_asset_resolver,
      flutter::AssetResolver::AssetResolverType type) {}

  flutter::Surface* surface() const { return surface_.get(); }
  flutter::PlatformMessage* message() const { return message_.get(); }
  const flutter::ViewportMetrics& metrics() const { return metrics_; }
  int32_t semantics_features() const { return semantics_features_; }
  bool semantics_enabled() const { return semantics_enabled_; }
  const std::vector<std::unique_ptr<flutter::PointerDataPacket>>&
  pointer_packets() const {
    return pointer_packets_;
  }
  std::vector<std::unique_ptr<flutter::PointerDataPacket>>
  TakePointerDataPackets() {
    auto tmp = std::move(pointer_packets_);
    pointer_packets_.clear();
    return tmp;
  }

 private:
  std::unique_ptr<flutter::Surface> surface_;
  std::unique_ptr<flutter::PlatformMessage> message_;
  flutter::ViewportMetrics metrics_;
  std::vector<std::unique_ptr<flutter::PointerDataPacket>> pointer_packets_;
  int32_t semantics_features_ = 0;
  bool semantics_enabled_ = false;
};

class MockResponse : public flutter::PlatformMessageResponse {
 public:
  MOCK_METHOD1(Complete, void(std::unique_ptr<fml::Mapping> data));
  MOCK_METHOD0(CompleteEmpty, void());
};

class TestPlatformMessageResponse : public flutter::PlatformMessageResponse {
 public:
  TestPlatformMessageResponse() {}
  void Complete(std::unique_ptr<fml::Mapping> data) override {
    result_string = std::string(
        reinterpret_cast<const char*>(data->GetMapping()), data->GetSize());
    is_complete_ = true;
  }
  void CompleteEmpty() override { is_complete_ = true; }
  std::string result_string;
  FML_DISALLOW_COPY_AND_ASSIGN(TestPlatformMessageResponse);
};

class MockKeyboard : public fuchsia::ui::input3::testing::Keyboard_TestBase {
 public:
  explicit MockKeyboard(
      fidl::InterfaceRequest<fuchsia::ui::input3::Keyboard> keyboard)
      : keyboard_(this, std::move(keyboard)) {}
  ~MockKeyboard() = default;

  void AddListener(fuchsia::ui::views::ViewRef view_ref,
                   fuchsia::ui::input3::KeyboardListenerHandle listener,
                   AddListenerCallback callback) override {
    FML_CHECK(!listener_.is_bound());

    listener_ = listener.Bind();
    view_ref_ = std::move(view_ref);

    callback();
  }

  void NotImplemented_(const std::string& name) override { FAIL(); }

  fidl::Binding<fuchsia::ui::input3::Keyboard> keyboard_;
  fuchsia::ui::input3::KeyboardListenerPtr listener_{};
  fuchsia::ui::views::ViewRef view_ref_{};

  FML_DISALLOW_COPY_AND_ASSIGN(MockKeyboard);
};

// Used to construct partial instances of PlatformView for testing.  The
// PlatformView constructor has many parameters, not all of which need to
// be filled out for each test.  The builder allows you to initialize only
// those that matter to your specific test.  Not all builder methods are
// provided: if you find some that are missing, feel free to add them.
class PlatformViewBuilder {
 public:
  PlatformViewBuilder(flutter::PlatformView::Delegate& delegate,
                      flutter::TaskRunners task_runners)
      : delegate_(delegate),
        task_runners_(task_runners),
        view_ref_pair_(scenic::ViewRefPair::New()) {}

  PlatformViewBuilder& SetExternalViewEmbedder(
      std::shared_ptr<flutter::ExternalViewEmbedder> embedder) {
    external_external_view_embedder_ = embedder;
    return *this;
  }

  PlatformViewBuilder& SetImeService(
      fuchsia::ui::input::ImeServiceHandle ime_service) {
    ime_service_ = std::move(ime_service);
    return *this;
  }

  PlatformViewBuilder& SetKeyboard(
      fuchsia::ui::input3::KeyboardHandle keyboard) {
    keyboard_ = std::move(keyboard);
    return *this;
  }

  PlatformViewBuilder& SetTouchSource(
      fuchsia::ui::pointer::TouchSourceHandle touch_source) {
    touch_source_ = std::move(touch_source);
    return *this;
  }

  PlatformViewBuilder& SetMouseSource(
      fuchsia::ui::pointer::MouseSourceHandle mouse_source) {
    mouse_source_ = std::move(mouse_source);
    return *this;
  }

  PlatformViewBuilder& SetFocuser(fuchsia::ui::views::FocuserHandle focuser) {
    focuser_ = std::move(focuser);
    return *this;
  }

  PlatformViewBuilder& SetViewRefFocused(
      fuchsia::ui::views::ViewRefFocusedHandle view_ref_focused) {
    view_ref_focused_ = std::move(view_ref_focused);
    return *this;
  }

  PlatformViewBuilder& SetSessionListenerRequest(
      fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener> request) {
    session_listener_request_ = std::move(request);
    return *this;
  }

  PlatformViewBuilder& SetEnableWireframeCallback(OnEnableWireframe callback) {
    wireframe_enabled_callback_ = std::move(callback);
    return *this;
  }

  PlatformViewBuilder& SetCreateViewCallback(OnCreateGfxView callback) {
    on_create_view_callback_ = std::move(callback);
    return *this;
  }

  PlatformViewBuilder& SetUpdateViewCallback(OnUpdateView callback) {
    on_update_view_callback_ = std::move(callback);
    return *this;
  }

  PlatformViewBuilder& SetDestroyViewCallback(OnDestroyGfxView callback) {
    on_destroy_view_callback_ = std::move(callback);
    return *this;
  }

  PlatformViewBuilder& SetCreateSurfaceCallback(OnCreateSurface callback) {
    on_create_surface_callback_ = std::move(callback);
    return *this;
  }

  PlatformViewBuilder& SetShaderWarmupCallback(OnShaderWarmup callback) {
    on_shader_warmup_callback_ = std::move(callback);
    return *this;
  }

  // Once Build is called, the instance is no longer usable.
  GfxPlatformView Build() {
    EXPECT_FALSE(std::exchange(built_, true))
        << "Build() was already called, this buider is good for one use only.";
    return GfxPlatformView(
        delegate_, task_runners_, std::move(view_ref_pair_.view_ref),
        external_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(session_listener_request_),
        std::move(on_session_listener_error_callback_),
        std::move(wireframe_enabled_callback_),
        std::move(on_create_view_callback_),
        std::move(on_update_view_callback_),
        std::move(on_destroy_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_callback_), [](auto...) {}, [](auto...) {});
  }

 private:
  PlatformViewBuilder() = delete;

  flutter::PlatformView::Delegate& delegate_;
  flutter::TaskRunners task_runners_;
  scenic::ViewRefPair view_ref_pair_;

  std::shared_ptr<flutter::ExternalViewEmbedder>
      external_external_view_embedder_;
  fuchsia::ui::input::ImeServiceHandle ime_service_;
  fuchsia::ui::input3::KeyboardHandle keyboard_;
  fuchsia::ui::pointer::TouchSourceHandle touch_source_;
  fuchsia::ui::pointer::MouseSourceHandle mouse_source_;
  fuchsia::ui::views::ViewRefFocusedHandle view_ref_focused_;
  fuchsia::ui::views::FocuserHandle focuser_;
  fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener>
      session_listener_request_;
  fit::closure on_session_listener_error_callback_;
  OnEnableWireframe wireframe_enabled_callback_;
  OnCreateGfxView on_create_view_callback_;
  OnUpdateView on_update_view_callback_;
  OnDestroyGfxView on_destroy_view_callback_;
  OnCreateSurface on_create_surface_callback_;
  OnSemanticsNodeUpdate on_semantics_node_update_callback_;
  OnRequestAnnounce on_request_announce_callback_;
  OnShaderWarmup on_shader_warmup_callback_;

  bool built_{false};
};

std::string ToString(const fml::Mapping& mapping) {
  return std::string(mapping.GetMapping(),
                     mapping.GetMapping() + mapping.GetSize());
}

// Stolen from pointer_data_packet_converter_unittests.cc.
void UnpackPointerPacket(std::vector<flutter::PointerData>& output,  // NOLINT
                         std::unique_ptr<flutter::PointerDataPacket> packet) {
  size_t kBytesPerPointerData =
      flutter::kPointerDataFieldCount * flutter::kBytesPerField;
  auto buffer = packet->data();
  size_t buffer_length = buffer.size();

  for (size_t i = 0; i < buffer_length / kBytesPerPointerData; i++) {
    flutter::PointerData pointer_data;
    memcpy(&pointer_data, &buffer[i * kBytesPerPointerData],
           sizeof(flutter::PointerData));
    output.push_back(pointer_data);
  }
  packet.reset();
}

}  // namespace

class PlatformViewTests : public ::testing::Test {
 protected:
  PlatformViewTests() : loop_(&kAsyncLoopConfigAttachToCurrentThread) {}

  async_dispatcher_t* dispatcher() { return loop_.dispatcher(); }

  void RunLoopUntilIdle() {
    loop_.RunUntilIdle();
    loop_.ResetQuit();
  }

  fuchsia::ui::input3::KeyEvent MakeEvent(
      fuchsia::ui::input3::KeyEventType event_type,
      std::optional<fuchsia::ui::input3::Modifiers> modifiers,
      fuchsia::input::Key key) {
    fuchsia::ui::input3::KeyEvent event;
    event.set_timestamp(++event_timestamp_);
    event.set_type(event_type);
    if (modifiers.has_value()) {
      event.set_modifiers(modifiers.value());
    }
    event.set_key(key);
    return event;
  }

 private:
  async::Loop loop_;

  uint64_t event_timestamp_{42};

  FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewTests);
};

// This test makes sure that the PlatformView always completes a platform
// message request, even for error conditions or if the request is malformed.
TEST_F(PlatformViewTests, InvalidPlatformMessageRequest) {
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);

  FakeViewRefFocused vrf;
  fidl::BindingSet<fuchsia::ui::views::ViewRefFocused> vrf_bindings;
  auto vrf_handle = vrf_bindings.AddBinding(&vrf);

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetViewRefFocused(std::move(vrf_handle))
          .Build();

  // Cast platform_view to its base view so we can have access to the public
  // "HandlePlatformMessage" function.
  auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
  EXPECT_TRUE(base_view);

  // Invalid platform channel.
  auto response1 = FakePlatformMessageResponse::Create();
  base_view->HandlePlatformMessage(response1->WithMessage(
      "flutter/invalid", "{\"method\":\"Invalid.invalidMethod\"}"));

  // Invalid json.
  auto response2 = FakePlatformMessageResponse::Create();
  base_view->HandlePlatformMessage(
      response2->WithMessage("flutter/platform_views", "{Invalid JSON"));

  // Invalid method.
  auto response3 = FakePlatformMessageResponse::Create();
  base_view->HandlePlatformMessage(response3->WithMessage(
      "flutter/platform_views", "{\"method\":\"View.focus.invalidMethod\"}"));

  // Missing arguments.
  auto response4 = FakePlatformMessageResponse::Create();
  base_view->HandlePlatformMessage(response4->WithMessage(
      "flutter/platform_views", "{\"method\":\"View.update\"}"));
  auto response5 = FakePlatformMessageResponse::Create();
  base_view->HandlePlatformMessage(
      response5->WithMessage("flutter/platform_views",
                             "{\"method\":\"View.update\",\"args\":{"
                             "\"irrelevantField\":\"irrelevantValue\"}}"));

  // Wrong argument types.
  auto response6 = FakePlatformMessageResponse::Create();
  base_view->HandlePlatformMessage(response6->WithMessage(
      "flutter/platform_views",
      "{\"method\":\"View.update\",\"args\":{\"viewId\":false,\"hitTestable\":"
      "123,\"focusable\":\"yes\"}}"));

  // Run the event loop and check our responses.
  RunLoopUntilIdle();
  response1->ExpectCompleted("");
  response2->ExpectCompleted("");
  response3->ExpectCompleted("");
  response4->ExpectCompleted("");
  response5->ExpectCompleted("");
  response6->ExpectCompleted("");
}

// This test makes sure that the PlatformView correctly returns a Surface
// instance that can surface the provided gr_context and external_view_embedder.
TEST_F(PlatformViewTests, CreateSurfaceTest) {
  MockPlatformViewDelegate delegate;

  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners",  // label
                           nullptr,         // platform
                           flutter_runner::CreateFMLTaskRunner(
                               async_get_default_dispatcher()),  // raster
                           nullptr,                              // ui
                           nullptr                               // io
      );

  // Test create surface callback function.
  sk_sp<GrDirectContext> gr_context = GrDirectContext::MakeMock(
      nullptr,
      flutter::MakeDefaultContextOptions(flutter::ContextType::kRender));
  std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
      std::make_shared<MockExternalViewEmbedder>();
  auto CreateSurfaceCallback = [&external_view_embedder, gr_context]() {
    return std::make_unique<flutter_runner::Surface>(
        "PlatformViewTest", external_view_embedder, gr_context.get());
  };

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetCreateSurfaceCallback(CreateSurfaceCallback)
          .SetExternalViewEmbedder(external_view_embedder)
          .Build();
  platform_view.NotifyCreated();

  RunLoopUntilIdle();

  EXPECT_EQ(gr_context.get(), delegate.surface()->GetContext());
  EXPECT_EQ(external_view_embedder.get(),
            platform_view.CreateExternalViewEmbedder().get());
}

// This test makes sure that the PlatformView correctly registers Scenic
// MetricsEvents sent to it via FIDL, correctly parses the metrics it receives,
// and calls the SetViewportMetrics callback with the appropriate parameters.
TEST_F(PlatformViewTests, SetViewportMetrics) {
  constexpr float invalid_pixel_ratio = -0.75f;
  constexpr float valid_pixel_ratio = 0.75f;
  constexpr float invalid_max_bound = -0.75f;
  constexpr float valid_max_bound = 0.75f;

  MockPlatformViewDelegate delegate;
  EXPECT_EQ(delegate.metrics(), flutter::ViewportMetrics());

  fuchsia::ui::scenic::SessionListenerPtr session_listener;
  std::vector<fuchsia::ui::scenic::Event> events;
  flutter::TaskRunners task_runners("test_runners", nullptr, nullptr, nullptr,
                                    nullptr);
  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetSessionListenerRequest(session_listener.NewRequest())
          .Build();
  RunLoopUntilIdle();
  EXPECT_EQ(delegate.metrics(), flutter::ViewportMetrics());

  // Test updating with an invalid pixel ratio.  The final metrics should be
  // unchanged.
  events.clear();
  events.emplace_back(fuchsia::ui::scenic::Event::WithGfx(
      fuchsia::ui::gfx::Event::WithMetrics(fuchsia::ui::gfx::MetricsEvent{
          .node_id = 0,
          .metrics =
              fuchsia::ui::gfx::Metrics{
                  .scale_x = invalid_pixel_ratio,
                  .scale_y = 1.f,
                  .scale_z = 1.f,
              },
      })));
  session_listener->OnScenicEvent(std::move(events));
  RunLoopUntilIdle();
  EXPECT_EQ(delegate.metrics(), flutter::ViewportMetrics());

  // Test updating with an invalid size. The final metrics should be unchanged.
  events.clear();
  events.emplace_back(
      fuchsia::ui::scenic::Event::WithGfx(
          fuchsia::ui::gfx::Event::WithViewPropertiesChanged(
              fuchsia::ui::gfx::ViewPropertiesChangedEvent{
                  .view_id = 0,
                  .properties =
                      fuchsia::ui::gfx::ViewProperties{
                          .bounding_box =
                              fuchsia::ui::gfx::BoundingBox{
                                  .min =
                                      fuchsia::ui::gfx::vec3{
                                          .x = 0.f,
                                          .y = 0.f,
                                          .z = 0.f,
                                      },
                                  .max =
                                      fuchsia::ui::gfx::vec3{
                                          .x = invalid_max_bound,
                                          .y = invalid_max_bound,
                                          .z = invalid_max_bound,
                                      },
                              },
                      },
              })));
  session_listener->OnScenicEvent(std::move(events));
  RunLoopUntilIdle();
  EXPECT_EQ(delegate.metrics(), flutter::ViewportMetrics());

  // Test updating the size only.  The final metrics should be unchanged until
  // both pixel ratio and size are updated.
  events.clear();
  events.emplace_back(
      fuchsia::ui::scenic::Event::WithGfx(
          fuchsia::ui::gfx::Event::WithViewPropertiesChanged(
              fuchsia::ui::gfx::ViewPropertiesChangedEvent{
                  .view_id = 0,
                  .properties =
                      fuchsia::ui::gfx::ViewProperties{
                          .bounding_box =
                              fuchsia::ui::gfx::BoundingBox{
                                  .min =
                                      fuchsia::ui::gfx::vec3{
                                          .x = 0.f,
                                          .y = 0.f,
                                          .z = 0.f,
                                      },
                                  .max =
                                      fuchsia::ui::gfx::vec3{
                                          .x = valid_max_bound,
                                          .y = valid_max_bound,
                                          .z = valid_max_bound,
                                      },
                              },
                      },
              })));
  session_listener->OnScenicEvent(std::move(events));
  RunLoopUntilIdle();
  EXPECT_EQ(delegate.metrics(), flutter::ViewportMetrics());

  // Test updating the pixel ratio only.  The final metrics should change now.
  events.clear();
  events.emplace_back(fuchsia::ui::scenic::Event::WithGfx(
      fuchsia::ui::gfx::Event::WithMetrics(fuchsia::ui::gfx::MetricsEvent{
          .node_id = 0,
          .metrics =
              fuchsia::ui::gfx::Metrics{
                  .scale_x = valid_pixel_ratio,
                  .scale_y = 1.f,
                  .scale_z = 1.f,
              },
      })));
  session_listener->OnScenicEvent(std::move(events));
  RunLoopUntilIdle();
  EXPECT_EQ(delegate.metrics(),
            flutter::ViewportMetrics(
                valid_pixel_ratio, valid_pixel_ratio * valid_max_bound,
                valid_pixel_ratio * valid_max_bound, -1.0));
}

// This test makes sure that the PlatformView correctly registers semantics
// settings changes applied to it and calls the SetSemanticsEnabled /
// SetAccessibilityFeatures callbacks with the appropriate parameters.
TEST_F(PlatformViewTests, ChangesAccessibilitySettings) {
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);

  EXPECT_FALSE(delegate.semantics_enabled());
  EXPECT_EQ(delegate.semantics_features(), 0);

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners)).Build();

  RunLoopUntilIdle();

  platform_view.SetSemanticsEnabled(true);

  EXPECT_TRUE(delegate.semantics_enabled());
  EXPECT_EQ(delegate.semantics_features(),
            static_cast<int32_t>(
                flutter::AccessibilityFeatureFlag::kAccessibleNavigation));

  platform_view.SetSemanticsEnabled(false);

  EXPECT_FALSE(delegate.semantics_enabled());
  EXPECT_EQ(delegate.semantics_features(), 0);
}

// This test makes sure that the PlatformView forwards messages on the
// "flutter/platform_views" channel for EnableWireframe.
TEST_F(PlatformViewTests, EnableWireframeTest) {
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);

  // Test wireframe callback function. If the message sent to the platform
  // view was properly handled and parsed, this function should be called,
  // setting |wireframe_enabled| to true.
  bool wireframe_enabled = false;
  auto EnableWireframeCallback = [&wireframe_enabled](bool should_enable) {
    wireframe_enabled = should_enable;
  };

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetEnableWireframeCallback(EnableWireframeCallback)
          .Build();

  // Cast platform_view to its base view so we can have access to the public
  // "HandlePlatformMessage" function.
  auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
  EXPECT_TRUE(base_view);

  // JSON for the message to be passed into the PlatformView.
  const uint8_t txt[] =
      "{"
      "    \"method\":\"View.enableWireframe\","
      "    \"args\": {"
      "       \"enable\":true"
      "    }"
      "}";

  std::unique_ptr<flutter::PlatformMessage> message =
      std::make_unique<flutter::PlatformMessage>(
          "flutter/platform_views", fml::MallocMapping::Copy(txt, sizeof(txt)),
          fml::RefPtr<flutter::PlatformMessageResponse>());
  base_view->HandlePlatformMessage(std::move(message));

  RunLoopUntilIdle();

  EXPECT_TRUE(wireframe_enabled);
}

// This test makes sure that the PlatformView forwards messages on the
// "flutter/platform_views" channel for Createview.
TEST_F(PlatformViewTests, CreateViewTest) {
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners",  // label
                           flutter_runner::CreateFMLTaskRunner(
                               async_get_default_dispatcher()),  // platform
                           nullptr,                              // raster
                           nullptr,                              // ui
                           nullptr                               // io
      );

  // Test wireframe callback function. If the message sent to the platform
  // view was properly handled and parsed, this function should be called,
  // setting |wireframe_enabled| to true.
  bool create_view_called = false;
  auto CreateViewCallback = [&create_view_called](
                                int64_t view_id,
                                flutter_runner::ViewCallback on_view_created,
                                flutter_runner::GfxViewIdCallback on_view_bound,
                                bool hit_testable, bool focusable) {
    create_view_called = true;
    on_view_created();
    on_view_bound(0);
  };

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetCreateViewCallback(CreateViewCallback)
          .Build();

  // Cast platform_view to its base view so we can have access to the public
  // "HandlePlatformMessage" function.
  auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
  EXPECT_TRUE(base_view);

  // JSON for the message to be passed into the PlatformView.
  const uint8_t txt[] =
      "{"
      "    \"method\":\"View.create\","
      "    \"args\": {"
      "       \"viewId\":42,"
      "       \"hitTestable\":true,"
      "       \"focusable\":true"
      "    }"
      "}";

  std::unique_ptr<flutter::PlatformMessage> message =
      std::make_unique<flutter::PlatformMessage>(
          "flutter/platform_views", fml::MallocMapping::Copy(txt, sizeof(txt)),
          fml::RefPtr<flutter::PlatformMessageResponse>());
  base_view->HandlePlatformMessage(std::move(message));

  RunLoopUntilIdle();

  EXPECT_TRUE(create_view_called);
}

// This test makes sure that the PlatformView forwards messages on the
// "flutter/platform_views" channel for UpdateView.
TEST_F(PlatformViewTests, UpdateViewTest) {
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);

  std::optional<SkRect> occlusion_hint_for_test;
  std::optional<bool> hit_testable_for_test;
  std::optional<bool> focusable_for_test;
  auto UpdateViewCallback = [&occlusion_hint_for_test, &hit_testable_for_test,
                             &focusable_for_test](
                                int64_t view_id, SkRect occlusion_hint,
                                bool hit_testable, bool focusable) {
    occlusion_hint_for_test = occlusion_hint;
    hit_testable_for_test = hit_testable;
    focusable_for_test = focusable;
  };

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetUpdateViewCallback(UpdateViewCallback)
          .Build();

  // Cast platform_view to its base view so we can have access to the public
  // "HandlePlatformMessage" function.
  auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
  EXPECT_TRUE(base_view);

  // Send a basic message.
  const uint8_t json[] =
      "{"
      "    \"method\":\"View.update\","
      "    \"args\": {"
      "       \"viewId\":42,"
      "       \"hitTestable\":true,"
      "       \"focusable\":true"
      "    }"
      "}";
  std::unique_ptr<flutter::PlatformMessage> message =
      std::make_unique<flutter::PlatformMessage>(
          "flutter/platform_views",
          fml::MallocMapping::Copy(json, sizeof(json)),
          fml::RefPtr<flutter::PlatformMessageResponse>());
  base_view->HandlePlatformMessage(std::move(message));

  RunLoopUntilIdle();
  ASSERT_TRUE(occlusion_hint_for_test.has_value());
  ASSERT_TRUE(hit_testable_for_test.has_value());
  ASSERT_TRUE(focusable_for_test.has_value());
  EXPECT_EQ(occlusion_hint_for_test.value(), SkRect::MakeEmpty());
  EXPECT_EQ(hit_testable_for_test.value(), true);
  EXPECT_EQ(focusable_for_test.value(), true);

  // Reset for the next message.
  occlusion_hint_for_test.reset();
  hit_testable_for_test.reset();
  focusable_for_test.reset();

  // Send another basic message.
  const uint8_t json_false[] =
      "{"
      "    \"method\":\"View.update\","
      "    \"args\": {"
      "       \"viewId\":42,"
      "       \"hitTestable\":false,"
      "       \"focusable\":false"
      "    }"
      "}";
  std::unique_ptr<flutter::PlatformMessage> message_false =
      std::make_unique<flutter::PlatformMessage>(
          "flutter/platform_views",
          fml::MallocMapping::Copy(json_false, sizeof(json_false)),
          fml::RefPtr<flutter::PlatformMessageResponse>());
  base_view->HandlePlatformMessage(std::move(message_false));
  RunLoopUntilIdle();
  ASSERT_TRUE(occlusion_hint_for_test.has_value());
  ASSERT_TRUE(hit_testable_for_test.has_value());
  ASSERT_TRUE(focusable_for_test.has_value());
  EXPECT_EQ(occlusion_hint_for_test.value(), SkRect::MakeEmpty());
  EXPECT_EQ(hit_testable_for_test.value(), false);
  EXPECT_EQ(focusable_for_test.value(), false);

  // Reset for the next message.
  occlusion_hint_for_test.reset();
  hit_testable_for_test.reset();
  focusable_for_test.reset();

  // Send a message including an occlusion hint.
  const uint8_t json_occlusion_hint[] =
      "{"
      "    \"method\":\"View.update\","
      "    \"args\": {"
      "       \"viewId\":42,"
      "       \"hitTestable\":true,"
      "       \"focusable\":true,"
      "       \"viewOcclusionHintLTRB\":[0.1,0.2,0.3,0.4]"
      "    }"
      "}";
  std::unique_ptr<flutter::PlatformMessage> message_occlusion_hint =
      std::make_unique<flutter::PlatformMessage>(
          "flutter/platform_views",
          fml::MallocMapping::Copy(json_occlusion_hint,
                                   sizeof(json_occlusion_hint)),
          fml::RefPtr<flutter::PlatformMessageResponse>());
  base_view->HandlePlatformMessage(std::move(message_occlusion_hint));
  RunLoopUntilIdle();
  ASSERT_TRUE(occlusion_hint_for_test.has_value());
  ASSERT_TRUE(hit_testable_for_test.has_value());
  ASSERT_TRUE(focusable_for_test.has_value());
  EXPECT_EQ(occlusion_hint_for_test.value(),
            SkRect::MakeLTRB(0.1, 0.2, 0.3, 0.4));
  EXPECT_EQ(hit_testable_for_test.value(), true);
  EXPECT_EQ(focusable_for_test.value(), true);
}

// This test makes sure that the PlatformView forwards messages on the
// "flutter/platform_views" channel for DestroyView.
TEST_F(PlatformViewTests, DestroyViewTest) {
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners",  // label
                           flutter_runner::CreateFMLTaskRunner(
                               async_get_default_dispatcher()),  // platform
                           nullptr,                              // raster
                           nullptr,                              // ui
                           nullptr                               // io
      );

  // Test wireframe callback function. If the message sent to the platform
  // view was properly handled and parsed, this function should be called,
  // setting |wireframe_enabled| to true.
  bool destroy_view_called = false;
  auto DestroyViewCallback =
      [&destroy_view_called](
          int64_t view_id, flutter_runner::GfxViewIdCallback on_view_unbound) {
        destroy_view_called = true;
        on_view_unbound(0);
      };

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetDestroyViewCallback(DestroyViewCallback)
          .Build();

  // Cast platform_view to its base view so we can have access to the public
  // "HandlePlatformMessage" function.
  auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
  EXPECT_TRUE(base_view);

  // JSON for the message to be passed into the PlatformView.
  const uint8_t txt[] =
      "{"
      "    \"method\":\"View.dispose\","
      "    \"args\": {"
      "       \"viewId\":42"
      "    }"
      "}";

  std::unique_ptr<flutter::PlatformMessage> message =
      std::make_unique<flutter::PlatformMessage>(
          "flutter/platform_views", fml::MallocMapping::Copy(txt, sizeof(txt)),
          fml::RefPtr<flutter::PlatformMessageResponse>());
  base_view->HandlePlatformMessage(std::move(message));

  RunLoopUntilIdle();

  EXPECT_TRUE(destroy_view_called);
}

// This test makes sure that the PlatformView forwards messages on the
// "flutter/platform_views" channel for ViewConnected, ViewDisconnected, and
// ViewStateChanged events.
TEST_F(PlatformViewTests, ViewEventsTest) {
  constexpr int64_t kViewId = 33;
  constexpr scenic::ResourceId kViewHolderId = 42;
  MockPlatformViewDelegate delegate;

  fuchsia::ui::scenic::SessionListenerPtr session_listener;
  std::vector<fuchsia::ui::scenic::Event> events;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners",  // label
                           flutter_runner::CreateFMLTaskRunner(
                               async_get_default_dispatcher()),  // platform
                           flutter_runner::CreateFMLTaskRunner(
                               async_get_default_dispatcher()),  // raster
                           flutter_runner::CreateFMLTaskRunner(
                               async_get_default_dispatcher()),  // ui
                           nullptr                               // io
      );

  auto on_create_view =
      [kViewId](int64_t view_id, flutter_runner::ViewCallback on_view_created,
                flutter_runner::GfxViewIdCallback on_view_bound,
                bool hit_testable, bool focusable) {
        ASSERT_EQ(view_id, kViewId);
        on_view_created();
        on_view_bound(kViewHolderId);
      };

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetSessionListenerRequest(session_listener.NewRequest())
          .SetCreateViewCallback(on_create_view)
          .Build();
  RunLoopUntilIdle();
  ASSERT_EQ(delegate.message(), nullptr);

  // Create initial view for testing.
  std::ostringstream create_view_message;
  create_view_message << "{"
                      << "  \"method\":\"View.create\","
                      << "  \"args\":{"
                      << "    \"viewId\":" << kViewId << ","
                      << "    \"hitTestable\":true,"
                      << "    \"focusable\":true"
                      << "  }"
                      << "}";
  std::string create_view_call = create_view_message.str();
  static_cast<flutter::PlatformView*>(&platform_view)
      ->HandlePlatformMessage(std::make_unique<flutter::PlatformMessage>(
          "flutter/platform_views",
          fml::MallocMapping::Copy(create_view_call.c_str(),
                                   create_view_call.size()),
          fml::RefPtr<flutter::PlatformMessageResponse>()));
  RunLoopUntilIdle();

  // ViewConnected event.
  delegate.Reset();
  events.clear();
  events.emplace_back(fuchsia::ui::scenic::Event::WithGfx(
      fuchsia::ui::gfx::Event::WithViewConnected(
          fuchsia::ui::gfx::ViewConnectedEvent{
              .view_holder_id = kViewHolderId,
          })));
  session_listener->OnScenicEvent(std::move(events));
  RunLoopUntilIdle();

  flutter::PlatformMessage* view_connected_msg = delegate.message();
  ASSERT_NE(view_connected_msg, nullptr);
  std::ostringstream view_connected_expected_out;
  view_connected_expected_out
      << "{"
      << "\"method\":\"View.viewConnected\","
      << "\"args\":{"
      << "  \"viewId\":" << kViewId  // ViewHolderToken handle
      << "  }"
      << "}";
  EXPECT_EQ(view_connected_expected_out.str(),
            ToString(view_connected_msg->data()));

  // ViewDisconnected event.
  delegate.Reset();
  events.clear();
  events.emplace_back(fuchsia::ui::scenic::Event::WithGfx(
      fuchsia::ui::gfx::Event::WithViewDisconnected(
          fuchsia::ui::gfx::ViewDisconnectedEvent{
              .view_holder_id = kViewHolderId,
          })));
  session_listener->OnScenicEvent(std::move(events));
  RunLoopUntilIdle();

  flutter::PlatformMessage* view_disconnected_msg = delegate.message();
  ASSERT_NE(view_disconnected_msg, nullptr);
  std::ostringstream view_disconnected_expected_out;
  view_disconnected_expected_out
      << "{"
      << "\"method\":\"View.viewDisconnected\","
      << "\"args\":{"
      << "  \"viewId\":" << kViewId  // ViewHolderToken handle
      << "  }"
      << "}";
  EXPECT_EQ(view_disconnected_expected_out.str(),
            ToString(view_disconnected_msg->data()));

  // ViewStateChanged event.
  delegate.Reset();
  events.clear();
  events.emplace_back(fuchsia::ui::scenic::Event::WithGfx(
      fuchsia::ui::gfx::Event::WithViewStateChanged(
          fuchsia::ui::gfx::ViewStateChangedEvent{
              .view_holder_id = kViewHolderId,
              .state =
                  fuchsia::ui::gfx::ViewState{
                      .is_rendering = true,
                  },
          })));
  session_listener->OnScenicEvent(std::move(events));
  RunLoopUntilIdle();

  flutter::PlatformMessage* view_state_changed_msg = delegate.message();
  ASSERT_NE(view_state_changed_msg, nullptr);
  std::ostringstream view_state_changed_expected_out;
  view_state_changed_expected_out
      << "{"
      << "\"method\":\"View.viewStateChanged\","
      << "\"args\":{"
      << "  \"viewId\":" << kViewId << ","  // ViewHolderToken
      << "  \"is_rendering\":true,"         // IsViewRendering
      << "  \"state\":true"                 // IsViewRendering
      << "  }"
      << "}";
  EXPECT_EQ(view_state_changed_expected_out.str(),
            ToString(view_state_changed_msg->data()));
}

// This test makes sure that the PlatformView forwards messages on the
// "flutter/platform_views" channel for View.focus.getCurrent and
// View.focus.getNext.
TEST_F(PlatformViewTests, GetFocusStatesTest) {
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);

  FakeViewRefFocused vrf;
  fidl::BindingSet<fuchsia::ui::views::ViewRefFocused> vrf_bindings;
  auto vrf_handle = vrf_bindings.AddBinding(&vrf);

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetViewRefFocused(std::move(vrf_handle))
          .Build();

  // Cast platform_view to its base view so we can have access to the public
  // "HandlePlatformMessage" function.
  auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
  EXPECT_TRUE(base_view);

  std::vector<bool> vrf_states{false, true,  true, false,
                               true,  false, true, true};

  for (std::size_t i = 0; i < vrf_states.size(); ++i) {
    // View.focus.getNext should complete with the next focus state.
    auto response1 = FakePlatformMessageResponse::Create();
    base_view->HandlePlatformMessage(response1->WithMessage(
        "flutter/platform_views", "{\"method\":\"View.focus.getNext\"}"));
    // Duplicate View.focus.getNext requests should complete empty.
    auto response2 = FakePlatformMessageResponse::Create();
    base_view->HandlePlatformMessage(response2->WithMessage(
        "flutter/platform_views", "{\"method\":\"View.focus.getNext\"}"));

    // Post watch events and make sure the hanging get is invoked each time.
    RunLoopUntilIdle();
    EXPECT_EQ(vrf.times_watched, i + 1);

    // Dispatch the next vrf event.
    vrf.ScheduleCallback(vrf_states[i]);
    RunLoopUntilIdle();

    // Make sure View.focus.getCurrent completes with the current focus state.
    auto response3 = FakePlatformMessageResponse::Create();
    base_view->HandlePlatformMessage(response3->WithMessage(
        "flutter/platform_views", "{\"method\":\"View.focus.getCurrent\"}"));
    // Duplicate View.focus.getCurrent are allowed.
    auto response4 = FakePlatformMessageResponse::Create();
    base_view->HandlePlatformMessage(response4->WithMessage(
        "flutter/platform_views", "{\"method\":\"View.focus.getCurrent\"}"));

    // Run event loop and check our results.
    RunLoopUntilIdle();
    response1->ExpectCompleted(vrf_states[i] ? "[true]" : "[false]");
    response2->ExpectCompleted("[null]");
    response3->ExpectCompleted(vrf_states[i] ? "[true]" : "[false]");
    response4->ExpectCompleted(vrf_states[i] ? "[true]" : "[false]");
  }
}

// This test makes sure that the PlatformView forwards messages on the
// "flutter/platform_views" channel for View.focus.request.
TEST_F(PlatformViewTests, RequestFocusTest) {
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);

  FakeFocuser focuser;
  fidl::BindingSet<fuchsia::ui::views::Focuser> focuser_bindings;
  auto focuser_handle = focuser_bindings.AddBinding(&focuser);

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetFocuser(std::move(focuser_handle))
          .Build();

  // Cast platform_view to its base view so we can have access to the public
  // "HandlePlatformMessage" function.
  auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
  EXPECT_TRUE(base_view);

  // This "Mock" ViewRef serves as the target for the RequestFocus operation.
  auto mock_view_ref_pair = scenic::ViewRefPair::New();

  // JSON for the message to be passed into the PlatformView.
  std::ostringstream message;
  message << "{"
          << "    \"method\":\"View.focus.request\","
          << "    \"args\": {"
          << "       \"viewRef\":"
          << mock_view_ref_pair.view_ref.reference.get() << "    }"
          << "}";

  // Dispatch the plaform message request.
  auto response = FakePlatformMessageResponse::Create();
  base_view->HandlePlatformMessage(
      response->WithMessage("flutter/platform_views", message.str()));
  RunLoopUntilIdle();

  response->ExpectCompleted("[0]");
  EXPECT_TRUE(focuser.request_focus_called());
}

// This test makes sure that the PlatformView correctly replies with an error
// response when a View.focus.request call fails.
TEST_F(PlatformViewTests, RequestFocusFailTest) {
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);

  FakeFocuser focuser;
  focuser.fail_request_focus();
  fidl::BindingSet<fuchsia::ui::views::Focuser> focuser_bindings;
  auto focuser_handle = focuser_bindings.AddBinding(&focuser);

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetFocuser(std::move(focuser_handle))
          .Build();

  // Cast platform_view to its base view so we can have access to the public
  // "HandlePlatformMessage" function.
  auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
  EXPECT_TRUE(base_view);

  // This "Mock" ViewRef serves as the target for the RequestFocus operation.
  auto mock_view_ref_pair = scenic::ViewRefPair::New();

  // JSON for the message to be passed into the PlatformView.
  std::ostringstream message;
  message << "{"
          << "    \"method\":\"View.focus.request\","
          << "    \"args\": {"
          << "       \"viewRef\":"
          << mock_view_ref_pair.view_ref.reference.get() << "    }"
          << "}";

  // Dispatch the plaform message request.
  auto response = FakePlatformMessageResponse::Create();
  base_view->HandlePlatformMessage(
      response->WithMessage("flutter/platform_views", message.str()));
  RunLoopUntilIdle();

  response->ExpectCompleted(
      "[" +
      std::to_string(
          static_cast<std::underlying_type_t<fuchsia::ui::views::Error>>(
              fuchsia::ui::views::Error::DENIED)) +
      "]");
  EXPECT_TRUE(focuser.request_focus_called());
}

// Makes sure that OnKeyEvent is dispatched as a platform message.
TEST_F(PlatformViewTests, OnKeyEvent) {
  struct EventFlow {
    fuchsia::ui::input3::KeyEvent event;
    fuchsia::ui::input3::KeyEventStatus expected_key_event_status;
    std::string expected_platform_message;
  };

  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);

  fuchsia::ui::input3::KeyboardHandle keyboard_service;
  MockKeyboard keyboard(keyboard_service.NewRequest());

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetKeyboard(std::move(keyboard_service))
          .Build();
  RunLoopUntilIdle();

  std::vector<EventFlow> events;
  // Press A.  Get 'a'.
  // The HID usage for the key A is 0x70004, or 458756.
  events.emplace_back(EventFlow{
      MakeEvent(fuchsia::ui::input3::KeyEventType::PRESSED, std::nullopt,
                fuchsia::input::Key::A),
      fuchsia::ui::input3::KeyEventStatus::HANDLED,
      R"({"type":"keydown","keymap":"fuchsia","hidUsage":458756,"codePoint":97,"modifiers":0})",
  });
  // Release A. Get 'a' release.
  events.emplace_back(EventFlow{
      MakeEvent(fuchsia::ui::input3::KeyEventType::RELEASED, std::nullopt,
                fuchsia::input::Key::A),
      fuchsia::ui::input3::KeyEventStatus::HANDLED,
      R"({"type":"keyup","keymap":"fuchsia","hidUsage":458756,"codePoint":97,"modifiers":0})",
  });
  // Press CAPS_LOCK.  Modifier now active.
  events.emplace_back(EventFlow{
      MakeEvent(fuchsia::ui::input3::KeyEventType::PRESSED,
                fuchsia::ui::input3::Modifiers::CAPS_LOCK,
                fuchsia::input::Key::CAPS_LOCK),
      fuchsia::ui::input3::KeyEventStatus::HANDLED,
      R"({"type":"keydown","keymap":"fuchsia","hidUsage":458809,"codePoint":0,"modifiers":1})",
  });
  // Press A.  Get 'A'.
  events.emplace_back(EventFlow{
      MakeEvent(fuchsia::ui::input3::KeyEventType::PRESSED, std::nullopt,
                fuchsia::input::Key::A),
      fuchsia::ui::input3::KeyEventStatus::HANDLED,
      R"({"type":"keydown","keymap":"fuchsia","hidUsage":458756,"codePoint":65,"modifiers":1})",
  });
  // Release CAPS_LOCK.
  events.emplace_back(EventFlow{
      MakeEvent(fuchsia::ui::input3::KeyEventType::RELEASED,
                fuchsia::ui::input3::Modifiers::CAPS_LOCK,
                fuchsia::input::Key::CAPS_LOCK),
      fuchsia::ui::input3::KeyEventStatus::HANDLED,
      R"({"type":"keyup","keymap":"fuchsia","hidUsage":458809,"codePoint":0,"modifiers":1})",
  });
  // Press A again.  This time get 'A'.
  // CAPS_LOCK is latched active even if it was just released.
  events.emplace_back(EventFlow{
      MakeEvent(fuchsia::ui::input3::KeyEventType::PRESSED, std::nullopt,
                fuchsia::input::Key::A),
      fuchsia::ui::input3::KeyEventStatus::HANDLED,
      R"({"type":"keydown","keymap":"fuchsia","hidUsage":458756,"codePoint":65,"modifiers":1})",
  });

  for (const auto& event : events) {
    fuchsia::ui::input3::KeyEvent e;
    event.event.Clone(&e);
    fuchsia::ui::input3::KeyEventStatus key_event_status{0u};
    keyboard.listener_->OnKeyEvent(
        std::move(e),
        [&key_event_status](fuchsia::ui::input3::KeyEventStatus status) {
          key_event_status = status;
        });
    RunLoopUntilIdle();

    ASSERT_NOTNULL(delegate.message());
    EXPECT_EQ(event.expected_platform_message,
              ToString(delegate.message()->data()));
    EXPECT_EQ(event.expected_key_event_status, key_event_status);
  }
}

TEST_F(PlatformViewTests, OnShaderWarmup) {
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners =
      flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);

  uint64_t width = 200;
  uint64_t height = 100;
  std::vector<std::string> shaders = {"foo.skp", "bar.skp", "baz.skp"};

  OnShaderWarmup on_shader_warmup =
      [&](const std::vector<std::string>& shaders_in,
          std::function<void(uint32_t)> completion_callback, uint64_t width_in,
          uint64_t height_in) {
        ASSERT_EQ(shaders.size(), shaders_in.size());
        for (size_t i = 0; i < shaders_in.size(); i++) {
          ASSERT_EQ(shaders[i], shaders_in[i]);
        }
        ASSERT_EQ(width, width_in);
        ASSERT_EQ(height, height_in);

        completion_callback(shaders_in.size());
      };

  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetShaderWarmupCallback(on_shader_warmup)
          .Build();

  std::ostringstream shaders_array_ostream;
  shaders_array_ostream << "[ ";
  for (auto it = shaders.begin(); it != shaders.end(); ++it) {
    shaders_array_ostream << "\"" << *it << "\"";
    if (std::next(it) != shaders.end()) {
      shaders_array_ostream << ", ";
    }
  }
  shaders_array_ostream << "]";

  std::string shaders_array_string = shaders_array_ostream.str();

  // Create initial view for testing.
  std::ostringstream warmup_shaders_ostream;
  warmup_shaders_ostream << "{"
                         << "  \"method\":\"WarmupSkps\","
                         << "  \"args\":{"
                         << "    \"shaders\":" << shaders_array_string << ","
                         << "    \"width\":" << width << ","
                         << "    \"height\":" << height << "  }"
                         << "}\n";
  std::string warmup_shaders_string = warmup_shaders_ostream.str();

  fml::RefPtr<TestPlatformMessageResponse> response(
      new TestPlatformMessageResponse);
  static_cast<flutter::PlatformView*>(&platform_view)
      ->HandlePlatformMessage(std::make_unique<flutter::PlatformMessage>(
          "fuchsia/shader_warmup",
          fml::MallocMapping::Copy(warmup_shaders_string.c_str(),
                                   warmup_shaders_string.size()),
          response));
  RunLoopUntilIdle();
  ASSERT_TRUE(response->is_complete());

  std::ostringstream expected_result_ostream;
  expected_result_ostream << "[" << shaders.size() << "]";
  std::string expected_result_string = expected_result_ostream.str();
  EXPECT_EQ(expected_result_string, response->result_string);
}

TEST_F(PlatformViewTests, TouchSourceLogicalToPhysicalConversion) {
  constexpr std::array<std::array<float, 2>, 2> kRect = {{{0, 0}, {20, 20}}};
  constexpr std::array<float, 9> kIdentity = {1, 0, 0, 0, 1, 0, 0, 0, 1};
  constexpr fuchsia::ui::pointer::TouchInteractionId kIxnOne = {
      .device_id = 0u, .pointer_id = 1u, .interaction_id = 2u};
  constexpr float valid_pixel_ratio = 2.f;

  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners("test_runners", nullptr, nullptr, nullptr,
                                    nullptr);

  fuchsia::ui::scenic::SessionListenerPtr session_listener;
  FakeTouchSource touch_server;
  fidl::BindingSet<fuchsia::ui::pointer::TouchSource> touch_bindings;
  auto touch_handle = touch_bindings.AddBinding(&touch_server);
  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetSessionListenerRequest(session_listener.NewRequest())
          .SetTouchSource(std::move(touch_handle))
          .Build();
  RunLoopUntilIdle();
  EXPECT_EQ(delegate.pointer_packets().size(), 0u);

  // Set logical-to-physical metrics and logical view size
  std::vector<fuchsia::ui::scenic::Event> scenic_events;
  scenic_events.emplace_back(fuchsia::ui::scenic::Event::WithGfx(
      fuchsia::ui::gfx::Event::WithMetrics(fuchsia::ui::gfx::MetricsEvent{
          .node_id = 0,
          .metrics =
              fuchsia::ui::gfx::Metrics{
                  .scale_x = valid_pixel_ratio,
                  .scale_y = valid_pixel_ratio,
                  .scale_z = valid_pixel_ratio,
              },
      })));
  scenic_events.emplace_back(
      fuchsia::ui::scenic::Event::WithGfx(
          fuchsia::ui::gfx::Event::WithViewPropertiesChanged(
              fuchsia::ui::gfx::ViewPropertiesChangedEvent{
                  .view_id = 0,
                  .properties =
                      fuchsia::ui::gfx::ViewProperties{
                          .bounding_box =
                              fuchsia::ui::gfx::BoundingBox{
                                  .min =
                                      fuchsia::ui::gfx::vec3{
                                          .x = 0.f,
                                          .y = 0.f,
                                          .z = 0.f,
                                      },
                                  .max =
                                      fuchsia::ui::gfx::vec3{
                                          .x = 20.f,
                                          .y = 20.f,
                                          .z = 20.f,
                                      },
                              },
                      },
              })));
  session_listener->OnScenicEvent(std::move(scenic_events));
  RunLoopUntilIdle();
  EXPECT_EQ(delegate.metrics(), flutter::ViewportMetrics(2.f, 40.f, 40.f, -1));

  // Inject
  std::vector<fuchsia::ui::pointer::TouchEvent> events =
      TouchEventBuilder::New()
          .AddTime(/* in nanoseconds */ 1111789u)
          .AddViewParameters(kRect, kRect, kIdentity)
          .AddSample(kIxnOne, fuchsia::ui::pointer::EventPhase::ADD,
                     {10.f, 10.f})
          .AddResult(
              {.interaction = kIxnOne,
               .status = fuchsia::ui::pointer::TouchInteractionStatus::GRANTED})
          .BuildAsVector();
  touch_server.ScheduleCallback(std::move(events));
  RunLoopUntilIdle();

  // Unpack
  std::vector<std::unique_ptr<flutter::PointerDataPacket>> packets =
      delegate.TakePointerDataPackets();
  ASSERT_EQ(packets.size(), 1u);
  std::vector<flutter::PointerData> flutter_events;
  UnpackPointerPacket(flutter_events, std::move(packets[0]));

  // Examine phases
  ASSERT_EQ(flutter_events.size(), 2u);
  EXPECT_EQ(flutter_events[0].change, flutter::PointerData::Change::kAdd);
  EXPECT_EQ(flutter_events[1].change, flutter::PointerData::Change::kDown);

  // Examine coordinates
  // With metrics defined, observe metrics ratio applied.
  EXPECT_EQ(flutter_events[0].physical_x, 20.f);
  EXPECT_EQ(flutter_events[0].physical_y, 20.f);
  EXPECT_EQ(flutter_events[1].physical_x, 20.f);
  EXPECT_EQ(flutter_events[1].physical_y, 20.f);
}

TEST_F(PlatformViewTests, DownPointerNumericNudge) {
  constexpr float kSmallDiscrepancy = -0.00003f;

  fuchsia::ui::scenic::SessionListenerPtr session_listener;
  MockPlatformViewDelegate delegate;
  flutter::TaskRunners task_runners("test_runners", nullptr, nullptr, nullptr,
                                    nullptr);
  flutter_runner::GfxPlatformView platform_view =
      PlatformViewBuilder(delegate, std::move(task_runners))
          .SetSessionListenerRequest(session_listener.NewRequest())
          .Build();
  RunLoopUntilIdle();
  EXPECT_EQ(delegate.pointer_packets().size(), 0u);

  std::vector<fuchsia::ui::scenic::Event> events;
  events.emplace_back(
      fuchsia::ui::scenic::Event::WithGfx(
          fuchsia::ui::gfx::Event::WithViewPropertiesChanged(
              fuchsia::ui::gfx::ViewPropertiesChangedEvent{
                  .view_id = 0,
                  .properties =
                      fuchsia::ui::gfx::ViewProperties{
                          .bounding_box =
                              fuchsia::ui::gfx::BoundingBox{
                                  .min =
                                      fuchsia::ui::gfx::vec3{
                                          .x = 0.f,
                                          .y = 0.f,
                                          .z = 0.f,
                                      },
                                  .max =
                                      fuchsia::ui::gfx::vec3{
                                          .x = 100.f,
                                          .y = 100.f,
                                          .z = 100.f,
                                      },
                              },
                      },
              })));
  events.emplace_back(fuchsia::ui::scenic::Event::WithGfx(
      fuchsia::ui::gfx::Event::WithMetrics(fuchsia::ui::gfx::MetricsEvent{
          .node_id = 0,
          .metrics =
              fuchsia::ui::gfx::Metrics{
                  .scale_x = 1.f,
                  .scale_y = 1.f,
                  .scale_z = 1.f,
              },
      })));
  events.emplace_back(fuchsia::ui::scenic::Event::WithInput(
      fuchsia::ui::input::InputEvent::WithPointer(
          fuchsia::ui::input::PointerEvent{
              .event_time = 1111,
              .device_id = 2222,
              .pointer_id = 3333,
              .type = fuchsia::ui::input::PointerEventType::TOUCH,
              .phase = fuchsia::ui::input::PointerEventPhase::ADD,
              .x = 50.f,
              .y = kSmallDiscrepancy,  // floating point inaccuracy
              .radius_major = 0.f,
              .radius_minor = 0.f,
              .buttons = 0u,
          })));
  events.emplace_back(fuchsia::ui::scenic::Event::WithInput(
      fuchsia::ui::input::InputEvent::WithPointer(
          fuchsia::ui::input::PointerEvent{
              .event_time = 1111,
              .device_id = 2222,
              .pointer_id = 3333,
              .type = fuchsia::ui::input::PointerEventType::TOUCH,
              .phase = fuchsia::ui::input::PointerEventPhase::DOWN,
              .x = 50.f,
              .y = kSmallDiscrepancy,  // floating point inaccuracy
              .radius_major = 0.f,
              .radius_minor = 0.f,
              .buttons = 0u,
          })));
  events.emplace_back(fuchsia::ui::scenic::Event::WithInput(
      fuchsia::ui::input::InputEvent::WithPointer(
          fuchsia::ui::input::PointerEvent{
              .event_time = 1111,
              .device_id = 2222,
              .pointer_id = 3333,
              .type = fuchsia::ui::input::PointerEventType::TOUCH,
              .phase = fuchsia::ui::input::PointerEventPhase::MOVE,
              .x = 50.f,
              .y = kSmallDiscrepancy,  // floating point inaccuracy
              .radius_major = 0.f,
              .radius_minor = 0.f,
              .buttons = 0u,
          })));
  session_listener->OnScenicEvent(std::move(events));
  RunLoopUntilIdle();
  ASSERT_EQ(delegate.pointer_packets().size(), 3u);

  // Embedder issues pointer data in a bytestream format, PointerDataPacket.
  // Use this handy utility to recover data as a C struct, PointerData.
  std::vector<std::unique_ptr<flutter::PointerDataPacket>> packets =
      delegate.TakePointerDataPackets();
  std::vector<flutter::PointerData> add, down, move;
  UnpackPointerPacket(add, std::move(packets[0]));
  UnpackPointerPacket(down, std::move(packets[1]));
  UnpackPointerPacket(move, std::move(packets[2]));

  EXPECT_EQ(add[0].physical_x, 50.f);
  EXPECT_EQ(add[0].physical_y, kSmallDiscrepancy);
  EXPECT_EQ(down[0].physical_x, 50.f);
  EXPECT_EQ(down[0].physical_y, 0.f);  // clamping happened
  EXPECT_EQ(move[0].physical_x, 50.f);
  EXPECT_EQ(move[0].physical_y, kSmallDiscrepancy);
}

}  // namespace flutter_runner::testing
