1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/accessibility/accessibility_panel_layout_manager.h"
6
7 #include <memory>
8
9 #include "ash/public/cpp/shelf_config.h"
10 #include "ash/shell.h"
11 #include "ash/test/ash_test_base.h"
12 #include "ui/display/display.h"
13 #include "ui/display/screen.h"
14 #include "ui/views/widget/widget.h"
15
16 namespace ash {
17 namespace {
18
19 // Shorten the name for better line wrapping.
20 constexpr int kDefaultPanelHeight =
21 AccessibilityPanelLayoutManager::kDefaultPanelHeight;
22
GetLayoutManager()23 AccessibilityPanelLayoutManager* GetLayoutManager() {
24 aura::Window* container =
25 Shell::GetContainer(Shell::GetPrimaryRootWindow(),
26 kShellWindowId_AccessibilityPanelContainer);
27 return static_cast<AccessibilityPanelLayoutManager*>(
28 container->layout_manager());
29 }
30
31 // Simulates Chrome creating the ChromeVoxPanel widget.
CreateChromeVoxPanel()32 std::unique_ptr<views::Widget> CreateChromeVoxPanel() {
33 std::unique_ptr<views::Widget> widget = std::make_unique<views::Widget>();
34 views::Widget::InitParams params(
35 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
36 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
37 aura::Window* root_window = Shell::GetPrimaryRootWindow();
38 params.parent = Shell::GetContainer(
39 root_window, kShellWindowId_AccessibilityPanelContainer);
40 params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
41 params.bounds = gfx::Rect(0, 0, root_window->bounds().width(),
42 root_window->bounds().height());
43 widget->Init(std::move(params));
44 return widget;
45 }
46
47 using AccessibilityPanelLayoutManagerTest = AshTestBase;
48
TEST_F(AccessibilityPanelLayoutManagerTest,Basics)49 TEST_F(AccessibilityPanelLayoutManagerTest, Basics) {
50 AccessibilityPanelLayoutManager* layout_manager = GetLayoutManager();
51 ASSERT_TRUE(layout_manager);
52
53 // The layout manager doesn't track anything at startup.
54 EXPECT_FALSE(layout_manager->panel_window_for_test());
55
56 // Simulate chrome creating the ChromeVox widget. The layout manager starts
57 // managing it.
58 std::unique_ptr<views::Widget> widget = CreateChromeVoxPanel();
59 widget->Show();
60 EXPECT_EQ(widget->GetNativeWindow(), layout_manager->panel_window_for_test());
61
62 // The layout manager doesn't track anything after the widget closes.
63 widget.reset();
64 EXPECT_FALSE(layout_manager->panel_window_for_test());
65 }
66
TEST_F(AccessibilityPanelLayoutManagerTest,Shutdown)67 TEST_F(AccessibilityPanelLayoutManagerTest, Shutdown) {
68 // Simulate chrome creating the ChromeVox widget.
69 std::unique_ptr<views::Widget> widget = CreateChromeVoxPanel();
70 widget->Show();
71
72 // Don't close the window.
73 widget.release();
74
75 // Ash should not crash if the window is still open at shutdown.
76 }
77
TEST_F(AccessibilityPanelLayoutManagerTest,PanelFullscreen)78 TEST_F(AccessibilityPanelLayoutManagerTest, PanelFullscreen) {
79 AccessibilityPanelLayoutManager* layout_manager = GetLayoutManager();
80 display::Screen* screen = display::Screen::GetScreen();
81
82 std::unique_ptr<views::Widget> widget = CreateChromeVoxPanel();
83 widget->Show();
84
85 layout_manager->SetPanelBounds(gfx::Rect(0, 0, 0, kDefaultPanelHeight),
86 AccessibilityPanelState::FULL_WIDTH);
87
88 gfx::Rect expected_work_area = screen->GetPrimaryDisplay().work_area();
89
90 // When the panel is fullscreen it fills the display and clears the
91 // work area.
92 layout_manager->SetPanelBounds(gfx::Rect(),
93 AccessibilityPanelState::FULLSCREEN);
94 EXPECT_EQ(widget->GetNativeWindow()->bounds(),
95 screen->GetPrimaryDisplay().bounds());
96 EXPECT_EQ(screen->GetPrimaryDisplay().work_area().y(), 0);
97
98 // Restoring the panel to default size restores the bounds and sets
99 // the work area.
100 layout_manager->SetPanelBounds(gfx::Rect(0, 0, 0, kDefaultPanelHeight),
101 AccessibilityPanelState::FULL_WIDTH);
102 gfx::Rect expected_bounds(0, 0, screen->GetPrimaryDisplay().bounds().width(),
103 kDefaultPanelHeight);
104 EXPECT_EQ(widget->GetNativeWindow()->bounds(), expected_bounds);
105 EXPECT_EQ(screen->GetPrimaryDisplay().work_area(), expected_work_area);
106 }
107
TEST_F(AccessibilityPanelLayoutManagerTest,SetBounds)108 TEST_F(AccessibilityPanelLayoutManagerTest, SetBounds) {
109 std::unique_ptr<views::Widget> widget = CreateChromeVoxPanel();
110 widget->Show();
111
112 gfx::Rect bounds(0, 0, 100, 100);
113 GetLayoutManager()->SetPanelBounds(bounds, AccessibilityPanelState::BOUNDED);
114 EXPECT_EQ(widget->GetNativeWindow()->bounds(), bounds);
115 }
116
TEST_F(AccessibilityPanelLayoutManagerTest,DisplayBoundsChange)117 TEST_F(AccessibilityPanelLayoutManagerTest, DisplayBoundsChange) {
118 std::unique_ptr<views::Widget> widget = CreateChromeVoxPanel();
119 widget->Show();
120 GetLayoutManager()->SetPanelBounds(gfx::Rect(0, 0, 0, kDefaultPanelHeight),
121 AccessibilityPanelState::FULL_WIDTH);
122
123 // When the display resolution changes the panel still sits at the top of the
124 // screen.
125 UpdateDisplay("1234,567");
126 display::Screen* screen = display::Screen::GetScreen();
127 gfx::Rect expected_bounds(0, 0, screen->GetPrimaryDisplay().bounds().width(),
128 kDefaultPanelHeight);
129 EXPECT_EQ(widget->GetNativeWindow()->bounds(), expected_bounds);
130
131 gfx::Rect expected_work_area = screen->GetPrimaryDisplay().bounds();
132 expected_work_area.Inset(0, kDefaultPanelHeight, 0,
133 ShelfConfig::Get()->shelf_size());
134 EXPECT_EQ(screen->GetPrimaryDisplay().work_area(), expected_work_area);
135 }
136
137 } // namespace
138 } // namespace ash
139