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