text: // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef UI_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_
  #define UI_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_
  
  #include <map>
  #include <set>
  
  #include "base/basictypes.h"
  #include "base/compiler_specific.h"
  #include "ui/compositor/compositor_export.h"
  #include "ui/compositor/layer_animation_element.h"
  
  namespace ui {
  
  class LayerAnimationSequence;
  class ScopedLayerAnimationSettings;
  class ImplicitAnimationObserver;
  
  // LayerAnimationObservers are notified when animations complete.
  class COMPOSITOR_EXPORT LayerAnimationObserver  {
   public:
    // Called when the |sequence| ends. Not called if |sequence| is aborted.
    virtual void OnLayerAnimationEnded(
        LayerAnimationSequence* sequence) = 0;
  
    // Called if |sequence| is aborted for any reason. Should never do anything
    // that may cause another animation to be started.
    virtual void OnLayerAnimationAborted(
        LayerAnimationSequence* sequence) = 0;
  
    // Called when the animation is scheduled.
    virtual void OnLayerAnimationScheduled(
        LayerAnimationSequence* sequence) = 0;
  
   protected:
    typedef std::set<LayerAnimationSequence*> AttachedSequences;
  
    LayerAnimationObserver();
    virtual ~LayerAnimationObserver();
  
    // If the animator is destroyed during an animation, the animations are
    // aborted. The resulting NotifyAborted notifications will NOT be sent to
    // this observer if this function returns false. NOTE: IF YOU override THIS
    // FUNCTION TO RETURN TRUE, YOU MUST REMEMBER TO REMOVE YOURSELF AS AN
    // OBSERVER WHEN YOU ARE DESTROYED.
    virtual bool RequiresNotificationWhenAnimatorDestroyed() const;
  
    // Called when |this| is added to |sequence|'s observer list.
    virtual void OnAttachedToSequence(LayerAnimationSequence* sequence);
  
    // Called when |this| is removed to |sequence|'s observer list.
    virtual void OnDetachedFromSequence(LayerAnimationSequence* sequence);
  
    // Detaches this observer from all sequences it is currently observing.
    void StopObserving();
  
    const AttachedSequences& attached_sequences() const {
      return attached_sequences_;
    }
  
   private:
    friend class LayerAnimationSequence;
  
    // Called when |this| is added to |sequence|'s observer list.
    void AttachedToSequence(LayerAnimationSequence* sequence);
  
    // Called when |this| is removed to |sequence|'s observer list.
    // This will only result in notifications if |send_notification| is true.
    void DetachedFromSequence(LayerAnimationSequence* sequence,
                              bool send_notification);
  
    AttachedSequences attached_sequences_;
  };
  
  // An implicit animation observer is intended to be used in conjunction with a
  // ScopedLayerAnimationSettings object in order to receive a notification when
  // all implicit animations complete.
  class COMPOSITOR_EXPORT ImplicitAnimationObserver
      : public LayerAnimationObserver {
   public:
    ImplicitAnimationObserver();
    ~ImplicitAnimationObserver() override;
  
    // Called when the first animation sequence has started.
    virtual void OnImplicitAnimationsScheduled() {}
  
    virtual void OnImplicitAnimationsCompleted() = 0;
  
   protected:
    // Deactivates the observer and clears the collection of animations it is
    // waiting for.
    void StopObservingImplicitAnimations();
  
    // Returns whether animation for |property| was aborted.
    // Note that if the property wasn't animated, then it couldn't have been
    // aborted, so this will return false for that property.
    bool WasAnimationAbortedForProperty(
        LayerAnimationElement::AnimatableProperty property) const;
  
    // Returns whether animation for |property| was completed successfully.
    // Note that if the property wasn't animated, then it couldn't have been
    // completed, so this will return false for that property.
    bool WasAnimationCompletedForProperty(
        LayerAnimationElement::AnimatableProperty property) const;
  
   private:
    enum AnimationStatus {
      ANIMATION_STATUS_UNKNOWN,
      ANIMATION_STATUS_COMPLETED,
      ANIMATION_STATUS_ABORTED,
    };
  
    friend class ScopedLayerAnimationSettings;
  
    // LayerAnimationObserver implementation
    void OnLayerAnimationEnded(LayerAnimationSequence* sequence) override;
    void OnLayerAnimationAborted(LayerAnimationSequence* sequence) override;
    void OnLayerAnimationScheduled(LayerAnimationSequence* sequence) override;
    void OnAttachedToSequence(LayerAnimationSequence* sequence) override;
    void OnDetachedFromSequence(LayerAnimationSequence* sequence) override;
  
    // OnImplicitAnimationsCompleted is not fired unless the observer is active.
    bool active() const { return active_; }
    void SetActive(bool active);
  
    void CheckCompleted();
  
    void UpdatePropertyAnimationStatus(LayerAnimationSequence* sequence,
                                       AnimationStatus status);
    AnimationStatus AnimationStatusForProperty(
        LayerAnimationElement::AnimatableProperty property) const;
  
    bool active_;
  
    // Set to true in the destructor (if non-NULL). Used to detect deletion while
    // calling out.
    bool* destroyed_;
  
    typedef std::map<LayerAnimationElement::AnimatableProperty,
                     AnimationStatus> PropertyAnimationStatusMap;
    PropertyAnimationStatusMap property_animation_status_;
  
    // True if OnLayerAnimationScheduled() has been called at least once.
    bool first_sequence_scheduled_;
  };
  
  }  // namespace ui
  
  #endif  // UI_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_
  