Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ash / shelf / shelf_layout_manager_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/shelf/shelf_layout_manager.h"
6
7 #include "ash/accelerators/accelerator_controller.h"
8 #include "ash/accelerators/accelerator_table.h"
9 #include "ash/ash_switches.h"
10 #include "ash/display/display_manager.h"
11 #include "ash/focus_cycler.h"
12 #include "ash/root_window_controller.h"
13 #include "ash/session_state_delegate.h"
14 #include "ash/shelf/shelf.h"
15 #include "ash/shelf/shelf_layout_manager_observer.h"
16 #include "ash/shelf/shelf_view.h"
17 #include "ash/shelf/shelf_widget.h"
18 #include "ash/shell.h"
19 #include "ash/shell_window_ids.h"
20 #include "ash/system/status_area_widget.h"
21 #include "ash/system/tray/system_tray.h"
22 #include "ash/system/tray/system_tray_item.h"
23 #include "ash/test/ash_test_base.h"
24 #include "ash/test/shelf_test_api.h"
25 #include "ash/wm/window_state.h"
26 #include "ash/wm/window_util.h"
27 #include "base/command_line.h"
28 #include "base/strings/utf_string_conversions.h"
29 #include "ui/aura/client/aura_constants.h"
30 #include "ui/aura/root_window.h"
31 #include "ui/aura/test/event_generator.h"
32 #include "ui/aura/window.h"
33 #include "ui/compositor/layer.h"
34 #include "ui/compositor/layer_animator.h"
35 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
36 #include "ui/events/gestures/gesture_configuration.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(base::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(base::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(
288         new views::Label(base::UTF8ToUTF16("Detailed")));
289     return detailed_view_;
290   }
291
292   virtual views::View* CreateNotificationView(
293       user::LoginStatus status) OVERRIDE {
294     notification_view_ = new views::View;
295     return notification_view_;
296   }
297
298   virtual void DestroyTrayView() OVERRIDE {
299     tray_view_ = NULL;
300   }
301
302   virtual void DestroyDefaultView() OVERRIDE {
303     default_view_ = NULL;
304   }
305
306   virtual void DestroyDetailedView() OVERRIDE {
307     detailed_view_ = NULL;
308   }
309
310   virtual void DestroyNotificationView() OVERRIDE {
311     notification_view_ = NULL;
312   }
313
314   virtual void UpdateAfterLoginStatusChange(
315       user::LoginStatus status) OVERRIDE {}
316
317   views::View* tray_view() const { return tray_view_; }
318   views::View* default_view() const { return default_view_; }
319   views::View* detailed_view() const { return detailed_view_; }
320   views::View* notification_view() const { return notification_view_; }
321
322  private:
323   views::View* tray_view_;
324   views::View* default_view_;
325   views::View* detailed_view_;
326   views::View* notification_view_;
327
328   DISALLOW_COPY_AND_ASSIGN(TestItem);
329 };
330
331 }  // namespace
332
333 class ShelfLayoutManagerTest : public ash::test::AshTestBase {
334  public:
335   ShelfLayoutManagerTest() {}
336
337   void SetState(ShelfLayoutManager* shelf,
338                 ShelfVisibilityState state) {
339     shelf->SetState(state);
340   }
341
342   void UpdateAutoHideStateNow() {
343     GetShelfLayoutManager()->UpdateAutoHideStateNow();
344   }
345
346   aura::Window* CreateTestWindow() {
347     aura::Window* window = new aura::Window(NULL);
348     window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
349     window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
350     window->Init(aura::WINDOW_LAYER_TEXTURED);
351     ParentWindowInPrimaryRootWindow(window);
352     return window;
353   }
354
355   views::Widget* CreateTestWidgetWithParams(
356       const views::Widget::InitParams& params) {
357     views::Widget* out = new views::Widget;
358     out->Init(params);
359     out->Show();
360     return out;
361   }
362
363   // Create a simple widget attached to the current context (will
364   // delete on TearDown).
365   views::Widget* CreateTestWidget() {
366     views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
367     params.bounds = gfx::Rect(0, 0, 200, 200);
368     params.context = CurrentContext();
369     return CreateTestWidgetWithParams(params);
370   }
371
372   // Overridden from AshTestBase:
373   virtual void SetUp() OVERRIDE {
374     CommandLine::ForCurrentProcess()->AppendSwitch(
375         ash::switches::kAshEnableTrayDragging);
376     test::AshTestBase::SetUp();
377   }
378
379   void RunGestureDragTests(gfx::Vector2d);
380
381  private:
382   DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest);
383 };
384
385 void ShelfLayoutManagerTest::RunGestureDragTests(gfx::Vector2d delta) {
386   ShelfLayoutManager* shelf = GetShelfLayoutManager();
387   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
388   views::Widget* widget = new views::Widget;
389   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
390   params.bounds = gfx::Rect(0, 0, 200, 200);
391   params.context = CurrentContext();
392   widget->Init(params);
393   widget->Show();
394   widget->Maximize();
395
396   aura::Window* window = widget->GetNativeWindow();
397   shelf->LayoutShelf();
398
399   gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen();
400   gfx::Rect bounds_shelf = window->bounds();
401   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
402
403   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
404   shelf->LayoutShelf();
405   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
406
407   gfx::Rect bounds_noshelf = window->bounds();
408   gfx::Rect shelf_hidden = GetShelfWidget()->GetWindowBoundsInScreen();
409
410   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
411   shelf->LayoutShelf();
412
413   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
414   const int kNumScrollSteps = 4;
415   ShelfDragCallback handler(shelf_hidden, shelf_shown);
416
417   // Swipe up on the shelf. This should not change any state.
418   gfx::Point start = GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
419   gfx::Point end = start + delta;
420
421   // Swipe down on the shelf to hide it.
422   generator.GestureScrollSequenceWithCallback(start, end,
423       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
424       base::Bind(&ShelfDragCallback::ProcessScroll,
425                  base::Unretained(&handler)));
426   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
427   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
428   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
429   EXPECT_NE(bounds_shelf.ToString(), window->bounds().ToString());
430   EXPECT_NE(shelf_shown.ToString(),
431             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
432
433   // Swipe up to show the shelf.
434   generator.GestureScrollSequenceWithCallback(end, start,
435       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
436       base::Bind(&ShelfDragCallback::ProcessScroll,
437                  base::Unretained(&handler)));
438   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
439   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
440   EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
441   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
442             GetShelfWidget()->GetWindowBoundsInScreen());
443   EXPECT_EQ(shelf_shown.ToString(),
444             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
445
446   // Swipe up again. The shelf should hide.
447   end = start - delta;
448   generator.GestureScrollSequenceWithCallback(start, end,
449       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
450       base::Bind(&ShelfDragCallback::ProcessScroll,
451                  base::Unretained(&handler)));
452   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
453   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
454   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
455   EXPECT_EQ(shelf_hidden.ToString(),
456             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
457
458   // Swipe up yet again to show it.
459   end = start + delta;
460   generator.GestureScrollSequenceWithCallback(end, start,
461       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
462       base::Bind(&ShelfDragCallback::ProcessScroll,
463                  base::Unretained(&handler)));
464
465   // Swipe down very little. It shouldn't change any state.
466   if (GetShelfLayoutManager()->IsHorizontalAlignment())
467     end.set_y(start.y() + shelf_shown.height() * 3 / 10);
468   else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
469     end.set_x(start.x() - shelf_shown.width() * 3 / 10);
470   else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
471     end.set_x(start.x() + shelf_shown.width() * 3 / 10);
472   generator.GestureScrollSequence(start, end,
473                                   base::TimeDelta::FromMilliseconds(10), 5);
474   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
475   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
476   EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
477   EXPECT_EQ(shelf_shown.ToString(),
478             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
479
480   // Swipe down again to hide.
481   end = start + delta;
482   generator.GestureScrollSequenceWithCallback(start, end,
483       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
484       base::Bind(&ShelfDragCallback::ProcessScroll,
485                  base::Unretained(&handler)));
486   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
487   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
488   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
489   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
490   EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
491   EXPECT_EQ(shelf_hidden.ToString(),
492             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
493
494   // Swipe up in extended hit region to show it.
495   gfx::Point extended_start = start;
496   if (GetShelfLayoutManager()->IsHorizontalAlignment())
497     extended_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().y() -1);
498   else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
499     extended_start.set_x(
500         GetShelfWidget()->GetWindowBoundsInScreen().right() + 1);
501   else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
502     extended_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().x() - 1);
503   end = extended_start - delta;
504   generator.GestureScrollSequenceWithCallback(extended_start, end,
505       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
506       base::Bind(&ShelfDragCallback::ProcessScroll,
507                  base::Unretained(&handler)));
508   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
509   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
510   EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
511   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
512             GetShelfWidget()->GetWindowBoundsInScreen());
513   EXPECT_EQ(shelf_shown.ToString(),
514             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
515
516   // Swipe down again to hide.
517   end = start + delta;
518   generator.GestureScrollSequenceWithCallback(start, end,
519       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
520       base::Bind(&ShelfDragCallback::ProcessScroll,
521                  base::Unretained(&handler)));
522   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
523   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
524   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
525   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
526   EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
527   EXPECT_EQ(shelf_hidden.ToString(),
528             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
529
530   // Swipe up outside the hit area. This should not change anything.
531   gfx::Point outside_start = gfx::Point(
532       (GetShelfWidget()->GetWindowBoundsInScreen().x() +
533        GetShelfWidget()->GetWindowBoundsInScreen().right())/2,
534       GetShelfWidget()->GetWindowBoundsInScreen().y() - 50);
535   end = outside_start + delta;
536   generator.GestureScrollSequence(outside_start,
537                                   end,
538                                   base::TimeDelta::FromMilliseconds(10),
539                                   kNumScrollSteps);
540   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
541   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
542   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
543   EXPECT_EQ(shelf_hidden.ToString(),
544             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
545
546   // Swipe up from below the shelf where a bezel would be, this should show the
547   // shelf.
548   gfx::Point below_start = start;
549   if (GetShelfLayoutManager()->IsHorizontalAlignment())
550     below_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().bottom() + 1);
551   else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
552     below_start.set_x(
553         GetShelfWidget()->GetWindowBoundsInScreen().x() - 1);
554   else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
555     below_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().right() + 1);
556   end = below_start - delta;
557   generator.GestureScrollSequence(below_start,
558                                   end,
559                                   base::TimeDelta::FromMilliseconds(10),
560                                   kNumScrollSteps);
561   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
562   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
563   EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
564   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
565             GetShelfWidget()->GetWindowBoundsInScreen());
566   EXPECT_EQ(shelf_shown.ToString(),
567             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
568
569   // Swipe down again to hide.
570   end = start + delta;
571   generator.GestureScrollSequenceWithCallback(start, end,
572       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
573       base::Bind(&ShelfDragCallback::ProcessScroll,
574                  base::Unretained(&handler)));
575   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
576   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
577   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
578   EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
579   EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
580   EXPECT_EQ(shelf_hidden.ToString(),
581             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
582
583   // Put |widget| into fullscreen. Set the shelf to be auto hidden when |widget|
584   // is fullscreen. (eg browser immersive fullscreen).
585   widget->SetFullscreen(true);
586   wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false);
587   shelf->UpdateVisibilityState();
588
589   gfx::Rect bounds_fullscreen = window->bounds();
590   EXPECT_TRUE(widget->IsFullscreen());
591   EXPECT_NE(bounds_noshelf.ToString(), bounds_fullscreen.ToString());
592
593   // Swipe up. This should show the shelf.
594   end = below_start - delta;
595   generator.GestureScrollSequenceWithCallback(below_start, end,
596       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
597       base::Bind(&ShelfDragCallback::ProcessScroll,
598                  base::Unretained(&handler)));
599   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
600   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
601   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
602   EXPECT_EQ(shelf_shown.ToString(),
603             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
604   EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
605
606   // Swipe up again. This should hide the shelf.
607   generator.GestureScrollSequenceWithCallback(below_start, end,
608       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
609       base::Bind(&ShelfDragCallback::ProcessScroll,
610                  base::Unretained(&handler)));
611   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
612   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
613   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
614   EXPECT_EQ(shelf_hidden.ToString(),
615             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
616   EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
617
618   // Set the shelf to be hidden when |widget| is fullscreen. (eg tab fullscreen
619   // with or without immersive browser fullscreen).
620   wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(true);
621   shelf->UpdateVisibilityState();
622   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
623   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
624
625   // Swipe-up. This should not change anything.
626   end = start - delta;
627   generator.GestureScrollSequenceWithCallback(below_start, end,
628       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
629       base::Bind(&ShelfDragCallback::ProcessScroll,
630                  base::Unretained(&handler)));
631   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
632   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
633   EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
634
635   // Close actually, otherwise further event may be affected since widget
636   // is fullscreen status.
637   widget->Close();
638   RunAllPendingInMessageLoop();
639
640   // The shelf should be shown because there are no more visible windows.
641   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
642   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
643   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
644
645   // Swipe-up to hide. This should have no effect because there are no visible
646   // windows.
647   end = below_start - delta;
648   generator.GestureScrollSequenceWithCallback(below_start, end,
649       base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
650       base::Bind(&ShelfDragCallback::ProcessScroll,
651                  base::Unretained(&handler)));
652   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
653   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
654   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
655 }
656
657 // Need to be implemented.  http://crbug.com/111279.
658 #if defined(OS_WIN)
659 #define MAYBE_SetVisible DISABLED_SetVisible
660 #else
661 #define MAYBE_SetVisible SetVisible
662 #endif
663 // Makes sure SetVisible updates work area and widget appropriately.
664 TEST_F(ShelfLayoutManagerTest, MAYBE_SetVisible) {
665   ShelfWidget* shelf = GetShelfWidget();
666   ShelfLayoutManager* manager = shelf->shelf_layout_manager();
667   // Force an initial layout.
668   manager->LayoutShelf();
669   EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state());
670
671   gfx::Rect status_bounds(
672       shelf->status_area_widget()->GetWindowBoundsInScreen());
673   gfx::Rect shelf_bounds(
674       shelf->GetWindowBoundsInScreen());
675   int shelf_height = manager->GetIdealBounds().height();
676   gfx::Screen* screen = Shell::GetScreen();
677   gfx::Display display = screen->GetDisplayNearestWindow(
678       Shell::GetPrimaryRootWindow());
679   ASSERT_NE(-1, display.id());
680   // Bottom inset should be the max of widget heights.
681   EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom());
682
683   // Hide the shelf.
684   SetState(manager, SHELF_HIDDEN);
685   // Run the animation to completion.
686   StepWidgetLayerAnimatorToEnd(shelf);
687   StepWidgetLayerAnimatorToEnd(shelf->status_area_widget());
688   EXPECT_EQ(SHELF_HIDDEN, manager->visibility_state());
689   display = screen->GetDisplayNearestWindow(
690       Shell::GetPrimaryRootWindow());
691
692   EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
693
694   // Make sure the bounds of the two widgets changed.
695   EXPECT_GE(shelf->GetNativeView()->bounds().y(),
696             screen->GetPrimaryDisplay().bounds().bottom());
697   EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(),
698             screen->GetPrimaryDisplay().bounds().bottom());
699
700   // And show it again.
701   SetState(manager, SHELF_VISIBLE);
702   // Run the animation to completion.
703   StepWidgetLayerAnimatorToEnd(shelf);
704   StepWidgetLayerAnimatorToEnd(shelf->status_area_widget());
705   EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state());
706   display = screen->GetDisplayNearestWindow(
707       Shell::GetPrimaryRootWindow());
708   EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom());
709
710   // Make sure the bounds of the two widgets changed.
711   shelf_bounds = shelf->GetNativeView()->bounds();
712   EXPECT_LT(shelf_bounds.y(), 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 shelf is sized when the status area changes size.
779 TEST_F(ShelfLayoutManagerTest, ShelfUpdatedWhenStatusAreaChangesSize) {
780   Shelf* shelf = Shelf::ForPrimaryDisplay();
781   ASSERT_TRUE(shelf);
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::ShelfTestAPI(shelf).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   // shelf 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   // shelf 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/shelf is focused.
1201 TEST_F(ShelfLayoutManagerTest, VisibleWhenStatusOrShelfFocused) {
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 shelf. 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 shelf_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       shelf_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(), shelf_bounds.x());
1429   EXPECT_EQ(display.bounds().y(), shelf_bounds.y());
1430   EXPECT_EQ(display.bounds().height(), shelf_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   shelf_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(shelf_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(), shelf_bounds.x());
1457   EXPECT_EQ(display.bounds().y(), shelf_bounds.y());
1458   EXPECT_EQ(display.bounds().height(), shelf_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   shelf_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(shelf_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(), shelf_bounds.bottom());
1486   EXPECT_EQ(display.bounds().x(), shelf_bounds.x());
1487   EXPECT_EQ(display.bounds().width(), shelf_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 TEST_F(ShelfLayoutManagerTest, GestureEdgeSwipe) {
1497   ShelfLayoutManager* shelf = GetShelfLayoutManager();
1498   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1499   views::Widget* widget = new views::Widget;
1500   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1501   params.bounds = gfx::Rect(0, 0, 200, 200);
1502   params.context = CurrentContext();
1503   widget->Init(params);
1504   widget->Show();
1505   widget->Maximize();
1506
1507   aura::Window* window = widget->GetNativeWindow();
1508   shelf->LayoutShelf();
1509
1510   gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen();
1511   gfx::Rect bounds_shelf = window->bounds();
1512   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1513
1514   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1515   shelf->LayoutShelf();
1516   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1517
1518   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1519   generator.GestureEdgeSwipe();
1520
1521   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1522   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
1523
1524   widget->SetFullscreen(true);
1525   wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false);
1526   shelf->UpdateVisibilityState();
1527
1528   gfx::Rect bounds_fullscreen = window->bounds();
1529   EXPECT_TRUE(widget->IsFullscreen());
1530   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1531
1532   generator.GestureEdgeSwipe();
1533   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1534   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
1535   EXPECT_FALSE(widget->IsFullscreen());
1536 }
1537
1538 #if defined(OS_WIN)
1539 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1540 #define MAYBE_GestureDrag DISABLED_GestureDrag
1541 #else
1542 #define MAYBE_GestureDrag GestureDrag
1543 #endif
1544
1545 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureDrag) {
1546   // Slop is an implementation detail of gesture recognition, and complicates
1547   // these tests. Ignore it.
1548   ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(0);
1549   ShelfLayoutManager* shelf = GetShelfLayoutManager();
1550   {
1551     SCOPED_TRACE("BOTTOM");
1552     RunGestureDragTests(gfx::Vector2d(0, 120));
1553   }
1554
1555   {
1556     SCOPED_TRACE("LEFT");
1557     shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
1558     RunGestureDragTests(gfx::Vector2d(-120, 0));
1559   }
1560
1561   {
1562     SCOPED_TRACE("RIGHT");
1563     shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
1564     RunGestureDragTests(gfx::Vector2d(120, 0));
1565   }
1566 }
1567
1568 TEST_F(ShelfLayoutManagerTest, WindowVisibilityDisablesAutoHide) {
1569   if (!SupportsMultipleDisplays())
1570     return;
1571
1572   UpdateDisplay("800x600,800x600");
1573   ShelfLayoutManager* shelf = GetShelfLayoutManager();
1574   shelf->LayoutShelf();
1575   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1576
1577   // Create a visible window so auto-hide behavior is enforced
1578   views::Widget* dummy = CreateTestWidget();
1579
1580   // Window visible => auto hide behaves normally.
1581   shelf->UpdateVisibilityState();
1582   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1583
1584   // Window minimized => auto hide disabled.
1585   dummy->Minimize();
1586   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1587
1588   // Window closed => auto hide disabled.
1589   dummy->CloseNow();
1590   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1591
1592   // Multiple window test
1593   views::Widget* window1 = CreateTestWidget();
1594   views::Widget* window2 = CreateTestWidget();
1595
1596   // both visible => normal autohide
1597   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1598
1599   // either minimzed => normal autohide
1600   window2->Minimize();
1601   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1602   window2->Restore();
1603   window1->Minimize();
1604   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1605
1606   // both minimized => disable auto hide
1607   window2->Minimize();
1608   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1609
1610   // Test moving windows to/from other display.
1611   window2->Restore();
1612   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1613   // Move to second display.
1614   window2->SetBounds(gfx::Rect(850, 50, 50, 50));
1615   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1616   // Move back to primary display.
1617   window2->SetBounds(gfx::Rect(50, 50, 50, 50));
1618   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1619 }
1620
1621 // Test that the shelf animates back to its normal position upon a user
1622 // completing a gesture drag.
1623 TEST_F(ShelfLayoutManagerTest, ShelfAnimatesWhenGestureComplete) {
1624   if (!SupportsHostWindowResize())
1625     return;
1626
1627   // Test the shelf animates back to its original visible bounds when it is
1628   // dragged when there are no visible windows.
1629   ShelfLayoutManager* shelf = GetShelfLayoutManager();
1630   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1631   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1632   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1633   gfx::Rect visible_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
1634   {
1635     // Enable animations so that we can make sure that they occur.
1636     ui::ScopedAnimationDurationScaleMode regular_animations(
1637         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
1638
1639     aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1640     gfx::Rect shelf_bounds_in_screen =
1641         GetShelfWidget()->GetWindowBoundsInScreen();
1642     gfx::Point start(shelf_bounds_in_screen.CenterPoint());
1643     gfx::Point end(start.x(), shelf_bounds_in_screen.bottom());
1644     generator.GestureScrollSequence(start, end,
1645         base::TimeDelta::FromMilliseconds(10), 5);
1646     EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1647     EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1648
1649     ShelfAnimationWaiter waiter(visible_bounds);
1650     // Wait till the animation completes and check that it occurred.
1651     waiter.WaitTillDoneAnimating();
1652     EXPECT_TRUE(waiter.WasValidAnimation());
1653   }
1654
1655   // Create a visible window so auto-hide behavior is enforced.
1656   CreateTestWidget();
1657
1658   // Get the bounds of the shelf when it is hidden.
1659   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1660   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1661   gfx::Rect auto_hidden_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
1662
1663   {
1664     // Enable the animations so that we can make sure they do occur.
1665     ui::ScopedAnimationDurationScaleMode regular_animations(
1666         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
1667
1668     gfx::Point start =
1669         GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
1670     gfx::Point end(start.x(), start.y() - 100);
1671     aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1672
1673     // Test that the shelf animates to the visible bounds after a swipe up on
1674     // the auto hidden shelf.
1675     generator.GestureScrollSequence(start, end,
1676         base::TimeDelta::FromMilliseconds(10), 1);
1677     EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1678     ShelfAnimationWaiter waiter1(visible_bounds);
1679     waiter1.WaitTillDoneAnimating();
1680     EXPECT_TRUE(waiter1.WasValidAnimation());
1681
1682     // Test that the shelf animates to the auto hidden bounds after a swipe up
1683     // on the visible shelf.
1684     EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1685     generator.GestureScrollSequence(start, end,
1686         base::TimeDelta::FromMilliseconds(10), 1);
1687     EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1688     EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1689     ShelfAnimationWaiter waiter2(auto_hidden_bounds);
1690     waiter2.WaitTillDoneAnimating();
1691     EXPECT_TRUE(waiter2.WasValidAnimation());
1692   }
1693 }
1694
1695 TEST_F(ShelfLayoutManagerTest, GestureRevealsTrayBubble) {
1696   if (!SupportsHostWindowResize())
1697     return;
1698
1699   ShelfLayoutManager* shelf = GetShelfLayoutManager();
1700   shelf->LayoutShelf();
1701
1702   // Create a visible window so auto-hide behavior is enforced.
1703   CreateTestWidget();
1704
1705   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1706   SystemTray* tray = GetSystemTray();
1707
1708   // First, make sure the shelf is visible.
1709   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1710   EXPECT_FALSE(tray->HasSystemBubble());
1711
1712   // Now, drag up on the tray to show the bubble.
1713   gfx::Point start = GetShelfWidget()->status_area_widget()->
1714       GetWindowBoundsInScreen().CenterPoint();
1715   gfx::Point end(start.x(), start.y() - 100);
1716   generator.GestureScrollSequence(start, end,
1717       base::TimeDelta::FromMilliseconds(10), 1);
1718   EXPECT_TRUE(tray->HasSystemBubble());
1719   tray->CloseSystemBubble();
1720   RunAllPendingInMessageLoop();
1721   EXPECT_FALSE(tray->HasSystemBubble());
1722
1723   // Drag again, but only a small amount, and slowly. The bubble should not be
1724   // visible.
1725   end.set_y(start.y() - 30);
1726   generator.GestureScrollSequence(start, end,
1727       base::TimeDelta::FromMilliseconds(500), 100);
1728   EXPECT_FALSE(tray->HasSystemBubble());
1729
1730   // Now, hide the shelf.
1731   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1732
1733   // Start a drag from the bezel, and drag up to show both the shelf and the
1734   // tray bubble.
1735   start.set_y(start.y() + 100);
1736   end.set_y(start.y() - 400);
1737   generator.GestureScrollSequence(start, end,
1738       base::TimeDelta::FromMilliseconds(10), 1);
1739   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1740   EXPECT_TRUE(tray->HasSystemBubble());
1741 }
1742
1743 TEST_F(ShelfLayoutManagerTest, ShelfFlickerOnTrayActivation) {
1744   ShelfLayoutManager* shelf = GetShelfLayoutManager();
1745
1746   // Create a visible window so auto-hide behavior is enforced.
1747   CreateTestWidget();
1748
1749   // Turn on auto-hide for the shelf.
1750   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1751   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1752   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1753
1754   // Show the status menu. That should make the shelf visible again.
1755   Shell::GetInstance()->accelerator_controller()->PerformAction(
1756       SHOW_SYSTEM_TRAY_BUBBLE, ui::Accelerator());
1757   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1758   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1759   EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
1760 }
1761
1762 TEST_F(ShelfLayoutManagerTest, WorkAreaChangeWorkspace) {
1763   // Make sure the shelf is always visible.
1764   ShelfLayoutManager* shelf = GetShelfLayoutManager();
1765   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1766   shelf->LayoutShelf();
1767
1768   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1769   params.bounds = gfx::Rect(0, 0, 200, 200);
1770   params.context = CurrentContext();
1771   views::Widget* widget_one = CreateTestWidgetWithParams(params);
1772   widget_one->Maximize();
1773
1774   views::Widget* widget_two = CreateTestWidgetWithParams(params);
1775   widget_two->Maximize();
1776   widget_two->Activate();
1777
1778   // Both windows are maximized. They should be of the same size.
1779   EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
1780             widget_two->GetNativeWindow()->bounds().ToString());
1781   int area_when_shelf_shown =
1782       widget_one->GetNativeWindow()->bounds().size().GetArea();
1783
1784   // Now hide the shelf.
1785   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1786
1787   // Both windows should be resized according to the shelf status.
1788   EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
1789             widget_two->GetNativeWindow()->bounds().ToString());
1790   // Resized to small.
1791   EXPECT_LT(area_when_shelf_shown,
1792             widget_one->GetNativeWindow()->bounds().size().GetArea());
1793
1794   // Now show the shelf.
1795   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1796
1797   // Again both windows should be of the same size.
1798   EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
1799             widget_two->GetNativeWindow()->bounds().ToString());
1800   EXPECT_EQ(area_when_shelf_shown,
1801             widget_one->GetNativeWindow()->bounds().size().GetArea());
1802 }
1803
1804 // Confirm that the shelf is dimmed only when content is maximized and
1805 // shelf is not autohidden.
1806 TEST_F(ShelfLayoutManagerTest, Dimming) {
1807   GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1808   scoped_ptr<aura::Window> w1(CreateTestWindow());
1809   w1->Show();
1810   wm::ActivateWindow(w1.get());
1811
1812   // Normal window doesn't dim shelf.
1813   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
1814   ShelfWidget* shelf = GetShelfWidget();
1815   EXPECT_FALSE(shelf->GetDimsShelf());
1816
1817   // Maximized window does.
1818   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1819   EXPECT_TRUE(shelf->GetDimsShelf());
1820
1821   // Change back to normal stops dimming.
1822   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
1823   EXPECT_FALSE(shelf->GetDimsShelf());
1824
1825   // Changing back to maximized dims again.
1826   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1827   EXPECT_TRUE(shelf->GetDimsShelf());
1828
1829   // Changing shelf to autohide stops dimming.
1830   GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1831   EXPECT_FALSE(shelf->GetDimsShelf());
1832 }
1833
1834 // Make sure that the shelf will not hide if the mouse is between a bubble and
1835 // the shelf.
1836 TEST_F(ShelfLayoutManagerTest, BubbleEnlargesShelfMouseHitArea) {
1837   ShelfLayoutManager* shelf = GetShelfLayoutManager();
1838   StatusAreaWidget* status_area_widget =
1839       Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
1840   SystemTray* tray = GetSystemTray();
1841
1842   // Create a visible window so auto-hide behavior is enforced.
1843   CreateTestWidget();
1844
1845   shelf->LayoutShelf();
1846   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1847
1848   // Make two iterations - first without a message bubble which should make
1849   // the shelf disappear and then with a message bubble which should keep it
1850   // visible.
1851   for (int i = 0; i < 2; i++) {
1852     // Make sure the shelf is visible and position the mouse over it. Then
1853     // allow auto hide.
1854     shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1855     EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1856     gfx::Point center =
1857         status_area_widget->GetWindowBoundsInScreen().CenterPoint();
1858     generator.MoveMouseTo(center.x(), center.y());
1859     shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1860     EXPECT_TRUE(shelf->IsVisible());
1861     if (!i) {
1862       // In our first iteration we make sure there is no bubble.
1863       tray->CloseSystemBubble();
1864       EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1865     } else {
1866       // In our second iteration we show a bubble.
1867       TestItem *item = new TestItem;
1868       tray->AddTrayItem(item);
1869       tray->ShowNotificationView(item);
1870       EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1871     }
1872     // Move the pointer over the edge of the shelf.
1873     generator.MoveMouseTo(
1874         center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 8);
1875     shelf->UpdateVisibilityState();
1876     if (i) {
1877       EXPECT_TRUE(shelf->IsVisible());
1878       EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1879     } else {
1880       EXPECT_FALSE(shelf->IsVisible());
1881       EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1882     }
1883   }
1884 }
1885
1886 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColor) {
1887   EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
1888
1889   scoped_ptr<aura::Window> w1(CreateTestWindow());
1890   w1->Show();
1891   wm::ActivateWindow(w1.get());
1892   EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
1893   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1894   EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
1895
1896   scoped_ptr<aura::Window> w2(CreateTestWindow());
1897   w2->Show();
1898   wm::ActivateWindow(w2.get());
1899   // Overlaps with shelf.
1900   w2->SetBounds(GetShelfLayoutManager()->GetIdealBounds());
1901
1902   // Still background is 'maximized'.
1903   EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
1904
1905   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
1906   EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
1907   w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
1908   EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
1909
1910   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1911   EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
1912   w1.reset();
1913   EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
1914 }
1915
1916 // Verify that the shelf doesn't have the opaque background if it's auto-hide
1917 // status.
1918 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColorAutoHide) {
1919   EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget ()->GetBackgroundType());
1920
1921   GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1922   scoped_ptr<aura::Window> w1(CreateTestWindow());
1923   w1->Show();
1924   wm::ActivateWindow(w1.get());
1925   EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
1926   w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1927   EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
1928 }
1929
1930 #if defined(OS_CHROMEOS)
1931 #define MAYBE_StatusAreaHitBoxCoversEdge StatusAreaHitBoxCoversEdge
1932 #else
1933 #define MAYBE_StatusAreaHitBoxCoversEdge DISABLED_StatusAreaHitBoxCoversEdge
1934 #endif
1935
1936 // Verify the hit bounds of the status area extend to the edge of the shelf.
1937 TEST_F(ShelfLayoutManagerTest, MAYBE_StatusAreaHitBoxCoversEdge) {
1938   UpdateDisplay("400x400");
1939   ShelfLayoutManager* shelf = GetShelfLayoutManager();
1940   StatusAreaWidget* status_area_widget =
1941       Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
1942   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1943   generator.MoveMouseTo(399,399);
1944
1945   // Test bottom right pixel for bottom alignment.
1946   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1947   generator.ClickLeftButton();
1948   EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1949   generator.ClickLeftButton();
1950   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1951
1952   // Test bottom right pixel for right alignment.
1953   shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
1954   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1955   generator.ClickLeftButton();
1956   EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1957   generator.ClickLeftButton();
1958   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1959
1960   // Test bottom left pixel for left alignment.
1961   generator.MoveMouseTo(0, 399);
1962   shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
1963   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1964   generator.ClickLeftButton();
1965   EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1966   generator.ClickLeftButton();
1967   EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1968 }
1969
1970 }  // namespace internal
1971 }  // namespace ash