Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / ash / shelf / shelf_layout_manager_unittest.cc
blob74d88df5279bbbd594858fd79f2d0f5b8ec2db9f
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_manager.h"
11 #include "ash/focus_cycler.h"
12 #include "ash/launcher/launcher.h"
13 #include "ash/launcher/launcher_view.h"
14 #include "ash/root_window_controller.h"
15 #include "ash/screen_ash.h"
16 #include "ash/shelf/shelf_widget.h"
17 #include "ash/shell.h"
18 #include "ash/shell_delegate.h"
19 #include "ash/shell_window_ids.h"
20 #include "ash/system/status_area_widget.h"
21 #include "ash/system/tray/system_tray.h"
22 #include "ash/system/tray/system_tray_item.h"
23 #include "ash/test/ash_test_base.h"
24 #include "ash/wm/window_util.h"
25 #include "base/command_line.h"
26 #include "base/utf_string_conversions.h"
27 #include "ui/aura/client/aura_constants.h"
28 #include "ui/aura/root_window.h"
29 #include "ui/aura/test/event_generator.h"
30 #include "ui/aura/window.h"
31 #include "ui/base/animation/animation_container_element.h"
32 #include "ui/compositor/layer.h"
33 #include "ui/compositor/layer_animator.h"
34 #include "ui/gfx/display.h"
35 #include "ui/gfx/screen.h"
36 #include "ui/views/controls/label.h"
37 #include "ui/views/layout/fill_layout.h"
38 #include "ui/views/view.h"
39 #include "ui/views/widget/widget.h"
41 #if defined(OS_WIN)
42 #include "base/win/windows_version.h"
43 #endif
45 namespace ash {
46 namespace internal {
48 namespace {
50 void StepWidgetLayerAnimatorToEnd(views::Widget* widget) {
51 ui::AnimationContainerElement* element =
52 static_cast<ui::AnimationContainerElement*>(
53 widget->GetNativeView()->layer()->GetAnimator());
54 element->Step(base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1));
57 ShelfWidget* GetShelfWidget() {
58 return Shell::GetPrimaryRootWindowController()->shelf();
61 ShelfLayoutManager* GetShelfLayoutManager() {
62 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
65 SystemTray* GetSystemTray() {
66 return Shell::GetPrimaryRootWindowController()->GetSystemTray();
69 class ShelfDragCallback {
70 public:
71 ShelfDragCallback(const gfx::Rect& not_visible, const gfx::Rect& visible)
72 : not_visible_bounds_(not_visible),
73 visible_bounds_(visible),
74 was_visible_on_drag_start_(false) {
75 EXPECT_EQ(not_visible_bounds_.bottom(), visible_bounds_.bottom());
78 virtual ~ShelfDragCallback() {
81 void ProcessScroll(ui::EventType type, const gfx::Vector2dF& delta) {
82 if (GetShelfLayoutManager()->visibility_state() == ash::SHELF_HIDDEN)
83 return;
85 if (type == ui::ET_GESTURE_SCROLL_BEGIN) {
86 scroll_ = gfx::Vector2dF();
87 was_visible_on_drag_start_ = GetShelfLayoutManager()->IsVisible();
88 return;
91 // The state of the shelf at the end of the gesture is tested separately.
92 if (type == ui::ET_GESTURE_SCROLL_END)
93 return;
95 if (type == ui::ET_GESTURE_SCROLL_UPDATE)
96 scroll_.Add(delta);
98 gfx::Rect shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
99 EXPECT_EQ(not_visible_bounds_.bottom(), shelf_bounds.bottom());
100 EXPECT_EQ(visible_bounds_.bottom(), shelf_bounds.bottom());
102 // The shelf should never be smaller than the hidden state.
103 EXPECT_GE(shelf_bounds.height(), not_visible_bounds_.height());
105 if (was_visible_on_drag_start_) {
106 if (scroll_.y() < 0) {
107 // If dragging up from the visible state, then the shelf should increase
108 // in height, but not as much as the scroll delta.
109 EXPECT_LE(shelf_bounds.y(), visible_bounds_.y());
110 EXPECT_LE(abs(shelf_bounds.y() - visible_bounds_.y()),
111 abs(scroll_.y()));
112 } else {
113 if (shelf_bounds.height() > not_visible_bounds_.height()) {
114 // If dragging down from the visible state, then the shelf should
115 // decrease in height, until it reaches the minimum height.
116 EXPECT_EQ(shelf_bounds.y(), visible_bounds_.y() + (scroll_.y()));
119 } else {
120 if (fabs(scroll_.y()) < not_visible_bounds_.y() - visible_bounds_.y()) {
121 // Tests that the shelf sticks with the touch point during the drag
122 // until the shelf is completely visible.
123 EXPECT_EQ(shelf_bounds.y(), not_visible_bounds_.y() + scroll_.y());
124 } else {
125 // Tests that after the shelf is completely visible, the shelf starts
126 // resisting the drag.
127 EXPECT_GT(shelf_bounds.y(), not_visible_bounds_.y() + scroll_.y());
132 private:
133 const gfx::Rect not_visible_bounds_;
134 const gfx::Rect visible_bounds_;
135 gfx::Vector2dF scroll_;
136 bool was_visible_on_drag_start_;
138 DISALLOW_COPY_AND_ASSIGN(ShelfDragCallback);
141 class ShelfLayoutObserverTest : public ShelfLayoutManager::Observer {
142 public:
143 ShelfLayoutObserverTest()
144 : changed_auto_hide_state_(false) {
147 virtual ~ShelfLayoutObserverTest() {}
149 bool changed_auto_hide_state() const { return changed_auto_hide_state_; }
151 private:
152 virtual void OnAutoHideStateChanged(
153 ShelfAutoHideState new_state) OVERRIDE {
154 changed_auto_hide_state_ = true;
157 bool changed_auto_hide_state_;
159 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest);
162 // Trivial item implementation that tracks its views for testing.
163 class TestItem : public SystemTrayItem {
164 public:
165 TestItem()
166 : SystemTrayItem(GetSystemTray()),
167 tray_view_(NULL),
168 default_view_(NULL),
169 detailed_view_(NULL),
170 notification_view_(NULL) {}
172 virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE {
173 tray_view_ = new views::View;
174 // Add a label so it has non-zero width.
175 tray_view_->SetLayoutManager(new views::FillLayout);
176 tray_view_->AddChildView(new views::Label(UTF8ToUTF16("Tray")));
177 return tray_view_;
180 virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE {
181 default_view_ = new views::View;
182 default_view_->SetLayoutManager(new views::FillLayout);
183 default_view_->AddChildView(new views::Label(UTF8ToUTF16("Default")));
184 return default_view_;
187 virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE {
188 detailed_view_ = new views::View;
189 detailed_view_->SetLayoutManager(new views::FillLayout);
190 detailed_view_->AddChildView(new views::Label(UTF8ToUTF16("Detailed")));
191 return detailed_view_;
194 virtual views::View* CreateNotificationView(
195 user::LoginStatus status) OVERRIDE {
196 notification_view_ = new views::View;
197 return notification_view_;
200 virtual void DestroyTrayView() OVERRIDE {
201 tray_view_ = NULL;
204 virtual void DestroyDefaultView() OVERRIDE {
205 default_view_ = NULL;
208 virtual void DestroyDetailedView() OVERRIDE {
209 detailed_view_ = NULL;
212 virtual void DestroyNotificationView() OVERRIDE {
213 notification_view_ = NULL;
216 virtual void UpdateAfterLoginStatusChange(
217 user::LoginStatus status) OVERRIDE {}
219 views::View* tray_view() const { return tray_view_; }
220 views::View* default_view() const { return default_view_; }
221 views::View* detailed_view() const { return detailed_view_; }
222 views::View* notification_view() const { return notification_view_; }
224 private:
225 views::View* tray_view_;
226 views::View* default_view_;
227 views::View* detailed_view_;
228 views::View* notification_view_;
230 DISALLOW_COPY_AND_ASSIGN(TestItem);
233 } // namespace
235 class ShelfLayoutManagerTest : public ash::test::AshTestBase {
236 public:
237 ShelfLayoutManagerTest() {}
239 void SetState(ShelfLayoutManager* shelf,
240 ShelfVisibilityState state) {
241 shelf->SetState(state);
244 void UpdateAutoHideStateNow() {
245 GetShelfLayoutManager()->UpdateAutoHideStateNow();
248 aura::Window* CreateTestWindow() {
249 aura::Window* window = new aura::Window(NULL);
250 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
251 window->SetType(aura::client::WINDOW_TYPE_NORMAL);
252 window->Init(ui::LAYER_TEXTURED);
253 SetDefaultParentByPrimaryRootWindow(window);
254 return window;
257 views::Widget* CreateTestWidgetWithParams(
258 const views::Widget::InitParams& params) {
259 views::Widget* out = new views::Widget;
260 out->Init(params);
261 out->Show();
262 return out;
265 // Create a simple widget attached to the current context (will
266 // delete on TearDown).
267 views::Widget* CreateTestWidget() {
268 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
269 params.bounds = gfx::Rect(0, 0, 200, 200);
270 params.context = CurrentContext();
271 return CreateTestWidgetWithParams(params);
274 // Overridden from AshTestBase:
275 virtual void SetUp() OVERRIDE {
276 CommandLine::ForCurrentProcess()->AppendSwitch(
277 ash::switches::kAshEnableTrayDragging);
278 test::AshTestBase::SetUp();
280 private:
281 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest);
284 // Fails on Mac only. Need to be implemented. http://crbug.com/111279.
285 #if defined(OS_MACOSX) || defined(OS_WIN)
286 #define MAYBE_SetVisible DISABLED_SetVisible
287 #else
288 #define MAYBE_SetVisible SetVisible
289 #endif
290 // Makes sure SetVisible updates work area and widget appropriately.
291 TEST_F(ShelfLayoutManagerTest, MAYBE_SetVisible) {
292 ShelfWidget* shelf = GetShelfWidget();
293 ShelfLayoutManager* manager = shelf->shelf_layout_manager();
294 // Force an initial layout.
295 manager->LayoutShelf();
296 EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state());
298 gfx::Rect status_bounds(
299 shelf->status_area_widget()->GetWindowBoundsInScreen());
300 gfx::Rect launcher_bounds(
301 shelf->GetWindowBoundsInScreen());
302 int shelf_height = manager->GetIdealBounds().height();
304 const gfx::Display& display = Shell::GetInstance()->display_manager()->
305 GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
306 ASSERT_NE(-1, display.id());
307 // Bottom inset should be the max of widget heights.
308 EXPECT_EQ(shelf_height,
309 display.bounds().bottom() - display.work_area().bottom());
311 // Hide the shelf.
312 SetState(manager, SHELF_HIDDEN);
313 // Run the animation to completion.
314 StepWidgetLayerAnimatorToEnd(shelf);
315 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget());
316 EXPECT_EQ(SHELF_HIDDEN, manager->visibility_state());
317 EXPECT_EQ(0,
318 display.bounds().bottom() - display.work_area().bottom());
320 // Make sure the bounds of the two widgets changed.
321 EXPECT_GE(shelf->GetNativeView()->bounds().y(),
322 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
323 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(),
324 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
326 // And show it again.
327 SetState(manager, SHELF_VISIBLE);
328 // Run the animation to completion.
329 StepWidgetLayerAnimatorToEnd(shelf);
330 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget());
331 EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state());
332 EXPECT_EQ(shelf_height,
333 display.bounds().bottom() - display.work_area().bottom());
335 // Make sure the bounds of the two widgets changed.
336 launcher_bounds = shelf->GetNativeView()->bounds();
337 int bottom =
338 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom() - shelf_height;
339 EXPECT_EQ(launcher_bounds.y(),
340 bottom + (manager->GetIdealBounds().height() -
341 launcher_bounds.height()) / 2);
342 status_bounds = shelf->status_area_widget()->GetNativeView()->bounds();
343 EXPECT_EQ(status_bounds.y(),
344 bottom + shelf_height - status_bounds.height());
347 // Makes sure LayoutShelf invoked while animating cleans things up.
348 TEST_F(ShelfLayoutManagerTest, LayoutShelfWhileAnimating) {
349 ShelfWidget* shelf = GetShelfWidget();
350 // Force an initial layout.
351 shelf->shelf_layout_manager()->LayoutShelf();
352 EXPECT_EQ(SHELF_VISIBLE, shelf->shelf_layout_manager()->visibility_state());
354 const gfx::Display& display = Shell::GetInstance()->display_manager()->
355 GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
357 // Hide the shelf.
358 SetState(shelf->shelf_layout_manager(), SHELF_HIDDEN);
359 shelf->shelf_layout_manager()->LayoutShelf();
360 EXPECT_EQ(SHELF_HIDDEN, shelf->shelf_layout_manager()->visibility_state());
361 EXPECT_EQ(0, display.bounds().bottom() - display.work_area().bottom());
363 // Make sure the bounds of the two widgets changed.
364 EXPECT_GE(shelf->GetNativeView()->bounds().y(),
365 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
366 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(),
367 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
370 // Makes sure the launcher is sized when the status area changes size.
371 TEST_F(ShelfLayoutManagerTest, LauncherUpdatedWhenStatusAreaChangesSize) {
372 Launcher* launcher = Launcher::ForPrimaryDisplay();
373 ASSERT_TRUE(launcher);
374 ShelfWidget* shelf_widget = GetShelfWidget();
375 ASSERT_TRUE(shelf_widget);
376 ASSERT_TRUE(shelf_widget->status_area_widget());
377 shelf_widget->status_area_widget()->SetBounds(
378 gfx::Rect(0, 0, 200, 200));
379 EXPECT_EQ(200, shelf_widget->GetContentsView()->width() -
380 launcher->GetLauncherViewForTest()->width());
384 #if defined(OS_WIN)
385 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
386 #define MAYBE_AutoHide DISABLED_AutoHide
387 #else
388 #define MAYBE_AutoHide AutoHide
389 #endif
391 // Various assertions around auto-hide.
392 TEST_F(ShelfLayoutManagerTest, MAYBE_AutoHide) {
393 aura::RootWindow* root = Shell::GetPrimaryRootWindow();
394 aura::test::EventGenerator generator(root, root);
395 generator.MoveMouseTo(0, 0);
397 ShelfLayoutManager* shelf = GetShelfLayoutManager();
398 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
399 views::Widget* widget = new views::Widget;
400 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
401 params.bounds = gfx::Rect(0, 0, 200, 200);
402 params.context = CurrentContext();
403 // Widget is now owned by the parent window.
404 widget->Init(params);
405 widget->Maximize();
406 widget->Show();
407 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
408 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
410 // LayoutShelf() forces the animation to completion, at which point the
411 // launcher should go off the screen.
412 shelf->LayoutShelf();
413 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
414 GetShelfWidget()->GetWindowBoundsInScreen().y());
415 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
416 Shell::GetScreen()->GetDisplayNearestWindow(
417 root).work_area().bottom());
419 // Move the mouse to the bottom of the screen.
420 generator.MoveMouseTo(0, root->bounds().bottom() - 1);
422 // Shelf should be shown again (but it shouldn't have changed the work area).
423 SetState(shelf, SHELF_AUTO_HIDE);
424 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
425 shelf->LayoutShelf();
426 EXPECT_EQ(root->bounds().bottom() - shelf->GetIdealBounds().height(),
427 GetShelfWidget()->GetWindowBoundsInScreen().y());
428 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
429 Shell::GetScreen()->GetDisplayNearestWindow(
430 root).work_area().bottom());
432 // Move mouse back up.
433 generator.MoveMouseTo(0, 0);
434 SetState(shelf, SHELF_AUTO_HIDE);
435 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
436 shelf->LayoutShelf();
437 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
438 GetShelfWidget()->GetWindowBoundsInScreen().y());
440 // Drag mouse to bottom of screen.
441 generator.PressLeftButton();
442 generator.MoveMouseTo(0, root->bounds().bottom() - 1);
443 UpdateAutoHideStateNow();
444 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
446 generator.ReleaseLeftButton();
447 generator.MoveMouseTo(1, root->bounds().bottom() - 1);
448 UpdateAutoHideStateNow();
449 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
450 generator.PressLeftButton();
451 generator.MoveMouseTo(1, root->bounds().bottom() - 1);
452 UpdateAutoHideStateNow();
453 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
456 // Assertions around the lock screen showing.
457 TEST_F(ShelfLayoutManagerTest, VisibleWhenLockScreenShowing) {
458 // Since ShelfLayoutManager queries for mouse location, move the mouse so
459 // it isn't over the shelf.
460 aura::test::EventGenerator generator(
461 Shell::GetPrimaryRootWindow(), gfx::Point());
462 generator.MoveMouseTo(0, 0);
464 ShelfLayoutManager* shelf = GetShelfLayoutManager();
465 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
466 views::Widget* widget = new views::Widget;
467 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
468 params.bounds = gfx::Rect(0, 0, 200, 200);
469 params.context = CurrentContext();
470 // Widget is now owned by the parent window.
471 widget->Init(params);
472 widget->Maximize();
473 widget->Show();
474 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
475 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
477 aura::RootWindow* root = Shell::GetPrimaryRootWindow();
478 // LayoutShelf() forces the animation to completion, at which point the
479 // launcher should go off the screen.
480 shelf->LayoutShelf();
481 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
482 GetShelfWidget()->GetWindowBoundsInScreen().y());
484 aura::Window* lock_container = Shell::GetContainer(
485 Shell::GetPrimaryRootWindow(),
486 internal::kShellWindowId_LockScreenContainer);
488 views::Widget* lock_widget = new views::Widget;
489 views::Widget::InitParams lock_params(
490 views::Widget::InitParams::TYPE_WINDOW);
491 lock_params.bounds = gfx::Rect(0, 0, 200, 200);
492 params.context = CurrentContext();
493 lock_params.parent = lock_container;
494 // Widget is now owned by the parent window.
495 lock_widget->Init(lock_params);
496 lock_widget->Maximize();
497 lock_widget->Show();
499 // Lock the screen.
500 Shell::GetInstance()->delegate()->LockScreen();
501 shelf->UpdateVisibilityState();
502 // Showing a widget in the lock screen should force the shelf to be visibile.
503 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
505 Shell::GetInstance()->delegate()->UnlockScreen();
506 shelf->UpdateVisibilityState();
507 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
510 // Assertions around SetAutoHideBehavior.
511 TEST_F(ShelfLayoutManagerTest, SetAutoHideBehavior) {
512 // Since ShelfLayoutManager queries for mouse location, move the mouse so
513 // it isn't over the shelf.
514 aura::test::EventGenerator generator(
515 Shell::GetPrimaryRootWindow(), gfx::Point());
516 generator.MoveMouseTo(0, 0);
518 ShelfLayoutManager* shelf = GetShelfLayoutManager();
519 views::Widget* widget = new views::Widget;
520 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
521 params.bounds = gfx::Rect(0, 0, 200, 200);
522 params.context = CurrentContext();
523 // Widget is now owned by the parent window.
524 widget->Init(params);
525 widget->Show();
526 aura::Window* window = widget->GetNativeWindow();
527 gfx::Rect display_bounds(
528 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
530 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
531 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
533 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
534 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
536 widget->Maximize();
537 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
538 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
539 window).work_area().bottom(),
540 widget->GetWorkAreaBoundsInScreen().bottom());
542 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
543 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
544 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
545 window).work_area().bottom(),
546 widget->GetWorkAreaBoundsInScreen().bottom());
548 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
549 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
550 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
551 window).work_area().bottom(),
552 widget->GetWorkAreaBoundsInScreen().bottom());
555 // Basic assertions around the dimming of the shelf.
556 TEST_F(ShelfLayoutManagerTest, TestDimmingBehavior) {
557 // Since ShelfLayoutManager queries for mouse location, move the mouse so
558 // it isn't over the shelf.
559 aura::test::EventGenerator generator(
560 Shell::GetPrimaryRootWindow(), gfx::Point());
561 generator.MoveMouseTo(0, 0);
563 ShelfLayoutManager* shelf = GetShelfLayoutManager();
564 shelf->shelf_widget()->DisableDimmingAnimationsForTest();
566 views::Widget* widget = new views::Widget;
567 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
568 params.bounds = gfx::Rect(0, 0, 200, 200);
569 params.context = CurrentContext();
570 // Widget is now owned by the parent window.
571 widget->Init(params);
572 widget->Show();
573 aura::Window* window = widget->GetNativeWindow();
574 gfx::Rect display_bounds(
575 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
577 gfx::Point off_shelf = display_bounds.CenterPoint();
578 gfx::Point on_shelf =
579 shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
581 // Test there is no dimming object active at this point.
582 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
583 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
584 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
585 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
587 // After maximization, the shelf should be visible and the dimmer created.
588 widget->Maximize();
590 on_shelf = shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
591 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
593 // Moving the mouse off the shelf should dim the bar.
594 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
595 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
597 // Adding touch events outside the shelf should still keep the shelf in
598 // dimmed state.
599 generator.PressTouch();
600 generator.MoveTouch(off_shelf);
601 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
602 // Move the touch into the shelf area should undim.
603 generator.MoveTouch(on_shelf);
604 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
605 generator.ReleaseTouch();
606 // And a release dims again.
607 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
609 // Moving the mouse on the shelf should undim the bar.
610 generator.MoveMouseTo(on_shelf);
611 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
613 // No matter what the touch events do, the shelf should stay undimmed.
614 generator.PressTouch();
615 generator.MoveTouch(off_shelf);
616 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
617 generator.MoveTouch(on_shelf);
618 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
619 generator.MoveTouch(off_shelf);
620 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
621 generator.MoveTouch(on_shelf);
622 generator.ReleaseTouch();
624 // After restore, the dimming object should be deleted again.
625 widget->Restore();
626 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
629 // Assertions around the dimming of the shelf in conjunction with menus.
630 TEST_F(ShelfLayoutManagerTest, TestDimmingBehaviorWithMenus) {
631 // Since ShelfLayoutManager queries for mouse location, move the mouse so
632 // it isn't over the shelf.
633 aura::test::EventGenerator generator(
634 Shell::GetPrimaryRootWindow(), gfx::Point());
635 generator.MoveMouseTo(0, 0);
637 ShelfLayoutManager* shelf = GetShelfLayoutManager();
638 shelf->shelf_widget()->DisableDimmingAnimationsForTest();
640 views::Widget* widget = new views::Widget;
641 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
642 params.bounds = gfx::Rect(0, 0, 200, 200);
643 params.context = CurrentContext();
644 // Widget is now owned by the parent window.
645 widget->Init(params);
646 widget->Show();
647 aura::Window* window = widget->GetNativeWindow();
648 gfx::Rect display_bounds(
649 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
651 // After maximization, the shelf should be visible and the dimmer created.
652 widget->Maximize();
654 gfx::Point off_shelf = display_bounds.CenterPoint();
655 gfx::Point on_shelf =
656 shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
658 // Moving the mouse on the shelf should undim the bar.
659 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
660 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
662 // Simulate a menu opening.
663 shelf->shelf_widget()->ForceUndimming(true);
665 // Moving the mouse off the shelf should not dim the bar.
666 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
667 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
669 // No matter what the touch events do, the shelf should stay undimmed.
670 generator.PressTouch();
671 generator.MoveTouch(off_shelf);
672 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
673 generator.MoveTouch(on_shelf);
674 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
675 generator.MoveTouch(off_shelf);
676 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
677 generator.ReleaseTouch();
678 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
680 // "Closing the menu" should now turn off the menu since no event is inside
681 // the shelf any longer.
682 shelf->shelf_widget()->ForceUndimming(false);
683 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
685 // Moving the mouse again on the shelf which should undim the bar again.
686 // This time we check that the bar stays undimmed when the mouse remains on
687 // the bar and the "menu gets closed".
688 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
689 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
690 shelf->shelf_widget()->ForceUndimming(true);
691 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
692 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
693 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
694 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
695 shelf->shelf_widget()->ForceUndimming(true);
696 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
699 // Verifies the shelf is visible when status/launcher is focused.
700 TEST_F(ShelfLayoutManagerTest, VisibleWhenStatusOrLauncherFocused) {
701 // Since ShelfLayoutManager queries for mouse location, move the mouse so
702 // it isn't over the shelf.
703 aura::test::EventGenerator generator(
704 Shell::GetPrimaryRootWindow(), gfx::Point());
705 generator.MoveMouseTo(0, 0);
707 ShelfLayoutManager* shelf = GetShelfLayoutManager();
708 views::Widget* widget = new views::Widget;
709 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
710 params.bounds = gfx::Rect(0, 0, 200, 200);
711 params.context = CurrentContext();
712 // Widget is now owned by the parent window.
713 widget->Init(params);
714 widget->Show();
715 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
716 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
717 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
719 // Focus the launcher. Have to go through the focus cycler as normal focus
720 // requests to it do nothing.
721 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD);
722 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
724 widget->Activate();
725 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
727 // Trying to activate the status should fail, since we only allow activating
728 // it when the user is using the keyboard (i.e. through FocusCycler).
729 GetShelfWidget()->status_area_widget()->Activate();
730 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
732 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD);
733 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
736 // Makes sure shelf will be visible when app list opens as shelf is in
737 // SHELF_VISIBLE state,and toggling app list won't change shelf
738 // visibility state.
739 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) {
740 Shell* shell = Shell::GetInstance();
741 ShelfLayoutManager* shelf = GetShelfLayoutManager();
742 shelf->LayoutShelf();
743 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
745 // Create a normal unmaximized windowm shelf should be visible.
746 aura::Window* window = CreateTestWindow();
747 window->SetBounds(gfx::Rect(0, 0, 100, 100));
748 window->Show();
749 EXPECT_FALSE(shell->GetAppListTargetVisibility());
750 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
752 // Toggle app list to show, and the shelf stays visible.
753 shell->ToggleAppList(NULL);
754 EXPECT_TRUE(shell->GetAppListTargetVisibility());
755 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
757 // Toggle app list to hide, and the shelf stays visible.
758 shell->ToggleAppList(NULL);
759 EXPECT_FALSE(shell->GetAppListTargetVisibility());
760 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
763 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state
764 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and
765 // toggling app list won't change shelf visibility state.
766 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) {
767 Shell* shell = Shell::GetInstance();
768 ShelfLayoutManager* shelf = GetShelfLayoutManager();
769 shelf->LayoutShelf();
770 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
772 // Create a window and show it in maximized state.
773 aura::Window* window = CreateTestWindow();
774 window->SetBounds(gfx::Rect(0, 0, 100, 100));
775 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
776 window->Show();
777 wm::ActivateWindow(window);
779 EXPECT_FALSE(shell->GetAppListTargetVisibility());
780 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
782 // Toggle app list to show.
783 shell->ToggleAppList(NULL);
784 // The shelf's auto hide state won't be changed until the timer fires, so
785 // calling shell->UpdateShelfVisibility() is kind of manually helping it to
786 // update the state.
787 shell->UpdateShelfVisibility();
788 EXPECT_TRUE(shell->GetAppListTargetVisibility());
789 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
790 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
792 // Toggle app list to hide.
793 shell->ToggleAppList(NULL);
794 EXPECT_FALSE(shell->GetAppListTargetVisibility());
795 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
798 // Makes sure shelf will be hidden when app list opens as shelf is in HIDDEN
799 // state, and toggling app list won't change shelf visibility state.
800 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfHiddenState) {
801 Shell* shell = Shell::GetInstance();
802 ShelfLayoutManager* shelf = GetShelfLayoutManager();
803 // For shelf to be visible, app list is not open in initial state.
804 shelf->LayoutShelf();
806 // Create a window and make it full screen.
807 aura::Window* window = CreateTestWindow();
808 window->SetBounds(gfx::Rect(0, 0, 100, 100));
809 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
810 window->Show();
811 wm::ActivateWindow(window);
813 // App list and shelf is not shown.
814 EXPECT_FALSE(shell->GetAppListTargetVisibility());
815 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
817 // Toggle app list to show.
818 shell->ToggleAppList(NULL);
819 EXPECT_TRUE(shell->GetAppListTargetVisibility());
820 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
822 // Toggle app list to hide.
823 shell->ToggleAppList(NULL);
824 EXPECT_FALSE(shell->GetAppListTargetVisibility());
825 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
828 #if defined(OS_WIN)
829 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
830 #define MAYBE_SetAlignment DISABLED_SetAlignment
831 #else
832 #define MAYBE_SetAlignment SetAlignment
833 #endif
835 // Tests SHELF_ALIGNMENT_(LEFT, RIGHT, TOP).
836 TEST_F(ShelfLayoutManagerTest, MAYBE_SetAlignment) {
837 ShelfLayoutManager* shelf = GetShelfLayoutManager();
838 // Force an initial layout.
839 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
840 shelf->LayoutShelf();
841 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
843 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
844 gfx::Rect launcher_bounds(
845 GetShelfWidget()->GetWindowBoundsInScreen());
846 const internal::DisplayManager* manager =
847 Shell::GetInstance()->display_manager();
848 gfx::Display display =
849 manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
850 ASSERT_NE(-1, display.id());
851 EXPECT_EQ(shelf->GetIdealBounds().width(),
852 display.GetWorkAreaInsets().left());
853 EXPECT_GE(
854 launcher_bounds.width(),
855 GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
856 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, GetSystemTray()->shelf_alignment());
857 StatusAreaWidget* status_area_widget = GetShelfWidget()->status_area_widget();
858 gfx::Rect status_bounds(status_area_widget->GetWindowBoundsInScreen());
859 EXPECT_GE(status_bounds.width(),
860 status_area_widget->GetContentsView()->GetPreferredSize().width());
861 EXPECT_EQ(shelf->GetIdealBounds().width(),
862 display.GetWorkAreaInsets().left());
863 EXPECT_EQ(0, display.GetWorkAreaInsets().top());
864 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
865 EXPECT_EQ(0, display.GetWorkAreaInsets().right());
866 EXPECT_EQ(display.bounds().x(), launcher_bounds.x());
867 EXPECT_EQ(display.bounds().y(), launcher_bounds.y());
868 EXPECT_EQ(display.bounds().height(), launcher_bounds.height());
869 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
870 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
871 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
872 display.GetWorkAreaInsets().left());
873 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, display.work_area().x());
875 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
876 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
877 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
878 launcher_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
879 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
880 ASSERT_NE(-1, display.id());
881 EXPECT_EQ(shelf->GetIdealBounds().width(),
882 display.GetWorkAreaInsets().right());
883 EXPECT_GE(launcher_bounds.width(),
884 GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
885 EXPECT_EQ(SHELF_ALIGNMENT_RIGHT, GetSystemTray()->shelf_alignment());
886 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen());
887 EXPECT_GE(status_bounds.width(),
888 status_area_widget->GetContentsView()->GetPreferredSize().width());
889 EXPECT_EQ(shelf->GetIdealBounds().width(),
890 display.GetWorkAreaInsets().right());
891 EXPECT_EQ(0, display.GetWorkAreaInsets().top());
892 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
893 EXPECT_EQ(0, display.GetWorkAreaInsets().left());
894 EXPECT_EQ(display.work_area().right(), launcher_bounds.x());
895 EXPECT_EQ(display.bounds().y(), launcher_bounds.y());
896 EXPECT_EQ(display.bounds().height(), launcher_bounds.height());
897 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
898 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
899 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
900 display.GetWorkAreaInsets().right());
901 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
902 display.bounds().right() - display.work_area().right());
904 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
905 shelf->SetAlignment(SHELF_ALIGNMENT_TOP);
906 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
907 launcher_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
908 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
909 ASSERT_NE(-1, display.id());
910 EXPECT_EQ(shelf->GetIdealBounds().height(),
911 display.GetWorkAreaInsets().top());
912 EXPECT_GE(launcher_bounds.height(),
913 GetShelfWidget()->GetContentsView()->GetPreferredSize().height());
914 EXPECT_EQ(SHELF_ALIGNMENT_TOP, GetSystemTray()->shelf_alignment());
915 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen());
916 EXPECT_GE(status_bounds.height(),
917 status_area_widget->GetContentsView()->GetPreferredSize().height());
918 EXPECT_EQ(shelf->GetIdealBounds().height(),
919 display.GetWorkAreaInsets().top());
920 EXPECT_EQ(0, display.GetWorkAreaInsets().right());
921 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
922 EXPECT_EQ(0, display.GetWorkAreaInsets().left());
923 EXPECT_EQ(display.work_area().y(), launcher_bounds.bottom());
924 EXPECT_EQ(display.bounds().x(), launcher_bounds.x());
925 EXPECT_EQ(display.bounds().width(), launcher_bounds.width());
926 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
927 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
928 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
929 display.GetWorkAreaInsets().top());
930 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
931 display.work_area().y() - display.bounds().y());
934 #if defined(OS_WIN)
935 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
936 #define MAYBE_GestureDrag DISABLED_GestureDrag
937 #else
938 #define MAYBE_GestureDrag GestureDrag
939 #endif
941 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureDrag) {
942 ShelfLayoutManager* shelf = GetShelfLayoutManager();
943 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
944 shelf->LayoutShelf();
946 views::Widget* widget = new views::Widget;
947 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
948 params.bounds = gfx::Rect(0, 0, 200, 200);
949 params.context = CurrentContext();
950 widget->Init(params);
951 widget->Show();
952 widget->Maximize();
954 aura::Window* window = widget->GetNativeWindow();
956 gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen();
957 gfx::Rect bounds_shelf = window->bounds();
958 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
960 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
961 shelf->LayoutShelf();
962 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
964 gfx::Rect bounds_noshelf = window->bounds();
965 gfx::Rect shelf_hidden = GetShelfWidget()->GetWindowBoundsInScreen();
967 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
968 shelf->LayoutShelf();
970 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
971 const int kNumScrollSteps = 10;
972 ShelfDragCallback handler(shelf_hidden, shelf_shown);
974 // Swipe up on the shelf. This should not change any state.
975 gfx::Point start = GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
976 gfx::Point end(start.x(), start.y() + 100);
978 // Swipe down on the shelf to hide it.
979 end.set_y(start.y() + 100);
980 generator.GestureScrollSequenceWithCallback(start, end,
981 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
982 base::Bind(&ShelfDragCallback::ProcessScroll,
983 base::Unretained(&handler)));
984 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
985 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
986 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
987 EXPECT_NE(bounds_shelf.ToString(), window->bounds().ToString());
988 EXPECT_NE(shelf_shown.ToString(),
989 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
991 // Swipe up to show the shelf.
992 generator.GestureScrollSequenceWithCallback(end, start,
993 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
994 base::Bind(&ShelfDragCallback::ProcessScroll,
995 base::Unretained(&handler)));
996 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
997 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
998 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
999 EXPECT_EQ(shelf_shown.ToString(),
1000 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
1002 // Swipe up again. The shelf should hide.
1003 end.set_y(start.y() - 100);
1004 generator.GestureScrollSequenceWithCallback(start, end,
1005 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
1006 base::Bind(&ShelfDragCallback::ProcessScroll,
1007 base::Unretained(&handler)));
1008 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1009 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1010 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
1011 EXPECT_EQ(shelf_hidden.ToString(),
1012 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
1014 // Swipe up yet again to show it.
1015 end.set_y(start.y() + 100);
1016 generator.GestureScrollSequenceWithCallback(end, start,
1017 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
1018 base::Bind(&ShelfDragCallback::ProcessScroll,
1019 base::Unretained(&handler)));
1021 // Swipe down very little. It shouldn't change any state.
1022 end.set_y(start.y() + shelf_shown.height() * 3 / 10);
1023 generator.GestureScrollSequenceWithCallback(start, end,
1024 base::TimeDelta::FromMilliseconds(100), 1,
1025 base::Bind(&ShelfDragCallback::ProcessScroll,
1026 base::Unretained(&handler)));
1027 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1028 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
1029 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
1030 EXPECT_EQ(shelf_shown.ToString(),
1031 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
1033 // Swipe down again to hide.
1034 end.set_y(start.y() + 100);
1035 generator.GestureScrollSequenceWithCallback(start, end,
1036 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
1037 base::Bind(&ShelfDragCallback::ProcessScroll,
1038 base::Unretained(&handler)));
1039 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1040 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1041 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
1042 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
1043 EXPECT_EQ(shelf_hidden.ToString(),
1044 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
1046 // Make the window fullscreen.
1047 widget->SetFullscreen(true);
1048 gfx::Rect bounds_fullscreen = window->bounds();
1049 EXPECT_TRUE(widget->IsFullscreen());
1050 EXPECT_NE(bounds_noshelf.ToString(), bounds_fullscreen.ToString());
1051 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1053 // Swipe-up. This should not change anything.
1054 generator.GestureScrollSequenceWithCallback(end, start,
1055 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
1056 base::Bind(&ShelfDragCallback::ProcessScroll,
1057 base::Unretained(&handler)));
1058 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1059 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
1060 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
1063 TEST_F(ShelfLayoutManagerTest, WindowVisibilityDisablesAutoHide) {
1064 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1065 shelf->LayoutShelf();
1066 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1068 // Create a visible window so auto-hide behavior is enforced
1069 views::Widget* dummy = CreateTestWidget();
1071 // Window visible => auto hide behaves normally.
1072 shelf->UpdateVisibilityState();
1073 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1075 // Window minimized => auto hide disabled.
1076 dummy->Minimize();
1077 shelf->UpdateVisibilityState();
1078 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1080 // Window closed => auto hide disabled.
1081 dummy->CloseNow();
1082 shelf->UpdateVisibilityState();
1083 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1085 // Multiple window test
1086 views::Widget* window1 = CreateTestWidget();
1087 views::Widget* window2 = CreateTestWidget();
1089 // both visible => normal autohide
1090 shelf->UpdateVisibilityState();
1091 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1093 // either minimzed => normal autohide
1094 window2->Minimize();
1095 shelf->UpdateVisibilityState();
1096 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1097 window2->Restore();
1098 window1->Minimize();
1099 shelf->UpdateVisibilityState();
1100 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1102 // both minimzed => disable auto hide
1103 window2->Minimize();
1104 shelf->UpdateVisibilityState();
1105 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1108 #if defined(OS_WIN)
1109 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1110 #define MAYBE_GestureRevealsTrayBubble DISABLED_GestureRevealsTrayBubble
1111 #else
1112 #define MAYBE_GestureRevealsTrayBubble GestureRevealsTrayBubble
1113 #endif
1115 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureRevealsTrayBubble) {
1116 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1117 shelf->LayoutShelf();
1119 // Create a visible window so auto-hide behavior is enforced.
1120 CreateTestWidget();
1122 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1123 SystemTray* tray = GetSystemTray();
1125 // First, make sure the shelf is visible.
1126 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1127 EXPECT_FALSE(tray->HasSystemBubble());
1129 // Now, drag up on the tray to show the bubble.
1130 gfx::Point start = GetShelfWidget()->status_area_widget()->
1131 GetWindowBoundsInScreen().CenterPoint();
1132 gfx::Point end(start.x(), start.y() - 100);
1133 generator.GestureScrollSequence(start, end,
1134 base::TimeDelta::FromMilliseconds(10), 1);
1135 EXPECT_TRUE(tray->HasSystemBubble());
1136 tray->CloseSystemBubbleForTest();
1137 RunAllPendingInMessageLoop();
1138 EXPECT_FALSE(tray->HasSystemBubble());
1140 // Drag again, but only a small amount, and slowly. The bubble should not be
1141 // visible.
1142 end.set_y(start.y() - 30);
1143 generator.GestureScrollSequence(start, end,
1144 base::TimeDelta::FromMilliseconds(500), 100);
1145 EXPECT_FALSE(tray->HasSystemBubble());
1147 // Now, hide the shelf.
1148 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1150 // Start a drag from the bezel, and drag up to show both the shelf and the
1151 // tray bubble.
1152 start.set_y(start.y() + 100);
1153 end.set_y(start.y() - 400);
1154 generator.GestureScrollSequence(start, end,
1155 base::TimeDelta::FromMilliseconds(10), 1);
1156 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1157 EXPECT_TRUE(tray->HasSystemBubble());
1160 TEST_F(ShelfLayoutManagerTest, ShelfFlickerOnTrayActivation) {
1161 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1163 // Create a visible window so auto-hide behavior is enforced.
1164 CreateTestWidget();
1166 // Turn on auto-hide for the shelf.
1167 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1168 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1169 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1171 // Show the status menu. That should make the shelf visible again.
1172 Shell::GetInstance()->accelerator_controller()->PerformAction(
1173 SHOW_SYSTEM_TRAY_BUBBLE, ui::Accelerator());
1174 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1175 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1176 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
1178 // Now activate the tray (using the keyboard, instead of using the mouse to
1179 // make sure the mouse does not alter the auto-hide state in the shelf).
1180 // This should not trigger any auto-hide state change in the shelf.
1181 ShelfLayoutObserverTest observer;
1182 shelf->AddObserver(&observer);
1184 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1185 generator.PressKey(ui::VKEY_SPACE, 0);
1186 generator.ReleaseKey(ui::VKEY_SPACE, 0);
1187 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
1188 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1189 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1190 EXPECT_FALSE(observer.changed_auto_hide_state());
1192 shelf->RemoveObserver(&observer);
1195 TEST_F(ShelfLayoutManagerTest, WorkAreaChangeWorkspace) {
1196 // Make sure the shelf is always visible.
1197 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1198 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1199 shelf->LayoutShelf();
1201 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1202 params.bounds = gfx::Rect(0, 0, 200, 200);
1203 params.context = CurrentContext();
1204 views::Widget* widget_one = CreateTestWidgetWithParams(params);
1205 widget_one->Maximize();
1207 views::Widget* widget_two = CreateTestWidgetWithParams(params);
1208 widget_two->Maximize();
1209 widget_two->Activate();
1211 // Both windows are maximized. They should be of the same size.
1212 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
1213 widget_two->GetNativeWindow()->bounds().ToString());
1215 // Now hide the shelf.
1216 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1218 // The active maximized window will get resized to the new work area. However,
1219 // the inactive window should not get resized.
1220 EXPECT_NE(widget_one->GetNativeWindow()->bounds().ToString(),
1221 widget_two->GetNativeWindow()->bounds().ToString());
1223 // Activate the first window. Now, both windows should be of the same size
1224 // again.
1225 widget_one->Activate();
1226 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
1227 widget_two->GetNativeWindow()->bounds().ToString());
1229 // Now show the shelf.
1230 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1232 // The active maximized window will get resized to the new work area. However,
1233 // the inactive window should not get resized.
1234 EXPECT_NE(widget_one->GetNativeWindow()->bounds().ToString(),
1235 widget_two->GetNativeWindow()->bounds().ToString());
1237 // Activate the first window. Now, both windows should be of the same size
1238 // again.
1239 widget_two->Activate();
1240 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
1241 widget_two->GetNativeWindow()->bounds().ToString());
1244 // Confirm that the shelf is dimmed only when content is maximized and
1245 // shelf is not autohidden.
1246 TEST_F(ShelfLayoutManagerTest, Dimming) {
1247 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1248 scoped_ptr<aura::Window> w1(CreateTestWindow());
1249 w1->Show();
1250 wm::ActivateWindow(w1.get());
1252 // Normal window doesn't dim shelf.
1253 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
1254 ShelfWidget* shelf = GetShelfWidget();
1255 EXPECT_FALSE(shelf->GetDimsShelf());
1257 // Maximized window does.
1258 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1259 EXPECT_TRUE(shelf->GetDimsShelf());
1261 // Change back to normal stops dimming.
1262 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
1263 EXPECT_FALSE(shelf->GetDimsShelf());
1265 // Changing back to maximized dims again.
1266 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1267 EXPECT_TRUE(shelf->GetDimsShelf());
1269 // Changing shelf to autohide stops dimming.
1270 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1271 EXPECT_FALSE(shelf->GetDimsShelf());
1274 // Make sure that the shelf will not hide if the mouse is between a bubble and
1275 // the shelf.
1276 TEST_F(ShelfLayoutManagerTest, BubbleEnlargesShelfMouseHitArea) {
1277 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1278 StatusAreaWidget* status_area_widget =
1279 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
1280 SystemTray* tray = GetSystemTray();
1282 // Create a visible window so auto-hide behavior is enforced.
1283 CreateTestWidget();
1285 shelf->LayoutShelf();
1286 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1288 // Make two iterations - first without a message bubble which should make
1289 // the shelf disappear and then with a message bubble which should keep it
1290 // visible.
1291 for (int i = 0; i < 2; i++) {
1292 // Make sure the shelf is visible and position the mouse over it. Then
1293 // allow auto hide.
1294 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1295 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1296 gfx::Point center =
1297 status_area_widget->GetWindowBoundsInScreen().CenterPoint();
1298 generator.MoveMouseTo(center.x(), center.y());
1299 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1300 EXPECT_TRUE(shelf->IsVisible());
1301 if (!i) {
1302 // In our first iteration we make sure there is no bubble.
1303 tray->CloseSystemBubbleForTest();
1304 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1305 } else {
1306 // In our second iteration we show a bubble.
1307 TestItem *item = new TestItem;
1308 tray->AddTrayItem(item);
1309 tray->ShowNotificationView(item);
1310 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1312 // Move the pointer over the edge of the shelf.
1313 generator.MoveMouseTo(
1314 center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 8);
1315 shelf->UpdateVisibilityState();
1316 if (i) {
1317 EXPECT_TRUE(shelf->IsVisible());
1318 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1319 } else {
1320 EXPECT_FALSE(shelf->IsVisible());
1321 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1326 } // namespace internal
1327 } // namespace ash