1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/compositor/layer_animation_sequence.h" 6 7 #include "base/basictypes.h" 8 #include "base/compiler_specific.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/time/time.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "ui/compositor/layer_animation_delegate.h" 13 #include "ui/compositor/layer_animation_element.h" 14 #include "ui/compositor/test/test_layer_animation_delegate.h" 15 #include "ui/compositor/test/test_layer_animation_observer.h" 16 #include "ui/compositor/test/test_utils.h" 17 #include "ui/gfx/rect.h" 18 #include "ui/gfx/transform.h" 19 20 namespace ui { 21 22 namespace { 23 24 // Check that the sequence behaves sanely when it contains no elements. 25 TEST(LayerAnimationSequenceTest, NoElement) { 26 LayerAnimationSequence sequence; 27 base::TimeTicks start_time; 28 start_time += base::TimeDelta::FromSeconds(1); 29 sequence.set_start_time(start_time); 30 EXPECT_TRUE(sequence.IsFinished(start_time)); 31 EXPECT_TRUE(sequence.properties().size() == 0); 32 LayerAnimationElement::AnimatableProperties properties; 33 EXPECT_FALSE(sequence.HasConflictingProperty(properties)); 34 } 35 36 // Check that the sequences progresses the delegate as expected when it contains 37 // a single non-threaded element. 38 TEST(LayerAnimationSequenceTest, SingleElement) { 39 LayerAnimationSequence sequence; 40 TestLayerAnimationDelegate delegate; 41 float start = 0.0f; 42 float middle = 0.5f; 43 float target = 1.0f; 44 base::TimeTicks start_time; 45 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 46 sequence.AddElement( 47 LayerAnimationElement::CreateBrightnessElement(target, delta)); 48 49 for (int i = 0; i < 2; ++i) { 50 start_time += delta; 51 sequence.set_start_time(start_time); 52 delegate.SetBrightnessFromAnimation(start); 53 sequence.Start(&delegate); 54 sequence.Progress(start_time, &delegate); 55 EXPECT_FLOAT_EQ(start, delegate.GetBrightnessForAnimation()); 56 sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(500), 57 &delegate); 58 EXPECT_FLOAT_EQ(middle, delegate.GetBrightnessForAnimation()); 59 EXPECT_TRUE(sequence.IsFinished(start_time + delta)); 60 sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(1000), 61 &delegate); 62 EXPECT_FLOAT_EQ(target, delegate.GetBrightnessForAnimation()); 63 } 64 65 EXPECT_TRUE(sequence.properties().size() == 1); 66 EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::BRIGHTNESS) != 67 sequence.properties().end()); 68 } 69 70 // Check that the sequences progresses the delegate as expected when it contains 71 // a single threaded element. 72 TEST(LayerAnimationSequenceTest, SingleThreadedElement) { 73 LayerAnimationSequence sequence; 74 TestLayerAnimationDelegate delegate; 75 float start = 0.0f; 76 float middle = 0.5f; 77 float target = 1.0f; 78 base::TimeTicks start_time; 79 base::TimeTicks effective_start; 80 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 81 sequence.AddElement( 82 LayerAnimationElement::CreateOpacityElement(target, delta)); 83 84 for (int i = 0; i < 2; ++i) { 85 int starting_group_id = 1; 86 sequence.set_animation_group_id(starting_group_id); 87 start_time = effective_start + delta; 88 sequence.set_start_time(start_time); 89 delegate.SetOpacityFromAnimation(start); 90 sequence.Start(&delegate); 91 sequence.Progress(start_time, &delegate); 92 EXPECT_FLOAT_EQ(start, sequence.last_progressed_fraction()); 93 effective_start = start_time + delta; 94 sequence.OnThreadedAnimationStarted(cc::AnimationEvent( 95 cc::AnimationEvent::Started, 96 0, 97 sequence.animation_group_id(), 98 cc::Animation::Opacity, 99 (effective_start - base::TimeTicks()).InSecondsF())); 100 sequence.Progress(effective_start + delta/2, &delegate); 101 EXPECT_FLOAT_EQ(middle, sequence.last_progressed_fraction()); 102 EXPECT_TRUE(sequence.IsFinished(effective_start + delta)); 103 sequence.Progress(effective_start + delta, &delegate); 104 EXPECT_FLOAT_EQ(target, sequence.last_progressed_fraction()); 105 EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation()); 106 } 107 108 EXPECT_TRUE(sequence.properties().size() == 1); 109 EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::OPACITY) != 110 sequence.properties().end()); 111 } 112 113 // Check that the sequences progresses the delegate as expected when it contains 114 // multiple elements. Note, see the layer animator tests for cyclic sequences. 115 TEST(LayerAnimationSequenceTest, MultipleElement) { 116 LayerAnimationSequence sequence; 117 TestLayerAnimationDelegate delegate; 118 float start_opacity = 0.0f; 119 float target_opacity = 1.0f; 120 base::TimeTicks start_time; 121 base::TimeTicks opacity_effective_start; 122 base::TimeTicks transform_effective_start; 123 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 124 sequence.AddElement( 125 LayerAnimationElement::CreateOpacityElement(target_opacity, delta)); 126 127 // Pause bounds for a second. 128 LayerAnimationElement::AnimatableProperties properties; 129 properties.insert(LayerAnimationElement::BOUNDS); 130 131 sequence.AddElement( 132 LayerAnimationElement::CreatePauseElement(properties, delta)); 133 134 gfx::Transform start_transform, target_transform, middle_transform; 135 start_transform.Rotate(-30.0); 136 target_transform.Rotate(30.0); 137 138 sequence.AddElement( 139 LayerAnimationElement::CreateTransformElement(target_transform, delta)); 140 141 for (int i = 0; i < 2; ++i) { 142 int starting_group_id = 1; 143 sequence.set_animation_group_id(starting_group_id); 144 start_time = opacity_effective_start + 4 * delta; 145 sequence.set_start_time(start_time); 146 delegate.SetOpacityFromAnimation(start_opacity); 147 delegate.SetTransformFromAnimation(start_transform); 148 149 sequence.Start(&delegate); 150 sequence.Progress(start_time, &delegate); 151 EXPECT_FLOAT_EQ(0.0, sequence.last_progressed_fraction()); 152 opacity_effective_start = start_time + delta; 153 EXPECT_EQ(starting_group_id, sequence.animation_group_id()); 154 sequence.OnThreadedAnimationStarted(cc::AnimationEvent( 155 cc::AnimationEvent::Started, 156 0, 157 sequence.animation_group_id(), 158 cc::Animation::Opacity, 159 (opacity_effective_start - base::TimeTicks()).InSecondsF())); 160 sequence.Progress(opacity_effective_start + delta/2, &delegate); 161 EXPECT_FLOAT_EQ(0.5, sequence.last_progressed_fraction()); 162 sequence.Progress(opacity_effective_start + delta, &delegate); 163 EXPECT_FLOAT_EQ(target_opacity, delegate.GetOpacityForAnimation()); 164 165 // Now at the start of the pause. 166 EXPECT_FLOAT_EQ(0.0, sequence.last_progressed_fraction()); 167 TestLayerAnimationDelegate copy = delegate; 168 169 // In the middle of the pause -- nothing should have changed. 170 sequence.Progress(opacity_effective_start + delta + delta/2, 171 &delegate); 172 CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), 173 copy.GetBoundsForAnimation()); 174 CheckApproximatelyEqual(delegate.GetTransformForAnimation(), 175 copy.GetTransformForAnimation()); 176 EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), 177 copy.GetOpacityForAnimation()); 178 179 sequence.Progress(opacity_effective_start + 2 * delta, &delegate); 180 CheckApproximatelyEqual(start_transform, 181 delegate.GetTransformForAnimation()); 182 EXPECT_FLOAT_EQ(0.0, sequence.last_progressed_fraction()); 183 transform_effective_start = opacity_effective_start + 3 * delta; 184 EXPECT_NE(starting_group_id, sequence.animation_group_id()); 185 sequence.OnThreadedAnimationStarted(cc::AnimationEvent( 186 cc::AnimationEvent::Started, 187 0, 188 sequence.animation_group_id(), 189 cc::Animation::Transform, 190 (transform_effective_start - base::TimeTicks()).InSecondsF())); 191 sequence.Progress(transform_effective_start + delta/2, &delegate); 192 EXPECT_FLOAT_EQ(0.5, sequence.last_progressed_fraction()); 193 EXPECT_TRUE(sequence.IsFinished(transform_effective_start + delta)); 194 sequence.Progress(transform_effective_start + delta, &delegate); 195 CheckApproximatelyEqual(target_transform, 196 delegate.GetTransformForAnimation()); 197 } 198 199 EXPECT_TRUE(sequence.properties().size() == 3); 200 EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::OPACITY) != 201 sequence.properties().end()); 202 EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::TRANSFORM) != 203 sequence.properties().end()); 204 EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::BOUNDS) != 205 sequence.properties().end()); 206 } 207 208 // Check that a sequence can still be aborted if it has cycled many times. 209 TEST(LayerAnimationSequenceTest, AbortingCyclicSequence) { 210 LayerAnimationSequence sequence; 211 TestLayerAnimationDelegate delegate; 212 float start_brightness = 0.0f; 213 float target_brightness = 1.0f; 214 base::TimeTicks start_time; 215 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 216 sequence.AddElement( 217 LayerAnimationElement::CreateBrightnessElement(target_brightness, delta)); 218 219 sequence.AddElement( 220 LayerAnimationElement::CreateBrightnessElement(start_brightness, delta)); 221 222 sequence.set_is_cyclic(true); 223 224 delegate.SetBrightnessFromAnimation(start_brightness); 225 226 start_time += delta; 227 sequence.set_start_time(start_time); 228 sequence.Start(&delegate); 229 sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(101000), 230 &delegate); 231 EXPECT_FLOAT_EQ(target_brightness, delegate.GetBrightnessForAnimation()); 232 sequence.Abort(&delegate); 233 234 // Should be able to reuse the sequence after aborting. 235 delegate.SetBrightnessFromAnimation(start_brightness); 236 start_time += base::TimeDelta::FromMilliseconds(101000); 237 sequence.set_start_time(start_time); 238 sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(100000), 239 &delegate); 240 EXPECT_FLOAT_EQ(start_brightness, delegate.GetBrightnessForAnimation()); 241 } 242 243 // Check that a sequence can be 'fast-forwarded' to the end and the target set. 244 // Also check that this has no effect if the sequence is cyclic. 245 TEST(LayerAnimationSequenceTest, SetTarget) { 246 LayerAnimationSequence sequence; 247 TestLayerAnimationDelegate delegate; 248 float start_opacity = 0.0f; 249 float target_opacity = 1.0f; 250 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 251 sequence.AddElement( 252 LayerAnimationElement::CreateOpacityElement(target_opacity, delta)); 253 254 LayerAnimationElement::TargetValue target_value(&delegate); 255 target_value.opacity = start_opacity; 256 sequence.GetTargetValue(&target_value); 257 EXPECT_FLOAT_EQ(target_opacity, target_value.opacity); 258 259 sequence.set_is_cyclic(true); 260 target_value.opacity = start_opacity; 261 sequence.GetTargetValue(&target_value); 262 EXPECT_FLOAT_EQ(start_opacity, target_value.opacity); 263 } 264 265 TEST(LayerAnimationSequenceTest, AddObserver) { 266 base::TimeTicks start_time; 267 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 268 LayerAnimationSequence sequence; 269 sequence.AddElement( 270 LayerAnimationElement::CreateBrightnessElement(1.0f, delta)); 271 for (int i = 0; i < 2; ++i) { 272 start_time += delta; 273 sequence.set_start_time(start_time); 274 TestLayerAnimationObserver observer; 275 TestLayerAnimationDelegate delegate; 276 sequence.AddObserver(&observer); 277 EXPECT_TRUE(!observer.last_ended_sequence()); 278 sequence.Progress(start_time + delta, &delegate); 279 EXPECT_EQ(observer.last_ended_sequence(), &sequence); 280 sequence.RemoveObserver(&observer); 281 } 282 } 283 284 } // namespace 285 286 } // namespace ui 287