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