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