summaryrefslogtreecommitdiffstats
path: root/ui/compositor
diff options
context:
space:
mode:
authorljagielski <ljagielski@opera.com>2015-01-07 12:32:55 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-07 20:34:29 +0000
commit205709806da5c07eb640fe256d473f1a64f56e44 (patch)
tree25650476f06b480ca1be13cd97223007905dff5e /ui/compositor
parentb639aca53effcba6978bd37c829745b6a84699cf (diff)
downloadchromium_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.cc4
-rw-r--r--ui/compositor/layer_animator_unittest.cc63
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