Home | History | Annotate | Download | only in wm
      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(ui::Tween::EASE_OUT);
    167   SetTransformForScaleAnimation(layer,
    168       above ? LAYER_SCALE_ANIMATION_ABOVE : LAYER_SCALE_ANIMATION_BELOW);
    169 
    170   settings.SetTweenType(ui::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(ui::Tween::EASE_OUT);
    207   layer->SetTransform(gfx::Transform());
    208 
    209   settings.SetTweenType(ui::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     ui::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::RootWindow* 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::RootWindow* 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::RootWindow* 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, ui::Tween::EASE_IN, observer);
    608       break;
    609     case ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS:
    610       StartGrayscaleBrightnessAnimationForWindow(
    611           window, 0.0, duration, ui::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
    635