// 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 "flutter/shell/common/engine.h"

// #include <cstring>

#include "flutter/common/constants.h"
#include "flutter/lib/ui/compositing/scene_builder.h"
#include "flutter/shell/common/shell_test.h"
#include "flutter/testing/fixture_test.h"
#include "gmock/gmock.h"

// CREATE_NATIVE_ENTRY is leaky by design
// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)

namespace flutter {

namespace {

using ::testing::Invoke;
using ::testing::ReturnRef;

fml::AutoResetWaitableEvent native_latch;

void PostSync(const fml::RefPtr<fml::TaskRunner>& task_runner,
              const fml::closure& task) {
  fml::AutoResetWaitableEvent latch;
  fml::TaskRunner::RunNowOrPostTask(task_runner, [&latch, &task] {
    task();
    latch.Signal();
  });
  latch.Wait();
}

// Sort the argument list of `LayerTreeTask` into a new list that is sorted by
// their view IDs. `FrameItem::layer_tree_tasks` might not come sorted.
std::vector<const LayerTreeTask*> Sorted(
    const std::vector<std::unique_ptr<LayerTreeTask>>& layer_tree_tasks) {
  std::vector<const LayerTreeTask*> result;
  result.reserve(layer_tree_tasks.size());
  for (auto& task_ptr : layer_tree_tasks) {
    result.push_back(task_ptr.get());
  }
  std::sort(result.begin(), result.end(),
            [](const LayerTreeTask* a, const LayerTreeTask* b) {
              return a->view_id < b->view_id;
            });
  return result;
}

class MockDelegate : public Engine::Delegate {
 public:
  MOCK_METHOD(void,
              OnEngineUpdateSemantics,
              (SemanticsNodeUpdates, CustomAccessibilityActionUpdates),
              (override));
  MOCK_METHOD(void,
              OnEngineHandlePlatformMessage,
              (std::unique_ptr<PlatformMessage>),
              (override));
  MOCK_METHOD(void, OnPreEngineRestart, (), (override));
  MOCK_METHOD(void, OnRootIsolateCreated, (), (override));
  MOCK_METHOD(void,
              UpdateIsolateDescription,
              (const std::string, int64_t),
              (override));
  MOCK_METHOD(void, SetNeedsReportTimings, (bool), (override));
  MOCK_METHOD(std::unique_ptr<std::vector<std::string>>,
              ComputePlatformResolvedLocale,
              (const std::vector<std::string>&),
              (override));
  MOCK_METHOD(void, RequestDartDeferredLibrary, (intptr_t), (override));
  MOCK_METHOD(fml::TimePoint, GetCurrentTimePoint, (), (override));
  MOCK_METHOD(const std::shared_ptr<PlatformMessageHandler>&,
              GetPlatformMessageHandler,
              (),
              (const, override));
  MOCK_METHOD(void, OnEngineChannelUpdate, (std::string, bool), (override));
  MOCK_METHOD(double,
              GetScaledFontSize,
              (double font_size, int configuration_id),
              (const, override));
};

class MockAnimatorDelegate : public Animator::Delegate {
 public:
  /* Animator::Delegate */
  MOCK_METHOD(void,
              OnAnimatorBeginFrame,
              (fml::TimePoint frame_target_time, uint64_t frame_number),
              (override));
  MOCK_METHOD(void,
              OnAnimatorNotifyIdle,
              (fml::TimeDelta deadline),
              (override));
  MOCK_METHOD(void,
              OnAnimatorUpdateLatestFrameTargetTime,
              (fml::TimePoint frame_target_time),
              (override));
  MOCK_METHOD(void,
              OnAnimatorDraw,
              (std::shared_ptr<FramePipeline> pipeline),
              (override));
  MOCK_METHOD(void,
              OnAnimatorDrawLastLayerTrees,
              (std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder),
              (override));
};

class MockPlatformMessageHandler : public PlatformMessageHandler {
 public:
  MOCK_METHOD(void,
              HandlePlatformMessage,
              (std::unique_ptr<PlatformMessage> message),
              (override));
  MOCK_METHOD(bool,
              DoesHandlePlatformMessageOnPlatformThread,
              (),
              (const, override));
  MOCK_METHOD(void,
              InvokePlatformMessageResponseCallback,
              (int response_id, std::unique_ptr<fml::Mapping> mapping),
              (override));
  MOCK_METHOD(void,
              InvokePlatformMessageEmptyResponseCallback,
              (int response_id),
              (override));
};

class EngineAnimatorTest : public testing::FixtureTest {
 public:
  EngineAnimatorTest()
      : thread_host_("EngineAnimatorTest",
                     ThreadHost::Type::kPlatform | ThreadHost::Type::kIo |
                         ThreadHost::Type::kUi | ThreadHost::Type::kRaster),
        task_runners_({
            "EngineAnimatorTest",
            thread_host_.platform_thread->GetTaskRunner(),  // platform
            thread_host_.raster_thread->GetTaskRunner(),    // raster
            thread_host_.ui_thread->GetTaskRunner(),        // ui
            thread_host_.io_thread->GetTaskRunner()         // io
        }) {}

  void PostUITaskSync(const std::function<void()>& function) {
    fml::AutoResetWaitableEvent latch;
    task_runners_.GetUITaskRunner()->PostTask([&] {
      function();
      latch.Signal();
    });
    latch.Wait();
  }

 protected:
  void SetUp() override {
    settings_ = CreateSettingsForFixture();
    dispatcher_maker_ = [](PointerDataDispatcher::Delegate&) {
      return nullptr;
    };
  }

  MockDelegate delegate_;
  PointerDataDispatcherMaker dispatcher_maker_;
  ThreadHost thread_host_;
  TaskRunners task_runners_;
  Settings settings_;
  std::unique_ptr<Animator> animator_;
  fml::WeakPtr<IOManager> io_manager_;
  std::unique_ptr<RuntimeController> runtime_controller_;
  std::shared_ptr<fml::ConcurrentTaskRunner> image_decoder_task_runner_;
  fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate_;
};

// A class that can launch an Engine with the specified Engine::Delegate.
//
// To use this class, contruct this class with Create, call Run, and use the
// engine with EngineTaskSync().
class EngineContext {
 public:
  using EngineCallback = std::function<void(Engine&)>;

  [[nodiscard]] static std::unique_ptr<EngineContext> Create(
      Engine::Delegate& delegate,       //
      Settings settings,                //
      const TaskRunners& task_runners,  //
      std::unique_ptr<Animator> animator) {
    auto [vm, isolate_snapshot] = Shell::InferVmInitDataFromSettings(settings);
    FML_CHECK(vm) << "Must be able to initialize the VM.";
    // Construct the class with `new` because `make_unique` has no access to the
    // private constructor.
    EngineContext* raw_pointer =
        new EngineContext(delegate, settings, task_runners, std::move(animator),
                          vm, isolate_snapshot);
    return std::unique_ptr<EngineContext>(raw_pointer);
  }

  void Run(RunConfiguration configuration) {
    PostSync(task_runners_.GetUITaskRunner(), [this, &configuration] {
      Engine::RunStatus run_status = engine_->Run(std::move(configuration));
      FML_CHECK(run_status == Engine::RunStatus::Success)
          << "Engine failed to run.";
      (void)run_status;  // Suppress unused-variable warning
    });
  }

  // Run a task that operates the Engine on the UI thread, and wait for the
  // task to end.
  //
  // If called on the UI thread, the task is executed synchronously.
  void EngineTaskSync(EngineCallback task) {
    ASSERT_TRUE(engine_);
    ASSERT_TRUE(task);
    auto runner = task_runners_.GetUITaskRunner();
    if (runner->RunsTasksOnCurrentThread()) {
      task(*engine_);
    } else {
      PostSync(task_runners_.GetUITaskRunner(), [&]() { task(*engine_); });
    }
  }

  ~EngineContext() {
    PostSync(task_runners_.GetUITaskRunner(), [this] { engine_.reset(); });
  }

 private:
  EngineContext(Engine::Delegate& delegate,          //
                Settings settings,                   //
                const TaskRunners& task_runners,     //
                std::unique_ptr<Animator> animator,  //
                const DartVMRef& vm,                 //
                fml::RefPtr<const DartSnapshot> isolate_snapshot)
      : task_runners_(task_runners), vm_(vm) {
    PostSync(task_runners.GetUITaskRunner(), [this, &settings, &animator,
                                              &delegate, &isolate_snapshot] {
      auto dispatcher_maker =
          [](DefaultPointerDataDispatcher::Delegate& delegate) {
            return std::make_unique<DefaultPointerDataDispatcher>(delegate);
          };
      engine_ = std::make_unique<Engine>(
          /*delegate=*/delegate,
          /*dispatcher_maker=*/dispatcher_maker,
          /*vm=*/*&vm_,
          /*isolate_snapshot=*/std::move(isolate_snapshot),
          /*task_runners=*/task_runners_,
          /*platform_data=*/PlatformData(),
          /*settings=*/settings,
          /*animator=*/std::move(animator),
          /*io_manager=*/io_manager_,
          /*unref_queue=*/nullptr,
          /*snapshot_delegate=*/snapshot_delegate_,
          /*volatile_path_tracker=*/nullptr,
          /*gpu_disabled_switch=*/std::make_shared<fml::SyncSwitch>());
    });
  }

  TaskRunners task_runners_;
  DartVMRef vm_;
  std::unique_ptr<Engine> engine_;

  fml::WeakPtr<IOManager> io_manager_;
  fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate_;
};
}  // namespace

TEST_F(EngineAnimatorTest, AnimatorAcceptsMultipleRenders) {
  MockAnimatorDelegate animator_delegate;
  std::unique_ptr<EngineContext> engine_context;

  std::shared_ptr<PlatformMessageHandler> platform_message_handler =
      std::make_shared<MockPlatformMessageHandler>();
  EXPECT_CALL(delegate_, GetPlatformMessageHandler)
      .WillOnce(ReturnRef(platform_message_handler));
  fml::AutoResetWaitableEvent draw_latch;
  EXPECT_CALL(animator_delegate, OnAnimatorDraw)
      .WillOnce(
          Invoke([&draw_latch](const std::shared_ptr<FramePipeline>& pipeline) {
            auto status =
                pipeline->Consume([&](std::unique_ptr<FrameItem> item) {
                  auto tasks = Sorted(item->layer_tree_tasks);
                  EXPECT_EQ(tasks.size(), 2u);
                  EXPECT_EQ(tasks[0]->view_id, 1);
                  EXPECT_EQ(tasks[1]->view_id, 2);
                });
            EXPECT_EQ(status, PipelineConsumeResult::Done);
            draw_latch.Signal();
          }));
  EXPECT_CALL(animator_delegate, OnAnimatorBeginFrame)
      .WillOnce(Invoke([&engine_context](fml::TimePoint frame_target_time,
                                         uint64_t frame_number) {
        engine_context->EngineTaskSync([&](Engine& engine) {
          engine.BeginFrame(frame_target_time, frame_number);
        });
      }));

  native_latch.Reset();
  AddNativeCallback("NotifyNative", [](auto args) { native_latch.Signal(); });

  std::unique_ptr<Animator> animator;
  PostSync(task_runners_.GetUITaskRunner(),
           [&animator, &animator_delegate, &task_runners = task_runners_] {
             animator = std::make_unique<Animator>(
                 animator_delegate, task_runners,
                 static_cast<std::unique_ptr<VsyncWaiter>>(
                     std::make_unique<testing::ConstantFiringVsyncWaiter>(
                         task_runners)));
           });

  engine_context = EngineContext::Create(delegate_, settings_, task_runners_,
                                         std::move(animator));
  auto configuration = RunConfiguration::InferFromSettings(settings_);
  configuration.SetEntrypoint("onDrawFrameRenderAllViews");
  engine_context->Run(std::move(configuration));

  engine_context->EngineTaskSync([](Engine& engine) {
    engine.AddView(1, ViewportMetrics{1, 10, 10, 22, 0},
                   [](bool added) { ASSERT_TRUE(added); });
    engine.AddView(2, ViewportMetrics{1, 10, 10, 22, 0},
                   [](bool added) { ASSERT_TRUE(added); });
  });

  native_latch.Wait();

  engine_context->EngineTaskSync(
      [](Engine& engine) { engine.ScheduleFrame(); });
  draw_latch.Wait();
}

TEST_F(EngineAnimatorTest, IgnoresOutOfFrameRenders) {
  MockAnimatorDelegate animator_delegate;
  std::unique_ptr<EngineContext> engine_context;

  std::shared_ptr<PlatformMessageHandler> platform_message_handler =
      std::make_shared<MockPlatformMessageHandler>();
  EXPECT_CALL(delegate_, GetPlatformMessageHandler)
      .WillOnce(ReturnRef(platform_message_handler));
  fml::AutoResetWaitableEvent draw_latch;
  EXPECT_CALL(animator_delegate, OnAnimatorDraw)
      .WillOnce(
          Invoke([&draw_latch](const std::shared_ptr<FramePipeline>& pipeline) {
            auto status =
                pipeline->Consume([&](std::unique_ptr<FrameItem> item) {
                  // View 1 is rendered before the frame, and is ignored.
                  // View 2 is rendered within the frame, and is accepted.
                  EXPECT_EQ(item->layer_tree_tasks.size(), 1u);
                  EXPECT_EQ(item->layer_tree_tasks[0]->view_id, 2);
                });
            EXPECT_EQ(status, PipelineConsumeResult::Done);
            draw_latch.Signal();
          }));
  EXPECT_CALL(animator_delegate, OnAnimatorBeginFrame)
      .WillOnce(Invoke([&engine_context](fml::TimePoint frame_target_time,
                                         uint64_t frame_number) {
        engine_context->EngineTaskSync([&](Engine& engine) {
          engine.BeginFrame(frame_target_time, frame_number);
        });
      }));

  std::unique_ptr<Animator> animator;
  PostSync(task_runners_.GetUITaskRunner(),
           [&animator, &animator_delegate, &task_runners = task_runners_] {
             animator = std::make_unique<Animator>(
                 animator_delegate, task_runners,
                 static_cast<std::unique_ptr<VsyncWaiter>>(
                     std::make_unique<testing::ConstantFiringVsyncWaiter>(
                         task_runners)));
           });

  engine_context = EngineContext::Create(delegate_, settings_, task_runners_,
                                         std::move(animator));

  engine_context->EngineTaskSync([](Engine& engine) {
    engine.AddView(1, ViewportMetrics{1, 10, 10, 22, 0},
                   [](bool added) { ASSERT_TRUE(added); });
    engine.AddView(2, ViewportMetrics{1, 10, 10, 22, 0},
                   [](bool added) { ASSERT_TRUE(added); });
  });

  auto configuration = RunConfiguration::InferFromSettings(settings_);
  configuration.SetEntrypoint("renderViewsInFrameAndOutOfFrame");
  engine_context->Run(std::move(configuration));

  draw_latch.Wait();
}

TEST_F(EngineAnimatorTest, IgnoresDuplicateRenders) {
  MockAnimatorDelegate animator_delegate;
  std::unique_ptr<EngineContext> engine_context;

  std::vector<std::shared_ptr<Layer>> benchmark_layers;
  auto capture_root_layer = [&benchmark_layers](Dart_NativeArguments args) {
    auto handle = Dart_GetNativeArgument(args, 0);
    intptr_t peer = 0;
    Dart_Handle result = Dart_GetNativeInstanceField(
        handle, tonic::DartWrappable::kPeerIndex, &peer);
    ASSERT_FALSE(Dart_IsError(result));
    SceneBuilder* scene_builder = reinterpret_cast<SceneBuilder*>(peer);
    ASSERT_TRUE(scene_builder);
    std::shared_ptr<ContainerLayer> root_layer =
        scene_builder->layer_stack()[0];
    ASSERT_TRUE(root_layer);
    benchmark_layers = root_layer->layers();
  };

  std::shared_ptr<PlatformMessageHandler> platform_message_handler =
      std::make_shared<MockPlatformMessageHandler>();
  EXPECT_CALL(delegate_, GetPlatformMessageHandler)
      .WillOnce(ReturnRef(platform_message_handler));
  fml::AutoResetWaitableEvent draw_latch;
  EXPECT_CALL(animator_delegate, OnAnimatorDraw)
      .WillOnce(Invoke([&draw_latch, &benchmark_layers](
                           const std::shared_ptr<FramePipeline>& pipeline) {
        auto status = pipeline->Consume([&](std::unique_ptr<FrameItem> item) {
          EXPECT_EQ(item->layer_tree_tasks.size(), 1u);
          EXPECT_EQ(item->layer_tree_tasks[0]->view_id, kFlutterImplicitViewId);
          ContainerLayer* root_layer = reinterpret_cast<ContainerLayer*>(
              item->layer_tree_tasks[0]->layer_tree->root_layer());
          std::vector<std::shared_ptr<Layer>> result_layers =
              root_layer->layers();
          EXPECT_EQ(result_layers.size(), benchmark_layers.size());
          EXPECT_EQ(result_layers[0], benchmark_layers[0]);
        });
        EXPECT_EQ(status, PipelineConsumeResult::Done);
        draw_latch.Signal();
      }));
  EXPECT_CALL(animator_delegate, OnAnimatorBeginFrame)
      .WillOnce(Invoke([&engine_context](fml::TimePoint frame_target_time,
                                         uint64_t frame_number) {
        engine_context->EngineTaskSync([&](Engine& engine) {
          engine.BeginFrame(frame_target_time, frame_number);
        });
      }));

  AddNativeCallback("CaptureRootLayer",
                    CREATE_NATIVE_ENTRY(capture_root_layer));

  std::unique_ptr<Animator> animator;
  PostSync(task_runners_.GetUITaskRunner(),
           [&animator, &animator_delegate, &task_runners = task_runners_] {
             animator = std::make_unique<Animator>(
                 animator_delegate, task_runners,
                 static_cast<std::unique_ptr<VsyncWaiter>>(
                     std::make_unique<testing::ConstantFiringVsyncWaiter>(
                         task_runners)));
           });

  engine_context = EngineContext::Create(delegate_, settings_, task_runners_,
                                         std::move(animator));

  engine_context->EngineTaskSync([](Engine& engine) {
    engine.AddView(kFlutterImplicitViewId, ViewportMetrics{1, 10, 10, 22, 0},
                   [](bool added) { ASSERT_TRUE(added); });
  });

  auto configuration = RunConfiguration::InferFromSettings(settings_);
  configuration.SetEntrypoint("renderTwiceForOneView");
  engine_context->Run(std::move(configuration));

  draw_latch.Wait();
}

TEST_F(EngineAnimatorTest, AnimatorSubmitsImplicitViewBeforeDrawFrameEnds) {
  MockAnimatorDelegate animator_delegate;
  std::unique_ptr<EngineContext> engine_context;

  std::shared_ptr<PlatformMessageHandler> platform_message_handler =
      std::make_shared<MockPlatformMessageHandler>();
  EXPECT_CALL(delegate_, GetPlatformMessageHandler)
      .WillOnce(ReturnRef(platform_message_handler));

  bool rasterization_started = false;
  EXPECT_CALL(animator_delegate, OnAnimatorDraw)
      .WillOnce(Invoke([&rasterization_started](
                           const std::shared_ptr<FramePipeline>& pipeline) {
        rasterization_started = true;
        auto status = pipeline->Consume([&](std::unique_ptr<FrameItem> item) {
          EXPECT_EQ(item->layer_tree_tasks.size(), 1u);
          EXPECT_EQ(item->layer_tree_tasks[0]->view_id, kFlutterImplicitViewId);
        });
        EXPECT_EQ(status, PipelineConsumeResult::Done);
      }));
  EXPECT_CALL(animator_delegate, OnAnimatorBeginFrame)
      .WillRepeatedly(Invoke([&engine_context](fml::TimePoint frame_target_time,
                                               uint64_t frame_number) {
        engine_context->EngineTaskSync([&](Engine& engine) {
          engine.BeginFrame(frame_target_time, frame_number);
        });
      }));

  std::unique_ptr<Animator> animator;
  PostSync(task_runners_.GetUITaskRunner(),
           [&animator, &animator_delegate, &task_runners = task_runners_] {
             animator = std::make_unique<Animator>(
                 animator_delegate, task_runners,
                 static_cast<std::unique_ptr<VsyncWaiter>>(
                     std::make_unique<testing::ConstantFiringVsyncWaiter>(
                         task_runners)));
           });

  native_latch.Reset();
  // The native_latch is signaled at the end of handleDrawFrame.
  AddNativeCallback("NotifyNative",
                    CREATE_NATIVE_ENTRY([&rasterization_started](auto args) {
                      EXPECT_EQ(rasterization_started, true);
                      native_latch.Signal();
                    }));

  engine_context = EngineContext::Create(delegate_, settings_, task_runners_,
                                         std::move(animator));

  engine_context->EngineTaskSync([](Engine& engine) {
    engine.AddView(kFlutterImplicitViewId, ViewportMetrics{1.0, 10, 10, 1, 0},
                   [](bool added) { ASSERT_TRUE(added); });
  });

  auto configuration = RunConfiguration::InferFromSettings(settings_);
  configuration.SetEntrypoint("renderSingleViewAndCallAfterOnDrawFrame");
  engine_context->Run(std::move(configuration));

  native_latch.Wait();
}

// The animator should submit to the pipeline the implicit view rendered in a
// warm up frame if there's already a continuation (i.e. Animator::BeginFrame
// has been called)
TEST_F(EngineAnimatorTest, AnimatorSubmitWarmUpImplicitView) {
  MockAnimatorDelegate animator_delegate;
  std::unique_ptr<EngineContext> engine_context;

  std::shared_ptr<PlatformMessageHandler> platform_message_handler =
      std::make_shared<MockPlatformMessageHandler>();
  EXPECT_CALL(delegate_, GetPlatformMessageHandler)
      .WillOnce(ReturnRef(platform_message_handler));

  fml::AutoResetWaitableEvent continuation_ready_latch;
  fml::AutoResetWaitableEvent draw_latch;
  EXPECT_CALL(animator_delegate, OnAnimatorDraw)
      .WillOnce(Invoke([&draw_latch](
                           const std::shared_ptr<FramePipeline>& pipeline) {
        auto status = pipeline->Consume([&](std::unique_ptr<FrameItem> item) {
          EXPECT_EQ(item->layer_tree_tasks.size(), 1u);
          EXPECT_EQ(item->layer_tree_tasks[0]->view_id, kFlutterImplicitViewId);
        });
        EXPECT_EQ(status, PipelineConsumeResult::Done);
        draw_latch.Signal();
      }));
  EXPECT_CALL(animator_delegate, OnAnimatorBeginFrame)
      .WillRepeatedly(
          Invoke([&engine_context, &continuation_ready_latch](
                     fml::TimePoint frame_target_time, uint64_t frame_number) {
            continuation_ready_latch.Signal();
            engine_context->EngineTaskSync([&](Engine& engine) {
              engine.BeginFrame(frame_target_time, frame_number);
            });
          }));

  std::unique_ptr<Animator> animator;
  PostSync(task_runners_.GetUITaskRunner(),
           [&animator, &animator_delegate, &task_runners = task_runners_] {
             animator = std::make_unique<Animator>(
                 animator_delegate, task_runners,
                 static_cast<std::unique_ptr<VsyncWaiter>>(
                     std::make_unique<testing::ConstantFiringVsyncWaiter>(
                         task_runners)));
           });

  engine_context = EngineContext::Create(delegate_, settings_, task_runners_,
                                         std::move(animator));

  engine_context->EngineTaskSync([](Engine& engine) {
    // Schedule a frame to trigger Animator::BeginFrame to create a
    // continuation. The continuation needs to be available before `Engine::Run`
    // since the Dart program immediately schedules a warm up frame.
    engine.ScheduleFrame(true);
    // Add the implicit view so that the engine recognizes it and that its
    // metrics is not empty.
    engine.AddView(kFlutterImplicitViewId, ViewportMetrics{1.0, 10, 10, 1, 0},
                   [](bool added) { ASSERT_TRUE(added); });
  });
  continuation_ready_latch.Wait();

  auto configuration = RunConfiguration::InferFromSettings(settings_);
  configuration.SetEntrypoint("renderWarmUpImplicitView");
  engine_context->Run(std::move(configuration));

  draw_latch.Wait();
}

// The warm up frame should work if only some of the registered views are
// included.
//
// This test also verifies that the warm up frame can render multiple views.
TEST_F(EngineAnimatorTest, AnimatorSubmitPartialViewsForWarmUp) {
  MockAnimatorDelegate animator_delegate;
  std::unique_ptr<EngineContext> engine_context;

  std::shared_ptr<PlatformMessageHandler> platform_message_handler =
      std::make_shared<MockPlatformMessageHandler>();
  EXPECT_CALL(delegate_, GetPlatformMessageHandler)
      .WillOnce(ReturnRef(platform_message_handler));

  fml::AutoResetWaitableEvent continuation_ready_latch;
  fml::AutoResetWaitableEvent draw_latch;
  EXPECT_CALL(animator_delegate, OnAnimatorDraw)
      .WillOnce(
          Invoke([&draw_latch](const std::shared_ptr<FramePipeline>& pipeline) {
            auto status =
                pipeline->Consume([&](std::unique_ptr<FrameItem> item) {
                  auto tasks = Sorted(item->layer_tree_tasks);
                  EXPECT_EQ(tasks.size(), 2u);
                  EXPECT_EQ(tasks[0]->view_id, 1);
                  EXPECT_EQ(tasks[1]->view_id, 2);
                });
            EXPECT_EQ(status, PipelineConsumeResult::Done);
            draw_latch.Signal();
          }));
  EXPECT_CALL(animator_delegate, OnAnimatorBeginFrame)
      .WillRepeatedly(
          Invoke([&engine_context, &continuation_ready_latch](
                     fml::TimePoint frame_target_time, uint64_t frame_number) {
            continuation_ready_latch.Signal();
            engine_context->EngineTaskSync([&](Engine& engine) {
              engine.BeginFrame(frame_target_time, frame_number);
            });
          }));

  std::unique_ptr<Animator> animator;
  PostSync(task_runners_.GetUITaskRunner(),
           [&animator, &animator_delegate, &task_runners = task_runners_] {
             animator = std::make_unique<Animator>(
                 animator_delegate, task_runners,
                 static_cast<std::unique_ptr<VsyncWaiter>>(
                     std::make_unique<testing::ConstantFiringVsyncWaiter>(
                         task_runners)));
           });

  engine_context = EngineContext::Create(delegate_, settings_, task_runners_,
                                         std::move(animator));

  engine_context->EngineTaskSync([](Engine& engine) {
    // Schedule a frame to make the animator create a continuation.
    engine.ScheduleFrame(true);
    // Add multiple views.
    engine.AddView(0, ViewportMetrics{1, 10, 10, 22, 0},
                   [](bool added) { ASSERT_TRUE(added); });
    engine.AddView(1, ViewportMetrics{1, 10, 10, 22, 0},
                   [](bool added) { ASSERT_TRUE(added); });
    engine.AddView(2, ViewportMetrics{1, 10, 10, 22, 0},
                   [](bool added) { ASSERT_TRUE(added); });
  });

  continuation_ready_latch.Wait();

  auto configuration = RunConfiguration::InferFromSettings(settings_);
  configuration.SetEntrypoint("renderWarmUpView1and2");
  engine_context->Run(std::move(configuration));

  draw_latch.Wait();
}

}  // namespace flutter

// NOLINTEND(clang-analyzer-core.StackAddressEscape)
