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