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