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.
5 #include "ui/compositor/layer_animation_element.h"
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/time.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/compositor/layer_animation_delegate.h"
13 #include "ui/compositor/test/test_layer_animation_delegate.h"
14 #include "ui/compositor/test/test_utils.h"
15 #include "ui/gfx/rect.h"
16 #include "ui/gfx/transform.h"
22 // Check that the transformation element progresses the delegate as expected and
23 // that the element can be reused after it completes.
24 TEST(LayerAnimationElementTest
, TransformElement
) {
25 TestLayerAnimationDelegate delegate
;
26 gfx::Transform start_transform
, target_transform
, middle_transform
;
27 start_transform
.Rotate(-30.0);
28 target_transform
.Rotate(30.0);
29 base::TimeTicks start_time
;
30 base::TimeTicks effective_start_time
;
31 base::TimeDelta delta
= base::TimeDelta::FromSeconds(1);
33 scoped_ptr
<LayerAnimationElement
> element(
34 LayerAnimationElement::CreateTransformElement(target_transform
, delta
));
35 element
->set_animation_group_id(1);
37 for (int i
= 0; i
< 2; ++i
) {
38 start_time
= effective_start_time
+ delta
;
39 element
->set_requested_start_time(start_time
);
40 delegate
.SetTransformFromAnimation(start_transform
);
41 element
->Start(&delegate
, 1);
42 element
->Progress(start_time
, &delegate
);
43 CheckApproximatelyEqual(start_transform
,
44 delegate
.GetTransformForAnimation());
45 effective_start_time
= start_time
+ delta
;
46 element
->set_effective_start_time(effective_start_time
);
47 element
->Progress(effective_start_time
, &delegate
);
48 EXPECT_FLOAT_EQ(0.0, element
->last_progressed_fraction());
49 element
->Progress(effective_start_time
+ delta
/2, &delegate
);
50 EXPECT_FLOAT_EQ(0.5, element
->last_progressed_fraction());
52 base::TimeDelta element_duration
;
53 EXPECT_TRUE(element
->IsFinished(effective_start_time
+ delta
,
55 EXPECT_EQ(2 * delta
, element_duration
);
57 element
->Progress(effective_start_time
+ delta
, &delegate
);
58 EXPECT_FLOAT_EQ(1.0, element
->last_progressed_fraction());
59 CheckApproximatelyEqual(target_transform
,
60 delegate
.GetTransformForAnimation());
63 LayerAnimationElement::TargetValue
target_value(&delegate
);
64 element
->GetTargetValue(&target_value
);
65 CheckApproximatelyEqual(target_transform
, target_value
.transform
);
68 // Check that the bounds element progresses the delegate as expected and
69 // that the element can be reused after it completes.
70 TEST(LayerAnimationElementTest
, BoundsElement
) {
71 TestLayerAnimationDelegate delegate
;
72 gfx::Rect start
, target
, middle
;
73 start
= target
= middle
= gfx::Rect(0, 0, 50, 50);
76 base::TimeTicks start_time
;
77 base::TimeDelta delta
= base::TimeDelta::FromSeconds(1);
79 scoped_ptr
<LayerAnimationElement
> element(
80 LayerAnimationElement::CreateBoundsElement(target
, delta
));
82 for (int i
= 0; i
< 2; ++i
) {
84 element
->set_requested_start_time(start_time
);
85 delegate
.SetBoundsFromAnimation(start
);
86 element
->Start(&delegate
, 1);
87 element
->Progress(start_time
, &delegate
);
88 CheckApproximatelyEqual(start
, delegate
.GetBoundsForAnimation());
89 element
->Progress(start_time
+ delta
/2, &delegate
);
90 CheckApproximatelyEqual(middle
, delegate
.GetBoundsForAnimation());
92 base::TimeDelta element_duration
;
93 EXPECT_TRUE(element
->IsFinished(start_time
+ delta
, &element_duration
));
94 EXPECT_EQ(delta
, element_duration
);
96 element
->Progress(start_time
+ delta
, &delegate
);
97 CheckApproximatelyEqual(target
, delegate
.GetBoundsForAnimation());
100 LayerAnimationElement::TargetValue
target_value(&delegate
);
101 element
->GetTargetValue(&target_value
);
102 CheckApproximatelyEqual(target
, target_value
.bounds
);
105 // Check that the opacity element progresses the delegate as expected and
106 // that the element can be reused after it completes.
107 TEST(LayerAnimationElementTest
, OpacityElement
) {
108 TestLayerAnimationDelegate delegate
;
112 base::TimeTicks start_time
;
113 base::TimeTicks effective_start_time
;
114 base::TimeDelta delta
= base::TimeDelta::FromSeconds(1);
115 scoped_ptr
<LayerAnimationElement
> element(
116 LayerAnimationElement::CreateOpacityElement(target
, delta
));
118 for (int i
= 0; i
< 2; ++i
) {
119 start_time
= effective_start_time
+ delta
;
120 element
->set_requested_start_time(start_time
);
121 delegate
.SetOpacityFromAnimation(start
);
122 element
->Start(&delegate
, 1);
123 element
->Progress(start_time
, &delegate
);
124 EXPECT_FLOAT_EQ(start
, element
->last_progressed_fraction());
125 effective_start_time
= start_time
+ delta
;
126 element
->set_effective_start_time(effective_start_time
);
127 element
->Progress(effective_start_time
, &delegate
);
128 EXPECT_FLOAT_EQ(start
, element
->last_progressed_fraction());
129 element
->Progress(effective_start_time
+ delta
/2, &delegate
);
130 EXPECT_FLOAT_EQ(middle
, element
->last_progressed_fraction());
132 base::TimeDelta element_duration
;
133 EXPECT_TRUE(element
->IsFinished(effective_start_time
+ delta
,
135 EXPECT_EQ(2 * delta
, element_duration
);
137 element
->Progress(effective_start_time
+ delta
, &delegate
);
138 EXPECT_FLOAT_EQ(target
, element
->last_progressed_fraction());
139 EXPECT_FLOAT_EQ(target
, delegate
.GetOpacityForAnimation());
142 LayerAnimationElement::TargetValue
target_value(&delegate
);
143 element
->GetTargetValue(&target_value
);
144 EXPECT_FLOAT_EQ(target
, target_value
.opacity
);
147 // Check that the visibility element progresses the delegate as expected and
148 // that the element can be reused after it completes.
149 TEST(LayerAnimationElementTest
, VisibilityElement
) {
150 TestLayerAnimationDelegate delegate
;
153 base::TimeTicks start_time
;
154 base::TimeDelta delta
= base::TimeDelta::FromSeconds(1);
155 scoped_ptr
<LayerAnimationElement
> element(
156 LayerAnimationElement::CreateVisibilityElement(target
, delta
));
158 for (int i
= 0; i
< 2; ++i
) {
160 element
->set_requested_start_time(start_time
);
161 delegate
.SetVisibilityFromAnimation(start
);
162 element
->Start(&delegate
, 1);
163 element
->Progress(start_time
, &delegate
);
164 EXPECT_TRUE(delegate
.GetVisibilityForAnimation());
165 element
->Progress(start_time
+ delta
/2, &delegate
);
166 EXPECT_TRUE(delegate
.GetVisibilityForAnimation());
168 base::TimeDelta element_duration
;
169 EXPECT_TRUE(element
->IsFinished(start_time
+ delta
, &element_duration
));
170 EXPECT_EQ(delta
, element_duration
);
172 element
->Progress(start_time
+ delta
, &delegate
);
173 EXPECT_FALSE(delegate
.GetVisibilityForAnimation());
176 LayerAnimationElement::TargetValue
target_value(&delegate
);
177 element
->GetTargetValue(&target_value
);
178 EXPECT_FALSE(target_value
.visibility
);
181 // Check that the Brightness element progresses the delegate as expected and
182 // that the element can be reused after it completes.
183 TEST(LayerAnimationElementTest
, BrightnessElement
) {
184 TestLayerAnimationDelegate delegate
;
188 base::TimeTicks start_time
;
189 base::TimeDelta delta
= base::TimeDelta::FromSeconds(1);
190 scoped_ptr
<LayerAnimationElement
> element(
191 LayerAnimationElement::CreateBrightnessElement(target
, delta
));
193 for (int i
= 0; i
< 2; ++i
) {
195 element
->set_requested_start_time(start_time
);
196 delegate
.SetBrightnessFromAnimation(start
);
197 element
->Start(&delegate
, 1);
198 element
->Progress(start_time
, &delegate
);
199 EXPECT_FLOAT_EQ(start
, delegate
.GetBrightnessForAnimation());
200 element
->Progress(start_time
+ delta
/2, &delegate
);
201 EXPECT_FLOAT_EQ(middle
, delegate
.GetBrightnessForAnimation());
203 base::TimeDelta element_duration
;
204 EXPECT_TRUE(element
->IsFinished(start_time
+ delta
, &element_duration
));
205 EXPECT_EQ(delta
, element_duration
);
207 element
->Progress(start_time
+ delta
, &delegate
);
208 EXPECT_FLOAT_EQ(target
, delegate
.GetBrightnessForAnimation());
211 LayerAnimationElement::TargetValue
target_value(&delegate
);
212 element
->GetTargetValue(&target_value
);
213 EXPECT_FLOAT_EQ(target
, target_value
.brightness
);
216 // Check that the Grayscale element progresses the delegate as expected and
217 // that the element can be reused after it completes.
218 TEST(LayerAnimationElementTest
, GrayscaleElement
) {
219 TestLayerAnimationDelegate delegate
;
223 base::TimeTicks start_time
;
224 base::TimeDelta delta
= base::TimeDelta::FromSeconds(1);
225 scoped_ptr
<LayerAnimationElement
> element(
226 LayerAnimationElement::CreateGrayscaleElement(target
, delta
));
228 for (int i
= 0; i
< 2; ++i
) {
230 element
->set_requested_start_time(start_time
);
231 delegate
.SetGrayscaleFromAnimation(start
);
232 element
->Start(&delegate
, 1);
233 element
->Progress(start_time
, &delegate
);
234 EXPECT_FLOAT_EQ(start
, delegate
.GetGrayscaleForAnimation());
235 element
->Progress(start_time
+ delta
/2, &delegate
);
236 EXPECT_FLOAT_EQ(middle
, delegate
.GetGrayscaleForAnimation());
238 base::TimeDelta element_duration
;
239 EXPECT_TRUE(element
->IsFinished(start_time
+ delta
, &element_duration
));
240 EXPECT_EQ(delta
, element_duration
);
242 element
->Progress(start_time
+ delta
, &delegate
);
243 EXPECT_FLOAT_EQ(target
, delegate
.GetGrayscaleForAnimation());
246 LayerAnimationElement::TargetValue
target_value(&delegate
);
247 element
->GetTargetValue(&target_value
);
248 EXPECT_FLOAT_EQ(target
, target_value
.grayscale
);
251 // Check that the pause element progresses the delegate as expected and
252 // that the element can be reused after it completes.
253 TEST(LayerAnimationElementTest
, PauseElement
) {
254 LayerAnimationElement::AnimatableProperties properties
;
255 properties
.insert(LayerAnimationElement::TRANSFORM
);
256 properties
.insert(LayerAnimationElement::BOUNDS
);
257 properties
.insert(LayerAnimationElement::OPACITY
);
258 properties
.insert(LayerAnimationElement::BRIGHTNESS
);
259 properties
.insert(LayerAnimationElement::GRAYSCALE
);
260 base::TimeTicks start_time
;
261 base::TimeDelta delta
= base::TimeDelta::FromSeconds(1);
263 scoped_ptr
<LayerAnimationElement
> element(
264 LayerAnimationElement::CreatePauseElement(properties
, delta
));
266 TestLayerAnimationDelegate delegate
;
267 TestLayerAnimationDelegate copy
= delegate
;
270 element
->set_requested_start_time(start_time
);
271 element
->Start(&delegate
, 1);
273 // Pause should last for |delta|.
274 base::TimeDelta element_duration
;
275 EXPECT_TRUE(element
->IsFinished(start_time
+ delta
, &element_duration
));
276 EXPECT_EQ(delta
, element_duration
);
278 element
->Progress(start_time
+ delta
, &delegate
);
280 // Nothing should have changed.
281 CheckApproximatelyEqual(delegate
.GetBoundsForAnimation(),
282 copy
.GetBoundsForAnimation());
283 CheckApproximatelyEqual(delegate
.GetTransformForAnimation(),
284 copy
.GetTransformForAnimation());
285 EXPECT_FLOAT_EQ(delegate
.GetOpacityForAnimation(),
286 copy
.GetOpacityForAnimation());
287 EXPECT_FLOAT_EQ(delegate
.GetBrightnessForAnimation(),
288 copy
.GetBrightnessForAnimation());
289 EXPECT_FLOAT_EQ(delegate
.GetGrayscaleForAnimation(),
290 copy
.GetGrayscaleForAnimation());
293 // Check that a threaded element updates the delegate as expected when aborted.
294 TEST(LayerAnimationElementTest
, AbortOpacityElement
) {
295 TestLayerAnimationDelegate delegate
;
298 base::TimeTicks start_time
;
299 base::TimeTicks effective_start_time
;
300 base::TimeDelta delta
= base::TimeDelta::FromSeconds(1);
301 scoped_ptr
<LayerAnimationElement
> element(
302 LayerAnimationElement::CreateOpacityElement(target
, delta
));
304 // Choose a non-linear Tween type.
305 Tween::Type tween_type
= Tween::EASE_IN
;
306 element
->set_tween_type(tween_type
);
309 element
->set_requested_start_time(start_time
);
310 delegate
.SetOpacityFromAnimation(start
);
311 element
->Start(&delegate
, 1);
312 element
->Progress(start_time
, &delegate
);
313 effective_start_time
= start_time
+ delta
;
314 element
->set_effective_start_time(effective_start_time
);
315 element
->Progress(effective_start_time
, &delegate
);
316 element
->Progress(effective_start_time
+ delta
/2, &delegate
);
318 element
->Abort(&delegate
);
319 EXPECT_FLOAT_EQ(Tween::CalculateValue(tween_type
, 0.5),
320 delegate
.GetOpacityForAnimation());