| 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..b23e16093e0b09b79262f3da188609bc9b437062 100644
 | 
| --- a/cc/animation/layer_animation_controller_unittest.cc
 | 
| +++ b/cc/animation/layer_animation_controller_unittest.cc
 | 
| @@ -1273,5 +1273,141 @@ 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));
 | 
| +}
 | 
| +
 | 
|  }  // namespace
 | 
|  }  // namespace cc
 | 
| 
 |