Add a new ContentRendererClient::HandleNavigation callback in RenderViewImpl::decideP...
[chromium-blink-merge.git] / ash / shell_unittest.cc
blobb762abb5f636a62d17983de10e266107099a3472
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/shell.h"
7 #include <algorithm>
8 #include <vector>
10 #include "ash/ash_switches.h"
11 #include "ash/desktop_background/desktop_background_widget_controller.h"
12 #include "ash/launcher/launcher.h"
13 #include "ash/root_window_controller.h"
14 #include "ash/shell_delegate.h"
15 #include "ash/shell_window_ids.h"
16 #include "ash/test/ash_test_base.h"
17 #include "ash/wm/root_window_layout_manager.h"
18 #include "ash/wm/shelf_layout_manager.h"
19 #include "ash/wm/window_util.h"
20 #include "base/utf_string_conversions.h"
21 #include "ui/aura/client/aura_constants.h"
22 #include "ui/aura/root_window.h"
23 #include "ui/aura/window.h"
24 #include "ui/gfx/size.h"
25 #include "ui/views/widget/widget.h"
26 #include "ui/views/widget/widget_delegate.h"
28 using aura::RootWindow;
30 namespace ash {
32 namespace {
34 views::Widget* CreateTestWindow(const views::Widget::InitParams& params) {
35 views::Widget* widget = new views::Widget;
36 widget->Init(params);
37 return widget;
40 aura::Window* GetDefaultContainer() {
41 return Shell::GetContainer(
42 Shell::GetPrimaryRootWindow(),
43 internal::kShellWindowId_DefaultContainer);
46 aura::Window* GetAlwaysOnTopContainer() {
47 return Shell::GetContainer(
48 Shell::GetPrimaryRootWindow(),
49 internal::kShellWindowId_AlwaysOnTopContainer);
52 // Expect ALL the containers!
53 void ExpectAllContainers() {
54 aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
55 EXPECT_TRUE(Shell::GetContainer(
56 root_window, internal::kShellWindowId_DesktopBackgroundContainer));
57 EXPECT_TRUE(Shell::GetContainer(
58 root_window, internal::kShellWindowId_DefaultContainer));
59 EXPECT_TRUE(Shell::GetContainer(
60 root_window, internal::kShellWindowId_AlwaysOnTopContainer));
61 EXPECT_TRUE(Shell::GetContainer(
62 root_window, internal::kShellWindowId_PanelContainer));
63 EXPECT_TRUE(Shell::GetContainer(
64 root_window, internal::kShellWindowId_LauncherContainer));
65 EXPECT_TRUE(Shell::GetContainer(
66 root_window, internal::kShellWindowId_SystemModalContainer));
67 EXPECT_TRUE(Shell::GetContainer(
68 root_window, internal::kShellWindowId_LockScreenBackgroundContainer));
69 EXPECT_TRUE(Shell::GetContainer(
70 root_window, internal::kShellWindowId_LockScreenContainer));
71 EXPECT_TRUE(Shell::GetContainer(
72 root_window, internal::kShellWindowId_LockSystemModalContainer));
73 EXPECT_TRUE(Shell::GetContainer(
74 root_window, internal::kShellWindowId_StatusContainer));
75 EXPECT_TRUE(Shell::GetContainer(
76 root_window, internal::kShellWindowId_MenuContainer));
77 EXPECT_TRUE(Shell::GetContainer(
78 root_window, internal::kShellWindowId_DragImageAndTooltipContainer));
79 EXPECT_TRUE(Shell::GetContainer(
80 root_window, internal::kShellWindowId_SettingBubbleContainer));
81 EXPECT_TRUE(Shell::GetContainer(
82 root_window, internal::kShellWindowId_OverlayContainer));
85 void TestCreateWindow(views::Widget::InitParams::Type type,
86 bool always_on_top,
87 aura::Window* expected_container) {
88 views::Widget::InitParams widget_params(type);
89 widget_params.keep_on_top = always_on_top;
91 views::Widget* widget = CreateTestWindow(widget_params);
92 widget->Show();
94 EXPECT_TRUE(expected_container->Contains(
95 widget->GetNativeWindow()->parent())) <<
96 "TestCreateWindow: type=" << type << ", always_on_top=" << always_on_top;
98 widget->Close();
101 class ModalWindow : public views::WidgetDelegateView {
102 public:
103 ModalWindow() {}
104 virtual ~ModalWindow() {}
106 // Overridden from views::WidgetDelegate:
107 virtual views::View* GetContentsView() OVERRIDE {
108 return this;
110 virtual bool CanResize() const OVERRIDE {
111 return true;
113 virtual string16 GetWindowTitle() const OVERRIDE {
114 return ASCIIToUTF16("Modal Window");
116 virtual ui::ModalType GetModalType() const OVERRIDE {
117 return ui::MODAL_TYPE_SYSTEM;
120 private:
121 DISALLOW_COPY_AND_ASSIGN(ModalWindow);
124 } // namespace
126 typedef test::AshTestBase ShellTest;
128 TEST_F(ShellTest, CreateWindow) {
129 // Normal window should be created in default container.
130 TestCreateWindow(views::Widget::InitParams::TYPE_WINDOW,
131 false, // always_on_top
132 GetDefaultContainer());
133 TestCreateWindow(views::Widget::InitParams::TYPE_POPUP,
134 false, // always_on_top
135 GetDefaultContainer());
137 // Always-on-top window and popup are created in always-on-top container.
138 TestCreateWindow(views::Widget::InitParams::TYPE_WINDOW,
139 true, // always_on_top
140 GetAlwaysOnTopContainer());
141 TestCreateWindow(views::Widget::InitParams::TYPE_POPUP,
142 true, // always_on_top
143 GetAlwaysOnTopContainer());
146 TEST_F(ShellTest, ChangeAlwaysOnTop) {
147 views::Widget::InitParams widget_params(
148 views::Widget::InitParams::TYPE_WINDOW);
150 // Creates a normal window
151 views::Widget* widget = CreateTestWindow(widget_params);
152 widget->Show();
154 // It should be in default container.
155 EXPECT_TRUE(GetDefaultContainer()->Contains(
156 widget->GetNativeWindow()->parent()));
158 // Flip always-on-top flag.
159 widget->SetAlwaysOnTop(true);
160 // And it should in always on top container now.
161 EXPECT_EQ(GetAlwaysOnTopContainer(), widget->GetNativeWindow()->parent());
163 // Flip always-on-top flag.
164 widget->SetAlwaysOnTop(false);
165 // It should go back to default container.
166 EXPECT_TRUE(GetDefaultContainer()->Contains(
167 widget->GetNativeWindow()->parent()));
169 // Set the same always-on-top flag again.
170 widget->SetAlwaysOnTop(false);
171 // Should have no effect and we are still in the default container.
172 EXPECT_TRUE(GetDefaultContainer()->Contains(
173 widget->GetNativeWindow()->parent()));
175 widget->Close();
178 TEST_F(ShellTest, CreateModalWindow) {
179 views::Widget::InitParams widget_params(
180 views::Widget::InitParams::TYPE_WINDOW);
182 // Create a normal window.
183 views::Widget* widget = CreateTestWindow(widget_params);
184 widget->Show();
186 // It should be in default container.
187 EXPECT_TRUE(GetDefaultContainer()->Contains(
188 widget->GetNativeWindow()->parent()));
190 // Create a modal window.
191 views::Widget* modal_widget = views::Widget::CreateWindowWithParent(
192 new ModalWindow(), widget->GetNativeView());
193 modal_widget->Show();
195 // It should be in modal container.
196 aura::Window* modal_container = Shell::GetContainer(
197 Shell::GetPrimaryRootWindow(),
198 internal::kShellWindowId_SystemModalContainer);
199 EXPECT_EQ(modal_container, modal_widget->GetNativeWindow()->parent());
201 modal_widget->Close();
202 widget->Close();
205 TEST_F(ShellTest, CreateLockScreenModalWindow) {
206 views::Widget::InitParams widget_params(
207 views::Widget::InitParams::TYPE_WINDOW);
209 // Create a normal window.
210 views::Widget* widget = CreateTestWindow(widget_params);
211 widget->Show();
213 // It should be in default container.
214 EXPECT_TRUE(GetDefaultContainer()->Contains(
215 widget->GetNativeWindow()->parent()));
217 Shell::GetInstance()->delegate()->LockScreen();
218 // Create a LockScreen window.
219 views::Widget* lock_widget = CreateTestWindow(widget_params);
220 ash::Shell::GetContainer(
221 Shell::GetPrimaryRootWindow(),
222 ash::internal::kShellWindowId_LockScreenContainer)->
223 AddChild(lock_widget->GetNativeView());
224 lock_widget->Show();
226 // It should be in LockScreen container.
227 aura::Window* lock_screen = Shell::GetContainer(
228 Shell::GetPrimaryRootWindow(),
229 ash::internal::kShellWindowId_LockScreenContainer);
230 EXPECT_EQ(lock_screen, lock_widget->GetNativeWindow()->parent());
232 // Create a modal window with a lock window as parent.
233 views::Widget* lock_modal_widget = views::Widget::CreateWindowWithParent(
234 new ModalWindow(), lock_widget->GetNativeView());
235 lock_modal_widget->Show();
237 // It should be in LockScreen modal container.
238 aura::Window* lock_modal_container = Shell::GetContainer(
239 Shell::GetPrimaryRootWindow(),
240 ash::internal::kShellWindowId_LockSystemModalContainer);
241 EXPECT_EQ(lock_modal_container,
242 lock_modal_widget->GetNativeWindow()->parent());
244 // Create a modal window with a normal window as parent.
245 views::Widget* modal_widget = views::Widget::CreateWindowWithParent(
246 new ModalWindow(), widget->GetNativeView());
247 modal_widget->Show();
249 // It should be in non-LockScreen modal container.
250 aura::Window* modal_container = Shell::GetContainer(
251 Shell::GetPrimaryRootWindow(),
252 ash::internal::kShellWindowId_SystemModalContainer);
253 EXPECT_EQ(modal_container, modal_widget->GetNativeWindow()->parent());
255 modal_widget->Close();
256 lock_modal_widget->Close();
257 lock_widget->Close();
258 widget->Close();
261 TEST_F(ShellTest, IsScreenLocked) {
262 ash::Shell::GetInstance()->delegate()->LockScreen();
263 EXPECT_TRUE(Shell::GetInstance()->IsScreenLocked());
264 ash::Shell::GetInstance()->delegate()->UnlockScreen();
265 EXPECT_FALSE(Shell::GetInstance()->IsScreenLocked());
268 // Fails on Mac, see http://crbug.com/115662
269 #if defined(OS_MACOSX)
270 #define MAYBE_ManagedWindowModeBasics DISABLED_ManagedWindowModeBasics
271 #else
272 #define MAYBE_ManagedWindowModeBasics ManagedWindowModeBasics
273 #endif
274 TEST_F(ShellTest, MAYBE_ManagedWindowModeBasics) {
275 Shell* shell = Shell::GetInstance();
276 Shell::TestApi test_api(shell);
278 // We start with the usual window containers.
279 ExpectAllContainers();
280 // Launcher is visible.
281 views::Widget* launcher_widget = Launcher::ForPrimaryDisplay()->widget();
282 EXPECT_TRUE(launcher_widget->IsVisible());
283 // Launcher is at bottom-left of screen.
284 EXPECT_EQ(0, launcher_widget->GetWindowBoundsInScreen().x());
285 EXPECT_EQ(Shell::GetPrimaryRootWindow()->GetHostSize().height(),
286 launcher_widget->GetWindowBoundsInScreen().bottom());
287 // We have a desktop background but not a bare layer.
288 // TODO (antrim): enable once we find out why it fails component build.
289 // internal::DesktopBackgroundWidgetController* background =
290 // Shell::GetPrimaryRootWindow()->
291 // GetProperty(internal::kWindowDesktopComponent);
292 // EXPECT_TRUE(background);
293 // EXPECT_TRUE(background->widget());
294 // EXPECT_FALSE(background->layer());
296 // Create a normal window. It is not maximized.
297 views::Widget::InitParams widget_params(
298 views::Widget::InitParams::TYPE_WINDOW);
299 widget_params.bounds.SetRect(11, 22, 300, 400);
300 views::Widget* widget = CreateTestWindow(widget_params);
301 widget->Show();
302 EXPECT_FALSE(widget->IsMaximized());
304 // Clean up.
305 widget->Close();
308 TEST_F(ShellTest, FullscreenWindowHidesShelf) {
309 ExpectAllContainers();
311 // Create a normal window. It is not maximized.
312 views::Widget::InitParams widget_params(
313 views::Widget::InitParams::TYPE_WINDOW);
314 widget_params.bounds.SetRect(11, 22, 300, 400);
315 views::Widget* widget = CreateTestWindow(widget_params);
316 widget->Show();
317 EXPECT_FALSE(widget->IsMaximized());
319 // Shelf defaults to visible.
320 EXPECT_EQ(
321 internal::ShelfLayoutManager::VISIBLE,
322 Shell::GetPrimaryRootWindowController()->shelf()->visibility_state());
324 // Fullscreen window hides it.
325 widget->SetFullscreen(true);
326 EXPECT_EQ(
327 internal::ShelfLayoutManager::HIDDEN,
328 Shell::GetPrimaryRootWindowController()->shelf()->visibility_state());
330 // Restoring the window restores it.
331 widget->Restore();
332 EXPECT_EQ(
333 internal::ShelfLayoutManager::VISIBLE,
334 Shell::GetPrimaryRootWindowController()->shelf()->visibility_state());
336 // Clean up.
337 widget->Close();
340 namespace {
342 // Builds the list of parents from |window| to the root. The returned vector is
343 // in reverse order (|window| is first).
344 std::vector<aura::Window*> BuildPathToRoot(aura::Window* window) {
345 std::vector<aura::Window*> results;
346 while (window) {
347 results.push_back(window);
348 window = window->parent();
350 return results;
353 } // namespace
355 // Various assertions around IsAutoHideMenuHideChecked() and
356 // ToggleAutoHideMenu().
357 TEST_F(ShellTest, ToggleAutoHide) {
358 scoped_ptr<aura::Window> window(new aura::Window(NULL));
359 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
360 window->SetType(aura::client::WINDOW_TYPE_NORMAL);
361 window->Init(ui::LAYER_TEXTURED);
362 window->SetParent(NULL);
363 window->Show();
364 wm::ActivateWindow(window.get());
366 internal::RootWindowController* controller =
367 Shell::GetPrimaryRootWindowController();
368 controller->SetShelfAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
369 EXPECT_EQ(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS,
370 controller->GetShelfAutoHideBehavior());
371 EXPECT_TRUE(controller->IsShelfAutoHideMenuHideChecked());
372 controller->SetShelfAutoHideBehavior(
373 controller->GetToggledShelfAutoHideBehavior());
374 EXPECT_EQ(ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER,
375 controller->GetShelfAutoHideBehavior());
377 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
378 EXPECT_FALSE(controller->IsShelfAutoHideMenuHideChecked());
379 controller->SetShelfAutoHideBehavior(
380 controller->GetToggledShelfAutoHideBehavior());
381 EXPECT_EQ(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS,
382 controller->GetShelfAutoHideBehavior());
383 EXPECT_TRUE(controller->IsShelfAutoHideMenuHideChecked());
384 controller->SetShelfAutoHideBehavior(
385 controller->GetToggledShelfAutoHideBehavior());
386 EXPECT_EQ(ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER,
387 controller->GetShelfAutoHideBehavior());
390 // This verifies WindowObservers are removed when a window is destroyed after
391 // the Shell is destroyed. This scenario (aura::Windows being deleted after the
392 // Shell) occurs if someone is holding a reference to an unparented Window, as
393 // is the case with a RenderWidgetHostViewAura that isn't on screen. As long as
394 // everything is ok, we won't crash. If there is a bug, window's destructor will
395 // notify some deleted object (say VideoDetector or ActivationController) and
396 // this will crash.
397 class ShellTest2 : public test::AshTestBase {
398 public:
399 ShellTest2() {}
400 virtual ~ShellTest2() {}
402 protected:
403 scoped_ptr<aura::Window> window_;
405 private:
406 DISALLOW_COPY_AND_ASSIGN(ShellTest2);
409 TEST_F(ShellTest2, DontCrashWhenWindowDeleted) {
410 window_.reset(new aura::Window(NULL));
411 window_->Init(ui::LAYER_NOT_DRAWN);
414 } // namespace ash