blob: cd5747926d409c0f77aa7ec1cd839aeaf67b12d1 [file] [log] [blame]
// 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/compiler_specific.h"
#include "ui/compositor/compositor_export.h"
#include "ui/compositor/layer_animation_element.h"
namespace ui {
namespace test {
class LayerAnimationObserverTestApi;
} // namespace test
class LayerAnimationSequence;
class ScopedLayerAnimationSettings;
class ImplicitAnimationObserver;
// LayerAnimationObservers are notified when animations complete.
class COMPOSITOR_EXPORT LayerAnimationObserver {
public:
// Called when the |sequence| starts.
virtual void OnLayerAnimationStarted(LayerAnimationSequence* sequence);
// 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 LayerAnimator 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. An observer who wants to
// receive the NotifyAborted notifications during destruction can override
// this function to return true.
//
// *** IMPORTANT ***: If a class overrides this function to return true and
// that class is a direct or indirect owner of the LayerAnimationSequence
// being observed, then the class must explicitly remove itself as an
// observer during destruction of the LayerAnimationObserver! This is to
// ensure that a partially destroyed observer isn't notified with an
// OnLayerAnimationAborted() call when the LayerAnimator is destroyed.
//
// This opt-in pattern is used because it is common for a class to be the
// observer of a LayerAnimationSequence that it owns indirectly because it
// owns the Layer which owns the LayerAnimator which owns the
// LayerAnimationSequence.
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;
friend class test::LayerAnimationObserverTestApi;
// 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.
// TODO(bruthig): Unify the ImplicitAnimationObserver with the
// CallbackLayerAnimationObserver. (See www.crbug.com/542825).
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_