blob: 48aadbd3d6419c4de5b705848184ba2e00089db9 [file] [log] [blame]
[email protected]f1853122012-06-27 16:21:261// 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.
4
[email protected]8674b312012-10-12 19:02:445#include "ash/root_window_controller.h"
6
dchenga94547472016-04-08 08:41:117#include <memory>
8
skyea4ca942016-09-12 21:56:199#include "ash/aura/wm_window_aura.h"
tdanderson0b7905b2016-06-22 21:53:0310#include "ash/common/material_design/material_design_controller.h"
jamescook7f99e932016-12-20 18:10:3511#include "ash/common/session/session_controller.h"
jamescook2b624c5a2016-06-08 01:34:0212#include "ash/common/session/session_state_delegate.h"
jamescook2a4d1eb2016-06-09 20:10:0713#include "ash/common/system/tray/system_tray_delegate.h"
skyea4ca942016-09-12 21:56:1914#include "ash/common/wm/system_modal_container_layout_manager.h"
skyd6063772016-06-01 17:52:2115#include "ash/common/wm/window_state.h"
skyea4ca942016-09-12 21:56:1916#include "ash/common/wm_lookup.h"
17#include "ash/common/wm_root_window_controller.h"
jamescook443e42d2016-06-10 21:44:4618#include "ash/common/wm_shell.h"
skyea4ca942016-09-12 21:56:1919#include "ash/common/wm_window.h"
jamescook8800b8232016-10-19 12:46:2720#include "ash/public/cpp/shell_window_ids.h"
jamescook7f99e932016-12-20 18:10:3521#include "ash/public/interfaces/session_controller.mojom.h"
[email protected]f1853122012-06-27 16:21:2622#include "ash/shell.h"
tdanderson0b7905b2016-06-22 21:53:0323#include "ash/test/ash_md_test_base.h"
[email protected]f1853122012-06-27 16:21:2624#include "ash/test/ash_test_base.h"
[email protected]2ee2f5d2013-01-10 23:37:1625#include "ash/wm/window_properties.h"
sky8d5646fe2016-04-15 17:03:4626#include "ash/wm/window_state_aura.h"
[email protected]f1853122012-06-27 16:21:2627#include "ash/wm/window_util.h"
[email protected]eff4c7f2013-08-13 01:45:5028#include "base/command_line.h"
[email protected]792b9b12012-12-11 03:53:2729#include "ui/aura/client/focus_change_observer.h"
[email protected]8cfb6722012-11-28 03:28:4630#include "ui/aura/client/focus_client.h"
sky28f20d62016-10-20 23:21:5931#include "ui/aura/client/window_parenting_client.h"
[email protected]f1853122012-06-27 16:21:2632#include "ui/aura/env.h"
[email protected]dbf835d82012-09-11 18:23:0933#include "ui/aura/test/test_window_delegate.h"
34#include "ui/aura/test/test_windows.h"
[email protected]f1853122012-06-27 16:21:2635#include "ui/aura/window.h"
[email protected]fcc51c952014-02-21 21:31:2636#include "ui/aura/window_event_dispatcher.h"
[email protected]dbf835d82012-09-11 18:23:0937#include "ui/aura/window_tracker.h"
[email protected]2082d7d2014-05-13 14:44:2338#include "ui/base/ime/dummy_text_input_client.h"
39#include "ui/base/ime/input_method.h"
40#include "ui/base/ime/text_input_client.h"
rjkroege72f8154f2016-10-29 00:49:0241#include "ui/display/manager/display_manager.h"
yhanada7e20c9b2016-11-25 00:03:1942#include "ui/display/test/display_manager_test_api.h"
43#include "ui/events/devices/device_data_manager.h"
44#include "ui/events/devices/touchscreen_device.h"
[email protected]73c9fd02014-07-28 01:48:5245#include "ui/events/test/event_generator.h"
[email protected]cd9f71d2014-03-20 21:54:2146#include "ui/events/test/test_event_handler.h"
jamescookcf8b648f2016-06-01 19:58:1747#include "ui/keyboard/keyboard_controller.h"
[email protected]eff4c7f2013-08-13 01:45:5048#include "ui/keyboard/keyboard_switches.h"
ben974286a2015-10-10 00:45:1249#include "ui/keyboard/keyboard_ui.h"
[email protected]39e95212014-04-23 20:00:0150#include "ui/keyboard/keyboard_util.h"
[email protected]f1853122012-06-27 16:21:2651#include "ui/views/controls/menu/menu_controller.h"
52#include "ui/views/widget/widget.h"
53#include "ui/views/widget/widget_delegate.h"
54
[email protected]2ee2f5d2013-01-10 23:37:1655using aura::Window;
56using views::Widget;
57
[email protected]f1853122012-06-27 16:21:2658namespace ash {
59namespace {
60
61class TestDelegate : public views::WidgetDelegateView {
62 public:
63 explicit TestDelegate(bool system_modal) : system_modal_(system_modal) {}
dcheng1f4538e2014-10-27 23:57:0564 ~TestDelegate() override {}
[email protected]f1853122012-06-27 16:21:2665
66 // Overridden from views::WidgetDelegate:
dcheng1f4538e2014-10-27 23:57:0567 ui::ModalType GetModalType() const override {
[email protected]f1853122012-06-27 16:21:2668 return system_modal_ ? ui::MODAL_TYPE_SYSTEM : ui::MODAL_TYPE_NONE;
69 }
70
71 private:
72 bool system_modal_;
[email protected]0fbfa972013-10-02 19:23:3373
[email protected]f1853122012-06-27 16:21:2674 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
75};
76
[email protected]792b9b12012-12-11 03:53:2777class DeleteOnBlurDelegate : public aura::test::TestWindowDelegate,
78 public aura::client::FocusChangeObserver {
[email protected]dbf835d82012-09-11 18:23:0979 public:
80 DeleteOnBlurDelegate() : window_(NULL) {}
dcheng1f4538e2014-10-27 23:57:0581 ~DeleteOnBlurDelegate() override {}
[email protected]dbf835d82012-09-11 18:23:0982
[email protected]792b9b12012-12-11 03:53:2783 void SetWindow(aura::Window* window) {
84 window_ = window;
85 aura::client::SetFocusChangeObserver(window_, this);
86 }
[email protected]dbf835d82012-09-11 18:23:0987
[email protected]869f6352012-12-06 20:47:1788 private:
[email protected]dbf835d82012-09-11 18:23:0989 // aura::test::TestWindowDelegate overrides:
dcheng1f4538e2014-10-27 23:57:0590 bool CanFocus() override { return true; }
[email protected]dbf835d82012-09-11 18:23:0991
[email protected]792b9b12012-12-11 03:53:2792 // aura::client::FocusChangeObserver implementation:
dcheng1f4538e2014-10-27 23:57:0593 void OnWindowFocused(aura::Window* gained_focus,
94 aura::Window* lost_focus) override {
[email protected]792b9b12012-12-11 03:53:2795 if (window_ == lost_focus)
96 delete window_;
[email protected]869f6352012-12-06 20:47:1797 }
98
[email protected]dbf835d82012-09-11 18:23:0999 aura::Window* window_;
100
101 DISALLOW_COPY_AND_ASSIGN(DeleteOnBlurDelegate);
102};
103
[email protected]f1853122012-06-27 16:21:26104} // namespace
105
106namespace test {
[email protected]f1853122012-06-27 16:21:26107
tdanderson0b7905b2016-06-22 21:53:03108class RootWindowControllerTest : public AshMDTestBase {
[email protected]a2e6af12013-01-07 21:40:35109 public:
110 views::Widget* CreateTestWidget(const gfx::Rect& bounds) {
111 views::Widget* widget = views::Widget::CreateWindowWithContextAndBounds(
112 NULL, CurrentContext(), bounds);
113 widget->Show();
114 return widget;
115 }
116
117 views::Widget* CreateModalWidget(const gfx::Rect& bounds) {
118 views::Widget* widget = views::Widget::CreateWindowWithContextAndBounds(
119 new TestDelegate(true), CurrentContext(), bounds);
120 widget->Show();
121 return widget;
122 }
123
124 views::Widget* CreateModalWidgetWithParent(const gfx::Rect& bounds,
125 gfx::NativeWindow parent) {
jamescookb8dcef522016-06-25 14:42:55126 views::Widget* widget = views::Widget::CreateWindowWithParentAndBounds(
127 new TestDelegate(true), parent, bounds);
[email protected]a2e6af12013-01-07 21:40:35128 widget->Show();
129 return widget;
130 }
131
[email protected]c9390bd2013-11-08 20:33:13132 aura::Window* GetModalContainer(aura::Window* root_window) {
[email protected]093b8d642014-04-03 20:59:28133 return Shell::GetContainer(root_window,
mswbc0a8b482016-06-30 02:21:14134 kShellWindowId_SystemModalContainer);
[email protected]a2e6af12013-01-07 21:40:35135 }
136};
[email protected]f1853122012-06-27 16:21:26137
tdanderson0b7905b2016-06-22 21:53:03138INSTANTIATE_TEST_CASE_P(
139 /* prefix intentionally left blank due to only one parameterization */,
140 RootWindowControllerTest,
141 testing::Values(MaterialDesignController::NON_MATERIAL,
142 MaterialDesignController::MATERIAL_NORMAL,
143 MaterialDesignController::MATERIAL_EXPERIMENTAL));
144
145TEST_P(RootWindowControllerTest, MoveWindows_Basic) {
[email protected]e75642a2013-06-12 17:21:18146 if (!SupportsMultipleDisplays())
147 return;
tdanderson0b7905b2016-06-22 21:53:03148 const int height_offset = GetMdMaximizedWindowHeightOffset();
149
[email protected]2816c2462013-12-17 02:22:25150 // Windows origin should be doubled when moved to the 1st display.
151 UpdateDisplay("600x600,300x300");
[email protected]c9390bd2013-11-08 20:33:13152 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
[email protected]f1853122012-06-27 16:21:26153
154 views::Widget* normal = CreateTestWidget(gfx::Rect(650, 10, 100, 100));
155 EXPECT_EQ(root_windows[1], normal->GetNativeView()->GetRootWindow());
[email protected]e2f64d102012-07-19 19:17:04156 EXPECT_EQ("650,10 100x100", normal->GetWindowBoundsInScreen().ToString());
[email protected]8d625fb2012-07-18 16:40:06157 EXPECT_EQ("50,10 100x100",
[email protected]e2f64d102012-07-19 19:17:04158 normal->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]f1853122012-06-27 16:21:26159
160 views::Widget* maximized = CreateTestWidget(gfx::Rect(700, 10, 100, 100));
161 maximized->Maximize();
162 EXPECT_EQ(root_windows[1], maximized->GetNativeView()->GetRootWindow());
tdanderson0b7905b2016-06-22 21:53:03163 EXPECT_EQ(gfx::Rect(600, 0, 300, 253 + height_offset).ToString(),
164 maximized->GetWindowBoundsInScreen().ToString());
165 EXPECT_EQ(gfx::Rect(0, 0, 300, 253 + height_offset).ToString(),
[email protected]8c0ec432013-05-10 04:33:39166 maximized->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]f1853122012-06-27 16:21:26167
168 views::Widget* minimized = CreateTestWidget(gfx::Rect(800, 10, 100, 100));
169 minimized->Minimize();
170 EXPECT_EQ(root_windows[1], minimized->GetNativeView()->GetRootWindow());
jamescookb8dcef522016-06-25 14:42:55171 EXPECT_EQ("800,10 100x100", minimized->GetWindowBoundsInScreen().ToString());
[email protected]f1853122012-06-27 16:21:26172
[email protected]2816c2462013-12-17 02:22:25173 views::Widget* fullscreen = CreateTestWidget(gfx::Rect(850, 10, 100, 100));
[email protected]f1853122012-06-27 16:21:26174 fullscreen->SetFullscreen(true);
175 EXPECT_EQ(root_windows[1], fullscreen->GetNativeView()->GetRootWindow());
[email protected]1a015382012-12-01 19:44:59176
jamescookb8dcef522016-06-25 14:42:55177 EXPECT_EQ("600,0 300x300", fullscreen->GetWindowBoundsInScreen().ToString());
[email protected]2816c2462013-12-17 02:22:25178 EXPECT_EQ("0,0 300x300",
[email protected]e2f64d102012-07-19 19:17:04179 fullscreen->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]f1853122012-06-27 16:21:26180
[email protected]8f2f151412013-01-26 03:58:37181 views::Widget* unparented_control = new Widget;
182 Widget::InitParams params;
183 params.bounds = gfx::Rect(650, 10, 100, 100);
184 params.context = CurrentContext();
185 params.type = Widget::InitParams::TYPE_CONTROL;
186 unparented_control->Init(params);
187 EXPECT_EQ(root_windows[1],
188 unparented_control->GetNativeView()->GetRootWindow());
[email protected]093b8d642014-04-03 20:59:28189 EXPECT_EQ(kShellWindowId_UnparentedControlContainer,
[email protected]8f2f151412013-01-26 03:58:37190 unparented_control->GetNativeView()->parent()->id());
191
[email protected]95db9c12013-01-31 11:47:44192 aura::Window* panel = CreateTestWindowInShellWithDelegateAndType(
[email protected]5b251f12013-12-19 01:50:05193 NULL, ui::wm::WINDOW_TYPE_PANEL, 0, gfx::Rect(700, 100, 100, 100));
[email protected]95db9c12013-01-31 11:47:44194 EXPECT_EQ(root_windows[1], panel->GetRootWindow());
[email protected]093b8d642014-04-03 20:59:28195 EXPECT_EQ(kShellWindowId_PanelContainer, panel->parent()->id());
[email protected]95db9c12013-01-31 11:47:44196
[email protected]dbf835d82012-09-11 18:23:09197 // Make sure a window that will delete itself when losing focus
198 // will not crash.
199 aura::WindowTracker tracker;
200 DeleteOnBlurDelegate delete_on_blur_delegate;
[email protected]5ebe6102012-11-28 21:00:03201 aura::Window* d2 = CreateTestWindowInShellWithDelegate(
202 &delete_on_blur_delegate, 0, gfx::Rect(50, 50, 100, 100));
[email protected]792b9b12012-12-11 03:53:27203 delete_on_blur_delegate.SetWindow(d2);
[email protected]550543e2013-01-11 22:43:44204 aura::client::GetFocusClient(root_windows[0])->FocusWindow(d2);
[email protected]dbf835d82012-09-11 18:23:09205 tracker.Add(d2);
206
[email protected]f634dd32012-07-23 22:49:07207 UpdateDisplay("600x600");
[email protected]f1853122012-06-27 16:21:26208
[email protected]dbf835d82012-09-11 18:23:09209 // d2 must have been deleted.
210 EXPECT_FALSE(tracker.Contains(d2));
211
[email protected]f1853122012-06-27 16:21:26212 EXPECT_EQ(root_windows[0], normal->GetNativeView()->GetRootWindow());
[email protected]2816c2462013-12-17 02:22:25213 EXPECT_EQ("100,20 100x100", normal->GetWindowBoundsInScreen().ToString());
214 EXPECT_EQ("100,20 100x100",
[email protected]e2f64d102012-07-19 19:17:04215 normal->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]f1853122012-06-27 16:21:26216
yiyix20e7d3f2016-06-14 21:49:36217 // Maximized area on primary display has 47px for non-md and 48px for md
mswbc0a8b482016-06-30 02:21:14218 // (defined in SHELF_SIZE) inset at the bottom.
[email protected]2a64b0a2013-07-23 23:15:54219
220 // First clear fullscreen status, since both fullscreen and maximized windows
221 // share the same desktop workspace, which cancels the shelf status.
222 fullscreen->SetFullscreen(false);
[email protected]f1853122012-06-27 16:21:26223 EXPECT_EQ(root_windows[0], maximized->GetNativeView()->GetRootWindow());
tdanderson0b7905b2016-06-22 21:53:03224 EXPECT_EQ(gfx::Rect(0, 0, 600, 553 + height_offset).ToString(),
225 maximized->GetWindowBoundsInScreen().ToString());
226 EXPECT_EQ(gfx::Rect(0, 0, 600, 553 + height_offset).ToString(),
[email protected]e2f64d102012-07-19 19:17:04227 maximized->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]f1853122012-06-27 16:21:26228
oshima5594d1232015-12-04 18:58:38229 // Set fullscreen to true, but maximized window's size won't change because
230 // it's not visible. see crbug.com/504299.
[email protected]2a64b0a2013-07-23 23:15:54231 fullscreen->SetFullscreen(true);
232 EXPECT_EQ(root_windows[0], maximized->GetNativeView()->GetRootWindow());
tdanderson0b7905b2016-06-22 21:53:03233 EXPECT_EQ(gfx::Rect(0, 0, 600, 553 + height_offset).ToString(),
234 maximized->GetWindowBoundsInScreen().ToString());
235 EXPECT_EQ(gfx::Rect(0, 0, 600, 553 + height_offset).ToString(),
[email protected]2a64b0a2013-07-23 23:15:54236 maximized->GetNativeView()->GetBoundsInRootWindow().ToString());
237
[email protected]f1853122012-06-27 16:21:26238 EXPECT_EQ(root_windows[0], minimized->GetNativeView()->GetRootWindow());
jamescookb8dcef522016-06-25 14:42:55239 EXPECT_EQ("400,20 100x100", minimized->GetWindowBoundsInScreen().ToString());
[email protected]f1853122012-06-27 16:21:26240
241 EXPECT_EQ(root_windows[0], fullscreen->GetNativeView()->GetRootWindow());
242 EXPECT_TRUE(fullscreen->IsFullscreen());
jamescookb8dcef522016-06-25 14:42:55243 EXPECT_EQ("0,0 600x600", fullscreen->GetWindowBoundsInScreen().ToString());
[email protected]8d625fb2012-07-18 16:40:06244 EXPECT_EQ("0,0 600x600",
[email protected]e2f64d102012-07-19 19:17:04245 fullscreen->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]8d625fb2012-07-18 16:40:06246
247 // Test if the restore bounds are correctly updated.
[email protected]a41b4e12013-09-20 04:36:34248 wm::GetWindowState(maximized->GetNativeView())->Restore();
[email protected]2816c2462013-12-17 02:22:25249 EXPECT_EQ("200,20 100x100", maximized->GetWindowBoundsInScreen().ToString());
250 EXPECT_EQ("200,20 100x100",
[email protected]e2f64d102012-07-19 19:17:04251 maximized->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]8d625fb2012-07-18 16:40:06252
253 fullscreen->SetFullscreen(false);
jamescookb8dcef522016-06-25 14:42:55254 EXPECT_EQ("500,20 100x100", fullscreen->GetWindowBoundsInScreen().ToString());
[email protected]2816c2462013-12-17 02:22:25255 EXPECT_EQ("500,20 100x100",
[email protected]e2f64d102012-07-19 19:17:04256 fullscreen->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]8f2f151412013-01-26 03:58:37257
258 // Test if the unparented widget has moved.
259 EXPECT_EQ(root_windows[0],
260 unparented_control->GetNativeView()->GetRootWindow());
[email protected]093b8d642014-04-03 20:59:28261 EXPECT_EQ(kShellWindowId_UnparentedControlContainer,
[email protected]8f2f151412013-01-26 03:58:37262 unparented_control->GetNativeView()->parent()->id());
[email protected]95db9c12013-01-31 11:47:44263
264 // Test if the panel has moved.
265 EXPECT_EQ(root_windows[0], panel->GetRootWindow());
[email protected]093b8d642014-04-03 20:59:28266 EXPECT_EQ(kShellWindowId_PanelContainer, panel->parent()->id());
[email protected]f1853122012-06-27 16:21:26267}
268
tdanderson0b7905b2016-06-22 21:53:03269TEST_P(RootWindowControllerTest, MoveWindows_Modal) {
[email protected]e75642a2013-06-12 17:21:18270 if (!SupportsMultipleDisplays())
271 return;
[email protected]1c3f7002013-01-21 18:46:05272
[email protected]f634dd32012-07-23 22:49:07273 UpdateDisplay("500x500,500x500");
[email protected]f1853122012-06-27 16:21:26274
[email protected]c9390bd2013-11-08 20:33:13275 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
[email protected]f1853122012-06-27 16:21:26276 // Emulate virtual screen coordinate system.
277 root_windows[0]->SetBounds(gfx::Rect(0, 0, 500, 500));
278 root_windows[1]->SetBounds(gfx::Rect(500, 0, 500, 500));
279
280 views::Widget* normal = CreateTestWidget(gfx::Rect(300, 10, 100, 100));
281 EXPECT_EQ(root_windows[0], normal->GetNativeView()->GetRootWindow());
282 EXPECT_TRUE(wm::IsActiveWindow(normal->GetNativeView()));
283
284 views::Widget* modal = CreateModalWidget(gfx::Rect(650, 10, 100, 100));
285 EXPECT_EQ(root_windows[1], modal->GetNativeView()->GetRootWindow());
jamescookb8dcef522016-06-25 14:42:55286 EXPECT_TRUE(
287 GetModalContainer(root_windows[1])->Contains(modal->GetNativeView()));
[email protected]f1853122012-06-27 16:21:26288 EXPECT_TRUE(wm::IsActiveWindow(modal->GetNativeView()));
289
[email protected]73c9fd02014-07-28 01:48:52290 ui::test::EventGenerator generator_1st(root_windows[0]);
[email protected]f1853122012-06-27 16:21:26291 generator_1st.ClickLeftButton();
292 EXPECT_TRUE(wm::IsActiveWindow(modal->GetNativeView()));
293
[email protected]f634dd32012-07-23 22:49:07294 UpdateDisplay("500x500");
[email protected]f1853122012-06-27 16:21:26295 EXPECT_EQ(root_windows[0], modal->GetNativeView()->GetRootWindow());
296 EXPECT_TRUE(wm::IsActiveWindow(modal->GetNativeView()));
297 generator_1st.ClickLeftButton();
298 EXPECT_TRUE(wm::IsActiveWindow(modal->GetNativeView()));
299}
300
oshima022a9542015-05-01 00:15:02301// Make sure lock related windows moves.
tdanderson0b7905b2016-06-22 21:53:03302TEST_P(RootWindowControllerTest, MoveWindows_LockWindowsInUnified) {
oshima022a9542015-05-01 00:15:02303 if (!SupportsMultipleDisplays())
304 return;
rjkroege72f8154f2016-10-29 00:49:02305 display_manager()->SetUnifiedDesktopEnabled(true);
oshimabba2d992015-05-22 19:21:39306
oshima022a9542015-05-01 00:15:02307 UpdateDisplay("500x500");
308 const int kLockScreenWindowId = 1000;
msw607227f82016-08-30 17:22:39309 const int kLockWallpaperWindowId = 1001;
oshima022a9542015-05-01 00:15:02310
mswbc0a8b482016-06-30 02:21:14311 RootWindowController* controller = Shell::GetPrimaryRootWindowController();
oshima022a9542015-05-01 00:15:02312
313 aura::Window* lock_container =
314 controller->GetContainer(kShellWindowId_LockScreenContainer);
msw607227f82016-08-30 17:22:39315 aura::Window* lock_wallpaper_container =
316 controller->GetContainer(kShellWindowId_LockScreenWallpaperContainer);
oshima022a9542015-05-01 00:15:02317
318 views::Widget* lock_screen =
319 CreateModalWidgetWithParent(gfx::Rect(10, 10, 100, 100), lock_container);
320 lock_screen->GetNativeWindow()->set_id(kLockScreenWindowId);
321 lock_screen->SetFullscreen(true);
322
msw607227f82016-08-30 17:22:39323 views::Widget* lock_wallpaper = CreateModalWidgetWithParent(
324 gfx::Rect(10, 10, 100, 100), lock_wallpaper_container);
325 lock_wallpaper->GetNativeWindow()->set_id(kLockWallpaperWindowId);
oshima022a9542015-05-01 00:15:02326
327 ASSERT_EQ(lock_screen->GetNativeWindow(),
328 controller->GetRootWindow()->GetChildById(kLockScreenWindowId));
msw607227f82016-08-30 17:22:39329 ASSERT_EQ(lock_wallpaper->GetNativeWindow(),
330 controller->GetRootWindow()->GetChildById(kLockWallpaperWindowId));
oshima022a9542015-05-01 00:15:02331 EXPECT_EQ("0,0 500x500", lock_screen->GetNativeWindow()->bounds().ToString());
332
333 // Switch to unified.
334 UpdateDisplay("500x500,500x500");
335
336 // In unified mode, RWC is created
mswbc0a8b482016-06-30 02:21:14337 controller = Shell::GetPrimaryRootWindowController();
oshima022a9542015-05-01 00:15:02338
339 ASSERT_EQ(lock_screen->GetNativeWindow(),
340 controller->GetRootWindow()->GetChildById(kLockScreenWindowId));
msw607227f82016-08-30 17:22:39341 ASSERT_EQ(lock_wallpaper->GetNativeWindow(),
342 controller->GetRootWindow()->GetChildById(kLockWallpaperWindowId));
oshima96f6a502015-05-02 08:43:32343 EXPECT_EQ("0,0 500x500", lock_screen->GetNativeWindow()->bounds().ToString());
oshima022a9542015-05-01 00:15:02344
345 // Switch to mirror.
rjkroege72f8154f2016-10-29 00:49:02346 display_manager()->SetMirrorMode(true);
347 EXPECT_TRUE(display_manager()->IsInMirrorMode());
oshima022a9542015-05-01 00:15:02348
mswbc0a8b482016-06-30 02:21:14349 controller = Shell::GetPrimaryRootWindowController();
oshima022a9542015-05-01 00:15:02350 ASSERT_EQ(lock_screen->GetNativeWindow(),
351 controller->GetRootWindow()->GetChildById(kLockScreenWindowId));
msw607227f82016-08-30 17:22:39352 ASSERT_EQ(lock_wallpaper->GetNativeWindow(),
353 controller->GetRootWindow()->GetChildById(kLockWallpaperWindowId));
oshima022a9542015-05-01 00:15:02354 EXPECT_EQ("0,0 500x500", lock_screen->GetNativeWindow()->bounds().ToString());
355
356 // Switch to unified.
rjkroege72f8154f2016-10-29 00:49:02357 display_manager()->SetMirrorMode(false);
358 EXPECT_TRUE(display_manager()->IsInUnifiedMode());
oshima022a9542015-05-01 00:15:02359
mswbc0a8b482016-06-30 02:21:14360 controller = Shell::GetPrimaryRootWindowController();
oshima022a9542015-05-01 00:15:02361
362 ASSERT_EQ(lock_screen->GetNativeWindow(),
363 controller->GetRootWindow()->GetChildById(kLockScreenWindowId));
msw607227f82016-08-30 17:22:39364 ASSERT_EQ(lock_wallpaper->GetNativeWindow(),
365 controller->GetRootWindow()->GetChildById(kLockWallpaperWindowId));
oshima96f6a502015-05-02 08:43:32366 EXPECT_EQ("0,0 500x500", lock_screen->GetNativeWindow()->bounds().ToString());
oshima022a9542015-05-01 00:15:02367
368 // Switch to single display.
369 UpdateDisplay("600x500");
rjkroege72f8154f2016-10-29 00:49:02370 EXPECT_FALSE(display_manager()->IsInUnifiedMode());
371 EXPECT_FALSE(display_manager()->IsInMirrorMode());
oshima022a9542015-05-01 00:15:02372
mswbc0a8b482016-06-30 02:21:14373 controller = Shell::GetPrimaryRootWindowController();
oshima022a9542015-05-01 00:15:02374
375 ASSERT_EQ(lock_screen->GetNativeWindow(),
376 controller->GetRootWindow()->GetChildById(kLockScreenWindowId));
msw607227f82016-08-30 17:22:39377 ASSERT_EQ(lock_wallpaper->GetNativeWindow(),
378 controller->GetRootWindow()->GetChildById(kLockWallpaperWindowId));
oshima022a9542015-05-01 00:15:02379 EXPECT_EQ("0,0 600x500", lock_screen->GetNativeWindow()->bounds().ToString());
380}
381
tdanderson0b7905b2016-06-22 21:53:03382TEST_P(RootWindowControllerTest, ModalContainer) {
[email protected]8674b312012-10-12 19:02:44383 UpdateDisplay("600x600");
jamescook443e42d2016-06-10 21:44:46384 WmShell* wm_shell = WmShell::Get();
skyea4ca942016-09-12 21:56:19385 WmRootWindowController* controller =
386 wm_shell->GetPrimaryRootWindowController();
skye79274a2016-06-08 05:39:02387 EXPECT_EQ(LoginStatus::USER,
jamescook443e42d2016-06-10 21:44:46388 wm_shell->system_tray_delegate()->GetUserLoginStatus());
[email protected]f5c9dbc2014-04-11 08:13:45389 EXPECT_EQ(controller->GetContainer(kShellWindowId_SystemModalContainer)
skyea4ca942016-09-12 21:56:19390 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28391 controller->GetSystemModalLayoutManager(NULL));
[email protected]8674b312012-10-12 19:02:44392
[email protected]3b162e12012-11-09 11:52:35393 views::Widget* session_modal_widget =
394 CreateModalWidget(gfx::Rect(300, 10, 100, 100));
[email protected]f5c9dbc2014-04-11 08:13:45395 EXPECT_EQ(controller->GetContainer(kShellWindowId_SystemModalContainer)
skyea4ca942016-09-12 21:56:19396 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28397 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19398 WmLookup::Get()->GetWindowForWidget(session_modal_widget)));
[email protected]3b162e12012-11-09 11:52:35399
mswbc0a8b482016-06-30 02:21:14400 wm_shell->GetSessionStateDelegate()->LockScreen();
skye79274a2016-06-08 05:39:02401 EXPECT_EQ(LoginStatus::LOCKED,
jamescook443e42d2016-06-10 21:44:46402 wm_shell->system_tray_delegate()->GetUserLoginStatus());
[email protected]f5c9dbc2014-04-11 08:13:45403 EXPECT_EQ(controller->GetContainer(kShellWindowId_LockSystemModalContainer)
skyea4ca942016-09-12 21:56:19404 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28405 controller->GetSystemModalLayoutManager(NULL));
[email protected]3b162e12012-11-09 11:52:35406
skyea4ca942016-09-12 21:56:19407 aura::Window* lock_container = WmWindowAura::GetAuraWindow(
408 controller->GetContainer(kShellWindowId_LockScreenContainer));
[email protected]3b162e12012-11-09 11:52:35409 views::Widget* lock_modal_widget =
410 CreateModalWidgetWithParent(gfx::Rect(300, 10, 100, 100), lock_container);
[email protected]f5c9dbc2014-04-11 08:13:45411 EXPECT_EQ(controller->GetContainer(kShellWindowId_LockSystemModalContainer)
skyea4ca942016-09-12 21:56:19412 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28413 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19414 WmLookup::Get()->GetWindowForWidget(lock_modal_widget)));
[email protected]f5c9dbc2014-04-11 08:13:45415 EXPECT_EQ(controller->GetContainer(kShellWindowId_SystemModalContainer)
skyea4ca942016-09-12 21:56:19416 ->GetLayoutManager(),
[email protected]3b162e12012-11-09 11:52:35417 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19418 WmLookup::Get()->GetWindowForWidget(session_modal_widget)));
[email protected]3b162e12012-11-09 11:52:35419
mswbc0a8b482016-06-30 02:21:14420 wm_shell->GetSessionStateDelegate()->UnlockScreen();
[email protected]8674b312012-10-12 19:02:44421}
422
tdanderson0b7905b2016-06-22 21:53:03423TEST_P(RootWindowControllerTest, ModalContainerNotLoggedInLoggedIn) {
[email protected]1b219922012-11-13 21:16:43424 UpdateDisplay("600x600");
[email protected]1b219922012-11-13 21:16:43425
426 // Configure login screen environment.
mswbc0a8b482016-06-30 02:21:14427 SessionStateDelegate* session_state_delegate =
428 WmShell::Get()->GetSessionStateDelegate();
[email protected]1b219922012-11-13 21:16:43429 SetUserLoggedIn(false);
skye79274a2016-06-08 05:39:02430 EXPECT_EQ(LoginStatus::NOT_LOGGED_IN,
mswbc0a8b482016-06-30 02:21:14431 WmShell::Get()->system_tray_delegate()->GetUserLoginStatus());
432 EXPECT_EQ(0, session_state_delegate->NumberOfLoggedInUsers());
433 EXPECT_FALSE(session_state_delegate->IsActiveUserSessionStarted());
[email protected]1b219922012-11-13 21:16:43434
skyea4ca942016-09-12 21:56:19435 WmRootWindowController* controller =
436 WmShell::Get()->GetPrimaryRootWindowController();
[email protected]f5c9dbc2014-04-11 08:13:45437 EXPECT_EQ(controller->GetContainer(kShellWindowId_LockSystemModalContainer)
skyea4ca942016-09-12 21:56:19438 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28439 controller->GetSystemModalLayoutManager(NULL));
[email protected]1b219922012-11-13 21:16:43440
skyea4ca942016-09-12 21:56:19441 aura::Window* lock_container = WmWindowAura::GetAuraWindow(
442 controller->GetContainer(kShellWindowId_LockScreenContainer));
[email protected]1b219922012-11-13 21:16:43443 views::Widget* login_modal_widget =
444 CreateModalWidgetWithParent(gfx::Rect(300, 10, 100, 100), lock_container);
[email protected]f5c9dbc2014-04-11 08:13:45445 EXPECT_EQ(controller->GetContainer(kShellWindowId_LockSystemModalContainer)
skyea4ca942016-09-12 21:56:19446 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28447 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19448 WmLookup::Get()->GetWindowForWidget(login_modal_widget)));
[email protected]1b219922012-11-13 21:16:43449 login_modal_widget->Close();
450
451 // Configure user session environment.
452 SetUserLoggedIn(true);
453 SetSessionStarted(true);
skye79274a2016-06-08 05:39:02454 EXPECT_EQ(LoginStatus::USER,
mswbc0a8b482016-06-30 02:21:14455 WmShell::Get()->system_tray_delegate()->GetUserLoginStatus());
456 EXPECT_EQ(1, session_state_delegate->NumberOfLoggedInUsers());
457 EXPECT_TRUE(session_state_delegate->IsActiveUserSessionStarted());
[email protected]f5c9dbc2014-04-11 08:13:45458 EXPECT_EQ(controller->GetContainer(kShellWindowId_SystemModalContainer)
skyea4ca942016-09-12 21:56:19459 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28460 controller->GetSystemModalLayoutManager(NULL));
[email protected]1b219922012-11-13 21:16:43461
462 views::Widget* session_modal_widget =
jamescookb8dcef522016-06-25 14:42:55463 CreateModalWidget(gfx::Rect(300, 10, 100, 100));
[email protected]f5c9dbc2014-04-11 08:13:45464 EXPECT_EQ(controller->GetContainer(kShellWindowId_SystemModalContainer)
skyea4ca942016-09-12 21:56:19465 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28466 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19467 WmLookup::Get()->GetWindowForWidget(session_modal_widget)));
[email protected]1b219922012-11-13 21:16:43468}
469
tdanderson0b7905b2016-06-22 21:53:03470TEST_P(RootWindowControllerTest, ModalContainerBlockedSession) {
[email protected]a44afbbd2013-07-24 21:49:35471 UpdateDisplay("600x600");
skyea4ca942016-09-12 21:56:19472 WmRootWindowController* controller =
473 WmShell::Get()->GetPrimaryRootWindowController();
474 aura::Window* lock_container = WmWindowAura::GetAuraWindow(
475 controller->GetContainer(kShellWindowId_LockScreenContainer));
[email protected]a44afbbd2013-07-24 21:49:35476 for (int block_reason = FIRST_BLOCK_REASON;
jamescookb8dcef522016-06-25 14:42:55477 block_reason < NUMBER_OF_BLOCK_REASONS; ++block_reason) {
[email protected]a44afbbd2013-07-24 21:49:35478 views::Widget* session_modal_widget =
jamescookb8dcef522016-06-25 14:42:55479 CreateModalWidget(gfx::Rect(300, 10, 100, 100));
[email protected]f5c9dbc2014-04-11 08:13:45480 EXPECT_EQ(controller->GetContainer(kShellWindowId_SystemModalContainer)
skyea4ca942016-09-12 21:56:19481 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28482 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19483 WmLookup::Get()->GetWindowForWidget(session_modal_widget)));
[email protected]f5c9dbc2014-04-11 08:13:45484 EXPECT_EQ(controller->GetContainer(kShellWindowId_SystemModalContainer)
skyea4ca942016-09-12 21:56:19485 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28486 controller->GetSystemModalLayoutManager(NULL));
[email protected]a44afbbd2013-07-24 21:49:35487 session_modal_widget->Close();
488
489 BlockUserSession(static_cast<UserSessionBlockReason>(block_reason));
490
[email protected]f5c9dbc2014-04-11 08:13:45491 EXPECT_EQ(controller->GetContainer(kShellWindowId_LockSystemModalContainer)
skyea4ca942016-09-12 21:56:19492 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28493 controller->GetSystemModalLayoutManager(NULL));
[email protected]a44afbbd2013-07-24 21:49:35494
jamescookb8dcef522016-06-25 14:42:55495 views::Widget* lock_modal_widget = CreateModalWidgetWithParent(
496 gfx::Rect(300, 10, 100, 100), lock_container);
[email protected]f5c9dbc2014-04-11 08:13:45497 EXPECT_EQ(controller->GetContainer(kShellWindowId_LockSystemModalContainer)
skyea4ca942016-09-12 21:56:19498 ->GetLayoutManager(),
[email protected]a44afbbd2013-07-24 21:49:35499 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19500 WmLookup::Get()->GetWindowForWidget(lock_modal_widget)));
[email protected]a44afbbd2013-07-24 21:49:35501
jamescookb8dcef522016-06-25 14:42:55502 session_modal_widget = CreateModalWidget(gfx::Rect(300, 10, 100, 100));
[email protected]f5c9dbc2014-04-11 08:13:45503 EXPECT_EQ(controller->GetContainer(kShellWindowId_SystemModalContainer)
skyea4ca942016-09-12 21:56:19504 ->GetLayoutManager(),
[email protected]093b8d642014-04-03 20:59:28505 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19506 WmLookup::Get()->GetWindowForWidget(session_modal_widget)));
[email protected]a44afbbd2013-07-24 21:49:35507 session_modal_widget->Close();
508
509 lock_modal_widget->Close();
510 UnblockUserSession();
511 }
512}
513
tdanderson0b7905b2016-06-22 21:53:03514TEST_P(RootWindowControllerTest, GetWindowForFullscreenMode) {
[email protected]2ee2f5d2013-01-10 23:37:16515 UpdateDisplay("600x600");
mswbc0a8b482016-06-30 02:21:14516 RootWindowController* controller = Shell::GetPrimaryRootWindowController();
[email protected]2ee2f5d2013-01-10 23:37:16517
[email protected]700849f2013-04-30 17:49:20518 Widget* w1 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
[email protected]2ee2f5d2013-01-10 23:37:16519 w1->Maximize();
[email protected]700849f2013-04-30 17:49:20520 Widget* w2 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
521 w2->SetFullscreen(true);
522 // |w3| is a transient child of |w2|.
jamescookb8dcef522016-06-25 14:42:55523 Widget* w3 = Widget::CreateWindowWithParentAndBounds(
524 NULL, w2->GetNativeWindow(), gfx::Rect(0, 0, 100, 100));
[email protected]2ee2f5d2013-01-10 23:37:16525
[email protected]2c9171d22013-12-10 21:55:10526 // Test that GetWindowForFullscreenMode() finds the fullscreen window when one
[email protected]e3bc88e2013-09-06 06:22:06527 // of its transient children is active.
[email protected]700849f2013-04-30 17:49:20528 w3->Activate();
[email protected]2c9171d22013-12-10 21:55:10529 EXPECT_EQ(w2->GetNativeWindow(), controller->GetWindowForFullscreenMode());
[email protected]2ee2f5d2013-01-10 23:37:16530
[email protected]2c9171d22013-12-10 21:55:10531 // If the topmost window is not fullscreen, it returns NULL.
[email protected]700849f2013-04-30 17:49:20532 w1->Activate();
[email protected]2c9171d22013-12-10 21:55:10533 EXPECT_EQ(NULL, controller->GetWindowForFullscreenMode());
534 w1->Close();
535 w3->Close();
[email protected]e3bc88e2013-09-06 06:22:06536
[email protected]2c9171d22013-12-10 21:55:10537 // Only w2 remains, if minimized GetWindowForFullscreenMode should return
538 // NULL.
[email protected]e3bc88e2013-09-06 06:22:06539 w2->Activate();
[email protected]2c9171d22013-12-10 21:55:10540 EXPECT_EQ(w2->GetNativeWindow(), controller->GetWindowForFullscreenMode());
541 w2->Minimize();
542 EXPECT_EQ(NULL, controller->GetWindowForFullscreenMode());
[email protected]2ee2f5d2013-01-10 23:37:16543}
544
tdanderson0b7905b2016-06-22 21:53:03545TEST_P(RootWindowControllerTest, MultipleDisplaysGetWindowForFullscreenMode) {
[email protected]2c5db9e2014-02-27 13:58:14546 if (!SupportsMultipleDisplays())
547 return;
548
549 UpdateDisplay("600x600,600x600");
550 Shell::RootWindowControllerList controllers =
551 Shell::GetInstance()->GetAllRootWindowControllers();
552
553 Widget* w1 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
554 w1->Maximize();
555 Widget* w2 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
556 w2->SetFullscreen(true);
557 Widget* w3 = CreateTestWidget(gfx::Rect(600, 0, 100, 100));
558
559 EXPECT_EQ(w1->GetNativeWindow()->GetRootWindow(),
[email protected]f5c9dbc2014-04-11 08:13:45560 controllers[0]->GetRootWindow());
[email protected]2c5db9e2014-02-27 13:58:14561 EXPECT_EQ(w2->GetNativeWindow()->GetRootWindow(),
[email protected]f5c9dbc2014-04-11 08:13:45562 controllers[0]->GetRootWindow());
[email protected]2c5db9e2014-02-27 13:58:14563 EXPECT_EQ(w3->GetNativeWindow()->GetRootWindow(),
[email protected]f5c9dbc2014-04-11 08:13:45564 controllers[1]->GetRootWindow());
[email protected]2c5db9e2014-02-27 13:58:14565
566 w1->Activate();
567 EXPECT_EQ(NULL, controllers[0]->GetWindowForFullscreenMode());
568 EXPECT_EQ(NULL, controllers[1]->GetWindowForFullscreenMode());
569
570 w2->Activate();
571 EXPECT_EQ(w2->GetNativeWindow(),
572 controllers[0]->GetWindowForFullscreenMode());
573 EXPECT_EQ(NULL, controllers[1]->GetWindowForFullscreenMode());
574
575 // Verify that the first root window controller remains in fullscreen mode
576 // when a window on the other display is activated.
577 w3->Activate();
578 EXPECT_EQ(w2->GetNativeWindow(),
579 controllers[0]->GetWindowForFullscreenMode());
580 EXPECT_EQ(NULL, controllers[1]->GetWindowForFullscreenMode());
581}
582
jamescook5d74ac02016-05-12 19:57:12583// Test that GetRootWindowController() works with multiple displays and
584// child widgets.
tdanderson0b7905b2016-06-22 21:53:03585TEST_P(RootWindowControllerTest, GetRootWindowController) {
jamescook5d74ac02016-05-12 19:57:12586 if (!SupportsMultipleDisplays())
587 return;
588 UpdateDisplay("600x600,600x600");
589 Shell::RootWindowControllerList controllers =
590 Shell::GetInstance()->GetAllRootWindowControllers();
591 ASSERT_EQ(2u, controllers.size());
592
593 // Test null.
594 EXPECT_FALSE(GetRootWindowController(nullptr));
595
596 // Test a widget on the first display.
597 Widget* w1 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
598 EXPECT_EQ(controllers[0],
599 GetRootWindowController(w1->GetNativeWindow()->GetRootWindow()));
600
601 // Test a child widget.
602 Widget* w2 = Widget::CreateWindowWithParentAndBounds(
603 nullptr, w1->GetNativeWindow(), gfx::Rect(0, 0, 100, 100));
604 EXPECT_EQ(controllers[0],
605 GetRootWindowController(w2->GetNativeWindow()->GetRootWindow()));
606
607 // Test a widget on the second display.
608 Widget* w3 = CreateTestWidget(gfx::Rect(600, 0, 100, 100));
609 EXPECT_EQ(controllers[1],
610 GetRootWindowController(w3->GetNativeWindow()->GetRootWindow()));
611}
612
[email protected]82ced2352013-07-19 20:49:06613// Test that user session window can't be focused if user session blocked by
614// some overlapping UI.
tdanderson0b7905b2016-06-22 21:53:03615TEST_P(RootWindowControllerTest, FocusBlockedWindow) {
[email protected]82ced2352013-07-19 20:49:06616 UpdateDisplay("600x600");
mswbc0a8b482016-06-30 02:21:14617 RootWindowController* controller = Shell::GetPrimaryRootWindowController();
[email protected]f5c9dbc2014-04-11 08:13:45618 aura::Window* lock_container =
619 controller->GetContainer(kShellWindowId_LockScreenContainer);
jamescookb8dcef522016-06-25 14:42:55620 aura::Window* lock_window =
621 Widget::CreateWindowWithParentAndBounds(NULL, lock_container,
622 gfx::Rect(0, 0, 100, 100))
623 ->GetNativeView();
[email protected]82ced2352013-07-19 20:49:06624 lock_window->Show();
625 aura::Window* session_window =
626 CreateTestWidget(gfx::Rect(0, 0, 100, 100))->GetNativeView();
627 session_window->Show();
628
[email protected]a44afbbd2013-07-24 21:49:35629 for (int block_reason = FIRST_BLOCK_REASON;
jamescookb8dcef522016-06-25 14:42:55630 block_reason < NUMBER_OF_BLOCK_REASONS; ++block_reason) {
[email protected]a44afbbd2013-07-24 21:49:35631 BlockUserSession(static_cast<UserSessionBlockReason>(block_reason));
632 lock_window->Focus();
633 EXPECT_TRUE(lock_window->HasFocus());
634 session_window->Focus();
635 EXPECT_FALSE(session_window->HasFocus());
636 UnblockUserSession();
637 }
[email protected]82ced2352013-07-19 20:49:06638}
639
[email protected]0fbfa972013-10-02 19:23:33640// Tracks whether OnWindowDestroying() has been invoked.
641class DestroyedWindowObserver : public aura::WindowObserver {
642 public:
643 DestroyedWindowObserver() : destroyed_(false), window_(NULL) {}
dcheng1f4538e2014-10-27 23:57:05644 ~DestroyedWindowObserver() override { Shutdown(); }
[email protected]0fbfa972013-10-02 19:23:33645
646 void SetWindow(Window* window) {
647 window_ = window;
648 window->AddObserver(this);
649 }
650
651 bool destroyed() const { return destroyed_; }
652
653 // WindowObserver overrides:
dcheng1f4538e2014-10-27 23:57:05654 void OnWindowDestroying(Window* window) override {
[email protected]0fbfa972013-10-02 19:23:33655 destroyed_ = true;
656 Shutdown();
657 }
658
659 private:
660 void Shutdown() {
661 if (!window_)
662 return;
663 window_->RemoveObserver(this);
664 window_ = NULL;
665 }
666
667 bool destroyed_;
668 Window* window_;
669
670 DISALLOW_COPY_AND_ASSIGN(DestroyedWindowObserver);
671};
672
673// Verifies shutdown doesn't delete windows that are not owned by the parent.
tdanderson0b7905b2016-06-22 21:53:03674TEST_P(RootWindowControllerTest, DontDeleteWindowsNotOwnedByParent) {
[email protected]0fbfa972013-10-02 19:23:33675 DestroyedWindowObserver observer1;
676 aura::test::TestWindowDelegate delegate1;
677 aura::Window* window1 = new aura::Window(&delegate1);
[email protected]5b251f12013-12-19 01:50:05678 window1->SetType(ui::wm::WINDOW_TYPE_CONTROL);
[email protected]0fbfa972013-10-02 19:23:33679 window1->set_owned_by_parent(false);
680 observer1.SetWindow(window1);
danakjb161836d2015-04-03 05:14:18681 window1->Init(ui::LAYER_NOT_DRAWN);
[email protected]e3225e02013-10-23 20:44:37682 aura::client::ParentWindowWithContext(
683 window1, Shell::GetInstance()->GetPrimaryRootWindow(), gfx::Rect());
[email protected]0fbfa972013-10-02 19:23:33684
685 DestroyedWindowObserver observer2;
686 aura::Window* window2 = new aura::Window(NULL);
687 window2->set_owned_by_parent(false);
688 observer2.SetWindow(window2);
danakjb161836d2015-04-03 05:14:18689 window2->Init(ui::LAYER_NOT_DRAWN);
[email protected]0fbfa972013-10-02 19:23:33690 Shell::GetInstance()->GetPrimaryRootWindow()->AddChild(window2);
691
mswbc0a8b482016-06-30 02:21:14692 Shell::GetPrimaryRootWindowController()->CloseChildWindows();
[email protected]0fbfa972013-10-02 19:23:33693
694 ASSERT_FALSE(observer1.destroyed());
695 delete window1;
696
697 ASSERT_FALSE(observer2.destroyed());
698 delete window2;
699}
700
[email protected]24f5e242014-07-22 02:16:09701class VirtualKeyboardRootWindowControllerTest
702 : public RootWindowControllerTest {
[email protected]eff4c7f2013-08-13 01:45:50703 public:
dcheng1f4538e2014-10-27 23:57:05704 VirtualKeyboardRootWindowControllerTest() {}
705 ~VirtualKeyboardRootWindowControllerTest() override {}
[email protected]eff4c7f2013-08-13 01:45:50706
dcheng1f4538e2014-10-27 23:57:05707 void SetUp() override {
pgal.u-szegedd84534d32014-10-29 12:34:30708 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]eff4c7f2013-08-13 01:45:50709 keyboard::switches::kEnableVirtualKeyboard);
710 test::AshTestBase::SetUp();
yhanada7e20c9b2016-11-25 00:03:19711 keyboard::SetTouchKeyboardEnabled(true);
712 Shell::GetInstance()->CreateKeyboard();
713 }
714
715 void TearDown() override {
716 keyboard::SetTouchKeyboardEnabled(false);
717 test::AshTestBase::TearDown();
[email protected]eff4c7f2013-08-13 01:45:50718 }
719
720 private:
721 DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardRootWindowControllerTest);
722};
723
[email protected]2082d7d2014-05-13 14:44:23724class MockTextInputClient : public ui::DummyTextInputClient {
725 public:
jamescookb8dcef522016-06-25 14:42:55726 MockTextInputClient() : ui::DummyTextInputClient(ui::TEXT_INPUT_TYPE_TEXT) {}
[email protected]2082d7d2014-05-13 14:44:23727
yhanada0ddd3462016-12-08 05:04:18728 void EnsureCaretNotInRect(const gfx::Rect& rect) override {
729 caret_exclude_rect_ = rect;
[email protected]2082d7d2014-05-13 14:44:23730 }
731
yhanada0ddd3462016-12-08 05:04:18732 const gfx::Rect& caret_exclude_rect() const { return caret_exclude_rect_; }
[email protected]2082d7d2014-05-13 14:44:23733
734 private:
yhanada0ddd3462016-12-08 05:04:18735 gfx::Rect caret_exclude_rect_;
[email protected]2082d7d2014-05-13 14:44:23736
737 DISALLOW_COPY_AND_ASSIGN(MockTextInputClient);
738};
739
kevers23f3987d2014-09-17 13:50:12740class TargetHitTestEventHandler : public ui::test::TestEventHandler {
741 public:
742 TargetHitTestEventHandler() {}
743
744 // ui::test::TestEventHandler overrides.
dcheng1f4538e2014-10-27 23:57:05745 void OnMouseEvent(ui::MouseEvent* event) override {
kevers23f3987d2014-09-17 13:50:12746 if (event->type() == ui::ET_MOUSE_PRESSED)
747 ui::test::TestEventHandler::OnMouseEvent(event);
748 event->StopPropagation();
749 }
750
751 private:
752 DISALLOW_COPY_AND_ASSIGN(TargetHitTestEventHandler);
753};
754
[email protected]b6ba05d902013-10-04 21:38:45755// Test for http://crbug.com/297858. Virtual keyboard container should only show
yhanada7e20c9b2016-11-25 00:03:19756// on primary root window if no window has touch capability.
[email protected]b6ba05d902013-10-04 21:38:45757TEST_F(VirtualKeyboardRootWindowControllerTest,
yhanada7e20c9b2016-11-25 00:03:19758 VirtualKeyboardOnPrimaryRootWindowDefault) {
[email protected]b6ba05d902013-10-04 21:38:45759 if (!SupportsMultipleDisplays())
760 return;
761
762 UpdateDisplay("500x500,500x500");
763
[email protected]c9390bd2013-11-08 20:33:13764 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
[email protected]bf9cdb362013-10-25 19:22:45765 aura::Window* primary_root_window = Shell::GetPrimaryRootWindow();
jamescookb8dcef522016-06-25 14:42:55766 aura::Window* secondary_root_window = root_windows[0] == primary_root_window
767 ? root_windows[1]
768 : root_windows[0];
[email protected]b6ba05d902013-10-04 21:38:45769
[email protected]093b8d642014-04-03 20:59:28770 ASSERT_TRUE(Shell::GetContainer(primary_root_window,
771 kShellWindowId_VirtualKeyboardContainer));
772 ASSERT_FALSE(Shell::GetContainer(secondary_root_window,
773 kShellWindowId_VirtualKeyboardContainer));
[email protected]b6ba05d902013-10-04 21:38:45774}
775
yhanada7e20c9b2016-11-25 00:03:19776// Test for http://crbug.com/303429. Virtual keyboard container should show on
777// a display which has touch capability.
778TEST_F(VirtualKeyboardRootWindowControllerTest,
779 VirtualKeyboardOnTouchableDisplayOnly) {
780 if (!SupportsMultipleDisplays())
781 return;
782
783 UpdateDisplay("500x500,500x500");
784 display::Display secondary_display =
785 Shell::GetInstance()->display_manager()->GetSecondaryDisplay();
786 display::test::DisplayManagerTestApi(Shell::GetInstance()->display_manager())
787 .SetTouchSupport(secondary_display.id(),
788 display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE);
789
790 // The primary display doesn't have touch capability and the secondary display
791 // does.
792 ASSERT_NE(display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE,
793 display::Screen::GetScreen()->GetPrimaryDisplay().touch_support());
794 ASSERT_EQ(display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE,
795 Shell::GetInstance()
796 ->display_manager()
797 ->GetSecondaryDisplay()
798 .touch_support());
799
800 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
801 aura::Window* primary_root_window = Shell::GetPrimaryRootWindow();
802 aura::Window* secondary_root_window = root_windows[0] == primary_root_window
803 ? root_windows[1]
804 : root_windows[0];
805
806 keyboard::KeyboardController::GetInstance()->ShowKeyboard(false);
807 ASSERT_FALSE(Shell::GetContainer(primary_root_window,
808 kShellWindowId_VirtualKeyboardContainer));
809 ASSERT_TRUE(Shell::GetContainer(secondary_root_window,
810 kShellWindowId_VirtualKeyboardContainer));
811
812 // Move the focus to the primary display.
813 aura::Window* focusable_window_in_primary_display =
814 CreateTestWindowInShellWithBounds(
815 primary_root_window->GetBoundsInScreen());
816 ASSERT_EQ(primary_root_window,
817 focusable_window_in_primary_display->GetRootWindow());
818 focusable_window_in_primary_display->Focus();
819 ASSERT_TRUE(focusable_window_in_primary_display->HasFocus());
820
821 // Virtual keyboard shows up on the secondary display even if a window in the
822 // primary screen has the focus.
823 keyboard::KeyboardController::GetInstance()->ShowKeyboard(false);
824 EXPECT_FALSE(Shell::GetContainer(primary_root_window,
825 kShellWindowId_VirtualKeyboardContainer));
826 EXPECT_TRUE(Shell::GetContainer(secondary_root_window,
827 kShellWindowId_VirtualKeyboardContainer));
828}
829
830// Test for http://crbug.com/303429. If both of displays have touch capability,
831// virtual keyboard follows the input focus.
832TEST_F(VirtualKeyboardRootWindowControllerTest, FollowInputFocus) {
833 if (!SupportsMultipleDisplays())
834 return;
835
836 UpdateDisplay("500x500,500x500");
837 const int64_t primary_display_id =
838 display::Screen::GetScreen()->GetPrimaryDisplay().id();
839 display::test::DisplayManagerTestApi(Shell::GetInstance()->display_manager())
840 .SetTouchSupport(primary_display_id,
841 display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE);
842 const int64_t secondary_display_id =
843 Shell::GetInstance()->display_manager()->GetSecondaryDisplay().id();
844 display::test::DisplayManagerTestApi(Shell::GetInstance()->display_manager())
845 .SetTouchSupport(secondary_display_id,
846 display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE);
847
848 // Both of displays have touch capability.
849 ASSERT_EQ(display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE,
850 display::Screen::GetScreen()->GetPrimaryDisplay().touch_support());
851 ASSERT_EQ(display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE,
852 Shell::GetInstance()
853 ->display_manager()
854 ->GetSecondaryDisplay()
855 .touch_support());
856
857 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
858 aura::Window* primary_root_window = Shell::GetPrimaryRootWindow();
859 aura::Window* secondary_root_window = root_windows[0] == primary_root_window
860 ? root_windows[1]
861 : root_windows[0];
862 aura::Window* focusable_window_in_primary_display =
863 CreateTestWindowInShellWithBounds(
864 primary_root_window->GetBoundsInScreen());
865 ASSERT_EQ(primary_root_window,
866 focusable_window_in_primary_display->GetRootWindow());
867 aura::Window* focusable_window_in_secondary_display =
868 CreateTestWindowInShellWithBounds(
869 secondary_root_window->GetBoundsInScreen());
870 ASSERT_EQ(secondary_root_window,
871 focusable_window_in_secondary_display->GetRootWindow());
872
873 keyboard::KeyboardController::GetInstance()->ShowKeyboard(false);
874 EXPECT_TRUE(Shell::GetContainer(primary_root_window,
875 kShellWindowId_VirtualKeyboardContainer));
876 EXPECT_FALSE(Shell::GetContainer(secondary_root_window,
877 kShellWindowId_VirtualKeyboardContainer));
878
879 // Move the focus to the secondary display.
880 focusable_window_in_secondary_display->Focus();
881 ASSERT_TRUE(focusable_window_in_secondary_display->HasFocus());
882
883 keyboard::KeyboardController::GetInstance()->ShowKeyboard(false);
884 ASSERT_FALSE(Shell::GetContainer(primary_root_window,
885 kShellWindowId_VirtualKeyboardContainer));
886 ASSERT_TRUE(Shell::GetContainer(secondary_root_window,
887 kShellWindowId_VirtualKeyboardContainer));
888
889 // Move back focus to the primary display.
890 focusable_window_in_primary_display->Focus();
891 ASSERT_TRUE(focusable_window_in_primary_display->HasFocus());
892
893 keyboard::KeyboardController::GetInstance()->ShowKeyboard(false);
894 EXPECT_TRUE(Shell::GetContainer(primary_root_window,
895 kShellWindowId_VirtualKeyboardContainer));
896 EXPECT_FALSE(Shell::GetContainer(secondary_root_window,
897 kShellWindowId_VirtualKeyboardContainer));
898}
899
900// Test for http://crbug.com/303429. Even if both of display don't have touch
901// capability, the virtual keyboard shows up on the specified display.
902TEST_F(VirtualKeyboardRootWindowControllerTest,
903 VirtualKeyboardShowOnSpecifiedDisplay) {
904 if (!SupportsMultipleDisplays())
905 return;
906
907 UpdateDisplay("500x500,500x500");
908 display::Display secondary_display =
909 Shell::GetInstance()->display_manager()->GetSecondaryDisplay();
910
911 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
912 aura::Window* primary_root_window = Shell::GetPrimaryRootWindow();
913 aura::Window* secondary_root_window = root_windows[0] == primary_root_window
914 ? root_windows[1]
915 : root_windows[0];
916
917 ASSERT_TRUE(Shell::GetContainer(primary_root_window,
918 kShellWindowId_VirtualKeyboardContainer));
919 ASSERT_FALSE(Shell::GetContainer(secondary_root_window,
920 kShellWindowId_VirtualKeyboardContainer));
921
922 const int64_t secondary_display_id = secondary_display.id();
923 keyboard::KeyboardController::GetInstance()->ShowKeyboardInDisplay(
924 secondary_display_id);
925
926 EXPECT_FALSE(Shell::GetContainer(primary_root_window,
927 kShellWindowId_VirtualKeyboardContainer));
928 EXPECT_TRUE(Shell::GetContainer(secondary_root_window,
929 kShellWindowId_VirtualKeyboardContainer));
930}
931
[email protected]eff4c7f2013-08-13 01:45:50932// Test for http://crbug.com/263599. Virtual keyboard should be able to receive
933// events at blocked user session.
934TEST_F(VirtualKeyboardRootWindowControllerTest,
935 ClickVirtualKeyboardInBlockedWindow) {
[email protected]bf9cdb362013-10-25 19:22:45936 aura::Window* root_window = Shell::GetPrimaryRootWindow();
[email protected]093b8d642014-04-03 20:59:28937 aura::Window* keyboard_container =
938 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
[email protected]eff4c7f2013-08-13 01:45:50939 ASSERT_TRUE(keyboard_container);
940 keyboard_container->Show();
941
ben974286a2015-10-10 00:45:12942 aura::Window* keyboard_window =
943 keyboard::KeyboardController::GetInstance()->ui()->GetKeyboardWindow();
[email protected]647b4842013-12-12 14:24:24944 keyboard_container->AddChild(keyboard_window);
[email protected]183e28d2014-01-20 18:18:02945 keyboard_window->set_owned_by_parent(false);
[email protected]647b4842013-12-12 14:24:24946 keyboard_window->SetBounds(gfx::Rect());
[email protected]eff4c7f2013-08-13 01:45:50947 keyboard_window->Show();
[email protected]647b4842013-12-12 14:24:24948
[email protected]3193ea722014-04-23 22:19:19949 ui::test::TestEventHandler handler;
950 root_window->AddPreTargetHandler(&handler);
[email protected]647b4842013-12-12 14:24:24951
[email protected]73c9fd02014-07-28 01:48:52952 ui::test::EventGenerator event_generator(root_window, keyboard_window);
[email protected]eff4c7f2013-08-13 01:45:50953 event_generator.ClickLeftButton();
954 int expected_mouse_presses = 1;
[email protected]3193ea722014-04-23 22:19:19955 EXPECT_EQ(expected_mouse_presses, handler.num_mouse_events() / 2);
[email protected]eff4c7f2013-08-13 01:45:50956
957 for (int block_reason = FIRST_BLOCK_REASON;
jamescookb8dcef522016-06-25 14:42:55958 block_reason < NUMBER_OF_BLOCK_REASONS; ++block_reason) {
[email protected]eff4c7f2013-08-13 01:45:50959 BlockUserSession(static_cast<UserSessionBlockReason>(block_reason));
960 event_generator.ClickLeftButton();
961 expected_mouse_presses++;
[email protected]3193ea722014-04-23 22:19:19962 EXPECT_EQ(expected_mouse_presses, handler.num_mouse_events() / 2);
[email protected]eff4c7f2013-08-13 01:45:50963 UnblockUserSession();
964 }
[email protected]3193ea722014-04-23 22:19:19965 root_window->RemovePreTargetHandler(&handler);
[email protected]eff4c7f2013-08-13 01:45:50966}
967
[email protected]45c66672013-10-01 22:48:56968// Test for http://crbug.com/299787. RootWindowController should delete
969// the old container since the keyboard controller creates a new window in
970// GetWindowContainer().
971TEST_F(VirtualKeyboardRootWindowControllerTest,
972 DeleteOldContainerOnVirtualKeyboardInit) {
[email protected]1025937e2014-02-13 01:25:50973 aura::Window* root_window = Shell::GetPrimaryRootWindow();
[email protected]093b8d642014-04-03 20:59:28974 aura::Window* keyboard_container =
975 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
[email protected]45c66672013-10-01 22:48:56976 ASSERT_TRUE(keyboard_container);
977 // Track the keyboard container window.
978 aura::WindowTracker tracker;
979 tracker.Add(keyboard_container);
jamescook7f99e932016-12-20 18:10:35980 // Reinitialize the keyboard.
981 Shell::GetInstance()->CreateKeyboard();
[email protected]45c66672013-10-01 22:48:56982 // keyboard_container should no longer be present.
983 EXPECT_FALSE(tracker.Contains(keyboard_container));
984}
985
[email protected]1025937e2014-02-13 01:25:50986// Test for crbug.com/342524. After user login, the work space should restore to
987// full screen.
988TEST_F(VirtualKeyboardRootWindowControllerTest, RestoreWorkspaceAfterLogin) {
989 aura::Window* root_window = Shell::GetPrimaryRootWindow();
[email protected]093b8d642014-04-03 20:59:28990 aura::Window* keyboard_container =
991 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
[email protected]1025937e2014-02-13 01:25:50992 keyboard_container->Show();
993 keyboard::KeyboardController* controller =
[email protected]a0b3fb882014-04-07 19:26:03994 keyboard::KeyboardController::GetInstance();
ben974286a2015-10-10 00:45:12995 aura::Window* keyboard_window = controller->ui()->GetKeyboardWindow();
[email protected]1025937e2014-02-13 01:25:50996 keyboard_container->AddChild(keyboard_window);
997 keyboard_window->set_owned_by_parent(false);
bshea0a57802015-04-08 18:21:29998 keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
999 root_window->bounds(), 100));
[email protected]1025937e2014-02-13 01:25:501000 keyboard_window->Show();
1001
oshimaf84b0da722016-04-27 19:47:191002 gfx::Rect before =
1003 display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
[email protected]1025937e2014-02-13 01:25:501004
1005 // Notify keyboard bounds changing.
bshea0a57802015-04-08 18:21:291006 controller->NotifyKeyboardBoundsChanging(keyboard_container->bounds());
[email protected]1025937e2014-02-13 01:25:501007
[email protected]25df7ad2014-04-30 18:10:251008 if (!keyboard::IsKeyboardOverscrollEnabled()) {
oshimaf84b0da722016-04-27 19:47:191009 gfx::Rect after =
1010 display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
[email protected]25df7ad2014-04-30 18:10:251011 EXPECT_LT(after, before);
1012 }
[email protected]1025937e2014-02-13 01:25:501013
1014 // Mock a login user profile change to reinitialize the keyboard.
jamescook7f99e932016-12-20 18:10:351015 mojom::SessionInfoPtr info = mojom::SessionInfo::New();
1016 info->state = session_manager::SessionState::ACTIVE;
1017 WmShell::Get()->session_controller()->SetSessionInfo(std::move(info));
oshimaf84b0da722016-04-27 19:47:191018 EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().work_area(),
1019 before);
[email protected]1025937e2014-02-13 01:25:501020}
1021
[email protected]602022b2014-03-31 17:07:311022// Ensure that system modal dialogs do not block events targeted at the virtual
1023// keyboard.
1024TEST_F(VirtualKeyboardRootWindowControllerTest, ClickWithActiveModalDialog) {
1025 aura::Window* root_window = Shell::GetPrimaryRootWindow();
[email protected]093b8d642014-04-03 20:59:281026 aura::Window* keyboard_container =
1027 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
[email protected]602022b2014-03-31 17:07:311028 ASSERT_TRUE(keyboard_container);
1029 keyboard_container->Show();
1030
ben974286a2015-10-10 00:45:121031 aura::Window* keyboard_window =
1032 keyboard::KeyboardController::GetInstance()->ui()->GetKeyboardWindow();
[email protected]602022b2014-03-31 17:07:311033 keyboard_container->AddChild(keyboard_window);
1034 keyboard_window->set_owned_by_parent(false);
bshea0a57802015-04-08 18:21:291035 keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
1036 root_window->bounds(), 100));
[email protected]3193ea722014-04-23 22:19:191037
1038 ui::test::TestEventHandler handler;
1039 root_window->AddPreTargetHandler(&handler);
[email protected]73c9fd02014-07-28 01:48:521040 ui::test::EventGenerator root_window_event_generator(root_window);
1041 ui::test::EventGenerator keyboard_event_generator(root_window,
1042 keyboard_window);
[email protected]602022b2014-03-31 17:07:311043
jamescookb8dcef522016-06-25 14:42:551044 views::Widget* modal_widget = CreateModalWidget(gfx::Rect(300, 10, 100, 100));
[email protected]602022b2014-03-31 17:07:311045
1046 // Verify that mouse events to the root window are block with a visble modal
1047 // dialog.
1048 root_window_event_generator.ClickLeftButton();
[email protected]3193ea722014-04-23 22:19:191049 EXPECT_EQ(0, handler.num_mouse_events());
[email protected]602022b2014-03-31 17:07:311050
1051 // Verify that event dispatch to the virtual keyboard is unblocked.
1052 keyboard_event_generator.ClickLeftButton();
[email protected]3193ea722014-04-23 22:19:191053 EXPECT_EQ(1, handler.num_mouse_events() / 2);
[email protected]602022b2014-03-31 17:07:311054
1055 modal_widget->Close();
1056
1057 // Verify that mouse events are now unblocked to the root window.
1058 root_window_event_generator.ClickLeftButton();
[email protected]3193ea722014-04-23 22:19:191059 EXPECT_EQ(2, handler.num_mouse_events() / 2);
1060 root_window->RemovePreTargetHandler(&handler);
[email protected]602022b2014-03-31 17:07:311061}
1062
[email protected]2082d7d2014-05-13 14:44:231063// Ensure that the visible area for scrolling the text caret excludes the
1064// region occluded by the on-screen keyboard.
1065TEST_F(VirtualKeyboardRootWindowControllerTest, EnsureCaretInWorkArea) {
1066 keyboard::KeyboardController* keyboard_controller =
1067 keyboard::KeyboardController::GetInstance();
ben974286a2015-10-10 00:45:121068 keyboard::KeyboardUI* ui = keyboard_controller->ui();
[email protected]2082d7d2014-05-13 14:44:231069
1070 MockTextInputClient text_input_client;
ben974286a2015-10-10 00:45:121071 ui::InputMethod* input_method = ui->GetInputMethod();
[email protected]2082d7d2014-05-13 14:44:231072 ASSERT_TRUE(input_method);
shuchen4e09795a2015-06-15 15:07:201073 input_method->SetFocusedTextInputClient(&text_input_client);
[email protected]2082d7d2014-05-13 14:44:231074
1075 aura::Window* root_window = Shell::GetPrimaryRootWindow();
1076 aura::Window* keyboard_container =
1077 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
1078 ASSERT_TRUE(keyboard_container);
1079 keyboard_container->Show();
1080
1081 const int keyboard_height = 100;
ben974286a2015-10-10 00:45:121082 aura::Window* keyboard_window = ui->GetKeyboardWindow();
[email protected]2082d7d2014-05-13 14:44:231083 keyboard_container->AddChild(keyboard_window);
1084 keyboard_window->set_owned_by_parent(false);
bshea0a57802015-04-08 18:21:291085 keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
1086 root_window->bounds(), keyboard_height));
[email protected]2082d7d2014-05-13 14:44:231087
ben974286a2015-10-10 00:45:121088 ui->EnsureCaretInWorkArea();
bshea0a57802015-04-08 18:21:291089 ASSERT_EQ(root_window->bounds().width(),
yhanada0ddd3462016-12-08 05:04:181090 text_input_client.caret_exclude_rect().width());
1091 ASSERT_EQ(keyboard_height, text_input_client.caret_exclude_rect().height());
[email protected]00a386792014-06-16 15:09:201092
shuchen4e09795a2015-06-15 15:07:201093 input_method->SetFocusedTextInputClient(NULL);
[email protected]2082d7d2014-05-13 14:44:231094}
1095
yhanada0ddd3462016-12-08 05:04:181096TEST_F(VirtualKeyboardRootWindowControllerTest,
1097 EnsureCaretInWorkAreaWithMultipleDisplays) {
1098 if (!SupportsMultipleDisplays())
1099 return;
1100
1101 UpdateDisplay("500x500,600x600");
1102 const int64_t primary_display_id =
1103 display::Screen::GetScreen()->GetPrimaryDisplay().id();
1104 const int64_t secondary_display_id =
1105 Shell::GetInstance()->display_manager()->GetSecondaryDisplay().id();
1106 ASSERT_NE(primary_display_id, secondary_display_id);
1107
1108 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1109 ASSERT_EQ(static_cast<size_t>(2), root_windows.size());
1110 aura::Window* primary_root_window = root_windows[0];
1111 aura::Window* secondary_root_window = root_windows[1];
1112
1113 keyboard::KeyboardController* keyboard_controller =
1114 keyboard::KeyboardController::GetInstance();
1115 keyboard::KeyboardUI* ui = keyboard_controller->ui();
1116
1117 MockTextInputClient text_input_client;
1118 ui::InputMethod* input_method = ui->GetInputMethod();
1119 ASSERT_TRUE(input_method);
1120 input_method->SetFocusedTextInputClient(&text_input_client);
1121
1122 const int keyboard_height = 100;
1123 // Check that the keyboard on the primary screen doesn't cover the window on
1124 // the secondary screen.
1125 aura::Window* keyboard_container = Shell::GetContainer(
1126 primary_root_window, kShellWindowId_VirtualKeyboardContainer);
1127 ASSERT_TRUE(keyboard_container);
1128 keyboard_container->Show();
1129 aura::Window* keyboard_window = ui->GetKeyboardWindow();
1130 keyboard_container->AddChild(keyboard_window);
1131 keyboard_window->set_owned_by_parent(false);
1132 keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
1133 primary_root_window->bounds(), keyboard_height));
1134
1135 EXPECT_TRUE(primary_root_window->GetBoundsInScreen().Contains(
1136 text_input_client.caret_exclude_rect()));
1137 EXPECT_FALSE(secondary_root_window->GetBoundsInScreen().Contains(
1138 text_input_client.caret_exclude_rect()));
1139
1140 // Move the keyboard into the secondary display and check that the keyboard
1141 // doesn't cover the window on the primary screen.
1142 keyboard_controller->ShowKeyboardInDisplay(secondary_display_id);
1143 keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
1144 secondary_root_window->bounds(), keyboard_height));
1145
1146 ui->EnsureCaretInWorkArea();
1147 EXPECT_FALSE(primary_root_window->GetBoundsInScreen().Contains(
1148 text_input_client.caret_exclude_rect()));
1149 EXPECT_TRUE(secondary_root_window->GetBoundsInScreen().Contains(
1150 text_input_client.caret_exclude_rect()));
1151
1152 input_method->SetFocusedTextInputClient(nullptr);
1153}
1154
kevers23f3987d2014-09-17 13:50:121155// Tests that the virtual keyboard does not block context menus. The virtual
1156// keyboard should appear in front of most content, but not context menus. See
1157// crbug/377180.
1158TEST_F(VirtualKeyboardRootWindowControllerTest, ZOrderTest) {
1159 UpdateDisplay("800x600");
1160 keyboard::KeyboardController* keyboard_controller =
1161 keyboard::KeyboardController::GetInstance();
ben974286a2015-10-10 00:45:121162 keyboard::KeyboardUI* ui = keyboard_controller->ui();
kevers23f3987d2014-09-17 13:50:121163
1164 aura::Window* root_window = Shell::GetPrimaryRootWindow();
1165 aura::Window* keyboard_container =
1166 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
1167 ASSERT_TRUE(keyboard_container);
1168 keyboard_container->Show();
1169
1170 const int keyboard_height = 200;
ben974286a2015-10-10 00:45:121171 aura::Window* keyboard_window = ui->GetKeyboardWindow();
kevers23f3987d2014-09-17 13:50:121172 keyboard_container->AddChild(keyboard_window);
1173 keyboard_window->set_owned_by_parent(false);
bshea0a57802015-04-08 18:21:291174 gfx::Rect keyboard_bounds = keyboard::FullWidthKeyboardBoundsFromRootBounds(
1175 root_window->bounds(), keyboard_height);
kevers23f3987d2014-09-17 13:50:121176 keyboard_window->SetBounds(keyboard_bounds);
1177 keyboard_window->Show();
1178
1179 ui::test::EventGenerator generator(root_window);
1180
1181 // Cover the screen with two windows: a normal window on the left side and a
1182 // context menu on the right side. When the virtual keyboard is displayed it
1183 // partially occludes the normal window, but not the context menu. Compute
1184 // positions for generating synthetic click events to perform hit tests,
1185 // ensuring the correct window layering. 'top' is above the VK, whereas
1186 // 'bottom' lies within the VK. 'left' is centered in the normal window, and
1187 // 'right' is centered in the context menu.
1188 int window_height = keyboard_bounds.bottom();
1189 int window_width = keyboard_bounds.width() / 2;
1190 int left = window_width / 2;
1191 int right = 3 * window_width / 2;
1192 int top = keyboard_bounds.y() / 2;
1193 int bottom = window_height - keyboard_height / 2;
1194
1195 // Normal window is partially occluded by the virtual keyboard.
1196 aura::test::TestWindowDelegate delegate;
dchenga94547472016-04-08 08:41:111197 std::unique_ptr<aura::Window> normal(
1198 CreateTestWindowInShellWithDelegateAndType(
1199 &delegate, ui::wm::WINDOW_TYPE_NORMAL, 0,
1200 gfx::Rect(0, 0, window_width, window_height)));
kevers23f3987d2014-09-17 13:50:121201 normal->set_owned_by_parent(false);
1202 normal->Show();
1203 TargetHitTestEventHandler normal_handler;
1204 normal->AddPreTargetHandler(&normal_handler);
1205
1206 // Test that only the click on the top portion of the window is picked up. The
1207 // click on the bottom hits the virtual keyboard instead.
1208 generator.MoveMouseTo(left, top);
1209 generator.ClickLeftButton();
1210 EXPECT_EQ(1, normal_handler.num_mouse_events());
1211 generator.MoveMouseTo(left, bottom);
1212 generator.ClickLeftButton();
1213 EXPECT_EQ(1, normal_handler.num_mouse_events());
1214
1215 // Menu overlaps virtual keyboard.
1216 aura::test::TestWindowDelegate delegate2;
dchenga94547472016-04-08 08:41:111217 std::unique_ptr<aura::Window> menu(CreateTestWindowInShellWithDelegateAndType(
1218 &delegate2, ui::wm::WINDOW_TYPE_MENU, 0,
kevers23f3987d2014-09-17 13:50:121219 gfx::Rect(window_width, 0, window_width, window_height)));
1220 menu->set_owned_by_parent(false);
1221 menu->Show();
1222 TargetHitTestEventHandler menu_handler;
1223 menu->AddPreTargetHandler(&menu_handler);
1224
1225 // Test that both clicks register.
1226 generator.MoveMouseTo(right, top);
1227 generator.ClickLeftButton();
1228 EXPECT_EQ(1, menu_handler.num_mouse_events());
1229 generator.MoveMouseTo(right, bottom);
1230 generator.ClickLeftButton();
1231 EXPECT_EQ(2, menu_handler.num_mouse_events());
1232
1233 // Cleanup to ensure that the test windows are destroyed before their
1234 // delegates.
1235 normal.reset();
1236 menu.reset();
1237}
1238
kevers0e450492014-09-30 16:02:311239// Tests that the virtual keyboard correctly resizes with a change to display
1240// orientation. See crbug/417612.
jamescook01bf23e72017-01-09 19:58:151241TEST_F(VirtualKeyboardRootWindowControllerTest, DisplayRotation) {
kevers0e450492014-09-30 16:02:311242 UpdateDisplay("800x600");
1243 aura::Window* root_window = Shell::GetPrimaryRootWindow();
1244 aura::Window* keyboard_container =
1245 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
1246 ASSERT_TRUE(keyboard_container);
bshea0a57802015-04-08 18:21:291247 keyboard::KeyboardController* keyboard_controller =
1248 keyboard::KeyboardController::GetInstance();
1249 keyboard_controller->ShowKeyboard(false);
ben974286a2015-10-10 00:45:121250 keyboard_controller->ui()->GetKeyboardWindow()->SetBounds(
bshea0a57802015-04-08 18:21:291251 gfx::Rect(0, 400, 800, 200));
1252 EXPECT_EQ("0,400 800x200", keyboard_container->bounds().ToString());
kevers0e450492014-09-30 16:02:311253
1254 UpdateDisplay("600x800");
bshea0a57802015-04-08 18:21:291255 EXPECT_EQ("0,600 600x200", keyboard_container->bounds().ToString());
kevers0e450492014-09-30 16:02:311256}
1257
[email protected]f1853122012-06-27 16:21:261258} // namespace test
1259} // namespace ash