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