Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(342)

Unified Diff: ui/gfx/compositor/layer_animation_unittest.cc

Issue 8247009: Explicit animation support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added new preemption strategy: replace queued animations. Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698