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

Unified Diff: ui/compositor/layer_animator.cc

Issue 10869066: Attempt 2 at Fixes crash introduced @ 153047 (you can hit crash by maximizing a (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Better fix Created 8 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/compositor/layer_animator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/compositor/layer_animator.cc
diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc
index fbb298ad88797ee6a661e5ce17696e36519614ad..7c12d33a84b61d7fcb02bc03874496f7e0909f87 100644
--- a/ui/compositor/layer_animator.cc
+++ b/ui/compositor/layer_animator.cc
@@ -28,6 +28,29 @@ static const base::TimeDelta kTimerInterval =
} // namespace
+class LayerAnimator::DestroyedTracker
+ : public base::RefCounted<LayerAnimator::DestroyedTracker> {
+ public:
+ DestroyedTracker() : is_alive_(true) {}
+ virtual ~DestroyedTracker() {
+ DCHECK(!is_alive_);
+ }
+
+ // Returns true if the animator is still alive.
+ bool is_alive() const { return is_alive_; }
+
+ // Invoked when the animator is destroyed.
+ void AnimatorDeleted() {
+ DCHECK(is_alive_);
+ is_alive_ = false;
+ }
+
+ private:
+ bool is_alive_;
+
+ DISALLOW_COPY_AND_ASSIGN(DestroyedTracker);
+};
+
// static
bool LayerAnimator::disable_animations_for_test_ = false;
// static
@@ -43,13 +66,15 @@ LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
transition_duration_(transition_duration),
tween_type_(Tween::LINEAR),
is_started_(false),
- disable_timer_for_test_(false) {
+ disable_timer_for_test_(false),
+ destroyed_tracker_(new DestroyedTracker) {
}
LayerAnimator::~LayerAnimator() {
for (size_t i = 0; i < running_animations_.size(); ++i)
running_animations_[i].sequence->OnAnimatorDestroyed();
ClearAnimations();
+ destroyed_tracker_->AnimatorDeleted();
}
// static
@@ -252,13 +277,16 @@ void LayerAnimator::StopAnimatingProperty(
RunningAnimation* running = GetRunningAnimation(property);
if (!running)
break;
- FinishAnimation(running->sequence);
+ if (FinishAnimation(running->sequence) == DESTROYED)
+ return;
}
}
void LayerAnimator::StopAnimating() {
- while (is_animating())
- FinishAnimation(running_animations_[0].sequence);
+ while (is_animating()) {
+ if (FinishAnimation(running_animations_[0].sequence) == DESTROYED)
+ return;
+ }
}
void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
@@ -310,9 +338,18 @@ void LayerAnimator::Step(base::TimeTicks now) {
base::TimeDelta delta = now - running_animations_copy[i].start_time;
if (delta >= running_animations_copy[i].sequence->duration() &&
!running_animations_copy[i].sequence->is_cyclic()) {
- FinishAnimation(running_animations_copy[i].sequence);
- } else if (ProgressAnimation(running_animations_copy[i].sequence, delta))
+ if (FinishAnimation(running_animations_copy[i].sequence) == DESTROYED)
+ return;
needs_redraw = true;
+ } else {
+ scoped_refptr<DestroyedTracker> tracker(destroyed_tracker_);
+ const bool progress_result =
+ ProgressAnimation(running_animations_copy[i].sequence, delta);
+ if (!tracker->is_alive())
+ return;
+ if (progress_result)
+ needs_redraw = true;
+ }
}
if (needs_redraw && delegate())
@@ -372,11 +409,18 @@ LayerAnimationSequence* LayerAnimator::RemoveAnimation(
return to_return.release();
}
-void LayerAnimator::FinishAnimation(LayerAnimationSequence* sequence) {
+LayerAnimator::DestroyedType LayerAnimator::FinishAnimation(
+ LayerAnimationSequence* sequence) {
scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
- sequence->Progress(sequence->duration(), delegate());
+ {
+ scoped_refptr<DestroyedTracker> tracker(destroyed_tracker_);
+ sequence->Progress(sequence->duration(), delegate());
+ if (!tracker->is_alive())
+ return DESTROYED;
+ }
ProcessQueue();
UpdateAnimationState();
+ return NOT_DESTROYED;
}
void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
« no previous file with comments | « ui/compositor/layer_animator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698