15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animator.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/animation/animation_id_provider.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "cc/output/begin_frame_args.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_delegate.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_observer.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_sequence.h"
17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/animation_container.h"
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/gfx/frame_time.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAFE_INVOKE_VOID(function, running_anim, ...) \
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (running_anim.is_sequence_alive()) \
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      function(running_anim.sequence(), ##__VA_ARGS__)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAFE_INVOKE_BOOL(function, running_anim) \
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((running_anim.is_sequence_alive()) \
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ? function(running_anim.sequence()) \
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : false)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAFE_INVOKE_PTR(function, running_anim) \
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((running_anim.is_sequence_alive()) \
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ? function(running_anim.sequence()) \
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : NULL)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LayerAnimator;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultTransitionDurationMs = 120;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kTimerIntervalMs = 10;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the AnimationContainer we're added to.
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)gfx::AnimationContainer* GetAnimationContainer() {
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  static gfx::AnimationContainer* container = NULL;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!container) {
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    container = new gfx::AnimationContainer();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    container->AddRef();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return container;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LayerAnimator public --------------------------------------------------------
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : delegate_(NULL),
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET),
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      is_transition_duration_locked_(false),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transition_duration_(transition_duration),
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      tween_type_(gfx::Tween::LINEAR),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_started_(false),
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      disable_timer_for_test_(false),
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      adding_animations_(false) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::~LayerAnimator() {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_.size(); ++i) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (running_animations_[i].is_sequence_alive())
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      running_animations_[i].sequence()->OnAnimatorDestroyed();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearAnimationsInternal();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = NULL;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator* LayerAnimator::CreateDefaultAnimator() {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new LayerAnimator(base::TimeDelta::FromMilliseconds(0));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new LayerAnimator(
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs));
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This macro provides the implementation for the setter and getter (well,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the getter of the target value) for an animated property. For example,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it is used for the implementations of SetTransform and GetTargetTransform.
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// It is worth noting that SetFoo avoids invoking the usual animation machinery
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// if the transition duration is zero -- in this case we just set the property
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// on the layer animation delegate immediately.
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ANIMATED_PROPERTY(type, property, name, member_type, member)  \
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LayerAnimator::Set##name(type value) {                           \
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta duration = GetTransitionDuration();                 \
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (duration == base::TimeDelta() && delegate() &&                  \
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (preemption_strategy_ != ENQUEUE_NEW_ANIMATION)) {              \
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StopAnimatingProperty(LayerAnimationElement::property);           \
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delegate()->Set##name##FromAnimation(value);                      \
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;                                                           \
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }                                                                   \
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<LayerAnimationElement> element(                          \
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LayerAnimationElement::Create##name##Element(value, duration)); \
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element->set_tween_type(tween_type_);                               \
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartAnimation(new LayerAnimationSequence(element.release()));      \
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}                                                                     \
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                                      \
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)member_type LayerAnimator::GetTarget##name() const {                  \
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerAnimationElement::TargetValue target(delegate());              \
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetTargetValue(&target);                                            \
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return target.member;                                               \
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Transform&, TRANSFORM, Transform, gfx::Transform, transform);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(const gfx::Rect&, BOUNDS, Bounds, gfx::Rect, bounds);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(float, OPACITY, Opacity, float, opacity);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::TimeDelta LayerAnimator::GetTransitionDuration() const {
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return transition_duration_;
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = delegate;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnScheduled(animation);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!StartSequenceImmediately(animation)) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Attempt to preempt a running animation.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (preemption_strategy_) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IMMEDIATELY_SET_NEW_TARGET:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ImmediatelySetNewTarget(animation);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ImmediatelyAnimateToNewTarget(animation);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ENQUEUE_NEW_ANIMATION:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EnqueueNewAnimation(animation);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case REPLACE_QUEUED_ANIMATIONS:
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ReplaceQueuedAnimations(animation);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case BLEND_WITH_CURRENT_ANIMATION: {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // TODO(vollick) Add support for blended sequences and use them here.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTIMPLEMENTED();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FinishAnyAnimationWithZeroDuration();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnScheduled(animation);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_animating()) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    animation_queue_.push_back(make_linked_ptr(animation));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessQueue();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartSequenceImmediately(animation);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LayerAnimator::StartTogether(
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<LayerAnimationSequence*>& animations) {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<LayerAnimationSequence*>::const_iterator iter;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (iter = animations.begin(); iter != animations.end(); ++iter) {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      StartAnimation(*iter);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  adding_animations_ = true;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!is_animating()) {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (GetAnimationContainer()->is_running())
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      last_step_time_ = GetAnimationContainer()->last_tick_time();
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      last_step_time_ = gfx::FrameTime::Now();
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Collect all the affected properties.
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerAnimationElement::AnimatableProperties animated_properties;
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<LayerAnimationSequence*>::const_iterator iter;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter) {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    animated_properties.insert((*iter)->properties().begin(),
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               (*iter)->properties().end());
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Starting a zero duration pause that affects all the animated properties
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will prevent any of the sequences from animating until there are no
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // running animations that affect any of these properties, as well as
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // handle preemption strategy.
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartAnimation(new LayerAnimationSequence(
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LayerAnimationElement::CreatePauseElement(animated_properties,
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                base::TimeDelta())));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool wait_for_group_start = false;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    wait_for_group_start |= (*iter)->IsFirstElementThreaded();
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int group_id = cc::AnimationIdProvider::NextGroupId();
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These animations (provided they don't animate any common properties) will
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // now animate together if trivially scheduled.
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter) {
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->set_animation_group_id(group_id);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->set_waiting_for_group_start(wait_for_group_start);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScheduleAnimation(*iter);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  adding_animations_ = false;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAnimationState();
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ScheduleTogether(
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<LayerAnimationSequence*>& animations) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Collect all the affected properties.
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayerAnimationElement::AnimatableProperties animated_properties;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<LayerAnimationSequence*>::const_iterator iter;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    animated_properties.insert((*iter)->properties().begin(),
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               (*iter)->properties().end());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Scheduling a zero duration pause that affects all the animated properties
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will prevent any of the sequences from animating until there are no
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // running animations that affect any of these properties.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAnimation(new LayerAnimationSequence(
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LayerAnimationElement::CreatePauseElement(animated_properties,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                base::TimeDelta())));
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool wait_for_group_start = false;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    wait_for_group_start |= (*iter)->IsFirstElementThreaded();
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int group_id = cc::AnimationIdProvider::NextGroupId();
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These animations (provided they don't animate any common properties) will
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // now animate together if trivially scheduled.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter) {
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->set_animation_group_id(group_id);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->set_waiting_for_group_start(wait_for_group_start);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleAnimation(*iter);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::SchedulePauseForProperties(
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta duration,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationElement::AnimatableProperty property,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ...) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::LayerAnimationElement::AnimatableProperties properties_to_pause;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_list marker;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_start(marker, property);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int p = static_cast<int>(property); p != -1; p = va_arg(marker, int)) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    properties_to_pause.insert(
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<LayerAnimationElement::AnimatableProperty>(p));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_end(marker);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAnimation(new ui::LayerAnimationSequence(
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ui::LayerAnimationElement::CreatePauseElement(
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            properties_to_pause, duration)));
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LayerAnimator::IsAnimatingProperty(
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationElement::AnimatableProperty property) const {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*queue_iter)->properties().find(property) !=
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (*queue_iter)->properties().end()) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::StopAnimatingProperty(
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationElement::AnimatableProperty property) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (true) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // GetRunningAnimation purges deleted animations before searching, so we are
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // guaranteed to find a live animation if any is returned at all.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunningAnimation* running = GetRunningAnimation(property);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!running)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // As was mentioned above, this sequence must be alive.
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(running->is_sequence_alive());
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FinishAnimation(running->sequence(), false);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!observers_.HasObserver(observer))
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observers_.AddObserver(observer);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers_.RemoveObserver(observer);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the observer from all sequences as well.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*queue_iter)->RemoveObserver(observer);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LayerAnimator::OnThreadedAnimationStarted(
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const cc::AnimationEvent& event) {
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerAnimationElement::AnimatableProperty property =
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerAnimationElement::ToAnimatableProperty(event.target_property);
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunningAnimation* running = GetRunningAnimation(property);
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!running)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(running->is_sequence_alive());
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (running->sequence()->animation_group_id() != event.group_id)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  running->sequence()->OnThreadedAnimationStarted(event);
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!running->sequence()->waiting_for_group_start())
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeTicks start_time = base::TimeTicks::FromInternalValue(
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event.monotonic_time * base::Time::kMicrosecondsPerSecond);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  running->sequence()->set_waiting_for_group_start(false);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The call to GetRunningAnimation made above already purged deleted
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // animations, so we are guaranteed that all the animations we iterate
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // over now are alive.
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (RunningAnimations::iterator iter = running_animations_.begin();
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != running_animations_.end(); ++iter) {
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Ensure that each sequence is only Started once, regardless of the
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // number of sequences in the group that have threaded first elements.
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (((*iter).sequence()->animation_group_id() == event.group_id) &&
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !(*iter).sequence()->IsFirstElementThreaded() &&
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (*iter).sequence()->waiting_for_group_start()) {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*iter).sequence()->set_start_time(start_time);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*iter).sequence()->set_waiting_for_group_start(false);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*iter).sequence()->Start(delegate());
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LayerAnimator protected -----------------------------------------------------
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      base::TimeTicks now) {
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!delegate() || sequence->waiting_for_group_start())
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sequence->Progress(now, delegate());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) {
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!delegate())
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sequence->ProgressToEnd(delegate());
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LayerAnimator::HasAnimation(LayerAnimationSequence* sequence) const {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*queue_iter).get() == sequence)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LayerAnimator private -------------------------------------------------------
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::Step(base::TimeTicks now) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("ui", "LayerAnimator::Step");
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_step_time_ = now;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PurgeDeletedAnimations();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need to make a copy of the running animations because progressing them
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and finishing them may indirectly affect the collection of running
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // animations.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunningAnimations running_animations_copy = running_animations_;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (running_animations_copy[i].sequence()->IsFinished(now)) {
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::SetStartTime(base::TimeTicks start_time) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do nothing.
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta LayerAnimator::GetTimerInterval() const {
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::TimeDelta::FromMilliseconds(kTimerIntervalMs);
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LayerAnimator::StopAnimatingInternal(bool abort) {
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (is_animating()) {
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We're going to attempt to finish the first running animation. Let's
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // ensure that it's valid.
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PurgeDeletedAnimations();
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If we've purged all running animations, attempt to start one up.
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (running_animations_.empty())
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProcessQueue();
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!running_animations_.empty());
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Still no luck, let's just bail and clear all animations.
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (running_animations_.empty()) {
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ClearAnimationsInternal();
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::UpdateAnimationState() {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (disable_timer_for_test_)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool should_start = is_animating();
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (should_start && !is_started_)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetAnimationContainer()->Start(this);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (!should_start && is_started_)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetAnimationContainer()->Stop(this);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_started_ = should_start;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimationSequence* LayerAnimator::RemoveAnimation(
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationSequence* sequence) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  linked_ptr<LayerAnimationSequence> to_return;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_running = false;
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First remove from running animations
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RunningAnimations::iterator iter = running_animations_.begin();
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != running_animations_.end(); ++iter) {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*iter).sequence() == sequence) {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      running_animations_.erase(iter);
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_running = true;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then remove from the queue
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*queue_iter) == sequence) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      to_return = *queue_iter;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      animation_queue_.erase(queue_iter);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!to_return.get() ||
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !to_return->waiting_for_group_start() ||
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !to_return->IsFirstElementThreaded())
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return to_return.release();
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The removed sequence may have been responsible for making other sequences
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // wait for a group start. If no other sequences in the group have a
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // threaded first element, the group no longer needs the additional wait.
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_wait_still_needed = false;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int group_id = to_return->animation_group_id();
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (((*queue_iter)->animation_group_id() == group_id) &&
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (*queue_iter)->IsFirstElementThreaded()) {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_wait_still_needed = true;
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_wait_still_needed)
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return to_return.release();
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*queue_iter)->animation_group_id() == group_id &&
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (*queue_iter)->waiting_for_group_start()) {
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*queue_iter)->set_waiting_for_group_start(false);
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (is_running) {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (*queue_iter)->set_start_time(last_step_time_);
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (*queue_iter)->Start(delegate());
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return to_return.release();
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LayerAnimator::FinishAnimation(
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerAnimationSequence* sequence, bool abort) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (abort)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sequence->Abort(delegate());
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProgressAnimationToEnd(sequence);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessQueue();
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Special case: if we've started a 0 duration animation, just finish it now
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and get rid of it. We need to make a copy because Progress may indirectly
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cause new animations to start running.
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunningAnimations running_animations_copy = running_animations_;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (running_animations_copy[i].sequence()->IsFinished(
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          running_animations_copy[i].sequence()->start_time())) {
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<LayerAnimationSequence> removed(
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessQueue();
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ClearAnimations() {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearAnimationsInternal();
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation(
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationElement::AnimatableProperty property) {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PurgeDeletedAnimations();
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RunningAnimations::iterator iter = running_animations_.begin();
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != running_animations_.end(); ++iter) {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*iter).sequence()->properties().find(property) !=
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (*iter).sequence()->properties().end())
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(*iter);
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::AddToQueueIfNotPresent(LayerAnimationSequence* animation) {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we don't have the animation in the queue yet, add it.
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool found_sequence = false;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*queue_iter) == animation) {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found_sequence = true;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!found_sequence)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    animation_queue_.push_front(make_linked_ptr(animation));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::RemoveAllAnimationsWithACommonProperty(
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationSequence* sequence, bool abort) {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For all the running animations, if they animate the same property,
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // progress them to the end and remove them. Note, Aborting or Progressing
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // animations may affect the collection of running animations, so we need to
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // operate on a copy.
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunningAnimations running_animations_copy = running_animations_;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (running_animations_copy[i].sequence()->HasConflictingProperty(
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sequence->properties())) {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<LayerAnimationSequence> removed(
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (abort)
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        running_animations_copy[i].sequence()->Abort(delegate());
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Same for the queued animations that haven't been started. Again, we'll
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // need to operate on a copy.
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sequences.push_back((*queue_iter)->AsWeakPtr());
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < sequences.size(); ++i) {
611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (sequences[i]->HasConflictingProperty(sequence->properties())) {
615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      scoped_ptr<LayerAnimationSequence> removed(
616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          RemoveAnimation(sequences[i].get()));
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (abort)
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        sequences[i]->Abort(delegate());
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        ProgressAnimationToEnd(sequences[i].get());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to detect if our sequence gets destroyed.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence->AsWeakPtr();
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool abort = false;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveAllAnimationsWithACommonProperty(sequence, abort);
632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!weak_sequence_ptr.get())
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayerAnimationSequence* removed = RemoveAnimation(sequence);
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(removed == NULL || removed == sequence);
637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!weak_sequence_ptr.get())
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProgressAnimationToEnd(sequence);
641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!weak_sequence_ptr.get())
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete sequence;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ImmediatelyAnimateToNewTarget(
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationSequence* sequence) {
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to detect if our sequence gets destroyed.
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence->AsWeakPtr();
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool abort = true;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveAllAnimationsWithACommonProperty(sequence, abort);
655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!weak_sequence_ptr.get())
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddToQueueIfNotPresent(sequence);
659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!weak_sequence_ptr.get())
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSequenceImmediately(sequence);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::EnqueueNewAnimation(LayerAnimationSequence* sequence) {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It is assumed that if there was no conflicting animation, we would
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not have been called. No need to check for a collision; just
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // add to the queue.
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation_queue_.push_back(make_linked_ptr(sequence));
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessQueue();
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ReplaceQueuedAnimations(LayerAnimationSequence* sequence) {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to detect if our sequence gets destroyed.
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence->AsWeakPtr();
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove all animations that aren't running. Note: at each iteration i is
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // incremented or an element is removed from the queue, so
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // animation_queue_.size() - i is always decreasing and we are always making
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // progress towards the loop terminating.
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < animation_queue_.size();) {
683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!weak_sequence_ptr.get())
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PurgeDeletedAnimations();
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_running = false;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (RunningAnimations::const_iterator iter = running_animations_.begin();
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         iter != running_animations_.end(); ++iter) {
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if ((*iter).sequence() == animation_queue_[i].get()) {
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        is_running = true;
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_running)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete RemoveAnimation(animation_queue_[i].get());
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++i;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation_queue_.push_back(make_linked_ptr(sequence));
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessQueue();
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ProcessQueue() {
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool started_sequence = false;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    started_sequence = false;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build a list of all currently animated properties.
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationElement::AnimatableProperties animated;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (RunningAnimations::const_iterator iter = running_animations_.begin();
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         iter != running_animations_.end(); ++iter) {
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!(*iter).is_sequence_alive())
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      animated.insert((*iter).sequence()->properties().begin(),
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      (*iter).sequence()->properties().end());
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Try to find an animation that doesn't conflict with an animated
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // property or a property that will be animated before it. Note: starting
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the animation may indirectly cause more animations to be started, so we
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // need to operate on a copy.
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         queue_iter != animation_queue_.end(); ++queue_iter)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequences.push_back((*queue_iter)->AsWeakPtr());
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < sequences.size(); ++i) {
730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!sequences[i]->HasConflictingProperty(animated)) {
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        StartSequenceImmediately(sequences[i].get());
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        started_sequence = true;
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Animation couldn't be started. Add its properties to the collection so
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // that we don't start a conflicting animation. For example, if our queue
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // has the elements { {T,B}, {B} } (that is, an element that animates both
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the transform and the bounds followed by an element that animates the
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // bounds), and we're currently animating the transform, we can't start
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the first element because it animates the transform, too. We cannot
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // start the second element, either, because the first element animates
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // bounds too, and needs to go first.
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      animated.insert(sequences[i]->properties().begin(),
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      sequences[i]->properties().end());
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we started a sequence, try again. We may be able to start several.
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (started_sequence);
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) {
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PurgeDeletedAnimations();
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that no one is animating one of the sequence's properties already.
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RunningAnimations::const_iterator iter = running_animations_.begin();
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != running_animations_.end(); ++iter) {
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All clear, actually start the sequence. Note: base::TimeTicks::Now has
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a resolution that can be as bad as 15ms. If this causes glitches in the
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // animations, this can be switched to HighResNow() (animation uses Now()
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // internally).
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All LayerAnimators share the same AnimationContainer. Use the
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // last_tick_time() from there to ensure animations started during the same
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // event complete at the same time.
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks start_time;
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_animating() || adding_animations_)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    start_time = last_step_time_;
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (GetAnimationContainer()->is_running())
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    start_time = GetAnimationContainer()->last_tick_time();
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
7781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    start_time = gfx::FrameTime::Now();
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!sequence->animation_group_id())
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!sequence->waiting_for_group_start() ||
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sequence->IsFirstElementThreaded()) {
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sequence->set_start_time(start_time);
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sequence->Start(delegate());
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  running_animations_.push_back(
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RunningAnimation(sequence->AsWeakPtr()));
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to keep a reference to the animation.
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddToQueueIfNotPresent(sequence);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that animations get stepped at their start time.
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Step(start_time);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::GetTargetValue(
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationElement::TargetValue* target) const {
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::const_iterator iter = animation_queue_.begin();
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != animation_queue_.end(); ++iter) {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*iter)->GetTargetValue(target);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observers_.might_have_observers()) {
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ObserverListBase<LayerAnimationObserver>::Iterator it(observers_);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationObserver* obs;
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((obs = it.GetNext()) != NULL) {
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence->AddObserver(obs);
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sequence->OnScheduled();
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
818a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void LayerAnimator::SetTransitionDuration(base::TimeDelta duration) {
819a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (is_transition_duration_locked_)
820a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
821a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  transition_duration_ = duration;
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ClearAnimationsInternal() {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PurgeDeletedAnimations();
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Abort should never affect the set of running animations, but just in case
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clients are badly behaved, we will use a copy of the running animations.
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunningAnimations running_animations_copy = running_animations_;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<LayerAnimationSequence> removed(
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RemoveAnimation(running_animations_copy[i].sequence()));
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (removed.get())
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      removed->Abort(delegate());
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This *should* have cleared the list of running animations.
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(running_animations_.empty());
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  running_animations_.clear();
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation_queue_.clear();
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::PurgeDeletedAnimations() {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_.size();) {
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!running_animations_[i].is_sequence_alive())
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      running_animations_.erase(running_animations_.begin() + i);
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      i++;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::RunningAnimation::RunningAnimation(
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::WeakPtr<LayerAnimationSequence>& sequence)
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : sequence_(sequence) {
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::RunningAnimation::~RunningAnimation() { }
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
863