Index: ui/gfx/compositor/layer_animation_unittest.cc |
diff --git a/ui/gfx/compositor/layer_animation_unittest.cc b/ui/gfx/compositor/layer_animation_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3af8f7d6c3ae2dc9b2d0dcd82c4824b26a51143d |
--- /dev/null |
+++ b/ui/gfx/compositor/layer_animation_unittest.cc |
@@ -0,0 +1,859 @@ |
+// Copyright (c) 2011 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 "base/basictypes.h" |
+#include "base/compiler_specific.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/time.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "ui/gfx/rect.h" |
+#include "ui/gfx/transform.h" |
+#include "ui/gfx/compositor/layer_animation_delegate.h" |
+#include "ui/gfx/compositor/layer_animation_element.h" |
+#include "ui/gfx/compositor/layer_animation_sequence.h" |
+#include "ui/gfx/compositor/layer_animator.h" |
+ |
+namespace ui { |
+ |
+namespace { |
+ |
+void CheckApproximatelyEqual(const Transform& lhs, |
+ const Transform& rhs) { |
+ for (int i = 0; i < 4; ++i) { |
+ for (int j = 0; j < 4; ++j) { |
+ EXPECT_FLOAT_EQ(lhs.matrix().get(i, j), rhs.matrix().get(i, j)); |
+ } |
+ } |
+} |
+ |
+void CheckApproximatelyEqual(const gfx::Rect& lhs, |
+ const gfx::Rect& rhs) { |
+ EXPECT_FLOAT_EQ(lhs.x(), rhs.x()); |
+ EXPECT_FLOAT_EQ(lhs.y(), rhs.y()); |
+ EXPECT_FLOAT_EQ(lhs.width(), rhs.width()); |
+ EXPECT_FLOAT_EQ(lhs.height(), rhs.height()); |
+} |
+ |
+class DummyLayerAnimationDelegate : public LayerAnimationDelegate { |
+ public: |
+ DummyLayerAnimationDelegate() : opacity_(1.0f) { |
+ } |
+ |
+ virtual void SetBoundsFromAnimation(const gfx::Rect& bounds) OVERRIDE { |
+ bounds_ = bounds; |
+ } |
+ virtual void SetTransformFromAnimation(const Transform& transform) OVERRIDE { |
+ transform_ = transform; |
+ } |
+ virtual void SetOpacityFromAnimation(float opacity) OVERRIDE { |
+ opacity_ = opacity; |
+ } |
+ virtual void ScheduleDrawForAnimation() OVERRIDE { |
+ } |
+ virtual const gfx::Rect& GetBoundsForAnimation() const OVERRIDE { |
+ return bounds_; |
+ } |
+ virtual const Transform& GetTransformForAnimation() const OVERRIDE { |
+ return transform_; |
+ } |
+ virtual const float GetOpacityForAnimation() const OVERRIDE { |
+ return opacity_; |
+ } |
+ |
+ private: |
+ gfx::Rect bounds_; |
+ Transform transform_; |
+ float opacity_; |
+}; |
+ |
+TEST(LayerAnimationElementTest, TransformElement) { |
sky
2011/10/19 00:06:33
It's better form to create _unittest for each of t
|
+ DummyLayerAnimationDelegate delegate; |
+ Transform start_transform, target_transform, middle_transform; |
+ start_transform.SetRotate(-90); |
+ target_transform.SetRotate(90); |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ scoped_ptr<LayerAnimationElement> element( |
+ LayerAnimationElement::CreateTransformElement(target_transform, delta)); |
+ |
+ for (int i = 0; i < 2; ++i) { |
+ delegate.SetTransformFromAnimation(start_transform); |
+ element->Progress(0.0, &delegate); |
+ CheckApproximatelyEqual(start_transform, |
+ delegate.GetTransformForAnimation()); |
+ element->Progress(0.5, &delegate); |
+ CheckApproximatelyEqual(middle_transform, |
+ delegate.GetTransformForAnimation()); |
+ element->Progress(1.0, &delegate); |
+ CheckApproximatelyEqual(target_transform, |
+ delegate.GetTransformForAnimation()); |
+ } |
+ |
+ EXPECT_EQ(delta, element->Duration()); |
+} |
+ |
+TEST(LayerAnimationElementTest, BoundsElement) { |
sky
2011/10/19 00:06:33
Add descriptions for each of your tests.
|
+ DummyLayerAnimationDelegate delegate; |
+ gfx::Rect start, target, middle; |
+ start = target = middle = gfx::Rect(0, 0, 50, 50); |
+ start.set_x(-90); |
+ target.set_x(90); |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ scoped_ptr<LayerAnimationElement> element( |
+ LayerAnimationElement::CreateBoundsElement(target, delta)); |
+ |
+ for (int i = 0; i < 2; ++i) { |
+ delegate.SetBoundsFromAnimation(start); |
+ element->Progress(0.0, &delegate); |
+ CheckApproximatelyEqual(start, delegate.GetBoundsForAnimation()); |
+ element->Progress(0.5, &delegate); |
+ CheckApproximatelyEqual(middle, delegate.GetBoundsForAnimation()); |
+ element->Progress(1.0, &delegate); |
+ CheckApproximatelyEqual(target, delegate.GetBoundsForAnimation()); |
+ } |
+ |
+ EXPECT_EQ(delta, element->Duration()); |
+} |
+ |
+TEST(LayerAnimationElementTest, OpacityElement) { |
+ DummyLayerAnimationDelegate delegate; |
+ float start = 0.0; |
+ float middle = 0.5; |
+ float target = 1.0; |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ scoped_ptr<LayerAnimationElement> element( |
+ LayerAnimationElement::CreateOpacityElement(target, delta)); |
+ |
+ for (int i = 0; i < 2; ++i) { |
+ delegate.SetOpacityFromAnimation(start); |
+ element->Progress(0.0, &delegate); |
+ EXPECT_FLOAT_EQ(start, delegate.GetOpacityForAnimation()); |
+ element->Progress(0.5, &delegate); |
+ EXPECT_FLOAT_EQ(middle, delegate.GetOpacityForAnimation()); |
+ element->Progress(1.0, &delegate); |
+ EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation()); |
+ } |
+ |
+ EXPECT_EQ(delta, element->Duration()); |
+} |
+ |
+TEST(LayerAnimationElementTest, PauseElement) { |
+ LayerAnimationElement::AnimatableProperties properties; |
+ properties.insert(LayerAnimationElement::TRANSFORM); |
+ properties.insert(LayerAnimationElement::BOUNDS); |
+ properties.insert(LayerAnimationElement::OPACITY); |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ scoped_ptr<LayerAnimationElement> element( |
+ LayerAnimationElement::CreatePauseElement(properties, delta)); |
+ |
+ DummyLayerAnimationDelegate delegate; |
+ DummyLayerAnimationDelegate copy = delegate; |
+ |
+ element->Progress(1.0, &delegate); |
+ |
+ // Nothing should have changed. |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), |
+ copy.GetBoundsForAnimation()); |
+ CheckApproximatelyEqual(delegate.GetTransformForAnimation(), |
+ copy.GetTransformForAnimation()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), |
+ copy.GetOpacityForAnimation()); |
+ |
+ // Pause should last for |delta|. |
+ EXPECT_EQ(delta, element->Duration()); |
+} |
+ |
+TEST(LayerAnimationSequenceTest, NoElement) { |
+ LayerAnimationSequence sequence; |
+ EXPECT_EQ(sequence.duration(), base::TimeDelta()); |
+ EXPECT_TRUE(sequence.properties().size() == 0); |
+ LayerAnimationElement::AnimatableProperties properties; |
+ EXPECT_FALSE(sequence.HasCommonProperty(properties)); |
+} |
+ |
+TEST(LayerAnimationSequenceTest, SingleElement) { |
+ LayerAnimationSequence sequence; |
+ DummyLayerAnimationDelegate delegate; |
+ float start = 0.0; |
+ float middle = 0.5; |
+ float target = 1.0; |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ sequence.AddElement( |
+ LayerAnimationElement::CreateOpacityElement(target, delta)); |
+ |
+ for (int i = 0; i < 2; ++i) { |
+ delegate.SetOpacityFromAnimation(start); |
+ sequence.Progress(base::TimeDelta::FromMilliseconds(0), &delegate); |
+ EXPECT_FLOAT_EQ(start, delegate.GetOpacityForAnimation()); |
+ sequence.Progress(base::TimeDelta::FromMilliseconds(500), &delegate); |
+ EXPECT_FLOAT_EQ(middle, delegate.GetOpacityForAnimation()); |
+ sequence.Progress(base::TimeDelta::FromMilliseconds(1000), &delegate); |
+ EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation()); |
+ } |
+ |
+ EXPECT_TRUE(sequence.properties().size() == 1); |
+ EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::OPACITY) != |
+ sequence.properties().end()); |
+ EXPECT_EQ(delta, sequence.duration()); |
+} |
+ |
+TEST(LayerAnimationSequenceTest, MultipleElement) { |
+ LayerAnimationSequence sequence; |
+ DummyLayerAnimationDelegate delegate; |
+ float start_opacity = 0.0; |
+ float middle_opacity = 0.5; |
+ float target_opacity = 1.0; |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ sequence.AddElement( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta)); |
+ |
+ // Pause bounds for a second. |
+ LayerAnimationElement::AnimatableProperties properties; |
+ properties.insert(LayerAnimationElement::BOUNDS); |
+ |
+ sequence.AddElement( |
+ LayerAnimationElement::CreatePauseElement(properties, delta)); |
+ |
+ Transform start_transform, target_transform, middle_transform; |
+ start_transform.SetRotate(-90); |
+ target_transform.SetRotate(90); |
+ |
+ sequence.AddElement( |
+ LayerAnimationElement::CreateTransformElement(target_transform, delta)); |
+ |
+ for (int i = 0; i < 2; ++i) { |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ delegate.SetTransformFromAnimation(start_transform); |
+ |
+ sequence.Progress(base::TimeDelta::FromMilliseconds(0), &delegate); |
+ EXPECT_FLOAT_EQ(start_opacity, delegate.GetOpacityForAnimation()); |
+ sequence.Progress(base::TimeDelta::FromMilliseconds(500), &delegate); |
+ EXPECT_FLOAT_EQ(middle_opacity, delegate.GetOpacityForAnimation()); |
+ sequence.Progress(base::TimeDelta::FromMilliseconds(1000), &delegate); |
+ EXPECT_FLOAT_EQ(target_opacity, delegate.GetOpacityForAnimation()); |
+ DummyLayerAnimationDelegate copy = delegate; |
+ |
+ // In the middle of the pause -- nothing should have changed. |
+ sequence.Progress(base::TimeDelta::FromMilliseconds(1500), &delegate); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), |
+ copy.GetBoundsForAnimation()); |
+ CheckApproximatelyEqual(delegate.GetTransformForAnimation(), |
+ copy.GetTransformForAnimation()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), |
+ copy.GetOpacityForAnimation()); |
+ |
+ |
+ sequence.Progress(base::TimeDelta::FromMilliseconds(2000), &delegate); |
+ CheckApproximatelyEqual(start_transform, |
+ delegate.GetTransformForAnimation()); |
+ sequence.Progress(base::TimeDelta::FromMilliseconds(2500), &delegate); |
+ CheckApproximatelyEqual(middle_transform, |
+ delegate.GetTransformForAnimation()); |
+ sequence.Progress(base::TimeDelta::FromMilliseconds(3000), &delegate); |
+ CheckApproximatelyEqual(target_transform, |
+ delegate.GetTransformForAnimation()); |
+ } |
+ |
+ EXPECT_TRUE(sequence.properties().size() == 3); |
+ EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::OPACITY) != |
+ sequence.properties().end()); |
+ EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::TRANSFORM) != |
+ sequence.properties().end()); |
+ EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::BOUNDS) != |
+ sequence.properties().end()); |
+ EXPECT_EQ(delta + delta + delta, sequence.duration()); |
+} |
+ |
+TEST(LayerAnimatorTest, ImplicitAnimation) { |
+ scoped_ptr<LayerAnimator> animator( |
+ LayerAnimator::CreateImplicitAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ animator->SetOpacity(0.5); |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ animator->Step(now + base::TimeDelta::FromSeconds(1)); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), 0.5); |
+} |
+ |
+TEST(LayerAnimatorTest, NoImplicitAnimation) { |
+ scoped_ptr<LayerAnimator> animator( |
+ LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ animator->SetOpacity(0.5); |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), 0.5); |
+} |
+ |
+TEST(LayerAnimatorTest, StopAnimatingProperty) { |
+ scoped_ptr<LayerAnimator> animator( |
+ LayerAnimator::CreateImplicitAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ double target_opacity(0.5); |
+ gfx::Rect target_bounds(0, 0, 50, 50); |
+ animator->SetOpacity(target_opacity); |
+ animator->SetBounds(target_bounds); |
+ animator->StopAnimatingProperty(LayerAnimationElement::OPACITY); |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), 0.5); |
+ animator->StopAnimatingProperty(LayerAnimationElement::BOUNDS); |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), target_bounds); |
+} |
+ |
+TEST(LayerAnimatorTest, StopAnimating) { |
+ scoped_ptr<LayerAnimator> animator( |
+ LayerAnimator::CreateImplicitAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ double target_opacity(0.5); |
+ gfx::Rect target_bounds(0, 0, 50, 50); |
+ animator->SetOpacity(target_opacity); |
+ animator->SetBounds(target_bounds); |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ animator->StopAnimating(); |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), 0.5); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), target_bounds); |
+} |
+ |
+// schedule animation (that can run immediately) |
+TEST(LayerAnimatorTest, ScheduleAnimationThatCanRunImmediately) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double middle_opacity(0.5); |
+ double target_opacity(1.0); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ |
+ animator->ScheduleAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ |
+ base::TimeTicks start_time = animator->get_last_step_time_for_test(); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(500)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000)); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity); |
+} |
+ |
+// schedule two animations on separate properties |
+TEST(LayerAnimatorTest, ScheduleTwoAnimationsThatCanRunImmediately) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double middle_opacity(0.5); |
+ double target_opacity(1.0); |
+ |
+ gfx::Rect start_bounds, target_bounds, middle_bounds; |
+ start_bounds = target_bounds = middle_bounds = gfx::Rect(0, 0, 50, 50); |
+ start_bounds.set_x(-90); |
+ target_bounds.set_x(90); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ delegate.SetBoundsFromAnimation(start_bounds); |
+ |
+ animator->ScheduleAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ animator->ScheduleAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateBoundsElement(target_bounds, delta))); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds); |
+ |
+ base::TimeTicks start_time = animator->get_last_step_time_for_test(); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(500)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), middle_bounds); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000)); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), target_bounds); |
+} |
+ |
+// schedule two animations on the same property |
+TEST(LayerAnimatorTest, ScheduleTwoAnimationsOnSameProperty) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double middle_opacity(0.5); |
+ double target_opacity(1.0); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ |
+ animator->ScheduleAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ animator->ScheduleAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta))); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ |
+ base::TimeTicks start_time = animator->get_last_step_time_for_test(); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(500)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1500)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(2000)); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+} |
+ |
+// schedule {o}, {o,b}, {b} and ensure that {b} doesn't run right away. |
+TEST(LayerAnimatorTest, ScheduleBlockedAnimation) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double middle_opacity(0.5); |
+ double target_opacity(1.0); |
+ |
+ gfx::Rect start_bounds, target_bounds, middle_bounds; |
+ start_bounds = target_bounds = middle_bounds = gfx::Rect(0, 0, 50, 50); |
+ start_bounds.set_x(-90); |
+ target_bounds.set_x(90); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ delegate.SetBoundsFromAnimation(start_bounds); |
+ |
+ animator->ScheduleAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ scoped_ptr<LayerAnimationSequence> bounds_and_opacity( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta))); |
+ |
+ bounds_and_opacity->AddElement( |
+ LayerAnimationElement::CreateBoundsElement(target_bounds, delta)); |
+ |
+ animator->ScheduleAnimation(bounds_and_opacity.release()); |
+ |
+ animator->ScheduleAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateBoundsElement(start_bounds, delta))); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds); |
+ |
+ base::TimeTicks start_time = animator->get_last_step_time_for_test(); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(500)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(2000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(3000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), target_bounds); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(4000)); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds); |
+} |
+ |
+// schedule {o} and then schedule {o} and {b} together |
+TEST(LayerAnimatorTest, ScheduleTogether) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double target_opacity(1.0); |
+ |
+ gfx::Rect start_bounds, target_bounds, middle_bounds; |
+ start_bounds = target_bounds = gfx::Rect(0, 0, 50, 50); |
+ start_bounds.set_x(-90); |
+ target_bounds.set_x(90); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ delegate.SetBoundsFromAnimation(start_bounds); |
+ |
+ animator->ScheduleAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ std::vector<LayerAnimationSequence*> sequences; |
+ sequences.push_back(new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta))); |
+ sequences.push_back(new LayerAnimationSequence( |
+ LayerAnimationElement::CreateBoundsElement(target_bounds, delta))); |
+ |
+ animator->ScheduleTogether(sequences); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds); |
+ |
+ base::TimeTicks start_time = animator->get_last_step_time_for_test(); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(2000)); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), target_bounds); |
+} |
+ |
+// start animation (that can run immediately) |
+TEST(LayerAnimatorTest, StartAnimationThatCanRunImmediately) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double middle_opacity(0.5); |
+ double target_opacity(1.0); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ |
+ base::TimeTicks start_time = animator->get_last_step_time_for_test(); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(500)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000)); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity); |
+} |
+ |
+// preempt by immediately setting new target |
+TEST(LayerAnimatorTest, PreemptBySettingNewTarget) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double target_opacity(1.0); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ |
+ animator->set_preemption_strategy(LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); |
+ |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta))); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+} |
+ |
+// preempt by animating to new target |
+TEST(LayerAnimatorTest, PreemptByImmediatelyAnimatingToNewTarget) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double middle_opacity(0.5); |
+ double target_opacity(1.0); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ |
+ animator->set_preemption_strategy( |
+ LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
+ |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ base::TimeTicks start_time = animator->get_last_step_time_for_test(); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(500)); |
+ |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta))); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta))); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), |
+ 0.5 * (start_opacity + middle_opacity)); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1500)); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+} |
+ |
+// preempt by enqueuing the new animation |
+TEST(LayerAnimatorTest, PreemptEnqueueNewAnimation) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double middle_opacity(0.5); |
+ double target_opacity(1.0); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ |
+ animator->set_preemption_strategy(LayerAnimator::ENQUEUE_NEW_ANIMATION); |
+ |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ base::TimeTicks start_time = animator->get_last_step_time_for_test(); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(500)); |
+ |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta))); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1500)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(2000)); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+} |
+ |
+// Start an animation when there are sequences waiting in the queue. In this |
+// case, all pending and running animations should be finished, and the new |
+// animation started. |
+TEST(LayerAnimatorTest, PreemptyByReplacingQueuedAnimations) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double middle_opacity(0.5); |
+ double target_opacity(1.0); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ |
+ animator->set_preemption_strategy(LayerAnimator::REPLACE_QUEUED_ANIMATIONS); |
+ |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ base::TimeTicks start_time = animator->get_last_step_time_for_test(); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(500)); |
+ |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(middle_opacity, delta))); |
+ |
+ // Queue should now have two animations. Starting a third should replace the |
+ // second. |
+ animator->StartAnimation( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta))); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1500)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(2000)); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+} |
+ |
+// cyclic sequence |
+TEST(LayerAnimatorTest, CyclicSequences) { |
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); |
+ animator->SetAnimationForTest(NULL); |
+ DummyLayerAnimationDelegate delegate; |
+ animator->SetDelegate(&delegate); |
+ |
+ double start_opacity(0.0); |
+ double target_opacity(1.0); |
+ |
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1); |
+ |
+ delegate.SetOpacityFromAnimation(start_opacity); |
+ |
+ scoped_ptr<LayerAnimationSequence> sequence( |
+ new LayerAnimationSequence( |
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta))); |
+ |
+ sequence->AddElement( |
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta)); |
+ |
+ sequence->set_is_cyclic(true); |
+ |
+ animator->StartAnimation(sequence.release()); |
+ |
+ base::TimeTicks start_time = animator->get_last_step_time_for_test(); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(2000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity); |
+ |
+ animator->Step(start_time + base::TimeDelta::FromMilliseconds(3000)); |
+ |
+ EXPECT_TRUE(animator->IsAnimating()); |
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity); |
+ |
+ animator->StopAnimatingProperty(LayerAnimationElement::OPACITY); |
+ |
+ EXPECT_FALSE(animator->IsAnimating()); |
+} |
+ |
+} // namespace |
+ |
+} // namespace ui |