layer_animation_element_unittest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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_element.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/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"
17
18namespace ui {
19
20namespace {
21
22// Check that the transformation element progresses the delegate as expected and
23// that the element can be reused after it completes.
24TEST(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);
32
33  scoped_ptr<LayerAnimationElement> element(
34      LayerAnimationElement::CreateTransformElement(target_transform, delta));
35  element->set_animation_group_id(1);
36
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());
51
52    base::TimeDelta element_duration;
53    EXPECT_TRUE(element->IsFinished(effective_start_time + delta,
54                                    &element_duration));
55    EXPECT_EQ(2 * delta, element_duration);
56
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());
61  }
62
63  LayerAnimationElement::TargetValue target_value(&delegate);
64  element->GetTargetValue(&target_value);
65  CheckApproximatelyEqual(target_transform, target_value.transform);
66}
67
68// Check that the bounds element progresses the delegate as expected and
69// that the element can be reused after it completes.
70TEST(LayerAnimationElementTest, BoundsElement) {
71  TestLayerAnimationDelegate delegate;
72  gfx::Rect start, target, middle;
73  start = target = middle = gfx::Rect(0, 0, 50, 50);
74  start.set_x(-90);
75  target.set_x(90);
76  base::TimeTicks start_time;
77  base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
78
79  scoped_ptr<LayerAnimationElement> element(
80      LayerAnimationElement::CreateBoundsElement(target, delta));
81
82  for (int i = 0; i < 2; ++i) {
83    start_time += delta;
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());
91
92    base::TimeDelta element_duration;
93    EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
94    EXPECT_EQ(delta, element_duration);
95
96    element->Progress(start_time + delta, &delegate);
97    CheckApproximatelyEqual(target, delegate.GetBoundsForAnimation());
98  }
99
100  LayerAnimationElement::TargetValue target_value(&delegate);
101  element->GetTargetValue(&target_value);
102  CheckApproximatelyEqual(target, target_value.bounds);
103}
104
105// Check that the opacity element progresses the delegate as expected and
106// that the element can be reused after it completes.
107TEST(LayerAnimationElementTest, OpacityElement) {
108  TestLayerAnimationDelegate delegate;
109  float start = 0.0;
110  float middle = 0.5;
111  float target = 1.0;
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));
117
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());
131
132    base::TimeDelta element_duration;
133    EXPECT_TRUE(element->IsFinished(effective_start_time + delta,
134                                    &element_duration));
135    EXPECT_EQ(2 * delta, element_duration);
136
137    element->Progress(effective_start_time + delta, &delegate);
138    EXPECT_FLOAT_EQ(target, element->last_progressed_fraction());
139    EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation());
140  }
141
142  LayerAnimationElement::TargetValue target_value(&delegate);
143  element->GetTargetValue(&target_value);
144  EXPECT_FLOAT_EQ(target, target_value.opacity);
145}
146
147// Check that the visibility element progresses the delegate as expected and
148// that the element can be reused after it completes.
149TEST(LayerAnimationElementTest, VisibilityElement) {
150  TestLayerAnimationDelegate delegate;
151  bool start = true;
152  bool target = false;
153  base::TimeTicks start_time;
154  base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
155  scoped_ptr<LayerAnimationElement> element(
156      LayerAnimationElement::CreateVisibilityElement(target, delta));
157
158  for (int i = 0; i < 2; ++i) {
159    start_time += delta;
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());
167
168    base::TimeDelta element_duration;
169    EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
170    EXPECT_EQ(delta, element_duration);
171
172    element->Progress(start_time + delta, &delegate);
173    EXPECT_FALSE(delegate.GetVisibilityForAnimation());
174  }
175
176  LayerAnimationElement::TargetValue target_value(&delegate);
177  element->GetTargetValue(&target_value);
178  EXPECT_FALSE(target_value.visibility);
179}
180
181// Check that the Brightness element progresses the delegate as expected and
182// that the element can be reused after it completes.
183TEST(LayerAnimationElementTest, BrightnessElement) {
184  TestLayerAnimationDelegate delegate;
185  float start = 0.0;
186  float middle = 0.5;
187  float target = 1.0;
188  base::TimeTicks start_time;
189  base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
190  scoped_ptr<LayerAnimationElement> element(
191      LayerAnimationElement::CreateBrightnessElement(target, delta));
192
193  for (int i = 0; i < 2; ++i) {
194    start_time += delta;
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());
202
203    base::TimeDelta element_duration;
204    EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
205    EXPECT_EQ(delta, element_duration);
206
207    element->Progress(start_time + delta, &delegate);
208    EXPECT_FLOAT_EQ(target, delegate.GetBrightnessForAnimation());
209  }
210
211  LayerAnimationElement::TargetValue target_value(&delegate);
212  element->GetTargetValue(&target_value);
213  EXPECT_FLOAT_EQ(target, target_value.brightness);
214}
215
216// Check that the Grayscale element progresses the delegate as expected and
217// that the element can be reused after it completes.
218TEST(LayerAnimationElementTest, GrayscaleElement) {
219  TestLayerAnimationDelegate delegate;
220  float start = 0.0;
221  float middle = 0.5;
222  float target = 1.0;
223  base::TimeTicks start_time;
224  base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
225  scoped_ptr<LayerAnimationElement> element(
226      LayerAnimationElement::CreateGrayscaleElement(target, delta));
227
228  for (int i = 0; i < 2; ++i) {
229    start_time += delta;
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());
237
238    base::TimeDelta element_duration;
239    EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
240    EXPECT_EQ(delta, element_duration);
241
242    element->Progress(start_time + delta, &delegate);
243    EXPECT_FLOAT_EQ(target, delegate.GetGrayscaleForAnimation());
244  }
245
246  LayerAnimationElement::TargetValue target_value(&delegate);
247  element->GetTargetValue(&target_value);
248  EXPECT_FLOAT_EQ(target, target_value.grayscale);
249}
250
251// Check that the pause element progresses the delegate as expected and
252// that the element can be reused after it completes.
253TEST(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);
262
263  scoped_ptr<LayerAnimationElement> element(
264      LayerAnimationElement::CreatePauseElement(properties, delta));
265
266  TestLayerAnimationDelegate delegate;
267  TestLayerAnimationDelegate copy = delegate;
268
269  start_time += delta;
270  element->set_requested_start_time(start_time);
271  element->Start(&delegate, 1);
272
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);
277
278  element->Progress(start_time + delta, &delegate);
279
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());
291}
292
293// Check that a threaded opacity element updates the delegate as expected when
294// aborted.
295TEST(LayerAnimationElementTest, AbortOpacityElement) {
296  TestLayerAnimationDelegate delegate;
297  float start = 0.0;
298  float target = 1.0;
299  base::TimeTicks start_time;
300  base::TimeTicks effective_start_time;
301  base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
302  scoped_ptr<LayerAnimationElement> element(
303      LayerAnimationElement::CreateOpacityElement(target, delta));
304
305  // Choose a non-linear Tween type.
306  Tween::Type tween_type = Tween::EASE_IN;
307  element->set_tween_type(tween_type);
308
309  delegate.SetOpacityFromAnimation(start);
310
311  // Aborting the element before it has started should not update the delegate.
312  element->Abort(&delegate);
313  EXPECT_FLOAT_EQ(start, delegate.GetOpacityForAnimation());
314
315  start_time += delta;
316  element->set_requested_start_time(start_time);
317  element->Start(&delegate, 1);
318  element->Progress(start_time, &delegate);
319  effective_start_time = start_time + delta;
320  element->set_effective_start_time(effective_start_time);
321  element->Progress(effective_start_time, &delegate);
322  element->Progress(effective_start_time + delta/2, &delegate);
323
324  // Since the element has started, it should update the delegate when
325  // aborted.
326  element->Abort(&delegate);
327  EXPECT_FLOAT_EQ(Tween::CalculateValue(tween_type, 0.5),
328                  delegate.GetOpacityForAnimation());
329}
330
331// Check that a threaded transform element updates the delegate as expected when
332// aborted.
333TEST(LayerAnimationElementTest, AbortTransformElement) {
334  TestLayerAnimationDelegate delegate;
335  gfx::Transform start_transform, target_transform;
336  start_transform.Rotate(-30.0);
337  target_transform.Rotate(30.0);
338  base::TimeTicks start_time;
339  base::TimeTicks effective_start_time;
340  base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
341  scoped_ptr<LayerAnimationElement> element(
342      LayerAnimationElement::CreateTransformElement(target_transform, delta));
343
344  // Choose a non-linear Tween type.
345  Tween::Type tween_type = Tween::EASE_IN;
346  element->set_tween_type(tween_type);
347
348  delegate.SetTransformFromAnimation(start_transform);
349
350  // Aborting the element before it has started should not update the delegate.
351  element->Abort(&delegate);
352  CheckApproximatelyEqual(start_transform, delegate.GetTransformForAnimation());
353
354  start_time += delta;
355  element->set_requested_start_time(start_time);
356  element->Start(&delegate, 1);
357  element->Progress(start_time, &delegate);
358  effective_start_time = start_time + delta;
359  element->set_effective_start_time(effective_start_time);
360  element->Progress(effective_start_time, &delegate);
361  element->Progress(effective_start_time + delta/2, &delegate);
362
363  // Since the element has started, it should update the delegate when
364  // aborted.
365  element->Abort(&delegate);
366  target_transform.Blend(start_transform,
367                         Tween::CalculateValue(tween_type, 0.5));
368  CheckApproximatelyEqual(target_transform,
369                          delegate.GetTransformForAnimation());
370}
371
372} // namespace
373
374} // namespace ui
375