// Copyright 2012 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/animation/layer_animation_controller.h"

#include "cc/animation/animation.h"
#include "cc/animation/animation_curve.h"
#include "cc/animation/animation_delegate.h"
#include "cc/animation/animation_registrar.h"
#include "cc/animation/keyframed_animation_curve.h"
#include "cc/animation/scroll_offset_animation_curve.h"
#include "cc/animation/transform_operations.h"
#include "cc/test/animation_test_common.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/box_f.h"
#include "ui/gfx/transform.h"

namespace cc {
namespace {

using base::TimeDelta;
using base::TimeTicks;

static base::TimeTicks TicksFromSecondsF(double seconds) {
  return base::TimeTicks::FromInternalValue(seconds *
                                            base::Time::kMicrosecondsPerSecond);
}

// A LayerAnimationController cannot be ticked at 0.0, since an animation
// with start time 0.0 is treated as an animation whose start time has
// not yet been set.
const TimeTicks kInitialTickTime = TicksFromSecondsF(1.0);

scoped_ptr<Animation> CreateAnimation(scoped_ptr<AnimationCurve> curve,
                                      int group_id,
                                      Animation::TargetProperty property) {
  return Animation::Create(curve.Pass(), 0, group_id, property);
}

TEST(LayerAnimationControllerTest, SyncNewAnimation) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  EXPECT_FALSE(controller_impl->GetAnimation(Animation::Opacity));

  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
  EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing());

  int animation_id =
      AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());

  controller->PushAnimationUpdatesTo(controller_impl.get());
  EXPECT_TRUE(controller_impl->needs_to_start_animations_for_testing());
  controller_impl->ActivateAnimations();

  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));
  EXPECT_EQ(Animation::WaitingForTargetAvailability,
            controller_impl->GetAnimationById(animation_id)->run_state());
}

// If an animation is started on the impl thread before it is ticked on the main
// thread, we must be sure to respect the synchronized start time.
TEST(LayerAnimationControllerTest, DoNotClobberStartTimes) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  EXPECT_FALSE(controller_impl->GetAnimation(Animation::Opacity));

  int animation_id =
      AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();

  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));
  EXPECT_EQ(Animation::WaitingForTargetAvailability,
            controller_impl->GetAnimationById(animation_id)->run_state());

  AnimationEventsVector events;
  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, &events);

  // Synchronize the start times.
  EXPECT_EQ(1u, events.size());
  controller->NotifyAnimationStarted(events[0]);
  EXPECT_EQ(controller->GetAnimationById(animation_id)->start_time(),
            controller_impl->GetAnimationById(animation_id)->start_time());

  // Start the animation on the main thread. Should not affect the start time.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));
  controller->UpdateState(true, nullptr);
  EXPECT_EQ(controller->GetAnimationById(animation_id)->start_time(),
            controller_impl->GetAnimationById(animation_id)->start_time());
}

TEST(LayerAnimationControllerTest, UseSpecifiedStartTimes) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  int animation_id =
      AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);

  const TimeTicks start_time = TicksFromSecondsF(123);
  controller->GetAnimation(Animation::Opacity)->set_start_time(start_time);

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();

  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));
  EXPECT_EQ(Animation::WaitingForTargetAvailability,
            controller_impl->GetAnimationById(animation_id)->run_state());

  AnimationEventsVector events;
  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, &events);

  // Synchronize the start times.
  EXPECT_EQ(1u, events.size());
  controller->NotifyAnimationStarted(events[0]);

  EXPECT_EQ(start_time,
            controller->GetAnimationById(animation_id)->start_time());
  EXPECT_EQ(controller->GetAnimationById(animation_id)->start_time(),
            controller_impl->GetAnimationById(animation_id)->start_time());

  // Start the animation on the main thread. Should not affect the start time.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));
  controller->UpdateState(true, nullptr);
  EXPECT_EQ(start_time,
            controller->GetAnimationById(animation_id)->start_time());
  EXPECT_EQ(controller->GetAnimationById(animation_id)->start_time(),
            controller_impl->GetAnimationById(animation_id)->start_time());
}

// Tests that controllers activate and deactivate as expected.
TEST(LayerAnimationControllerTest, Activation) {
  scoped_ptr<AnimationRegistrar> registrar = AnimationRegistrar::Create();
  scoped_ptr<AnimationRegistrar> registrar_impl = AnimationRegistrar::Create();

  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));

  controller->SetAnimationRegistrar(registrar.get());
  controller_impl->SetAnimationRegistrar(registrar_impl.get());
  EXPECT_EQ(1u, registrar->all_animation_controllers().size());
  EXPECT_EQ(1u, registrar_impl->all_animation_controllers().size());

  // Initially, both controllers should be inactive.
  EXPECT_EQ(0u, registrar->active_animation_controllers().size());
  EXPECT_EQ(0u, registrar_impl->active_animation_controllers().size());

  AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
  // The main thread controller should now be active.
  EXPECT_EQ(1u, registrar->active_animation_controllers().size());

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  // Both controllers should now be active.
  EXPECT_EQ(1u, registrar->active_animation_controllers().size());
  EXPECT_EQ(1u, registrar_impl->active_animation_controllers().size());

  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());
  EXPECT_EQ(1u, events->size());
  controller->NotifyAnimationStarted((*events)[0]);

  EXPECT_EQ(1u, registrar->active_animation_controllers().size());
  EXPECT_EQ(1u, registrar_impl->active_animation_controllers().size());

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));
  controller->UpdateState(true, nullptr);
  EXPECT_EQ(1u, registrar->active_animation_controllers().size());

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->UpdateState(true, nullptr);
  EXPECT_EQ(Animation::Finished,
            controller->GetAnimation(Animation::Opacity)->run_state());
  EXPECT_EQ(1u, registrar->active_animation_controllers().size());

  events.reset(new AnimationEventsVector);
  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(1500));
  controller_impl->UpdateState(true, events.get());

  EXPECT_EQ(Animation::WaitingForDeletion,
            controller_impl->GetAnimation(Animation::Opacity)->run_state());
  // The impl thread controller should have de-activated.
  EXPECT_EQ(0u, registrar_impl->active_animation_controllers().size());

  EXPECT_EQ(1u, events->size());
  controller->NotifyAnimationFinished((*events)[0]);
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1500));
  controller->UpdateState(true, nullptr);

  EXPECT_EQ(Animation::WaitingForDeletion,
            controller->GetAnimation(Animation::Opacity)->run_state());
  // The main thread controller should have de-activated.
  EXPECT_EQ(0u, registrar->active_animation_controllers().size());

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller->has_any_animation());
  EXPECT_FALSE(controller_impl->has_any_animation());
  EXPECT_EQ(0u, registrar->active_animation_controllers().size());
  EXPECT_EQ(0u, registrar_impl->active_animation_controllers().size());

  controller->SetAnimationRegistrar(nullptr);
  controller_impl->SetAnimationRegistrar(nullptr);
}

TEST(LayerAnimationControllerTest, SyncPause) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  EXPECT_FALSE(controller_impl->GetAnimation(Animation::Opacity));

  int animation_id =
      AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();

  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));
  EXPECT_EQ(Animation::WaitingForTargetAvailability,
            controller_impl->GetAnimationById(animation_id)->run_state());

  // Start the animations on each controller.
  AnimationEventsVector events;
  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, &events);
  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, nullptr);
  EXPECT_EQ(Animation::Running,
            controller_impl->GetAnimationById(animation_id)->run_state());
  EXPECT_EQ(Animation::Running,
            controller->GetAnimationById(animation_id)->run_state());

  // Pause the main-thread animation.
  controller->PauseAnimation(
      animation_id,
      TimeDelta::FromMilliseconds(1000) + TimeDelta::FromMilliseconds(1000));
  EXPECT_EQ(Animation::Paused,
            controller->GetAnimationById(animation_id)->run_state());

  // The pause run state change should make it to the impl thread controller.
  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_EQ(Animation::Paused,
            controller_impl->GetAnimationById(animation_id)->run_state());
}

TEST(LayerAnimationControllerTest, DoNotSyncFinishedAnimation) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  EXPECT_FALSE(controller_impl->GetAnimation(Animation::Opacity));

  int animation_id =
      AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
  int group_id = controller->GetAnimationById(animation_id)->group();

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();

  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));
  EXPECT_EQ(Animation::WaitingForTargetAvailability,
            controller_impl->GetAnimationById(animation_id)->run_state());

  // Notify main thread controller that the animation has started.
  AnimationEvent animation_started_event(AnimationEvent::Started,
                                         0,
                                         group_id,
                                         Animation::Opacity,
                                         kInitialTickTime);
  controller->NotifyAnimationStarted(animation_started_event);

  // Force animation to complete on impl thread.
  controller_impl->RemoveAnimation(animation_id);

  EXPECT_FALSE(controller_impl->GetAnimationById(animation_id));

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();

  // Even though the main thread has a 'new' animation, it should not be pushed
  // because the animation has already completed on the impl thread.
  EXPECT_FALSE(controller_impl->GetAnimationById(animation_id));
}

// Ensure that a finished animation is eventually deleted by both the
// main-thread and the impl-thread controllers.
TEST(LayerAnimationControllerTest, AnimationsAreDeleted) {
  FakeLayerAnimationValueObserver dummy;
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);
  controller_impl->AddValueObserver(&dummy_impl);

  AddOpacityTransitionToController(controller.get(), 1.0, 0.0f, 1.0f, false);
  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, nullptr);
  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();

  controller_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));
  controller_impl->UpdateState(true, events.get());

  // There should be a Started event for the animation.
  EXPECT_EQ(1u, events->size());
  EXPECT_EQ(AnimationEvent::Started, (*events)[0].type);
  controller->NotifyAnimationStarted((*events)[0]);

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->UpdateState(true, nullptr);

  EXPECT_FALSE(dummy.animation_waiting_for_deletion());
  EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion());

  events.reset(new AnimationEventsVector);
  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(2000));
  controller_impl->UpdateState(true, events.get());

  EXPECT_TRUE(dummy_impl.animation_waiting_for_deletion());

  // There should be a Finished event for the animation.
  EXPECT_EQ(1u, events->size());
  EXPECT_EQ(AnimationEvent::Finished, (*events)[0].type);

  // Neither controller should have deleted the animation yet.
  EXPECT_TRUE(controller->GetAnimation(Animation::Opacity));
  EXPECT_TRUE(controller_impl->GetAnimation(Animation::Opacity));

  controller->NotifyAnimationFinished((*events)[0]);

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000));
  controller->UpdateState(true, nullptr);
  EXPECT_TRUE(dummy.animation_waiting_for_deletion());

  controller->PushAnimationUpdatesTo(controller_impl.get());

  // Both controllers should now have deleted the animation. The impl controller
  // should have deleted the animation even though activation has not occurred,
  // since the animation was already waiting for deletion when
  // PushAnimationUpdatesTo was called.
  EXPECT_FALSE(controller->has_any_animation());
  EXPECT_FALSE(controller_impl->has_any_animation());
}

// Tests that transitioning opacity from 0 to 1 works as expected.

static const AnimationEvent* GetMostRecentPropertyUpdateEvent(
    const AnimationEventsVector* events) {
  const AnimationEvent* event = 0;
  for (size_t i = 0; i < events->size(); ++i)
    if ((*events)[i].type == AnimationEvent::PropertyUpdate)
      event = &(*events)[i];

  return event;
}

TEST(LayerAnimationControllerTest, TrivialTransition) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  scoped_ptr<Animation> to_add(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));

  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
  controller->AddAnimation(to_add.Pass());
  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());
  controller->Animate(kInitialTickTime);
  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());
  // A non-impl-only animation should not generate property updates.
  const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(1.f, dummy.opacity());
  EXPECT_FALSE(controller->HasActiveAnimation());
  event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);
}

TEST(LayerAnimationControllerTest, TrivialTransitionOnImpl) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);

  scoped_ptr<Animation> to_add(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));
  to_add->set_is_impl_only(true);

  controller_impl->AddAnimation(to_add.Pass());
  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());
  EXPECT_TRUE(controller_impl->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy_impl.opacity());
  EXPECT_EQ(1u, events->size());
  const AnimationEvent* start_opacity_event =
      GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_EQ(0.f, start_opacity_event->opacity);

  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(1000));
  controller_impl->UpdateState(true, events.get());
  EXPECT_EQ(1.f, dummy_impl.opacity());
  EXPECT_FALSE(controller_impl->HasActiveAnimation());
  EXPECT_EQ(2u, events->size());
  const AnimationEvent* end_opacity_event =
      GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_EQ(1.f, end_opacity_event->opacity);
}

TEST(LayerAnimationControllerTest, TrivialTransformOnImpl) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);

  // Choose different values for x and y to avoid coincidental values in the
  // observed transforms.
  const float delta_x = 3;
  const float delta_y = 4;

  scoped_ptr<KeyframedTransformAnimationCurve> curve(
      KeyframedTransformAnimationCurve::Create());

  // Create simple Transform animation.
  TransformOperations operations;
  curve->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations, nullptr));
  operations.AppendTranslate(delta_x, delta_y, 0);
  curve->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations, nullptr));

  scoped_ptr<Animation> animation(
      Animation::Create(curve.Pass(), 1, 0, Animation::Transform));
  animation->set_is_impl_only(true);
  controller_impl->AddAnimation(animation.Pass());

  // Run animation.
  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());
  EXPECT_TRUE(controller_impl->HasActiveAnimation());
  EXPECT_EQ(gfx::Transform(), dummy_impl.transform());
  EXPECT_EQ(1u, events->size());
  const AnimationEvent* start_transform_event =
      GetMostRecentPropertyUpdateEvent(events.get());
  ASSERT_TRUE(start_transform_event);
  EXPECT_EQ(gfx::Transform(), start_transform_event->transform);
  EXPECT_TRUE(start_transform_event->is_impl_only);

  gfx::Transform expected_transform;
  expected_transform.Translate(delta_x, delta_y);

  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(1000));
  controller_impl->UpdateState(true, events.get());
  EXPECT_EQ(expected_transform, dummy_impl.transform());
  EXPECT_FALSE(controller_impl->HasActiveAnimation());
  EXPECT_EQ(2u, events->size());
  const AnimationEvent* end_transform_event =
      GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_EQ(expected_transform, end_transform_event->transform);
  EXPECT_TRUE(end_transform_event->is_impl_only);
}

TEST(LayerAnimationControllerTest, FilterTransition) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  scoped_ptr<KeyframedFilterAnimationCurve> curve(
      KeyframedFilterAnimationCurve::Create());

  FilterOperations start_filters;
  start_filters.Append(FilterOperation::CreateBrightnessFilter(1.f));
  curve->AddKeyframe(
      FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr));
  FilterOperations end_filters;
  end_filters.Append(FilterOperation::CreateBrightnessFilter(2.f));
  curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
                                            end_filters, nullptr));

  scoped_ptr<Animation> animation(
      Animation::Create(curve.Pass(), 1, 0, Animation::Filter));
  controller->AddAnimation(animation.Pass());

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(start_filters, dummy.filters());
  // A non-impl-only animation should not generate property updates.
  const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(1u, dummy.filters().size());
  EXPECT_EQ(FilterOperation::CreateBrightnessFilter(1.5f),
            dummy.filters().at(0));
  event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(end_filters, dummy.filters());
  EXPECT_FALSE(controller->HasActiveAnimation());
  event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);
}

TEST(LayerAnimationControllerTest, FilterTransitionOnImplOnly) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);

  scoped_ptr<KeyframedFilterAnimationCurve> curve(
      KeyframedFilterAnimationCurve::Create());

  // Create simple Filter animation.
  FilterOperations start_filters;
  start_filters.Append(FilterOperation::CreateBrightnessFilter(1.f));
  curve->AddKeyframe(
      FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr));
  FilterOperations end_filters;
  end_filters.Append(FilterOperation::CreateBrightnessFilter(2.f));
  curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
                                            end_filters, nullptr));

  scoped_ptr<Animation> animation(
      Animation::Create(curve.Pass(), 1, 0, Animation::Filter));
  animation->set_is_impl_only(true);
  controller_impl->AddAnimation(animation.Pass());

  // Run animation.
  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());
  EXPECT_TRUE(controller_impl->HasActiveAnimation());
  EXPECT_EQ(start_filters, dummy_impl.filters());
  EXPECT_EQ(1u, events->size());
  const AnimationEvent* start_filter_event =
      GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_TRUE(start_filter_event);
  EXPECT_EQ(start_filters, start_filter_event->filters);
  EXPECT_TRUE(start_filter_event->is_impl_only);

  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(1000));
  controller_impl->UpdateState(true, events.get());
  EXPECT_EQ(end_filters, dummy_impl.filters());
  EXPECT_FALSE(controller_impl->HasActiveAnimation());
  EXPECT_EQ(2u, events->size());
  const AnimationEvent* end_filter_event =
      GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_TRUE(end_filter_event);
  EXPECT_EQ(end_filters, end_filter_event->filters);
  EXPECT_TRUE(end_filter_event->is_impl_only);
}

TEST(LayerAnimationControllerTest, ScrollOffsetTransition) {
  FakeLayerAnimationValueObserver dummy_impl;
  FakeLayerAnimationValueProvider dummy_provider_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  controller_impl->set_value_provider(&dummy_provider_impl);
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  FakeLayerAnimationValueProvider dummy_provider;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);
  controller->set_value_provider(&dummy_provider);

  gfx::ScrollOffset initial_value(100.f, 300.f);
  gfx::ScrollOffset target_value(300.f, 200.f);
  scoped_ptr<ScrollOffsetAnimationCurve> curve(
      ScrollOffsetAnimationCurve::Create(
          target_value,
          EaseInOutTimingFunction::Create().Pass()));

  scoped_ptr<Animation> animation(
      Animation::Create(curve.Pass(), 1, 0, Animation::ScrollOffset));
  animation->set_needs_synchronized_start_time(true);
  controller->AddAnimation(animation.Pass());

  dummy_provider_impl.set_scroll_offset(initial_value);
  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_TRUE(controller_impl->GetAnimation(Animation::ScrollOffset));
  TimeDelta duration = controller_impl->GetAnimation(Animation::ScrollOffset)
                           ->curve()
                           ->Duration();
  EXPECT_EQ(
      duration,
      controller->GetAnimation(Animation::ScrollOffset)->curve()->Duration());

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, nullptr);
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(initial_value, dummy.scroll_offset());

  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());
  EXPECT_TRUE(controller_impl->HasActiveAnimation());
  EXPECT_EQ(initial_value, dummy_impl.scroll_offset());
  // Scroll offset animations should not generate property updates.
  const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);

  controller->NotifyAnimationStarted((*events)[0]);
  controller->Animate(kInitialTickTime + duration / 2);
  controller->UpdateState(true, nullptr);
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(200.f, 250.f), dummy.scroll_offset());

  controller_impl->Animate(kInitialTickTime + duration / 2);
  controller_impl->UpdateState(true, events.get());
  EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(200.f, 250.f),
                      dummy_impl.scroll_offset());
  event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);

  controller_impl->Animate(kInitialTickTime + duration);
  controller_impl->UpdateState(true, events.get());
  EXPECT_VECTOR2DF_EQ(target_value, dummy_impl.scroll_offset());
  EXPECT_FALSE(controller_impl->HasActiveAnimation());
  event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);

  controller->Animate(kInitialTickTime + duration);
  controller->UpdateState(true, nullptr);
  EXPECT_VECTOR2DF_EQ(target_value, dummy.scroll_offset());
  EXPECT_FALSE(controller->HasActiveAnimation());
}

// Ensure that when the impl controller doesn't have a value provider,
// the main-thread controller's value provider is used to obtain the intial
// scroll offset.
TEST(LayerAnimationControllerTest, ScrollOffsetTransitionNoImplProvider) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  FakeLayerAnimationValueProvider dummy_provider;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);
  controller->set_value_provider(&dummy_provider);

  gfx::ScrollOffset initial_value(500.f, 100.f);
  gfx::ScrollOffset target_value(300.f, 200.f);
  scoped_ptr<ScrollOffsetAnimationCurve> curve(
      ScrollOffsetAnimationCurve::Create(
          target_value,
          EaseInOutTimingFunction::Create().Pass()));

  scoped_ptr<Animation> animation(
      Animation::Create(curve.Pass(), 1, 0, Animation::ScrollOffset));
  animation->set_needs_synchronized_start_time(true);
  controller->AddAnimation(animation.Pass());

  dummy_provider.set_scroll_offset(initial_value);
  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_TRUE(controller_impl->GetAnimation(Animation::ScrollOffset));
  TimeDelta duration = controller_impl->GetAnimation(Animation::ScrollOffset)
                           ->curve()
                           ->Duration();
  EXPECT_EQ(
      duration,
      controller->GetAnimation(Animation::ScrollOffset)->curve()->Duration());

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, nullptr);
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(initial_value, dummy.scroll_offset());

  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());
  EXPECT_TRUE(controller_impl->HasActiveAnimation());
  EXPECT_EQ(initial_value, dummy_impl.scroll_offset());
  // Scroll offset animations should not generate property updates.
  const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);


  controller->NotifyAnimationStarted((*events)[0]);
  controller->Animate(kInitialTickTime + duration / 2);
  controller->UpdateState(true, nullptr);
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(400.f, 150.f), dummy.scroll_offset());

  controller_impl->Animate(kInitialTickTime + duration / 2);
  controller_impl->UpdateState(true, events.get());
  EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(400.f, 150.f),
                      dummy_impl.scroll_offset());
  event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);

  controller_impl->Animate(kInitialTickTime + duration);
  controller_impl->UpdateState(true, events.get());
  EXPECT_VECTOR2DF_EQ(target_value, dummy_impl.scroll_offset());
  EXPECT_FALSE(controller_impl->HasActiveAnimation());
  event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);

  controller->Animate(kInitialTickTime + duration);
  controller->UpdateState(true, nullptr);
  EXPECT_VECTOR2DF_EQ(target_value, dummy.scroll_offset());
  EXPECT_FALSE(controller->HasActiveAnimation());
}

TEST(LayerAnimationControllerTest, ScrollOffsetTransitionOnImplOnly) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));

  gfx::ScrollOffset initial_value(100.f, 300.f);
  gfx::ScrollOffset target_value(300.f, 200.f);
  scoped_ptr<ScrollOffsetAnimationCurve> curve(
      ScrollOffsetAnimationCurve::Create(
          target_value,
          EaseInOutTimingFunction::Create().Pass()));
  curve->SetInitialValue(initial_value);
  double duration_in_seconds = curve->Duration().InSecondsF();

  scoped_ptr<Animation> animation(
      Animation::Create(curve.Pass(), 1, 0, Animation::ScrollOffset));
  animation->set_is_impl_only(true);
  controller_impl->AddAnimation(animation.Pass());

  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());
  EXPECT_TRUE(controller_impl->HasActiveAnimation());
  EXPECT_EQ(initial_value, dummy_impl.scroll_offset());
  // Scroll offset animations should not generate property updates.
  const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);

  TimeDelta duration = TimeDelta::FromMicroseconds(
      duration_in_seconds * base::Time::kMicrosecondsPerSecond);

  controller_impl->Animate(kInitialTickTime + duration / 2);
  controller_impl->UpdateState(true, events.get());
  EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(200.f, 250.f),
                      dummy_impl.scroll_offset());
  event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);

  controller_impl->Animate(kInitialTickTime + duration);
  controller_impl->UpdateState(true, events.get());
  EXPECT_VECTOR2DF_EQ(target_value, dummy_impl.scroll_offset());
  EXPECT_FALSE(controller_impl->HasActiveAnimation());
  event = GetMostRecentPropertyUpdateEvent(events.get());
  EXPECT_FALSE(event);
}

TEST(LayerAnimationControllerTest, ScrollOffsetRemovalClearsScrollDelta) {
  FakeLayerAnimationValueObserver dummy_impl;
  FakeLayerAnimationValueProvider dummy_provider_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  controller_impl->set_value_provider(&dummy_provider_impl);
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  FakeLayerAnimationValueProvider dummy_provider;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);
  controller->set_value_provider(&dummy_provider);

  // First test the 1-argument version of RemoveAnimation.
  gfx::ScrollOffset target_value(300.f, 200.f);
  scoped_ptr<ScrollOffsetAnimationCurve> curve(
      ScrollOffsetAnimationCurve::Create(
          target_value, EaseInOutTimingFunction::Create().Pass()));

  int animation_id = 1;
  scoped_ptr<Animation> animation(Animation::Create(
      curve.Pass(), animation_id, 0, Animation::ScrollOffset));
  animation->set_needs_synchronized_start_time(true);
  controller->AddAnimation(animation.Pass());
  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted());
  EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted());

  controller->RemoveAnimation(animation_id);
  EXPECT_TRUE(controller->scroll_offset_animation_was_interrupted());

  controller->PushAnimationUpdatesTo(controller_impl.get());
  EXPECT_TRUE(controller_impl->scroll_offset_animation_was_interrupted());
  EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted());

  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted());

  // Now, test the 2-argument version of RemoveAnimation.
  curve = ScrollOffsetAnimationCurve::Create(
      target_value, EaseInOutTimingFunction::Create().Pass());
  animation =
      Animation::Create(curve.Pass(), animation_id, 0, Animation::ScrollOffset);
  animation->set_needs_synchronized_start_time(true);
  controller->AddAnimation(animation.Pass());
  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted());
  EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted());

  controller->RemoveAnimation(animation_id);
  EXPECT_TRUE(controller->scroll_offset_animation_was_interrupted());

  controller->PushAnimationUpdatesTo(controller_impl.get());
  EXPECT_TRUE(controller_impl->scroll_offset_animation_was_interrupted());
  EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted());

  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted());

  // Check that removing non-scroll-offset animations does not cause
  // scroll_offset_animation_was_interrupted() to get set.
  animation_id = AddAnimatedTransformToController(controller.get(), 1.0, 1, 2);
  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted());
  EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted());

  controller->RemoveAnimation(animation_id);
  EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted());

  controller->PushAnimationUpdatesTo(controller_impl.get());
  EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted());
  EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted());

  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted());

  animation_id =
      AddAnimatedFilterToController(controller.get(), 1.0, 0.1f, 0.2f);
  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted());
  EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted());

  controller->RemoveAnimation(animation_id);
  EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted());

  controller->PushAnimationUpdatesTo(controller_impl.get());
  EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted());
  EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted());

  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted());
}

class FakeAnimationDelegate : public AnimationDelegate {
 public:
  FakeAnimationDelegate()
      : started_(false),
        finished_(false) {}

  void NotifyAnimationStarted(TimeTicks monotonic_time,
                              Animation::TargetProperty target_property,
                              int group) override {
    started_ = true;
  }

  void NotifyAnimationFinished(TimeTicks monotonic_time,
                               Animation::TargetProperty target_property,
                               int group) override {
    finished_ = true;
  }

  bool started() { return started_; }

  bool finished() { return finished_; }

 private:
  bool started_;
  bool finished_;
};

// Tests that impl-only animations lead to start and finished notifications
// on the impl thread controller's animation delegate.
TEST(LayerAnimationControllerTest,
     NotificationsForImplOnlyAnimationsAreSentToImplThreadDelegate) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeAnimationDelegate delegate;
  controller_impl->set_layer_animation_delegate(&delegate);

  scoped_ptr<Animation> to_add(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));
  to_add->set_is_impl_only(true);
  controller_impl->AddAnimation(to_add.Pass());

  EXPECT_FALSE(delegate.started());
  EXPECT_FALSE(delegate.finished());

  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());

  EXPECT_TRUE(delegate.started());
  EXPECT_FALSE(delegate.finished());

  events.reset(new AnimationEventsVector);
  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(1000));
  controller_impl->UpdateState(true, events.get());

  EXPECT_TRUE(delegate.started());
  EXPECT_TRUE(delegate.finished());
}

// Tests animations that are waiting for a synchronized start time do not
// finish.
TEST(LayerAnimationControllerTest,
     AnimationsWaitingForStartTimeDoNotFinishIfTheyOutwaitTheirFinish) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  scoped_ptr<Animation> to_add(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));
  to_add->set_needs_synchronized_start_time(true);

  // We should pause at the first keyframe indefinitely waiting for that
  // animation to start.
  controller->AddAnimation(to_add.Pass());
  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());

  // Send the synchronized start time.
  controller->NotifyAnimationStarted(
      AnimationEvent(AnimationEvent::Started,
                     0,
                     1,
                     Animation::Opacity,
                     kInitialTickTime + TimeDelta::FromMilliseconds(2000)));
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(5000));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(1.f, dummy.opacity());
  EXPECT_FALSE(controller->HasActiveAnimation());
}

// Tests that two queued animations affecting the same property run in sequence.
TEST(LayerAnimationControllerTest, TrivialQueuing) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());

  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));
  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(
          new FakeFloatTransition(1.0, 1.f, 0.5f)).Pass(),
      2,
      Animation::Opacity));

  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());

  controller->Animate(kInitialTickTime);

  // The second animation still needs to be started.
  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());

  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());
  controller->UpdateState(true, events.get());
  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());

  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(1.f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(0.5f, dummy.opacity());
  EXPECT_FALSE(controller->HasActiveAnimation());
}

// Tests interrupting a transition with another transition.
TEST(LayerAnimationControllerTest, Interrupt) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);
  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));
  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());

  scoped_ptr<Animation> to_add(CreateAnimation(
      scoped_ptr<AnimationCurve>(
          new FakeFloatTransition(1.0, 1.f, 0.5f)).Pass(),
      2,
      Animation::Opacity));
  controller->AbortAnimations(Animation::Opacity);
  controller->AddAnimation(to_add.Pass());

  // Since the previous animation was aborted, the new animation should start
  // right in this call to animate.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(1.f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1500));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(0.5f, dummy.opacity());
  EXPECT_FALSE(controller->HasActiveAnimation());
}

// Tests scheduling two animations to run together when only one property is
// free.
TEST(LayerAnimationControllerTest, ScheduleTogetherWhenAPropertyIsBlocked) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeTransformTransition(1)).Pass(),
      1,
      Animation::Transform));
  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeTransformTransition(1)).Pass(),
      2,
      Animation::Transform));
  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      2,
      Animation::Opacity));

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_EQ(0.f, dummy.opacity());
  EXPECT_TRUE(controller->HasActiveAnimation());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->UpdateState(true, events.get());
  // Should not have started the float transition yet.
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());
  // The float animation should have started at time 1 and should be done.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(1.f, dummy.opacity());
  EXPECT_FALSE(controller->HasActiveAnimation());
}

// Tests scheduling two animations to run together with different lengths and
// another animation queued to start when the shorter animation finishes (should
// wait for both to finish).
TEST(LayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeTransformTransition(2)).Pass(),
      1,
      Animation::Transform));
  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));
  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(
          new FakeFloatTransition(1.0, 1.f, 0.5f)).Pass(),
      2,
      Animation::Opacity));

  // Animations with id 1 should both start now.
  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());
  // The opacity animation should have finished at time 1, but the group
  // of animations with id 1 don't finish until time 2 because of the length
  // of the transform animation.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
  controller->UpdateState(true, events.get());
  // Should not have started the float transition yet.
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(1.f, dummy.opacity());

  // The second opacity animation should start at time 2 and should be done by
  // time 3.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(0.5f, dummy.opacity());
  EXPECT_FALSE(controller->HasActiveAnimation());
}

// Test that a looping animation loops and for the correct number of iterations.
TEST(LayerAnimationControllerTest, TrivialLooping) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  scoped_ptr<Animation> to_add(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));
  to_add->set_iterations(3);
  controller->AddAnimation(to_add.Pass());

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1250));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.25f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1750));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.75f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2250));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.25f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2750));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.75f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000));
  controller->UpdateState(true, events.get());
  EXPECT_FALSE(controller->HasActiveAnimation());
  EXPECT_EQ(1.f, dummy.opacity());

  // Just be extra sure.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(4000));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(1.f, dummy.opacity());
}

// Test that an infinitely looping animation does indeed go until aborted.
TEST(LayerAnimationControllerTest, InfiniteLooping) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  scoped_ptr<Animation> to_add(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1, Animation::Opacity));
  to_add->set_iterations(-1);
  controller->AddAnimation(to_add.Pass());

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1250));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.25f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1750));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.75f, dummy.opacity());

  controller->Animate(kInitialTickTime +
                      TimeDelta::FromMilliseconds(1073741824250));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.25f, dummy.opacity());
  controller->Animate(kInitialTickTime +
                      TimeDelta::FromMilliseconds(1073741824750));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.75f, dummy.opacity());

  EXPECT_TRUE(controller->GetAnimation(Animation::Opacity));
  controller->GetAnimation(Animation::Opacity)
      ->SetRunState(Animation::Aborted,
                    kInitialTickTime + TimeDelta::FromMilliseconds(750));
  EXPECT_FALSE(controller->HasActiveAnimation());
  EXPECT_EQ(0.75f, dummy.opacity());
}

// Test that pausing and resuming work as expected.
TEST(LayerAnimationControllerTest, PauseResume) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1, Animation::Opacity));

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.5f, dummy.opacity());

  EXPECT_TRUE(controller->GetAnimation(Animation::Opacity));
  controller->GetAnimation(Animation::Opacity)
      ->SetRunState(Animation::Paused,
                    kInitialTickTime + TimeDelta::FromMilliseconds(500));

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1024000));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.5f, dummy.opacity());

  EXPECT_TRUE(controller->GetAnimation(Animation::Opacity));
  controller->GetAnimation(Animation::Opacity)
      ->SetRunState(Animation::Running,
                    kInitialTickTime + TimeDelta::FromMilliseconds(1024000));
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1024250));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.75f, dummy.opacity());

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1024500));
  controller->UpdateState(true, events.get());
  EXPECT_FALSE(controller->HasActiveAnimation());
  EXPECT_EQ(1.f, dummy.opacity());
}

TEST(LayerAnimationControllerTest, AbortAGroupedAnimation) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  const int animation_id = 2;
  controller->AddAnimation(Animation::Create(
      scoped_ptr<AnimationCurve>(new FakeTransformTransition(1)).Pass(), 1, 1,
      Animation::Transform));
  controller->AddAnimation(Animation::Create(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(2.0, 0.f, 1.f)).Pass(),
      animation_id, 1, Animation::Opacity));
  controller->AddAnimation(Animation::Create(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 1.f, 0.75f))
          .Pass(),
      3, 2, Animation::Opacity));

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.5f, dummy.opacity());

  EXPECT_TRUE(controller->GetAnimationById(animation_id));
  controller->GetAnimationById(animation_id)
      ->SetRunState(Animation::Aborted,
                    kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(1.f, dummy.opacity());
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(!controller->HasActiveAnimation());
  EXPECT_EQ(0.75f, dummy.opacity());
}

TEST(LayerAnimationControllerTest, PushUpdatesWhenSynchronizedStartTimeNeeded) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  scoped_ptr<Animation> to_add(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(2.0, 0.f, 1.f)).Pass(),
      0,
      Animation::Opacity));
  to_add->set_needs_synchronized_start_time(true);
  controller->AddAnimation(to_add.Pass());

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_TRUE(controller->HasActiveAnimation());
  Animation* active_animation = controller->GetAnimation(Animation::Opacity);
  EXPECT_TRUE(active_animation);
  EXPECT_TRUE(active_animation->needs_synchronized_start_time());

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();

  active_animation = controller_impl->GetAnimation(Animation::Opacity);
  EXPECT_TRUE(active_animation);
  EXPECT_EQ(Animation::WaitingForTargetAvailability,
            active_animation->run_state());
}

// Tests that skipping a call to UpdateState works as expected.
TEST(LayerAnimationControllerTest, SkipUpdateState) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeTransformTransition(1)).Pass(),
      1,
      Animation::Transform));

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());

  controller->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      2,
      Animation::Opacity));

  // Animate but don't UpdateState.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
  events.reset(new AnimationEventsVector);
  controller->UpdateState(true, events.get());

  // Should have one Started event and one Finished event.
  EXPECT_EQ(2u, events->size());
  EXPECT_NE((*events)[0].type, (*events)[1].type);

  // The float transition should still be at its starting point.
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_EQ(0.f, dummy.opacity());

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000));
  controller->UpdateState(true, events.get());

  // The float tranisition should now be done.
  EXPECT_EQ(1.f, dummy.opacity());
  EXPECT_FALSE(controller->HasActiveAnimation());
}

// Tests that an animation controller with only a pending observer gets ticked
// but doesn't progress animations past the Starting state.
TEST(LayerAnimationControllerTest, InactiveObserverGetsTicked) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy;
  FakeInactiveLayerAnimationValueObserver pending_dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));

  const int id = 1;
  controller->AddAnimation(CreateAnimation(scoped_ptr<AnimationCurve>(
      new FakeFloatTransition(1.0, 0.5f, 1.f)).Pass(),
      id,
      Animation::Opacity));

  // Without an observer, the animation shouldn't progress to the Starting
  // state.
  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, events.get());
  EXPECT_EQ(0u, events->size());
  EXPECT_EQ(Animation::WaitingForTargetAvailability,
            controller->GetAnimation(Animation::Opacity)->run_state());

  controller->AddValueObserver(&pending_dummy);

  // With only a pending observer, the animation should progress to the
  // Starting state and get ticked at its starting point, but should not
  // progress to Running.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(0u, events->size());
  EXPECT_EQ(Animation::Starting,
            controller->GetAnimation(Animation::Opacity)->run_state());
  EXPECT_EQ(0.5f, pending_dummy.opacity());

  // Even when already in the Starting state, the animation should stay
  // there, and shouldn't be ticked past its starting point.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(0u, events->size());
  EXPECT_EQ(Animation::Starting,
            controller->GetAnimation(Animation::Opacity)->run_state());
  EXPECT_EQ(0.5f, pending_dummy.opacity());

  controller->AddValueObserver(&dummy);

  // Now that an active observer has been added, the animation should still
  // initially tick at its starting point, but should now progress to Running.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000));
  controller->UpdateState(true, events.get());
  EXPECT_EQ(1u, events->size());
  EXPECT_EQ(Animation::Running,
            controller->GetAnimation(Animation::Opacity)->run_state());
  EXPECT_EQ(0.5f, pending_dummy.opacity());
  EXPECT_EQ(0.5f, dummy.opacity());

  // The animation should now tick past its starting point.
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3500));
  EXPECT_NE(0.5f, pending_dummy.opacity());
  EXPECT_NE(0.5f, dummy.opacity());
}

TEST(LayerAnimationControllerTest, TransformAnimationBounds) {
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));

  scoped_ptr<KeyframedTransformAnimationCurve> curve1(
      KeyframedTransformAnimationCurve::Create());

  TransformOperations operations1;
  curve1->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
  operations1.AppendTranslate(10.0, 15.0, 0.0);
  curve1->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations1, nullptr));

  scoped_ptr<Animation> animation(
      Animation::Create(curve1.Pass(), 1, 1, Animation::Transform));
  controller_impl->AddAnimation(animation.Pass());

  scoped_ptr<KeyframedTransformAnimationCurve> curve2(
      KeyframedTransformAnimationCurve::Create());

  TransformOperations operations2;
  curve2->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr));
  operations2.AppendScale(2.0, 3.0, 4.0);
  curve2->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));

  animation = Animation::Create(curve2.Pass(), 2, 2, Animation::Transform);
  controller_impl->AddAnimation(animation.Pass());

  gfx::BoxF box(1.f, 2.f, -1.f, 3.f, 4.f, 5.f);
  gfx::BoxF bounds;

  EXPECT_TRUE(controller_impl->TransformAnimationBoundsForBox(box, &bounds));
  EXPECT_EQ(gfx::BoxF(1.f, 2.f, -4.f, 13.f, 19.f, 20.f).ToString(),
            bounds.ToString());

  controller_impl->GetAnimationById(1)
      ->SetRunState(Animation::Finished, TicksFromSecondsF(0.0));

  // Only the unfinished animation should affect the animated bounds.
  EXPECT_TRUE(controller_impl->TransformAnimationBoundsForBox(box, &bounds));
  EXPECT_EQ(gfx::BoxF(1.f, 2.f, -4.f, 7.f, 16.f, 20.f).ToString(),
            bounds.ToString());

  controller_impl->GetAnimationById(2)
      ->SetRunState(Animation::Finished, TicksFromSecondsF(0.0));

  // There are no longer any running animations.
  EXPECT_FALSE(controller_impl->HasTransformAnimationThatInflatesBounds());

  // Add an animation whose bounds we don't yet support computing.
  scoped_ptr<KeyframedTransformAnimationCurve> curve3(
      KeyframedTransformAnimationCurve::Create());
  TransformOperations operations3;
  gfx::Transform transform3;
  transform3.Scale3d(1.0, 2.0, 3.0);
  curve3->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr));
  operations3.AppendMatrix(transform3);
  curve3->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations3, nullptr));
  animation = Animation::Create(curve3.Pass(), 3, 3, Animation::Transform);
  controller_impl->AddAnimation(animation.Pass());
  EXPECT_FALSE(controller_impl->TransformAnimationBoundsForBox(box, &bounds));
}

// Tests that AbortAnimations aborts all animations targeting the specified
// property.
TEST(LayerAnimationControllerTest, AbortAnimations) {
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  // Start with several animations, and allow some of them to reach the finished
  // state.
  controller->AddAnimation(Animation::Create(
      scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)).Pass(), 1, 1,
      Animation::Transform));
  controller->AddAnimation(Animation::Create(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      2, 2, Animation::Opacity));
  controller->AddAnimation(Animation::Create(
      scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)).Pass(), 3, 3,
      Animation::Transform));
  controller->AddAnimation(Animation::Create(
      scoped_ptr<AnimationCurve>(new FakeTransformTransition(2.0)).Pass(), 4, 4,
      Animation::Transform));
  controller->AddAnimation(Animation::Create(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      5, 5, Animation::Opacity));

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, nullptr);
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  controller->UpdateState(true, nullptr);

  EXPECT_EQ(Animation::Finished, controller->GetAnimationById(1)->run_state());
  EXPECT_EQ(Animation::Finished, controller->GetAnimationById(2)->run_state());
  EXPECT_EQ(Animation::Running, controller->GetAnimationById(3)->run_state());
  EXPECT_EQ(Animation::WaitingForTargetAvailability,
            controller->GetAnimationById(4)->run_state());
  EXPECT_EQ(Animation::Running, controller->GetAnimationById(5)->run_state());

  controller->AbortAnimations(Animation::Transform);

  // Only un-finished Transform animations should have been aborted.
  EXPECT_EQ(Animation::Finished, controller->GetAnimationById(1)->run_state());
  EXPECT_EQ(Animation::Finished, controller->GetAnimationById(2)->run_state());
  EXPECT_EQ(Animation::Aborted, controller->GetAnimationById(3)->run_state());
  EXPECT_EQ(Animation::Aborted, controller->GetAnimationById(4)->run_state());
  EXPECT_EQ(Animation::Running, controller->GetAnimationById(5)->run_state());
}

// An animation aborted on the main thread should get deleted on both threads.
TEST(LayerAnimationControllerTest, MainThreadAbortedAnimationGetsDeleted) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  int animation_id =
      AddOpacityTransitionToController(controller.get(), 1.0, 0.f, 1.f, false);

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));

  controller->AbortAnimations(Animation::Opacity);
  EXPECT_EQ(Animation::Aborted,
            controller->GetAnimation(Animation::Opacity)->run_state());
  EXPECT_FALSE(dummy.animation_waiting_for_deletion());
  EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion());

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, nullptr);
  EXPECT_TRUE(dummy.animation_waiting_for_deletion());
  EXPECT_EQ(Animation::WaitingForDeletion,
            controller->GetAnimation(Animation::Opacity)->run_state());

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller->GetAnimationById(animation_id));
  EXPECT_FALSE(controller_impl->GetAnimationById(animation_id));
}

// An animation aborted on the impl thread should get deleted on both threads.
TEST(LayerAnimationControllerTest, ImplThreadAbortedAnimationGetsDeleted) {
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  int animation_id =
      AddOpacityTransitionToController(controller.get(), 1.0, 0.f, 1.f, false);

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));

  controller_impl->AbortAnimations(Animation::Opacity);
  EXPECT_EQ(Animation::Aborted,
            controller_impl->GetAnimation(Animation::Opacity)->run_state());
  EXPECT_FALSE(dummy.animation_waiting_for_deletion());
  EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion());

  AnimationEventsVector events;
  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, &events);
  EXPECT_TRUE(dummy_impl.animation_waiting_for_deletion());
  EXPECT_EQ(1u, events.size());
  EXPECT_EQ(AnimationEvent::Aborted, events[0].type);
  EXPECT_EQ(Animation::WaitingForDeletion,
            controller_impl->GetAnimation(Animation::Opacity)->run_state());

  controller->NotifyAnimationAborted(events[0]);
  EXPECT_EQ(Animation::Aborted,
            controller->GetAnimation(Animation::Opacity)->run_state());

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));
  controller->UpdateState(true, nullptr);
  EXPECT_TRUE(dummy.animation_waiting_for_deletion());
  EXPECT_EQ(Animation::WaitingForDeletion,
            controller->GetAnimation(Animation::Opacity)->run_state());

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  EXPECT_FALSE(controller->GetAnimationById(animation_id));
  EXPECT_FALSE(controller_impl->GetAnimationById(animation_id));
}

// Ensure that we only generate Finished events for animations in a group
// once all animations in that group are finished.
TEST(LayerAnimationControllerTest, FinishedEventsForGroup) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);

  const int group_id = 1;

  // Add two animations with the same group id but different durations.
  controller_impl->AddAnimation(Animation::Create(
      scoped_ptr<AnimationCurve>(new FakeTransformTransition(2.0)).Pass(), 1,
      group_id, Animation::Transform));
  controller_impl->AddAnimation(Animation::Create(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      2, group_id, Animation::Opacity));

  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());

  // Both animations should have started.
  EXPECT_EQ(2u, events->size());
  EXPECT_EQ(AnimationEvent::Started, (*events)[0].type);
  EXPECT_EQ(AnimationEvent::Started, (*events)[1].type);

  events.reset(new AnimationEventsVector);
  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(1000));
  controller_impl->UpdateState(true, events.get());

  // The opacity animation should be finished, but should not have generated
  // a Finished event yet.
  EXPECT_EQ(0u, events->size());
  EXPECT_EQ(Animation::Finished,
            controller_impl->GetAnimationById(2)->run_state());
  EXPECT_EQ(Animation::Running,
            controller_impl->GetAnimationById(1)->run_state());

  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(2000));
  controller_impl->UpdateState(true, events.get());

  // Both animations should have generated Finished events.
  EXPECT_EQ(2u, events->size());
  EXPECT_EQ(AnimationEvent::Finished, (*events)[0].type);
  EXPECT_EQ(AnimationEvent::Finished, (*events)[1].type);
}

// Ensure that when a group has a mix of aborted and finished animations,
// we generate a Finished event for the finished animation and an Aborted
// event for the aborted animation.
TEST(LayerAnimationControllerTest, FinishedAndAbortedEventsForGroup) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);

  // Add two animations with the same group id.
  controller_impl->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)).Pass(),
      1,
      Animation::Transform));
  controller_impl->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));

  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());

  // Both animations should have started.
  EXPECT_EQ(2u, events->size());
  EXPECT_EQ(AnimationEvent::Started, (*events)[0].type);
  EXPECT_EQ(AnimationEvent::Started, (*events)[1].type);

  controller_impl->AbortAnimations(Animation::Opacity);

  events.reset(new AnimationEventsVector);
  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(1000));
  controller_impl->UpdateState(true, events.get());

  // We should have exactly 2 events: a Finished event for the tranform
  // animation, and an Aborted event for the opacity animation.
  EXPECT_EQ(2u, events->size());
  EXPECT_EQ(AnimationEvent::Finished, (*events)[0].type);
  EXPECT_EQ(Animation::Transform, (*events)[0].target_property);
  EXPECT_EQ(AnimationEvent::Aborted, (*events)[1].type);
  EXPECT_EQ(Animation::Opacity, (*events)[1].target_property);
}

TEST(LayerAnimationControllerTest, HasAnimationThatAffectsScale) {
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));

  EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale());

  controller_impl->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));

  // Opacity animations don't affect scale.
  EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale());

  scoped_ptr<KeyframedTransformAnimationCurve> curve1(
      KeyframedTransformAnimationCurve::Create());

  TransformOperations operations1;
  curve1->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
  operations1.AppendTranslate(10.0, 15.0, 0.0);
  curve1->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations1, nullptr));

  scoped_ptr<Animation> animation(
      Animation::Create(curve1.Pass(), 2, 2, Animation::Transform));
  controller_impl->AddAnimation(animation.Pass());

  // Translations don't affect scale.
  EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale());

  scoped_ptr<KeyframedTransformAnimationCurve> curve2(
      KeyframedTransformAnimationCurve::Create());

  TransformOperations operations2;
  curve2->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr));
  operations2.AppendScale(2.0, 3.0, 4.0);
  curve2->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));

  animation = Animation::Create(curve2.Pass(), 3, 3, Animation::Transform);
  controller_impl->AddAnimation(animation.Pass());

  EXPECT_TRUE(controller_impl->HasAnimationThatAffectsScale());

  controller_impl->GetAnimationById(3)
      ->SetRunState(Animation::Finished, TicksFromSecondsF(0.0));

  // Only unfinished animations should be considered by
  // HasAnimationThatAffectsScale.
  EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale());
}

TEST(LayerAnimationControllerTest, HasOnlyTranslationTransforms) {
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));

  EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms());

  controller_impl->AddAnimation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));

  // Opacity animations aren't non-translation transforms.
  EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms());

  scoped_ptr<KeyframedTransformAnimationCurve> curve1(
      KeyframedTransformAnimationCurve::Create());

  TransformOperations operations1;
  curve1->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
  operations1.AppendTranslate(10.0, 15.0, 0.0);
  curve1->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations1, nullptr));

  scoped_ptr<Animation> animation(
      Animation::Create(curve1.Pass(), 2, 2, Animation::Transform));
  controller_impl->AddAnimation(animation.Pass());

  // The only transform animation we've added is a translation.
  EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms());

  scoped_ptr<KeyframedTransformAnimationCurve> curve2(
      KeyframedTransformAnimationCurve::Create());

  TransformOperations operations2;
  curve2->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr));
  operations2.AppendScale(2.0, 3.0, 4.0);
  curve2->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));

  animation = Animation::Create(curve2.Pass(), 3, 3, Animation::Transform);
  controller_impl->AddAnimation(animation.Pass());

  // A scale animation is not a translation.
  EXPECT_FALSE(controller_impl->HasOnlyTranslationTransforms());

  controller_impl->GetAnimationById(3)
      ->SetRunState(Animation::Finished, TicksFromSecondsF(0.0));

  // Only unfinished animations should be considered by
  // HasOnlyTranslationTransforms.
  EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms());
}

TEST(LayerAnimationControllerTest, MaximumTargetScale) {
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));

  float max_scale = 0.f;
  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(0.f, max_scale);

  scoped_ptr<KeyframedTransformAnimationCurve> curve1(
      KeyframedTransformAnimationCurve::Create());

  TransformOperations operations1;
  curve1->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
  operations1.AppendScale(2.0, 3.0, 4.0);
  curve1->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations1, nullptr));

  scoped_ptr<Animation> animation(
      Animation::Create(curve1.Pass(), 1, 1, Animation::Transform));
  controller_impl->AddAnimation(animation.Pass());

  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(4.f, max_scale);

  scoped_ptr<KeyframedTransformAnimationCurve> curve2(
      KeyframedTransformAnimationCurve::Create());

  TransformOperations operations2;
  curve2->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr));
  operations2.AppendScale(6.0, 5.0, 4.0);
  curve2->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));

  animation = Animation::Create(curve2.Pass(), 2, 2, Animation::Transform);
  controller_impl->AddAnimation(animation.Pass());

  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(6.f, max_scale);

  scoped_ptr<KeyframedTransformAnimationCurve> curve3(
      KeyframedTransformAnimationCurve::Create());

  TransformOperations operations3;
  curve3->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr));
  operations3.AppendPerspective(6.0);
  curve3->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations3, nullptr));

  animation = Animation::Create(curve3.Pass(), 3, 3, Animation::Transform);
  controller_impl->AddAnimation(animation.Pass());

  EXPECT_FALSE(controller_impl->MaximumTargetScale(&max_scale));

  controller_impl->GetAnimationById(3)
      ->SetRunState(Animation::Finished, TicksFromSecondsF(0.0));
  controller_impl->GetAnimationById(2)
      ->SetRunState(Animation::Finished, TicksFromSecondsF(0.0));

  // Only unfinished animations should be considered by
  // MaximumTargetScale.
  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(4.f, max_scale);
}

TEST(LayerAnimationControllerTest, MaximumTargetScaleWithDirection) {
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));

  scoped_ptr<KeyframedTransformAnimationCurve> curve1(
      KeyframedTransformAnimationCurve::Create());
  TransformOperations operations1;
  operations1.AppendScale(1.0, 2.0, 3.0);
  curve1->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
  TransformOperations operations2;
  operations2.AppendScale(4.0, 5.0, 6.0);
  curve1->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));

  scoped_ptr<Animation> animation_owned(
      Animation::Create(curve1.Pass(), 1, 1, Animation::Transform));
  Animation* animation = animation_owned.get();
  controller_impl->AddAnimation(animation_owned.Pass());

  float max_scale = 0.f;

  EXPECT_GT(animation->playback_rate(), 0.0);

  // Normal direction with positive playback rate.
  animation->set_direction(Animation::Normal);
  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(6.f, max_scale);

  // Alternate direction with positive playback rate.
  animation->set_direction(Animation::Alternate);
  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(6.f, max_scale);

  // Reverse direction with positive playback rate.
  animation->set_direction(Animation::Reverse);
  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(3.f, max_scale);

  // Alternate reverse direction.
  animation->set_direction(Animation::Reverse);
  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(3.f, max_scale);

  animation->set_playback_rate(-1.0);

  // Normal direction with negative playback rate.
  animation->set_direction(Animation::Normal);
  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(3.f, max_scale);

  // Alternate direction with negative playback rate.
  animation->set_direction(Animation::Alternate);
  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(3.f, max_scale);

  // Reverse direction with negative playback rate.
  animation->set_direction(Animation::Reverse);
  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(6.f, max_scale);

  // Alternate reverse direction with negative playback rate.
  animation->set_direction(Animation::Reverse);
  EXPECT_TRUE(controller_impl->MaximumTargetScale(&max_scale));
  EXPECT_EQ(6.f, max_scale);
}

TEST(LayerAnimationControllerTest, NewlyPushedAnimationWaitsForActivation) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy_impl;
  FakeInactiveLayerAnimationValueObserver pending_dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  controller_impl->AddValueObserver(&pending_dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
  int animation_id =
      AddOpacityTransitionToController(controller.get(), 1, 0.5f, 1.f, false);
  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());

  EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing());
  controller->PushAnimationUpdatesTo(controller_impl.get());
  EXPECT_TRUE(controller_impl->needs_to_start_animations_for_testing());

  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));
  EXPECT_EQ(Animation::WaitingForTargetAvailability,
            controller_impl->GetAnimationById(animation_id)->run_state());
  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)
                  ->affects_pending_observers());
  EXPECT_FALSE(controller_impl->GetAnimationById(animation_id)
                   ->affects_active_observers());

  controller_impl->Animate(kInitialTickTime);
  EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing());
  controller_impl->UpdateState(true, events.get());

  // Since the animation hasn't been activated, it should still be Starting
  // rather than Running.
  EXPECT_EQ(Animation::Starting,
            controller_impl->GetAnimationById(animation_id)->run_state());

  // Since the animation hasn't been activated, only the pending observer
  // should have been ticked.
  EXPECT_EQ(0.5f, pending_dummy_impl.opacity());
  EXPECT_EQ(0.f, dummy_impl.opacity());

  controller_impl->ActivateAnimations();
  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)
                  ->affects_pending_observers());
  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)
                  ->affects_active_observers());

  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(1000));
  controller_impl->UpdateState(true, events.get());

  // Since the animation has been activated, it should have reached the
  // Running state and the active observer should start to get ticked.
  EXPECT_EQ(Animation::Running,
            controller_impl->GetAnimationById(animation_id)->run_state());
  EXPECT_EQ(0.5f, pending_dummy_impl.opacity());
  EXPECT_EQ(0.5f, dummy_impl.opacity());
}

TEST(LayerAnimationControllerTest, ActivationBetweenAnimateAndUpdateState) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy_impl;
  FakeInactiveLayerAnimationValueObserver pending_dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  controller_impl->AddValueObserver(&pending_dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  int animation_id =
      AddOpacityTransitionToController(controller.get(), 1, 0.5f, 1.f, true);

  controller->PushAnimationUpdatesTo(controller_impl.get());

  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));
  EXPECT_EQ(Animation::WaitingForTargetAvailability,
            controller_impl->GetAnimationById(animation_id)->run_state());
  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)
                  ->affects_pending_observers());
  EXPECT_FALSE(controller_impl->GetAnimationById(animation_id)
                   ->affects_active_observers());

  controller_impl->Animate(kInitialTickTime);

  // Since the animation hasn't been activated, only the pending observer
  // should have been ticked.
  EXPECT_EQ(0.5f, pending_dummy_impl.opacity());
  EXPECT_EQ(0.f, dummy_impl.opacity());

  controller_impl->ActivateAnimations();
  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)
                  ->affects_pending_observers());
  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)
                  ->affects_active_observers());

  controller_impl->UpdateState(true, events.get());

  // Since the animation has been activated, it should have reached the
  // Running state.
  EXPECT_EQ(Animation::Running,
            controller_impl->GetAnimationById(animation_id)->run_state());

  controller_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));

  // Both observers should have been ticked.
  EXPECT_EQ(0.75f, pending_dummy_impl.opacity());
  EXPECT_EQ(0.75f, dummy_impl.opacity());
}

TEST(LayerAnimationControllerTest, ClippedOpacityValues) {
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  AddOpacityTransitionToController(controller.get(), 1, 1.f, 2.f, true);

  controller->Animate(kInitialTickTime);
  EXPECT_EQ(1.f, dummy.opacity());

  // Opacity values are clipped [0,1]
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  EXPECT_EQ(1.f, dummy.opacity());
}

TEST(LayerAnimationControllerTest, ClippedNegativeOpacityValues) {
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  AddOpacityTransitionToController(controller.get(), 1, 0.f, -2.f, true);

  controller->Animate(kInitialTickTime);
  EXPECT_EQ(0.f, dummy.opacity());

  // Opacity values are clipped [0,1]
  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
  EXPECT_EQ(0.f, dummy.opacity());
}

TEST(LayerAnimationControllerTest, PushedDeletedAnimationWaitsForActivation) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy_impl;
  FakeInactiveLayerAnimationValueObserver pending_dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  controller_impl->AddValueObserver(&pending_dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  int animation_id =
      AddOpacityTransitionToController(controller.get(), 1, 0.5f, 1.f, true);

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());
  EXPECT_EQ(Animation::Running,
            controller_impl->GetAnimationById(animation_id)->run_state());
  EXPECT_EQ(0.5f, pending_dummy_impl.opacity());
  EXPECT_EQ(0.5f, dummy_impl.opacity());

  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)
                  ->affects_pending_observers());
  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)
                  ->affects_active_observers());

  // Delete the animation on the main-thread controller.
  controller->RemoveAnimation(
      controller->GetAnimation(Animation::Opacity)->id());
  controller->PushAnimationUpdatesTo(controller_impl.get());

  // The animation should no longer affect pending observers.
  EXPECT_FALSE(controller_impl->GetAnimationById(animation_id)
                   ->affects_pending_observers());
  EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)
                  ->affects_active_observers());

  controller_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));
  controller_impl->UpdateState(true, events.get());

  // Only the active observer should have been ticked.
  EXPECT_EQ(0.5f, pending_dummy_impl.opacity());
  EXPECT_EQ(0.75f, dummy_impl.opacity());

  controller_impl->ActivateAnimations();

  // Activation should cause the animation to be deleted.
  EXPECT_FALSE(controller_impl->has_any_animation());
}

// Tests that an animation that affects only active observers won't block
// an animation that affects only pending observers from starting.
TEST(LayerAnimationControllerTest, StartAnimationsAffectingDifferentObservers) {
  scoped_ptr<AnimationEventsVector> events(
      make_scoped_ptr(new AnimationEventsVector));
  FakeLayerAnimationValueObserver dummy_impl;
  FakeInactiveLayerAnimationValueObserver pending_dummy_impl;
  scoped_refptr<LayerAnimationController> controller_impl(
      LayerAnimationController::Create(0));
  controller_impl->AddValueObserver(&dummy_impl);
  controller_impl->AddValueObserver(&pending_dummy_impl);
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  int first_animation_id =
      AddOpacityTransitionToController(controller.get(), 1, 0.f, 1.f, true);

  controller->PushAnimationUpdatesTo(controller_impl.get());
  controller_impl->ActivateAnimations();
  controller_impl->Animate(kInitialTickTime);
  controller_impl->UpdateState(true, events.get());

  // Remove the first animation from the main-thread controller, and add a
  // new animation affecting the same property.
  controller->RemoveAnimation(
      controller->GetAnimation(Animation::Opacity)->id());
  int second_animation_id =
      AddOpacityTransitionToController(controller.get(), 1, 1.f, 0.5f, true);
  controller->PushAnimationUpdatesTo(controller_impl.get());

  // The original animation should only affect active observers, and the new
  // animation should only affect pending observers.
  EXPECT_FALSE(controller_impl->GetAnimationById(first_animation_id)
                   ->affects_pending_observers());
  EXPECT_TRUE(controller_impl->GetAnimationById(first_animation_id)
                  ->affects_active_observers());
  EXPECT_TRUE(controller_impl->GetAnimationById(second_animation_id)
                  ->affects_pending_observers());
  EXPECT_FALSE(controller_impl->GetAnimationById(second_animation_id)
                   ->affects_active_observers());

  controller_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500));
  controller_impl->UpdateState(true, events.get());

  // The original animation should still be running, and the new animation
  // should be starting.
  EXPECT_EQ(Animation::Running,
            controller_impl->GetAnimationById(first_animation_id)->run_state());
  EXPECT_EQ(
      Animation::Starting,
      controller_impl->GetAnimationById(second_animation_id)->run_state());

  // The active observer should have been ticked by the original animation,
  // and the pending observer should have been ticked by the new animation.
  EXPECT_EQ(1.f, pending_dummy_impl.opacity());
  EXPECT_EQ(0.5f, dummy_impl.opacity());

  controller_impl->ActivateAnimations();

  // The original animation should have been deleted, and the new animation
  // should now affect both observers.
  EXPECT_FALSE(controller_impl->GetAnimationById(first_animation_id));
  EXPECT_TRUE(controller_impl->GetAnimationById(second_animation_id)
                  ->affects_pending_observers());
  EXPECT_TRUE(controller_impl->GetAnimationById(second_animation_id)
                  ->affects_active_observers());

  controller_impl->Animate(kInitialTickTime +
                           TimeDelta::FromMilliseconds(1000));
  controller_impl->UpdateState(true, events.get());

  // The new animation should be running, and the active observer should have
  // been ticked at the new animation's starting point.
  EXPECT_EQ(
      Animation::Running,
      controller_impl->GetAnimationById(second_animation_id)->run_state());
  EXPECT_EQ(1.f, pending_dummy_impl.opacity());
  EXPECT_EQ(1.f, dummy_impl.opacity());
}

TEST(LayerAnimationControllerTest, TestIsAnimatingProperty) {
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  scoped_ptr<Animation> animation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));
  controller->AddAnimation(animation.Pass());
  controller->Animate(kInitialTickTime);
  EXPECT_TRUE(controller->IsAnimatingProperty(Animation::Opacity));
  controller->UpdateState(true, nullptr);
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_TRUE(controller->IsAnimatingProperty(Animation::Opacity));
  EXPECT_FALSE(controller->IsAnimatingProperty(Animation::Filter));
  EXPECT_EQ(0.f, dummy.opacity());
}

TEST(LayerAnimationControllerTest, TestIsAnimatingPropertyTimeOffsetFillMode) {
  FakeLayerAnimationValueObserver dummy;
  scoped_refptr<LayerAnimationController> controller(
      LayerAnimationController::Create(0));
  controller->AddValueObserver(&dummy);

  scoped_ptr<Animation> animation(CreateAnimation(
      scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
      1,
      Animation::Opacity));
  animation->set_fill_mode(Animation::FillModeNone);
  animation->set_time_offset(TimeDelta::FromMilliseconds(-2000));
  controller->AddAnimation(animation.Pass());

  controller->Animate(kInitialTickTime);
  controller->UpdateState(true, nullptr);
  EXPECT_FALSE(controller->IsAnimatingProperty(Animation::Opacity));
  EXPECT_TRUE(controller->HasActiveAnimation());
  EXPECT_FALSE(controller->IsAnimatingProperty(Animation::Opacity));
  EXPECT_FALSE(controller->IsAnimatingProperty(Animation::Filter));

  controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
  controller->UpdateState(true, nullptr);
  EXPECT_TRUE(controller->IsAnimatingProperty(Animation::Opacity));
}

}  // namespace
}  // namespace cc
