- add sources.
[platform/framework/web/crosswalk.git] / src / ash / wm / session_state_animator.cc
1 // Copyright (c) 2012 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/wm/session_state_animator.h"
6
7 #include "ash/shell.h"
8 #include "ash/shell_window_ids.h"
9 #include "ash/wm/window_animations.h"
10 #include "ui/aura/client/aura_constants.h"
11 #include "ui/aura/root_window.h"
12 #include "ui/compositor/layer_animation_observer.h"
13 #include "ui/compositor/layer_animation_sequence.h"
14 #include "ui/compositor/scoped_layer_animation_settings.h"
15 #include "ui/views/widget/widget.h"
16
17 namespace ash {
18 namespace internal {
19
20 namespace {
21
22 // Slightly-smaller size that we scale the screen down to for the pre-lock and
23 // pre-shutdown states.
24 const float kSlowCloseSizeRatio = 0.95f;
25
26 // Maximum opacity of white layer when animating pre-shutdown state.
27 const float kPartialFadeRatio = 0.3f;
28
29 // Minimum size. Not zero as it causes numeric issues.
30 const float kMinimumScale = 1e-4f;
31
32 // Returns the transform that should be applied to containers for the slow-close
33 // animation.
34 gfx::Transform GetSlowCloseTransform() {
35   gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
36   gfx::Transform transform;
37   transform.Translate(
38       floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5),
39       floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5));
40   transform.Scale(kSlowCloseSizeRatio, kSlowCloseSizeRatio);
41  return transform;
42 }
43
44 // Returns the transform that should be applied to containers for the fast-close
45 // animation.
46 gfx::Transform GetFastCloseTransform() {
47   gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
48   gfx::Transform transform;
49   transform.Translate(floor(0.5 * root_size.width() + 0.5),
50                       floor(0.5 * root_size.height() + 0.5));
51   transform.Scale(kMinimumScale, kMinimumScale);
52   return transform;
53 }
54
55 // Slowly shrinks |window| to a slightly-smaller size.
56 void StartSlowCloseAnimationForWindow(aura::Window* window,
57                                       base::TimeDelta duration,
58                                       ui::LayerAnimationObserver* observer) {
59   ui::LayerAnimator* animator = window->layer()->GetAnimator();
60   animator->set_preemption_strategy(
61       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
62   ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
63       ui::LayerAnimationElement::CreateTransformElement(
64           GetSlowCloseTransform(),
65           duration));
66   if (observer)
67     sequence->AddObserver(observer);
68   animator->StartAnimation(sequence);
69 }
70
71 // Quickly undoes the effects of the slow-close animation on |window|.
72 void StartUndoSlowCloseAnimationForWindow(
73     aura::Window* window,
74     base::TimeDelta duration,
75     ui::LayerAnimationObserver* observer) {
76   ui::LayerAnimator* animator = window->layer()->GetAnimator();
77   animator->set_preemption_strategy(
78       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
79   ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
80       ui::LayerAnimationElement::CreateTransformElement(
81           gfx::Transform(),
82           duration));
83   if (observer)
84     sequence->AddObserver(observer);
85   animator->StartAnimation(sequence);
86 }
87
88 // Quickly shrinks |window| down to a point in the center of the screen and
89 // fades it out to 0 opacity.
90 void StartFastCloseAnimationForWindow(aura::Window* window,
91                                       base::TimeDelta duration,
92                                       ui::LayerAnimationObserver* observer) {
93   ui::LayerAnimator* animator = window->layer()->GetAnimator();
94   animator->set_preemption_strategy(
95       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
96   animator->StartAnimation(
97       new ui::LayerAnimationSequence(
98           ui::LayerAnimationElement::CreateTransformElement(
99               GetFastCloseTransform(), duration)));
100   ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
101       ui::LayerAnimationElement::CreateOpacityElement(0.0, duration));
102   if (observer)
103     sequence->AddObserver(observer);
104   animator->StartAnimation(sequence);
105 }
106
107 // Fades |window| to |target_opacity| over |duration|.
108 void StartPartialFadeAnimation(aura::Window* window,
109                                float target_opacity,
110                                base::TimeDelta duration,
111                                ui::LayerAnimationObserver* observer) {
112   ui::LayerAnimator* animator = window->layer()->GetAnimator();
113   animator->set_preemption_strategy(
114       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
115   ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
116       ui::LayerAnimationElement::CreateOpacityElement(
117           target_opacity, duration));
118   if (observer)
119     sequence->AddObserver(observer);
120   animator->StartAnimation(sequence);
121 }
122
123 // Fades |window| to |opacity| over |duration|.
124 void StartOpacityAnimationForWindow(aura::Window* window,
125                                     float opacity,
126                                     base::TimeDelta duration,
127                                     ui::LayerAnimationObserver* observer) {
128   ui::LayerAnimator* animator = window->layer()->GetAnimator();
129   animator->set_preemption_strategy(
130       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
131   ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
132       ui::LayerAnimationElement::CreateOpacityElement(opacity, duration));
133   if (observer)
134     sequence->AddObserver(observer);
135   animator->StartAnimation(sequence);
136 }
137
138 // Makes |window| fully transparent instantaneously.
139 void HideWindowImmediately(aura::Window* window,
140                            ui::LayerAnimationObserver* observer) {
141   window->layer()->SetOpacity(0.0);
142   if (observer)
143     observer->OnLayerAnimationEnded(NULL);
144 }
145
146 // Restores |window| to its original position and scale and full opacity
147 // instantaneously.
148 void RestoreWindow(aura::Window* window, ui::LayerAnimationObserver* observer) {
149   window->layer()->SetTransform(gfx::Transform());
150   window->layer()->SetOpacity(1.0);
151   if (observer)
152     observer->OnLayerAnimationEnded(NULL);
153 }
154
155 void HideWindow(aura::Window* window,
156                 base::TimeDelta duration,
157                 bool above,
158                 ui::LayerAnimationObserver* observer) {
159   ui::Layer* layer = window->layer();
160   ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
161
162   settings.SetPreemptionStrategy(
163       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
164   settings.SetTransitionDuration(duration);
165
166   settings.SetTweenType(gfx::Tween::EASE_OUT);
167   SetTransformForScaleAnimation(layer,
168       above ? LAYER_SCALE_ANIMATION_ABOVE : LAYER_SCALE_ANIMATION_BELOW);
169
170   settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
171   layer->SetOpacity(0.0f);
172
173   // After the animation completes snap the transform back to the identity,
174   // otherwise any one that asks for screen bounds gets a slightly scaled
175   // version.
176   settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
177   settings.SetTransitionDuration(base::TimeDelta());
178   layer->SetTransform(gfx::Transform());
179
180   // A bit of a dirty trick: we need to catch the end of the animation we don't
181   // control. So we use two facts we know: which animator will be used and the
182   // target opacity to add "Do nothing" animation sequence.
183   // Unfortunately, we can not just use empty LayerAnimationSequence, because
184   // it does not call NotifyEnded().
185   if (observer) {
186     ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
187         ui::LayerAnimationElement::CreateOpacityElement(
188             0.0, base::TimeDelta()));
189       sequence->AddObserver(observer);
190     layer->GetAnimator()->ScheduleAnimation(sequence);
191   }
192 }
193
194 // Animates |window| to identity transform and full opacity over |duration|.
195 void TransformWindowToBaseState(aura::Window* window,
196                                 base::TimeDelta duration,
197                                 ui::LayerAnimationObserver* observer) {
198   ui::Layer* layer = window->layer();
199   ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
200
201   // Animate to target values.
202   settings.SetPreemptionStrategy(
203       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
204   settings.SetTransitionDuration(duration);
205
206   settings.SetTweenType(gfx::Tween::EASE_OUT);
207   layer->SetTransform(gfx::Transform());
208
209   settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
210   layer->SetOpacity(1.0f);
211
212   // A bit of a dirty trick: we need to catch the end of the animation we don't
213   // control. So we use two facts we know: which animator will be used and the
214   // target opacity to add "Do nothing" animation sequence.
215   // Unfortunately, we can not just use empty LayerAnimationSequence, because
216   // it does not call NotifyEnded().
217   if (observer) {
218     ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
219         ui::LayerAnimationElement::CreateOpacityElement(
220             1.0, base::TimeDelta()));
221     sequence->AddObserver(observer);
222     layer->GetAnimator()->ScheduleAnimation(sequence);
223   }
224 }
225
226 void ShowWindow(aura::Window* window,
227                 base::TimeDelta duration,
228                 bool above,
229                 ui::LayerAnimationObserver* observer) {
230   ui::Layer* layer = window->layer();
231   ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
232
233   // Set initial state of animation
234   settings.SetPreemptionStrategy(
235       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
236   settings.SetTransitionDuration(base::TimeDelta());
237   SetTransformForScaleAnimation(layer,
238       above ? LAYER_SCALE_ANIMATION_ABOVE : LAYER_SCALE_ANIMATION_BELOW);
239
240   TransformWindowToBaseState(window, duration, observer);
241 }
242
243 // Starts grayscale/brightness animation for |window| over |duration|. Target
244 // value for both grayscale and brightness are specified by |target|.
245 void StartGrayscaleBrightnessAnimationForWindow(
246     aura::Window* window,
247     float target,
248     base::TimeDelta duration,
249     gfx::Tween::Type tween_type,
250     ui::LayerAnimationObserver* observer) {
251   ui::LayerAnimator* animator = window->layer()->GetAnimator();
252
253   scoped_ptr<ui::LayerAnimationSequence> brightness_sequence(
254       new ui::LayerAnimationSequence());
255   scoped_ptr<ui::LayerAnimationSequence> grayscale_sequence(
256       new ui::LayerAnimationSequence());
257
258   scoped_ptr<ui::LayerAnimationElement> brightness_element(
259       ui::LayerAnimationElement::CreateBrightnessElement(
260           target, duration));
261   brightness_element->set_tween_type(tween_type);
262   brightness_sequence->AddElement(brightness_element.release());
263
264   scoped_ptr<ui::LayerAnimationElement> grayscale_element(
265       ui::LayerAnimationElement::CreateGrayscaleElement(
266           target, duration));
267   grayscale_element->set_tween_type(tween_type);
268   grayscale_sequence->AddElement(grayscale_element.release());
269
270   std::vector<ui::LayerAnimationSequence*> animations;
271   animations.push_back(brightness_sequence.release());
272   animations.push_back(grayscale_sequence.release());
273
274   if (observer)
275     animations[0]->AddObserver(observer);
276
277   animator->set_preemption_strategy(
278       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
279
280   animator->StartTogether(animations);
281 }
282
283 // Animation observer that will drop animated foreground once animation is
284 // finished. It is used in when undoing shutdown animation.
285 class CallbackAnimationObserver : public ui::LayerAnimationObserver {
286  public:
287   explicit CallbackAnimationObserver(base::Callback<void(void)> &callback)
288       : callback_(callback) {
289   }
290   virtual ~CallbackAnimationObserver() {
291   }
292
293  private:
294   // Overridden from ui::LayerAnimationObserver:
295   virtual void OnLayerAnimationEnded(ui::LayerAnimationSequence* seq)
296       OVERRIDE {
297     // Drop foreground once animation is over.
298     callback_.Run();
299     delete this;
300   }
301
302   virtual void OnLayerAnimationAborted(ui::LayerAnimationSequence* seq)
303       OVERRIDE {
304     // Drop foreground once animation is over.
305     callback_.Run();
306     delete this;
307   }
308
309   virtual void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq)
310       OVERRIDE {}
311
312   base::Callback<void(void)> callback_;
313
314   DISALLOW_COPY_AND_ASSIGN(CallbackAnimationObserver);
315 };
316
317
318 bool IsLayerAnimated(ui::Layer* layer,
319                      SessionStateAnimator::AnimationType type) {
320   switch (type) {
321     case SessionStateAnimator::ANIMATION_PARTIAL_CLOSE:
322       if (layer->GetTargetTransform() != GetSlowCloseTransform())
323         return false;
324       break;
325     case SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE:
326       if (layer->GetTargetTransform() != gfx::Transform())
327         return false;
328       break;
329     case SessionStateAnimator::ANIMATION_FULL_CLOSE:
330       if (layer->GetTargetTransform() != GetFastCloseTransform() ||
331           layer->GetTargetOpacity() > 0.0001)
332         return false;
333       break;
334     case SessionStateAnimator::ANIMATION_FADE_IN:
335       if (layer->GetTargetOpacity() < 0.9999)
336         return false;
337       break;
338     case SessionStateAnimator::ANIMATION_FADE_OUT:
339       if (layer->GetTargetOpacity() > 0.0001)
340         return false;
341       break;
342     case SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY:
343       if (layer->GetTargetOpacity() > 0.0001)
344         return false;
345       break;
346     case SessionStateAnimator::ANIMATION_RESTORE:
347       if (layer->opacity() < 0.9999 || layer->transform() != gfx::Transform())
348         return false;
349       break;
350     case SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS:
351       if ((layer->GetTargetBrightness() < 0.9999) ||
352           (layer->GetTargetGrayscale() < 0.9999))
353         return false;
354       break;
355     case SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS:
356       if ((layer->GetTargetBrightness() > 0.0001) ||
357           (layer->GetTargetGrayscale() > 0.0001))
358         return false;
359       break;
360     case SessionStateAnimator::ANIMATION_DROP:
361     case SessionStateAnimator::ANIMATION_UNDO_LIFT:
362       //ToDo(antim) : check other effects
363       if (layer->GetTargetOpacity() < 0.9999)
364         return false;
365       break;
366       //ToDo(antim) : check other effects
367     case SessionStateAnimator::ANIMATION_LIFT:
368       if (layer->GetTargetOpacity() > 0.0001)
369         return false;
370       break;
371     case SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN:
372       //ToDo(antim) : check other effects
373       if (layer->GetTargetOpacity() < 0.9999)
374         return false;
375       break;
376       //ToDo(antim) : check other effects
377     case SessionStateAnimator::ANIMATION_LOWER_BELOW_SCREEN:
378       if (layer->GetTargetOpacity() > 0.0001)
379         return false;
380       break;
381     default:
382       NOTREACHED() << "Unhandled animation type " << type;
383       return false;
384   }
385   return true;
386 }
387
388 }  // namespace
389
390 bool SessionStateAnimator::TestApi::ContainersAreAnimated(
391     int container_mask, AnimationType type) const {
392   aura::Window::Windows containers;
393   animator_->GetContainers(container_mask, &containers);
394   for (aura::Window::Windows::const_iterator it = containers.begin();
395        it != containers.end(); ++it) {
396     aura::Window* window = *it;
397     ui::Layer* layer = window->layer();
398     if (!IsLayerAnimated(layer, type))
399       return false;
400   }
401   return true;
402 }
403
404 bool SessionStateAnimator::TestApi::RootWindowIsAnimated(AnimationType type)
405     const {
406   aura::Window* root_window = Shell::GetPrimaryRootWindow();
407   ui::Layer* layer = root_window->layer();
408   return IsLayerAnimated(layer, type);
409 }
410
411 const int SessionStateAnimator::kAllLockScreenContainersMask =
412     SessionStateAnimator::LOCK_SCREEN_BACKGROUND |
413     SessionStateAnimator::LOCK_SCREEN_CONTAINERS |
414     SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS;
415
416 const int SessionStateAnimator::kAllContainersMask =
417     SessionStateAnimator::kAllLockScreenContainersMask |
418     SessionStateAnimator::DESKTOP_BACKGROUND |
419     SessionStateAnimator::LAUNCHER |
420     SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS;
421
422 SessionStateAnimator::SessionStateAnimator() {
423 }
424
425 SessionStateAnimator::~SessionStateAnimator() {
426 }
427
428 base::TimeDelta SessionStateAnimator::GetDuration(AnimationSpeed speed) {
429   switch (speed) {
430     case ANIMATION_SPEED_IMMEDIATE:
431       return base::TimeDelta();
432     case ANIMATION_SPEED_UNDOABLE:
433       return base::TimeDelta::FromMilliseconds(400);
434     case ANIMATION_SPEED_REVERT:
435       return base::TimeDelta::FromMilliseconds(150);
436     case ANIMATION_SPEED_FAST:
437       return base::TimeDelta::FromMilliseconds(150);
438     case ANIMATION_SPEED_SHOW_LOCK_SCREEN:
439       return base::TimeDelta::FromMilliseconds(200);
440     case ANIMATION_SPEED_MOVE_WINDOWS:
441       return base::TimeDelta::FromMilliseconds(350);
442     case ANIMATION_SPEED_UNDO_MOVE_WINDOWS:
443       return base::TimeDelta::FromMilliseconds(350);
444     case ANIMATION_SPEED_SHUTDOWN:
445       return base::TimeDelta::FromMilliseconds(1000);
446     case ANIMATION_SPEED_REVERT_SHUTDOWN:
447       return base::TimeDelta::FromMilliseconds(500);
448   }
449   // Satisfy compilers that do not understand that we will return from switch
450   // above anyway.
451   DCHECK(false) << "Unhandled animation speed " << speed;
452   return base::TimeDelta();
453 }
454
455 // Fills |containers| with the containers described by |container_mask|.
456 void SessionStateAnimator::GetContainers(int container_mask,
457                                          aura::Window::Windows* containers) {
458   aura::Window* root_window = Shell::GetPrimaryRootWindow();
459   containers->clear();
460
461   if (container_mask & DESKTOP_BACKGROUND) {
462     containers->push_back(Shell::GetContainer(
463         root_window,
464         internal::kShellWindowId_DesktopBackgroundContainer));
465   }
466   if (container_mask & LAUNCHER) {
467     containers->push_back(Shell::GetContainer(
468         root_window,
469         internal::kShellWindowId_ShelfContainer));
470   }
471   if (container_mask & NON_LOCK_SCREEN_CONTAINERS) {
472     // TODO(antrim): Figure out a way to eliminate a need to exclude launcher
473     // in such way.
474     aura::Window* non_lock_screen_containers = Shell::GetContainer(
475         root_window,
476         internal::kShellWindowId_NonLockScreenContainersContainer);
477     aura::Window::Windows children = non_lock_screen_containers->children();
478
479     for (aura::Window::Windows::const_iterator it = children.begin();
480          it != children.end(); ++it) {
481       aura::Window* window = *it;
482       if (window->id() == internal::kShellWindowId_ShelfContainer)
483         continue;
484       containers->push_back(window);
485     }
486   }
487   if (container_mask & LOCK_SCREEN_BACKGROUND) {
488     containers->push_back(Shell::GetContainer(
489         root_window,
490         internal::kShellWindowId_LockScreenBackgroundContainer));
491   }
492   if (container_mask & LOCK_SCREEN_CONTAINERS) {
493     containers->push_back(Shell::GetContainer(
494         root_window,
495         internal::kShellWindowId_LockScreenContainersContainer));
496   }
497   if (container_mask & LOCK_SCREEN_RELATED_CONTAINERS) {
498     containers->push_back(Shell::GetContainer(
499         root_window,
500         internal::kShellWindowId_LockScreenRelatedContainersContainer));
501   }
502 }
503
504 void SessionStateAnimator::StartAnimation(int container_mask,
505                                           AnimationType type,
506                                           AnimationSpeed speed) {
507   aura::Window::Windows containers;
508   GetContainers(container_mask, &containers);
509   for (aura::Window::Windows::const_iterator it = containers.begin();
510        it != containers.end(); ++it) {
511     RunAnimationForWindow(*it, type, speed, NULL);
512   }
513 }
514
515 void SessionStateAnimator::StartAnimationWithCallback(
516     int container_mask,
517     AnimationType type,
518     AnimationSpeed speed,
519     base::Callback<void(void)>& callback) {
520   aura::Window::Windows containers;
521   GetContainers(container_mask, &containers);
522   for (aura::Window::Windows::const_iterator it = containers.begin();
523        it != containers.end(); ++it) {
524     ui::LayerAnimationObserver* observer =
525         new CallbackAnimationObserver(callback);
526     RunAnimationForWindow(*it, type, speed, observer);
527   }
528 }
529
530 void SessionStateAnimator::StartAnimationWithObserver(
531     int container_mask,
532     AnimationType type,
533     AnimationSpeed speed,
534     ui::LayerAnimationObserver* observer) {
535   aura::Window::Windows containers;
536   GetContainers(container_mask, &containers);
537   for (aura::Window::Windows::const_iterator it = containers.begin();
538        it != containers.end(); ++it) {
539     RunAnimationForWindow(*it, type, speed, observer);
540   }
541 }
542
543 void SessionStateAnimator::StartGlobalAnimation(AnimationType type,
544                                                 AnimationSpeed speed) {
545   aura::Window* root_window = Shell::GetPrimaryRootWindow();
546   RunAnimationForWindow(root_window, type, speed, NULL);
547 }
548
549 void SessionStateAnimator::RunAnimationForWindow(
550     aura::Window* window,
551     AnimationType type,
552     AnimationSpeed speed,
553     ui::LayerAnimationObserver* observer) {
554   base::TimeDelta duration = GetDuration(speed);
555
556   switch (type) {
557     case ANIMATION_PARTIAL_CLOSE:
558       StartSlowCloseAnimationForWindow(window, duration, observer);
559       break;
560     case ANIMATION_UNDO_PARTIAL_CLOSE:
561       StartUndoSlowCloseAnimationForWindow(window, duration, observer);
562       break;
563     case ANIMATION_FULL_CLOSE:
564       StartFastCloseAnimationForWindow(window, duration, observer);
565       break;
566     case ANIMATION_FADE_IN:
567       StartOpacityAnimationForWindow(window, 1.0, duration, observer);
568       break;
569     case ANIMATION_FADE_OUT:
570       StartOpacityAnimationForWindow(window, 0.0, duration, observer);
571       break;
572     case ANIMATION_HIDE_IMMEDIATELY:
573       DCHECK_EQ(speed, ANIMATION_SPEED_IMMEDIATE);
574       HideWindowImmediately(window, observer);
575       break;
576     case ANIMATION_RESTORE:
577       DCHECK_EQ(speed, ANIMATION_SPEED_IMMEDIATE);
578       RestoreWindow(window, observer);
579       break;
580     case ANIMATION_LIFT:
581       HideWindow(window, duration, true, observer);
582       break;
583     case ANIMATION_DROP:
584       ShowWindow(window, duration, true, observer);
585       break;
586     case ANIMATION_UNDO_LIFT:
587       TransformWindowToBaseState(window, duration, observer);
588       break;
589     case ANIMATION_RAISE_TO_SCREEN:
590       ShowWindow(window, duration, false, observer);
591       break;
592     case ANIMATION_LOWER_BELOW_SCREEN:
593       HideWindow(window, duration, false, observer);
594       break;
595     case ANIMATION_PARTIAL_FADE_IN:
596       StartPartialFadeAnimation(
597           window, kPartialFadeRatio, duration, observer);
598       break;
599     case ANIMATION_UNDO_PARTIAL_FADE_IN:
600       StartPartialFadeAnimation(window, 0.0, duration, observer);
601       break;
602     case ANIMATION_FULL_FADE_IN:
603       StartPartialFadeAnimation(window, 1.0, duration, observer);
604       break;
605     case ANIMATION_GRAYSCALE_BRIGHTNESS:
606       StartGrayscaleBrightnessAnimationForWindow(
607           window, 1.0, duration, gfx::Tween::EASE_IN, observer);
608       break;
609     case ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS:
610       StartGrayscaleBrightnessAnimationForWindow(
611           window, 0.0, duration, gfx::Tween::EASE_IN_OUT, observer);
612       break;
613   }
614 }
615
616 void SessionStateAnimator::CreateForeground() {
617   if (foreground_)
618     return;
619   aura::Window* window = Shell::GetContainer(
620       Shell::GetPrimaryRootWindow(),
621       internal::kShellWindowId_PowerButtonAnimationContainer);
622   HideWindowImmediately(window, NULL);
623   foreground_.reset(
624       new ColoredWindowController(window, "SessionStateAnimatorForeground"));
625   foreground_->SetColor(SK_ColorWHITE);
626   foreground_->GetWidget()->Show();
627 }
628
629 void SessionStateAnimator::DropForeground() {
630   foreground_.reset();
631 }
632
633 }  // namespace internal
634 }  // namespace ash