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