Refactored not to expose raw pointers on ProxyList class.
[chromium-blink-merge.git] / ash / shelf / shelf_widget_unittest.cc
blobdcc7ee66375654931fd19e4575e60ea6371114f5
1 // Copyright (c) 2013 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_widget.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/shelf/shelf.h"
9 #include "ash/shelf/shelf_button.h"
10 #include "ash/shelf/shelf_layout_manager.h"
11 #include "ash/shelf/shelf_model.h"
12 #include "ash/shelf/shelf_view.h"
13 #include "ash/shell.h"
14 #include "ash/test/ash_test_base.h"
15 #include "ash/test/shelf_test_api.h"
16 #include "ash/test/shelf_view_test_api.h"
17 #include "ash/wm/window_util.h"
18 #include "ui/aura/window_event_dispatcher.h"
19 #include "ui/events/event_utils.h"
20 #include "ui/gfx/display.h"
21 #include "ui/gfx/screen.h"
22 #include "ui/views/view.h"
23 #include "ui/views/widget/widget.h"
25 namespace ash {
27 namespace {
29 ShelfWidget* GetShelfWidget() {
30 return Shelf::ForPrimaryDisplay()->shelf_widget();
33 ShelfLayoutManager* GetShelfLayoutManager() {
34 return GetShelfWidget()->shelf_layout_manager();
37 } // namespace
39 typedef test::AshTestBase ShelfWidgetTest;
41 void TestLauncherAlignment(aura::Window* root,
42 ShelfAlignment alignment,
43 const std::string& expected) {
44 Shell::GetInstance()->SetShelfAlignment(alignment, root);
45 gfx::Screen* screen = gfx::Screen::GetScreenFor(root);
46 EXPECT_EQ(expected,
47 screen->GetDisplayNearestWindow(root).work_area().ToString());
50 TEST_F(ShelfWidgetTest, TestAlignment) {
51 Shelf* shelf = Shelf::ForPrimaryDisplay();
52 UpdateDisplay("400x400");
53 ASSERT_TRUE(shelf);
55 SCOPED_TRACE("Single Bottom");
56 TestLauncherAlignment(Shell::GetPrimaryRootWindow(),
57 SHELF_ALIGNMENT_BOTTOM,
58 "0,0 400x353");
61 SCOPED_TRACE("Single Right");
62 TestLauncherAlignment(Shell::GetPrimaryRootWindow(),
63 SHELF_ALIGNMENT_RIGHT,
64 "0,0 353x400");
67 SCOPED_TRACE("Single Left");
68 TestLauncherAlignment(Shell::GetPrimaryRootWindow(),
69 SHELF_ALIGNMENT_LEFT,
70 "47,0 353x400");
72 if (!SupportsMultipleDisplays())
73 return;
75 UpdateDisplay("300x300,500x500");
76 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
78 SCOPED_TRACE("Primary Bottom");
79 TestLauncherAlignment(root_windows[0],
80 SHELF_ALIGNMENT_BOTTOM,
81 "0,0 300x253");
84 SCOPED_TRACE("Primary Right");
85 TestLauncherAlignment(root_windows[0],
86 SHELF_ALIGNMENT_RIGHT,
87 "0,0 253x300");
90 SCOPED_TRACE("Primary Left");
91 TestLauncherAlignment(root_windows[0],
92 SHELF_ALIGNMENT_LEFT,
93 "47,0 253x300");
96 SCOPED_TRACE("Secondary Bottom");
97 TestLauncherAlignment(root_windows[1],
98 SHELF_ALIGNMENT_BOTTOM,
99 "300,0 500x453");
102 SCOPED_TRACE("Secondary Right");
103 TestLauncherAlignment(root_windows[1],
104 SHELF_ALIGNMENT_RIGHT,
105 "300,0 453x500");
108 SCOPED_TRACE("Secondary Left");
109 TestLauncherAlignment(root_windows[1],
110 SHELF_ALIGNMENT_LEFT,
111 "347,0 453x500");
115 // Makes sure the shelf is initially sized correctly.
116 TEST_F(ShelfWidgetTest, LauncherInitiallySized) {
117 ShelfWidget* shelf_widget = GetShelfWidget();
118 Shelf* shelf = shelf_widget->shelf();
119 ASSERT_TRUE(shelf);
120 ShelfLayoutManager* shelf_layout_manager = GetShelfLayoutManager();
121 ASSERT_TRUE(shelf_layout_manager);
122 ASSERT_TRUE(shelf_widget->status_area_widget());
123 int status_width = shelf_widget->status_area_widget()->
124 GetWindowBoundsInScreen().width();
125 // Test only makes sense if the status is > 0, which it better be.
126 EXPECT_GT(status_width, 0);
127 EXPECT_EQ(status_width, shelf_widget->GetContentsView()->width() -
128 test::ShelfTestAPI(shelf).shelf_view()->width());
131 // Verifies when the shell is deleted with a full screen window we don't crash.
132 TEST_F(ShelfWidgetTest, DontReferenceShelfAfterDeletion) {
133 views::Widget* widget = new views::Widget;
134 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
135 params.bounds = gfx::Rect(0, 0, 200, 200);
136 params.context = CurrentContext();
137 // Widget is now owned by the parent window.
138 widget->Init(params);
139 widget->SetFullscreen(true);
142 #if defined(OS_CHROMEOS)
143 // Verifies shelf is created with correct size after user login and when its
144 // container and status widget has finished sizing.
145 // See http://crbug.com/252533
146 TEST_F(ShelfWidgetTest, ShelfInitiallySizedAfterLogin) {
147 SetUserLoggedIn(false);
148 UpdateDisplay("300x200,400x300");
150 ShelfWidget* shelf_widget = NULL;
151 Shell::RootWindowControllerList controllers(
152 Shell::GetAllRootWindowControllers());
153 for (Shell::RootWindowControllerList::const_iterator i = controllers.begin();
154 i != controllers.end();
155 ++i) {
156 if (!(*i)->shelf()->shelf()) {
157 shelf_widget = (*i)->shelf();
158 break;
161 ASSERT_TRUE(shelf_widget != NULL);
163 SetUserLoggedIn(true);
164 Shell::GetInstance()->CreateShelf();
166 Shelf* shelf = shelf_widget->shelf();
167 ASSERT_TRUE(shelf != NULL);
169 const int status_width =
170 shelf_widget->status_area_widget()->GetWindowBoundsInScreen().width();
171 EXPECT_GT(status_width, 0);
172 EXPECT_EQ(status_width,
173 shelf_widget->GetContentsView()->width() -
174 test::ShelfTestAPI(shelf).shelf_view()->width());
176 #endif // defined(OS_CHROMEOS)
178 // Tests that the shelf lets mouse-events close to the edge fall through to the
179 // window underneath.
180 TEST_F(ShelfWidgetTest, ShelfEdgeOverlappingWindowHitTestMouse) {
181 ShelfWidget* shelf_widget = GetShelfWidget();
182 gfx::Rect shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
183 EXPECT_TRUE(!shelf_bounds.IsEmpty());
184 ShelfLayoutManager* shelf_layout_manager =
185 shelf_widget->shelf_layout_manager();
186 ASSERT_TRUE(shelf_layout_manager);
187 EXPECT_EQ(SHELF_VISIBLE, shelf_layout_manager->visibility_state());
189 // Create a Widget which overlaps the shelf in both left and bottom
190 // alignments.
191 const int kOverlapSize = 15;
192 const int kWindowHeight = 200;
193 const int kWindowWidth = 200;
194 views::Widget* widget = new views::Widget;
195 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
196 params.bounds = gfx::Rect(shelf_bounds.height() - kOverlapSize,
197 shelf_bounds.y() - kWindowHeight + kOverlapSize,
198 kWindowWidth, kWindowHeight);
199 params.context = CurrentContext();
200 // Widget is now owned by the parent window.
201 widget->Init(params);
202 widget->Show();
203 gfx::Rect widget_bounds = widget->GetWindowBoundsInScreen();
204 EXPECT_TRUE(widget_bounds.Intersects(shelf_bounds));
206 ui::EventTarget* root = widget->GetNativeWindow()->GetRootWindow();
207 ui::EventTargeter* targeter = root->GetEventTargeter();
209 // Create a mouse-event targeting the top of the shelf widget. The
210 // window-targeter should find |widget| as the target (instead of the
211 // shelf).
212 gfx::Point event_location(widget_bounds.x() + 5, shelf_bounds.y() + 1);
213 ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
214 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
215 ui::EventTarget* target = targeter->FindTargetForEvent(root, &mouse);
216 EXPECT_EQ(widget->GetNativeWindow(), target);
219 // Change shelf alignment to verify that the targeter insets are updated.
220 shelf_layout_manager->SetAlignment(SHELF_ALIGNMENT_LEFT);
221 shelf_layout_manager->LayoutShelf();
222 shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
224 // Create a mouse-event targeting the right edge of the shelf widget. The
225 // window-targeter should find |widget| as the target (instead of the
226 // shelf).
227 gfx::Point event_location(shelf_bounds.right() - 1, widget_bounds.y() + 5);
228 ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
229 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
230 ui::EventTarget* target = targeter->FindTargetForEvent(root, &mouse);
231 EXPECT_EQ(widget->GetNativeWindow(), target);
234 // Now restore shelf alignment (bottom) and auto-hide (hidden) the shelf.
235 shelf_layout_manager->SetAlignment(SHELF_ALIGNMENT_BOTTOM);
236 shelf_layout_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
237 shelf_layout_manager->LayoutShelf();
238 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_layout_manager->visibility_state());
239 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_layout_manager->auto_hide_state());
240 shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
241 EXPECT_TRUE(!shelf_bounds.IsEmpty());
243 // Move |widget| so it still overlaps the shelf.
244 widget->SetBounds(gfx::Rect(0,
245 shelf_bounds.y() - kWindowHeight + kOverlapSize,
246 kWindowWidth, kWindowHeight));
247 widget_bounds = widget->GetWindowBoundsInScreen();
248 EXPECT_TRUE(widget_bounds.Intersects(shelf_bounds));
250 // Create a mouse-event targeting the top of the shelf widget. This time,
251 // window-target should find the shelf as the target.
252 gfx::Point event_location(widget_bounds.x() + 5, shelf_bounds.y() + 1);
253 ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
254 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
255 ui::EventTarget* target = targeter->FindTargetForEvent(root, &mouse);
256 EXPECT_EQ(shelf_widget->GetNativeWindow(), target);
260 // Tests that the shelf has a slightly larger hit-region for touch-events when
261 // it's in the auto-hidden state.
262 TEST_F(ShelfWidgetTest, HiddenShelfHitTestTouch) {
263 ShelfWidget* shelf_widget = GetShelfWidget();
264 gfx::Rect shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
265 EXPECT_TRUE(!shelf_bounds.IsEmpty());
266 ShelfLayoutManager* shelf_layout_manager =
267 shelf_widget->shelf_layout_manager();
268 ASSERT_TRUE(shelf_layout_manager);
269 EXPECT_EQ(SHELF_VISIBLE, shelf_layout_manager->visibility_state());
271 // Create a widget to make sure that the shelf does auto-hide.
272 views::Widget* widget = new views::Widget;
273 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
274 params.bounds = gfx::Rect(0, 0, 200, 200);
275 params.context = CurrentContext();
276 // Widget is now owned by the parent window.
277 widget->Init(params);
278 widget->Show();
280 ui::EventTarget* root = shelf_widget->GetNativeWindow()->GetRootWindow();
281 ui::EventTargeter* targeter = root->GetEventTargeter();
282 // Touch just over the shelf. Since the shelf is visible, the window-targeter
283 // should not find the shelf as the target.
285 gfx::Point event_location(20, shelf_bounds.y() - 1);
286 ui::TouchEvent touch(ui::ET_TOUCH_PRESSED, event_location, 0,
287 ui::EventTimeForNow());
288 EXPECT_NE(shelf_widget->GetNativeWindow(),
289 targeter->FindTargetForEvent(root, &touch));
292 // Now auto-hide (hidden) the shelf.
293 shelf_layout_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
294 shelf_layout_manager->LayoutShelf();
295 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_layout_manager->visibility_state());
296 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_layout_manager->auto_hide_state());
297 shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
298 EXPECT_TRUE(!shelf_bounds.IsEmpty());
300 // Touch just over the shelf again. This time, the targeter should find the
301 // shelf as the target.
303 gfx::Point event_location(20, shelf_bounds.y() - 1);
304 ui::TouchEvent touch(ui::ET_TOUCH_PRESSED, event_location, 0,
305 ui::EventTimeForNow());
306 EXPECT_EQ(shelf_widget->GetNativeWindow(),
307 targeter->FindTargetForEvent(root, &touch));
311 } // namespace ash