[Android] Introduce new UMA action for when user copies Image URL from context menu
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation_timelines.cc
blobc8513744cad5208fba255960deb46a9041340707
1 // Copyright 2015 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.
5 #include "cc/trees/layer_tree_host.h"
7 #include "cc/animation/animation_curve.h"
8 #include "cc/animation/animation_host.h"
9 #include "cc/animation/animation_id_provider.h"
10 #include "cc/animation/animation_player.h"
11 #include "cc/animation/animation_timeline.h"
12 #include "cc/animation/element_animations.h"
13 #include "cc/animation/layer_animation_controller.h"
14 #include "cc/animation/scroll_offset_animation_curve.h"
15 #include "cc/animation/timing_function.h"
16 #include "cc/base/time_util.h"
17 #include "cc/layers/layer.h"
18 #include "cc/layers/layer_impl.h"
19 #include "cc/test/animation_test_common.h"
20 #include "cc/test/fake_content_layer_client.h"
21 #include "cc/test/fake_picture_layer.h"
22 #include "cc/test/layer_tree_test.h"
23 #include "cc/trees/layer_tree_impl.h"
25 namespace cc {
26 namespace {
28 class LayerTreeHostTimelinesTest : public LayerTreeTest {
29 public:
30 LayerTreeHostTimelinesTest()
31 : timeline_id_(AnimationIdProvider::NextTimelineId()),
32 player_id_(AnimationIdProvider::NextPlayerId()),
33 player_child_id_(AnimationIdProvider::NextPlayerId()) {
34 timeline_ = AnimationTimeline::Create(timeline_id_);
35 player_ = AnimationPlayer::Create(player_id_);
36 player_child_ = AnimationPlayer::Create(player_child_id_);
38 player_->set_layer_animation_delegate(this);
41 void InitializeSettings(LayerTreeSettings* settings) override {
42 settings->use_compositor_animation_timelines = true;
45 void InitializeLayerSettings(LayerSettings* layer_settings) override {
46 layer_settings->use_compositor_animation_timelines = true;
49 void SetupTree() override { LayerTreeTest::SetupTree(); }
51 void AttachPlayersToTimeline() {
52 layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get());
53 timeline_->AttachPlayer(player_.get());
54 timeline_->AttachPlayer(player_child_.get());
57 protected:
58 scoped_refptr<AnimationTimeline> timeline_;
59 scoped_refptr<AnimationPlayer> player_;
60 scoped_refptr<AnimationPlayer> player_child_;
62 const int timeline_id_;
63 const int player_id_;
64 const int player_child_id_;
67 // Add a layer animation and confirm that
68 // LayerTreeHostImpl::UpdateAnimationState does get called.
69 // Evolved frome LayerTreeHostAnimationTestAddAnimation
70 class LayerTreeHostTimelinesTestAddAnimation
71 : public LayerTreeHostTimelinesTest {
72 public:
73 LayerTreeHostTimelinesTestAddAnimation()
74 : update_animation_state_was_called_(false) {}
76 void BeginTest() override {
77 AttachPlayersToTimeline();
78 player_->AttachLayer(layer_tree_host()->root_layer()->id());
79 PostAddInstantAnimationToMainThreadPlayer(player_.get());
82 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
83 bool has_unfinished_animation) override {
84 EXPECT_FALSE(has_unfinished_animation);
85 update_animation_state_was_called_ = true;
88 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
89 Animation::TargetProperty target_property,
90 int group) override {
91 EXPECT_LT(base::TimeTicks(), monotonic_time);
93 LayerAnimationController* controller =
94 player_->element_animations()->layer_animation_controller();
95 Animation* animation = controller->GetAnimation(Animation::OPACITY);
96 if (animation)
97 player_->RemoveAnimation(animation->id());
99 EndTest();
102 void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); }
104 private:
105 bool update_animation_state_was_called_;
108 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAddAnimation);
110 // Add a layer animation to a layer, but continually fail to draw. Confirm that
111 // after a while, we do eventually force a draw.
112 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws.
113 class LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws
114 : public LayerTreeHostTimelinesTest {
115 public:
116 LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws()
117 : started_animating_(false) {}
119 void BeginTest() override {
120 AttachPlayersToTimeline();
121 player_->AttachLayer(layer_tree_host()->root_layer()->id());
122 PostAddAnimationToMainThreadPlayer(player_.get());
125 void AnimateLayers(LayerTreeHostImpl* host_impl,
126 base::TimeTicks monotonic_time) override {
127 started_animating_ = true;
130 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
131 if (started_animating_)
132 EndTest();
135 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
136 LayerTreeHostImpl::FrameData* frame,
137 DrawResult draw_result) override {
138 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
141 void AfterTest() override {}
143 private:
144 bool started_animating_;
147 // Starvation can only be an issue with the MT compositor.
148 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws);
150 // Ensures that animations eventually get deleted.
151 // Evolved from LayerTreeHostAnimationTestAnimationsGetDeleted.
152 class LayerTreeHostTimelinesTestAnimationsGetDeleted
153 : public LayerTreeHostTimelinesTest {
154 public:
155 LayerTreeHostTimelinesTestAnimationsGetDeleted()
156 : started_animating_(false) {}
158 void BeginTest() override {
159 AttachPlayersToTimeline();
160 player_->AttachLayer(layer_tree_host()->root_layer()->id());
161 PostAddAnimationToMainThreadPlayer(player_.get());
164 void AnimateLayers(LayerTreeHostImpl* host_impl,
165 base::TimeTicks monotonic_time) override {
166 bool have_animations = !host_impl->animation_host()
167 ->animation_registrar()
168 ->active_animation_controllers_for_testing()
169 .empty();
170 if (!started_animating_ && have_animations) {
171 started_animating_ = true;
172 return;
175 if (started_animating_ && !have_animations)
176 EndTest();
179 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
180 Animation::TargetProperty target_property,
181 int group) override {
182 // Animations on the impl-side controller only get deleted during a commit,
183 // so we need to schedule a commit.
184 layer_tree_host()->SetNeedsCommit();
187 void AfterTest() override {}
189 private:
190 bool started_animating_;
193 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationsGetDeleted);
195 // Ensure that an animation's timing function is respected.
196 // Evolved from LayerTreeHostAnimationTestAddAnimationWithTimingFunction.
197 class LayerTreeHostTimelinesTestAddAnimationWithTimingFunction
198 : public LayerTreeHostTimelinesTest {
199 public:
200 LayerTreeHostTimelinesTestAddAnimationWithTimingFunction() {}
202 void SetupTree() override {
203 LayerTreeHostTimelinesTest::SetupTree();
204 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
205 picture_->SetBounds(gfx::Size(4, 4));
206 layer_tree_host()->root_layer()->AddChild(picture_);
208 AttachPlayersToTimeline();
209 player_child_->AttachLayer(picture_->id());
212 void BeginTest() override {
213 PostAddAnimationToMainThreadPlayer(player_child_.get());
216 void AnimateLayers(LayerTreeHostImpl* host_impl,
217 base::TimeTicks monotonic_time) override {
218 scoped_refptr<AnimationTimeline> timeline_impl =
219 host_impl->animation_host()->GetTimelineById(timeline_id_);
220 scoped_refptr<AnimationPlayer> player_child_impl =
221 timeline_impl->GetPlayerById(player_child_id_);
223 LayerAnimationController* controller_impl =
224 player_child_impl->element_animations()->layer_animation_controller();
225 if (!controller_impl)
226 return;
228 Animation* animation = controller_impl->GetAnimation(Animation::OPACITY);
229 if (!animation)
230 return;
232 const FloatAnimationCurve* curve =
233 animation->curve()->ToFloatAnimationCurve();
234 float start_opacity = curve->GetValue(base::TimeDelta());
235 float end_opacity = curve->GetValue(curve->Duration());
236 float linearly_interpolated_opacity =
237 0.25f * end_opacity + 0.75f * start_opacity;
238 base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f);
239 // If the linear timing function associated with this animation was not
240 // picked up, then the linearly interpolated opacity would be different
241 // because of the default ease timing function.
242 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
244 EndTest();
247 void AfterTest() override {}
249 FakeContentLayerClient client_;
250 scoped_refptr<FakePictureLayer> picture_;
253 SINGLE_AND_MULTI_THREAD_TEST_F(
254 LayerTreeHostTimelinesTestAddAnimationWithTimingFunction);
256 // Ensures that main thread animations have their start times synchronized with
257 // impl thread animations.
258 // Evolved from LayerTreeHostAnimationTestSynchronizeAnimationStartTimes.
259 class LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes
260 : public LayerTreeHostTimelinesTest {
261 public:
262 LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes() {}
264 void SetupTree() override {
265 LayerTreeHostTimelinesTest::SetupTree();
266 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
267 picture_->SetBounds(gfx::Size(4, 4));
269 layer_tree_host()->root_layer()->AddChild(picture_);
271 AttachPlayersToTimeline();
272 player_child_->set_layer_animation_delegate(this);
273 player_child_->AttachLayer(picture_->id());
276 void BeginTest() override {
277 PostAddAnimationToMainThreadPlayer(player_child_.get());
280 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
281 Animation::TargetProperty target_property,
282 int group) override {
283 LayerAnimationController* controller =
284 player_child_->element_animations()->layer_animation_controller();
285 Animation* animation = controller->GetAnimation(Animation::OPACITY);
286 main_start_time_ = animation->start_time();
287 controller->RemoveAnimation(animation->id());
288 EndTest();
291 void UpdateAnimationState(LayerTreeHostImpl* impl_host,
292 bool has_unfinished_animation) override {
293 scoped_refptr<AnimationTimeline> timeline_impl =
294 impl_host->animation_host()->GetTimelineById(timeline_id_);
295 scoped_refptr<AnimationPlayer> player_child_impl =
296 timeline_impl->GetPlayerById(player_child_id_);
298 LayerAnimationController* controller =
299 player_child_impl->element_animations()->layer_animation_controller();
300 Animation* animation = controller->GetAnimation(Animation::OPACITY);
301 if (!animation)
302 return;
304 impl_start_time_ = animation->start_time();
307 void AfterTest() override {
308 EXPECT_EQ(impl_start_time_, main_start_time_);
309 EXPECT_LT(base::TimeTicks(), impl_start_time_);
312 private:
313 base::TimeTicks main_start_time_;
314 base::TimeTicks impl_start_time_;
315 FakeContentLayerClient client_;
316 scoped_refptr<FakePictureLayer> picture_;
319 SINGLE_AND_MULTI_THREAD_TEST_F(
320 LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes);
322 // Ensures that notify animation finished is called.
323 // Evolved from LayerTreeHostAnimationTestAnimationFinishedEvents.
324 class LayerTreeHostTimelinesTestAnimationFinishedEvents
325 : public LayerTreeHostTimelinesTest {
326 public:
327 LayerTreeHostTimelinesTestAnimationFinishedEvents() {}
329 void BeginTest() override {
330 AttachPlayersToTimeline();
331 player_->AttachLayer(layer_tree_host()->root_layer()->id());
332 PostAddInstantAnimationToMainThreadPlayer(player_.get());
335 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
336 Animation::TargetProperty target_property,
337 int group) override {
338 LayerAnimationController* controller =
339 player_->element_animations()->layer_animation_controller();
340 Animation* animation = controller->GetAnimation(Animation::OPACITY);
341 if (animation)
342 controller->RemoveAnimation(animation->id());
343 EndTest();
346 void AfterTest() override {}
349 SINGLE_AND_MULTI_THREAD_TEST_F(
350 LayerTreeHostTimelinesTestAnimationFinishedEvents);
352 // Ensures that when opacity is being animated, this value does not cause the
353 // subtree to be skipped.
354 // Evolved from LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity.
355 class LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity
356 : public LayerTreeHostTimelinesTest {
357 public:
358 LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity()
359 : update_check_layer_(
360 FakePictureLayer::Create(layer_settings(), &client_)) {}
362 void SetupTree() override {
363 update_check_layer_->SetOpacity(0.f);
364 layer_tree_host()->SetRootLayer(update_check_layer_);
365 LayerTreeHostTimelinesTest::SetupTree();
367 AttachPlayersToTimeline();
368 player_->AttachLayer(update_check_layer_->id());
371 void BeginTest() override {
372 PostAddAnimationToMainThreadPlayer(player_.get());
375 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
376 scoped_refptr<AnimationTimeline> timeline_impl =
377 host_impl->animation_host()->GetTimelineById(timeline_id_);
378 scoped_refptr<AnimationPlayer> player_impl =
379 timeline_impl->GetPlayerById(player_id_);
381 LayerAnimationController* controller_impl =
382 player_impl->element_animations()->layer_animation_controller();
383 Animation* animation_impl =
384 controller_impl->GetAnimation(Animation::OPACITY);
385 controller_impl->RemoveAnimation(animation_impl->id());
386 EndTest();
389 void AfterTest() override {
390 // Update() should have been called once, proving that the layer was not
391 // skipped.
392 EXPECT_EQ(1, update_check_layer_->update_count());
394 // clear update_check_layer_ so LayerTreeHost dies.
395 update_check_layer_ = NULL;
398 private:
399 FakeContentLayerClient client_;
400 scoped_refptr<FakePictureLayer> update_check_layer_;
403 SINGLE_AND_MULTI_THREAD_TEST_F(
404 LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity);
406 // Layers added to tree with existing active animations should have the
407 // animation correctly recognized.
408 // Evolved from LayerTreeHostAnimationTestLayerAddedWithAnimation.
409 class LayerTreeHostTimelinesTestLayerAddedWithAnimation
410 : public LayerTreeHostTimelinesTest {
411 public:
412 LayerTreeHostTimelinesTestLayerAddedWithAnimation() {}
414 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
416 void DidCommit() override {
417 if (layer_tree_host()->source_frame_number() == 1) {
418 AttachPlayersToTimeline();
420 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
421 player_->AttachLayer(layer->id());
422 player_->set_layer_animation_delegate(this);
424 // Any valid AnimationCurve will do here.
425 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
426 scoped_ptr<Animation> animation(
427 Animation::Create(curve.Pass(), 1, 1, Animation::OPACITY));
428 player_->AddAnimation(animation.Pass());
430 // We add the animation *before* attaching the layer to the tree.
431 layer_tree_host()->root_layer()->AddChild(layer);
435 void AnimateLayers(LayerTreeHostImpl* impl_host,
436 base::TimeTicks monotonic_time) override {
437 EndTest();
440 void AfterTest() override {}
443 SINGLE_AND_MULTI_THREAD_TEST_F(
444 LayerTreeHostTimelinesTestLayerAddedWithAnimation);
446 // Make sure the main thread can still execute animations when CanDraw() is not
447 // true.
448 // Evolved from LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
449 class LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw
450 : public LayerTreeHostTimelinesTest {
451 public:
452 LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
454 void SetupTree() override {
455 LayerTreeHostTimelinesTest::SetupTree();
456 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
457 picture_->SetBounds(gfx::Size(4, 4));
458 layer_tree_host()->root_layer()->AddChild(picture_);
460 AttachPlayersToTimeline();
461 player_child_->AttachLayer(picture_->id());
462 player_child_->set_layer_animation_delegate(this);
465 void BeginTest() override {
466 layer_tree_host()->SetViewportSize(gfx::Size());
467 PostAddAnimationToMainThreadPlayer(player_child_.get());
470 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
471 Animation::TargetProperty target_property,
472 int group) override {
473 started_times_++;
476 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
477 Animation::TargetProperty target_property,
478 int group) override {
479 EndTest();
482 void AfterTest() override { EXPECT_EQ(1, started_times_); }
484 private:
485 int started_times_;
486 FakeContentLayerClient client_;
487 scoped_refptr<FakePictureLayer> picture_;
490 SINGLE_AND_MULTI_THREAD_TEST_F(
491 LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw);
493 // Animations should not be started when frames are being skipped due to
494 // checkerboard.
495 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations.
496 class LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations
497 : public LayerTreeHostTimelinesTest {
498 void SetupTree() override {
499 LayerTreeHostTimelinesTest::SetupTree();
500 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
501 picture_->SetBounds(gfx::Size(4, 4));
502 layer_tree_host()->root_layer()->AddChild(picture_);
504 AttachPlayersToTimeline();
505 player_child_->AttachLayer(picture_->id());
506 player_child_->set_layer_animation_delegate(this);
509 void InitializeSettings(LayerTreeSettings* settings) override {
510 // Make sure that drawing many times doesn't cause a checkerboarded
511 // animation to start so we avoid flake in this test.
512 settings->timeout_and_draw_when_animation_checkerboards = false;
513 LayerTreeHostTimelinesTest::InitializeSettings(settings);
516 void BeginTest() override {
517 prevented_draw_ = 0;
518 added_animations_ = 0;
519 started_times_ = 0;
521 PostSetNeedsCommitToMainThread();
524 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
525 LayerTreeHostImpl::FrameData* frame_data,
526 DrawResult draw_result) override {
527 if (added_animations_ < 2)
528 return draw_result;
529 if (TestEnded())
530 return draw_result;
531 // Act like there is checkerboard when the second animation wants to draw.
532 ++prevented_draw_;
533 if (prevented_draw_ > 2)
534 EndTest();
535 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
538 void DidCommitAndDrawFrame() override {
539 switch (layer_tree_host()->source_frame_number()) {
540 case 1:
541 // The animation is longer than 1 BeginFrame interval.
542 AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 0.2f, 0.8f,
543 false);
544 added_animations_++;
545 break;
546 case 2:
547 // This second animation will not be drawn so it should not start.
548 AddAnimatedTransformToPlayer(player_child_.get(), 0.1, 5, 5);
549 added_animations_++;
550 break;
554 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
555 Animation::TargetProperty target_property,
556 int group) override {
557 if (TestEnded())
558 return;
559 started_times_++;
562 void AfterTest() override {
563 // Make sure we tried to draw the second animation but failed.
564 EXPECT_LT(0, prevented_draw_);
565 // The first animation should be started, but the second should not because
566 // of checkerboard.
567 EXPECT_EQ(1, started_times_);
570 int prevented_draw_;
571 int added_animations_;
572 int started_times_;
573 FakeContentLayerClient client_;
574 scoped_refptr<FakePictureLayer> picture_;
577 MULTI_THREAD_TEST_F(
578 LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations);
580 // When animations are simultaneously added to an existing layer and to a new
581 // layer, they should start at the same time, even when there's already a
582 // running animation on the existing layer.
583 // Evolved from LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers.
584 class LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
585 : public LayerTreeHostTimelinesTest {
586 public:
587 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers()
588 : frame_count_with_pending_tree_(0) {}
590 void BeginTest() override {
591 AttachPlayersToTimeline();
592 PostSetNeedsCommitToMainThread();
595 void DidCommit() override {
596 if (layer_tree_host()->source_frame_number() == 1) {
597 player_->AttachLayer(layer_tree_host()->root_layer()->id());
598 AddAnimatedTransformToPlayer(player_.get(), 4, 1, 1);
599 } else if (layer_tree_host()->source_frame_number() == 2) {
600 AddOpacityTransitionToPlayer(player_.get(), 1, 0.f, 0.5f, true);
602 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
603 layer_tree_host()->root_layer()->AddChild(layer);
604 layer->SetBounds(gfx::Size(4, 4));
606 player_child_->AttachLayer(layer->id());
607 player_child_->set_layer_animation_delegate(this);
608 AddOpacityTransitionToPlayer(player_child_.get(), 1, 0.f, 0.5f, true);
612 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
613 host_impl->BlockNotifyReadyToActivateForTesting(true);
616 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
617 // For the commit that added animations to new and existing layers, keep
618 // blocking activation. We want to verify that even with activation blocked,
619 // the animation on the layer that's already in the active tree won't get a
620 // head start.
621 if (host_impl->pending_tree()->source_frame_number() != 2) {
622 host_impl->BlockNotifyReadyToActivateForTesting(false);
626 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
627 const BeginFrameArgs& args) override {
628 if (!host_impl->pending_tree() ||
629 host_impl->pending_tree()->source_frame_number() != 2)
630 return;
632 frame_count_with_pending_tree_++;
633 if (frame_count_with_pending_tree_ == 2) {
634 host_impl->BlockNotifyReadyToActivateForTesting(false);
638 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
639 bool has_unfinished_animation) override {
640 scoped_refptr<AnimationTimeline> timeline_impl =
641 host_impl->animation_host()->GetTimelineById(timeline_id_);
642 scoped_refptr<AnimationPlayer> player_impl =
643 timeline_impl->GetPlayerById(player_id_);
644 scoped_refptr<AnimationPlayer> player_child_impl =
645 timeline_impl->GetPlayerById(player_child_id_);
647 // wait for tree activation.
648 if (!player_impl->element_animations())
649 return;
651 LayerAnimationController* root_controller_impl =
652 player_impl->element_animations()->layer_animation_controller();
653 Animation* root_animation =
654 root_controller_impl->GetAnimation(Animation::OPACITY);
655 if (!root_animation || root_animation->run_state() != Animation::RUNNING)
656 return;
658 LayerAnimationController* child_controller_impl =
659 player_child_impl->element_animations()->layer_animation_controller();
660 Animation* child_animation =
661 child_controller_impl->GetAnimation(Animation::OPACITY);
662 EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
663 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
664 root_controller_impl->AbortAnimations(Animation::OPACITY);
665 root_controller_impl->AbortAnimations(Animation::TRANSFORM);
666 child_controller_impl->AbortAnimations(Animation::OPACITY);
667 EndTest();
670 void AfterTest() override {}
672 private:
673 int frame_count_with_pending_tree_;
676 // This test blocks activation which is not supported for single thread mode.
677 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
678 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers);
680 // Evolved from LayerTreeHostAnimationTestAddAnimationAfterAnimating.
681 class LayerTreeHostTimelinesTestAddAnimationAfterAnimating
682 : public LayerTreeHostTimelinesTest {
683 public:
684 void SetupTree() override {
685 LayerTreeHostTimelinesTest::SetupTree();
686 content_ = Layer::Create(layer_settings());
687 content_->SetBounds(gfx::Size(4, 4));
688 layer_tree_host()->root_layer()->AddChild(content_);
690 AttachPlayersToTimeline();
692 player_->AttachLayer(layer_tree_host()->root_layer()->id());
693 player_child_->AttachLayer(content_->id());
696 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
698 void DidCommit() override {
699 switch (layer_tree_host()->source_frame_number()) {
700 case 1:
701 // First frame: add an animation to the root layer.
702 AddAnimatedTransformToPlayer(player_.get(), 0.1, 5, 5);
703 break;
704 case 2:
705 // Second frame: add an animation to the content layer. The root layer
706 // animation has caused us to animate already during this frame.
707 AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 5, 5, false);
708 break;
712 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
713 // After both animations have started, verify that they have valid
714 // start times.
715 if (host_impl->active_tree()->source_frame_number() < 2)
716 return;
717 AnimationRegistrar::AnimationControllerMap controllers_copy =
718 host_impl->animation_host()
719 ->animation_registrar()
720 ->active_animation_controllers_for_testing();
721 EXPECT_EQ(2u, controllers_copy.size());
722 for (auto& it : controllers_copy) {
723 int id = it.first;
724 if (id == host_impl->RootLayer()->id()) {
725 Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
726 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
727 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
728 Animation* anim = it.second->GetAnimation(Animation::OPACITY);
729 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
731 EndTest();
735 void AfterTest() override {}
737 private:
738 scoped_refptr<Layer> content_;
741 SINGLE_AND_MULTI_THREAD_TEST_F(
742 LayerTreeHostTimelinesTestAddAnimationAfterAnimating);
744 } // namespace
745 } // namespace cc