OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2013, 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 are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include "core/animation/AnimationTimeline.h" | |
32 | |
33 #include "core/animation/AnimationClock.h" | |
34 #include "core/animation/AnimationEffectReadOnly.h" | |
35 #include "core/animation/CompositorPendingAnimations.h" | |
36 #include "core/animation/KeyframeEffect.h" | |
37 #include "core/animation/KeyframeEffectModel.h" | |
38 #include "core/dom/Document.h" | |
39 #include "core/dom/Element.h" | |
40 #include "core/dom/QualifiedName.h" | |
41 #include "core/testing/DummyPageHolder.h" | |
42 #include "platform/weborigin/KURL.h" | |
43 #include "testing/gmock/include/gmock/gmock.h" | |
44 #include "testing/gtest/include/gtest/gtest.h" | |
45 #include <memory> | |
46 | |
47 namespace blink { | |
48 | |
49 class MockPlatformTiming : public AnimationTimeline::PlatformTiming { | |
50 public: | |
51 MOCK_METHOD1(WakeAfter, void(double)); | |
52 MOCK_METHOD0(ServiceOnNextFrame, void()); | |
53 | |
54 DEFINE_INLINE_TRACE() { AnimationTimeline::PlatformTiming::Trace(visitor); } | |
55 }; | |
56 | |
57 class AnimationAnimationTimelineTest : public ::testing::Test { | |
58 protected: | |
59 virtual void SetUp() { | |
60 page_holder = DummyPageHolder::Create(); | |
61 document = &page_holder->GetDocument(); | |
62 document->GetAnimationClock().ResetTimeForTesting(); | |
63 element = Element::Create(QualifiedName::Null(), document.Get()); | |
64 platform_timing = new MockPlatformTiming; | |
65 timeline = AnimationTimeline::Create(document.Get(), platform_timing); | |
66 timeline->ResetForTesting(); | |
67 ASSERT_EQ(0, timeline->CurrentTimeInternal()); | |
68 } | |
69 | |
70 virtual void TearDown() { | |
71 document.Release(); | |
72 element.Release(); | |
73 timeline.Release(); | |
74 ThreadState::Current()->CollectAllGarbage(); | |
75 } | |
76 | |
77 void UpdateClockAndService(double time) { | |
78 document->GetAnimationClock().UpdateTime(time); | |
79 document->GetCompositorPendingAnimations().Update( | |
80 Optional<CompositorElementIdSet>(), false); | |
81 timeline->ServiceAnimations(kTimingUpdateForAnimationFrame); | |
82 timeline->ScheduleNextService(); | |
83 } | |
84 | |
85 std::unique_ptr<DummyPageHolder> page_holder; | |
86 Persistent<Document> document; | |
87 Persistent<Element> element; | |
88 Persistent<AnimationTimeline> timeline; | |
89 Timing timing; | |
90 Persistent<MockPlatformTiming> platform_timing; | |
91 | |
92 void Wake() { timeline->Wake(); } | |
93 | |
94 double MinimumDelay() { return AnimationTimeline::kMinimumDelay; } | |
95 }; | |
96 | |
97 TEST_F(AnimationAnimationTimelineTest, EmptyKeyframeAnimation) { | |
98 AnimatableValueKeyframeEffectModel* effect = | |
99 AnimatableValueKeyframeEffectModel::Create( | |
100 AnimatableValueKeyframeVector()); | |
101 KeyframeEffect* keyframe_effect = | |
102 KeyframeEffect::Create(element.Get(), effect, timing); | |
103 | |
104 timeline->Play(keyframe_effect); | |
105 | |
106 UpdateClockAndService(0); | |
107 EXPECT_FLOAT_EQ(0, timeline->CurrentTimeInternal()); | |
108 EXPECT_FALSE(keyframe_effect->IsInEffect()); | |
109 | |
110 UpdateClockAndService(100); | |
111 EXPECT_FLOAT_EQ(100, timeline->CurrentTimeInternal()); | |
112 } | |
113 | |
114 TEST_F(AnimationAnimationTimelineTest, EmptyForwardsKeyframeAnimation) { | |
115 AnimatableValueKeyframeEffectModel* effect = | |
116 AnimatableValueKeyframeEffectModel::Create( | |
117 AnimatableValueKeyframeVector()); | |
118 timing.fill_mode = Timing::FillMode::FORWARDS; | |
119 KeyframeEffect* keyframe_effect = | |
120 KeyframeEffect::Create(element.Get(), effect, timing); | |
121 | |
122 timeline->Play(keyframe_effect); | |
123 | |
124 UpdateClockAndService(0); | |
125 EXPECT_FLOAT_EQ(0, timeline->CurrentTimeInternal()); | |
126 EXPECT_TRUE(keyframe_effect->IsInEffect()); | |
127 | |
128 UpdateClockAndService(100); | |
129 EXPECT_FLOAT_EQ(100, timeline->CurrentTimeInternal()); | |
130 } | |
131 | |
132 TEST_F(AnimationAnimationTimelineTest, ZeroTime) { | |
133 bool is_null; | |
134 | |
135 document->GetAnimationClock().UpdateTime(100); | |
136 EXPECT_EQ(100, timeline->CurrentTimeInternal()); | |
137 EXPECT_EQ(100, timeline->CurrentTimeInternal(is_null)); | |
138 EXPECT_FALSE(is_null); | |
139 | |
140 document->GetAnimationClock().UpdateTime(200); | |
141 EXPECT_EQ(200, timeline->CurrentTimeInternal()); | |
142 EXPECT_EQ(200, timeline->CurrentTimeInternal(is_null)); | |
143 EXPECT_FALSE(is_null); | |
144 } | |
145 | |
146 TEST_F(AnimationAnimationTimelineTest, PlaybackRateNormal) { | |
147 double zero_time = timeline->ZeroTime(); | |
148 bool is_null; | |
149 | |
150 timeline->SetPlaybackRate(1.0); | |
151 EXPECT_EQ(1.0, timeline->PlaybackRate()); | |
152 document->GetAnimationClock().UpdateTime(100); | |
153 EXPECT_EQ(zero_time, timeline->ZeroTime()); | |
154 EXPECT_EQ(100, timeline->CurrentTimeInternal()); | |
155 EXPECT_EQ(100, timeline->CurrentTimeInternal(is_null)); | |
156 EXPECT_FALSE(is_null); | |
157 | |
158 document->GetAnimationClock().UpdateTime(200); | |
159 EXPECT_EQ(zero_time, timeline->ZeroTime()); | |
160 EXPECT_EQ(200, timeline->CurrentTimeInternal()); | |
161 EXPECT_EQ(200, timeline->CurrentTimeInternal(is_null)); | |
162 EXPECT_FALSE(is_null); | |
163 } | |
164 | |
165 TEST_F(AnimationAnimationTimelineTest, PlaybackRatePause) { | |
166 bool is_null; | |
167 | |
168 document->GetAnimationClock().UpdateTime(100); | |
169 EXPECT_EQ(0, timeline->ZeroTime()); | |
170 EXPECT_EQ(100, timeline->CurrentTimeInternal()); | |
171 EXPECT_EQ(100, timeline->CurrentTimeInternal(is_null)); | |
172 EXPECT_FALSE(is_null); | |
173 | |
174 timeline->SetPlaybackRate(0.0); | |
175 EXPECT_EQ(0.0, timeline->PlaybackRate()); | |
176 document->GetAnimationClock().UpdateTime(200); | |
177 EXPECT_EQ(100, timeline->ZeroTime()); | |
178 EXPECT_EQ(100, timeline->CurrentTimeInternal()); | |
179 EXPECT_EQ(100, timeline->CurrentTimeInternal(is_null)); | |
180 | |
181 timeline->SetPlaybackRate(1.0); | |
182 EXPECT_EQ(1.0, timeline->PlaybackRate()); | |
183 document->GetAnimationClock().UpdateTime(400); | |
184 EXPECT_EQ(100, timeline->ZeroTime()); | |
185 EXPECT_EQ(300, timeline->CurrentTimeInternal()); | |
186 EXPECT_EQ(300, timeline->CurrentTimeInternal(is_null)); | |
187 | |
188 EXPECT_FALSE(is_null); | |
189 } | |
190 | |
191 TEST_F(AnimationAnimationTimelineTest, PlaybackRateSlow) { | |
192 bool is_null; | |
193 | |
194 document->GetAnimationClock().UpdateTime(100); | |
195 EXPECT_EQ(0, timeline->ZeroTime()); | |
196 EXPECT_EQ(100, timeline->CurrentTimeInternal()); | |
197 EXPECT_EQ(100, timeline->CurrentTimeInternal(is_null)); | |
198 EXPECT_FALSE(is_null); | |
199 | |
200 timeline->SetPlaybackRate(0.5); | |
201 EXPECT_EQ(0.5, timeline->PlaybackRate()); | |
202 document->GetAnimationClock().UpdateTime(300); | |
203 EXPECT_EQ(-100, timeline->ZeroTime()); | |
204 EXPECT_EQ(200, timeline->CurrentTimeInternal()); | |
205 EXPECT_EQ(200, timeline->CurrentTimeInternal(is_null)); | |
206 | |
207 timeline->SetPlaybackRate(1.0); | |
208 EXPECT_EQ(1.0, timeline->PlaybackRate()); | |
209 document->GetAnimationClock().UpdateTime(400); | |
210 EXPECT_EQ(100, timeline->ZeroTime()); | |
211 EXPECT_EQ(300, timeline->CurrentTimeInternal()); | |
212 EXPECT_EQ(300, timeline->CurrentTimeInternal(is_null)); | |
213 | |
214 EXPECT_FALSE(is_null); | |
215 } | |
216 | |
217 TEST_F(AnimationAnimationTimelineTest, PlaybackRateFast) { | |
218 bool is_null; | |
219 | |
220 document->GetAnimationClock().UpdateTime(100); | |
221 EXPECT_EQ(0, timeline->ZeroTime()); | |
222 EXPECT_EQ(100, timeline->CurrentTimeInternal()); | |
223 EXPECT_EQ(100, timeline->CurrentTimeInternal(is_null)); | |
224 EXPECT_FALSE(is_null); | |
225 | |
226 timeline->SetPlaybackRate(2.0); | |
227 EXPECT_EQ(2.0, timeline->PlaybackRate()); | |
228 document->GetAnimationClock().UpdateTime(300); | |
229 EXPECT_EQ(50, timeline->ZeroTime()); | |
230 EXPECT_EQ(500, timeline->CurrentTimeInternal()); | |
231 EXPECT_EQ(500, timeline->CurrentTimeInternal(is_null)); | |
232 | |
233 timeline->SetPlaybackRate(1.0); | |
234 EXPECT_EQ(1.0, timeline->PlaybackRate()); | |
235 document->GetAnimationClock().UpdateTime(400); | |
236 EXPECT_EQ(-200, timeline->ZeroTime()); | |
237 EXPECT_EQ(600, timeline->CurrentTimeInternal()); | |
238 EXPECT_EQ(600, timeline->CurrentTimeInternal(is_null)); | |
239 | |
240 EXPECT_FALSE(is_null); | |
241 } | |
242 | |
243 TEST_F(AnimationAnimationTimelineTest, PauseForTesting) { | |
244 float seek_time = 1; | |
245 timing.fill_mode = Timing::FillMode::FORWARDS; | |
246 KeyframeEffect* anim1 = | |
247 KeyframeEffect::Create(element.Get(), | |
248 AnimatableValueKeyframeEffectModel::Create( | |
249 AnimatableValueKeyframeVector()), | |
250 timing); | |
251 KeyframeEffect* anim2 = | |
252 KeyframeEffect::Create(element.Get(), | |
253 AnimatableValueKeyframeEffectModel::Create( | |
254 AnimatableValueKeyframeVector()), | |
255 timing); | |
256 Animation* animation1 = timeline->Play(anim1); | |
257 Animation* animation2 = timeline->Play(anim2); | |
258 timeline->PauseAnimationsForTesting(seek_time); | |
259 | |
260 EXPECT_FLOAT_EQ(seek_time, animation1->CurrentTimeInternal()); | |
261 EXPECT_FLOAT_EQ(seek_time, animation2->CurrentTimeInternal()); | |
262 } | |
263 | |
264 TEST_F(AnimationAnimationTimelineTest, DelayBeforeAnimationStart) { | |
265 timing.iteration_duration = 2; | |
266 timing.start_delay = 5; | |
267 | |
268 KeyframeEffect* keyframe_effect = | |
269 KeyframeEffect::Create(element.Get(), nullptr, timing); | |
270 | |
271 timeline->Play(keyframe_effect); | |
272 | |
273 // TODO: Put the animation startTime in the future when we add the capability | |
274 // to change animation startTime | |
275 EXPECT_CALL(*platform_timing, WakeAfter(timing.start_delay - MinimumDelay())); | |
276 UpdateClockAndService(0); | |
277 | |
278 EXPECT_CALL(*platform_timing, | |
279 WakeAfter(timing.start_delay - MinimumDelay() - 1.5)); | |
280 UpdateClockAndService(1.5); | |
281 | |
282 EXPECT_CALL(*platform_timing, ServiceOnNextFrame()); | |
283 Wake(); | |
284 | |
285 EXPECT_CALL(*platform_timing, ServiceOnNextFrame()); | |
286 UpdateClockAndService(4.98); | |
287 } | |
288 | |
289 TEST_F(AnimationAnimationTimelineTest, UseAnimationAfterTimelineDeref) { | |
290 Animation* animation = timeline->Play(0); | |
291 timeline.Clear(); | |
292 // Test passes if this does not crash. | |
293 animation->setStartTime(0, false); | |
294 } | |
295 | |
296 } // namespace blink | |
OLD | NEW |