diff options
author | ljagielski <ljagielski@opera.com> | 2015-01-07 12:32:55 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-07 20:34:29 +0000 |
commit | 205709806da5c07eb640fe256d473f1a64f56e44 (patch) | |
tree | 25650476f06b480ca1be13cd97223007905dff5e /ui/compositor | |
parent | b639aca53effcba6978bd37c829745b6a84699cf (diff) | |
download | chromium_src-205709806da5c07eb640fe256d473f1a64f56e44.zip chromium_src-205709806da5c07eb640fe256d473f1a64f56e44.tar.gz chromium_src-205709806da5c07eb640fe256d473f1a64f56e44.tar.bz2 |
LayerAnimator should withdraw from processing animation queue when its delegate becomes nullptr.
BUG=
Review URL: https://codereview.chromium.org/795113002
Cr-Commit-Position: refs/heads/master@{#310354}
Diffstat (limited to 'ui/compositor')
-rw-r--r-- | ui/compositor/layer_animator.cc | 4 | ||||
-rw-r--r-- | ui/compositor/layer_animator_unittest.cc | 63 |
2 files changed, 66 insertions, 1 deletions
diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc index 39585a7..adff73f 100644 --- a/ui/compositor/layer_animator.cc +++ b/ui/compositor/layer_animator.cc @@ -409,7 +409,7 @@ void LayerAnimator::Step(base::TimeTicks now) { void LayerAnimator::StopAnimatingInternal(bool abort) { scoped_refptr<LayerAnimator> retain(this); - while (is_animating()) { + while (is_animating() && delegate()) { // We're going to attempt to finish the first running animation. Let's // ensure that it's valid. PurgeDeletedAnimations(); @@ -517,6 +517,8 @@ void LayerAnimator::FinishAnimation( sequence->Abort(delegate()); else ProgressAnimationToEnd(sequence); + if (!delegate()) + return; ProcessQueue(); UpdateAnimationState(); } diff --git a/ui/compositor/layer_animator_unittest.cc b/ui/compositor/layer_animator_unittest.cc index 3ecf0c3..f6aff59 100644 --- a/ui/compositor/layer_animator_unittest.cc +++ b/ui/compositor/layer_animator_unittest.cc @@ -2611,4 +2611,67 @@ TEST(LayerAnimatorTest, LayerMovedBetweenCompositorsDuringAnimation) { TerminateContextFactoryForTests(); } +class LayerOwnerAnimationObserver : public LayerAnimationObserver { + public: + LayerOwnerAnimationObserver(LayerAnimator* animator) + : animator_layer_(new Layer(LAYER_TEXTURED)) { + animator_layer_->SetAnimator(animator); + } + + ~LayerOwnerAnimationObserver() override {} + + void OnLayerAnimationEnded(LayerAnimationSequence* sequence) override { + ASSERT_TRUE(sequence); + animator_layer_.reset(); + } + + void OnLayerAnimationAborted(LayerAnimationSequence* sequence) override { + ASSERT_TRUE(sequence); + animator_layer_.reset(); + } + + LayerAnimationDelegate* animator_layer() { + return animator_layer_.get(); + } + + void OnLayerAnimationScheduled(LayerAnimationSequence* sequence) override {} + + private: + scoped_ptr<Layer> animator_layer_; + + DISALLOW_COPY_AND_ASSIGN(LayerOwnerAnimationObserver); +}; + +TEST(LayerAnimatorTest, ObserverDeletesLayerInStopAnimating) { + scoped_refptr<LayerAnimator> animator( + LayerAnimator::CreateImplicitAnimator()); + animator->set_disable_timer_for_test(true); + LayerOwnerAnimationObserver observer(animator.get()); + LayerAnimationDelegate* delegate = observer.animator_layer(); + + const gfx::Rect start_bounds(0, 0, 50, 50); + const gfx::Rect target_bounds(10, 10, 100, 100); + const double target_opacity = 1.0; + + delegate->SetOpacityFromAnimation(0.0f); + delegate->SetBoundsFromAnimation(start_bounds); + + base::TimeDelta time_delta = base::TimeDelta::FromSeconds(1); + LayerAnimationSequence* opacity = new LayerAnimationSequence( + LayerAnimationElement::CreateOpacityElement(target_opacity, time_delta)); + opacity->AddObserver(&observer); + animator->ScheduleAnimation(opacity); + time_delta = base::TimeDelta::FromSeconds(2); + LayerAnimationSequence* move = new LayerAnimationSequence( + LayerAnimationElement::CreateBoundsElement(target_bounds, time_delta)); + animator->ScheduleAnimation(move); + EXPECT_TRUE(animator->is_animating()); + animator->Step(animator->last_step_time() + + base::TimeDelta::FromMilliseconds(500)); + animator->StopAnimating(); + + EXPECT_EQ(nullptr, observer.animator_layer()); + EXPECT_TRUE(animator->is_animating()); +} + } // namespace ui |