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

Side by Side Diff: components/mus/ws/animation_runner_unittest.cc

Issue 2119963002: Move mus to //services/ui (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 5 months 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
« no previous file with comments | « components/mus/ws/animation_runner_observer.h ('k') | components/mus/ws/cursor_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "components/mus/ws/animation_runner.h"
6
7 #include "base/strings/stringprintf.h"
8 #include "components/mus/public/interfaces/window_manager_constants.mojom.h"
9 #include "components/mus/ws/animation_runner_observer.h"
10 #include "components/mus/ws/scheduled_animation_group.h"
11 #include "components/mus/ws/server_window.h"
12 #include "components/mus/ws/test_server_window_delegate.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 using base::TimeDelta;
16
17 namespace mus {
18 using mojom::AnimationProperty;
19 using mojom::AnimationTweenType;
20 using mojom::AnimationElement;
21 using mojom::AnimationGroup;
22 using mojom::AnimationProperty;
23 using mojom::AnimationSequence;
24 using mojom::AnimationTweenType;
25 using mojom::AnimationValue;
26 using mojom::AnimationValuePtr;
27
28 namespace ws {
29 namespace {
30
31 class TestAnimationRunnerObserver : public AnimationRunnerObserver {
32 public:
33 TestAnimationRunnerObserver() {}
34 ~TestAnimationRunnerObserver() override {}
35
36 std::vector<std::string>* changes() { return &changes_; }
37 std::vector<uint32_t>* change_ids() { return &change_ids_; }
38
39 void clear_changes() {
40 changes_.clear();
41 change_ids_.clear();
42 }
43
44 // AnimationRunnerDelgate:
45 void OnAnimationScheduled(uint32_t id) override {
46 change_ids_.push_back(id);
47 changes_.push_back("scheduled");
48 }
49 void OnAnimationDone(uint32_t id) override {
50 change_ids_.push_back(id);
51 changes_.push_back("done");
52 }
53 void OnAnimationInterrupted(uint32_t id) override {
54 change_ids_.push_back(id);
55 changes_.push_back("interrupted");
56 }
57 void OnAnimationCanceled(uint32_t id) override {
58 change_ids_.push_back(id);
59 changes_.push_back("canceled");
60 }
61
62 private:
63 std::vector<uint32_t> change_ids_;
64 std::vector<std::string> changes_;
65
66 DISALLOW_COPY_AND_ASSIGN(TestAnimationRunnerObserver);
67 };
68
69 // Creates an AnimationValuePtr from the specified float value.
70 AnimationValuePtr FloatAnimationValue(float float_value) {
71 AnimationValuePtr value(AnimationValue::New());
72 value->float_value = float_value;
73 return value;
74 }
75
76 // Creates an AnimationValuePtr from the specified transform.
77 AnimationValuePtr TransformAnimationValue(const gfx::Transform& transform) {
78 AnimationValuePtr value(AnimationValue::New());
79 value->transform = transform;
80 return value;
81 }
82
83 // Adds an AnimationElement to |group|s last sequence with the specified value.
84 void AddElement(AnimationGroup* group,
85 TimeDelta time,
86 AnimationValuePtr start_value,
87 AnimationValuePtr target_value,
88 AnimationProperty property,
89 AnimationTweenType tween_type) {
90 AnimationSequence& sequence =
91 *(group->sequences[group->sequences.size() - 1]);
92 sequence.elements.push_back(AnimationElement::New());
93 AnimationElement& element =
94 *(sequence.elements[sequence.elements.size() - 1]);
95 element.property = property;
96 element.duration = time.InMicroseconds();
97 element.tween_type = tween_type;
98 element.start_value = std::move(start_value);
99 element.target_value = std::move(target_value);
100 }
101
102 void AddOpacityElement(AnimationGroup* group,
103 TimeDelta time,
104 AnimationValuePtr start_value,
105 AnimationValuePtr target_value) {
106 AddElement(group, time, std::move(start_value), std::move(target_value),
107 AnimationProperty::OPACITY, AnimationTweenType::LINEAR);
108 }
109
110 void AddTransformElement(AnimationGroup* group,
111 TimeDelta time,
112 AnimationValuePtr start_value,
113 AnimationValuePtr target_value) {
114 AddElement(group, time, std::move(start_value), std::move(target_value),
115 AnimationProperty::TRANSFORM, AnimationTweenType::LINEAR);
116 }
117
118 void AddPauseElement(AnimationGroup* group, TimeDelta time) {
119 AddElement(group, time, AnimationValuePtr(), AnimationValuePtr(),
120 AnimationProperty::NONE, AnimationTweenType::LINEAR);
121 }
122
123 void InitGroupForWindow(AnimationGroup* group,
124 const WindowId& id,
125 int cycle_count) {
126 group->window_id = WindowIdToTransportId(id);
127 group->sequences.push_back(AnimationSequence::New());
128 group->sequences[group->sequences.size() - 1]->cycle_count = cycle_count;
129 }
130
131 } // namespace
132
133 class AnimationRunnerTest : public testing::Test {
134 public:
135 AnimationRunnerTest()
136 : initial_time_(base::TimeTicks::Now()), runner_(initial_time_) {
137 runner_.AddObserver(&runner_observer_);
138 }
139 ~AnimationRunnerTest() override { runner_.RemoveObserver(&runner_observer_); }
140
141 protected:
142 // Convenience to schedule an animation for a single window/group pair.
143 AnimationRunner::AnimationId ScheduleForSingleWindow(
144 ServerWindow* window,
145 const AnimationGroup* group,
146 base::TimeTicks now) {
147 std::vector<AnimationRunner::WindowAndAnimationPair> pairs;
148 pairs.push_back(std::make_pair(window, group));
149 return runner_.Schedule(pairs, now);
150 }
151
152 // If |id| is valid and there is only one window schedule against the
153 // animation it is returned; otherwise returns null.
154 ServerWindow* GetSingleWindowAnimating(AnimationRunner::AnimationId id) {
155 std::set<ServerWindow*> windows(runner_.GetWindowsAnimating(id));
156 return windows.size() == 1 ? *windows.begin() : nullptr;
157 }
158
159 const base::TimeTicks initial_time_;
160 TestAnimationRunnerObserver runner_observer_;
161 AnimationRunner runner_;
162
163 private:
164 DISALLOW_COPY_AND_ASSIGN(AnimationRunnerTest);
165 };
166
167 // Opacity from 1 to .5 over 1000.
168 TEST_F(AnimationRunnerTest, SingleProperty) {
169 TestServerWindowDelegate window_delegate;
170 ServerWindow window(&window_delegate, WindowId());
171
172 AnimationGroup group;
173 InitGroupForWindow(&group, window.id(), 1);
174 AddOpacityElement(&group, TimeDelta::FromMicroseconds(1000),
175 AnimationValuePtr(), FloatAnimationValue(.5));
176
177 const uint32_t animation_id =
178 ScheduleForSingleWindow(&window, &group, initial_time_);
179
180 ASSERT_EQ(1u, runner_observer_.changes()->size());
181 EXPECT_EQ("scheduled", runner_observer_.changes()->at(0));
182 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
183 runner_observer_.clear_changes();
184
185 EXPECT_TRUE(runner_.HasAnimations());
186
187 // Opacity should still be 1 (the initial value).
188 EXPECT_EQ(1.f, window.opacity());
189
190 // Animate half way.
191 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(500));
192
193 EXPECT_EQ(.75f, window.opacity());
194 EXPECT_TRUE(runner_observer_.changes()->empty());
195
196 // Run well past the end. Value should progress to end and delegate should
197 // be notified.
198 runner_.Tick(initial_time_ + TimeDelta::FromSeconds(10));
199 EXPECT_EQ(.5f, window.opacity());
200
201 ASSERT_EQ(1u, runner_observer_.changes()->size());
202 EXPECT_EQ("done", runner_observer_.changes()->at(0));
203 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
204
205 EXPECT_FALSE(runner_.HasAnimations());
206 }
207
208 // Opacity from 1 to .5, followed by transform from identity to 2x,3x.
209 TEST_F(AnimationRunnerTest, TwoPropertiesInSequence) {
210 TestServerWindowDelegate window_delegate;
211 ServerWindow window(&window_delegate, WindowId());
212
213 AnimationGroup group;
214 InitGroupForWindow(&group, window.id(), 1);
215 AddOpacityElement(&group, TimeDelta::FromMicroseconds(1000),
216 AnimationValuePtr(), FloatAnimationValue(.5f));
217
218 gfx::Transform done_transform;
219 done_transform.Scale(2, 4);
220 AddTransformElement(&group, TimeDelta::FromMicroseconds(2000),
221 AnimationValuePtr(),
222 TransformAnimationValue(done_transform));
223
224 const uint32_t animation_id =
225 ScheduleForSingleWindow(&window, &group, initial_time_);
226 runner_observer_.clear_changes();
227
228 // Nothing in the window should have changed yet.
229 EXPECT_EQ(1.f, window.opacity());
230 EXPECT_TRUE(window.transform().IsIdentity());
231
232 // Animate half way from through opacity animation.
233 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(500));
234
235 EXPECT_EQ(.75f, window.opacity());
236 EXPECT_TRUE(window.transform().IsIdentity());
237
238 // Finish first element (opacity).
239 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(1000));
240 EXPECT_EQ(.5f, window.opacity());
241 EXPECT_TRUE(window.transform().IsIdentity());
242
243 // Half way through second (transform).
244 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(2000));
245 EXPECT_EQ(.5f, window.opacity());
246 gfx::Transform half_way_transform;
247 half_way_transform.Scale(1.5, 2.5);
248 EXPECT_EQ(half_way_transform, window.transform());
249
250 EXPECT_TRUE(runner_observer_.changes()->empty());
251
252 // To end.
253 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(3500));
254 EXPECT_EQ(.5f, window.opacity());
255 EXPECT_EQ(done_transform, window.transform());
256
257 ASSERT_EQ(1u, runner_observer_.changes()->size());
258 EXPECT_EQ("done", runner_observer_.changes()->at(0));
259 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
260 }
261
262 // Opacity from .5 to 1 over 1000, transform to 2x,4x over 500.
263 TEST_F(AnimationRunnerTest, TwoPropertiesInParallel) {
264 TestServerWindowDelegate window_delegate;
265 ServerWindow window(&window_delegate, WindowId(1, 1));
266
267 AnimationGroup group;
268 InitGroupForWindow(&group, window.id(), 1);
269 AddOpacityElement(&group, TimeDelta::FromMicroseconds(1000),
270 FloatAnimationValue(.5f), FloatAnimationValue(1));
271
272 group.sequences.push_back(AnimationSequence::New());
273 group.sequences[1]->cycle_count = 1;
274 gfx::Transform done_transform;
275 done_transform.Scale(2, 4);
276 AddTransformElement(&group, TimeDelta::FromMicroseconds(500),
277 AnimationValuePtr(),
278 TransformAnimationValue(done_transform));
279
280 const uint32_t animation_id =
281 ScheduleForSingleWindow(&window, &group, initial_time_);
282
283 runner_observer_.clear_changes();
284
285 // Nothing in the window should have changed yet.
286 EXPECT_EQ(1.f, window.opacity());
287 EXPECT_TRUE(window.transform().IsIdentity());
288
289 // Animate to 250, which is 1/4 way through opacity and half way through
290 // transform.
291 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(250));
292
293 EXPECT_EQ(.625f, window.opacity());
294 gfx::Transform half_way_transform;
295 half_way_transform.Scale(1.5, 2.5);
296 EXPECT_EQ(half_way_transform, window.transform());
297
298 // Animate to 500, which is 1/2 way through opacity and transform done.
299 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(500));
300 EXPECT_EQ(.75f, window.opacity());
301 EXPECT_EQ(done_transform, window.transform());
302
303 // Animate to 750, which is 3/4 way through opacity and transform done.
304 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(750));
305 EXPECT_EQ(.875f, window.opacity());
306 EXPECT_EQ(done_transform, window.transform());
307
308 EXPECT_TRUE(runner_observer_.changes()->empty());
309
310 // To end.
311 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(3500));
312 EXPECT_EQ(1.f, window.opacity());
313 EXPECT_EQ(done_transform, window.transform());
314
315 ASSERT_EQ(1u, runner_observer_.changes()->size());
316 EXPECT_EQ("done", runner_observer_.changes()->at(0));
317 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
318 }
319
320 // Opacity from .5 to 1 over 1000, pause for 500, 1 to .5 over 500, with a cycle
321 // count of 3.
322 TEST_F(AnimationRunnerTest, Cycles) {
323 TestServerWindowDelegate window_delegate;
324 ServerWindow window(&window_delegate, WindowId(1, 2));
325
326 window.SetOpacity(.5f);
327
328 AnimationGroup group;
329 InitGroupForWindow(&group, window.id(), 3);
330 AddOpacityElement(&group, TimeDelta::FromMicroseconds(1000),
331 AnimationValuePtr(), FloatAnimationValue(1));
332 AddPauseElement(&group, TimeDelta::FromMicroseconds(500));
333 AddOpacityElement(&group, TimeDelta::FromMicroseconds(500),
334 AnimationValuePtr(), FloatAnimationValue(.5));
335
336 ScheduleForSingleWindow(&window, &group, initial_time_);
337 runner_observer_.clear_changes();
338
339 // Nothing in the window should have changed yet.
340 EXPECT_EQ(.5f, window.opacity());
341
342 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(500));
343 EXPECT_EQ(.75f, window.opacity());
344
345 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(1250));
346 EXPECT_EQ(1.f, window.opacity());
347
348 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(1750));
349 EXPECT_EQ(.75f, window.opacity());
350
351 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(2500));
352 EXPECT_EQ(.75f, window.opacity());
353
354 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(3250));
355 EXPECT_EQ(1.f, window.opacity());
356
357 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(3750));
358 EXPECT_EQ(.75f, window.opacity());
359
360 // Animate to the end.
361 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(6500));
362 EXPECT_EQ(.5f, window.opacity());
363
364 ASSERT_EQ(1u, runner_observer_.changes()->size());
365 EXPECT_EQ("done", runner_observer_.changes()->at(0));
366 }
367
368 // Verifies scheduling the same window twice sends an interrupt.
369 TEST_F(AnimationRunnerTest, ScheduleTwice) {
370 TestServerWindowDelegate window_delegate;
371 ServerWindow window(&window_delegate, WindowId(1, 2));
372
373 AnimationGroup group;
374 InitGroupForWindow(&group, window.id(), 1);
375 AddOpacityElement(&group, TimeDelta::FromMicroseconds(1000),
376 AnimationValuePtr(), FloatAnimationValue(.5));
377
378 const uint32_t animation_id =
379 ScheduleForSingleWindow(&window, &group, initial_time_);
380 runner_observer_.clear_changes();
381
382 // Animate half way.
383 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(500));
384
385 EXPECT_EQ(.75f, window.opacity());
386 EXPECT_TRUE(runner_observer_.changes()->empty());
387
388 // Schedule again. We should get an interrupt, but opacity shouldn't change.
389 const uint32_t animation2_id = ScheduleForSingleWindow(
390 &window, &group, initial_time_ + TimeDelta::FromMicroseconds(500));
391
392 // Id should have changed.
393 EXPECT_NE(animation_id, animation2_id);
394
395 EXPECT_FALSE(runner_.IsAnimating(animation_id));
396 EXPECT_EQ(&window, GetSingleWindowAnimating(animation2_id));
397
398 EXPECT_EQ(.75f, window.opacity());
399 EXPECT_EQ(2u, runner_observer_.changes()->size());
400 EXPECT_EQ("interrupted", runner_observer_.changes()->at(0));
401 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
402 EXPECT_EQ("scheduled", runner_observer_.changes()->at(1));
403 EXPECT_EQ(animation2_id, runner_observer_.change_ids()->at(1));
404 runner_observer_.clear_changes();
405
406 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(1000));
407 EXPECT_EQ(.625f, window.opacity());
408 EXPECT_TRUE(runner_observer_.changes()->empty());
409
410 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(2000));
411 EXPECT_EQ(.5f, window.opacity());
412 EXPECT_EQ(1u, runner_observer_.changes()->size());
413 EXPECT_EQ("done", runner_observer_.changes()->at(0));
414 EXPECT_EQ(animation2_id, runner_observer_.change_ids()->at(0));
415 }
416
417 // Verifies Remove() works.
418 TEST_F(AnimationRunnerTest, CancelAnimationForWindow) {
419 // Create an animation and advance it part way.
420 TestServerWindowDelegate window_delegate;
421 ServerWindow window(&window_delegate, WindowId());
422 AnimationGroup group;
423 InitGroupForWindow(&group, window.id(), 1);
424 AddOpacityElement(&group, TimeDelta::FromMicroseconds(1000),
425 AnimationValuePtr(), FloatAnimationValue(.5));
426
427 const uint32_t animation_id =
428 ScheduleForSingleWindow(&window, &group, initial_time_);
429 runner_observer_.clear_changes();
430 EXPECT_EQ(&window, GetSingleWindowAnimating(animation_id));
431
432 EXPECT_TRUE(runner_.HasAnimations());
433
434 // Animate half way.
435 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(500));
436 EXPECT_EQ(.75f, window.opacity());
437 EXPECT_TRUE(runner_observer_.changes()->empty());
438
439 // Cancel the animation.
440 runner_.CancelAnimationForWindow(&window);
441
442 EXPECT_FALSE(runner_.HasAnimations());
443 EXPECT_EQ(nullptr, GetSingleWindowAnimating(animation_id));
444
445 EXPECT_EQ(.75f, window.opacity());
446
447 EXPECT_EQ(1u, runner_observer_.changes()->size());
448 EXPECT_EQ("canceled", runner_observer_.changes()->at(0));
449 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
450 }
451
452 // Verifies a tick with a very large delta and a sequence that repeats forever
453 // doesn't take a long time.
454 TEST_F(AnimationRunnerTest, InfiniteRepeatWithHugeGap) {
455 TestServerWindowDelegate window_delegate;
456 ServerWindow window(&window_delegate, WindowId(1, 2));
457
458 window.SetOpacity(.5f);
459
460 AnimationGroup group;
461 InitGroupForWindow(&group, window.id(), 0);
462 AddOpacityElement(&group, TimeDelta::FromMicroseconds(500),
463 AnimationValuePtr(), FloatAnimationValue(1));
464 AddOpacityElement(&group, TimeDelta::FromMicroseconds(500),
465 AnimationValuePtr(), FloatAnimationValue(.5));
466
467 ScheduleForSingleWindow(&window, &group, initial_time_);
468 runner_observer_.clear_changes();
469
470 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(1000000000750));
471
472 EXPECT_EQ(.75f, window.opacity());
473
474 ASSERT_EQ(0u, runner_observer_.changes()->size());
475 }
476
477 // Verifies a second schedule sets any properties that are no longer animating
478 // to their final value.
479 TEST_F(AnimationRunnerTest, RescheduleSetsPropertiesToFinalValue) {
480 TestServerWindowDelegate window_delegate;
481 ServerWindow window(&window_delegate, WindowId());
482
483 AnimationGroup group;
484 InitGroupForWindow(&group, window.id(), 1);
485 AddOpacityElement(&group, TimeDelta::FromMicroseconds(1000),
486 AnimationValuePtr(), FloatAnimationValue(.5));
487
488 gfx::Transform done_transform;
489 done_transform.Scale(2, 4);
490 AddTransformElement(&group, TimeDelta::FromMicroseconds(500),
491 AnimationValuePtr(),
492 TransformAnimationValue(done_transform));
493
494 ScheduleForSingleWindow(&window, &group, initial_time_);
495
496 // Schedule() again, this time without animating opacity.
497 group.sequences[0]->elements[0]->property = AnimationProperty::NONE;
498 ScheduleForSingleWindow(&window, &group, initial_time_);
499
500 // Opacity should go to final value.
501 EXPECT_EQ(.5f, window.opacity());
502 // Transform shouldn't have changed since newly scheduled animation also has
503 // transform in it.
504 EXPECT_TRUE(window.transform().IsIdentity());
505 }
506
507 // Opacity from 1 to .5 over 1000 of v1 and v2 transform to 2x,4x over 500.
508 TEST_F(AnimationRunnerTest, TwoWindows) {
509 TestServerWindowDelegate window_delegate;
510 ServerWindow window1(&window_delegate, WindowId());
511 ServerWindow window2(&window_delegate, WindowId(1, 2));
512
513 AnimationGroup group1;
514 InitGroupForWindow(&group1, window1.id(), 1);
515 AddOpacityElement(&group1, TimeDelta::FromMicroseconds(1000),
516 AnimationValuePtr(), FloatAnimationValue(.5));
517
518 AnimationGroup group2;
519 InitGroupForWindow(&group2, window2.id(), 1);
520 gfx::Transform done_transform;
521 done_transform.Scale(2, 4);
522 AddTransformElement(&group2, TimeDelta::FromMicroseconds(500),
523 AnimationValuePtr(),
524 TransformAnimationValue(done_transform));
525
526 std::vector<AnimationRunner::WindowAndAnimationPair> pairs;
527 pairs.push_back(std::make_pair(&window1, &group1));
528 pairs.push_back(std::make_pair(&window2, &group2));
529
530 const uint32_t animation_id = runner_.Schedule(pairs, initial_time_);
531
532 ASSERT_EQ(1u, runner_observer_.changes()->size());
533 EXPECT_EQ("scheduled", runner_observer_.changes()->at(0));
534 EXPECT_EQ(animation_id, runner_observer_.change_ids()->at(0));
535 runner_observer_.clear_changes();
536
537 EXPECT_TRUE(runner_.HasAnimations());
538 EXPECT_TRUE(runner_.IsAnimating(animation_id));
539
540 // Properties should be at the initial value.
541 EXPECT_EQ(1.f, window1.opacity());
542 EXPECT_TRUE(window2.transform().IsIdentity());
543
544 // Animate 250ms in, which is quarter way for opacity and half way for
545 // transform.
546 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(250));
547 EXPECT_EQ(.875f, window1.opacity());
548 gfx::Transform half_way_transform;
549 half_way_transform.Scale(1.5, 2.5);
550 EXPECT_EQ(half_way_transform, window2.transform());
551 std::set<ServerWindow*> windows_animating(
552 runner_.GetWindowsAnimating(animation_id));
553 EXPECT_EQ(2u, windows_animating.size());
554 EXPECT_EQ(1u, windows_animating.count(&window1));
555 EXPECT_EQ(1u, windows_animating.count(&window2));
556
557 // Animate 750ms in, window1 should be done 3/4 done, and window2 done.
558 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(750));
559 EXPECT_EQ(.625, window1.opacity());
560 EXPECT_EQ(done_transform, window2.transform());
561 windows_animating = runner_.GetWindowsAnimating(animation_id);
562 EXPECT_EQ(1u, windows_animating.size());
563 EXPECT_EQ(1u, windows_animating.count(&window1));
564 EXPECT_TRUE(runner_.HasAnimations());
565 EXPECT_TRUE(runner_.IsAnimating(animation_id));
566
567 // Animate to end.
568 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(1750));
569 EXPECT_EQ(.5, window1.opacity());
570 EXPECT_EQ(done_transform, window2.transform());
571 windows_animating = runner_.GetWindowsAnimating(animation_id);
572 EXPECT_TRUE(windows_animating.empty());
573 EXPECT_FALSE(runner_.HasAnimations());
574 EXPECT_FALSE(runner_.IsAnimating(animation_id));
575 }
576
577 TEST_F(AnimationRunnerTest, Reschedule) {
578 TestServerWindowDelegate window_delegate;
579 ServerWindow window(&window_delegate, WindowId());
580
581 // Animation from 1-0 over 1ms and in parallel transform to 2x,4x over 1ms.
582 AnimationGroup group;
583 InitGroupForWindow(&group, window.id(), 1);
584 AddOpacityElement(&group, TimeDelta::FromMicroseconds(1000),
585 AnimationValuePtr(), FloatAnimationValue(0));
586 group.sequences.push_back(AnimationSequence::New());
587 group.sequences[1]->cycle_count = 1;
588 gfx::Transform done_transform;
589 done_transform.Scale(2, 4);
590 AddTransformElement(&group, TimeDelta::FromMicroseconds(1000),
591 AnimationValuePtr(),
592 TransformAnimationValue(done_transform));
593 const uint32_t animation_id1 =
594 ScheduleForSingleWindow(&window, &group, initial_time_);
595
596 // Animate half way in.
597 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(500));
598 EXPECT_EQ(.5f, window.opacity());
599 gfx::Transform half_way_transform;
600 half_way_transform.Scale(1.5, 2.5);
601 EXPECT_EQ(half_way_transform, window.transform());
602
603 runner_observer_.clear_changes();
604
605 // Schedule the same window animating opacity to 1.
606 AnimationGroup group2;
607 InitGroupForWindow(&group2, window.id(), 1);
608 AddOpacityElement(&group2, TimeDelta::FromMicroseconds(1000),
609 AnimationValuePtr(), FloatAnimationValue(1));
610 const uint32_t animation_id2 = ScheduleForSingleWindow(
611 &window, &group2, initial_time_ + TimeDelta::FromMicroseconds(500));
612
613 // Opacity should remain at .5, but transform should go to end state.
614 EXPECT_EQ(.5f, window.opacity());
615 EXPECT_EQ(done_transform, window.transform());
616
617 ASSERT_EQ(2u, runner_observer_.changes()->size());
618 EXPECT_EQ("interrupted", runner_observer_.changes()->at(0));
619 EXPECT_EQ(animation_id1, runner_observer_.change_ids()->at(0));
620 EXPECT_EQ("scheduled", runner_observer_.changes()->at(1));
621 EXPECT_EQ(animation_id2, runner_observer_.change_ids()->at(1));
622 runner_observer_.clear_changes();
623
624 // Animate half way through new sequence. Opacity should be the only thing
625 // changing.
626 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(1000));
627 EXPECT_EQ(.75f, window.opacity());
628 EXPECT_EQ(done_transform, window.transform());
629 ASSERT_EQ(0u, runner_observer_.changes()->size());
630
631 // Animate to end.
632 runner_.Tick(initial_time_ + TimeDelta::FromMicroseconds(2000));
633 ASSERT_EQ(1u, runner_observer_.changes()->size());
634 EXPECT_EQ("done", runner_observer_.changes()->at(0));
635 EXPECT_EQ(animation_id2, runner_observer_.change_ids()->at(0));
636 }
637
638 } // ws
639 } // mus
OLDNEW
« no previous file with comments | « components/mus/ws/animation_runner_observer.h ('k') | components/mus/ws/cursor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698