This source file includes following definitions.
- CreateAnimation
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- GetMostRecentPropertyUpdateEvent
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- finished_
- NotifyAnimationStarted
- NotifyAnimationFinished
- started
- finished
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
#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/box_f.h"
#include "ui/gfx/transform.h"
namespace cc {
namespace {
const double kInitialTickTime = 1.0;
scoped_ptr<Animation> CreateAnimation(scoped_ptr<AnimationCurve> curve,
int id,
Animation::TargetProperty property) {
return Animation::Create(curve.Pass(), 0, 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));
AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
int group_id = controller->GetAnimation(Animation::Opacity)->group();
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_TRUE(controller_impl->GetAnimation(group_id, Animation::Opacity));
EXPECT_EQ(Animation::WaitingForTargetAvailability,
controller_impl->GetAnimation(group_id,
Animation::Opacity)->run_state());
}
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));
AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
int group_id = controller->GetAnimation(Animation::Opacity)->group();
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_TRUE(controller_impl->GetAnimation(group_id, Animation::Opacity));
EXPECT_EQ(Animation::WaitingForTargetAvailability,
controller_impl->GetAnimation(group_id,
Animation::Opacity)->run_state());
AnimationEventsVector events;
controller_impl->Animate(kInitialTickTime);
controller_impl->UpdateState(true, &events);
EXPECT_EQ(1u, events.size());
controller->NotifyAnimationStarted(events[0]);
EXPECT_EQ(controller->GetAnimation(group_id,
Animation::Opacity)->start_time(),
controller_impl->GetAnimation(group_id,
Animation::Opacity)->start_time());
controller->Animate(kInitialTickTime + 0.5);
controller->UpdateState(true, NULL);
EXPECT_EQ(controller->GetAnimation(group_id,
Animation::Opacity)->start_time(),
controller_impl->GetAnimation(group_id,
Animation::Opacity)->start_time());
}
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());
EXPECT_EQ(0u, registrar->active_animation_controllers().size());
EXPECT_EQ(0u, registrar_impl->active_animation_controllers().size());
AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
EXPECT_EQ(1u, registrar->active_animation_controllers().size());
controller->PushAnimationUpdatesTo(controller_impl.get());
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 + 0.5);
controller->UpdateState(true, NULL);
EXPECT_EQ(1u, registrar->active_animation_controllers().size());
controller->Animate(kInitialTickTime + 1.0);
controller->UpdateState(true, NULL);
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 + 1.5);
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(Animation::WaitingForDeletion,
controller_impl->GetAnimation(Animation::Opacity)->run_state());
EXPECT_EQ(0u, registrar_impl->active_animation_controllers().size());
EXPECT_EQ(1u, events->size());
controller->NotifyAnimationFinished((*events)[0]);
controller->Animate(kInitialTickTime + 1.5);
controller->UpdateState(true, NULL);
EXPECT_EQ(Animation::WaitingForDeletion,
controller->GetAnimation(Animation::Opacity)->run_state());
EXPECT_EQ(0u, registrar->active_animation_controllers().size());
controller->PushAnimationUpdatesTo(controller_impl.get());
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(NULL);
controller_impl->SetAnimationRegistrar(NULL);
}
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));
AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
int group_id = controller->GetAnimation(Animation::Opacity)->group();
int animation_id = controller->GetAnimation(Animation::Opacity)->id();
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_TRUE(controller_impl->GetAnimation(group_id, Animation::Opacity));
EXPECT_EQ(Animation::WaitingForTargetAvailability,
controller_impl->GetAnimation(group_id,
Animation::Opacity)->run_state());
AnimationEventsVector events;
controller_impl->Animate(kInitialTickTime);
controller_impl->UpdateState(true, &events);
controller->Animate(kInitialTickTime);
controller->UpdateState(true, NULL);
EXPECT_EQ(Animation::Running,
controller_impl->GetAnimation(group_id,
Animation::Opacity)->run_state());
EXPECT_EQ(Animation::Running,
controller->GetAnimation(group_id,
Animation::Opacity)->run_state());
controller->PauseAnimation(animation_id, kInitialTickTime + 1.0);
EXPECT_EQ(Animation::Paused,
controller->GetAnimation(group_id,
Animation::Opacity)->run_state());
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_EQ(Animation::Paused,
controller_impl->GetAnimation(group_id,
Animation::Opacity)->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->GetAnimation(Animation::Opacity)->group();
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_TRUE(controller_impl->GetAnimation(group_id, Animation::Opacity));
EXPECT_EQ(Animation::WaitingForTargetAvailability,
controller_impl->GetAnimation(group_id,
Animation::Opacity)->run_state());
AnimationEvent animation_started_event(AnimationEvent::Started,
0,
group_id,
Animation::Opacity,
kInitialTickTime);
controller->NotifyAnimationStarted(animation_started_event);
controller_impl->RemoveAnimation(animation_id);
EXPECT_FALSE(controller_impl->GetAnimation(group_id, Animation::Opacity));
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_FALSE(controller_impl->GetAnimation(group_id, Animation::Opacity));
}
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, NULL);
controller->PushAnimationUpdatesTo(controller_impl.get());
controller_impl->Animate(kInitialTickTime + 0.5);
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(1u, events->size());
EXPECT_EQ(AnimationEvent::Started, (*events)[0].type);
controller->NotifyAnimationStarted((*events)[0]);
controller->Animate(kInitialTickTime + 1.0);
controller->UpdateState(true, NULL);
EXPECT_FALSE(dummy.animation_waiting_for_deletion());
EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion());
events.reset(new AnimationEventsVector);
controller_impl->Animate(kInitialTickTime + 2.0);
controller_impl->UpdateState(true, events.get());
EXPECT_TRUE(dummy_impl.animation_waiting_for_deletion());
EXPECT_EQ(1u, events->size());
EXPECT_EQ(AnimationEvent::Finished, (*events)[0].type);
EXPECT_TRUE(controller->GetAnimation(Animation::Opacity));
EXPECT_TRUE(controller_impl->GetAnimation(Animation::Opacity));
controller->NotifyAnimationFinished((*events)[0]);
controller->Animate(kInitialTickTime + 3.0);
controller->UpdateState(true, NULL);
EXPECT_TRUE(dummy.animation_waiting_for_deletion());
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_FALSE(controller->has_any_animation());
EXPECT_FALSE(controller_impl->has_any_animation());
}
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));
controller->AddAnimation(to_add.Pass());
controller->Animate(kInitialTickTime);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.f, dummy.opacity());
const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get());
EXPECT_FALSE(event);
controller->Animate(kInitialTickTime + 1.0);
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(2u, events->size());
const AnimationEvent* start_opacity_event =
GetMostRecentPropertyUpdateEvent(events.get());
EXPECT_EQ(0.f, start_opacity_event->opacity);
controller_impl->Animate(kInitialTickTime + 1.0);
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(1.f, dummy_impl.opacity());
EXPECT_FALSE(controller_impl->HasActiveAnimation());
EXPECT_EQ(4u, 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);
const float delta_x = 3;
const float delta_y = 4;
scoped_ptr<KeyframedTransformAnimationCurve> curve(
KeyframedTransformAnimationCurve::Create());
TransformOperations operations;
curve->AddKeyframe(
TransformKeyframe::Create(0, operations, scoped_ptr<TimingFunction>()));
operations.AppendTranslate(delta_x, delta_y, 0);
curve->AddKeyframe(
TransformKeyframe::Create(1, operations, scoped_ptr<TimingFunction>()));
scoped_ptr<Animation> animation(Animation::Create(
curve.PassAs<AnimationCurve>(), 1, 0, Animation::Transform));
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(gfx::Transform(), dummy_impl.transform());
EXPECT_EQ(2u, 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 + 1.0);
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(expected_transform, dummy_impl.transform());
EXPECT_FALSE(controller_impl->HasActiveAnimation());
EXPECT_EQ(4u, 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(0, start_filters, scoped_ptr<TimingFunction>()));
FilterOperations end_filters;
end_filters.Append(FilterOperation::CreateBrightnessFilter(2.f));
curve->AddKeyframe(
FilterKeyframe::Create(1, end_filters, scoped_ptr<TimingFunction>()));
scoped_ptr<Animation> animation(Animation::Create(
curve.PassAs<AnimationCurve>(), 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());
const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get());
EXPECT_FALSE(event);
controller->Animate(kInitialTickTime + 0.5);
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 + 1.0);
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());
FilterOperations start_filters;
start_filters.Append(FilterOperation::CreateBrightnessFilter(1.f));
curve->AddKeyframe(
FilterKeyframe::Create(0, start_filters, scoped_ptr<TimingFunction>()));
FilterOperations end_filters;
end_filters.Append(FilterOperation::CreateBrightnessFilter(2.f));
curve->AddKeyframe(
FilterKeyframe::Create(1, end_filters, scoped_ptr<TimingFunction>()));
scoped_ptr<Animation> animation(Animation::Create(
curve.PassAs<AnimationCurve>(), 1, 0, Animation::Filter));
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(start_filters, dummy_impl.filters());
EXPECT_EQ(2u, 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 + 1.0);
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(end_filters, dummy_impl.filters());
EXPECT_FALSE(controller_impl->HasActiveAnimation());
EXPECT_EQ(4u, 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::Vector2dF initial_value(100.f, 300.f);
gfx::Vector2dF target_value(300.f, 200.f);
scoped_ptr<ScrollOffsetAnimationCurve> curve(
ScrollOffsetAnimationCurve::Create(
target_value,
EaseInOutTimingFunction::Create().Pass()));
scoped_ptr<Animation> animation(Animation::Create(
curve.PassAs<AnimationCurve>(), 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());
EXPECT_TRUE(controller_impl->GetAnimation(Animation::ScrollOffset));
double duration = controller_impl->GetAnimation(
Animation::ScrollOffset)->curve()->Duration();
EXPECT_EQ(
duration,
controller->GetAnimation(Animation::ScrollOffset)->curve()->Duration());
controller->Animate(kInitialTickTime);
controller->UpdateState(true, NULL);
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());
const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get());
EXPECT_FALSE(event);
controller->NotifyAnimationStarted((*events)[0]);
controller->Animate(kInitialTickTime + duration/2.0);
controller->UpdateState(true, NULL);
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(200.f, 250.f), dummy.scroll_offset());
controller_impl->Animate(kInitialTickTime + duration/2.0);
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, NULL);
EXPECT_VECTOR2DF_EQ(target_value, dummy.scroll_offset());
EXPECT_FALSE(controller->HasActiveAnimation());
}
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::Vector2dF initial_value(500.f, 100.f);
gfx::Vector2dF target_value(300.f, 200.f);
scoped_ptr<ScrollOffsetAnimationCurve> curve(
ScrollOffsetAnimationCurve::Create(
target_value,
EaseInOutTimingFunction::Create().Pass()));
scoped_ptr<Animation> animation(Animation::Create(
curve.PassAs<AnimationCurve>(), 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());
EXPECT_TRUE(controller_impl->GetAnimation(Animation::ScrollOffset));
double duration = controller_impl->GetAnimation(
Animation::ScrollOffset)->curve()->Duration();
EXPECT_EQ(
duration,
controller->GetAnimation(Animation::ScrollOffset)->curve()->Duration());
controller->Animate(kInitialTickTime);
controller->UpdateState(true, NULL);
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());
const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get());
EXPECT_FALSE(event);
controller->NotifyAnimationStarted((*events)[0]);
controller->Animate(kInitialTickTime + duration/2.0);
controller->UpdateState(true, NULL);
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(400.f, 150.f), dummy.scroll_offset());
controller_impl->Animate(kInitialTickTime + duration/2.0);
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, NULL);
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::Vector2dF initial_value(100.f, 300.f);
gfx::Vector2dF target_value(300.f, 200.f);
scoped_ptr<ScrollOffsetAnimationCurve> curve(
ScrollOffsetAnimationCurve::Create(
target_value,
EaseInOutTimingFunction::Create().Pass()));
curve->SetInitialValue(initial_value);
double duration = curve->Duration();
scoped_ptr<Animation> animation(Animation::Create(
curve.PassAs<AnimationCurve>(), 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());
const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get());
EXPECT_FALSE(event);
controller_impl->Animate(kInitialTickTime + duration/2.0);
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);
}
class FakeAnimationDelegate : public AnimationDelegate {
public:
FakeAnimationDelegate()
: started_(false),
finished_(false) {}
virtual void NotifyAnimationStarted(
base::TimeTicks monotonic_time,
Animation::TargetProperty target_property) OVERRIDE {
started_ = true;
}
virtual void NotifyAnimationFinished(
base::TimeTicks monotonic_time,
Animation::TargetProperty target_property) OVERRIDE {
finished_ = true;
}
bool started() { return started_; }
bool finished() { return finished_; }
private:
bool started_;
bool finished_;
};
TEST(LayerAnimationControllerTest,
NotificationsForImplOnlyAnimationsAreSentToMainThreadDelegate) {
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);
FakeAnimationDelegate delegate;
controller->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());
controller_impl->Animate(kInitialTickTime);
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(2u, events->size());
EXPECT_EQ(AnimationEvent::Started, (*events)[0].type);
EXPECT_TRUE((*events)[0].is_impl_only);
EXPECT_EQ(AnimationEvent::PropertyUpdate, (*events)[1].type);
EXPECT_TRUE((*events)[1].is_impl_only);
EXPECT_FALSE(delegate.started());
controller->NotifyAnimationStarted((*events)[0]);
EXPECT_TRUE(delegate.started());
events.reset(new AnimationEventsVector);
controller_impl->Animate(kInitialTickTime + 1.0);
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(2u, events->size());
EXPECT_EQ(AnimationEvent::Finished, (*events)[0].type);
EXPECT_TRUE((*events)[0].is_impl_only);
EXPECT_EQ(AnimationEvent::PropertyUpdate, (*events)[1].type);
EXPECT_TRUE((*events)[1].is_impl_only);
EXPECT_FALSE(delegate.finished());
controller->NotifyAnimationFinished((*events)[0]);
EXPECT_TRUE(delegate.finished());
}
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);
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 + 1.0);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.f, dummy.opacity());
controller->Animate(kInitialTickTime + 2.0);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.f, dummy.opacity());
controller->NotifyAnimationStarted(AnimationEvent(
AnimationEvent::Started, 0, 1, Animation::Opacity, kInitialTickTime + 2));
controller->Animate(kInitialTickTime + 5.0);
controller->UpdateState(true, events.get());
EXPECT_EQ(1.f, dummy.opacity());
EXPECT_FALSE(controller->HasActiveAnimation());
}
TEST(LayerAnimationControllerTest, TrivialQueuing) {
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->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(
new FakeFloatTransition(1.0, 1.f, 0.5f)).Pass(),
2,
Animation::Opacity));
controller->Animate(kInitialTickTime);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.f, dummy.opacity());
controller->Animate(kInitialTickTime + 1.0);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(1.f, dummy.opacity());
controller->Animate(kInitialTickTime + 2.0);
controller->UpdateState(true, events.get());
EXPECT_EQ(0.5f, dummy.opacity());
EXPECT_FALSE(controller->HasActiveAnimation());
}
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());
controller->Animate(kInitialTickTime + 0.5);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(1.f, dummy.opacity());
controller->Animate(kInitialTickTime + 1.5);
controller->UpdateState(true, events.get());
EXPECT_EQ(0.5f, dummy.opacity());
EXPECT_FALSE(controller->HasActiveAnimation());
}
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 + 1.0);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.f, dummy.opacity());
controller->Animate(kInitialTickTime + 2.0);
controller->UpdateState(true, events.get());
EXPECT_EQ(1.f, dummy.opacity());
EXPECT_FALSE(controller->HasActiveAnimation());
}
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));
controller->Animate(kInitialTickTime);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.f, dummy.opacity());
controller->Animate(kInitialTickTime + 2.0);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(1.f, dummy.opacity());
controller->Animate(kInitialTickTime + 3.0);
controller->UpdateState(true, events.get());
EXPECT_EQ(0.5f, dummy.opacity());
EXPECT_FALSE(controller->HasActiveAnimation());
}
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 + 1.25);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.25f, dummy.opacity());
controller->Animate(kInitialTickTime + 1.75);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.75f, dummy.opacity());
controller->Animate(kInitialTickTime + 2.25);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.25f, dummy.opacity());
controller->Animate(kInitialTickTime + 2.75);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.75f, dummy.opacity());
controller->Animate(kInitialTickTime + 3.0);
controller->UpdateState(true, events.get());
EXPECT_FALSE(controller->HasActiveAnimation());
EXPECT_EQ(1.f, dummy.opacity());
controller->Animate(kInitialTickTime + 4.0);
controller->UpdateState(true, events.get());
EXPECT_EQ(1.f, dummy.opacity());
}
TEST(LayerAnimationControllerTest, InfiniteLooping) {
scoped_ptr<AnimationEventsVector> events(
make_scoped_ptr(new AnimationEventsVector));
FakeLayerAnimationValueObserver dummy;
scoped_refptr<LayerAnimationController> controller(
LayerAnimationController::Create(0));
controller->AddValueObserver(&dummy);
const int id = 1;
scoped_ptr<Animation> to_add(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
id,
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 + 1.25);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.25f, dummy.opacity());
controller->Animate(kInitialTickTime + 1.75);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.75f, dummy.opacity());
controller->Animate(kInitialTickTime + 1073741824.25);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.25f, dummy.opacity());
controller->Animate(kInitialTickTime + 1073741824.75);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.75f, dummy.opacity());
EXPECT_TRUE(controller->GetAnimation(id, Animation::Opacity));
controller->GetAnimation(id, Animation::Opacity)->SetRunState(
Animation::Aborted, kInitialTickTime + 0.75);
EXPECT_FALSE(controller->HasActiveAnimation());
EXPECT_EQ(0.75f, dummy.opacity());
}
TEST(LayerAnimationControllerTest, PauseResume) {
scoped_ptr<AnimationEventsVector> events(
make_scoped_ptr(new AnimationEventsVector));
FakeLayerAnimationValueObserver dummy;
scoped_refptr<LayerAnimationController> controller(
LayerAnimationController::Create(0));
controller->AddValueObserver(&dummy);
const int id = 1;
controller->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
id,
Animation::Opacity));
controller->Animate(kInitialTickTime);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.f, dummy.opacity());
controller->Animate(kInitialTickTime + 0.5);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.5f, dummy.opacity());
EXPECT_TRUE(controller->GetAnimation(id, Animation::Opacity));
controller->GetAnimation(id, Animation::Opacity)->SetRunState(
Animation::Paused, kInitialTickTime + 0.5);
controller->Animate(kInitialTickTime + 1024.0);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.5f, dummy.opacity());
EXPECT_TRUE(controller->GetAnimation(id, Animation::Opacity));
controller->GetAnimation(id, Animation::Opacity)->SetRunState(
Animation::Running, kInitialTickTime + 1024);
controller->Animate(kInitialTickTime + 1024.25);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.75f, dummy.opacity());
controller->Animate(kInitialTickTime + 1024.5);
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 id = 1;
controller->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeTransformTransition(1)).Pass(),
id,
Animation::Transform));
controller->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeFloatTransition(2.0, 0.f, 1.f)).Pass(),
id,
Animation::Opacity));
controller->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(
new FakeFloatTransition(1.0, 1.f, 0.75f)).Pass(),
2,
Animation::Opacity));
controller->Animate(kInitialTickTime);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.f, dummy.opacity());
controller->Animate(kInitialTickTime + 1.0);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.5f, dummy.opacity());
EXPECT_TRUE(controller->GetAnimation(id, Animation::Opacity));
controller->GetAnimation(id, Animation::Opacity)->SetRunState(
Animation::Aborted, kInitialTickTime + 1.0);
controller->Animate(kInitialTickTime + 1.0);
controller->UpdateState(true, events.get());
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(1.f, dummy.opacity());
controller->Animate(kInitialTickTime + 2.0);
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(0, Animation::Opacity);
EXPECT_TRUE(active_animation);
EXPECT_TRUE(active_animation->needs_synchronized_start_time());
controller->PushAnimationUpdatesTo(controller_impl.get());
active_animation = controller_impl->GetAnimation(0, Animation::Opacity);
EXPECT_TRUE(active_animation);
EXPECT_EQ(Animation::WaitingForTargetAvailability,
active_animation->run_state());
}
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));
controller->Animate(kInitialTickTime + 1.0);
controller->Animate(kInitialTickTime + 2.0);
events.reset(new AnimationEventsVector);
controller->UpdateState(true, events.get());
EXPECT_EQ(2u, events->size());
EXPECT_NE((*events)[0].type, (*events)[1].type);
EXPECT_TRUE(controller->HasActiveAnimation());
EXPECT_EQ(0.f, dummy.opacity());
controller->Animate(kInitialTickTime + 3.0);
controller->UpdateState(true, events.get());
EXPECT_EQ(1.f, dummy.opacity());
EXPECT_FALSE(controller->HasActiveAnimation());
}
TEST(LayerAnimationControllerTest, InactiveObserverGetsTicked) {
scoped_ptr<AnimationEventsVector> events(
make_scoped_ptr(new AnimationEventsVector));
FakeLayerAnimationValueObserver dummy;
FakeInactiveLayerAnimationValueObserver inactive_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));
controller->Animate(kInitialTickTime);
controller->UpdateState(true, events.get());
EXPECT_EQ(0u, events->size());
EXPECT_EQ(Animation::WaitingForTargetAvailability,
controller->GetAnimation(id, Animation::Opacity)->run_state());
controller->AddValueObserver(&inactive_dummy);
controller->Animate(kInitialTickTime + 1.0);
controller->UpdateState(true, events.get());
EXPECT_EQ(0u, events->size());
EXPECT_EQ(Animation::Starting,
controller->GetAnimation(id, Animation::Opacity)->run_state());
EXPECT_EQ(0.5f, inactive_dummy.opacity());
controller->Animate(kInitialTickTime + 2.0);
controller->UpdateState(true, events.get());
EXPECT_EQ(0u, events->size());
EXPECT_EQ(Animation::Starting,
controller->GetAnimation(id, Animation::Opacity)->run_state());
EXPECT_EQ(0.5f, inactive_dummy.opacity());
controller->AddValueObserver(&dummy);
controller->Animate(kInitialTickTime + 3.0);
controller->UpdateState(true, events.get());
EXPECT_EQ(1u, events->size());
EXPECT_EQ(Animation::Running,
controller->GetAnimation(id, Animation::Opacity)->run_state());
EXPECT_EQ(0.5f, inactive_dummy.opacity());
EXPECT_EQ(0.5f, dummy.opacity());
controller->Animate(kInitialTickTime + 3.5);
EXPECT_NE(0.5f, inactive_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(
0.0, operations1, scoped_ptr<TimingFunction>()));
operations1.AppendTranslate(10.0, 15.0, 0.0);
curve1->AddKeyframe(TransformKeyframe::Create(
1.0, operations1, scoped_ptr<TimingFunction>()));
scoped_ptr<Animation> animation(Animation::Create(
curve1.PassAs<AnimationCurve>(), 1, 1, Animation::Transform));
controller_impl->AddAnimation(animation.Pass());
scoped_ptr<KeyframedTransformAnimationCurve> curve2(
KeyframedTransformAnimationCurve::Create());
TransformOperations operations2;
curve2->AddKeyframe(TransformKeyframe::Create(
0.0, operations2, scoped_ptr<TimingFunction>()));
operations2.AppendScale(2.0, 3.0, 4.0);
curve2->AddKeyframe(TransformKeyframe::Create(
1.0, operations2, scoped_ptr<TimingFunction>()));
animation = Animation::Create(
curve2.PassAs<AnimationCurve>(), 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->GetAnimation(1, Animation::Transform)
->SetRunState(Animation::Finished, 0.0);
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->GetAnimation(2, Animation::Transform)
->SetRunState(Animation::Finished, 0.0);
EXPECT_FALSE(controller_impl->HasTransformAnimationThatInflatesBounds());
scoped_ptr<KeyframedTransformAnimationCurve> curve3(
KeyframedTransformAnimationCurve::Create());
TransformOperations operations3;
gfx::Transform transform3;
transform3.Scale3d(1.0, 2.0, 3.0);
curve3->AddKeyframe(TransformKeyframe::Create(
0.0, operations3, scoped_ptr<TimingFunction>()));
operations3.AppendMatrix(transform3);
curve3->AddKeyframe(TransformKeyframe::Create(
1.0, operations3, scoped_ptr<TimingFunction>()));
animation = Animation::Create(
curve3.PassAs<AnimationCurve>(), 3, 3, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
EXPECT_FALSE(controller_impl->TransformAnimationBoundsForBox(box, &bounds));
}
TEST(LayerAnimationControllerTest, AbortAnimations) {
FakeLayerAnimationValueObserver dummy;
scoped_refptr<LayerAnimationController> controller(
LayerAnimationController::Create(0));
controller->AddValueObserver(&dummy);
controller->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)).Pass(),
1,
Animation::Transform));
controller->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
2,
Animation::Opacity));
controller->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)).Pass(),
3,
Animation::Transform));
controller->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeTransformTransition(2.0)).Pass(),
4,
Animation::Transform));
controller->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
5,
Animation::Opacity));
controller->Animate(kInitialTickTime);
controller->UpdateState(true, NULL);
controller->Animate(kInitialTickTime + 1.0);
controller->UpdateState(true, NULL);
EXPECT_EQ(Animation::Finished,
controller->GetAnimation(1, Animation::Transform)->run_state());
EXPECT_EQ(Animation::Finished,
controller->GetAnimation(2, Animation::Opacity)->run_state());
EXPECT_EQ(Animation::Running,
controller->GetAnimation(3, Animation::Transform)->run_state());
EXPECT_EQ(Animation::WaitingForTargetAvailability,
controller->GetAnimation(4, Animation::Transform)->run_state());
EXPECT_EQ(Animation::Running,
controller->GetAnimation(5, Animation::Opacity)->run_state());
controller->AbortAnimations(Animation::Transform);
EXPECT_EQ(Animation::Finished,
controller->GetAnimation(1, Animation::Transform)->run_state());
EXPECT_EQ(Animation::Finished,
controller->GetAnimation(2, Animation::Opacity)->run_state());
EXPECT_EQ(Animation::Aborted,
controller->GetAnimation(3, Animation::Transform)->run_state());
EXPECT_EQ(Animation::Aborted,
controller->GetAnimation(4, Animation::Transform)->run_state());
EXPECT_EQ(Animation::Running,
controller->GetAnimation(5, Animation::Opacity)->run_state());
}
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);
AddOpacityTransitionToController(controller.get(), 1.0, 0.f, 1.f, false);
int group_id = controller->GetAnimation(Animation::Opacity)->group();
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_TRUE(controller_impl->GetAnimation(group_id, Animation::Opacity));
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, NULL);
EXPECT_TRUE(dummy.animation_waiting_for_deletion());
EXPECT_EQ(Animation::WaitingForDeletion,
controller->GetAnimation(Animation::Opacity)->run_state());
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_FALSE(controller->GetAnimation(group_id, Animation::Opacity));
EXPECT_FALSE(controller_impl->GetAnimation(group_id, Animation::Opacity));
}
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);
AddOpacityTransitionToController(controller.get(), 1.0, 0.f, 1.f, false);
int group_id = controller->GetAnimation(Animation::Opacity)->group();
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_TRUE(controller_impl->GetAnimation(group_id, Animation::Opacity));
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 + 0.5);
controller->UpdateState(true, NULL);
EXPECT_TRUE(dummy.animation_waiting_for_deletion());
EXPECT_EQ(Animation::WaitingForDeletion,
controller->GetAnimation(Animation::Opacity)->run_state());
controller->PushAnimationUpdatesTo(controller_impl.get());
EXPECT_FALSE(controller->GetAnimation(group_id, Animation::Opacity));
EXPECT_FALSE(controller_impl->GetAnimation(group_id, Animation::Opacity));
}
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);
controller_impl->AddAnimation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeTransformTransition(2.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());
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 + 1.0);
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(0u, events->size());
EXPECT_EQ(Animation::Finished,
controller_impl->GetAnimation(1, Animation::Opacity)->run_state());
EXPECT_EQ(Animation::Running,
controller_impl->GetAnimation(1,
Animation::Transform)->run_state());
controller_impl->Animate(kInitialTickTime + 2.0);
controller_impl->UpdateState(true, events.get());
EXPECT_EQ(2u, events->size());
EXPECT_EQ(AnimationEvent::Finished, (*events)[0].type);
EXPECT_EQ(AnimationEvent::Finished, (*events)[1].type);
}
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);
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());
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 + 1.0);
controller_impl->UpdateState(true, events.get());
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));
EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale());
scoped_ptr<KeyframedTransformAnimationCurve> curve1(
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
curve1->AddKeyframe(TransformKeyframe::Create(
0.0, operations1, scoped_ptr<TimingFunction>()));
operations1.AppendTranslate(10.0, 15.0, 0.0);
curve1->AddKeyframe(TransformKeyframe::Create(
1.0, operations1, scoped_ptr<TimingFunction>()));
scoped_ptr<Animation> animation(Animation::Create(
curve1.PassAs<AnimationCurve>(), 2, 2, Animation::Transform));
controller_impl->AddAnimation(animation.Pass());
EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale());
scoped_ptr<KeyframedTransformAnimationCurve> curve2(
KeyframedTransformAnimationCurve::Create());
TransformOperations operations2;
curve2->AddKeyframe(TransformKeyframe::Create(
0.0, operations2, scoped_ptr<TimingFunction>()));
operations2.AppendScale(2.0, 3.0, 4.0);
curve2->AddKeyframe(TransformKeyframe::Create(
1.0, operations2, scoped_ptr<TimingFunction>()));
animation = Animation::Create(
curve2.PassAs<AnimationCurve>(), 3, 3, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
EXPECT_TRUE(controller_impl->HasAnimationThatAffectsScale());
controller_impl->GetAnimation(3, Animation::Transform)
->SetRunState(Animation::Finished, 0.0);
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));
EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms());
scoped_ptr<KeyframedTransformAnimationCurve> curve1(
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
curve1->AddKeyframe(TransformKeyframe::Create(
0.0, operations1, scoped_ptr<TimingFunction>()));
operations1.AppendTranslate(10.0, 15.0, 0.0);
curve1->AddKeyframe(TransformKeyframe::Create(
1.0, operations1, scoped_ptr<TimingFunction>()));
scoped_ptr<Animation> animation(Animation::Create(
curve1.PassAs<AnimationCurve>(), 2, 2, Animation::Transform));
controller_impl->AddAnimation(animation.Pass());
EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms());
scoped_ptr<KeyframedTransformAnimationCurve> curve2(
KeyframedTransformAnimationCurve::Create());
TransformOperations operations2;
curve2->AddKeyframe(TransformKeyframe::Create(
0.0, operations2, scoped_ptr<TimingFunction>()));
operations2.AppendScale(2.0, 3.0, 4.0);
curve2->AddKeyframe(TransformKeyframe::Create(
1.0, operations2, scoped_ptr<TimingFunction>()));
animation = Animation::Create(
curve2.PassAs<AnimationCurve>(), 3, 3, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
EXPECT_FALSE(controller_impl->HasOnlyTranslationTransforms());
controller_impl->GetAnimation(3, Animation::Transform)
->SetRunState(Animation::Finished, 0.0);
EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms());
}
TEST(LayerAnimationControllerTest, MaximumScale) {
scoped_refptr<LayerAnimationController> controller_impl(
LayerAnimationController::Create(0));
float max_scale = 0.f;
EXPECT_TRUE(controller_impl->MaximumScale(&max_scale));
EXPECT_EQ(0.f, max_scale);
scoped_ptr<KeyframedTransformAnimationCurve> curve1(
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
curve1->AddKeyframe(TransformKeyframe::Create(
0.0, operations1, scoped_ptr<TimingFunction>()));
operations1.AppendScale(2.0, 3.0, 4.0);
curve1->AddKeyframe(TransformKeyframe::Create(
1.0, operations1, scoped_ptr<TimingFunction>()));
scoped_ptr<Animation> animation(Animation::Create(
curve1.PassAs<AnimationCurve>(), 1, 1, Animation::Transform));
controller_impl->AddAnimation(animation.Pass());
EXPECT_TRUE(controller_impl->MaximumScale(&max_scale));
EXPECT_EQ(4.f, max_scale);
scoped_ptr<KeyframedTransformAnimationCurve> curve2(
KeyframedTransformAnimationCurve::Create());
TransformOperations operations2;
curve2->AddKeyframe(TransformKeyframe::Create(
0.0, operations2, scoped_ptr<TimingFunction>()));
operations2.AppendScale(6.0, 5.0, 4.0);
curve2->AddKeyframe(TransformKeyframe::Create(
1.0, operations2, scoped_ptr<TimingFunction>()));
animation = Animation::Create(
curve2.PassAs<AnimationCurve>(), 2, 2, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
EXPECT_TRUE(controller_impl->MaximumScale(&max_scale));
EXPECT_EQ(6.f, max_scale);
scoped_ptr<KeyframedTransformAnimationCurve> curve3(
KeyframedTransformAnimationCurve::Create());
TransformOperations operations3;
curve3->AddKeyframe(TransformKeyframe::Create(
0.0, operations3, scoped_ptr<TimingFunction>()));
operations3.AppendPerspective(6.0);
curve3->AddKeyframe(TransformKeyframe::Create(
1.0, operations3, scoped_ptr<TimingFunction>()));
animation = Animation::Create(
curve3.PassAs<AnimationCurve>(), 3, 3, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
EXPECT_FALSE(controller_impl->MaximumScale(&max_scale));
controller_impl->GetAnimation(3, Animation::Transform)
->SetRunState(Animation::Finished, 0.0);
controller_impl->GetAnimation(2, Animation::Transform)
->SetRunState(Animation::Finished, 0.0);
EXPECT_TRUE(controller_impl->MaximumScale(&max_scale));
EXPECT_EQ(4.f, max_scale);
}
}
}