| Index: ash/system/tray/system_tray_bubble.cc
 | 
| diff --git a/ash/system/tray/system_tray_bubble.cc b/ash/system/tray/system_tray_bubble.cc
 | 
| index bf94470ed85f0c75f6784d3d8513fc6c2e1cc0de..5fd9532d03b8d59e0ad96b51b9e1b189a45db6ff 100644
 | 
| --- a/ash/system/tray/system_tray_bubble.cc
 | 
| +++ b/ash/system/tray/system_tray_bubble.cc
 | 
| @@ -15,6 +15,7 @@
 | 
|  #include "ash/system/tray/system_tray_item.h"
 | 
|  #include "ash/system/tray/tray_bubble_wrapper.h"
 | 
|  #include "ash/system/tray/tray_constants.h"
 | 
| +#include "ash/wm/maximize_mode/maximize_mode_controller.h"
 | 
|  #include "base/metrics/histogram_macros.h"
 | 
|  #include "base/threading/thread_task_runner_handle.h"
 | 
|  #include "ui/compositor/layer.h"
 | 
| @@ -68,6 +69,26 @@ class AnimationObserverDeleteLayer : public ui::ImplicitAnimationObserver {
 | 
|  
 | 
|  }  // namespace
 | 
|  
 | 
| +// CloseBubbleObserver is used to delay closing the system tray bubble until the
 | 
| +// animation completes.
 | 
| +class CloseBubbleObserver : public ui::ImplicitAnimationObserver {
 | 
| + public:
 | 
| +  explicit CloseBubbleObserver(SystemTrayBubble* system_tray_bubble)
 | 
| +      : system_tray_bubble_(system_tray_bubble) {}
 | 
| +
 | 
| +  ~CloseBubbleObserver() override {}
 | 
| +
 | 
| +  void OnImplicitAnimationsCompleted() override {
 | 
| +    system_tray_bubble_->Close();
 | 
| +    delete this;
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  SystemTrayBubble* system_tray_bubble_ = nullptr;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(CloseBubbleObserver);
 | 
| +};
 | 
| +
 | 
|  // SystemTrayBubble
 | 
|  
 | 
|  SystemTrayBubble::SystemTrayBubble(
 | 
| @@ -197,8 +218,27 @@ void SystemTrayBubble::InitView(views::View* anchor,
 | 
|    }
 | 
|  
 | 
|    init_params->delegate = tray_;
 | 
| -  // Place the bubble on same display as this system tray.
 | 
| -  init_params->parent_window = tray_->GetBubbleWindowContainer();
 | 
| +  // Place the bubble on same display as this system tray if it is not on
 | 
| +  // maximize mode. Otherwise, create an clipping window to hold the system
 | 
| +  // bubble. And place the clipping window on the same display as the system
 | 
| +  // tray.
 | 
| +  if (Shell::Get()
 | 
| +          ->maximize_mode_controller()
 | 
| +          ->IsMaximizeModeWindowManagerEnabled()) {
 | 
| +    if (!clipping_window_.get()) {
 | 
| +      clipping_window_ =
 | 
| +          std::unique_ptr<aura::Window>(new aura::Window(nullptr));
 | 
| +      clipping_window_->Init(ui::LAYER_NOT_DRAWN);
 | 
| +      clipping_window_->layer()->SetMasksToBounds(true);
 | 
| +      tray_->GetBubbleWindowContainer()->AddChild(clipping_window_.get());
 | 
| +      clipping_window_->Show();
 | 
| +    }
 | 
| +    clipping_window_->SetBounds(tray_->GetWorkAreaBoundsInScreen());
 | 
| +    init_params->parent_window = clipping_window_.get();
 | 
| +  } else {
 | 
| +    init_params->parent_window = tray_->GetBubbleWindowContainer();
 | 
| +  }
 | 
| +
 | 
|    init_params->anchor_view = anchor;
 | 
|    bubble_view_ = new TrayBubbleView(*init_params);
 | 
|    UpdateBottomPadding();
 | 
| @@ -298,6 +338,22 @@ void SystemTrayBubble::RecordVisibleRowMetrics() {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +void SystemTrayBubble::AnimateToTargetBounds(const gfx::Rect& target_bounds,
 | 
| +                                             bool close_bubble) {
 | 
| +  const int kAnimationDurationMS = 200;
 | 
| +
 | 
| +  ui::ScopedLayerAnimationSettings settings(
 | 
| +      bubble_view()->GetWidget()->GetNativeView()->layer()->GetAnimator());
 | 
| +  settings.SetTransitionDuration(
 | 
| +      base::TimeDelta::FromMilliseconds(kAnimationDurationMS));
 | 
| +  settings.SetTweenType(gfx::Tween::EASE_OUT);
 | 
| +  settings.SetPreemptionStrategy(
 | 
| +      ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
 | 
| +  if (close_bubble)
 | 
| +    settings.AddObserver(new CloseBubbleObserver(this));
 | 
| +  bubble_view()->GetWidget()->SetBounds(target_bounds);
 | 
| +}
 | 
| +
 | 
|  void SystemTrayBubble::UpdateBottomPadding() {
 | 
|    if (bubble_type_ == BUBBLE_TYPE_DEFAULT)
 | 
|      bubble_view_->SetBottomPadding(kDefaultViewBottomPadding);
 | 
| 
 |