Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / ash / test / test_session_state_animator.cc
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,
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