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