layer_animation_observer.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/compositor/layer_animation_observer.h"
6
7#include "ui/compositor/layer_animation_sequence.h"
8
9namespace ui {
10
11////////////////////////////////////////////////////////////////////////////////
12// LayerAnimationObserver
13
14LayerAnimationObserver::LayerAnimationObserver() {
15}
16
17LayerAnimationObserver::~LayerAnimationObserver() {
18  StopObserving();
19}
20
21bool LayerAnimationObserver::RequiresNotificationWhenAnimatorDestroyed() const {
22  return false;
23}
24
25void LayerAnimationObserver::OnAttachedToSequence(
26    LayerAnimationSequence* sequence) {
27}
28
29void LayerAnimationObserver::OnDetachedFromSequence(
30    LayerAnimationSequence* sequence) {
31}
32
33void LayerAnimationObserver::StopObserving() {
34  while (!attached_sequences_.empty()) {
35    LayerAnimationSequence* sequence = *attached_sequences_.begin();
36    sequence->RemoveObserver(this);
37  }
38}
39
40void LayerAnimationObserver::AttachedToSequence(
41    LayerAnimationSequence* sequence) {
42  DCHECK(attached_sequences_.find(sequence) == attached_sequences_.end());
43  attached_sequences_.insert(sequence);
44  OnAttachedToSequence(sequence);
45}
46
47void LayerAnimationObserver::DetachedFromSequence(
48    LayerAnimationSequence* sequence, bool send_notification) {
49  if (attached_sequences_.find(sequence) != attached_sequences_.end())
50    attached_sequences_.erase(sequence);
51  if (send_notification)
52    OnDetachedFromSequence(sequence);
53}
54
55////////////////////////////////////////////////////////////////////////////////
56// ImplicitAnimationObserver
57
58ImplicitAnimationObserver::ImplicitAnimationObserver()
59    : active_(false),
60      destroyed_(NULL),
61      first_sequence_scheduled_(false) {
62}
63
64ImplicitAnimationObserver::~ImplicitAnimationObserver() {
65  if (destroyed_)
66    *destroyed_ = true;
67}
68
69void ImplicitAnimationObserver::SetActive(bool active) {
70  active_ = active;
71  CheckCompleted();
72}
73
74void ImplicitAnimationObserver::StopObservingImplicitAnimations() {
75  SetActive(false);
76  StopObserving();
77}
78
79bool ImplicitAnimationObserver::WasAnimationAbortedForProperty(
80    LayerAnimationElement::AnimatableProperty property) const {
81  return AnimationStatusForProperty(property) == ANIMATION_STATUS_ABORTED;
82}
83
84bool ImplicitAnimationObserver::WasAnimationCompletedForProperty(
85    LayerAnimationElement::AnimatableProperty property) const {
86  return AnimationStatusForProperty(property) == ANIMATION_STATUS_COMPLETED;
87}
88
89void ImplicitAnimationObserver::OnLayerAnimationEnded(
90    LayerAnimationSequence* sequence) {
91  UpdatePropertyAnimationStatus(sequence, ANIMATION_STATUS_COMPLETED);
92  bool destroyed = false;
93  destroyed_ = &destroyed;
94  sequence->RemoveObserver(this);
95  if (destroyed)
96    return;
97  destroyed_ = NULL;
98  DCHECK(attached_sequences().find(sequence) == attached_sequences().end());
99  CheckCompleted();
100}
101
102void ImplicitAnimationObserver::OnLayerAnimationAborted(
103    LayerAnimationSequence* sequence) {
104  UpdatePropertyAnimationStatus(sequence, ANIMATION_STATUS_ABORTED);
105  bool destroyed = false;
106  destroyed_ = &destroyed;
107  sequence->RemoveObserver(this);
108  if (destroyed)
109    return;
110  destroyed_ = NULL;
111  DCHECK(attached_sequences().find(sequence) == attached_sequences().end());
112  CheckCompleted();
113}
114
115void ImplicitAnimationObserver::OnLayerAnimationScheduled(
116    LayerAnimationSequence* sequence) {
117  if (!first_sequence_scheduled_) {
118    first_sequence_scheduled_ = true;
119    OnImplicitAnimationsScheduled();
120  }
121}
122
123void ImplicitAnimationObserver::OnAttachedToSequence(
124    LayerAnimationSequence* sequence) {
125}
126
127void ImplicitAnimationObserver::OnDetachedFromSequence(
128    LayerAnimationSequence* sequence) {
129  DCHECK(attached_sequences().find(sequence) == attached_sequences().end());
130  CheckCompleted();
131}
132
133void ImplicitAnimationObserver::CheckCompleted() {
134  if (active_ && attached_sequences().empty()) {
135    active_ = false;
136    OnImplicitAnimationsCompleted();
137  }
138}
139
140void ImplicitAnimationObserver::UpdatePropertyAnimationStatus(
141    LayerAnimationSequence* sequence,
142    AnimationStatus status) {
143  LayerAnimationElement::AnimatableProperties properties =
144      sequence->properties();
145  for (unsigned i = LayerAnimationElement::FIRST_PROPERTY;
146       i != LayerAnimationElement::SENTINEL;
147       i = i << 1) {
148    if (i & properties) {
149      LayerAnimationElement::AnimatableProperty property =
150          static_cast<LayerAnimationElement::AnimatableProperty>(i);
151      property_animation_status_[property] = status;
152    }
153  }
154}
155
156ImplicitAnimationObserver::AnimationStatus
157ImplicitAnimationObserver::AnimationStatusForProperty(
158    LayerAnimationElement::AnimatableProperty property) const {
159  PropertyAnimationStatusMap::const_iterator iter =
160      property_animation_status_.find(property);
161  return iter == property_animation_status_.end() ? ANIMATION_STATUS_UNKNOWN :
162      iter->second;
163}
164
165}  // namespace ui
166