// Copyright 2017 The Chromium 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 "cc/trees/image_animation_controller.h"

#include <memory>

#include "base/run_loop.h"
#include "base/test/gtest_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {

class FakeAnimationDriver : public ImageAnimationController::AnimationDriver {
 public:
  FakeAnimationDriver() = default;
  ~FakeAnimationDriver() override = default;

  void set_should_animate(bool should_animate) {
    should_animate_ = should_animate;
  }

  // ImageAnimationController::AnimationDriver implementation.
  bool ShouldAnimate(PaintImage::Id paint_image_id) const override {
    return should_animate_;
  }

 private:
  bool should_animate_ = true;
};

class DelayTrackingTaskRunner : public base::SingleThreadTaskRunner {
 public:
  explicit DelayTrackingTaskRunner(base::SingleThreadTaskRunner* task_runner)
      : task_runner_(task_runner) {}

  bool PostDelayedTask(const base::Location& from_here,
                       base::OnceClosure task,
                       base::TimeDelta delay) override {
    last_delay_.emplace(delay);
    return task_runner_->PostTask(from_here, std::move(task));
  }

  bool RunsTasksInCurrentSequence() const override {
    return task_runner_->RunsTasksInCurrentSequence();
  }

  bool PostNonNestableDelayedTask(const base::Location& from_here,
                                  base::OnceClosure task,
                                  base::TimeDelta delay) override {
    last_delay_.emplace(delay);
    return task_runner_->PostTask(from_here, std::move(task));
  }

  void VerifyDelay(base::TimeDelta expected) {
    DCHECK(last_delay_.has_value());
    EXPECT_EQ(last_delay_.value(), expected);
    last_delay_.reset();
  }

  bool has_delay() const { return last_delay_.has_value(); }

 private:
  ~DelayTrackingTaskRunner() override = default;

  base::Optional<base::TimeDelta> last_delay_;
  base::SingleThreadTaskRunner* task_runner_;
};

class ImageAnimationControllerTest : public testing::Test {
 public:
  void SetUp() override {
    task_runner_ =
        new DelayTrackingTaskRunner(base::ThreadTaskRunnerHandle::Get().get());
    base::Closure invalidation_callback =
        base::Bind(&ImageAnimationControllerTest::RequestInvalidation,
                   base::Unretained(this));
    controller_ = std::make_unique<ImageAnimationController>(
        task_runner_.get(), invalidation_callback,
        GetEnableImageAnimationResync());
    now_ += base::TimeDelta::FromSeconds(10);
  }

  void TearDown() override { controller_.reset(); }

  void LoopOnceNoDelay(PaintImage::Id paint_image_id,
                       const std::vector<FrameMetadata>& frames,
                       size_t num_of_frames_to_loop,
                       int repetitions_completed,
                       bool restarting = false) {
    DCHECK_LE(num_of_frames_to_loop, frames.size());

    invalidation_count_ = 0;
    for (size_t i = 0; i < num_of_frames_to_loop; ++i) {
      SCOPED_TRACE(i);

      // Run the pending invalidation.
      base::RunLoop().RunUntilIdle();
      EXPECT_EQ(invalidation_count_, static_cast<int>(i + 1));

      // Animate the image on the sync tree.
      auto animated_images = controller_->AnimateForSyncTree(now_);

      // No frames should have been skipped since we add no delay in advancing
      // the animation.
      EXPECT_EQ(
          controller_->GetLastNumOfFramesSkippedForTesting(paint_image_id), 0u);

      EXPECT_EQ(controller_->GetFrameIndexForImage(paint_image_id,
                                                   WhichTree::PENDING_TREE),
                i);
      if (i == 0u && !restarting) {
        // If we are displaying the first frame on the pending tree, then the
        // active tree has the first frame as well if this is the first loop,
        // otherwise it should be the last frame since we are starting a new
        // loop.
        size_t active_index = 0u;
        if (repetitions_completed != 0)
          active_index = frames.size() - 1;
        EXPECT_EQ(controller_->GetFrameIndexForImage(paint_image_id,
                                                     WhichTree::ACTIVE_TREE),
                  active_index);
      } else if (i != 0u) {
        EXPECT_EQ(controller_->GetFrameIndexForImage(paint_image_id,
                                                     WhichTree::ACTIVE_TREE),
                  i - 1);
      }

      if (i == 0u && repetitions_completed == 0 && !restarting) {
        // Starting the animation does not perform any invalidation.
        EXPECT_EQ(animated_images.size(), 0u);
      } else {
        EXPECT_EQ(animated_images.size(), 1u);
        EXPECT_EQ(animated_images.count(paint_image_id), 1u);
      }

      // Animating should schedule an invalidation for the next frame, until we
      // reach the last frame.
      if (i != num_of_frames_to_loop - 1)
        task_runner_->VerifyDelay(frames[i].duration);

      // Activate and advance time to the next frame.
      controller_->DidActivate();
      AdvanceNow(frames[i].duration);
    }
  }

 protected:
  void RequestInvalidation() { invalidation_count_++; }

  void AdvanceNow(base::TimeDelta delta) { now_ += delta; }

  virtual bool GetEnableImageAnimationResync() const { return true; }

  base::TimeTicks now_;
  int invalidation_count_ = 0;
  std::unique_ptr<ImageAnimationController> controller_;
  scoped_refptr<DelayTrackingTaskRunner> task_runner_;
};

TEST_F(ImageAnimationControllerTest, AnimationWithDelays) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(5)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};

  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames,
      kAnimationLoopInfinite, 0);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Display 2 loops in the animation.
  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 0);
  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 1);

  // now_ is set to the time at which the first frame should be displayed for
  // the third iteration. Add a delay that causes us to skip the first frame.
  base::TimeDelta additional_delay = base::TimeDelta::FromMilliseconds(1);
  AdvanceNow(data.frames[0].duration + additional_delay);
  auto animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(animated_images.size(), 1u);
  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
  EXPECT_EQ(
      controller_->GetLastNumOfFramesSkippedForTesting(data.paint_image_id),
      1u);

  // The pending tree displays the second frame while the active tree has the
  // last frame.
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            1u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            3u);

  // Invalidation delay is based on the duration of the second frame and the
  // delay in creating this sync tree.
  task_runner_->VerifyDelay(frames[1].duration - additional_delay);
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);

  // Activate and animate with a delay that causes us to skip another 2 frames.
  controller_->DidActivate();
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            1u);
  AdvanceNow(data.frames[1].duration + data.frames[2].duration +
             data.frames[3].duration);
  animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(animated_images.size(), 1u);
  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
  EXPECT_EQ(
      controller_->GetLastNumOfFramesSkippedForTesting(data.paint_image_id),
      2u);

  // The pending tree displays the first frame, while the active tree has the
  // second frame.
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            1u);

  // Invalidation delay is based on the duration of the first frame and the
  // initial additionaly delay.
  task_runner_->VerifyDelay(frames[0].duration - additional_delay);
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);

  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
}

TEST_F(ImageAnimationControllerTest, DriversControlAnimationTicking) {
  std::vector<FrameMetadata> first_image_frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
  DiscardableImageMap::AnimatedImageMetadata first_data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE,
      first_image_frames, kAnimationLoopOnce, 0);
  controller_->UpdateAnimatedImage(first_data);
  FakeAnimationDriver first_driver;
  controller_->RegisterAnimationDriver(first_data.paint_image_id,
                                       &first_driver);

  std::vector<FrameMetadata> second_image_frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(5)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
  DiscardableImageMap::AnimatedImageMetadata second_data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE,
      second_image_frames, kAnimationLoopOnce, 0);
  controller_->UpdateAnimatedImage(second_data);
  FakeAnimationDriver second_driver;
  controller_->RegisterAnimationDriver(second_data.paint_image_id,
                                       &second_driver);

  // Disable animating from all drivers, no invalidation request should be made.
  first_driver.set_should_animate(false);
  second_driver.set_should_animate(false);
  controller_->UpdateStateFromDrivers(now_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 0);

  // Enable animating from the first driver, which should schedule an
  // invalidation to advance this animation.
  first_driver.set_should_animate(true);
  controller_->UpdateStateFromDrivers(now_);
  task_runner_->VerifyDelay(base::TimeDelta());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);

  // Start animating the first image.
  auto animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(animated_images.size(), 0u);

  // Invalidation should be scheduled for this image.
  task_runner_->VerifyDelay(first_image_frames[0].duration);

  // Now enable animating the second image instead.
  second_driver.set_should_animate(true);
  controller_->UpdateStateFromDrivers(now_);

  // Invalidation is triggered to start with no delay since the second image has
  // not started animating yet.
  task_runner_->VerifyDelay(base::TimeDelta());

  // Disable animating all images.
  first_driver.set_should_animate(false);
  second_driver.set_should_animate(false);
  controller_->UpdateStateFromDrivers(now_);

  // Any scheduled invalidation should be cancelled.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);

  controller_->UnregisterAnimationDriver(first_data.paint_image_id,
                                         &first_driver);
  controller_->UnregisterAnimationDriver(second_data.paint_image_id,
                                         &second_driver);
}

TEST_F(ImageAnimationControllerTest, RepetitionsRequested) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4))};

  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames,
      kAnimationLoopOnce, 0);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Finish a single loop in the animation.
  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 0);

  // No invalidation should be scheduled now, since the requested number of
  // loops have been completed.
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 0);
  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);

  // Now with a repetition count of 5.
  data.paint_image_id = PaintImage::GetNextId();
  data.repetition_count = 5;
  controller_->UpdateAnimatedImage(data);
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);
  for (int i = 0; i < data.repetition_count; ++i) {
    LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), i);

    // Since we will be looping back to the first frame, the invalidation should
    // have the delay of the last frame. Until we reach the end of requested
    // iterations.
    if (i < data.repetition_count - 1)
      task_runner_->VerifyDelay(frames.back().duration);
    invalidation_count_ = 0;
  }

  // No invalidation should be scheduled now, since the requested number of
  // loops have been completed.
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 0);
  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);

  // Now with kAnimationLoopInfinite.
  data.paint_image_id = PaintImage::GetNextId();
  data.repetition_count = kAnimationLoopInfinite;
  controller_->UpdateAnimatedImage(data);
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);
  for (int i = 0; i < 7; ++i) {
    LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), i);

    // Since we will be looping back to the first frame, the invalidation should
    // have the delay of the last frame. Until we reach the end of requested
    // iterations.
    if (i < data.repetition_count - 1)
      task_runner_->VerifyDelay(frames.back().duration);
    invalidation_count_ = 0;
  }

  // We still have an invalidation scheduled since the image will keep looping
  // till the drivers keep the animation active.
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);
  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);

  // Now try with a kAnimationNone image, which should result in a DCHECK
  // failure.
  data.paint_image_id = PaintImage::GetNextId();
  data.repetition_count = kAnimationNone;
  EXPECT_DCHECK_DEATH(controller_->UpdateAnimatedImage(data));
}

TEST_F(ImageAnimationControllerTest, DisplayCompleteFrameOnly) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
      FrameMetadata(false, base::TimeDelta::FromMilliseconds(4))};

  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::PARTIALLY_DONE,
      frames, kAnimationLoopInfinite, 0);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Advance until the second frame.
  LoopOnceNoDelay(data.paint_image_id, frames, 2, 0);

  // We have no invalidation scheduled since its not possible to animate the
  // image further until the second frame is completed.
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 0);

  // Completely load the image but the frame is still incomplete. It should not
  // be advanced.
  data.completion_state = PaintImage::CompletionState::DONE;
  controller_->UpdateAnimatedImage(data);
  controller_->UpdateStateFromDrivers(now_);

  // No invalidation is scheduled since the last frame is still incomplete.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 0);

  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
}

TEST_F(ImageAnimationControllerTest, DontLoopPartiallyLoadedImages) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};

  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::PARTIALLY_DONE,
      frames, 2, 0);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Finish the first loop.
  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 0);

  // We shouldn't be looping back to the first frame until the image is known to
  // be completely loaded.
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 0);

  // Now add another frame and mark the image complete. The animation should
  // advance and we should see another repetition. This verifies that we don't
  // mark loops complete on reaching the last frame until the image is
  // completely loaded and the frame count is known to be accurate.
  frames.push_back(FrameMetadata(true, base::TimeDelta::FromMilliseconds(4)));
  data.completion_state = PaintImage::CompletionState::DONE;
  data.frames = frames;
  controller_->UpdateAnimatedImage(data);
  controller_->UpdateStateFromDrivers(now_);

  // The animation advances to the last frame. We don't have a delay since we
  // already advanced to the desired time in the loop above.
  task_runner_->VerifyDelay(base::TimeDelta());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);
  auto animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            2u);
  EXPECT_EQ(animated_images.size(), 1u);
  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
  controller_->DidActivate();

  // Advancing the animation scheduled an invalidation for the next iteration.
  task_runner_->VerifyDelay(frames.back().duration);

  // Perform another loop in the animation.
  AdvanceNow(frames.back().duration);
  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 1);

  // No invalidation should have been requested at the end of the second loop.
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 0);

  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
}

TEST_F(ImageAnimationControllerTest, DontAdvanceUntilDesiredTime) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};

  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames,
      kAnimationLoopOnce, 0);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Advance the first frame.
  task_runner_->VerifyDelay(base::TimeDelta());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);
  auto animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            0u);
  EXPECT_EQ(animated_images.size(), 0u);
  controller_->DidActivate();

  // We have an invalidation request for the second frame.
  task_runner_->VerifyDelay(frames[0].duration);

  // While there is still time for the second frame, we get a new sync tree. The
  // animation is not advanced.
  base::TimeDelta time_remaining = base::TimeDelta::FromMilliseconds(1);
  AdvanceNow(frames[0].duration - time_remaining);
  animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            0u);
  EXPECT_EQ(animated_images.size(), 0u);
  controller_->DidActivate();

  // We did not get another invalidation request because there is no change in
  // the desired time and the previous request is still pending.
  EXPECT_FALSE(task_runner_->has_delay());

  // We have a sync tree before the invalidation task could run.
  AdvanceNow(time_remaining);
  animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(animated_images.size(), 1u);
  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            1u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            0u);
  controller_->DidActivate();

  // We shouldn't have an invalidation because the animation was already
  // advanced to the last frame and the previous one should have been cancelled.
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 0);

  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
}

TEST_F(ImageAnimationControllerTest, RestartAfterSyncCutoff) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};

  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames,
      kAnimationLoopOnce, 0);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Advance the first frame.
  task_runner_->VerifyDelay(base::TimeDelta());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);
  auto animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(animated_images.size(), 0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            0u);
  controller_->DidActivate();

  // Invalidation request for the second frame.
  task_runner_->VerifyDelay(frames[0].duration);

  // Advance the time by 10 min.
  AdvanceNow(base::TimeDelta::FromMinutes(10));

  // Animate again, it starts from the first frame. We don't see an
  // invalidation, because that's the frame we are already displaying.
  animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(animated_images.size(), 0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            0u);
  controller_->DidActivate();

  // New invalidation request since the desired invalidation time changed.
  task_runner_->VerifyDelay(frames[0].duration);
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);

  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
}

TEST_F(ImageAnimationControllerTest, DontSkipLoopsToCatchUpAfterLoad) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(5))};

  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::PARTIALLY_DONE,
      frames, kAnimationLoopInfinite, 0);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Perform the first loop while the image is partially loaded, until the third
  // frame.
  LoopOnceNoDelay(data.paint_image_id, frames, 3u, 0);

  // The invalidation has been scheduled with a delay for the third frame's
  // duration.
  task_runner_->VerifyDelay(frames[2].duration);

  // |now_| is set to the desired time for the fourth frame. Advance further so
  // we would reach the time for the second frame.
  AdvanceNow(frames[3].duration + frames[0].duration);

  // Finish the image load.
  data.completion_state = PaintImage::CompletionState::DONE;
  controller_->UpdateAnimatedImage(data);
  controller_->UpdateStateFromDrivers(now_);

  // Invalidation is scheduled immediately because we are way past the desired
  // time. We should start from the first frame after the image is loaded
  // instead of skipping frames.
  task_runner_->VerifyDelay(base::TimeDelta());
  auto animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(animated_images.size(), 1u);
  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            2u);
  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
}

TEST_F(ImageAnimationControllerTest, FinishRepetitionsDuringCatchUp) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4))};

  // The animation wants 3 loops.
  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames, 3, 0);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Finish 2 loops.
  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 0);
  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 1);

  // now_ is set to the desired time for the first frame. Advance it so we would
  // reach way beyond the third repeition.
  AdvanceNow(base::TimeDelta::FromMinutes(1));

  // Advance the animation, we should see the last frame since the desired
  // repetition count will be reached during catch up.
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);
  auto animated_images = controller_->AnimateForSyncTree(now_);
  // No invalidation since the active tree is already at the last frame.
  EXPECT_EQ(animated_images.size(), 0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            frames.size() - 1);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            frames.size() - 1);

  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
}

TEST_F(ImageAnimationControllerTest, ResetAnimations) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4))};
  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames, 3,
      0u);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Go uptill the second frame during the second iteration.
  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 0);
  LoopOnceNoDelay(data.paint_image_id, frames, 2u, 1);

  // Reset the animation.
  data.reset_animation_sequence_id++;
  controller_->UpdateAnimatedImage(data);
  controller_->UpdateStateFromDrivers(now_);

  // It should start again from the first frame and do 3 loops.
  for (int i = 0; i < 3; ++i) {
    bool restarting = i == 0;
    LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), i, restarting);
  }

  // No invalidation should be pending.
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 0);

  // Same image used again in a recording. There shouldn't be an invalidation
  // since the reset sequence has already been synchronized.
  controller_->UpdateAnimatedImage(data);
  controller_->UpdateStateFromDrivers(now_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 0);

  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
}

TEST_F(ImageAnimationControllerTest, ResetAnimationStateMapOnNavigation) {
  std::vector<FrameMetadata> first_image_frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
  DiscardableImageMap::AnimatedImageMetadata first_data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE,
      first_image_frames, kAnimationLoopOnce, 0);
  controller_->UpdateAnimatedImage(first_data);
  FakeAnimationDriver first_driver;
  controller_->RegisterAnimationDriver(first_data.paint_image_id,
                                       &first_driver);

  std::vector<FrameMetadata> second_image_frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(5)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
  DiscardableImageMap::AnimatedImageMetadata second_data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE,
      second_image_frames, kAnimationLoopOnce, 0);
  controller_->UpdateAnimatedImage(second_data);
  FakeAnimationDriver second_driver;
  controller_->RegisterAnimationDriver(second_data.paint_image_id,
                                       &second_driver);

  controller_->AnimateForSyncTree(now_);

  controller_->UnregisterAnimationDriver(first_data.paint_image_id,
                                         &first_driver);
  EXPECT_EQ(controller_->animation_state_map_size_for_testing(), 2u);

  // Fake navigation and activation.
  controller_->set_did_navigate();
  controller_->DidActivate();

  // Animation state map entries without drivers will be purged on navigation.
  EXPECT_EQ(controller_->animation_state_map_size_for_testing(), 1u);

  controller_->UnregisterAnimationDriver(second_data.paint_image_id,
                                         &second_driver);

  EXPECT_EQ(controller_->animation_state_map_size_for_testing(), 1u);
}

class ImageAnimationControllerNoResyncTest
    : public ImageAnimationControllerTest {
 protected:
  bool GetEnableImageAnimationResync() const override { return false; }
};

TEST_F(ImageAnimationControllerNoResyncTest, NoSyncCutoffAfterIdle) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};

  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames,
      kAnimationLoopInfinite, 0);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Advance the first frame.
  task_runner_->VerifyDelay(base::TimeDelta());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);
  auto animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(animated_images.size(), 0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            0u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            0u);
  controller_->DidActivate();

  // Invalidation request for the second frame.
  task_runner_->VerifyDelay(frames[0].duration);

  // Advance the time by 10 min (divisible by animation duration) and first
  // frame duration.
  AdvanceNow(base::TimeDelta::FromMinutes(10) + frames[0].duration);

  // Animate again, it should not restart from the start. Should display second
  // animation frame.
  animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(animated_images.size(), 1u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            1u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            0u);
  controller_->DidActivate();

  // New invalidation request since the desired invalidation time changed.
  task_runner_->VerifyDelay(frames[1].duration);
  invalidation_count_ = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(invalidation_count_, 1);

  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
}

TEST_F(ImageAnimationControllerNoResyncTest, SkipsLoopsAfterFirstIteration) {
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(5))};

  DiscardableImageMap::AnimatedImageMetadata data(
      PaintImage::GetNextId(), PaintImage::CompletionState::PARTIALLY_DONE,
      frames, kAnimationLoopInfinite, 0);
  controller_->UpdateAnimatedImage(data);
  FakeAnimationDriver driver;
  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
  controller_->UpdateStateFromDrivers(now_);

  // Perform the first loop while the image is partially loaded, until the third
  // frame.
  LoopOnceNoDelay(data.paint_image_id, frames, 3u, 0);

  // The invalidation has been scheduled with a delay for the third frame's
  // duration.
  task_runner_->VerifyDelay(frames[2].duration);

  // |now_| is set to the desired time for the fourth frame. Advance further so
  // we reach the time for the second frame.
  AdvanceNow(frames[3].duration + frames[0].duration);

  // Finish the image load.
  data.completion_state = PaintImage::CompletionState::DONE;
  controller_->UpdateAnimatedImage(data);
  controller_->UpdateStateFromDrivers(now_);

  // Invalidation is scheduled immediately because we are way past the desired
  // time. We skip frames even after the image is loaded.
  task_runner_->VerifyDelay(base::TimeDelta());
  auto animated_images = controller_->AnimateForSyncTree(now_);
  EXPECT_EQ(animated_images.size(), 1u);
  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::PENDING_TREE),
            1u);
  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                               WhichTree::ACTIVE_TREE),
            2u);
  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
}

}  // namespace cc
