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 <memory>
8
9 #include "base/compiler_specific.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/time/time.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/compositor/layer_animation_delegate.h"
14 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
15 #include "ui/compositor/test/test_layer_animation_delegate.h"
16 #include "ui/compositor/test/test_utils.h"
17 #include "ui/gfx/geometry/rect.h"
18 #include "ui/gfx/transform.h"
19
20 namespace ui {
21
22 namespace {
23
24 // Verify that the TargetValue(TestLayerAnimationDelegate*) constructor
25 // correctly assigns values. See www.crbug.com/483134.
TEST(TargetValueTest,VerifyLayerAnimationDelegateConstructor)26 TEST(TargetValueTest, VerifyLayerAnimationDelegateConstructor) {
27 const gfx::Rect kBounds(1, 2, 3, 5);
28 const gfx::Transform kTransform(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f);
29 const float kOpacity = 1.235f;
30 const bool kVisibility = false;
31 const float kBrightness = 2.358f;
32 const float kGrayscale = 2.5813f;
33 const SkColor kColor = SK_ColorCYAN;
34 const gfx::Rect kClipRect(2, 3, 4, 5);
35 const gfx::RoundedCornersF kRoundedCorners(2.0f, 3.0f, 4.0f, 5.0f);
36
37 TestLayerAnimationDelegate delegate;
38 delegate.SetBoundsFromAnimation(kBounds,
39 PropertyChangeReason::NOT_FROM_ANIMATION);
40 delegate.SetTransformFromAnimation(kTransform,
41 PropertyChangeReason::NOT_FROM_ANIMATION);
42 delegate.SetOpacityFromAnimation(kOpacity,
43 PropertyChangeReason::NOT_FROM_ANIMATION);
44 delegate.SetVisibilityFromAnimation(kVisibility,
45 PropertyChangeReason::NOT_FROM_ANIMATION);
46 delegate.SetBrightnessFromAnimation(kBrightness,
47 PropertyChangeReason::NOT_FROM_ANIMATION);
48 delegate.SetGrayscaleFromAnimation(kGrayscale,
49 PropertyChangeReason::NOT_FROM_ANIMATION);
50 delegate.SetColorFromAnimation(kColor,
51 PropertyChangeReason::NOT_FROM_ANIMATION);
52 delegate.SetClipRectFromAnimation(kClipRect,
53 PropertyChangeReason::NOT_FROM_ANIMATION);
54 delegate.SetRoundedCornersFromAnimation(
55 kRoundedCorners, PropertyChangeReason::NOT_FROM_ANIMATION);
56
57 LayerAnimationElement::TargetValue target_value(&delegate);
58
59 EXPECT_EQ(kBounds, target_value.bounds);
60 EXPECT_EQ(kTransform, target_value.transform);
61 EXPECT_FLOAT_EQ(kOpacity, target_value.opacity);
62 EXPECT_EQ(kVisibility, target_value.visibility);
63 EXPECT_FLOAT_EQ(kBrightness, target_value.brightness);
64 EXPECT_FLOAT_EQ(kGrayscale, target_value.grayscale);
65 EXPECT_EQ(SK_ColorCYAN, target_value.color);
66 EXPECT_EQ(kClipRect, target_value.clip_rect);
67 EXPECT_EQ(kRoundedCorners, target_value.rounded_corners);
68 }
69
70 // Check that the transformation element progresses the delegate as expected and
71 // that the element can be reused after it completes.
TEST(LayerAnimationElementTest,TransformElement)72 TEST(LayerAnimationElementTest, TransformElement) {
73 TestLayerAnimationDelegate delegate;
74 gfx::Transform start_transform, target_transform;
75 start_transform.Rotate(-30.0);
76 target_transform.Rotate(30.0);
77 base::TimeTicks start_time;
78 base::TimeTicks effective_start_time;
79 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
80
81 std::unique_ptr<LayerAnimationElement> element =
82 LayerAnimationElement::CreateTransformElement(target_transform, delta);
83 element->set_animation_group_id(1);
84
85 for (int i = 0; i < 2; ++i) {
86 start_time = effective_start_time + delta;
87 element->set_requested_start_time(start_time);
88 delegate.SetTransformFromAnimation(
89 start_transform, PropertyChangeReason::NOT_FROM_ANIMATION);
90 element->Start(&delegate, 1);
91 element->Progress(start_time, &delegate);
92 CheckApproximatelyEqual(start_transform,
93 delegate.GetTransformForAnimation());
94 delegate.ExpectLastPropertyChangeReason(
95 PropertyChangeReason::FROM_ANIMATION);
96 effective_start_time = start_time + delta;
97 element->set_effective_start_time(effective_start_time);
98 element->Progress(effective_start_time, &delegate);
99 EXPECT_FLOAT_EQ(0.0, element->last_progressed_fraction());
100 element->Progress(effective_start_time + delta/2, &delegate);
101 EXPECT_FLOAT_EQ(0.5, element->last_progressed_fraction());
102
103 base::TimeDelta element_duration;
104 EXPECT_TRUE(element->IsFinished(effective_start_time + delta,
105 &element_duration));
106 EXPECT_EQ(2 * delta, element_duration);
107
108 element->Progress(effective_start_time + delta, &delegate);
109 EXPECT_FLOAT_EQ(1.0, element->last_progressed_fraction());
110 CheckApproximatelyEqual(target_transform,
111 delegate.GetTransformForAnimation());
112 delegate.ExpectLastPropertyChangeReason(
113 PropertyChangeReason::FROM_ANIMATION);
114 }
115
116 LayerAnimationElement::TargetValue target_value(&delegate);
117 element->GetTargetValue(&target_value);
118 CheckApproximatelyEqual(target_transform, target_value.transform);
119 }
120
121 // Check that the bounds element progresses the delegate as expected and
122 // that the element can be reused after it completes.
TEST(LayerAnimationElementTest,BoundsElement)123 TEST(LayerAnimationElementTest, BoundsElement) {
124 TestLayerAnimationDelegate delegate;
125 gfx::Rect start, target, middle;
126 start = target = middle = gfx::Rect(0, 0, 50, 50);
127 start.set_x(-90);
128 target.set_x(90);
129 base::TimeTicks start_time;
130 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
131
132 std::unique_ptr<LayerAnimationElement> element =
133 LayerAnimationElement::CreateBoundsElement(target, delta);
134
135 for (int i = 0; i < 2; ++i) {
136 start_time += delta;
137 element->set_requested_start_time(start_time);
138 delegate.SetBoundsFromAnimation(start,
139 PropertyChangeReason::NOT_FROM_ANIMATION);
140 element->Start(&delegate, 1);
141 element->Progress(start_time, &delegate);
142 CheckApproximatelyEqual(start, delegate.GetBoundsForAnimation());
143 delegate.ExpectLastPropertyChangeReason(
144 PropertyChangeReason::FROM_ANIMATION);
145 element->Progress(start_time + delta/2, &delegate);
146 CheckApproximatelyEqual(middle, delegate.GetBoundsForAnimation());
147 delegate.ExpectLastPropertyChangeReason(
148 PropertyChangeReason::FROM_ANIMATION);
149
150 base::TimeDelta element_duration;
151 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
152 EXPECT_EQ(delta, element_duration);
153
154 element->Progress(start_time + delta, &delegate);
155 CheckApproximatelyEqual(target, delegate.GetBoundsForAnimation());
156 delegate.ExpectLastPropertyChangeReason(
157 PropertyChangeReason::FROM_ANIMATION);
158 }
159
160 LayerAnimationElement::TargetValue target_value(&delegate);
161 element->GetTargetValue(&target_value);
162 CheckApproximatelyEqual(target, target_value.bounds);
163 }
164
165 // Check that the opacity element progresses the delegate as expected and
166 // that the element can be reused after it completes.
TEST(LayerAnimationElementTest,OpacityElement)167 TEST(LayerAnimationElementTest, OpacityElement) {
168 TestLayerAnimationDelegate delegate;
169 float start = 0.0;
170 float middle = 0.5;
171 float target = 1.0;
172 base::TimeTicks start_time;
173 base::TimeTicks effective_start_time;
174 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
175 std::unique_ptr<LayerAnimationElement> element =
176 LayerAnimationElement::CreateOpacityElement(target, delta);
177
178 for (int i = 0; i < 2; ++i) {
179 start_time = effective_start_time + delta;
180 element->set_requested_start_time(start_time);
181 delegate.SetOpacityFromAnimation(start,
182 PropertyChangeReason::NOT_FROM_ANIMATION);
183 element->Start(&delegate, 1);
184 element->Progress(start_time, &delegate);
185 EXPECT_FLOAT_EQ(start, element->last_progressed_fraction());
186 effective_start_time = start_time + delta;
187 element->set_effective_start_time(effective_start_time);
188 element->Progress(effective_start_time, &delegate);
189 EXPECT_FLOAT_EQ(start, element->last_progressed_fraction());
190 element->Progress(effective_start_time + delta/2, &delegate);
191 EXPECT_FLOAT_EQ(middle, element->last_progressed_fraction());
192
193 base::TimeDelta element_duration;
194 EXPECT_TRUE(element->IsFinished(effective_start_time + delta,
195 &element_duration));
196 EXPECT_EQ(2 * delta, element_duration);
197
198 element->Progress(effective_start_time + delta, &delegate);
199 EXPECT_FLOAT_EQ(target, element->last_progressed_fraction());
200 EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation());
201 delegate.ExpectLastPropertyChangeReason(
202 PropertyChangeReason::FROM_ANIMATION);
203 }
204
205 LayerAnimationElement::TargetValue target_value(&delegate);
206 element->GetTargetValue(&target_value);
207 EXPECT_FLOAT_EQ(target, target_value.opacity);
208 }
209
210 // Check that the visibility element progresses the delegate as expected and
211 // that the element can be reused after it completes.
TEST(LayerAnimationElementTest,VisibilityElement)212 TEST(LayerAnimationElementTest, VisibilityElement) {
213 TestLayerAnimationDelegate delegate;
214 bool start = true;
215 bool target = false;
216 base::TimeTicks start_time;
217 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
218 std::unique_ptr<LayerAnimationElement> element =
219 LayerAnimationElement::CreateVisibilityElement(target, delta);
220
221 for (int i = 0; i < 2; ++i) {
222 start_time += delta;
223 element->set_requested_start_time(start_time);
224 delegate.SetVisibilityFromAnimation(
225 start, PropertyChangeReason::NOT_FROM_ANIMATION);
226 element->Start(&delegate, 1);
227 element->Progress(start_time, &delegate);
228 EXPECT_TRUE(delegate.GetVisibilityForAnimation());
229 delegate.ExpectLastPropertyChangeReason(
230 PropertyChangeReason::FROM_ANIMATION);
231 element->Progress(start_time + delta/2, &delegate);
232 EXPECT_TRUE(delegate.GetVisibilityForAnimation());
233 delegate.ExpectLastPropertyChangeReason(
234 PropertyChangeReason::FROM_ANIMATION);
235
236 base::TimeDelta element_duration;
237 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
238 EXPECT_EQ(delta, element_duration);
239
240 element->Progress(start_time + delta, &delegate);
241 EXPECT_FALSE(delegate.GetVisibilityForAnimation());
242 delegate.ExpectLastPropertyChangeReason(
243 PropertyChangeReason::FROM_ANIMATION);
244 }
245
246 LayerAnimationElement::TargetValue target_value(&delegate);
247 element->GetTargetValue(&target_value);
248 EXPECT_FALSE(target_value.visibility);
249 }
250
251 // Check that the Brightness element progresses the delegate as expected and
252 // that the element can be reused after it completes.
TEST(LayerAnimationElementTest,BrightnessElement)253 TEST(LayerAnimationElementTest, BrightnessElement) {
254 TestLayerAnimationDelegate delegate;
255 float start = 0.0;
256 float middle = 0.5;
257 float target = 1.0;
258 base::TimeTicks start_time;
259 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
260 std::unique_ptr<LayerAnimationElement> element =
261 LayerAnimationElement::CreateBrightnessElement(target, delta);
262
263 for (int i = 0; i < 2; ++i) {
264 start_time += delta;
265 element->set_requested_start_time(start_time);
266 delegate.SetBrightnessFromAnimation(
267 start, PropertyChangeReason::NOT_FROM_ANIMATION);
268 element->Start(&delegate, 1);
269 element->Progress(start_time, &delegate);
270 EXPECT_FLOAT_EQ(start, delegate.GetBrightnessForAnimation());
271 delegate.ExpectLastPropertyChangeReason(
272 PropertyChangeReason::FROM_ANIMATION);
273 element->Progress(start_time + delta/2, &delegate);
274 EXPECT_FLOAT_EQ(middle, delegate.GetBrightnessForAnimation());
275 delegate.ExpectLastPropertyChangeReason(
276 PropertyChangeReason::FROM_ANIMATION);
277
278 base::TimeDelta element_duration;
279 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
280 EXPECT_EQ(delta, element_duration);
281
282 element->Progress(start_time + delta, &delegate);
283 EXPECT_FLOAT_EQ(target, delegate.GetBrightnessForAnimation());
284 delegate.ExpectLastPropertyChangeReason(
285 PropertyChangeReason::FROM_ANIMATION);
286 }
287
288 LayerAnimationElement::TargetValue target_value(&delegate);
289 element->GetTargetValue(&target_value);
290 EXPECT_FLOAT_EQ(target, target_value.brightness);
291 }
292
293 // Check that the Grayscale element progresses the delegate as expected and
294 // that the element can be reused after it completes.
TEST(LayerAnimationElementTest,GrayscaleElement)295 TEST(LayerAnimationElementTest, GrayscaleElement) {
296 TestLayerAnimationDelegate delegate;
297 float start = 0.0;
298 float middle = 0.5;
299 float target = 1.0;
300 base::TimeTicks start_time;
301 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
302 std::unique_ptr<LayerAnimationElement> element =
303 LayerAnimationElement::CreateGrayscaleElement(target, delta);
304
305 for (int i = 0; i < 2; ++i) {
306 start_time += delta;
307 element->set_requested_start_time(start_time);
308 delegate.SetGrayscaleFromAnimation(
309 start, PropertyChangeReason::NOT_FROM_ANIMATION);
310 element->Start(&delegate, 1);
311 element->Progress(start_time, &delegate);
312 EXPECT_FLOAT_EQ(start, delegate.GetGrayscaleForAnimation());
313 delegate.ExpectLastPropertyChangeReason(
314 PropertyChangeReason::FROM_ANIMATION);
315 element->Progress(start_time + delta/2, &delegate);
316 EXPECT_FLOAT_EQ(middle, delegate.GetGrayscaleForAnimation());
317 delegate.ExpectLastPropertyChangeReason(
318 PropertyChangeReason::FROM_ANIMATION);
319
320 base::TimeDelta element_duration;
321 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
322 EXPECT_EQ(delta, element_duration);
323
324 element->Progress(start_time + delta, &delegate);
325 EXPECT_FLOAT_EQ(target, delegate.GetGrayscaleForAnimation());
326 delegate.ExpectLastPropertyChangeReason(
327 PropertyChangeReason::FROM_ANIMATION);
328 }
329
330 LayerAnimationElement::TargetValue target_value(&delegate);
331 element->GetTargetValue(&target_value);
332 EXPECT_FLOAT_EQ(target, target_value.grayscale);
333 }
334
335 // Check that the pause element progresses the delegate as expected and
336 // that the element can be reused after it completes.
TEST(LayerAnimationElementTest,PauseElement)337 TEST(LayerAnimationElementTest, PauseElement) {
338 LayerAnimationElement::AnimatableProperties properties =
339 LayerAnimationElement::TRANSFORM | LayerAnimationElement::BOUNDS |
340 LayerAnimationElement::OPACITY | LayerAnimationElement::BRIGHTNESS |
341 LayerAnimationElement::GRAYSCALE;
342
343 base::TimeTicks start_time;
344 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
345
346 std::unique_ptr<LayerAnimationElement> element =
347 LayerAnimationElement::CreatePauseElement(properties, delta);
348
349 TestLayerAnimationDelegate delegate;
350 TestLayerAnimationDelegate copy = delegate;
351
352 start_time += delta;
353 element->set_requested_start_time(start_time);
354 element->Start(&delegate, 1);
355
356 // Pause should last for |delta|.
357 base::TimeDelta element_duration;
358 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
359 EXPECT_EQ(delta, element_duration);
360
361 element->Progress(start_time + delta, &delegate);
362
363 // Nothing should have changed.
364 CheckApproximatelyEqual(delegate.GetBoundsForAnimation(),
365 copy.GetBoundsForAnimation());
366 CheckApproximatelyEqual(delegate.GetTransformForAnimation(),
367 copy.GetTransformForAnimation());
368 EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(),
369 copy.GetOpacityForAnimation());
370 EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(),
371 copy.GetBrightnessForAnimation());
372 EXPECT_FLOAT_EQ(delegate.GetGrayscaleForAnimation(),
373 copy.GetGrayscaleForAnimation());
374 }
375
376 // Check that the ClipRect element progresses the delegate as expected and
377 // that the element can be reused after it completes.
TEST(LayerAnimationElementTest,ClipRectElement)378 TEST(LayerAnimationElementTest, ClipRectElement) {
379 TestLayerAnimationDelegate delegate;
380 gfx::Rect start, target, middle;
381 start = target = middle = gfx::Rect(0, 0, 50, 50);
382
383 start.set_x(-10);
384 target.set_x(10);
385
386 start.set_y(-20);
387 target.set_y(20);
388
389 start.set_width(70);
390 target.set_width(30);
391 base::TimeTicks start_time;
392 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
393
394 std::unique_ptr<LayerAnimationElement> element =
395 LayerAnimationElement::CreateClipRectElement(target, delta);
396
397 for (int i = 0; i < 2; ++i) {
398 start_time += delta;
399 element->set_requested_start_time(start_time);
400 delegate.SetClipRectFromAnimation(start,
401 PropertyChangeReason::NOT_FROM_ANIMATION);
402 element->Start(&delegate, 1);
403 element->Progress(start_time, &delegate);
404 CheckApproximatelyEqual(start, delegate.GetClipRectForAnimation());
405 delegate.ExpectLastPropertyChangeReason(
406 PropertyChangeReason::FROM_ANIMATION);
407 element->Progress(start_time + delta / 2, &delegate);
408 CheckApproximatelyEqual(middle, delegate.GetClipRectForAnimation());
409 delegate.ExpectLastPropertyChangeReason(
410 PropertyChangeReason::FROM_ANIMATION);
411
412 base::TimeDelta element_duration;
413 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
414 EXPECT_EQ(delta, element_duration);
415
416 element->Progress(start_time + delta, &delegate);
417 CheckApproximatelyEqual(target, delegate.GetClipRectForAnimation());
418 delegate.ExpectLastPropertyChangeReason(
419 PropertyChangeReason::FROM_ANIMATION);
420 }
421
422 LayerAnimationElement::TargetValue target_value(&delegate);
423 element->GetTargetValue(&target_value);
424 CheckApproximatelyEqual(target, target_value.clip_rect);
425 }
426
427 // Check that the RoundedCorners element progresses the delegate as expected and
428 // that the element can be reused after it completes.
TEST(LayerAnimationElementTest,RoundedCornersElement)429 TEST(LayerAnimationElementTest, RoundedCornersElement) {
430 TestLayerAnimationDelegate delegate;
431 gfx::RoundedCornersF start(1.0f, 2.0f, 3.0f, 4.0f);
432 gfx::RoundedCornersF target(11.0f, 12.0f, 13.0f, 14.0f);
433 gfx::RoundedCornersF middle(6.0f, 7.0f, 8.0f, 9.0f);
434
435 base::TimeTicks start_time;
436 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
437
438 std::unique_ptr<LayerAnimationElement> element =
439 LayerAnimationElement::CreateRoundedCornersElement(target, delta);
440
441 for (int i = 0; i < 2; ++i) {
442 start_time += delta;
443 element->set_requested_start_time(start_time);
444 delegate.SetRoundedCornersFromAnimation(
445 start, PropertyChangeReason::NOT_FROM_ANIMATION);
446 element->Start(&delegate, 1);
447 element->Progress(start_time, &delegate);
448 CheckApproximatelyEqual(start, delegate.GetRoundedCornersForAnimation());
449 delegate.ExpectLastPropertyChangeReason(
450 PropertyChangeReason::FROM_ANIMATION);
451 element->Progress(start_time + delta / 2, &delegate);
452 CheckApproximatelyEqual(middle, delegate.GetRoundedCornersForAnimation());
453 delegate.ExpectLastPropertyChangeReason(
454 PropertyChangeReason::FROM_ANIMATION);
455
456 base::TimeDelta element_duration;
457 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
458 EXPECT_EQ(delta, element_duration);
459
460 element->Progress(start_time + delta, &delegate);
461 CheckApproximatelyEqual(target, delegate.GetRoundedCornersForAnimation());
462 delegate.ExpectLastPropertyChangeReason(
463 PropertyChangeReason::FROM_ANIMATION);
464 }
465
466 LayerAnimationElement::TargetValue target_value(&delegate);
467 element->GetTargetValue(&target_value);
468 CheckApproximatelyEqual(target, target_value.rounded_corners);
469 }
470
471 // Check that a threaded opacity element updates the delegate as expected when
472 // aborted.
TEST(LayerAnimationElementTest,AbortOpacityElement)473 TEST(LayerAnimationElementTest, AbortOpacityElement) {
474 TestLayerAnimationDelegate delegate;
475 float start = 0.0;
476 float target = 1.0;
477 base::TimeTicks start_time;
478 base::TimeTicks effective_start_time;
479 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
480 std::unique_ptr<LayerAnimationElement> element =
481 LayerAnimationElement::CreateOpacityElement(target, delta);
482
483 // Choose a non-linear Tween type.
484 gfx::Tween::Type tween_type = gfx::Tween::EASE_IN;
485 element->set_tween_type(tween_type);
486
487 delegate.SetOpacityFromAnimation(start,
488 PropertyChangeReason::NOT_FROM_ANIMATION);
489 delegate.ExpectLastPropertyChangeReason(
490 PropertyChangeReason::NOT_FROM_ANIMATION);
491
492 // Aborting the element before it has started should not update the delegate.
493 element->Abort(&delegate);
494 EXPECT_FLOAT_EQ(start, delegate.GetOpacityForAnimation());
495 delegate.ExpectLastPropertyChangeReasonIsUnset();
496
497 start_time += delta;
498 element->set_requested_start_time(start_time);
499 element->Start(&delegate, 1);
500 element->Progress(start_time, &delegate);
501 effective_start_time = start_time + delta;
502 element->set_effective_start_time(effective_start_time);
503 element->Progress(effective_start_time, &delegate);
504 element->Progress(effective_start_time + delta/2, &delegate);
505
506 // Since the element has started, it should update the delegate when
507 // aborted.
508 element->Abort(&delegate);
509 EXPECT_FLOAT_EQ(gfx::Tween::CalculateValue(tween_type, 0.5),
510 delegate.GetOpacityForAnimation());
511 delegate.ExpectLastPropertyChangeReason(PropertyChangeReason::FROM_ANIMATION);
512 }
513
514 // Check that a threaded transform element updates the delegate as expected when
515 // aborted.
TEST(LayerAnimationElementTest,AbortTransformElement)516 TEST(LayerAnimationElementTest, AbortTransformElement) {
517 TestLayerAnimationDelegate delegate;
518 gfx::Transform start_transform, target_transform;
519 start_transform.Rotate(-30.0);
520 target_transform.Rotate(30.0);
521 base::TimeTicks start_time;
522 base::TimeTicks effective_start_time;
523 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
524 std::unique_ptr<LayerAnimationElement> element =
525 LayerAnimationElement::CreateTransformElement(target_transform, delta);
526
527 // Choose a non-linear Tween type.
528 gfx::Tween::Type tween_type = gfx::Tween::EASE_IN;
529 element->set_tween_type(tween_type);
530
531 delegate.SetTransformFromAnimation(start_transform,
532 PropertyChangeReason::NOT_FROM_ANIMATION);
533 delegate.ExpectLastPropertyChangeReason(
534 PropertyChangeReason::NOT_FROM_ANIMATION);
535
536 // Aborting the element before it has started should not update the delegate.
537 element->Abort(&delegate);
538 CheckApproximatelyEqual(start_transform, delegate.GetTransformForAnimation());
539 delegate.ExpectLastPropertyChangeReasonIsUnset();
540
541 start_time += delta;
542 element->set_requested_start_time(start_time);
543 element->Start(&delegate, 1);
544 element->Progress(start_time, &delegate);
545 effective_start_time = start_time + delta;
546 element->set_effective_start_time(effective_start_time);
547 element->Progress(effective_start_time, &delegate);
548 element->Progress(effective_start_time + delta/2, &delegate);
549
550 // Since the element has started, it should update the delegate when
551 // aborted.
552 element->Abort(&delegate);
553 target_transform.Blend(start_transform,
554 gfx::Tween::CalculateValue(tween_type, 0.5));
555 CheckApproximatelyEqual(target_transform,
556 delegate.GetTransformForAnimation());
557 delegate.ExpectLastPropertyChangeReason(PropertyChangeReason::FROM_ANIMATION);
558 }
559
560 // Check that an opacity element is not threaded if the start and target values
561 // are the same.
TEST(LayerAnimationElementTest,OpacityElementIsThreaded)562 TEST(LayerAnimationElementTest, OpacityElementIsThreaded) {
563 TestLayerAnimationDelegate delegate;
564 float start = 0.0;
565 float target = 1.0;
566 delegate.SetOpacityFromAnimation(start,
567 PropertyChangeReason::NOT_FROM_ANIMATION);
568 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
569 std::unique_ptr<LayerAnimationElement> element =
570 LayerAnimationElement::CreateOpacityElement(target, delta);
571 EXPECT_TRUE(element->IsThreaded(&delegate));
572 element->ProgressToEnd(&delegate);
573 EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation());
574 delegate.ExpectLastPropertyChangeReason(PropertyChangeReason::FROM_ANIMATION);
575
576 start = 1.0;
577 delegate.SetOpacityFromAnimation(start,
578 PropertyChangeReason::NOT_FROM_ANIMATION);
579 element = LayerAnimationElement::CreateOpacityElement(target, delta);
580 EXPECT_FALSE(element->IsThreaded(&delegate));
581 element->ProgressToEnd(&delegate);
582 EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation());
583 delegate.ExpectLastPropertyChangeReason(PropertyChangeReason::FROM_ANIMATION);
584 }
585
TEST(LayerAnimationElementTest,ToString)586 TEST(LayerAnimationElementTest, ToString) {
587 float target = 1.0;
588 base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
589 std::unique_ptr<LayerAnimationElement> element =
590 LayerAnimationElement::CreateOpacityElement(target, delta);
591 element->set_animation_group_id(42);
592 // TODO(wkorman): Test varying last_progressed_fraction.
593 EXPECT_EQ(
594 base::StringPrintf("LayerAnimationElement{name=ThreadedOpacityTransition,"
595 " id=%d, group=42, "
596 "last_progressed_fraction=0.00}",
597 element->keyframe_model_id()),
598 element->ToString());
599 }
600
601 } // namespace
602
603 } // namespace ui
604