72361092af2287e7df7b255664cf029413b82a01
[WebKit-https.git] / Source / WebKit / chromium / tests / CCLayerAnimationControllerTest.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "cc/CCLayerAnimationController.h"
28
29 #include "CCAnimationTestCommon.h"
30 #include "GraphicsLayer.h"
31 #include "Length.h"
32 #include "cc/CCActiveAnimation.h"
33 #include "cc/CCAnimationCurve.h"
34
35 #include <gmock/gmock.h>
36 #include <gtest/gtest.h>
37 #include <public/WebTransformationMatrix.h>
38 #include <wtf/Vector.h>
39
40 using namespace WebCore;
41 using namespace WebKitTests;
42 using WebKit::WebTransformationMatrix;
43
44 namespace {
45
46 void expectTranslateX(double translateX, const WebTransformationMatrix& matrix)
47 {
48     EXPECT_FLOAT_EQ(translateX, matrix.m41());
49 }
50
51 PassOwnPtr<CCActiveAnimation> createActiveAnimation(PassOwnPtr<CCAnimationCurve> curve, int id, CCActiveAnimation::TargetProperty property)
52 {
53     return CCActiveAnimation::create(curve, 0, id, property);
54 }
55
56 TEST(CCLayerAnimationControllerTest, syncNewAnimation)
57 {
58     FakeLayerAnimationControllerClient dummyImpl;
59     OwnPtr<CCLayerAnimationController> controllerImpl(CCLayerAnimationController::create(&dummyImpl));
60     FakeLayerAnimationControllerClient dummy;
61     OwnPtr<CCLayerAnimationController> controller(CCLayerAnimationController::create(&dummy));
62
63     EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
64
65     addOpacityTransitionToController(*controller, 1, 0, 1, false);
66
67     controller->pushAnimationUpdatesTo(controllerImpl.get());
68
69     EXPECT_TRUE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
70     EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
71 }
72
73 // If an animation is started on the impl thread before it is ticked on the main
74 // thread, we must be sure to respect the synchronized start time.
75 TEST(CCLayerAnimationControllerTest, doNotClobberStartTimes)
76 {
77     FakeLayerAnimationControllerClient dummyImpl;
78     OwnPtr<CCLayerAnimationController> controllerImpl(CCLayerAnimationController::create(&dummyImpl));
79     FakeLayerAnimationControllerClient dummy;
80     OwnPtr<CCLayerAnimationController> controller(CCLayerAnimationController::create(&dummy));
81
82     EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
83
84     addOpacityTransitionToController(*controller, 1, 0, 1, false);
85
86     controller->pushAnimationUpdatesTo(controllerImpl.get());
87
88     EXPECT_TRUE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
89     EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
90
91     CCAnimationEventsVector events;
92     controllerImpl->animate(1, &events);
93
94     // Synchronize the start times.
95     EXPECT_EQ(1u, events.size());
96     controller->notifyAnimationStarted(events[0]);
97     EXPECT_EQ(controller->getActiveAnimation(0, CCActiveAnimation::Opacity)->startTime(), controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->startTime());
98
99     // Start the animation on the main thread. Should not affect the start time.
100     controller->animate(1.5, 0);
101     EXPECT_EQ(controller->getActiveAnimation(0, CCActiveAnimation::Opacity)->startTime(), controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->startTime());
102 }
103
104 TEST(CCLayerAnimationControllerTest, syncPauseAndResume)
105 {
106     FakeLayerAnimationControllerClient dummyImpl;
107     OwnPtr<CCLayerAnimationController> controllerImpl(CCLayerAnimationController::create(&dummyImpl));
108     FakeLayerAnimationControllerClient dummy;
109     OwnPtr<CCLayerAnimationController> controller(CCLayerAnimationController::create(&dummy));
110
111     EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
112
113     addOpacityTransitionToController(*controller, 1, 0, 1, false);
114
115     controller->pushAnimationUpdatesTo(controllerImpl.get());
116
117     EXPECT_TRUE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
118     EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
119
120     // Start the animations on each controller.
121     CCAnimationEventsVector events;
122     controllerImpl->animate(0, &events);
123     controller->animate(0, 0);
124     EXPECT_EQ(CCActiveAnimation::Running, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
125     EXPECT_EQ(CCActiveAnimation::Running, controller->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
126
127     // Pause the main-thread animation.
128     controller->suspendAnimations(1);
129     EXPECT_EQ(CCActiveAnimation::Paused, controller->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
130
131     // The pause run state change should make it to the impl thread controller.
132     controller->pushAnimationUpdatesTo(controllerImpl.get());
133     EXPECT_EQ(CCActiveAnimation::Paused, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
134
135     // Resume the main-thread animation.
136     controller->resumeAnimations(2);
137     EXPECT_EQ(CCActiveAnimation::Running, controller->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
138
139     // The pause run state change should make it to the impl thread controller.
140     controller->pushAnimationUpdatesTo(controllerImpl.get());
141     EXPECT_EQ(CCActiveAnimation::Running, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
142 }
143
144 TEST(CCLayerAnimationControllerTest, doNotSyncFinishedAnimation)
145 {
146     FakeLayerAnimationControllerClient dummyImpl;
147     OwnPtr<CCLayerAnimationController> controllerImpl(CCLayerAnimationController::create(&dummyImpl));
148     FakeLayerAnimationControllerClient dummy;
149     OwnPtr<CCLayerAnimationController> controller(CCLayerAnimationController::create(&dummy));
150
151     EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
152
153     addOpacityTransitionToController(*controller, 1, 0, 1, false);
154
155     controller->pushAnimationUpdatesTo(controllerImpl.get());
156
157     EXPECT_TRUE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
158     EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
159
160     // Notify main thread controller that the animation has started.
161     CCAnimationEvent animationStartedEvent(CCAnimationEvent::Started, 0, 0, CCActiveAnimation::Opacity, 0);
162     controller->notifyAnimationStarted(animationStartedEvent);
163
164     // Force animation to complete on impl thread.
165     controllerImpl->removeAnimation(0);
166
167     EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
168
169     controller->pushAnimationUpdatesTo(controllerImpl.get());
170
171     // Even though the main thread has a 'new' animation, it should not be pushed because the animation has already completed on the impl thread.
172     EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
173 }
174
175 // Tests that transitioning opacity from 0 to 1 works as expected.
176 TEST(CCLayerAnimationControllerTest, TrivialTransition)
177 {
178     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
179     FakeLayerAnimationControllerClient dummy;
180     OwnPtr<CCLayerAnimationController> controller(
181         CCLayerAnimationController::create(&dummy));
182
183     OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
184
185     controller->addAnimation(toAdd.release());
186     controller->animate(0, events.get());
187     EXPECT_TRUE(controller->hasActiveAnimation());
188     EXPECT_EQ(0, dummy.opacity());
189     controller->animate(1, events.get());
190     EXPECT_EQ(1, dummy.opacity());
191     EXPECT_FALSE(controller->hasActiveAnimation());
192 }
193
194 // Tests animations that are waiting for a synchronized start time do not finish.
195 TEST(CCLayerAnimationControllerTest, AnimationsWaitingForStartTimeDoNotFinishIfTheyWaitLongerToStartThanTheirDuration)
196 {
197     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
198     FakeLayerAnimationControllerClient dummy;
199     OwnPtr<CCLayerAnimationController> controller(
200         CCLayerAnimationController::create(&dummy));
201
202     OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
203     toAdd->setNeedsSynchronizedStartTime(true);
204
205     // We should pause at the first keyframe indefinitely waiting for that animation to start.
206     controller->addAnimation(toAdd.release());
207     controller->animate(0, events.get());
208     EXPECT_TRUE(controller->hasActiveAnimation());
209     EXPECT_EQ(0, dummy.opacity());
210     controller->animate(1, events.get());
211     EXPECT_TRUE(controller->hasActiveAnimation());
212     EXPECT_EQ(0, dummy.opacity());
213     controller->animate(2, events.get());
214     EXPECT_TRUE(controller->hasActiveAnimation());
215     EXPECT_EQ(0, dummy.opacity());
216
217     // Send the synchronized start time.
218     controller->notifyAnimationStarted(CCAnimationEvent(CCAnimationEvent::Started, 0, 1, CCActiveAnimation::Opacity, 2));
219     controller->animate(5, events.get());
220     EXPECT_EQ(1, dummy.opacity());
221     EXPECT_FALSE(controller->hasActiveAnimation());
222 }
223
224 // Tests that two queued animations affecting the same property run in sequence.
225 TEST(CCLayerAnimationControllerTest, TrivialQueuing)
226 {
227     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
228     FakeLayerAnimationControllerClient dummy;
229     OwnPtr<CCLayerAnimationController> controller(
230         CCLayerAnimationController::create(&dummy));
231
232     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
233     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 1, 0.5)), 2, CCActiveAnimation::Opacity));
234
235     controller->animate(0, events.get());
236     EXPECT_TRUE(controller->hasActiveAnimation());
237     EXPECT_EQ(0, dummy.opacity());
238     controller->animate(1, events.get());
239     EXPECT_TRUE(controller->hasActiveAnimation());
240     EXPECT_EQ(1, dummy.opacity());
241     controller->animate(2, events.get());
242     EXPECT_EQ(0.5, dummy.opacity());
243     EXPECT_FALSE(controller->hasActiveAnimation());
244 }
245
246 // Tests interrupting a transition with another transition.
247 TEST(CCLayerAnimationControllerTest, Interrupt)
248 {
249     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
250     FakeLayerAnimationControllerClient dummy;
251     OwnPtr<CCLayerAnimationController> controller(
252         CCLayerAnimationController::create(&dummy));
253     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
254     controller->animate(0, events.get());
255     EXPECT_TRUE(controller->hasActiveAnimation());
256     EXPECT_EQ(0, dummy.opacity());
257
258     OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 1, 0.5)), 2, CCActiveAnimation::Opacity));
259     toAdd->setRunState(CCActiveAnimation::WaitingForNextTick, 0);
260     controller->addAnimation(toAdd.release());
261
262     // Since the animation was in the WaitingForNextTick state, it should start right in
263     // this call to animate.
264     controller->animate(0.5, events.get());
265     EXPECT_TRUE(controller->hasActiveAnimation());
266     EXPECT_EQ(1, dummy.opacity());
267     controller->animate(1.5, events.get());
268     EXPECT_EQ(0.5, dummy.opacity());
269     EXPECT_FALSE(controller->hasActiveAnimation());
270 }
271
272 // Tests scheduling two animations to run together when only one property is free.
273 TEST(CCLayerAnimationControllerTest, ScheduleTogetherWhenAPropertyIsBlocked)
274 {
275     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
276     FakeLayerAnimationControllerClient dummy;
277     OwnPtr<CCLayerAnimationController> controller(
278         CCLayerAnimationController::create(&dummy));
279
280     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeTransformTransition(1)), 1, CCActiveAnimation::Transform));
281     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeTransformTransition(1)), 2, CCActiveAnimation::Transform));
282     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 2, CCActiveAnimation::Opacity));
283
284     controller->animate(0, events.get());
285     EXPECT_EQ(0, dummy.opacity());
286     EXPECT_TRUE(controller->hasActiveAnimation());
287     controller->animate(1, events.get());
288     // Should not have started the float transition yet.
289     EXPECT_TRUE(controller->hasActiveAnimation());
290     EXPECT_EQ(0, dummy.opacity());
291     // The float animation should have started at time 1 and should be done.
292     controller->animate(2, events.get());
293     EXPECT_EQ(1, dummy.opacity());
294     EXPECT_FALSE(controller->hasActiveAnimation());
295 }
296
297 // Tests scheduling two animations to run together with different lengths and another
298 // animation queued to start when the shorter animation finishes (should wait
299 // for both to finish).
300 TEST(CCLayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting)
301 {
302     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
303     FakeLayerAnimationControllerClient dummy;
304     OwnPtr<CCLayerAnimationController> controller(
305         CCLayerAnimationController::create(&dummy));
306
307     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeTransformTransition(2)), 1, CCActiveAnimation::Transform));
308     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
309     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 1, 0.5)), 2, CCActiveAnimation::Opacity));
310
311     // Animations with id 1 should both start now.
312     controller->animate(0, events.get());
313     EXPECT_TRUE(controller->hasActiveAnimation());
314     EXPECT_EQ(0, dummy.opacity());
315     // The opacity animation should have finished at time 1, but the group
316     // of animations with id 1 don't finish until time 2 because of the length
317     // of the transform animation.
318     controller->animate(2, events.get());
319     // Should not have started the float transition yet.
320     EXPECT_TRUE(controller->hasActiveAnimation());
321     EXPECT_EQ(1, dummy.opacity());
322
323     // The second opacity animation should start at time 2 and should be done by time 3
324     controller->animate(3, events.get());
325     EXPECT_EQ(0.5, dummy.opacity());
326     EXPECT_FALSE(controller->hasActiveAnimation());
327 }
328
329 // Tests scheduling an animation to start in the future.
330 TEST(CCLayerAnimationControllerTest, ScheduleAnimation)
331 {
332     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
333     FakeLayerAnimationControllerClient dummy;
334     OwnPtr<CCLayerAnimationController> controller(
335         CCLayerAnimationController::create(&dummy));
336
337     OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
338     toAdd->setRunState(CCActiveAnimation::WaitingForStartTime, 0);
339     toAdd->setStartTime(1);
340     controller->addAnimation(toAdd.release());
341
342     controller->animate(0, events.get());
343     EXPECT_TRUE(controller->hasActiveAnimation());
344     EXPECT_EQ(0, dummy.opacity());
345     controller->animate(1, events.get());
346     EXPECT_TRUE(controller->hasActiveAnimation());
347     EXPECT_EQ(0, dummy.opacity());
348     controller->animate(2, events.get());
349     EXPECT_EQ(1, dummy.opacity());
350     EXPECT_FALSE(controller->hasActiveAnimation());
351 }
352
353 // Tests scheduling an animation to start in the future that's interrupting a running animation.
354 TEST(CCLayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimation)
355 {
356     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
357     FakeLayerAnimationControllerClient dummy;
358     OwnPtr<CCLayerAnimationController> controller(
359         CCLayerAnimationController::create(&dummy));
360
361     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(2, 0, 1)), 1, CCActiveAnimation::Opacity));
362
363     OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0.5, 0)), 2, CCActiveAnimation::Opacity));
364     toAdd->setRunState(CCActiveAnimation::WaitingForStartTime, 0);
365     toAdd->setStartTime(1);
366     controller->addAnimation(toAdd.release());
367
368     // First 2s opacity transition should start immediately.
369     controller->animate(0, events.get());
370     EXPECT_TRUE(controller->hasActiveAnimation());
371     EXPECT_EQ(0, dummy.opacity());
372     controller->animate(0.5, events.get());
373     EXPECT_TRUE(controller->hasActiveAnimation());
374     EXPECT_EQ(0.25, dummy.opacity());
375     controller->animate(1, events.get());
376     EXPECT_TRUE(controller->hasActiveAnimation());
377     EXPECT_EQ(0.5, dummy.opacity());
378     controller->animate(2, events.get());
379     EXPECT_EQ(0, dummy.opacity());
380     EXPECT_FALSE(controller->hasActiveAnimation());
381 }
382
383 // Tests scheduling an animation to start in the future that interrupts a running animation
384 // and there is yet another animation queued to start later.
385 TEST(CCLayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimationWithAnimInQueue)
386 {
387     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
388     FakeLayerAnimationControllerClient dummy;
389     OwnPtr<CCLayerAnimationController> controller(
390         CCLayerAnimationController::create(&dummy));
391
392     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(2, 0, 1)), 1, CCActiveAnimation::Opacity));
393
394     OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(2, 0.5, 0)), 2, CCActiveAnimation::Opacity));
395     toAdd->setRunState(CCActiveAnimation::WaitingForStartTime, 0);
396     toAdd->setStartTime(1);
397     controller->addAnimation(toAdd.release());
398
399     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 0.75)), 3, CCActiveAnimation::Opacity));
400
401     // First 2s opacity transition should start immediately.
402     controller->animate(0, events.get());
403     EXPECT_TRUE(controller->hasActiveAnimation());
404     EXPECT_EQ(0, dummy.opacity());
405     controller->animate(0.5, events.get());
406     EXPECT_TRUE(controller->hasActiveAnimation());
407     EXPECT_EQ(0.25, dummy.opacity());
408     EXPECT_TRUE(controller->hasActiveAnimation());
409     controller->animate(1, events.get());
410     EXPECT_TRUE(controller->hasActiveAnimation());
411     EXPECT_EQ(0.5, dummy.opacity());
412     controller->animate(3, events.get());
413     EXPECT_TRUE(controller->hasActiveAnimation());
414     EXPECT_EQ(0, dummy.opacity());
415     controller->animate(4, events.get());
416     EXPECT_EQ(0.75, dummy.opacity());
417     EXPECT_FALSE(controller->hasActiveAnimation());
418 }
419
420 // Test that a looping animation loops and for the correct number of iterations.
421 TEST(CCLayerAnimationControllerTest, TrivialLooping)
422 {
423     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
424     FakeLayerAnimationControllerClient dummy;
425     OwnPtr<CCLayerAnimationController> controller(
426         CCLayerAnimationController::create(&dummy));
427
428     OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
429     toAdd->setIterations(3);
430     controller->addAnimation(toAdd.release());
431
432     controller->animate(0, events.get());
433     EXPECT_TRUE(controller->hasActiveAnimation());
434     EXPECT_EQ(0, dummy.opacity());
435     controller->animate(1.25, events.get());
436     EXPECT_TRUE(controller->hasActiveAnimation());
437     EXPECT_EQ(0.25, dummy.opacity());
438     controller->animate(1.75, events.get());
439     EXPECT_TRUE(controller->hasActiveAnimation());
440     EXPECT_EQ(0.75, dummy.opacity());
441     controller->animate(2.25, events.get());
442     EXPECT_TRUE(controller->hasActiveAnimation());
443     EXPECT_EQ(0.25, dummy.opacity());
444     controller->animate(2.75, events.get());
445     EXPECT_TRUE(controller->hasActiveAnimation());
446     EXPECT_EQ(0.75, dummy.opacity());
447     controller->animate(3, events.get());
448     EXPECT_FALSE(controller->hasActiveAnimation());
449     EXPECT_EQ(1, dummy.opacity());
450
451     // Just be extra sure.
452     controller->animate(4, events.get());
453     EXPECT_EQ(1, dummy.opacity());
454 }
455
456 // Test that an infinitely looping animation does indeed go until aborted.
457 TEST(CCLayerAnimationControllerTest, InfiniteLooping)
458 {
459     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
460     FakeLayerAnimationControllerClient dummy;
461     OwnPtr<CCLayerAnimationController> controller(
462         CCLayerAnimationController::create(&dummy));
463
464     const int id = 1;
465     OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), id, CCActiveAnimation::Opacity));
466     toAdd->setIterations(-1);
467     controller->addAnimation(toAdd.release());
468
469     controller->animate(0, events.get());
470     EXPECT_TRUE(controller->hasActiveAnimation());
471     EXPECT_EQ(0, dummy.opacity());
472     controller->animate(1.25, events.get());
473     EXPECT_TRUE(controller->hasActiveAnimation());
474     EXPECT_EQ(0.25, dummy.opacity());
475     controller->animate(1.75, events.get());
476     EXPECT_TRUE(controller->hasActiveAnimation());
477     EXPECT_EQ(0.75, dummy.opacity());
478
479     controller->animate(1073741824.25, events.get());
480     EXPECT_TRUE(controller->hasActiveAnimation());
481     EXPECT_EQ(0.25, dummy.opacity());
482     controller->animate(1073741824.75, events.get());
483     EXPECT_TRUE(controller->hasActiveAnimation());
484     EXPECT_EQ(0.75, dummy.opacity());
485
486     EXPECT_TRUE(controller->getActiveAnimation(id, CCActiveAnimation::Opacity));
487     controller->getActiveAnimation(id, CCActiveAnimation::Opacity)->setRunState(CCActiveAnimation::Aborted, 0.75);
488     EXPECT_FALSE(controller->hasActiveAnimation());
489     EXPECT_EQ(0.75, dummy.opacity());
490 }
491
492 // Test that pausing and resuming work as expected.
493 TEST(CCLayerAnimationControllerTest, PauseResume)
494 {
495     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
496     FakeLayerAnimationControllerClient dummy;
497     OwnPtr<CCLayerAnimationController> controller(
498         CCLayerAnimationController::create(&dummy));
499
500     const int id = 1;
501     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), id, CCActiveAnimation::Opacity));
502
503     controller->animate(0, events.get());
504     EXPECT_TRUE(controller->hasActiveAnimation());
505     EXPECT_EQ(0, dummy.opacity());
506     controller->animate(0.5, events.get());
507     EXPECT_TRUE(controller->hasActiveAnimation());
508     EXPECT_EQ(0.5, dummy.opacity());
509
510     EXPECT_TRUE(controller->getActiveAnimation(id, CCActiveAnimation::Opacity));
511     controller->getActiveAnimation(id, CCActiveAnimation::Opacity)->setRunState(CCActiveAnimation::Paused, 0.5);
512
513     controller->animate(1024, events.get());
514     EXPECT_TRUE(controller->hasActiveAnimation());
515     EXPECT_EQ(0.5, dummy.opacity());
516
517     EXPECT_TRUE(controller->getActiveAnimation(id, CCActiveAnimation::Opacity));
518     controller->getActiveAnimation(id, CCActiveAnimation::Opacity)->setRunState(CCActiveAnimation::Running, 1024);
519
520     controller->animate(1024.25, events.get());
521     EXPECT_TRUE(controller->hasActiveAnimation());
522     EXPECT_EQ(0.75, dummy.opacity());
523     controller->animate(1024.5, events.get());
524     EXPECT_FALSE(controller->hasActiveAnimation());
525     EXPECT_EQ(1, dummy.opacity());
526 }
527
528 TEST(CCLayerAnimationControllerTest, AbortAGroupedAnimation)
529 {
530     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
531     FakeLayerAnimationControllerClient dummy;
532     OwnPtr<CCLayerAnimationController> controller(
533         CCLayerAnimationController::create(&dummy));
534
535     const int id = 1;
536     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeTransformTransition(1)), id, CCActiveAnimation::Transform));
537     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(2, 0, 1)), id, CCActiveAnimation::Opacity));
538     controller->addAnimation(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 1, 0.75)), 2, CCActiveAnimation::Opacity));
539
540     controller->animate(0, events.get());
541     EXPECT_TRUE(controller->hasActiveAnimation());
542     EXPECT_EQ(0, dummy.opacity());
543     controller->animate(1, events.get());
544     EXPECT_TRUE(controller->hasActiveAnimation());
545     EXPECT_EQ(0.5, dummy.opacity());
546
547     EXPECT_TRUE(controller->getActiveAnimation(id, CCActiveAnimation::Opacity));
548     controller->getActiveAnimation(id, CCActiveAnimation::Opacity)->setRunState(CCActiveAnimation::Aborted, 1);
549     controller->animate(1, events.get());
550     EXPECT_TRUE(controller->hasActiveAnimation());
551     EXPECT_EQ(1, dummy.opacity());
552     controller->animate(2, events.get());
553     EXPECT_TRUE(!controller->hasActiveAnimation());
554     EXPECT_EQ(0.75, dummy.opacity());
555 }
556
557 TEST(CCLayerAnimationControllerTest, ForceSyncWhenSynchronizedStartTimeNeeded)
558 {
559     FakeLayerAnimationControllerClient dummyImpl;
560     OwnPtr<CCLayerAnimationController> controllerImpl(CCLayerAnimationController::create(&dummyImpl));
561     OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
562     FakeLayerAnimationControllerClient dummy;
563     OwnPtr<CCLayerAnimationController> controller(
564         CCLayerAnimationController::create(&dummy));
565
566     OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(2, 0, 1)), 0, CCActiveAnimation::Opacity));
567     toAdd->setNeedsSynchronizedStartTime(true);
568     controller->addAnimation(toAdd.release());
569
570     controller->animate(0, 0);
571     EXPECT_TRUE(controller->hasActiveAnimation());
572     CCActiveAnimation* activeAnimation = controller->getActiveAnimation(0, CCActiveAnimation::Opacity);
573     EXPECT_TRUE(activeAnimation);
574     EXPECT_TRUE(activeAnimation->needsSynchronizedStartTime());
575
576     controller->setForceSync();
577
578     controller->pushAnimationUpdatesTo(controllerImpl.get());
579
580     activeAnimation = controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity);
581     EXPECT_TRUE(activeAnimation);
582     EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, activeAnimation->runState());
583 }
584
585 } // namespace