Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Side by Side Diff: services/view_manager/animation_runner_unittest.cc

Issue 772893004: Adds constants and runner for animations (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Merge Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 "services/view_manager/animation_runner.h"
6
7 #include "base/strings/stringprintf.h"
8 #include "mojo/converters/geometry/geometry_type_converters.h"
9 #include "mojo/services/public/interfaces/view_manager/view_manager_constants.mo jom.h"
10 #include "services/view_manager/animation_runner_observer.h"
11 #include "services/view_manager/scheduled_animation_group.h"
12 #include "services/view_manager/server_view.h"
13 #include "services/view_manager/test_server_view_delegate.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace mojo {
17 namespace service {
18 namespace {
19
20 class TestAnimationRunnerObserver : public AnimationRunnerObserver {
21 public:
22 TestAnimationRunnerObserver() {}
23 ~TestAnimationRunnerObserver() override {}
24
25 std::vector<std::string>* changes() { return &changes_; }
26 std::vector<uint32_t>* change_ids() { return &change_ids_; }
27
28 void clear_changes() {
29 changes_.clear();
30 change_ids_.clear();
31 }
32
33 // AnimationRunnerDelgate:
34 void OnAnimationScheduled(const ServerView* view, uint32_t id) override {
35 change_ids_.push_back(id);
36 changes_.push_back(base::StringPrintf(
37 "scheduled view=%d,%d", view->id().connection_id, view->id().view_id));
38 }
39 void OnAnimationDone(const ServerView* view, uint32_t id) override {
40 change_ids_.push_back(id);
41 changes_.push_back(base::StringPrintf(
42 "done view=%d,%d", view->id().connection_id, view->id().view_id));
43 }
44 void OnAnimationInterrupted(const ServerView* view, uint32_t id) override {
45 change_ids_.push_back(id);
46 changes_.push_back(base::StringPrintf(
47 "interruped view=%d,%d", view->id().connection_id, view->id().view_id));
48 }
49 void OnAnimationCanceled(const ServerView* view, uint32_t id) override {
50 change_ids_.push_back(id);
51 changes_.push_back(base::StringPrintf(
52 "canceled view=%d,%d", view->id().connection_id, view->id().view_id));
53 }
54
55 private:
56 std::vector<uint32_t> change_ids_;
57 std::vector<std::string> changes_;
58
59 DISALLOW_COPY_AND_ASSIGN(TestAnimationRunnerObserver);
60 };
61
62 } // namespace
63
64 class AnimationRunnerTest : public testing::Test {
65 public:
66 AnimationRunnerTest()
67 : initial_time_(base::TimeTicks::Now()), runner_(initial_time_) {
68 runner_.AddObserver(&runner_observer_);
69 }
70 ~AnimationRunnerTest() override { runner_.RemoveObserver(&runner_observer_); }
71
72 protected:
73 const base::TimeTicks initial_time_;
74 TestAnimationRunnerObserver runner_observer_;
75 AnimationRunner runner_;
76
77 private:
78 DISALLOW_COPY_AND_ASSIGN(AnimationRunnerTest);
79 };
80
81 // Opacity from 1 to .5 over 1000.
82 TEST_F(AnimationRunnerTest, SingleProperty) {
83 TestServerViewDelegate view_delegate;
84 ServerView view(&view_delegate, ViewId());
85
86 AnimationGroup group;
87 group.view_id = ViewIdToTransportId(view.id());
88 group.sequences.push_back(AnimationSequence::New());
89 AnimationSequence& sequence = *(group.sequences[0]);
90 sequence.cycle_count = 1;
91 sequence.elements.push_back(AnimationElement::New());
92 AnimationElement& element = *(sequence.elements[0]);
93 element.property = ANIMATION_PROPERTY_OPACITY;
94 element.duration = 1000;
95 element.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
96 element.target_value = AnimationValue::New();
97 element.target_value->float_value = .5;
98
99 const uint32_t animation_id = runner_.Schedule(&view, group);
100
101 ASSERT_EQ(1u, runner_observer_.changes()->size());
102 EXPECT_EQ("scheduled view=0,0", runner_observer_.changes()->at(0));
103 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
104 runner_observer_.clear_changes();
105
106 EXPECT_TRUE(runner_.HasAnimations());
107
108 // Opacity should still be 1 (the initial value).
109 EXPECT_EQ(1.f, view.opacity());
110
111 // Animate half way.
112 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(500));
113
114 EXPECT_EQ(.75f, view.opacity());
115 EXPECT_TRUE(runner_observer_.changes()->empty());
116
117 // Run well past the end. Value should progress to end and delegate should
118 // be notified.
119 runner_.Tick(initial_time_ + base::TimeDelta::FromSeconds(10));
120 EXPECT_EQ(.5f, view.opacity());
121
122 ASSERT_EQ(1u, runner_observer_.changes()->size());
123 EXPECT_EQ("done view=0,0", runner_observer_.changes()->at(0));
124 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
125
126 EXPECT_FALSE(runner_.HasAnimations());
127 }
128
129 // Opacity from 1 to .5, followed by transform from identity to 2x,3x.
130 TEST_F(AnimationRunnerTest, TwoPropertiesInSequence) {
131 TestServerViewDelegate view_delegate;
132 ServerView view(&view_delegate, ViewId());
133
134 AnimationGroup group;
135 group.view_id = ViewIdToTransportId(view.id());
136 group.sequences.push_back(AnimationSequence::New());
137 AnimationSequence& sequence = *(group.sequences[0]);
138 sequence.cycle_count = 1;
139 sequence.elements.push_back(AnimationElement::New());
140 AnimationElement& element = *(sequence.elements[0]);
141 element.property = ANIMATION_PROPERTY_OPACITY;
142 element.duration = 1000;
143 element.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
144 element.target_value = AnimationValue::New();
145 element.target_value->float_value = .5;
146 sequence.elements.push_back(AnimationElement::New());
147 AnimationElement& element2 = *(sequence.elements[1]);
148 element2.property = ANIMATION_PROPERTY_TRANSFORM;
149 element2.duration = 2000;
150 element2.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
151 element2.target_value = AnimationValue::New();
152 gfx::Transform done_transform;
153 done_transform.Scale(2, 4);
154 element2.target_value->transform = Transform::From(done_transform);
155
156 const uint32_t animation_id = runner_.Schedule(&view, group);
157 runner_observer_.clear_changes();
158
159 // Nothing in the view should have changed yet.
160 EXPECT_EQ(1.f, view.opacity());
161 EXPECT_TRUE(view.transform().IsIdentity());
162
163 // Animate half way from through opacity animation.
164 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(500));
165
166 EXPECT_EQ(.75f, view.opacity());
167 EXPECT_TRUE(view.transform().IsIdentity());
168
169 // Finish first element (opacity).
170 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(1000));
171 EXPECT_EQ(.5f, view.opacity());
172 EXPECT_TRUE(view.transform().IsIdentity());
173
174 // Half way through second (transform).
175 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(2000));
176 EXPECT_EQ(.5f, view.opacity());
177 gfx::Transform half_way_transform;
178 half_way_transform.Scale(1.5, 2.5);
179 EXPECT_EQ(half_way_transform, view.transform());
180
181 EXPECT_TRUE(runner_observer_.changes()->empty());
182
183 // To end.
184 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(3500));
185 EXPECT_EQ(.5f, view.opacity());
186 EXPECT_EQ(done_transform, view.transform());
187
188 ASSERT_EQ(1u, runner_observer_.changes()->size());
189 EXPECT_EQ("done view=0,0", runner_observer_.changes()->at(0));
190 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
191 }
192
193 // Opacity from .5 to 1 over 1000, transform to 2x,3x over 500.
194 TEST_F(AnimationRunnerTest, TwoPropertiesInParallel) {
195 TestServerViewDelegate view_delegate;
196 ServerView view(&view_delegate, ViewId(1, 1));
197
198 AnimationGroup group;
199 group.view_id = ViewIdToTransportId(view.id());
200 group.sequences.push_back(AnimationSequence::New());
201 AnimationSequence& sequence = *(group.sequences[0]);
202 sequence.cycle_count = 1;
203 sequence.elements.push_back(AnimationElement::New());
204 AnimationElement& element = *(sequence.elements[0]);
205 element.property = ANIMATION_PROPERTY_OPACITY;
206 element.duration = 1000;
207 element.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
208 element.start_value = AnimationValue::New();
209 element.start_value->float_value = .5;
210 element.target_value = AnimationValue::New();
211 element.target_value->float_value = 1;
212 group.sequences.push_back(AnimationSequence::New());
213 AnimationSequence& sequence2 = *(group.sequences[1]);
214 sequence2.cycle_count = 1;
215 sequence2.elements.push_back(AnimationElement::New());
216 AnimationElement& element2 = *(sequence2.elements[0]);
217 element2.property = ANIMATION_PROPERTY_TRANSFORM;
218 element2.duration = 500;
219 element2.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
220 element2.target_value = AnimationValue::New();
221 gfx::Transform done_transform;
222 done_transform.Scale(2, 4);
223 element2.target_value->transform = Transform::From(done_transform);
224
225 const uint32_t animation_id = runner_.Schedule(&view, group);
226
227 runner_observer_.clear_changes();
228
229 // Nothing in the view should have changed yet.
230 EXPECT_EQ(1.f, view.opacity());
231 EXPECT_TRUE(view.transform().IsIdentity());
232
233 // Animate to 250, which is 1/4 way through opacity and half way through
234 // transform.
235 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(250));
236
237 EXPECT_EQ(.625f, view.opacity());
238 gfx::Transform half_way_transform;
239 half_way_transform.Scale(1.5, 2.5);
240 EXPECT_EQ(half_way_transform, view.transform());
241
242 // Animate to 500, which is 1/2 way through opacity and transform done.
243 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(500));
244 EXPECT_EQ(.75f, view.opacity());
245 EXPECT_EQ(done_transform, view.transform());
246
247 // Animate to 750, which is 3/4 way through opacity and transform done.
248 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(750));
249 EXPECT_EQ(.875f, view.opacity());
250 EXPECT_EQ(done_transform, view.transform());
251
252 EXPECT_TRUE(runner_observer_.changes()->empty());
253
254 // To end.
255 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(3500));
256 EXPECT_EQ(1.f, view.opacity());
257 EXPECT_EQ(done_transform, view.transform());
258
259 ASSERT_EQ(1u, runner_observer_.changes()->size());
260 EXPECT_EQ("done view=1,1", runner_observer_.changes()->at(0));
261 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
262 }
263
264 // Opacity from .5 to 1 over 1000, pause for 500, 1 to .5 over 500, with a cycle
265 // count of 3.
266 TEST_F(AnimationRunnerTest, Cycles) {
267 TestServerViewDelegate view_delegate;
268 ServerView view(&view_delegate, ViewId(1, 2));
269
270 view.SetOpacity(.5f);
271
272 AnimationGroup group;
273 group.view_id = ViewIdToTransportId(view.id());
274 group.sequences.push_back(AnimationSequence::New());
275 AnimationSequence& sequence = *(group.sequences[0]);
276 sequence.cycle_count = 3;
277 sequence.elements.push_back(AnimationElement::New());
278 AnimationElement& element = *(sequence.elements[0]);
279 element.property = ANIMATION_PROPERTY_OPACITY;
280 element.duration = 1000;
281 element.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
282 element.target_value = AnimationValue::New();
283 element.target_value->float_value = 1;
284 sequence.elements.push_back(AnimationElement::New());
285 AnimationElement& element2 = *(sequence.elements[1]);
286 element2.property = ANIMATION_PROPERTY_NONE;
287 element2.duration = 500;
288 sequence.elements.push_back(AnimationElement::New());
289 AnimationElement& element3 = *(sequence.elements[2]);
290 element3.property = ANIMATION_PROPERTY_OPACITY;
291 element3.duration = 500;
292 element3.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
293 element3.target_value = AnimationValue::New();
294 element3.target_value->float_value = .5f;
295
296 runner_.Schedule(&view, group);
297 runner_observer_.clear_changes();
298
299 // Nothing in the view should have changed yet.
300 EXPECT_EQ(.5f, view.opacity());
301
302 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(500));
303 EXPECT_EQ(.75f, view.opacity());
304
305 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(1250));
306 EXPECT_EQ(1.f, view.opacity());
307
308 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(1750));
309 EXPECT_EQ(.75f, view.opacity());
310
311 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(2500));
312 EXPECT_EQ(.75f, view.opacity());
313
314 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(3250));
315 EXPECT_EQ(1.f, view.opacity());
316
317 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(3750));
318 EXPECT_EQ(.75f, view.opacity());
319
320 // Animate to the end.
321 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(6500));
322 EXPECT_EQ(.5f, view.opacity());
323
324 ASSERT_EQ(1u, runner_observer_.changes()->size());
325 EXPECT_EQ("done view=1,2", runner_observer_.changes()->at(0));
326 }
327
328 // Verifies scheduling the same view twice sends an interrupt.
329 TEST_F(AnimationRunnerTest, ScheduleTwice) {
330 TestServerViewDelegate view_delegate;
331 ServerView view(&view_delegate, ViewId(1, 2));
332
333 AnimationGroup group;
334 group.view_id = ViewIdToTransportId(view.id());
335 group.sequences.push_back(AnimationSequence::New());
336 AnimationSequence& sequence = *(group.sequences[0]);
337 sequence.cycle_count = 1;
338 sequence.elements.push_back(AnimationElement::New());
339 AnimationElement& element = *(sequence.elements[0]);
340 element.property = ANIMATION_PROPERTY_OPACITY;
341 element.duration = 1000;
342 element.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
343 element.target_value = AnimationValue::New();
344 element.target_value->float_value = .5f;
345
346 const uint32_t animation_id = runner_.Schedule(&view, group);
347 runner_observer_.clear_changes();
348
349 // Animate half way.
350 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(500));
351
352 EXPECT_EQ(.75f, view.opacity());
353 EXPECT_TRUE(runner_observer_.changes()->empty());
354
355 // Schedule again. We should get an interrupt, but opacity shouldn't change.
356 const uint32_t animation2_id = runner_.Schedule(&view, group);
357
358 // Id should have changed.
359 EXPECT_NE(animation_id, animation2_id);
360
361 EXPECT_EQ(nullptr, runner_.GetViewForAnimation(animation_id));
362 EXPECT_EQ(&view, runner_.GetViewForAnimation(animation2_id));
363
364 EXPECT_EQ(.75f, view.opacity());
365 EXPECT_EQ(2u, runner_observer_.changes()->size());
366 EXPECT_EQ("interruped view=1,2", runner_observer_.changes()->at(0));
367 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
368 EXPECT_EQ("scheduled view=1,2", runner_observer_.changes()->at(1));
369 EXPECT_EQ(animation2_id, runner_observer_.change_ids()->at(1));
370 runner_observer_.clear_changes();
371
372 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(1000));
373 EXPECT_EQ(.625f, view.opacity());
374 EXPECT_TRUE(runner_observer_.changes()->empty());
375
376 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(2000));
377 EXPECT_EQ(.5f, view.opacity());
378 EXPECT_EQ(1u, runner_observer_.changes()->size());
379 EXPECT_EQ("done view=1,2", runner_observer_.changes()->at(0));
380 EXPECT_EQ(animation2_id, runner_observer_.change_ids()->at(0));
381 }
382
383 // Verifies Remove() works.
384 TEST_F(AnimationRunnerTest, CancelAnimationForView) {
385 // Create an animation and advance it part way.
386 TestServerViewDelegate view_delegate;
387 ServerView view(&view_delegate, ViewId());
388 AnimationGroup group;
389 group.view_id = ViewIdToTransportId(view.id());
390 group.sequences.push_back(AnimationSequence::New());
391 AnimationSequence& sequence = *(group.sequences[0]);
392 sequence.cycle_count = 1;
393 sequence.elements.push_back(AnimationElement::New());
394 AnimationElement& element = *(sequence.elements[0]);
395 element.property = ANIMATION_PROPERTY_OPACITY;
396 element.duration = 1000;
397 element.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
398 element.target_value = AnimationValue::New();
399 element.target_value->float_value = .5;
400
401 const uint32_t animation_id = runner_.Schedule(&view, group);
402 runner_observer_.clear_changes();
403 EXPECT_EQ(&view, runner_.GetViewForAnimation(animation_id));
404
405 EXPECT_TRUE(runner_.HasAnimations());
406
407 // Animate half way.
408 runner_.Tick(initial_time_ + base::TimeDelta::FromMicroseconds(500));
409 EXPECT_EQ(.75f, view.opacity());
410 EXPECT_TRUE(runner_observer_.changes()->empty());
411
412 // Cancel the animation.
413 runner_.CancelAnimationForView(&view);
414
415 EXPECT_FALSE(runner_.HasAnimations());
416 EXPECT_EQ(nullptr, runner_.GetViewForAnimation(animation_id));
417
418 EXPECT_EQ(.75f, view.opacity());
419
420 EXPECT_EQ(1u, runner_observer_.changes()->size());
421 EXPECT_EQ("canceled view=0,0", runner_observer_.changes()->at(0));
422 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
423 }
424
425 // Verifies a tick with a very large delta and a sequence that repeats forever
426 // doesn't take a long time.
427 TEST_F(AnimationRunnerTest, InfiniteRepeatWithHugeGap) {
428 TestServerViewDelegate view_delegate;
429 ServerView view(&view_delegate, ViewId(1, 2));
430
431 view.SetOpacity(.5f);
432
433 AnimationGroup group;
434 group.view_id = ViewIdToTransportId(view.id());
435 group.sequences.push_back(AnimationSequence::New());
436 AnimationSequence& sequence = *(group.sequences[0]);
437 sequence.cycle_count = 0; // Repeats forever.
438 sequence.elements.push_back(AnimationElement::New());
439 AnimationElement& element = *(sequence.elements[0]);
440 element.property = ANIMATION_PROPERTY_OPACITY;
441 element.duration = 500;
442 element.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
443 element.target_value = AnimationValue::New();
444 element.target_value->float_value = 1;
445 sequence.elements.push_back(AnimationElement::New());
446 AnimationElement& element2 = *(sequence.elements[1]);
447 element2.property = ANIMATION_PROPERTY_OPACITY;
448 element2.duration = 500;
449 element2.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
450 element2.target_value = AnimationValue::New();
451 element2.target_value->float_value = .5f;
452
453 runner_.Schedule(&view, group);
454 runner_observer_.clear_changes();
455
456 runner_.Tick(initial_time_ +
457 base::TimeDelta::FromMicroseconds(1000000000750));
458
459 EXPECT_EQ(.75f, view.opacity());
460
461 ASSERT_EQ(0u, runner_observer_.changes()->size());
462 }
463
464 // Verifies a second schedule sets any properties that are no longer animating
465 // to their final value.
466 TEST_F(AnimationRunnerTest, RescheduleSetsPropertiesToFinalValue) {
467 TestServerViewDelegate view_delegate;
468 ServerView view(&view_delegate, ViewId());
469
470 AnimationGroup group;
471 group.view_id = ViewIdToTransportId(view.id());
472 group.sequences.push_back(AnimationSequence::New());
473 AnimationSequence& sequence = *(group.sequences[0]);
474 sequence.cycle_count = 1;
475 sequence.elements.push_back(AnimationElement::New());
476 AnimationElement& element = *(sequence.elements[0]);
477 element.property = ANIMATION_PROPERTY_OPACITY;
478 element.duration = 1000;
479 element.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
480 element.target_value = AnimationValue::New();
481 element.target_value->float_value = .5;
482 sequence.elements.push_back(AnimationElement::New());
483 AnimationElement& element2 = *(sequence.elements[1]);
484 element2.property = ANIMATION_PROPERTY_TRANSFORM;
485 element2.duration = 500;
486 element2.tween_type = ANIMATION_TWEEN_TYPE_LINEAR;
487 element2.target_value = AnimationValue::New();
488 gfx::Transform done_transform;
489 done_transform.Scale(2, 4);
490 element2.target_value->transform = Transform::From(done_transform);
491 runner_.Schedule(&view, group);
492
493 // Schedule() again, this time without animating opacity.
494 element.property = ANIMATION_PROPERTY_NONE;
495 runner_.Schedule(&view, group);
496
497 // Opacity should go to final value.
498 EXPECT_EQ(.5f, view.opacity());
499 // Transform shouldn't have changed since newly scheduled animation also has
500 // transform in it.
501 EXPECT_TRUE(view.transform().IsIdentity());
502 }
503
504 } // namespace service
505 } // namespace mojo
OLDNEW
« no previous file with comments | « services/view_manager/animation_runner_observer.h ('k') | services/view_manager/scheduled_animation_group.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698