Home | History | Annotate | Download | only in shelf
      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/shelf/shelf_layout_manager.h"
      6 
      7 #include "ash/accelerators/accelerator_controller.h"
      8 #include "ash/accelerators/accelerator_table.h"
      9 #include "ash/ash_switches.h"
     10 #include "ash/display/display_manager.h"
     11 #include "ash/focus_cycler.h"
     12 #include "ash/root_window_controller.h"
     13 #include "ash/session/session_state_delegate.h"
     14 #include "ash/shelf/shelf.h"
     15 #include "ash/shelf/shelf_layout_manager_observer.h"
     16 #include "ash/shelf/shelf_view.h"
     17 #include "ash/shelf/shelf_widget.h"
     18 #include "ash/shell.h"
     19 #include "ash/shell_window_ids.h"
     20 #include "ash/system/status_area_widget.h"
     21 #include "ash/system/tray/system_tray.h"
     22 #include "ash/system/tray/system_tray_item.h"
     23 #include "ash/test/ash_test_base.h"
     24 #include "ash/test/shelf_test_api.h"
     25 #include "ash/wm/window_state.h"
     26 #include "ash/wm/window_util.h"
     27 #include "base/command_line.h"
     28 #include "base/strings/utf_string_conversions.h"
     29 #include "ui/aura/client/aura_constants.h"
     30 #include "ui/aura/window.h"
     31 #include "ui/aura/window_event_dispatcher.h"
     32 #include "ui/compositor/layer.h"
     33 #include "ui/compositor/layer_animator.h"
     34 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
     35 #include "ui/events/gestures/gesture_configuration.h"
     36 #include "ui/events/test/event_generator.h"
     37 #include "ui/gfx/display.h"
     38 #include "ui/gfx/screen.h"
     39 #include "ui/views/controls/label.h"
     40 #include "ui/views/layout/fill_layout.h"
     41 #include "ui/views/view.h"
     42 #include "ui/views/widget/widget.h"
     43 
     44 #if defined(OS_WIN)
     45 #include "base/win/windows_version.h"
     46 #endif
     47 
     48 namespace ash {
     49 namespace {
     50 
     51 void StepWidgetLayerAnimatorToEnd(views::Widget* widget) {
     52   widget->GetNativeView()->layer()->GetAnimator()->Step(
     53       base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1));
     54 }
     55 
     56 ShelfWidget* GetShelfWidget() {
     57   return Shell::GetPrimaryRootWindowController()->shelf();
     58 }
     59 
     60 ShelfLayoutManager* GetShelfLayoutManager() {
     61   return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
     62 }
     63 
     64 SystemTray* GetSystemTray() {
     65   return Shell::GetPrimaryRootWindowController()->GetSystemTray();
     66 }
     67 
     68 // Class which waits till the shelf finishes animating to the target size and
     69 // counts the number of animation steps.
     70 class ShelfAnimationWaiter : views::WidgetObserver {
     71  public:
     72   explicit ShelfAnimationWaiter(const gfx::Rect& target_bounds)
     73       : target_bounds_(target_bounds),
     74         animation_steps_(0),
     75         done_waiting_(false) {
     76     GetShelfWidget()->AddObserver(this);
     77   }
     78 
     79   virtual ~ShelfAnimationWaiter() {
     80     GetShelfWidget()->RemoveObserver(this);
     81   }
     82 
     83   // Wait till the shelf finishes animating to its expected bounds.
     84   void WaitTillDoneAnimating() {
     85     if (IsDoneAnimating())
     86       done_waiting_ = true;
     87     else
     88       base::MessageLoop::current()->Run();
     89   }
     90 
     91   // Returns true if the animation has completed and it was valid.
     92   bool WasValidAnimation() const {
     93     return done_waiting_ && animation_steps_ > 0;
     94   }
     95 
     96  private:
     97   // Returns true if shelf has finished animating to the target size.
     98   bool IsDoneAnimating() const {
     99     ShelfLayoutManager* layout_manager = GetShelfLayoutManager();
    100     gfx::Rect current_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
    101     int size = layout_manager->PrimaryAxisValue(current_bounds.height(),
    102         current_bounds.width());
    103     int desired_size = layout_manager->PrimaryAxisValue(target_bounds_.height(),
    104         target_bounds_.width());
    105     return (size == desired_size);
    106   }
    107 
    108   // views::WidgetObserver override.
    109   virtual void OnWidgetBoundsChanged(views::Widget* widget,
    110                                      const gfx::Rect& new_bounds) OVERRIDE {
    111     if (done_waiting_)
    112       return;
    113 
    114     ++animation_steps_;
    115     if (IsDoneAnimating()) {
    116       done_waiting_ = true;
    117       base::MessageLoop::current()->Quit();
    118     }
    119   }
    120 
    121   gfx::Rect target_bounds_;
    122   int animation_steps_;
    123   bool done_waiting_;
    124 
    125   DISALLOW_COPY_AND_ASSIGN(ShelfAnimationWaiter);
    126 };
    127 
    128 class ShelfDragCallback {
    129  public:
    130   ShelfDragCallback(const gfx::Rect& not_visible, const gfx::Rect& visible)
    131       : not_visible_bounds_(not_visible),
    132         visible_bounds_(visible),
    133         was_visible_on_drag_start_(false) {
    134     EXPECT_EQ(not_visible_bounds_.bottom(), visible_bounds_.bottom());
    135   }
    136 
    137   virtual ~ShelfDragCallback() {
    138   }
    139 
    140   void ProcessScroll(ui::EventType type, const gfx::Vector2dF& delta) {
    141     if (GetShelfLayoutManager()->visibility_state() == ash::SHELF_HIDDEN)
    142       return;
    143 
    144     if (type == ui::ET_GESTURE_SCROLL_BEGIN) {
    145       scroll_ = gfx::Vector2dF();
    146       was_visible_on_drag_start_ = GetShelfLayoutManager()->IsVisible();
    147       return;
    148     }
    149 
    150     // The state of the shelf at the end of the gesture is tested separately.
    151     if (type == ui::ET_GESTURE_SCROLL_END)
    152       return;
    153 
    154     if (type == ui::ET_GESTURE_SCROLL_UPDATE)
    155       scroll_.Add(delta);
    156 
    157     gfx::Rect shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
    158     if (GetShelfLayoutManager()->IsHorizontalAlignment()) {
    159       EXPECT_EQ(not_visible_bounds_.bottom(), shelf_bounds.bottom());
    160       EXPECT_EQ(visible_bounds_.bottom(), shelf_bounds.bottom());
    161     } else if (SHELF_ALIGNMENT_RIGHT ==
    162         GetShelfLayoutManager()->GetAlignment()){
    163       EXPECT_EQ(not_visible_bounds_.right(), shelf_bounds.right());
    164       EXPECT_EQ(visible_bounds_.right(), shelf_bounds.right());
    165     } else if (SHELF_ALIGNMENT_LEFT ==
    166         GetShelfLayoutManager()->GetAlignment()) {
    167       EXPECT_EQ(not_visible_bounds_.x(), shelf_bounds.x());
    168       EXPECT_EQ(visible_bounds_.x(), shelf_bounds.x());
    169     }
    170 
    171     // if the shelf is being dimmed test dimmer bounds as well.
    172     if (GetShelfWidget()->GetDimsShelf())
    173       EXPECT_EQ(GetShelfWidget()->GetWindowBoundsInScreen(),
    174                 GetShelfWidget()->GetDimmerBoundsForTest());
    175 
    176     // The shelf should never be smaller than the hidden state.
    177     EXPECT_GE(shelf_bounds.height(), not_visible_bounds_.height());
    178     float scroll_delta = GetShelfLayoutManager()->PrimaryAxisValue(
    179         scroll_.y(),
    180         scroll_.x());
    181     bool increasing_drag =
    182         GetShelfLayoutManager()->SelectValueForShelfAlignment(
    183             scroll_delta < 0,
    184             scroll_delta > 0,
    185             scroll_delta < 0,
    186             scroll_delta > 0);
    187     int shelf_size = GetShelfLayoutManager()->PrimaryAxisValue(
    188         shelf_bounds.height(),
    189         shelf_bounds.width());
    190     int visible_bounds_size = GetShelfLayoutManager()->PrimaryAxisValue(
    191         visible_bounds_.height(),
    192         visible_bounds_.width());
    193     int not_visible_bounds_size = GetShelfLayoutManager()->PrimaryAxisValue(
    194         not_visible_bounds_.height(),
    195         not_visible_bounds_.width());
    196     if (was_visible_on_drag_start_) {
    197       if (increasing_drag) {
    198         // If dragging inwards from the visible state, then the shelf should
    199         // increase in size, but not more than the scroll delta.
    200         EXPECT_LE(visible_bounds_size, shelf_size);
    201         EXPECT_LE(std::abs(shelf_size - visible_bounds_size),
    202                   std::abs(scroll_delta));
    203       } else {
    204         if (shelf_size > not_visible_bounds_size) {
    205           // If dragging outwards from the visible state, then the shelf
    206           // should decrease in size, until it reaches the minimum size.
    207           EXPECT_EQ(shelf_size, visible_bounds_size - std::abs(scroll_delta));
    208         }
    209       }
    210     } else {
    211       if (std::abs(scroll_delta) <
    212           visible_bounds_size - not_visible_bounds_size) {
    213         // Tests that the shelf sticks with the touch point during the drag
    214         // until the shelf is completely visible.
    215         EXPECT_EQ(shelf_size, not_visible_bounds_size + std::abs(scroll_delta));
    216       } else {
    217         // Tests that after the shelf is completely visible, the shelf starts
    218         // resisting the drag.
    219         EXPECT_LT(shelf_size, not_visible_bounds_size + std::abs(scroll_delta));
    220       }
    221     }
    222   }
    223 
    224  private:
    225   const gfx::Rect not_visible_bounds_;
    226   const gfx::Rect visible_bounds_;
    227   gfx::Vector2dF scroll_;
    228   bool was_visible_on_drag_start_;
    229 
    230   DISALLOW_COPY_AND_ASSIGN(ShelfDragCallback);
    231 };
    232 
    233 class ShelfLayoutObserverTest : public ShelfLayoutManagerObserver {
    234  public:
    235   ShelfLayoutObserverTest()
    236       : changed_auto_hide_state_(false) {
    237   }
    238 
    239   virtual ~ShelfLayoutObserverTest() {}
    240 
    241   bool changed_auto_hide_state() const { return changed_auto_hide_state_; }
    242 
    243  private:
    244   virtual void OnAutoHideStateChanged(
    245       ShelfAutoHideState new_state) OVERRIDE {
    246     changed_auto_hide_state_ = true;
    247   }
    248 
    249   bool changed_auto_hide_state_;
    250 
    251   DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest);
    252 };
    253 
    254 // Trivial item implementation that tracks its views for testing.
    255 class TestItem : public SystemTrayItem {
    256  public:
    257   TestItem()
    258       : SystemTrayItem(GetSystemTray()),
    259         tray_view_(NULL),
    260         default_view_(NULL),
    261         detailed_view_(NULL),
    262         notification_view_(NULL) {}
    263 
    264   virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE {
    265     tray_view_ = new views::View;
    266     // Add a label so it has non-zero width.
    267     tray_view_->SetLayoutManager(new views::FillLayout);
    268     tray_view_->AddChildView(new views::Label(base::UTF8ToUTF16("Tray")));
    269     return tray_view_;
    270   }
    271 
    272   virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE {
    273     default_view_ = new views::View;
    274     default_view_->SetLayoutManager(new views::FillLayout);
    275     default_view_->AddChildView(new views::Label(base::UTF8ToUTF16("Default")));
    276     return default_view_;
    277   }
    278 
    279   virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE {
    280     detailed_view_ = new views::View;
    281     detailed_view_->SetLayoutManager(new views::FillLayout);
    282     detailed_view_->AddChildView(
    283         new views::Label(base::UTF8ToUTF16("Detailed")));
    284     return detailed_view_;
    285   }
    286 
    287   virtual views::View* CreateNotificationView(
    288       user::LoginStatus status) OVERRIDE {
    289     notification_view_ = new views::View;
    290     return notification_view_;
    291   }
    292 
    293   virtual void DestroyTrayView() OVERRIDE {
    294     tray_view_ = NULL;
    295   }
    296 
    297   virtual void DestroyDefaultView() OVERRIDE {
    298     default_view_ = NULL;
    299   }
    300 
    301   virtual void DestroyDetailedView() OVERRIDE {
    302     detailed_view_ = NULL;
    303   }
    304 
    305   virtual void DestroyNotificationView() OVERRIDE {
    306     notification_view_ = NULL;
    307   }
    308 
    309   virtual void UpdateAfterLoginStatusChange(
    310       user::LoginStatus status) OVERRIDE {}
    311 
    312   views::View* tray_view() const { return tray_view_; }
    313   views::View* default_view() const { return default_view_; }
    314   views::View* detailed_view() const { return detailed_view_; }
    315   views::View* notification_view() const { return notification_view_; }
    316 
    317  private:
    318   views::View* tray_view_;
    319   views::View* default_view_;
    320   views::View* detailed_view_;
    321   views::View* notification_view_;
    322 
    323   DISALLOW_COPY_AND_ASSIGN(TestItem);
    324 };
    325 
    326 }  // namespace
    327 
    328 class ShelfLayoutManagerTest : public ash::test::AshTestBase {
    329  public:
    330   ShelfLayoutManagerTest() {}
    331 
    332   void SetState(ShelfLayoutManager* shelf,
    333                 ShelfVisibilityState state) {
    334     shelf->SetState(state);
    335   }
    336 
    337   void UpdateAutoHideStateNow() {
    338     GetShelfLayoutManager()->UpdateAutoHideStateNow();
    339   }
    340 
    341   aura::Window* CreateTestWindow() {
    342     aura::Window* window = new aura::Window(NULL);
    343     window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
    344     window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
    345     window->Init(aura::WINDOW_LAYER_TEXTURED);
    346     ParentWindowInPrimaryRootWindow(window);
    347     return window;
    348   }
    349 
    350   views::Widget* CreateTestWidgetWithParams(
    351       const views::Widget::InitParams& params) {
    352     views::Widget* out = new views::Widget;
    353     out->Init(params);
    354     out->Show();
    355     return out;
    356   }
    357 
    358   // Create a simple widget attached to the current context (will
    359   // delete on TearDown).
    360   views::Widget* CreateTestWidget() {
    361     views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
    362     params.bounds = gfx::Rect(0, 0, 200, 200);
    363     params.context = CurrentContext();
    364     return CreateTestWidgetWithParams(params);
    365   }
    366 
    367   // Overridden from AshTestBase:
    368   virtual void SetUp() OVERRIDE {
    369     CommandLine::ForCurrentProcess()->AppendSwitch(
    370         ash::switches::kAshEnableTrayDragging);
    371     test::AshTestBase::SetUp();
    372   }
    373 
    374   void RunGestureDragTests(gfx::Vector2d);
    375 
    376  private:
    377   DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest);
    378 };
    379 
    380 void ShelfLayoutManagerTest::RunGestureDragTests(gfx::Vector2d delta) {
    381   ShelfLayoutManager* shelf = GetShelfLayoutManager();
    382   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
    383   views::Widget* widget = new views::Widget;
    384   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
    385   params.bounds = gfx::Rect(0, 0, 200, 200);
    386   params.context = CurrentContext();
    387   widget->Init(params);
    388   widget->Show();
    389   widget->Maximize();
    390 
    391   // The time delta should be large enough to prevent accidental fling creation.
    392   const base::TimeDelta kTimeDelta = base::TimeDelta::FromMilliseconds(100);
    393 
    394   aura::Window* window = widget->GetNativeWindow();
    395   shelf->LayoutShelf();
    396 
    397   gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen();
    398   gfx::Rect bounds_shelf = window->bounds();
    399   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
    400 
    401   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
    402   shelf->LayoutShelf();
    403   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    404 
    405   gfx::Rect bounds_noshelf = window->bounds();
    406   gfx::Rect shelf_hidden = GetShelfWidget()->GetWindowBoundsInScreen();
    407 
    408   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
    409   shelf->LayoutShelf();
    410 
    411   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
    412   const int kNumScrollSteps = 4;
    413   ShelfDragCallback handler(shelf_hidden, shelf_shown);
    414 
    415   // Swipe up on the shelf. This should not change any state.
    416   gfx::Point start = GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
    417   gfx::Point end = start + delta;
    418 
    419   // Swipe down on the shelf to hide it.
    420   generator.GestureScrollSequenceWithCallback(
    421       start,
    422       end,
    423       kTimeDelta,
    424       kNumScrollSteps,
    425       base::Bind(&ShelfDragCallback::ProcessScroll,
    426                  base::Unretained(&handler)));
    427   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    428   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    429   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    430   EXPECT_NE(bounds_shelf.ToString(), window->bounds().ToString());
    431   EXPECT_NE(shelf_shown.ToString(),
    432             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    433 
    434   // Swipe up to show the shelf.
    435   generator.GestureScrollSequenceWithCallback(
    436       end,
    437       start,
    438       kTimeDelta,
    439       kNumScrollSteps,
    440       base::Bind(&ShelfDragCallback::ProcessScroll,
    441                  base::Unretained(&handler)));
    442   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
    443   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
    444   EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
    445   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
    446             GetShelfWidget()->GetWindowBoundsInScreen());
    447   EXPECT_EQ(shelf_shown.ToString(),
    448             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    449 
    450   // Swipe up again. The shelf should hide.
    451   end = start - delta;
    452   generator.GestureScrollSequenceWithCallback(
    453       start,
    454       end,
    455       kTimeDelta,
    456       kNumScrollSteps,
    457       base::Bind(&ShelfDragCallback::ProcessScroll,
    458                  base::Unretained(&handler)));
    459   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    460   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    461   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    462   EXPECT_EQ(shelf_hidden.ToString(),
    463             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    464 
    465   // Swipe up yet again to show it.
    466   end = start + delta;
    467   generator.GestureScrollSequenceWithCallback(
    468       end,
    469       start,
    470       kTimeDelta,
    471       kNumScrollSteps,
    472       base::Bind(&ShelfDragCallback::ProcessScroll,
    473                  base::Unretained(&handler)));
    474 
    475   // Swipe down very little. It shouldn't change any state.
    476   if (GetShelfLayoutManager()->IsHorizontalAlignment())
    477     end.set_y(start.y() + shelf_shown.height() * 3 / 10);
    478   else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
    479     end.set_x(start.x() - shelf_shown.width() * 3 / 10);
    480   else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
    481     end.set_x(start.x() + shelf_shown.width() * 3 / 10);
    482   generator.GestureScrollSequence(start, end, kTimeDelta, 5);
    483   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
    484   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
    485   EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
    486   EXPECT_EQ(shelf_shown.ToString(),
    487             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    488 
    489   // Swipe down again to hide.
    490   end = start + delta;
    491   generator.GestureScrollSequenceWithCallback(
    492       start,
    493       end,
    494       kTimeDelta,
    495       kNumScrollSteps,
    496       base::Bind(&ShelfDragCallback::ProcessScroll,
    497                  base::Unretained(&handler)));
    498   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    499   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    500   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    501   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
    502   EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
    503   EXPECT_EQ(shelf_hidden.ToString(),
    504             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    505 
    506   // Swipe up in extended hit region to show it.
    507   gfx::Point extended_start = start;
    508   if (GetShelfLayoutManager()->IsHorizontalAlignment())
    509     extended_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().y() -1);
    510   else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
    511     extended_start.set_x(
    512         GetShelfWidget()->GetWindowBoundsInScreen().right() + 1);
    513   else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
    514     extended_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().x() - 1);
    515   end = extended_start - delta;
    516   generator.GestureScrollSequenceWithCallback(
    517       extended_start,
    518       end,
    519       kTimeDelta,
    520       kNumScrollSteps,
    521       base::Bind(&ShelfDragCallback::ProcessScroll,
    522                  base::Unretained(&handler)));
    523   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
    524   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
    525   EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
    526   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
    527             GetShelfWidget()->GetWindowBoundsInScreen());
    528   EXPECT_EQ(shelf_shown.ToString(),
    529             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    530 
    531   // Swipe down again to hide.
    532   end = start + delta;
    533   generator.GestureScrollSequenceWithCallback(
    534       start,
    535       end,
    536       kTimeDelta,
    537       kNumScrollSteps,
    538       base::Bind(&ShelfDragCallback::ProcessScroll,
    539                  base::Unretained(&handler)));
    540   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    541   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    542   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    543   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
    544   EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
    545   EXPECT_EQ(shelf_hidden.ToString(),
    546             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    547 
    548   // Swipe up outside the hit area. This should not change anything.
    549   gfx::Point outside_start = gfx::Point(
    550       (GetShelfWidget()->GetWindowBoundsInScreen().x() +
    551        GetShelfWidget()->GetWindowBoundsInScreen().right())/2,
    552       GetShelfWidget()->GetWindowBoundsInScreen().y() - 50);
    553   end = outside_start + delta;
    554   generator.GestureScrollSequence(
    555       outside_start, end, kTimeDelta, kNumScrollSteps);
    556   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    557   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    558   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    559   EXPECT_EQ(shelf_hidden.ToString(),
    560             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    561 
    562   // Swipe up from below the shelf where a bezel would be, this should show the
    563   // shelf.
    564   gfx::Point below_start = start;
    565   if (GetShelfLayoutManager()->IsHorizontalAlignment())
    566     below_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().bottom() + 1);
    567   else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
    568     below_start.set_x(
    569         GetShelfWidget()->GetWindowBoundsInScreen().x() - 1);
    570   else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
    571     below_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().right() + 1);
    572   end = below_start - delta;
    573   generator.GestureScrollSequence(
    574       below_start, end, kTimeDelta, kNumScrollSteps);
    575   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
    576   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
    577   EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
    578   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
    579             GetShelfWidget()->GetWindowBoundsInScreen());
    580   EXPECT_EQ(shelf_shown.ToString(),
    581             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    582 
    583   // Swipe down again to hide.
    584   end = start + delta;
    585   generator.GestureScrollSequenceWithCallback(
    586       start,
    587       end,
    588       kTimeDelta,
    589       kNumScrollSteps,
    590       base::Bind(&ShelfDragCallback::ProcessScroll,
    591                  base::Unretained(&handler)));
    592   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    593   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    594   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    595   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
    596   EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
    597   EXPECT_EQ(shelf_hidden.ToString(),
    598             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    599 
    600   // Put |widget| into fullscreen. Set the shelf to be auto hidden when |widget|
    601   // is fullscreen. (eg browser immersive fullscreen).
    602   widget->SetFullscreen(true);
    603   wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false);
    604   shelf->UpdateVisibilityState();
    605 
    606   gfx::Rect bounds_fullscreen = window->bounds();
    607   EXPECT_TRUE(widget->IsFullscreen());
    608   EXPECT_NE(bounds_noshelf.ToString(), bounds_fullscreen.ToString());
    609 
    610   // Swipe up. This should show the shelf.
    611   end = below_start - delta;
    612   generator.GestureScrollSequenceWithCallback(
    613       below_start,
    614       end,
    615       kTimeDelta,
    616       kNumScrollSteps,
    617       base::Bind(&ShelfDragCallback::ProcessScroll,
    618                  base::Unretained(&handler)));
    619   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    620   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
    621   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
    622   EXPECT_EQ(shelf_shown.ToString(),
    623             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    624   EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
    625 
    626   // Swipe up again. This should hide the shelf.
    627   generator.GestureScrollSequenceWithCallback(
    628       below_start,
    629       end,
    630       kTimeDelta,
    631       kNumScrollSteps,
    632       base::Bind(&ShelfDragCallback::ProcessScroll,
    633                  base::Unretained(&handler)));
    634   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    635   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    636   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    637   EXPECT_EQ(shelf_hidden.ToString(),
    638             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
    639   EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
    640 
    641   // Set the shelf to be hidden when |widget| is fullscreen. (eg tab fullscreen
    642   // with or without immersive browser fullscreen).
    643   wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(true);
    644   shelf->UpdateVisibilityState();
    645   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
    646   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    647 
    648   // Swipe-up. This should not change anything.
    649   end = start - delta;
    650   generator.GestureScrollSequenceWithCallback(
    651       below_start,
    652       end,
    653       kTimeDelta,
    654       kNumScrollSteps,
    655       base::Bind(&ShelfDragCallback::ProcessScroll,
    656                  base::Unretained(&handler)));
    657   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
    658   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    659   EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
    660 
    661   // Close actually, otherwise further event may be affected since widget
    662   // is fullscreen status.
    663   widget->Close();
    664   RunAllPendingInMessageLoop();
    665 
    666   // The shelf should be shown because there are no more visible windows.
    667   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    668   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
    669   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    670 
    671   // Swipe-up to hide. This should have no effect because there are no visible
    672   // windows.
    673   end = below_start - delta;
    674   generator.GestureScrollSequenceWithCallback(
    675       below_start,
    676       end,
    677       kTimeDelta,
    678       kNumScrollSteps,
    679       base::Bind(&ShelfDragCallback::ProcessScroll,
    680                  base::Unretained(&handler)));
    681   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    682   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
    683   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
    684 }
    685 
    686 // Need to be implemented.  http://crbug.com/111279.
    687 #if defined(OS_WIN)
    688 #define MAYBE_SetVisible DISABLED_SetVisible
    689 #else
    690 #define MAYBE_SetVisible SetVisible
    691 #endif
    692 // Makes sure SetVisible updates work area and widget appropriately.
    693 TEST_F(ShelfLayoutManagerTest, MAYBE_SetVisible) {
    694   ShelfWidget* shelf = GetShelfWidget();
    695   ShelfLayoutManager* manager = shelf->shelf_layout_manager();
    696   // Force an initial layout.
    697   manager->LayoutShelf();
    698   EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state());
    699 
    700   gfx::Rect status_bounds(
    701       shelf->status_area_widget()->GetWindowBoundsInScreen());
    702   gfx::Rect shelf_bounds(
    703       shelf->GetWindowBoundsInScreen());
    704   int shelf_height = manager->GetIdealBounds().height();
    705   gfx::Screen* screen = Shell::GetScreen();
    706   gfx::Display display = screen->GetDisplayNearestWindow(
    707       Shell::GetPrimaryRootWindow());
    708   ASSERT_NE(-1, display.id());
    709   // Bottom inset should be the max of widget heights.
    710   EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom());
    711 
    712   // Hide the shelf.
    713   SetState(manager, SHELF_HIDDEN);
    714   // Run the animation to completion.
    715   StepWidgetLayerAnimatorToEnd(shelf);
    716   StepWidgetLayerAnimatorToEnd(shelf->status_area_widget());
    717   EXPECT_EQ(SHELF_HIDDEN, manager->visibility_state());
    718   display = screen->GetDisplayNearestWindow(
    719       Shell::GetPrimaryRootWindow());
    720 
    721   EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
    722 
    723   // Make sure the bounds of the two widgets changed.
    724   EXPECT_GE(shelf->GetNativeView()->bounds().y(),
    725             screen->GetPrimaryDisplay().bounds().bottom());
    726   EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(),
    727             screen->GetPrimaryDisplay().bounds().bottom());
    728 
    729   // And show it again.
    730   SetState(manager, SHELF_VISIBLE);
    731   // Run the animation to completion.
    732   StepWidgetLayerAnimatorToEnd(shelf);
    733   StepWidgetLayerAnimatorToEnd(shelf->status_area_widget());
    734   EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state());
    735   display = screen->GetDisplayNearestWindow(
    736       Shell::GetPrimaryRootWindow());
    737   EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom());
    738 
    739   // Make sure the bounds of the two widgets changed.
    740   shelf_bounds = shelf->GetNativeView()->bounds();
    741   EXPECT_LT(shelf_bounds.y(), screen->GetPrimaryDisplay().bounds().bottom());
    742   status_bounds = shelf->status_area_widget()->GetNativeView()->bounds();
    743   EXPECT_LT(status_bounds.y(),
    744             screen->GetPrimaryDisplay().bounds().bottom());
    745 }
    746 
    747 // Makes sure shelf alignment is correct for lock screen.
    748 TEST_F(ShelfLayoutManagerTest, SideAlignmentInteractionWithLockScreen) {
    749   ShelfLayoutManager* manager = GetShelfWidget()->shelf_layout_manager();
    750   manager->SetAlignment(SHELF_ALIGNMENT_LEFT);
    751   EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment());
    752   Shell::GetInstance()->session_state_delegate()->LockScreen();
    753   EXPECT_EQ(SHELF_ALIGNMENT_BOTTOM, manager->GetAlignment());
    754   Shell::GetInstance()->session_state_delegate()->UnlockScreen();
    755   EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment());
    756 }
    757 
    758 // Makes sure LayoutShelf invoked while animating cleans things up.
    759 TEST_F(ShelfLayoutManagerTest, LayoutShelfWhileAnimating) {
    760   ShelfWidget* shelf = GetShelfWidget();
    761   // Force an initial layout.
    762   shelf->shelf_layout_manager()->LayoutShelf();
    763   EXPECT_EQ(SHELF_VISIBLE, shelf->shelf_layout_manager()->visibility_state());
    764 
    765   // Hide the shelf.
    766   SetState(shelf->shelf_layout_manager(), SHELF_HIDDEN);
    767   shelf->shelf_layout_manager()->LayoutShelf();
    768   EXPECT_EQ(SHELF_HIDDEN, shelf->shelf_layout_manager()->visibility_state());
    769   gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow(
    770       Shell::GetPrimaryRootWindow());
    771   EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
    772 
    773   // Make sure the bounds of the two widgets changed.
    774   EXPECT_GE(shelf->GetNativeView()->bounds().y(),
    775             Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
    776   EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(),
    777             Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
    778 }
    779 
    780 // Test that switching to a different visibility state does not restart the
    781 // shelf show / hide animation if it is already running. (crbug.com/250918)
    782 TEST_F(ShelfLayoutManagerTest, SetStateWhileAnimating) {
    783   ShelfWidget* shelf = GetShelfWidget();
    784   SetState(shelf->shelf_layout_manager(), SHELF_VISIBLE);
    785   gfx::Rect initial_shelf_bounds = shelf->GetWindowBoundsInScreen();
    786   gfx::Rect initial_status_bounds =
    787       shelf->status_area_widget()->GetWindowBoundsInScreen();
    788 
    789   ui::ScopedAnimationDurationScaleMode normal_animation_duration(
    790       ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
    791   SetState(shelf->shelf_layout_manager(), SHELF_HIDDEN);
    792   SetState(shelf->shelf_layout_manager(), SHELF_VISIBLE);
    793 
    794   gfx::Rect current_shelf_bounds = shelf->GetWindowBoundsInScreen();
    795   gfx::Rect current_status_bounds =
    796       shelf->status_area_widget()->GetWindowBoundsInScreen();
    797 
    798   const int small_change = initial_shelf_bounds.height() / 2;
    799   EXPECT_LE(
    800       std::abs(initial_shelf_bounds.height() - current_shelf_bounds.height()),
    801       small_change);
    802   EXPECT_LE(
    803       std::abs(initial_status_bounds.height() - current_status_bounds.height()),
    804       small_change);
    805 }
    806 
    807 // Makes sure the shelf is sized when the status area changes size.
    808 TEST_F(ShelfLayoutManagerTest, ShelfUpdatedWhenStatusAreaChangesSize) {
    809   Shelf* shelf = Shelf::ForPrimaryDisplay();
    810   ASSERT_TRUE(shelf);
    811   ShelfWidget* shelf_widget = GetShelfWidget();
    812   ASSERT_TRUE(shelf_widget);
    813   ASSERT_TRUE(shelf_widget->status_area_widget());
    814   shelf_widget->status_area_widget()->SetBounds(
    815       gfx::Rect(0, 0, 200, 200));
    816   EXPECT_EQ(200, shelf_widget->GetContentsView()->width() -
    817             test::ShelfTestAPI(shelf).shelf_view()->width());
    818 }
    819 
    820 
    821 #if defined(OS_WIN)
    822 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
    823 #define MAYBE_AutoHide DISABLED_AutoHide
    824 #else
    825 #define MAYBE_AutoHide AutoHide
    826 #endif
    827 
    828 // Various assertions around auto-hide.
    829 TEST_F(ShelfLayoutManagerTest, MAYBE_AutoHide) {
    830   aura::Window* root = Shell::GetPrimaryRootWindow();
    831   ui::test::EventGenerator generator(root, root);
    832   generator.MoveMouseTo(0, 0);
    833 
    834   ShelfLayoutManager* shelf = GetShelfLayoutManager();
    835   shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
    836   views::Widget* widget = new views::Widget;
    837   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
    838   params.bounds = gfx::Rect(0, 0, 200, 200);
    839   params.context = CurrentContext();
    840   // Widget is now owned by the parent window.
    841   widget->Init(params);
    842   widget->Maximize();
    843   widget->Show();
    844   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    845   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    846 
    847   // LayoutShelf() forces the animation to completion, at which point the
    848   // shelf should go off the screen.
    849   shelf->LayoutShelf();
    850   EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
    851             GetShelfWidget()->GetWindowBoundsInScreen().y());
    852   EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
    853             Shell::GetScreen()->GetDisplayNearestWindow(
    854                 root).work_area().bottom());
    855 
    856   // Move the mouse to the bottom of the screen.
    857   generator.MoveMouseTo(0, root->bounds().bottom() - 1);
    858 
    859   // Shelf should be shown again (but it shouldn't have changed the work area).
    860   SetState(shelf, SHELF_AUTO_HIDE);
    861   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
    862   shelf->LayoutShelf();
    863   EXPECT_EQ(root->bounds().bottom() - shelf->GetIdealBounds().height(),
    864             GetShelfWidget()->GetWindowBoundsInScreen().y());
    865   EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
    866             Shell::GetScreen()->GetDisplayNearestWindow(
    867                 root).work_area().bottom());
    868 
    869   // Move mouse back up.
    870   generator.MoveMouseTo(0, 0);
    871   SetState(shelf, SHELF_AUTO_HIDE);
    872   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    873   shelf->LayoutShelf();
    874   EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
    875             GetShelfWidget()->GetWindowBoundsInScreen().y());
    876 
    877   // Drag mouse to bottom of screen.
    878   generator.PressLeftButton();
    879   generator.MoveMouseTo(0, root->bounds().bottom() - 1);
    880   UpdateAutoHideStateNow();
    881   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    882 
    883   generator.ReleaseLeftButton();
    884   generator.MoveMouseTo(1, root->bounds().bottom() - 1);
    885   UpdateAutoHideStateNow();
    886   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
    887   generator.PressLeftButton();
    888   generator.MoveMouseTo(1, root->bounds().bottom() - 1);
    889   UpdateAutoHideStateNow();
    890   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
    891 }
    892 
    893 // Test the behavior of the shelf when it is auto hidden and it is on the
    894 // boundary between the primary and the secondary display.
    895 TEST_F(ShelfLayoutManagerTest, AutoHideShelfOnScreenBoundary) {
    896   if (!SupportsMultipleDisplays())
    897     return;
    898 
    899   UpdateDisplay("800x600,800x600");
    900   DisplayLayout display_layout(DisplayLayout::RIGHT, 0);
    901   Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
    902       display_layout);
    903   // Put the primary monitor's shelf on the display boundary.
    904   ShelfLayoutManager* shelf = GetShelfLayoutManager();
    905   shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
    906 
    907   // Create a window because the shelf is always shown when no windows are
    908   // visible.
    909   CreateTestWidget();
    910 
    911   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    912   ASSERT_EQ(root_windows[0],
    913             GetShelfWidget()->GetNativeWindow()->GetRootWindow());
    914 
    915   shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
    916   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
    917 
    918   int right_edge = root_windows[0]->GetBoundsInScreen().right() - 1;
    919   int y = root_windows[0]->GetBoundsInScreen().y();
    920 
    921   // Start off the mouse nowhere near the shelf; the shelf should be hidden.
    922   ui::test::EventGenerator& generator(GetEventGenerator());
    923   generator.MoveMouseTo(right_edge - 50, y);
    924   UpdateAutoHideStateNow();
    925   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    926 
    927   // Moving the mouse over the light bar (but not to the edge of the screen)
    928   // should show the shelf.
    929   generator.MoveMouseTo(right_edge - 1, y);
    930   UpdateAutoHideStateNow();
    931   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
    932   EXPECT_EQ(right_edge - 1, Shell::GetScreen()->GetCursorScreenPoint().x());
    933 
    934   // Moving the mouse off the light bar should hide the shelf.
    935   generator.MoveMouseTo(right_edge - 50, y);
    936   UpdateAutoHideStateNow();
    937   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    938 
    939   // Moving the mouse to the right edge of the screen crossing the light bar
    940   // should show the shelf despite the mouse cursor getting warped to the
    941   // secondary display.
    942   generator.MoveMouseTo(right_edge - 1, y);
    943   generator.MoveMouseTo(right_edge, y);
    944   UpdateAutoHideStateNow();
    945   EXPECT_NE(right_edge - 1, Shell::GetScreen()->GetCursorScreenPoint().x());
    946   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
    947 
    948   // Hide the shelf.
    949   generator.MoveMouseTo(right_edge - 50, y);
    950   UpdateAutoHideStateNow();
    951   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    952 
    953   // Moving the mouse to the right edge of the screen crossing the light bar and
    954   // overshooting by a lot should keep the shelf hidden.
    955   generator.MoveMouseTo(right_edge - 1, y);
    956   generator.MoveMouseTo(right_edge + 50, y);
    957   UpdateAutoHideStateNow();
    958   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    959 
    960   // Moving the mouse to the right edge of the screen crossing the light bar and
    961   // overshooting a bit should show the shelf.
    962   generator.MoveMouseTo(right_edge - 1, y);
    963   generator.MoveMouseTo(right_edge + 2, y);
    964   UpdateAutoHideStateNow();
    965   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
    966 
    967   // Keeping the mouse close to the left edge of the secondary display after the
    968   // shelf is shown should keep the shelf shown.
    969   generator.MoveMouseTo(right_edge + 2, y + 1);
    970   UpdateAutoHideStateNow();
    971   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
    972 
    973   // Moving the mouse far from the left edge of the secondary display should
    974   // hide the shelf.
    975   generator.MoveMouseTo(right_edge + 50, y);
    976   UpdateAutoHideStateNow();
    977   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    978 
    979   // Moving to the left edge of the secondary display without first crossing
    980   // the primary display's right aligned shelf first should not show the shelf.
    981   generator.MoveMouseTo(right_edge + 2, y);
    982   UpdateAutoHideStateNow();
    983   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    984 }
    985 
    986 // Assertions around the lock screen showing.
    987 TEST_F(ShelfLayoutManagerTest, VisibleWhenLockScreenShowing) {
    988   // Since ShelfLayoutManager queries for mouse location, move the mouse so
    989   // it isn't over the shelf.
    990   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    991                                      gfx::Point());
    992   generator.MoveMouseTo(0, 0);
    993 
    994   ShelfLayoutManager* shelf = GetShelfLayoutManager();
    995   shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
    996   views::Widget* widget = new views::Widget;
    997   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
    998   params.bounds = gfx::Rect(0, 0, 200, 200);
    999   params.context = CurrentContext();
   1000   // Widget is now owned by the parent window.
   1001   widget->Init(params);
   1002   widget->Maximize();
   1003   widget->Show();
   1004   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1005   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1006 
   1007   aura::Window* root = Shell::GetPrimaryRootWindow();
   1008   // LayoutShelf() forces the animation to completion, at which point the
   1009   // shelf should go off the screen.
   1010   shelf->LayoutShelf();
   1011   EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
   1012             GetShelfWidget()->GetWindowBoundsInScreen().y());
   1013 
   1014   aura::Window* lock_container = Shell::GetContainer(
   1015       Shell::GetPrimaryRootWindow(), kShellWindowId_LockScreenContainer);
   1016 
   1017   views::Widget* lock_widget = new views::Widget;
   1018   views::Widget::InitParams lock_params(
   1019       views::Widget::InitParams::TYPE_WINDOW);
   1020   lock_params.bounds = gfx::Rect(0, 0, 200, 200);
   1021   params.context = CurrentContext();
   1022   lock_params.parent = lock_container;
   1023   // Widget is now owned by the parent window.
   1024   lock_widget->Init(lock_params);
   1025   lock_widget->Maximize();
   1026   lock_widget->Show();
   1027 
   1028   // Lock the screen.
   1029   Shell::GetInstance()->session_state_delegate()->LockScreen();
   1030   shelf->UpdateVisibilityState();
   1031   // Showing a widget in the lock screen should force the shelf to be visibile.
   1032   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1033 
   1034   Shell::GetInstance()->session_state_delegate()->UnlockScreen();
   1035   shelf->UpdateVisibilityState();
   1036   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1037 }
   1038 
   1039 // Assertions around SetAutoHideBehavior.
   1040 TEST_F(ShelfLayoutManagerTest, SetAutoHideBehavior) {
   1041   // Since ShelfLayoutManager queries for mouse location, move the mouse so
   1042   // it isn't over the shelf.
   1043   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
   1044                                      gfx::Point());
   1045   generator.MoveMouseTo(0, 0);
   1046 
   1047   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1048   views::Widget* widget = new views::Widget;
   1049   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
   1050   params.bounds = gfx::Rect(0, 0, 200, 200);
   1051   params.context = CurrentContext();
   1052   // Widget is now owned by the parent window.
   1053   widget->Init(params);
   1054   widget->Show();
   1055   aura::Window* window = widget->GetNativeWindow();
   1056   gfx::Rect display_bounds(
   1057       Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
   1058 
   1059   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1060   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1061 
   1062   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1063   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1064 
   1065   widget->Maximize();
   1066   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1067   EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
   1068                 window).work_area().bottom(),
   1069             widget->GetWorkAreaBoundsInScreen().bottom());
   1070 
   1071   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1072   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1073   EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
   1074                 window).work_area().bottom(),
   1075             widget->GetWorkAreaBoundsInScreen().bottom());
   1076 
   1077   ui::ScopedAnimationDurationScaleMode animation_duration(
   1078       ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
   1079 
   1080   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1081   ShelfWidget* shelf_widget = GetShelfWidget();
   1082   EXPECT_TRUE(shelf_widget->status_area_widget()->IsVisible());
   1083   StepWidgetLayerAnimatorToEnd(shelf_widget);
   1084   StepWidgetLayerAnimatorToEnd(shelf_widget->status_area_widget());
   1085   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1086   EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
   1087                 window).work_area().bottom(),
   1088             widget->GetWorkAreaBoundsInScreen().bottom());
   1089 }
   1090 
   1091 // Basic assertions around the dimming of the shelf.
   1092 TEST_F(ShelfLayoutManagerTest, TestDimmingBehavior) {
   1093   // Since ShelfLayoutManager queries for mouse location, move the mouse so
   1094   // it isn't over the shelf.
   1095   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
   1096                                      gfx::Point());
   1097   generator.MoveMouseTo(0, 0);
   1098 
   1099   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1100   shelf->shelf_widget()->DisableDimmingAnimationsForTest();
   1101 
   1102   views::Widget* widget = new views::Widget;
   1103   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
   1104   params.bounds = gfx::Rect(0, 0, 200, 200);
   1105   params.context = CurrentContext();
   1106   // Widget is now owned by the parent window.
   1107   widget->Init(params);
   1108   widget->Show();
   1109   aura::Window* window = widget->GetNativeWindow();
   1110   gfx::Rect display_bounds(
   1111       Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
   1112 
   1113   gfx::Point off_shelf = display_bounds.CenterPoint();
   1114   gfx::Point on_shelf =
   1115       shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
   1116 
   1117   // Test there is no dimming object active at this point.
   1118   generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
   1119   EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1120   generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
   1121   EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1122 
   1123   // After maximization, the shelf should be visible and the dimmer created.
   1124   widget->Maximize();
   1125 
   1126   on_shelf = shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
   1127   EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1128 
   1129   // Moving the mouse off the shelf should dim the bar.
   1130   generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
   1131   EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1132 
   1133   // Adding touch events outside the shelf should still keep the shelf in
   1134   // dimmed state.
   1135   generator.PressTouch();
   1136   generator.MoveTouch(off_shelf);
   1137   EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1138   // Move the touch into the shelf area should undim.
   1139   generator.MoveTouch(on_shelf);
   1140   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1141   generator.ReleaseTouch();
   1142   // And a release dims again.
   1143   EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1144 
   1145   // Moving the mouse on the shelf should undim the bar.
   1146   generator.MoveMouseTo(on_shelf);
   1147   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1148 
   1149   // No matter what the touch events do, the shelf should stay undimmed.
   1150   generator.PressTouch();
   1151   generator.MoveTouch(off_shelf);
   1152   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1153   generator.MoveTouch(on_shelf);
   1154   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1155   generator.MoveTouch(off_shelf);
   1156   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1157   generator.MoveTouch(on_shelf);
   1158   generator.ReleaseTouch();
   1159 
   1160   // After restore, the dimming object should be deleted again.
   1161   widget->Restore();
   1162   EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1163 }
   1164 
   1165 // Assertions around the dimming of the shelf in conjunction with menus.
   1166 TEST_F(ShelfLayoutManagerTest, TestDimmingBehaviorWithMenus) {
   1167   // Since ShelfLayoutManager queries for mouse location, move the mouse so
   1168   // it isn't over the shelf.
   1169   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
   1170                                      gfx::Point());
   1171   generator.MoveMouseTo(0, 0);
   1172 
   1173   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1174   shelf->shelf_widget()->DisableDimmingAnimationsForTest();
   1175 
   1176   views::Widget* widget = new views::Widget;
   1177   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
   1178   params.bounds = gfx::Rect(0, 0, 200, 200);
   1179   params.context = CurrentContext();
   1180   // Widget is now owned by the parent window.
   1181   widget->Init(params);
   1182   widget->Show();
   1183   aura::Window* window = widget->GetNativeWindow();
   1184   gfx::Rect display_bounds(
   1185       Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
   1186 
   1187   // After maximization, the shelf should be visible and the dimmer created.
   1188   widget->Maximize();
   1189 
   1190   gfx::Point off_shelf = display_bounds.CenterPoint();
   1191   gfx::Point on_shelf =
   1192       shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
   1193 
   1194   // Moving the mouse on the shelf should undim the bar.
   1195   generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
   1196   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1197 
   1198   // Simulate a menu opening.
   1199   shelf->shelf_widget()->ForceUndimming(true);
   1200 
   1201   // Moving the mouse off the shelf should not dim the bar.
   1202   generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
   1203   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1204 
   1205   // No matter what the touch events do, the shelf should stay undimmed.
   1206   generator.PressTouch();
   1207   generator.MoveTouch(off_shelf);
   1208   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1209   generator.MoveTouch(on_shelf);
   1210   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1211   generator.MoveTouch(off_shelf);
   1212   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1213   generator.ReleaseTouch();
   1214   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1215 
   1216   // "Closing the menu" should now turn off the menu since no event is inside
   1217   // the shelf any longer.
   1218   shelf->shelf_widget()->ForceUndimming(false);
   1219   EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1220 
   1221   // Moving the mouse again on the shelf which should undim the bar again.
   1222   // This time we check that the bar stays undimmed when the mouse remains on
   1223   // the bar and the "menu gets closed".
   1224   generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
   1225   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1226   shelf->shelf_widget()->ForceUndimming(true);
   1227   generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
   1228   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1229   generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
   1230   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1231   shelf->shelf_widget()->ForceUndimming(true);
   1232   EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
   1233 }
   1234 
   1235 // Verifies the shelf is visible when status/shelf is focused.
   1236 TEST_F(ShelfLayoutManagerTest, VisibleWhenStatusOrShelfFocused) {
   1237   // Since ShelfLayoutManager queries for mouse location, move the mouse so
   1238   // it isn't over the shelf.
   1239   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
   1240                                      gfx::Point());
   1241   generator.MoveMouseTo(0, 0);
   1242 
   1243   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1244   views::Widget* widget = new views::Widget;
   1245   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
   1246   params.bounds = gfx::Rect(0, 0, 200, 200);
   1247   params.context = CurrentContext();
   1248   // Widget is now owned by the parent window.
   1249   widget->Init(params);
   1250   widget->Show();
   1251   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1252   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1253   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1254 
   1255   // Focus the shelf. Have to go through the focus cycler as normal focus
   1256   // requests to it do nothing.
   1257   GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD);
   1258   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1259 
   1260   widget->Activate();
   1261   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1262 
   1263   // Trying to activate the status should fail, since we only allow activating
   1264   // it when the user is using the keyboard (i.e. through FocusCycler).
   1265   GetShelfWidget()->status_area_widget()->Activate();
   1266   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1267 
   1268   GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD);
   1269   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1270 }
   1271 
   1272 // Makes sure shelf will be visible when app list opens as shelf is in
   1273 // SHELF_VISIBLE state,and toggling app list won't change shelf
   1274 // visibility state.
   1275 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) {
   1276   Shell* shell = Shell::GetInstance();
   1277   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1278   shelf->LayoutShelf();
   1279   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1280 
   1281   // Create a normal unmaximized windowm shelf should be visible.
   1282   aura::Window* window = CreateTestWindow();
   1283   window->SetBounds(gfx::Rect(0, 0, 100, 100));
   1284   window->Show();
   1285   EXPECT_FALSE(shell->GetAppListTargetVisibility());
   1286   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1287 
   1288   // Show app list and the shelf stays visible.
   1289   shell->ShowAppList(NULL);
   1290   EXPECT_TRUE(shell->GetAppListTargetVisibility());
   1291   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1292 
   1293   // Hide app list and the shelf stays visible.
   1294   shell->DismissAppList();
   1295   EXPECT_FALSE(shell->GetAppListTargetVisibility());
   1296   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1297 }
   1298 
   1299 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state
   1300 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and
   1301 // toggling app list won't change shelf visibility state.
   1302 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) {
   1303   Shell* shell = Shell::GetInstance();
   1304   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1305   shelf->LayoutShelf();
   1306   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1307 
   1308   // Create a window and show it in maximized state.
   1309   aura::Window* window = CreateTestWindow();
   1310   window->SetBounds(gfx::Rect(0, 0, 100, 100));
   1311   window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
   1312   window->Show();
   1313   wm::ActivateWindow(window);
   1314 
   1315   EXPECT_FALSE(shell->GetAppListTargetVisibility());
   1316   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1317 
   1318   // Show app list.
   1319   shell->ShowAppList(NULL);
   1320   // The shelf's auto hide state won't be changed until the timer fires, so
   1321   // calling shell->UpdateShelfVisibility() is kind of manually helping it to
   1322   // update the state.
   1323   shell->UpdateShelfVisibility();
   1324   EXPECT_TRUE(shell->GetAppListTargetVisibility());
   1325   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1326   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1327 
   1328   // Hide app list.
   1329   shell->DismissAppList();
   1330   EXPECT_FALSE(shell->GetAppListTargetVisibility());
   1331   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1332 }
   1333 
   1334 // Makes sure shelf will be hidden when app list opens as shelf is in HIDDEN
   1335 // state, and toggling app list won't change shelf visibility state.
   1336 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfHiddenState) {
   1337   Shell* shell = Shell::GetInstance();
   1338   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1339   // For shelf to be visible, app list is not open in initial state.
   1340   shelf->LayoutShelf();
   1341 
   1342   // Create a window and make it full screen.
   1343   aura::Window* window = CreateTestWindow();
   1344   window->SetBounds(gfx::Rect(0, 0, 100, 100));
   1345   window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
   1346   window->Show();
   1347   wm::ActivateWindow(window);
   1348 
   1349   // App list and shelf is not shown.
   1350   EXPECT_FALSE(shell->GetAppListTargetVisibility());
   1351   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
   1352 
   1353   // Show app list.
   1354   shell->ShowAppList(NULL);
   1355   EXPECT_TRUE(shell->GetAppListTargetVisibility());
   1356   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
   1357 
   1358   // Hide app list.
   1359   shell->DismissAppList();
   1360   EXPECT_FALSE(shell->GetAppListTargetVisibility());
   1361   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
   1362 }
   1363 
   1364 // Tests that the shelf is only hidden for a fullscreen window at the front and
   1365 // toggles visibility when another window is activated.
   1366 TEST_F(ShelfLayoutManagerTest, FullscreenWindowInFrontHidesShelf) {
   1367   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1368 
   1369   // Create a window and make it full screen.
   1370   aura::Window* window1 = CreateTestWindow();
   1371   window1->SetBounds(gfx::Rect(0, 0, 100, 100));
   1372   window1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
   1373   window1->Show();
   1374 
   1375   aura::Window* window2 = CreateTestWindow();
   1376   window2->SetBounds(gfx::Rect(0, 0, 100, 100));
   1377   window2->Show();
   1378 
   1379   wm::GetWindowState(window1)->Activate();
   1380   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
   1381 
   1382   wm::GetWindowState(window2)->Activate();
   1383   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1384 
   1385   wm::GetWindowState(window1)->Activate();
   1386   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
   1387 }
   1388 
   1389 // Test the behavior of the shelf when a window on one display is fullscreen
   1390 // but the other display has the active window.
   1391 TEST_F(ShelfLayoutManagerTest, FullscreenWindowOnSecondDisplay) {
   1392   if (!SupportsMultipleDisplays())
   1393     return;
   1394 
   1395   UpdateDisplay("800x600,800x600");
   1396   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
   1397   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
   1398   Shell::RootWindowControllerList root_window_controllers =
   1399       Shell::GetAllRootWindowControllers();
   1400 
   1401   // Create windows on either display.
   1402   aura::Window* window1 = CreateTestWindow();
   1403   window1->SetBoundsInScreen(
   1404       gfx::Rect(0, 0, 100, 100),
   1405       display_manager->GetDisplayAt(0));
   1406   window1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
   1407   window1->Show();
   1408 
   1409   aura::Window* window2 = CreateTestWindow();
   1410   window2->SetBoundsInScreen(
   1411       gfx::Rect(800, 0, 100, 100),
   1412       display_manager->GetDisplayAt(1));
   1413   window2->Show();
   1414 
   1415   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
   1416   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
   1417 
   1418   wm::GetWindowState(window2)->Activate();
   1419   EXPECT_EQ(SHELF_HIDDEN,
   1420       root_window_controllers[0]->GetShelfLayoutManager()->visibility_state());
   1421   EXPECT_EQ(SHELF_VISIBLE,
   1422       root_window_controllers[1]->GetShelfLayoutManager()->visibility_state());
   1423 }
   1424 
   1425 
   1426 #if defined(OS_WIN)
   1427 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
   1428 #define MAYBE_SetAlignment DISABLED_SetAlignment
   1429 #else
   1430 #define MAYBE_SetAlignment SetAlignment
   1431 #endif
   1432 
   1433 // Tests SHELF_ALIGNMENT_(LEFT, RIGHT, TOP).
   1434 TEST_F(ShelfLayoutManagerTest, MAYBE_SetAlignment) {
   1435   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1436   // Force an initial layout.
   1437   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1438   shelf->LayoutShelf();
   1439   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1440 
   1441   shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
   1442   gfx::Rect shelf_bounds(
   1443       GetShelfWidget()->GetWindowBoundsInScreen());
   1444   const gfx::Screen* screen = Shell::GetScreen();
   1445   gfx::Display display =
   1446       screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
   1447   ASSERT_NE(-1, display.id());
   1448   EXPECT_EQ(shelf->GetIdealBounds().width(),
   1449             display.GetWorkAreaInsets().left());
   1450   EXPECT_GE(
   1451       shelf_bounds.width(),
   1452       GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
   1453   EXPECT_EQ(SHELF_ALIGNMENT_LEFT, GetSystemTray()->shelf_alignment());
   1454   StatusAreaWidget* status_area_widget = GetShelfWidget()->status_area_widget();
   1455   gfx::Rect status_bounds(status_area_widget->GetWindowBoundsInScreen());
   1456   EXPECT_GE(status_bounds.width(),
   1457             status_area_widget->GetContentsView()->GetPreferredSize().width());
   1458   EXPECT_EQ(shelf->GetIdealBounds().width(),
   1459             display.GetWorkAreaInsets().left());
   1460   EXPECT_EQ(0, display.GetWorkAreaInsets().top());
   1461   EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
   1462   EXPECT_EQ(0, display.GetWorkAreaInsets().right());
   1463   EXPECT_EQ(display.bounds().x(), shelf_bounds.x());
   1464   EXPECT_EQ(display.bounds().y(), shelf_bounds.y());
   1465   EXPECT_EQ(display.bounds().height(), shelf_bounds.height());
   1466   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1467   display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
   1468   EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
   1469       display.GetWorkAreaInsets().left());
   1470   EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, display.work_area().x());
   1471 
   1472   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1473   shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
   1474   display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
   1475   shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
   1476   display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
   1477   ASSERT_NE(-1, display.id());
   1478   EXPECT_EQ(shelf->GetIdealBounds().width(),
   1479             display.GetWorkAreaInsets().right());
   1480   EXPECT_GE(shelf_bounds.width(),
   1481             GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
   1482   EXPECT_EQ(SHELF_ALIGNMENT_RIGHT, GetSystemTray()->shelf_alignment());
   1483   status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen());
   1484   EXPECT_GE(status_bounds.width(),
   1485             status_area_widget->GetContentsView()->GetPreferredSize().width());
   1486   EXPECT_EQ(shelf->GetIdealBounds().width(),
   1487             display.GetWorkAreaInsets().right());
   1488   EXPECT_EQ(0, display.GetWorkAreaInsets().top());
   1489   EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
   1490   EXPECT_EQ(0, display.GetWorkAreaInsets().left());
   1491   EXPECT_EQ(display.work_area().right(), shelf_bounds.x());
   1492   EXPECT_EQ(display.bounds().y(), shelf_bounds.y());
   1493   EXPECT_EQ(display.bounds().height(), shelf_bounds.height());
   1494   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1495   display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
   1496   EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
   1497       display.GetWorkAreaInsets().right());
   1498   EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
   1499       display.bounds().right() - display.work_area().right());
   1500 
   1501   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1502   shelf->SetAlignment(SHELF_ALIGNMENT_TOP);
   1503   display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
   1504   shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
   1505   display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
   1506   ASSERT_NE(-1, display.id());
   1507   EXPECT_EQ(shelf->GetIdealBounds().height(),
   1508             display.GetWorkAreaInsets().top());
   1509   EXPECT_GE(shelf_bounds.height(),
   1510             GetShelfWidget()->GetContentsView()->GetPreferredSize().height());
   1511   EXPECT_EQ(SHELF_ALIGNMENT_TOP, GetSystemTray()->shelf_alignment());
   1512   status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen());
   1513   EXPECT_GE(status_bounds.height(),
   1514             status_area_widget->GetContentsView()->GetPreferredSize().height());
   1515   EXPECT_EQ(shelf->GetIdealBounds().height(),
   1516             display.GetWorkAreaInsets().top());
   1517   EXPECT_EQ(0, display.GetWorkAreaInsets().right());
   1518   EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
   1519   EXPECT_EQ(0, display.GetWorkAreaInsets().left());
   1520   EXPECT_EQ(display.work_area().y(), shelf_bounds.bottom());
   1521   EXPECT_EQ(display.bounds().x(), shelf_bounds.x());
   1522   EXPECT_EQ(display.bounds().width(), shelf_bounds.width());
   1523   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1524   display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
   1525   EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
   1526       display.GetWorkAreaInsets().top());
   1527   EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
   1528             display.work_area().y() - display.bounds().y());
   1529 }
   1530 
   1531 TEST_F(ShelfLayoutManagerTest, GestureEdgeSwipe) {
   1532   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1533   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1534   views::Widget* widget = new views::Widget;
   1535   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
   1536   params.bounds = gfx::Rect(0, 0, 200, 200);
   1537   params.context = CurrentContext();
   1538   widget->Init(params);
   1539   widget->Show();
   1540   widget->Maximize();
   1541 
   1542   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
   1543 
   1544   aura::Window* window = widget->GetNativeWindow();
   1545   shelf->LayoutShelf();
   1546 
   1547   gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen();
   1548   gfx::Rect bounds_shelf = window->bounds();
   1549 
   1550   // Edge swipe when SHELF_VISIBLE should not change visibility state.
   1551   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1552   generator.GestureEdgeSwipe();
   1553   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1554 
   1555   // Edge swipe when AUTO_HIDE_HIDDEN should change to AUTO_HIDE_SHOWN.
   1556   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1557   shelf->LayoutShelf();
   1558   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1559   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1560   generator.GestureEdgeSwipe();
   1561   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1562   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1563 
   1564   widget->SetFullscreen(true);
   1565   wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false);
   1566   shelf->UpdateVisibilityState();
   1567 
   1568   // Edge swipe in fullscreen + AUTO_HIDE_HIDDEN should show the shelf and
   1569   // remain fullscreen.
   1570   EXPECT_TRUE(widget->IsFullscreen());
   1571   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1572   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1573   generator.GestureEdgeSwipe();
   1574   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1575   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1576   EXPECT_TRUE(widget->IsFullscreen());
   1577 }
   1578 
   1579 #if defined(OS_WIN)
   1580 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
   1581 #define MAYBE_GestureDrag DISABLED_GestureDrag
   1582 #else
   1583 #define MAYBE_GestureDrag GestureDrag
   1584 #endif
   1585 
   1586 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureDrag) {
   1587   // Slop is an implementation detail of gesture recognition, and complicates
   1588   // these tests. Ignore it.
   1589   ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(0);
   1590   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1591   {
   1592     SCOPED_TRACE("BOTTOM");
   1593     RunGestureDragTests(gfx::Vector2d(0, 120));
   1594   }
   1595 
   1596   {
   1597     SCOPED_TRACE("LEFT");
   1598     shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
   1599     RunGestureDragTests(gfx::Vector2d(-120, 0));
   1600   }
   1601 
   1602   {
   1603     SCOPED_TRACE("RIGHT");
   1604     shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
   1605     RunGestureDragTests(gfx::Vector2d(120, 0));
   1606   }
   1607 }
   1608 
   1609 TEST_F(ShelfLayoutManagerTest, WindowVisibilityDisablesAutoHide) {
   1610   if (!SupportsMultipleDisplays())
   1611     return;
   1612 
   1613   UpdateDisplay("800x600,800x600");
   1614   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1615   shelf->LayoutShelf();
   1616   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1617 
   1618   // Create a visible window so auto-hide behavior is enforced
   1619   views::Widget* dummy = CreateTestWidget();
   1620 
   1621   // Window visible => auto hide behaves normally.
   1622   shelf->UpdateVisibilityState();
   1623   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1624 
   1625   // Window minimized => auto hide disabled.
   1626   dummy->Minimize();
   1627   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1628 
   1629   // Window closed => auto hide disabled.
   1630   dummy->CloseNow();
   1631   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1632 
   1633   // Multiple window test
   1634   views::Widget* window1 = CreateTestWidget();
   1635   views::Widget* window2 = CreateTestWidget();
   1636 
   1637   // both visible => normal autohide
   1638   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1639 
   1640   // either minimzed => normal autohide
   1641   window2->Minimize();
   1642   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1643   window2->Restore();
   1644   window1->Minimize();
   1645   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1646 
   1647   // both minimized => disable auto hide
   1648   window2->Minimize();
   1649   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1650 
   1651   // Test moving windows to/from other display.
   1652   window2->Restore();
   1653   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1654   // Move to second display.
   1655   window2->SetBounds(gfx::Rect(850, 50, 50, 50));
   1656   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1657   // Move back to primary display.
   1658   window2->SetBounds(gfx::Rect(50, 50, 50, 50));
   1659   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1660 }
   1661 
   1662 // Test that the shelf animates back to its normal position upon a user
   1663 // completing a gesture drag.
   1664 TEST_F(ShelfLayoutManagerTest, ShelfAnimatesWhenGestureComplete) {
   1665   if (!SupportsHostWindowResize())
   1666     return;
   1667 
   1668   // Test the shelf animates back to its original visible bounds when it is
   1669   // dragged when there are no visible windows.
   1670   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1671   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1672   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1673   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1674   gfx::Rect visible_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
   1675   {
   1676     // Enable animations so that we can make sure that they occur.
   1677     ui::ScopedAnimationDurationScaleMode regular_animations(
   1678         ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
   1679 
   1680     ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
   1681     gfx::Rect shelf_bounds_in_screen =
   1682         GetShelfWidget()->GetWindowBoundsInScreen();
   1683     gfx::Point start(shelf_bounds_in_screen.CenterPoint());
   1684     gfx::Point end(start.x(), shelf_bounds_in_screen.bottom());
   1685     generator.GestureScrollSequence(start, end,
   1686         base::TimeDelta::FromMilliseconds(10), 5);
   1687     EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1688     EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1689 
   1690     ShelfAnimationWaiter waiter(visible_bounds);
   1691     // Wait till the animation completes and check that it occurred.
   1692     waiter.WaitTillDoneAnimating();
   1693     EXPECT_TRUE(waiter.WasValidAnimation());
   1694   }
   1695 
   1696   // Create a visible window so auto-hide behavior is enforced.
   1697   CreateTestWidget();
   1698 
   1699   // Get the bounds of the shelf when it is hidden.
   1700   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1701   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1702   gfx::Rect auto_hidden_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
   1703 
   1704   {
   1705     // Enable the animations so that we can make sure they do occur.
   1706     ui::ScopedAnimationDurationScaleMode regular_animations(
   1707         ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
   1708 
   1709     gfx::Point start =
   1710         GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
   1711     gfx::Point end(start.x(), start.y() - 100);
   1712     ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
   1713 
   1714     // Test that the shelf animates to the visible bounds after a swipe up on
   1715     // the auto hidden shelf.
   1716     generator.GestureScrollSequence(start, end,
   1717         base::TimeDelta::FromMilliseconds(10), 1);
   1718     EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1719     ShelfAnimationWaiter waiter1(visible_bounds);
   1720     waiter1.WaitTillDoneAnimating();
   1721     EXPECT_TRUE(waiter1.WasValidAnimation());
   1722 
   1723     // Test that the shelf animates to the auto hidden bounds after a swipe up
   1724     // on the visible shelf.
   1725     EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1726     generator.GestureScrollSequence(start, end,
   1727         base::TimeDelta::FromMilliseconds(10), 1);
   1728     EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1729     EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1730     ShelfAnimationWaiter waiter2(auto_hidden_bounds);
   1731     waiter2.WaitTillDoneAnimating();
   1732     EXPECT_TRUE(waiter2.WasValidAnimation());
   1733   }
   1734 }
   1735 
   1736 TEST_F(ShelfLayoutManagerTest, GestureRevealsTrayBubble) {
   1737   if (!SupportsHostWindowResize())
   1738     return;
   1739 
   1740   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1741   shelf->LayoutShelf();
   1742 
   1743   // Create a visible window so auto-hide behavior is enforced.
   1744   CreateTestWidget();
   1745 
   1746   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
   1747   SystemTray* tray = GetSystemTray();
   1748 
   1749   // First, make sure the shelf is visible.
   1750   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1751   EXPECT_FALSE(tray->HasSystemBubble());
   1752 
   1753   // Now, drag up on the tray to show the bubble.
   1754   gfx::Point start = GetShelfWidget()->status_area_widget()->
   1755       GetWindowBoundsInScreen().CenterPoint();
   1756   gfx::Point end(start.x(), start.y() - 100);
   1757   generator.GestureScrollSequence(start, end,
   1758       base::TimeDelta::FromMilliseconds(10), 1);
   1759   EXPECT_TRUE(tray->HasSystemBubble());
   1760   tray->CloseSystemBubble();
   1761   RunAllPendingInMessageLoop();
   1762   EXPECT_FALSE(tray->HasSystemBubble());
   1763 
   1764   // Drag again, but only a small amount, and slowly. The bubble should not be
   1765   // visible.
   1766   end.set_y(start.y() - 30);
   1767   generator.GestureScrollSequence(start, end,
   1768       base::TimeDelta::FromMilliseconds(500), 100);
   1769   EXPECT_FALSE(tray->HasSystemBubble());
   1770 
   1771   // Now, hide the shelf.
   1772   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1773 
   1774   // Start a drag from the bezel, and drag up to show both the shelf and the
   1775   // tray bubble.
   1776   start.set_y(start.y() + 100);
   1777   end.set_y(start.y() - 400);
   1778   generator.GestureScrollSequence(start, end,
   1779       base::TimeDelta::FromMilliseconds(10), 1);
   1780   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   1781   EXPECT_TRUE(tray->HasSystemBubble());
   1782 }
   1783 
   1784 TEST_F(ShelfLayoutManagerTest, ShelfFlickerOnTrayActivation) {
   1785   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1786 
   1787   // Create a visible window so auto-hide behavior is enforced.
   1788   CreateTestWidget();
   1789 
   1790   // Turn on auto-hide for the shelf.
   1791   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1792   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1793   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   1794 
   1795   // Show the status menu. That should make the shelf visible again.
   1796   Shell::GetInstance()->accelerator_controller()->PerformAction(
   1797       SHOW_SYSTEM_TRAY_BUBBLE, ui::Accelerator());
   1798   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   1799   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
   1800   EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
   1801 }
   1802 
   1803 TEST_F(ShelfLayoutManagerTest, WorkAreaChangeWorkspace) {
   1804   // Make sure the shelf is always visible.
   1805   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1806   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1807   shelf->LayoutShelf();
   1808 
   1809   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
   1810   params.bounds = gfx::Rect(0, 0, 200, 200);
   1811   params.context = CurrentContext();
   1812   views::Widget* widget_one = CreateTestWidgetWithParams(params);
   1813   widget_one->Maximize();
   1814 
   1815   views::Widget* widget_two = CreateTestWidgetWithParams(params);
   1816   widget_two->Maximize();
   1817   widget_two->Activate();
   1818 
   1819   // Both windows are maximized. They should be of the same size.
   1820   EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
   1821             widget_two->GetNativeWindow()->bounds().ToString());
   1822   int area_when_shelf_shown =
   1823       widget_one->GetNativeWindow()->bounds().size().GetArea();
   1824 
   1825   // Now hide the shelf.
   1826   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1827 
   1828   // Both windows should be resized according to the shelf status.
   1829   EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
   1830             widget_two->GetNativeWindow()->bounds().ToString());
   1831   // Resized to small.
   1832   EXPECT_LT(area_when_shelf_shown,
   1833             widget_one->GetNativeWindow()->bounds().size().GetArea());
   1834 
   1835   // Now show the shelf.
   1836   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1837 
   1838   // Again both windows should be of the same size.
   1839   EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
   1840             widget_two->GetNativeWindow()->bounds().ToString());
   1841   EXPECT_EQ(area_when_shelf_shown,
   1842             widget_one->GetNativeWindow()->bounds().size().GetArea());
   1843 }
   1844 
   1845 // Confirm that the shelf is dimmed only when content is maximized and
   1846 // shelf is not autohidden.
   1847 TEST_F(ShelfLayoutManagerTest, Dimming) {
   1848   GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1849   scoped_ptr<aura::Window> w1(CreateTestWindow());
   1850   w1->Show();
   1851   wm::ActivateWindow(w1.get());
   1852 
   1853   // Normal window doesn't dim shelf.
   1854   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
   1855   ShelfWidget* shelf = GetShelfWidget();
   1856   EXPECT_FALSE(shelf->GetDimsShelf());
   1857 
   1858   // Maximized window does.
   1859   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
   1860   EXPECT_TRUE(shelf->GetDimsShelf());
   1861 
   1862   // Change back to normal stops dimming.
   1863   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
   1864   EXPECT_FALSE(shelf->GetDimsShelf());
   1865 
   1866   // Changing back to maximized dims again.
   1867   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
   1868   EXPECT_TRUE(shelf->GetDimsShelf());
   1869 
   1870   // Changing shelf to autohide stops dimming.
   1871   GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1872   EXPECT_FALSE(shelf->GetDimsShelf());
   1873 }
   1874 
   1875 // Make sure that the shelf will not hide if the mouse is between a bubble and
   1876 // the shelf.
   1877 TEST_F(ShelfLayoutManagerTest, BubbleEnlargesShelfMouseHitArea) {
   1878   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1879   StatusAreaWidget* status_area_widget =
   1880       Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
   1881   SystemTray* tray = GetSystemTray();
   1882 
   1883   // Create a visible window so auto-hide behavior is enforced.
   1884   CreateTestWidget();
   1885 
   1886   shelf->LayoutShelf();
   1887   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
   1888 
   1889   // Make two iterations - first without a message bubble which should make
   1890   // the shelf disappear and then with a message bubble which should keep it
   1891   // visible.
   1892   for (int i = 0; i < 2; i++) {
   1893     // Make sure the shelf is visible and position the mouse over it. Then
   1894     // allow auto hide.
   1895     shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   1896     EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
   1897     gfx::Point center =
   1898         status_area_widget->GetWindowBoundsInScreen().CenterPoint();
   1899     generator.MoveMouseTo(center.x(), center.y());
   1900     shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1901     EXPECT_TRUE(shelf->IsVisible());
   1902     if (!i) {
   1903       // In our first iteration we make sure there is no bubble.
   1904       tray->CloseSystemBubble();
   1905       EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
   1906     } else {
   1907       // In our second iteration we show a bubble.
   1908       TestItem *item = new TestItem;
   1909       tray->AddTrayItem(item);
   1910       tray->ShowNotificationView(item);
   1911       EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
   1912     }
   1913     // Move the pointer over the edge of the shelf.
   1914     generator.MoveMouseTo(
   1915         center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 8);
   1916     shelf->UpdateVisibilityState();
   1917     if (i) {
   1918       EXPECT_TRUE(shelf->IsVisible());
   1919       EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
   1920     } else {
   1921       EXPECT_FALSE(shelf->IsVisible());
   1922       EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
   1923     }
   1924   }
   1925 }
   1926 
   1927 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColor) {
   1928   EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
   1929 
   1930   scoped_ptr<aura::Window> w1(CreateTestWindow());
   1931   w1->Show();
   1932   wm::ActivateWindow(w1.get());
   1933   EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
   1934   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
   1935   EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
   1936 
   1937   scoped_ptr<aura::Window> w2(CreateTestWindow());
   1938   w2->Show();
   1939   wm::ActivateWindow(w2.get());
   1940   // Overlaps with shelf.
   1941   w2->SetBounds(GetShelfLayoutManager()->GetIdealBounds());
   1942 
   1943   // Still background is 'maximized'.
   1944   EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
   1945 
   1946   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
   1947   EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
   1948   w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
   1949   EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
   1950 
   1951   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
   1952   EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
   1953   w1.reset();
   1954   EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
   1955 }
   1956 
   1957 // Verify that the shelf doesn't have the opaque background if it's auto-hide
   1958 // status.
   1959 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColorAutoHide) {
   1960   EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget ()->GetBackgroundType());
   1961 
   1962   GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
   1963   scoped_ptr<aura::Window> w1(CreateTestWindow());
   1964   w1->Show();
   1965   wm::ActivateWindow(w1.get());
   1966   EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
   1967   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
   1968   EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
   1969 }
   1970 
   1971 #if defined(OS_CHROMEOS)
   1972 #define MAYBE_StatusAreaHitBoxCoversEdge StatusAreaHitBoxCoversEdge
   1973 #else
   1974 #define MAYBE_StatusAreaHitBoxCoversEdge DISABLED_StatusAreaHitBoxCoversEdge
   1975 #endif
   1976 
   1977 // Verify the hit bounds of the status area extend to the edge of the shelf.
   1978 TEST_F(ShelfLayoutManagerTest, MAYBE_StatusAreaHitBoxCoversEdge) {
   1979   UpdateDisplay("400x400");
   1980   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   1981   StatusAreaWidget* status_area_widget =
   1982       Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
   1983   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
   1984   generator.MoveMouseTo(399,399);
   1985 
   1986   // Test bottom right pixel for bottom alignment.
   1987   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
   1988   generator.ClickLeftButton();
   1989   EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
   1990   generator.ClickLeftButton();
   1991   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
   1992 
   1993   // Test bottom right pixel for right alignment.
   1994   shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
   1995   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
   1996   generator.ClickLeftButton();
   1997   EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
   1998   generator.ClickLeftButton();
   1999   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
   2000 
   2001   // Test bottom left pixel for left alignment.
   2002   generator.MoveMouseTo(0, 399);
   2003   shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
   2004   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
   2005   generator.ClickLeftButton();
   2006   EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
   2007   generator.ClickLeftButton();
   2008   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
   2009 }
   2010 
   2011 // Tests that when the auto-hide behaviour is changed during an animation the
   2012 // target bounds are updated to reflect the new state.
   2013 TEST_F(ShelfLayoutManagerTest,
   2014        ShelfAutoHideToggleDuringAnimationUpdatesBounds) {
   2015   ShelfLayoutManager* shelf_manager = GetShelfLayoutManager();
   2016   aura::Window* status_window = GetShelfWidget()->status_area_widget()->
   2017       GetNativeView();
   2018   gfx::Rect initial_bounds = status_window->bounds();
   2019 
   2020   ui::ScopedAnimationDurationScaleMode regular_animations(
   2021       ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
   2022   shelf_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
   2023   gfx::Rect hide_target_bounds =  status_window->GetTargetBounds();
   2024   EXPECT_GT(hide_target_bounds.y(), initial_bounds.y());
   2025 
   2026   shelf_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
   2027   gfx::Rect reshow_target_bounds = status_window->GetTargetBounds();
   2028   EXPECT_EQ(initial_bounds, reshow_target_bounds);
   2029 }
   2030 
   2031 }  // namespace ash
   2032