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"
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
34 class TestSessionStateAnimator::AnimationSequence
35 : public SessionStateAnimator::AnimationSequence
{
37 AnimationSequence(base::Closure callback
, TestSessionStateAnimator
* animator
)
38 : SessionStateAnimator::AnimationSequence(callback
),
40 sequence_aborted_(false),
44 ~AnimationSequence() override
{}
46 virtual void SequenceAttached() {
50 // Notify the sequence that is has completed.
51 virtual void SequenceFinished(bool successfully
) {
52 DCHECK_GT(sequence_count_
, 0);
54 sequence_aborted_
|= !successfully
;
55 if (sequence_count_
== 0) {
56 if (sequence_aborted_
)
59 OnAnimationCompleted();
63 // ash::SessionStateAnimator::AnimationSequence:
64 void StartAnimation(int container_mask
,
66 AnimationSpeed speed
) override
{
67 animator_
->StartAnimationInSequence(container_mask
, type
, speed
, this);
71 // Tracks the number of contained animations.
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(
85 base::TimeDelta duration
,
86 SessionStateAnimator::Container container
,
89 base::Closure success_callback
,
90 base::Closure failed_callback
)
91 : animation_epoch(animation_epoch
),
92 remaining_duration(duration
),
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();
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
);
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();
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();
149 active_animation
.failed_callback
.Run();
150 animation_iter
= (*container_iter
).second
.erase(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();
173 const ActiveAnimation
& active_animation
= *animation_iter
;
174 if (active_animation
.type
== type
)
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
)) {
192 size_t TestSessionStateAnimator::GetAnimationCount() const {
194 for (ActiveAnimationsMap::const_iterator container_iter
=
195 active_animations_
.begin();
196 container_iter
!= active_animations_
.end();
198 count
+= (*container_iter
).second
.size();
203 void TestSessionStateAnimator::StartAnimation(int container_mask
,
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(
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(
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
,
269 void TestSessionStateAnimator::AddAnimation(
270 SessionStateAnimator::Container container
,
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_
,
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
);