Index: cc/animation/layer_animation_controller_unittest.cc |
diff --git a/cc/animation/layer_animation_controller_unittest.cc b/cc/animation/layer_animation_controller_unittest.cc |
index c3387f489709468371f55713c96f782c2a788e61..23257ad6f4a1cd3f9930d672ac14d694c442b933 100644 |
--- a/cc/animation/layer_animation_controller_unittest.cc |
+++ b/cc/animation/layer_animation_controller_unittest.cc |
@@ -1273,5 +1273,235 @@ TEST(LayerAnimationControllerTest, AnimatedBounds) { |
EXPECT_FALSE(controller_impl->AnimatedBoundsForBox(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(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(1.0); |
+ controller->UpdateState(true, NULL); |
+ controller->Animate(2.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); |
+ |
+ // Only un-finished Transform animations should have been aborted. |
+ 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()); |
+} |
+ |
+// 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); |
+ |
+ 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()); |
+ |
+ controller->Animate(1.0); |
+ controller->UpdateState(true, NULL); |
+ 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)); |
+} |
+ |
+// 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); |
+ |
+ 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()); |
+ |
+ AnimationEventsVector events; |
+ controller_impl->Animate(1.0); |
+ controller_impl->UpdateState(true, &events); |
+ 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(1.5); |
+ controller->UpdateState(true, NULL); |
+ 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)); |
+} |
+ |
+// 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); |
+ |
+ // Add two animations with the same group id but different durations. |
+ 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(1.0); |
+ 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(2.0); |
+ 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->GetAnimation(1, Animation::Opacity)->run_state()); |
+ EXPECT_EQ(Animation::Running, |
+ controller_impl->GetAnimation(1, |
+ Animation::Transform)->run_state()); |
+ |
+ controller_impl->Animate(3.0); |
+ 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(1.0); |
+ 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(2.0); |
+ 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); |
+} |
+ |
} // namespace |
} // namespace cc |