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 #include "base/time/time.h" | |
Daniel Erat
2014/09/08 16:16:01
nit: move this to the header since you use time st
bruthig
2014/09/09 17:32:32
Done.
| |
11 | |
12 namespace ash { | |
13 namespace test { | |
14 | |
15 namespace { | |
16 // A no-op callback that can be used when managing an animation that didn't | |
17 // actually have a callback given. | |
18 void DummyCallback() {} | |
Daniel Erat
2014/09/08 16:16:01
i could swear that something like this already dec
| |
19 } | |
20 | |
21 const SessionStateAnimator::Container | |
22 TestSessionStateAnimator::kAllContainers[] = { | |
23 SessionStateAnimator::DESKTOP_BACKGROUND, | |
24 SessionStateAnimator::LAUNCHER, | |
25 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
26 SessionStateAnimator::LOCK_SCREEN_BACKGROUND, | |
27 SessionStateAnimator::LOCK_SCREEN_CONTAINERS, | |
28 SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS, | |
29 SessionStateAnimator::ROOT_CONTAINER | |
30 }; | |
31 | |
32 // A simple SessionStateAnimator::AnimationSequence that tracks the number of | |
33 // attached sequences. The callback will be invoked if all animations complete | |
34 // successfully. | |
35 class TestSessionStateAnimator::AnimationSequence | |
36 : public SessionStateAnimator::AnimationSequence { | |
37 public: | |
38 AnimationSequence(base::Closure callback, TestSessionStateAnimator* animator) | |
39 : SessionStateAnimator::AnimationSequence(callback), | |
40 sequence_count_(0), | |
41 sequence_aborted_(false), | |
42 animator_(animator) { | |
43 } | |
44 | |
45 virtual ~AnimationSequence() {} | |
46 | |
47 virtual void SequenceAttached() { | |
48 ++sequence_count_; | |
49 } | |
50 | |
51 // Notify the sequence that is has completed. | |
52 virtual void SequenceFinished(bool successfully) { | |
53 DCHECK_GT(sequence_count_, 0); | |
54 --sequence_count_; | |
55 sequence_aborted_ |= !successfully; | |
56 if (sequence_count_ == 0) { | |
57 if (sequence_aborted_) | |
58 OnAnimationAborted(); | |
59 else | |
60 OnAnimationCompleted(); | |
61 } | |
62 } | |
63 | |
64 // ash::SessionStateAnimator::AnimationSequence: | |
65 virtual void StartAnimation(int container_mask, | |
66 AnimationType type, | |
67 AnimationSpeed speed) OVERRIDE { | |
68 animator_->StartAnimationInSequence(container_mask, type, speed, this); | |
69 } | |
70 | |
71 private: | |
72 // Tracks the number of contained animations. | |
73 int sequence_count_; | |
74 | |
75 // True if the sequence was aborted. | |
76 bool sequence_aborted_; | |
77 | |
78 // The TestSessionAnimator that created this. Not owned. | |
79 TestSessionStateAnimator* animator_; | |
80 | |
81 DISALLOW_COPY_AND_ASSIGN(AnimationSequence); | |
82 }; | |
83 | |
84 TestSessionStateAnimator::ActiveAnimation::ActiveAnimation( | |
85 int animation_epoch, | |
86 base::TimeDelta duration, | |
87 SessionStateAnimator::Container container, | |
88 AnimationType type, | |
89 AnimationSpeed speed, | |
90 base::Closure success_callback, | |
91 base::Closure failed_callback) | |
92 : animation_epoch(animation_epoch), | |
93 remaining_duration(duration), | |
94 container(container), | |
95 type(type), | |
96 speed(speed), | |
97 success_callback(success_callback), | |
98 failed_callback(failed_callback) { | |
99 } | |
100 | |
101 TestSessionStateAnimator::ActiveAnimation::~ActiveAnimation() { | |
102 } | |
103 | |
104 TestSessionStateAnimator::TestSessionStateAnimator() | |
105 : last_animation_epoch_(0) { | |
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_itr = active_animations_.begin(); | |
Daniel Erat
2014/09/08 16:16:01
nit: i've seen both "it" or "iter" used commonly i
bruthig
2014/09/09 17:32:32
Done.
| |
119 container_itr != active_animations_.end(); | |
120 ++container_itr) { | |
121 AnimationList::iterator animation_itr = (*container_itr).second.begin(); | |
122 while (animation_itr != (*container_itr).second.end()) { | |
123 ActiveAnimation& active_animation = *animation_itr; | |
124 active_animation.remaining_duration -= duration; | |
125 if (active_animation.remaining_duration <= base::TimeDelta()) { | |
126 active_animation.success_callback.Run(); | |
127 animation_itr = (*container_itr).second.erase(animation_itr); | |
128 } else { | |
129 ++animation_itr; | |
130 } | |
131 } | |
132 } | |
133 } | |
134 | |
135 void TestSessionStateAnimator::CompleteAnimations(int animation_epoch, | |
136 bool completed_successfully) { | |
137 for (ActiveAnimationsMap::iterator container_itr = active_animations_.begin(); | |
138 container_itr != active_animations_.end(); | |
139 ++container_itr) { | |
140 AnimationList::iterator animation_itr = (*container_itr).second.begin(); | |
141 while (animation_itr != (*container_itr).second.end()) { | |
142 ActiveAnimation active_animation = *animation_itr; | |
143 if (active_animation.animation_epoch <= animation_epoch) { | |
144 if (completed_successfully) | |
145 active_animation.success_callback.Run(); | |
146 else | |
147 active_animation.failed_callback.Run(); | |
148 animation_itr = (*container_itr).second.erase(animation_itr); | |
149 } else { | |
150 ++animation_itr; | |
151 } | |
152 } | |
153 } | |
154 } | |
155 | |
156 void TestSessionStateAnimator::CompleteAllAnimations( | |
157 bool completed_successfully) { | |
158 CompleteAnimations(last_animation_epoch_, completed_successfully); | |
159 } | |
160 | |
161 bool TestSessionStateAnimator::IsContainerAnimated( | |
162 SessionStateAnimator::Container container, | |
163 SessionStateAnimator::AnimationType type) const { | |
164 ActiveAnimationsMap::const_iterator container_itr = | |
165 active_animations_.find(container); | |
166 if (container_itr != active_animations_.end()) { | |
167 for (AnimationList::const_iterator animation_itr = | |
168 (*container_itr).second.begin(); | |
169 animation_itr != (*container_itr).second.end(); | |
170 ++animation_itr) { | |
171 const ActiveAnimation& active_animation = *animation_itr; | |
172 if (active_animation.type == type) | |
173 return true; | |
174 } | |
175 } | |
176 return false; | |
177 } | |
178 | |
179 bool TestSessionStateAnimator::AreContainersAnimated( | |
180 int container_mask, SessionStateAnimator::AnimationType type) const { | |
181 for (size_t i = 0; i < arraysize(kAllContainers); ++i) { | |
182 if (container_mask & kAllContainers[i] && | |
183 !IsContainerAnimated(kAllContainers[i], type)) { | |
184 return false; | |
185 } | |
186 } | |
187 return true; | |
188 } | |
189 | |
190 size_t TestSessionStateAnimator::GetAnimationCount() const { | |
191 size_t count = 0; | |
192 for (ActiveAnimationsMap::const_iterator container_itr = | |
193 active_animations_.begin(); container_itr != active_animations_.end(); | |
194 ++container_itr) { | |
195 count += (*container_itr).second.size(); | |
196 } | |
197 return count; | |
198 } | |
199 | |
200 void TestSessionStateAnimator::StartAnimation(int container_mask, | |
201 AnimationType type, | |
202 AnimationSpeed speed) { | |
203 ++last_animation_epoch_; | |
204 for (size_t i = 0; i < arraysize(kAllContainers); ++i) { | |
205 if (container_mask & kAllContainers[i]) { | |
206 // Use a dummy no-op callback because one isn't required by the client | |
207 // but one is required when completing or aborting animations. | |
208 base::Closure callback = base::Bind(&DummyCallback); | |
209 AddAnimation(kAllContainers[i], type, speed, callback, callback); | |
210 } | |
211 } | |
212 } | |
213 | |
214 void TestSessionStateAnimator::StartAnimationWithCallback( | |
215 int container_mask, | |
216 AnimationType type, | |
217 AnimationSpeed speed, | |
218 base::Closure callback) { | |
219 ++last_animation_epoch_; | |
220 for (size_t i = 0; i < arraysize(kAllContainers); ++i) | |
221 if (container_mask & kAllContainers[i]) { | |
222 // ash::SessionStateAnimatorImpl invokes the callback whether or not the | |
223 // animation was completed successfully or not. | |
224 AddAnimation(kAllContainers[i], type, speed, callback, callback); | |
225 } | |
226 } | |
227 | |
228 ash::SessionStateAnimator::AnimationSequence* | |
229 TestSessionStateAnimator::BeginAnimationSequence(base::Closure callback) { | |
230 return new AnimationSequence(callback, this); | |
231 } | |
232 | |
233 void TestSessionStateAnimator::StartAnimationInSequence( | |
234 int container_mask, | |
235 AnimationType type, | |
236 AnimationSpeed speed, | |
237 AnimationSequence* animation_sequence) { | |
238 ++last_animation_epoch_; | |
239 for (size_t i = 0; i < arraysize(kAllContainers); ++i) { | |
240 if (container_mask & kAllContainers[i]) { | |
241 base::Closure success_callback = | |
242 base::Bind(&AnimationSequence::SequenceFinished, | |
243 base::Unretained(animation_sequence), true); | |
244 base::Closure failed_callback = | |
245 base::Bind(&AnimationSequence::SequenceFinished, | |
246 base::Unretained(animation_sequence), false); | |
247 animation_sequence->SequenceAttached(); | |
248 AddAnimation(kAllContainers[i], type, speed, success_callback, | |
249 failed_callback); | |
250 } | |
251 } | |
252 } | |
253 | |
254 void TestSessionStateAnimator::AddAnimation( | |
255 SessionStateAnimator::Container container, | |
256 AnimationType type, | |
257 AnimationSpeed speed, | |
258 base::Closure success_callback, | |
259 base::Closure failed_callback) { | |
260 base::TimeDelta duration = GetDuration(speed); | |
261 ActiveAnimation active_animation = { | |
Daniel Erat
2014/09/08 16:16:01
nit: use the c'tor here (since you defined it)?
bruthig
2014/09/09 17:32:32
Done.
| |
262 last_animation_epoch_, | |
263 duration, | |
264 container, | |
265 type, | |
266 speed, | |
267 success_callback, | |
268 failed_callback | |
269 }; | |
270 // This test double is limited to only have one animation active for a given | |
271 // container at a time. | |
272 AbortAnimation(container); | |
273 active_animations_[container].push_back(active_animation); | |
274 } | |
275 | |
276 void TestSessionStateAnimator::AbortAnimation( | |
277 SessionStateAnimator::Container container) { | |
278 ActiveAnimationsMap::iterator container_itr = | |
279 active_animations_.find(container); | |
280 if (container_itr != active_animations_.end()) { | |
281 AnimationList::iterator animation_itr = (*container_itr).second.begin(); | |
282 while (animation_itr != (*container_itr).second.end()) { | |
283 ActiveAnimation active_animation = *animation_itr; | |
284 active_animation.failed_callback.Run(); | |
285 animation_itr = (*container_itr).second.erase(animation_itr); | |
286 } | |
287 } | |
288 } | |
289 | |
290 } // namespace test | |
291 } // namespace ash | |
OLD | NEW |