OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "ash/test/test_session_state_animator.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/bind.h" | |
10 | |
11 namespace ash { | |
12 namespace test { | |
13 | |
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() {} | |
18 } | |
19 | |
20 const SessionStateAnimator::Container | |
21 TestSessionStateAnimator::kAllContainers[] = { | |
22 SessionStateAnimator::DESKTOP_BACKGROUND, | |
flackr
2014/09/10 19:38:37
nit: I believe this should be an indent of 4 (from
bruthig
2014/09/12 15:30:06
Done.
| |
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 | |
29 }; | |
30 | |
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) { | |
42 } | |
43 | |
44 virtual ~AnimationSequence() {} | |
45 | |
46 virtual void SequenceAttached() { | |
47 ++sequence_count_; | |
48 } | |
49 | |
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(); | |
60 } | |
61 } | |
62 | |
63 // ash::SessionStateAnimator::AnimationSequence: | |
64 virtual void StartAnimation(int container_mask, | |
65 AnimationType type, | |
66 AnimationSpeed speed) OVERRIDE { | |
67 animator_->StartAnimationInSequence(container_mask, type, speed, this); | |
68 } | |
69 | |
70 private: | |
71 // Tracks the number of contained animations. | |
72 int sequence_count_; | |
73 | |
74 // True if the sequence was aborted. | |
75 bool sequence_aborted_; | |
76 | |
77 // The TestSessionAnimator that created this. Not owned. | |
78 TestSessionStateAnimator* animator_; | |
79 | |
80 DISALLOW_COPY_AND_ASSIGN(AnimationSequence); | |
81 }; | |
82 | |
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) { | |
98 } | |
99 | |
100 TestSessionStateAnimator::ActiveAnimation::~ActiveAnimation() { | |
101 } | |
102 | |
103 TestSessionStateAnimator::TestSessionStateAnimator() | |
104 : last_animation_epoch_(0), | |
105 is_background_hidden_(false) { | |
106 } | |
107 | |
108 TestSessionStateAnimator::~TestSessionStateAnimator() { | |
109 CompleteAllAnimations(false); | |
110 } | |
111 | |
112 void TestSessionStateAnimator::ResetAnimationEpoch() { | |
113 CompleteAllAnimations(false); | |
114 last_animation_epoch_ = 0; | |
115 } | |
116 | |
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; | |
131 } | |
132 } | |
133 } | |
134 } | |
135 | |
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; | |
153 } | |
154 } | |
155 } | |
156 } | |
157 | |
158 void TestSessionStateAnimator::CompleteAllAnimations( | |
159 bool completed_successfully) { | |
160 CompleteAnimations(last_animation_epoch_, completed_successfully); | |
161 } | |
162 | |
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; | |
176 } | |
177 } | |
178 return false; | |
179 } | |
180 | |
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; | |
187 } | |
188 } | |
189 return true; | |
190 } | |
191 | |
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(); | |
199 } | |
200 return count; | |
201 } | |
202 | |
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); | |
213 } | |
214 } | |
215 } | |
216 | |
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); | |
228 } | |
229 } | |
230 | |
231 ash::SessionStateAnimator::AnimationSequence* | |
232 TestSessionStateAnimator::BeginAnimationSequence(base::Closure callback) { | |
233 return new AnimationSequence(callback, this); | |
234 } | |
235 | |
236 bool TestSessionStateAnimator::IsBackgroundHidden() const { | |
237 return is_background_hidden_; | |
238 } | |
239 | |
240 void TestSessionStateAnimator::ShowBackground() { | |
241 is_background_hidden_ = false; | |
242 } | |
243 | |
244 void TestSessionStateAnimator::HideBackground() { | |
245 is_background_hidden_ = true; | |
246 } | |
247 | |
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); | |
265 } | |
266 } | |
267 } | |
268 | |
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); | |
287 } | |
288 | |
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); | |
299 } | |
300 } | |
301 } | |
302 | |
303 } // namespace test | |
304 } // namespace ash | |
OLD | NEW |