Added llvm into exceptions as we can't add README.chromium into 3rd party repository
[chromium-blink-merge.git] / ash / test / test_session_state_animator.cc
blobf16a1c5a978c2762afece68261aa2b72cacdd833
1 // Copyright 2014 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.
5 #include "ash/test/test_session_state_animator.h"
7 #include <vector>
9 #include "base/bind.h"
11 namespace ash {
12 namespace test {
14 namespace {
15 // A no-op callback that can be used when managing an animation that didn't
16 // actually have a callback given.
17 void DummyCallback() {}
20 const SessionStateAnimator::Container
21 TestSessionStateAnimator::kAllContainers[] = {
22 SessionStateAnimator::DESKTOP_BACKGROUND,
23 SessionStateAnimator::LAUNCHER,
24 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
25 SessionStateAnimator::LOCK_SCREEN_BACKGROUND,
26 SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
27 SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS,
28 SessionStateAnimator::ROOT_CONTAINER
31 // A simple SessionStateAnimator::AnimationSequence that tracks the number of
32 // attached sequences. The callback will be invoked if all animations complete
33 // successfully.
34 class TestSessionStateAnimator::AnimationSequence
35 : public SessionStateAnimator::AnimationSequence {
36 public:
37 AnimationSequence(base::Closure callback, TestSessionStateAnimator* animator)
38 : SessionStateAnimator::AnimationSequence(callback),
39 sequence_count_(0),
40 sequence_aborted_(false),
41 animator_(animator) {
44 ~AnimationSequence() override {}
46 virtual void SequenceAttached() {
47 ++sequence_count_;
50 // Notify the sequence that is has completed.
51 virtual void SequenceFinished(bool successfully) {
52 DCHECK_GT(sequence_count_, 0);
53 --sequence_count_;
54 sequence_aborted_ |= !successfully;
55 if (sequence_count_ == 0) {
56 if (sequence_aborted_)
57 OnAnimationAborted();
58 else
59 OnAnimationCompleted();
63 // ash::SessionStateAnimator::AnimationSequence:
64 void StartAnimation(int container_mask,
65 AnimationType type,
66 AnimationSpeed speed) override {
67 animator_->StartAnimationInSequence(container_mask, type, speed, this);
70 private:
71 // Tracks the number of contained animations.
72 int sequence_count_;
74 // True if the sequence was aborted.
75 bool sequence_aborted_;
77 // The TestSessionAnimator that created this. Not owned.
78 TestSessionStateAnimator* animator_;
80 DISALLOW_COPY_AND_ASSIGN(AnimationSequence);
83 TestSessionStateAnimator::ActiveAnimation::ActiveAnimation(
84 int animation_epoch,
85 base::TimeDelta duration,
86 SessionStateAnimator::Container container,
87 AnimationType type,
88 AnimationSpeed speed,
89 base::Closure success_callback,
90 base::Closure failed_callback)
91 : animation_epoch(animation_epoch),
92 remaining_duration(duration),
93 container(container),
94 type(type),
95 speed(speed),
96 success_callback(success_callback),
97 failed_callback(failed_callback) {
100 TestSessionStateAnimator::ActiveAnimation::~ActiveAnimation() {
103 TestSessionStateAnimator::TestSessionStateAnimator()
104 : last_animation_epoch_(0),
105 is_background_hidden_(false) {
108 TestSessionStateAnimator::~TestSessionStateAnimator() {
109 CompleteAllAnimations(false);
112 void TestSessionStateAnimator::ResetAnimationEpoch() {
113 CompleteAllAnimations(false);
114 last_animation_epoch_ = 0;
117 void TestSessionStateAnimator::Advance(const base::TimeDelta& duration) {
118 for (ActiveAnimationsMap::iterator container_iter =
119 active_animations_.begin();
120 container_iter != active_animations_.end();
121 ++container_iter) {
122 AnimationList::iterator animation_iter = (*container_iter).second.begin();
123 while (animation_iter != (*container_iter).second.end()) {
124 ActiveAnimation& active_animation = *animation_iter;
125 active_animation.remaining_duration -= duration;
126 if (active_animation.remaining_duration <= base::TimeDelta()) {
127 active_animation.success_callback.Run();
128 animation_iter = (*container_iter).second.erase(animation_iter);
129 } else {
130 ++animation_iter;
136 void TestSessionStateAnimator::CompleteAnimations(int animation_epoch,
137 bool completed_successfully) {
138 for (ActiveAnimationsMap::iterator container_iter =
139 active_animations_.begin();
140 container_iter != active_animations_.end();
141 ++container_iter) {
142 AnimationList::iterator animation_iter = (*container_iter).second.begin();
143 while (animation_iter != (*container_iter).second.end()) {
144 ActiveAnimation active_animation = *animation_iter;
145 if (active_animation.animation_epoch <= animation_epoch) {
146 if (completed_successfully)
147 active_animation.success_callback.Run();
148 else
149 active_animation.failed_callback.Run();
150 animation_iter = (*container_iter).second.erase(animation_iter);
151 } else {
152 ++animation_iter;
158 void TestSessionStateAnimator::CompleteAllAnimations(
159 bool completed_successfully) {
160 CompleteAnimations(last_animation_epoch_, completed_successfully);
163 bool TestSessionStateAnimator::IsContainerAnimated(
164 SessionStateAnimator::Container container,
165 SessionStateAnimator::AnimationType type) const {
166 ActiveAnimationsMap::const_iterator container_iter =
167 active_animations_.find(container);
168 if (container_iter != active_animations_.end()) {
169 for (AnimationList::const_iterator animation_iter =
170 (*container_iter).second.begin();
171 animation_iter != (*container_iter).second.end();
172 ++animation_iter) {
173 const ActiveAnimation& active_animation = *animation_iter;
174 if (active_animation.type == type)
175 return true;
178 return false;
181 bool TestSessionStateAnimator::AreContainersAnimated(
182 int container_mask, SessionStateAnimator::AnimationType type) const {
183 for (size_t i = 0; i < arraysize(kAllContainers); ++i) {
184 if (container_mask & kAllContainers[i] &&
185 !IsContainerAnimated(kAllContainers[i], type)) {
186 return false;
189 return true;
192 size_t TestSessionStateAnimator::GetAnimationCount() const {
193 size_t count = 0;
194 for (ActiveAnimationsMap::const_iterator container_iter =
195 active_animations_.begin();
196 container_iter != active_animations_.end();
197 ++container_iter) {
198 count += (*container_iter).second.size();
200 return count;
203 void TestSessionStateAnimator::StartAnimation(int container_mask,
204 AnimationType type,
205 AnimationSpeed speed) {
206 ++last_animation_epoch_;
207 for (size_t i = 0; i < arraysize(kAllContainers); ++i) {
208 if (container_mask & kAllContainers[i]) {
209 // Use a dummy no-op callback because one isn't required by the client
210 // but one is required when completing or aborting animations.
211 base::Closure callback = base::Bind(&DummyCallback);
212 AddAnimation(kAllContainers[i], type, speed, callback, callback);
217 void TestSessionStateAnimator::StartAnimationWithCallback(
218 int container_mask,
219 AnimationType type,
220 AnimationSpeed speed,
221 base::Closure callback) {
222 ++last_animation_epoch_;
223 for (size_t i = 0; i < arraysize(kAllContainers); ++i)
224 if (container_mask & kAllContainers[i]) {
225 // ash::SessionStateAnimatorImpl invokes the callback whether or not the
226 // animation was completed successfully or not.
227 AddAnimation(kAllContainers[i], type, speed, callback, callback);
231 ash::SessionStateAnimator::AnimationSequence*
232 TestSessionStateAnimator::BeginAnimationSequence(base::Closure callback) {
233 return new AnimationSequence(callback, this);
236 bool TestSessionStateAnimator::IsBackgroundHidden() const {
237 return is_background_hidden_;
240 void TestSessionStateAnimator::ShowBackground() {
241 is_background_hidden_ = false;
244 void TestSessionStateAnimator::HideBackground() {
245 is_background_hidden_ = true;
248 void TestSessionStateAnimator::StartAnimationInSequence(
249 int container_mask,
250 AnimationType type,
251 AnimationSpeed speed,
252 AnimationSequence* animation_sequence) {
253 ++last_animation_epoch_;
254 for (size_t i = 0; i < arraysize(kAllContainers); ++i) {
255 if (container_mask & kAllContainers[i]) {
256 base::Closure success_callback =
257 base::Bind(&AnimationSequence::SequenceFinished,
258 base::Unretained(animation_sequence), true);
259 base::Closure failed_callback =
260 base::Bind(&AnimationSequence::SequenceFinished,
261 base::Unretained(animation_sequence), false);
262 animation_sequence->SequenceAttached();
263 AddAnimation(kAllContainers[i], type, speed, success_callback,
264 failed_callback);
269 void TestSessionStateAnimator::AddAnimation(
270 SessionStateAnimator::Container container,
271 AnimationType type,
272 AnimationSpeed speed,
273 base::Closure success_callback,
274 base::Closure failed_callback) {
275 base::TimeDelta duration = GetDuration(speed);
276 ActiveAnimation active_animation(last_animation_epoch_,
277 duration,
278 container,
279 type,
280 speed,
281 success_callback,
282 failed_callback);
283 // This test double is limited to only have one animation active for a given
284 // container at a time.
285 AbortAnimation(container);
286 active_animations_[container].push_back(active_animation);
289 void TestSessionStateAnimator::AbortAnimation(
290 SessionStateAnimator::Container container) {
291 ActiveAnimationsMap::iterator container_iter =
292 active_animations_.find(container);
293 if (container_iter != active_animations_.end()) {
294 AnimationList::iterator animation_iter = (*container_iter).second.begin();
295 while (animation_iter != (*container_iter).second.end()) {
296 ActiveAnimation active_animation = *animation_iter;
297 active_animation.failed_callback.Run();
298 animation_iter = (*container_iter).second.erase(animation_iter);
303 } // namespace test
304 } // namespace ash