blob: 4d33dee044f5f92312abd25a25a08660aabc9b4a [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
jamescooke3d63f62017-01-12 07:12:409#include "ash/common/session/session_controller.h"
jamescook2b624c5a2016-06-08 01:34:0210#include "ash/common/session/session_state_delegate.h"
jamescook2a4d1eb2016-06-09 20:10:0711#include "ash/common/system/tray/system_tray_delegate.h"
skyea4ca942016-09-12 21:56:1912#include "ash/common/wm/system_modal_container_layout_manager.h"
skyd6063772016-06-01 17:52:2113#include "ash/common/wm/window_state.h"
skyea4ca942016-09-12 21:56:1914#include "ash/common/wm_lookup.h"
jamescook443e42d2016-06-10 21:44:4615#include "ash/common/wm_shell.h"
skyea4ca942016-09-12 21:56:1916#include "ash/common/wm_window.h"
jamescook8800b8232016-10-19 12:46:2717#include "ash/public/cpp/shell_window_ids.h"
[email protected]f1853122012-06-27 16:21:2618#include "ash/shell.h"
[email protected]f1853122012-06-27 16:21:2619#include "ash/test/ash_test_base.h"
[email protected]2ee2f5d2013-01-10 23:37:1620#include "ash/wm/window_properties.h"
sky8d5646fe2016-04-15 17:03:4621#include "ash/wm/window_state_aura.h"
[email protected]f1853122012-06-27 16:21:2622#include "ash/wm/window_util.h"
[email protected]eff4c7f2013-08-13 01:45:5023#include "base/command_line.h"
[email protected]792b9b12012-12-11 03:53:2724#include "ui/aura/client/focus_change_observer.h"
[email protected]8cfb6722012-11-28 03:28:4625#include "ui/aura/client/focus_client.h"
sky28f20d62016-10-20 23:21:5926#include "ui/aura/client/window_parenting_client.h"
[email protected]f1853122012-06-27 16:21:2627#include "ui/aura/env.h"
[email protected]dbf835d82012-09-11 18:23:0928#include "ui/aura/test/test_window_delegate.h"
29#include "ui/aura/test/test_windows.h"
[email protected]f1853122012-06-27 16:21:2630#include "ui/aura/window.h"
[email protected]fcc51c952014-02-21 21:31:2631#include "ui/aura/window_event_dispatcher.h"
[email protected]dbf835d82012-09-11 18:23:0932#include "ui/aura/window_tracker.h"
[email protected]2082d7d2014-05-13 14:44:2333#include "ui/base/ime/dummy_text_input_client.h"
34#include "ui/base/ime/input_method.h"
35#include "ui/base/ime/text_input_client.h"
rjkroege72f8154f2016-10-29 00:49:0236#include "ui/display/manager/display_manager.h"
yhanada7e20c9b2016-11-25 00:03:1937#include "ui/display/test/display_manager_test_api.h"
38#include "ui/events/devices/device_data_manager.h"
39#include "ui/events/devices/touchscreen_device.h"
[email protected]73c9fd02014-07-28 01:48:5240#include "ui/events/test/event_generator.h"
[email protected]cd9f71d2014-03-20 21:54:2141#include "ui/events/test/test_event_handler.h"
jamescookcf8b648f2016-06-01 19:58:1742#include "ui/keyboard/keyboard_controller.h"
[email protected]eff4c7f2013-08-13 01:45:5043#include "ui/keyboard/keyboard_switches.h"
ben974286a2015-10-10 00:45:1244#include "ui/keyboard/keyboard_ui.h"
[email protected]39e95212014-04-23 20:00:0145#include "ui/keyboard/keyboard_util.h"
[email protected]f1853122012-06-27 16:21:2646#include "ui/views/controls/menu/menu_controller.h"
47#include "ui/views/widget/widget.h"
48#include "ui/views/widget/widget_delegate.h"
49
[email protected]2ee2f5d2013-01-10 23:37:1650using aura::Window;
51using views::Widget;
52
[email protected]f1853122012-06-27 16:21:2653namespace ash {
54namespace {
55
56class TestDelegate : public views::WidgetDelegateView {
57 public:
58 explicit TestDelegate(bool system_modal) : system_modal_(system_modal) {}
dcheng1f4538e2014-10-27 23:57:0559 ~TestDelegate() override {}
[email protected]f1853122012-06-27 16:21:2660
61 // Overridden from views::WidgetDelegate:
dcheng1f4538e2014-10-27 23:57:0562 ui::ModalType GetModalType() const override {
[email protected]f1853122012-06-27 16:21:2663 return system_modal_ ? ui::MODAL_TYPE_SYSTEM : ui::MODAL_TYPE_NONE;
64 }
65
66 private:
67 bool system_modal_;
[email protected]0fbfa972013-10-02 19:23:3368
[email protected]f1853122012-06-27 16:21:2669 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
70};
71
[email protected]792b9b12012-12-11 03:53:2772class DeleteOnBlurDelegate : public aura::test::TestWindowDelegate,
73 public aura::client::FocusChangeObserver {
[email protected]dbf835d82012-09-11 18:23:0974 public:
75 DeleteOnBlurDelegate() : window_(NULL) {}
dcheng1f4538e2014-10-27 23:57:0576 ~DeleteOnBlurDelegate() override {}
[email protected]dbf835d82012-09-11 18:23:0977
[email protected]792b9b12012-12-11 03:53:2778 void SetWindow(aura::Window* window) {
79 window_ = window;
80 aura::client::SetFocusChangeObserver(window_, this);
81 }
[email protected]dbf835d82012-09-11 18:23:0982
[email protected]869f6352012-12-06 20:47:1783 private:
[email protected]dbf835d82012-09-11 18:23:0984 // aura::test::TestWindowDelegate overrides:
dcheng1f4538e2014-10-27 23:57:0585 bool CanFocus() override { return true; }
[email protected]dbf835d82012-09-11 18:23:0986
[email protected]792b9b12012-12-11 03:53:2787 // aura::client::FocusChangeObserver implementation:
dcheng1f4538e2014-10-27 23:57:0588 void OnWindowFocused(aura::Window* gained_focus,
89 aura::Window* lost_focus) override {
[email protected]792b9b12012-12-11 03:53:2790 if (window_ == lost_focus)
91 delete window_;
[email protected]869f6352012-12-06 20:47:1792 }
93
[email protected]dbf835d82012-09-11 18:23:0994 aura::Window* window_;
95
96 DISALLOW_COPY_AND_ASSIGN(DeleteOnBlurDelegate);
97};
98
skyb6643832017-01-11 22:08:4599WmLayoutManager* GetLayoutManager(RootWindowController* controller, int id) {
sky5dbc91d52017-01-13 00:26:14100 return WmWindow::Get(controller->GetContainer(id))->GetLayoutManager();
skyb6643832017-01-11 22:08:45101}
102
[email protected]f1853122012-06-27 16:21:26103} // namespace
104
105namespace test {
[email protected]f1853122012-06-27 16:21:26106
estadea23d6ceb2017-02-15 00:47:09107class RootWindowControllerTest : public AshTestBase {
[email protected]a2e6af12013-01-07 21:40:35108 public:
109 views::Widget* CreateTestWidget(const gfx::Rect& bounds) {
110 views::Widget* widget = views::Widget::CreateWindowWithContextAndBounds(
111 NULL, CurrentContext(), bounds);
112 widget->Show();
113 return widget;
114 }
115
116 views::Widget* CreateModalWidget(const gfx::Rect& bounds) {
117 views::Widget* widget = views::Widget::CreateWindowWithContextAndBounds(
118 new TestDelegate(true), CurrentContext(), bounds);
119 widget->Show();
120 return widget;
121 }
122
123 views::Widget* CreateModalWidgetWithParent(const gfx::Rect& bounds,
124 gfx::NativeWindow parent) {
jamescookb8dcef522016-06-25 14:42:55125 views::Widget* widget = views::Widget::CreateWindowWithParentAndBounds(
126 new TestDelegate(true), parent, bounds);
[email protected]a2e6af12013-01-07 21:40:35127 widget->Show();
128 return widget;
129 }
130
[email protected]c9390bd2013-11-08 20:33:13131 aura::Window* GetModalContainer(aura::Window* root_window) {
[email protected]093b8d642014-04-03 20:59:28132 return Shell::GetContainer(root_window,
mswbc0a8b482016-06-30 02:21:14133 kShellWindowId_SystemModalContainer);
[email protected]a2e6af12013-01-07 21:40:35134 }
135};
[email protected]f1853122012-06-27 16:21:26136
estadea23d6ceb2017-02-15 00:47:09137TEST_F(RootWindowControllerTest, MoveWindows_Basic) {
[email protected]2816c2462013-12-17 02:22:25138 // Windows origin should be doubled when moved to the 1st display.
139 UpdateDisplay("600x600,300x300");
[email protected]c9390bd2013-11-08 20:33:13140 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
[email protected]f1853122012-06-27 16:21:26141
142 views::Widget* normal = CreateTestWidget(gfx::Rect(650, 10, 100, 100));
143 EXPECT_EQ(root_windows[1], normal->GetNativeView()->GetRootWindow());
[email protected]e2f64d102012-07-19 19:17:04144 EXPECT_EQ("650,10 100x100", normal->GetWindowBoundsInScreen().ToString());
[email protected]8d625fb2012-07-18 16:40:06145 EXPECT_EQ("50,10 100x100",
[email protected]e2f64d102012-07-19 19:17:04146 normal->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]f1853122012-06-27 16:21:26147
148 views::Widget* maximized = CreateTestWidget(gfx::Rect(700, 10, 100, 100));
149 maximized->Maximize();
150 EXPECT_EQ(root_windows[1], maximized->GetNativeView()->GetRootWindow());
estadea23d6ceb2017-02-15 00:47:09151 EXPECT_EQ(gfx::Rect(600, 0, 300, 252).ToString(),
tdanderson0b7905b2016-06-22 21:53:03152 maximized->GetWindowBoundsInScreen().ToString());
estadea23d6ceb2017-02-15 00:47:09153 EXPECT_EQ(gfx::Rect(0, 0, 300, 252).ToString(),
[email protected]8c0ec432013-05-10 04:33:39154 maximized->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]f1853122012-06-27 16:21:26155
156 views::Widget* minimized = CreateTestWidget(gfx::Rect(800, 10, 100, 100));
157 minimized->Minimize();
158 EXPECT_EQ(root_windows[1], minimized->GetNativeView()->GetRootWindow());
jamescookb8dcef522016-06-25 14:42:55159 EXPECT_EQ("800,10 100x100", minimized->GetWindowBoundsInScreen().ToString());
[email protected]f1853122012-06-27 16:21:26160
[email protected]2816c2462013-12-17 02:22:25161 views::Widget* fullscreen = CreateTestWidget(gfx::Rect(850, 10, 100, 100));
[email protected]f1853122012-06-27 16:21:26162 fullscreen->SetFullscreen(true);
163 EXPECT_EQ(root_windows[1], fullscreen->GetNativeView()->GetRootWindow());
[email protected]1a015382012-12-01 19:44:59164
jamescookb8dcef522016-06-25 14:42:55165 EXPECT_EQ("600,0 300x300", fullscreen->GetWindowBoundsInScreen().ToString());
[email protected]2816c2462013-12-17 02:22:25166 EXPECT_EQ("0,0 300x300",
[email protected]e2f64d102012-07-19 19:17:04167 fullscreen->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]f1853122012-06-27 16:21:26168
[email protected]8f2f151412013-01-26 03:58:37169 views::Widget* unparented_control = new Widget;
170 Widget::InitParams params;
171 params.bounds = gfx::Rect(650, 10, 100, 100);
172 params.context = CurrentContext();
173 params.type = Widget::InitParams::TYPE_CONTROL;
174 unparented_control->Init(params);
175 EXPECT_EQ(root_windows[1],
176 unparented_control->GetNativeView()->GetRootWindow());
[email protected]093b8d642014-04-03 20:59:28177 EXPECT_EQ(kShellWindowId_UnparentedControlContainer,
[email protected]8f2f151412013-01-26 03:58:37178 unparented_control->GetNativeView()->parent()->id());
179
[email protected]95db9c12013-01-31 11:47:44180 aura::Window* panel = CreateTestWindowInShellWithDelegateAndType(
[email protected]5b251f12013-12-19 01:50:05181 NULL, ui::wm::WINDOW_TYPE_PANEL, 0, gfx::Rect(700, 100, 100, 100));
[email protected]95db9c12013-01-31 11:47:44182 EXPECT_EQ(root_windows[1], panel->GetRootWindow());
[email protected]093b8d642014-04-03 20:59:28183 EXPECT_EQ(kShellWindowId_PanelContainer, panel->parent()->id());
[email protected]95db9c12013-01-31 11:47:44184
[email protected]dbf835d82012-09-11 18:23:09185 // Make sure a window that will delete itself when losing focus
186 // will not crash.
187 aura::WindowTracker tracker;
188 DeleteOnBlurDelegate delete_on_blur_delegate;
[email protected]5ebe6102012-11-28 21:00:03189 aura::Window* d2 = CreateTestWindowInShellWithDelegate(
190 &delete_on_blur_delegate, 0, gfx::Rect(50, 50, 100, 100));
[email protected]792b9b12012-12-11 03:53:27191 delete_on_blur_delegate.SetWindow(d2);
[email protected]550543e2013-01-11 22:43:44192 aura::client::GetFocusClient(root_windows[0])->FocusWindow(d2);
[email protected]dbf835d82012-09-11 18:23:09193 tracker.Add(d2);
194
[email protected]f634dd32012-07-23 22:49:07195 UpdateDisplay("600x600");
[email protected]f1853122012-06-27 16:21:26196
[email protected]dbf835d82012-09-11 18:23:09197 // d2 must have been deleted.
198 EXPECT_FALSE(tracker.Contains(d2));
199
[email protected]f1853122012-06-27 16:21:26200 EXPECT_EQ(root_windows[0], normal->GetNativeView()->GetRootWindow());
[email protected]2816c2462013-12-17 02:22:25201 EXPECT_EQ("100,20 100x100", normal->GetWindowBoundsInScreen().ToString());
202 EXPECT_EQ("100,20 100x100",
[email protected]e2f64d102012-07-19 19:17:04203 normal->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]f1853122012-06-27 16:21:26204
yiyix20e7d3f2016-06-14 21:49:36205 // Maximized area on primary display has 47px for non-md and 48px for md
mswbc0a8b482016-06-30 02:21:14206 // (defined in SHELF_SIZE) inset at the bottom.
[email protected]2a64b0a2013-07-23 23:15:54207
208 // First clear fullscreen status, since both fullscreen and maximized windows
209 // share the same desktop workspace, which cancels the shelf status.
210 fullscreen->SetFullscreen(false);
[email protected]f1853122012-06-27 16:21:26211 EXPECT_EQ(root_windows[0], maximized->GetNativeView()->GetRootWindow());
estadea23d6ceb2017-02-15 00:47:09212 EXPECT_EQ(gfx::Rect(0, 0, 600, 552).ToString(),
tdanderson0b7905b2016-06-22 21:53:03213 maximized->GetWindowBoundsInScreen().ToString());
estadea23d6ceb2017-02-15 00:47:09214 EXPECT_EQ(gfx::Rect(0, 0, 600, 552).ToString(),
[email protected]e2f64d102012-07-19 19:17:04215 maximized->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]f1853122012-06-27 16:21:26216
oshima5594d1232015-12-04 18:58:38217 // Set fullscreen to true, but maximized window's size won't change because
218 // it's not visible. see crbug.com/504299.
[email protected]2a64b0a2013-07-23 23:15:54219 fullscreen->SetFullscreen(true);
220 EXPECT_EQ(root_windows[0], maximized->GetNativeView()->GetRootWindow());
estadea23d6ceb2017-02-15 00:47:09221 EXPECT_EQ(gfx::Rect(0, 0, 600, 552).ToString(),
tdanderson0b7905b2016-06-22 21:53:03222 maximized->GetWindowBoundsInScreen().ToString());
estadea23d6ceb2017-02-15 00:47:09223 EXPECT_EQ(gfx::Rect(0, 0, 600, 552).ToString(),
[email protected]2a64b0a2013-07-23 23:15:54224 maximized->GetNativeView()->GetBoundsInRootWindow().ToString());
225
[email protected]f1853122012-06-27 16:21:26226 EXPECT_EQ(root_windows[0], minimized->GetNativeView()->GetRootWindow());
jamescookb8dcef522016-06-25 14:42:55227 EXPECT_EQ("400,20 100x100", minimized->GetWindowBoundsInScreen().ToString());
[email protected]f1853122012-06-27 16:21:26228
229 EXPECT_EQ(root_windows[0], fullscreen->GetNativeView()->GetRootWindow());
230 EXPECT_TRUE(fullscreen->IsFullscreen());
jamescookb8dcef522016-06-25 14:42:55231 EXPECT_EQ("0,0 600x600", fullscreen->GetWindowBoundsInScreen().ToString());
[email protected]8d625fb2012-07-18 16:40:06232 EXPECT_EQ("0,0 600x600",
[email protected]e2f64d102012-07-19 19:17:04233 fullscreen->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]8d625fb2012-07-18 16:40:06234
235 // Test if the restore bounds are correctly updated.
[email protected]a41b4e12013-09-20 04:36:34236 wm::GetWindowState(maximized->GetNativeView())->Restore();
[email protected]2816c2462013-12-17 02:22:25237 EXPECT_EQ("200,20 100x100", maximized->GetWindowBoundsInScreen().ToString());
238 EXPECT_EQ("200,20 100x100",
[email protected]e2f64d102012-07-19 19:17:04239 maximized->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]8d625fb2012-07-18 16:40:06240
241 fullscreen->SetFullscreen(false);
jamescookb8dcef522016-06-25 14:42:55242 EXPECT_EQ("500,20 100x100", fullscreen->GetWindowBoundsInScreen().ToString());
[email protected]2816c2462013-12-17 02:22:25243 EXPECT_EQ("500,20 100x100",
[email protected]e2f64d102012-07-19 19:17:04244 fullscreen->GetNativeView()->GetBoundsInRootWindow().ToString());
[email protected]8f2f151412013-01-26 03:58:37245
246 // Test if the unparented widget has moved.
247 EXPECT_EQ(root_windows[0],
248 unparented_control->GetNativeView()->GetRootWindow());
[email protected]093b8d642014-04-03 20:59:28249 EXPECT_EQ(kShellWindowId_UnparentedControlContainer,
[email protected]8f2f151412013-01-26 03:58:37250 unparented_control->GetNativeView()->parent()->id());
[email protected]95db9c12013-01-31 11:47:44251
252 // Test if the panel has moved.
253 EXPECT_EQ(root_windows[0], panel->GetRootWindow());
[email protected]093b8d642014-04-03 20:59:28254 EXPECT_EQ(kShellWindowId_PanelContainer, panel->parent()->id());
[email protected]f1853122012-06-27 16:21:26255}
256
estadea23d6ceb2017-02-15 00:47:09257TEST_F(RootWindowControllerTest, MoveWindows_Modal) {
[email protected]f634dd32012-07-23 22:49:07258 UpdateDisplay("500x500,500x500");
[email protected]f1853122012-06-27 16:21:26259
[email protected]c9390bd2013-11-08 20:33:13260 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
[email protected]f1853122012-06-27 16:21:26261 // Emulate virtual screen coordinate system.
262 root_windows[0]->SetBounds(gfx::Rect(0, 0, 500, 500));
263 root_windows[1]->SetBounds(gfx::Rect(500, 0, 500, 500));
264
265 views::Widget* normal = CreateTestWidget(gfx::Rect(300, 10, 100, 100));
266 EXPECT_EQ(root_windows[0], normal->GetNativeView()->GetRootWindow());
267 EXPECT_TRUE(wm::IsActiveWindow(normal->GetNativeView()));
268
269 views::Widget* modal = CreateModalWidget(gfx::Rect(650, 10, 100, 100));
270 EXPECT_EQ(root_windows[1], modal->GetNativeView()->GetRootWindow());
jamescookb8dcef522016-06-25 14:42:55271 EXPECT_TRUE(
272 GetModalContainer(root_windows[1])->Contains(modal->GetNativeView()));
[email protected]f1853122012-06-27 16:21:26273 EXPECT_TRUE(wm::IsActiveWindow(modal->GetNativeView()));
274
[email protected]73c9fd02014-07-28 01:48:52275 ui::test::EventGenerator generator_1st(root_windows[0]);
[email protected]f1853122012-06-27 16:21:26276 generator_1st.ClickLeftButton();
277 EXPECT_TRUE(wm::IsActiveWindow(modal->GetNativeView()));
278
[email protected]f634dd32012-07-23 22:49:07279 UpdateDisplay("500x500");
[email protected]f1853122012-06-27 16:21:26280 EXPECT_EQ(root_windows[0], modal->GetNativeView()->GetRootWindow());
281 EXPECT_TRUE(wm::IsActiveWindow(modal->GetNativeView()));
282 generator_1st.ClickLeftButton();
283 EXPECT_TRUE(wm::IsActiveWindow(modal->GetNativeView()));
284}
285
oshima022a9542015-05-01 00:15:02286// Make sure lock related windows moves.
estadea23d6ceb2017-02-15 00:47:09287TEST_F(RootWindowControllerTest, MoveWindows_LockWindowsInUnified) {
rjkroege72f8154f2016-10-29 00:49:02288 display_manager()->SetUnifiedDesktopEnabled(true);
oshimabba2d992015-05-22 19:21:39289
oshima022a9542015-05-01 00:15:02290 UpdateDisplay("500x500");
291 const int kLockScreenWindowId = 1000;
msw607227f82016-08-30 17:22:39292 const int kLockWallpaperWindowId = 1001;
oshima022a9542015-05-01 00:15:02293
mswbc0a8b482016-06-30 02:21:14294 RootWindowController* controller = Shell::GetPrimaryRootWindowController();
oshima022a9542015-05-01 00:15:02295
296 aura::Window* lock_container =
297 controller->GetContainer(kShellWindowId_LockScreenContainer);
msw607227f82016-08-30 17:22:39298 aura::Window* lock_wallpaper_container =
299 controller->GetContainer(kShellWindowId_LockScreenWallpaperContainer);
oshima022a9542015-05-01 00:15:02300
301 views::Widget* lock_screen =
302 CreateModalWidgetWithParent(gfx::Rect(10, 10, 100, 100), lock_container);
303 lock_screen->GetNativeWindow()->set_id(kLockScreenWindowId);
304 lock_screen->SetFullscreen(true);
305
msw607227f82016-08-30 17:22:39306 views::Widget* lock_wallpaper = CreateModalWidgetWithParent(
307 gfx::Rect(10, 10, 100, 100), lock_wallpaper_container);
308 lock_wallpaper->GetNativeWindow()->set_id(kLockWallpaperWindowId);
oshima022a9542015-05-01 00:15:02309
310 ASSERT_EQ(lock_screen->GetNativeWindow(),
311 controller->GetRootWindow()->GetChildById(kLockScreenWindowId));
msw607227f82016-08-30 17:22:39312 ASSERT_EQ(lock_wallpaper->GetNativeWindow(),
313 controller->GetRootWindow()->GetChildById(kLockWallpaperWindowId));
oshima022a9542015-05-01 00:15:02314 EXPECT_EQ("0,0 500x500", lock_screen->GetNativeWindow()->bounds().ToString());
315
316 // Switch to unified.
317 UpdateDisplay("500x500,500x500");
318
319 // In unified mode, RWC is created
mswbc0a8b482016-06-30 02:21:14320 controller = Shell::GetPrimaryRootWindowController();
oshima022a9542015-05-01 00:15:02321
322 ASSERT_EQ(lock_screen->GetNativeWindow(),
323 controller->GetRootWindow()->GetChildById(kLockScreenWindowId));
msw607227f82016-08-30 17:22:39324 ASSERT_EQ(lock_wallpaper->GetNativeWindow(),
325 controller->GetRootWindow()->GetChildById(kLockWallpaperWindowId));
oshima96f6a502015-05-02 08:43:32326 EXPECT_EQ("0,0 500x500", lock_screen->GetNativeWindow()->bounds().ToString());
oshima022a9542015-05-01 00:15:02327
328 // Switch to mirror.
rjkroege72f8154f2016-10-29 00:49:02329 display_manager()->SetMirrorMode(true);
330 EXPECT_TRUE(display_manager()->IsInMirrorMode());
oshima022a9542015-05-01 00:15:02331
mswbc0a8b482016-06-30 02:21:14332 controller = Shell::GetPrimaryRootWindowController();
oshima022a9542015-05-01 00:15:02333 ASSERT_EQ(lock_screen->GetNativeWindow(),
334 controller->GetRootWindow()->GetChildById(kLockScreenWindowId));
msw607227f82016-08-30 17:22:39335 ASSERT_EQ(lock_wallpaper->GetNativeWindow(),
336 controller->GetRootWindow()->GetChildById(kLockWallpaperWindowId));
oshima022a9542015-05-01 00:15:02337 EXPECT_EQ("0,0 500x500", lock_screen->GetNativeWindow()->bounds().ToString());
338
339 // Switch to unified.
rjkroege72f8154f2016-10-29 00:49:02340 display_manager()->SetMirrorMode(false);
341 EXPECT_TRUE(display_manager()->IsInUnifiedMode());
oshima022a9542015-05-01 00:15:02342
mswbc0a8b482016-06-30 02:21:14343 controller = Shell::GetPrimaryRootWindowController();
oshima022a9542015-05-01 00:15:02344
345 ASSERT_EQ(lock_screen->GetNativeWindow(),
346 controller->GetRootWindow()->GetChildById(kLockScreenWindowId));
msw607227f82016-08-30 17:22:39347 ASSERT_EQ(lock_wallpaper->GetNativeWindow(),
348 controller->GetRootWindow()->GetChildById(kLockWallpaperWindowId));
oshima96f6a502015-05-02 08:43:32349 EXPECT_EQ("0,0 500x500", lock_screen->GetNativeWindow()->bounds().ToString());
oshima022a9542015-05-01 00:15:02350
351 // Switch to single display.
352 UpdateDisplay("600x500");
rjkroege72f8154f2016-10-29 00:49:02353 EXPECT_FALSE(display_manager()->IsInUnifiedMode());
354 EXPECT_FALSE(display_manager()->IsInMirrorMode());
oshima022a9542015-05-01 00:15:02355
mswbc0a8b482016-06-30 02:21:14356 controller = Shell::GetPrimaryRootWindowController();
oshima022a9542015-05-01 00:15:02357
358 ASSERT_EQ(lock_screen->GetNativeWindow(),
359 controller->GetRootWindow()->GetChildById(kLockScreenWindowId));
msw607227f82016-08-30 17:22:39360 ASSERT_EQ(lock_wallpaper->GetNativeWindow(),
361 controller->GetRootWindow()->GetChildById(kLockWallpaperWindowId));
oshima022a9542015-05-01 00:15:02362 EXPECT_EQ("0,0 600x500", lock_screen->GetNativeWindow()->bounds().ToString());
363}
364
estadea23d6ceb2017-02-15 00:47:09365TEST_F(RootWindowControllerTest, ModalContainer) {
[email protected]8674b312012-10-12 19:02:44366 UpdateDisplay("600x600");
jamescook443e42d2016-06-10 21:44:46367 WmShell* wm_shell = WmShell::Get();
skyb6643832017-01-11 22:08:45368 RootWindowController* controller = wm_shell->GetPrimaryRootWindowController();
skye79274a2016-06-08 05:39:02369 EXPECT_EQ(LoginStatus::USER,
jamescook443e42d2016-06-10 21:44:46370 wm_shell->system_tray_delegate()->GetUserLoginStatus());
skyb6643832017-01-11 22:08:45371 EXPECT_EQ(GetLayoutManager(controller, kShellWindowId_SystemModalContainer),
[email protected]093b8d642014-04-03 20:59:28372 controller->GetSystemModalLayoutManager(NULL));
[email protected]8674b312012-10-12 19:02:44373
[email protected]3b162e12012-11-09 11:52:35374 views::Widget* session_modal_widget =
375 CreateModalWidget(gfx::Rect(300, 10, 100, 100));
skyb6643832017-01-11 22:08:45376 EXPECT_EQ(GetLayoutManager(controller, kShellWindowId_SystemModalContainer),
[email protected]093b8d642014-04-03 20:59:28377 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19378 WmLookup::Get()->GetWindowForWidget(session_modal_widget)));
[email protected]3b162e12012-11-09 11:52:35379
mswbc0a8b482016-06-30 02:21:14380 wm_shell->GetSessionStateDelegate()->LockScreen();
skye79274a2016-06-08 05:39:02381 EXPECT_EQ(LoginStatus::LOCKED,
jamescook443e42d2016-06-10 21:44:46382 wm_shell->system_tray_delegate()->GetUserLoginStatus());
skyb6643832017-01-11 22:08:45383 EXPECT_EQ(
384 GetLayoutManager(controller, kShellWindowId_LockSystemModalContainer),
385 controller->GetSystemModalLayoutManager(nullptr));
[email protected]3b162e12012-11-09 11:52:35386
skyb6643832017-01-11 22:08:45387 aura::Window* lock_container =
388 controller->GetContainer(kShellWindowId_LockScreenContainer);
[email protected]3b162e12012-11-09 11:52:35389 views::Widget* lock_modal_widget =
390 CreateModalWidgetWithParent(gfx::Rect(300, 10, 100, 100), lock_container);
skyb6643832017-01-11 22:08:45391 EXPECT_EQ(
392 GetLayoutManager(controller, kShellWindowId_LockSystemModalContainer),
393 controller->GetSystemModalLayoutManager(
394 WmLookup::Get()->GetWindowForWidget(lock_modal_widget)));
395 EXPECT_EQ(GetLayoutManager(controller, kShellWindowId_SystemModalContainer),
[email protected]3b162e12012-11-09 11:52:35396 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19397 WmLookup::Get()->GetWindowForWidget(session_modal_widget)));
[email protected]3b162e12012-11-09 11:52:35398
mswbc0a8b482016-06-30 02:21:14399 wm_shell->GetSessionStateDelegate()->UnlockScreen();
[email protected]8674b312012-10-12 19:02:44400}
401
estadea23d6ceb2017-02-15 00:47:09402TEST_F(RootWindowControllerTest, ModalContainerNotLoggedInLoggedIn) {
[email protected]1b219922012-11-13 21:16:43403 UpdateDisplay("600x600");
[email protected]1b219922012-11-13 21:16:43404
405 // Configure login screen environment.
mswbc0a8b482016-06-30 02:21:14406 SessionStateDelegate* session_state_delegate =
407 WmShell::Get()->GetSessionStateDelegate();
[email protected]1b219922012-11-13 21:16:43408 SetUserLoggedIn(false);
skye79274a2016-06-08 05:39:02409 EXPECT_EQ(LoginStatus::NOT_LOGGED_IN,
mswbc0a8b482016-06-30 02:21:14410 WmShell::Get()->system_tray_delegate()->GetUserLoginStatus());
411 EXPECT_EQ(0, session_state_delegate->NumberOfLoggedInUsers());
412 EXPECT_FALSE(session_state_delegate->IsActiveUserSessionStarted());
[email protected]1b219922012-11-13 21:16:43413
skyb6643832017-01-11 22:08:45414 RootWindowController* controller =
skyea4ca942016-09-12 21:56:19415 WmShell::Get()->GetPrimaryRootWindowController();
skyb6643832017-01-11 22:08:45416 EXPECT_EQ(
417 GetLayoutManager(controller, kShellWindowId_LockSystemModalContainer),
418 controller->GetSystemModalLayoutManager(NULL));
[email protected]1b219922012-11-13 21:16:43419
skyb6643832017-01-11 22:08:45420 aura::Window* lock_container =
421 controller->GetContainer(kShellWindowId_LockScreenContainer);
[email protected]1b219922012-11-13 21:16:43422 views::Widget* login_modal_widget =
423 CreateModalWidgetWithParent(gfx::Rect(300, 10, 100, 100), lock_container);
skyb6643832017-01-11 22:08:45424 EXPECT_EQ(
425 GetLayoutManager(controller, kShellWindowId_LockSystemModalContainer),
426 controller->GetSystemModalLayoutManager(
427 WmLookup::Get()->GetWindowForWidget(login_modal_widget)));
[email protected]1b219922012-11-13 21:16:43428 login_modal_widget->Close();
429
430 // Configure user session environment.
431 SetUserLoggedIn(true);
432 SetSessionStarted(true);
skye79274a2016-06-08 05:39:02433 EXPECT_EQ(LoginStatus::USER,
mswbc0a8b482016-06-30 02:21:14434 WmShell::Get()->system_tray_delegate()->GetUserLoginStatus());
435 EXPECT_EQ(1, session_state_delegate->NumberOfLoggedInUsers());
436 EXPECT_TRUE(session_state_delegate->IsActiveUserSessionStarted());
skyb6643832017-01-11 22:08:45437 EXPECT_EQ(GetLayoutManager(controller, kShellWindowId_SystemModalContainer),
[email protected]093b8d642014-04-03 20:59:28438 controller->GetSystemModalLayoutManager(NULL));
[email protected]1b219922012-11-13 21:16:43439
440 views::Widget* session_modal_widget =
jamescookb8dcef522016-06-25 14:42:55441 CreateModalWidget(gfx::Rect(300, 10, 100, 100));
skyb6643832017-01-11 22:08:45442 EXPECT_EQ(GetLayoutManager(controller, kShellWindowId_SystemModalContainer),
[email protected]093b8d642014-04-03 20:59:28443 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19444 WmLookup::Get()->GetWindowForWidget(session_modal_widget)));
[email protected]1b219922012-11-13 21:16:43445}
446
estadea23d6ceb2017-02-15 00:47:09447TEST_F(RootWindowControllerTest, ModalContainerBlockedSession) {
[email protected]a44afbbd2013-07-24 21:49:35448 UpdateDisplay("600x600");
skyb6643832017-01-11 22:08:45449 RootWindowController* controller =
skyea4ca942016-09-12 21:56:19450 WmShell::Get()->GetPrimaryRootWindowController();
skyb6643832017-01-11 22:08:45451 aura::Window* lock_container =
452 controller->GetContainer(kShellWindowId_LockScreenContainer);
[email protected]a44afbbd2013-07-24 21:49:35453 for (int block_reason = FIRST_BLOCK_REASON;
jamescookb8dcef522016-06-25 14:42:55454 block_reason < NUMBER_OF_BLOCK_REASONS; ++block_reason) {
[email protected]a44afbbd2013-07-24 21:49:35455 views::Widget* session_modal_widget =
jamescookb8dcef522016-06-25 14:42:55456 CreateModalWidget(gfx::Rect(300, 10, 100, 100));
skyb6643832017-01-11 22:08:45457 EXPECT_EQ(GetLayoutManager(controller, kShellWindowId_SystemModalContainer),
[email protected]093b8d642014-04-03 20:59:28458 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19459 WmLookup::Get()->GetWindowForWidget(session_modal_widget)));
skyb6643832017-01-11 22:08:45460 EXPECT_EQ(GetLayoutManager(controller, kShellWindowId_SystemModalContainer),
[email protected]093b8d642014-04-03 20:59:28461 controller->GetSystemModalLayoutManager(NULL));
[email protected]a44afbbd2013-07-24 21:49:35462 session_modal_widget->Close();
463
464 BlockUserSession(static_cast<UserSessionBlockReason>(block_reason));
465
skyb6643832017-01-11 22:08:45466 EXPECT_EQ(
467 GetLayoutManager(controller, kShellWindowId_LockSystemModalContainer),
468 controller->GetSystemModalLayoutManager(NULL));
[email protected]a44afbbd2013-07-24 21:49:35469
jamescookb8dcef522016-06-25 14:42:55470 views::Widget* lock_modal_widget = CreateModalWidgetWithParent(
471 gfx::Rect(300, 10, 100, 100), lock_container);
skyb6643832017-01-11 22:08:45472 EXPECT_EQ(
473 GetLayoutManager(controller, kShellWindowId_LockSystemModalContainer),
474 controller->GetSystemModalLayoutManager(
475 WmLookup::Get()->GetWindowForWidget(lock_modal_widget)));
[email protected]a44afbbd2013-07-24 21:49:35476
jamescookb8dcef522016-06-25 14:42:55477 session_modal_widget = CreateModalWidget(gfx::Rect(300, 10, 100, 100));
skyb6643832017-01-11 22:08:45478 EXPECT_EQ(GetLayoutManager(controller, kShellWindowId_SystemModalContainer),
[email protected]093b8d642014-04-03 20:59:28479 controller->GetSystemModalLayoutManager(
skyea4ca942016-09-12 21:56:19480 WmLookup::Get()->GetWindowForWidget(session_modal_widget)));
[email protected]a44afbbd2013-07-24 21:49:35481 session_modal_widget->Close();
482
483 lock_modal_widget->Close();
484 UnblockUserSession();
485 }
486}
487
estadea23d6ceb2017-02-15 00:47:09488TEST_F(RootWindowControllerTest, GetWindowForFullscreenMode) {
[email protected]2ee2f5d2013-01-10 23:37:16489 UpdateDisplay("600x600");
mswbc0a8b482016-06-30 02:21:14490 RootWindowController* controller = Shell::GetPrimaryRootWindowController();
[email protected]2ee2f5d2013-01-10 23:37:16491
[email protected]700849f2013-04-30 17:49:20492 Widget* w1 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
[email protected]2ee2f5d2013-01-10 23:37:16493 w1->Maximize();
[email protected]700849f2013-04-30 17:49:20494 Widget* w2 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
495 w2->SetFullscreen(true);
496 // |w3| is a transient child of |w2|.
jamescookb8dcef522016-06-25 14:42:55497 Widget* w3 = Widget::CreateWindowWithParentAndBounds(
498 NULL, w2->GetNativeWindow(), gfx::Rect(0, 0, 100, 100));
[email protected]2ee2f5d2013-01-10 23:37:16499
[email protected]2c9171d22013-12-10 21:55:10500 // Test that GetWindowForFullscreenMode() finds the fullscreen window when one
[email protected]e3bc88e2013-09-06 06:22:06501 // of its transient children is active.
[email protected]700849f2013-04-30 17:49:20502 w3->Activate();
[email protected]2c9171d22013-12-10 21:55:10503 EXPECT_EQ(w2->GetNativeWindow(), controller->GetWindowForFullscreenMode());
[email protected]2ee2f5d2013-01-10 23:37:16504
[email protected]2c9171d22013-12-10 21:55:10505 // If the topmost window is not fullscreen, it returns NULL.
[email protected]700849f2013-04-30 17:49:20506 w1->Activate();
[email protected]2c9171d22013-12-10 21:55:10507 EXPECT_EQ(NULL, controller->GetWindowForFullscreenMode());
508 w1->Close();
509 w3->Close();
[email protected]e3bc88e2013-09-06 06:22:06510
[email protected]2c9171d22013-12-10 21:55:10511 // Only w2 remains, if minimized GetWindowForFullscreenMode should return
512 // NULL.
[email protected]e3bc88e2013-09-06 06:22:06513 w2->Activate();
[email protected]2c9171d22013-12-10 21:55:10514 EXPECT_EQ(w2->GetNativeWindow(), controller->GetWindowForFullscreenMode());
515 w2->Minimize();
516 EXPECT_EQ(NULL, controller->GetWindowForFullscreenMode());
[email protected]2ee2f5d2013-01-10 23:37:16517}
518
estadea23d6ceb2017-02-15 00:47:09519TEST_F(RootWindowControllerTest, MultipleDisplaysGetWindowForFullscreenMode) {
[email protected]2c5db9e2014-02-27 13:58:14520 UpdateDisplay("600x600,600x600");
521 Shell::RootWindowControllerList controllers =
522 Shell::GetInstance()->GetAllRootWindowControllers();
523
524 Widget* w1 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
525 w1->Maximize();
526 Widget* w2 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
527 w2->SetFullscreen(true);
528 Widget* w3 = CreateTestWidget(gfx::Rect(600, 0, 100, 100));
529
530 EXPECT_EQ(w1->GetNativeWindow()->GetRootWindow(),
[email protected]f5c9dbc2014-04-11 08:13:45531 controllers[0]->GetRootWindow());
[email protected]2c5db9e2014-02-27 13:58:14532 EXPECT_EQ(w2->GetNativeWindow()->GetRootWindow(),
[email protected]f5c9dbc2014-04-11 08:13:45533 controllers[0]->GetRootWindow());
[email protected]2c5db9e2014-02-27 13:58:14534 EXPECT_EQ(w3->GetNativeWindow()->GetRootWindow(),
[email protected]f5c9dbc2014-04-11 08:13:45535 controllers[1]->GetRootWindow());
[email protected]2c5db9e2014-02-27 13:58:14536
537 w1->Activate();
538 EXPECT_EQ(NULL, controllers[0]->GetWindowForFullscreenMode());
539 EXPECT_EQ(NULL, controllers[1]->GetWindowForFullscreenMode());
540
541 w2->Activate();
542 EXPECT_EQ(w2->GetNativeWindow(),
543 controllers[0]->GetWindowForFullscreenMode());
544 EXPECT_EQ(NULL, controllers[1]->GetWindowForFullscreenMode());
545
546 // Verify that the first root window controller remains in fullscreen mode
547 // when a window on the other display is activated.
548 w3->Activate();
549 EXPECT_EQ(w2->GetNativeWindow(),
550 controllers[0]->GetWindowForFullscreenMode());
551 EXPECT_EQ(NULL, controllers[1]->GetWindowForFullscreenMode());
552}
553
jamescook5d74ac02016-05-12 19:57:12554// Test that GetRootWindowController() works with multiple displays and
555// child widgets.
estadea23d6ceb2017-02-15 00:47:09556TEST_F(RootWindowControllerTest, GetRootWindowController) {
jamescook5d74ac02016-05-12 19:57:12557 UpdateDisplay("600x600,600x600");
558 Shell::RootWindowControllerList controllers =
559 Shell::GetInstance()->GetAllRootWindowControllers();
560 ASSERT_EQ(2u, controllers.size());
561
562 // Test null.
563 EXPECT_FALSE(GetRootWindowController(nullptr));
564
565 // Test a widget on the first display.
566 Widget* w1 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
567 EXPECT_EQ(controllers[0],
568 GetRootWindowController(w1->GetNativeWindow()->GetRootWindow()));
569
570 // Test a child widget.
571 Widget* w2 = Widget::CreateWindowWithParentAndBounds(
572 nullptr, w1->GetNativeWindow(), gfx::Rect(0, 0, 100, 100));
573 EXPECT_EQ(controllers[0],
574 GetRootWindowController(w2->GetNativeWindow()->GetRootWindow()));
575
576 // Test a widget on the second display.
577 Widget* w3 = CreateTestWidget(gfx::Rect(600, 0, 100, 100));
578 EXPECT_EQ(controllers[1],
579 GetRootWindowController(w3->GetNativeWindow()->GetRootWindow()));
580}
581
[email protected]82ced2352013-07-19 20:49:06582// Test that user session window can't be focused if user session blocked by
583// some overlapping UI.
estadea23d6ceb2017-02-15 00:47:09584TEST_F(RootWindowControllerTest, FocusBlockedWindow) {
[email protected]82ced2352013-07-19 20:49:06585 UpdateDisplay("600x600");
mswbc0a8b482016-06-30 02:21:14586 RootWindowController* controller = Shell::GetPrimaryRootWindowController();
[email protected]f5c9dbc2014-04-11 08:13:45587 aura::Window* lock_container =
588 controller->GetContainer(kShellWindowId_LockScreenContainer);
jamescookb8dcef522016-06-25 14:42:55589 aura::Window* lock_window =
590 Widget::CreateWindowWithParentAndBounds(NULL, lock_container,
591 gfx::Rect(0, 0, 100, 100))
592 ->GetNativeView();
[email protected]82ced2352013-07-19 20:49:06593 lock_window->Show();
594 aura::Window* session_window =
595 CreateTestWidget(gfx::Rect(0, 0, 100, 100))->GetNativeView();
596 session_window->Show();
597
[email protected]a44afbbd2013-07-24 21:49:35598 for (int block_reason = FIRST_BLOCK_REASON;
jamescookb8dcef522016-06-25 14:42:55599 block_reason < NUMBER_OF_BLOCK_REASONS; ++block_reason) {
[email protected]a44afbbd2013-07-24 21:49:35600 BlockUserSession(static_cast<UserSessionBlockReason>(block_reason));
601 lock_window->Focus();
602 EXPECT_TRUE(lock_window->HasFocus());
603 session_window->Focus();
604 EXPECT_FALSE(session_window->HasFocus());
605 UnblockUserSession();
606 }
[email protected]82ced2352013-07-19 20:49:06607}
608
[email protected]0fbfa972013-10-02 19:23:33609// Tracks whether OnWindowDestroying() has been invoked.
610class DestroyedWindowObserver : public aura::WindowObserver {
611 public:
612 DestroyedWindowObserver() : destroyed_(false), window_(NULL) {}
dcheng1f4538e2014-10-27 23:57:05613 ~DestroyedWindowObserver() override { Shutdown(); }
[email protected]0fbfa972013-10-02 19:23:33614
615 void SetWindow(Window* window) {
616 window_ = window;
617 window->AddObserver(this);
618 }
619
620 bool destroyed() const { return destroyed_; }
621
622 // WindowObserver overrides:
dcheng1f4538e2014-10-27 23:57:05623 void OnWindowDestroying(Window* window) override {
[email protected]0fbfa972013-10-02 19:23:33624 destroyed_ = true;
625 Shutdown();
626 }
627
628 private:
629 void Shutdown() {
630 if (!window_)
631 return;
632 window_->RemoveObserver(this);
633 window_ = NULL;
634 }
635
636 bool destroyed_;
637 Window* window_;
638
639 DISALLOW_COPY_AND_ASSIGN(DestroyedWindowObserver);
640};
641
642// Verifies shutdown doesn't delete windows that are not owned by the parent.
estadea23d6ceb2017-02-15 00:47:09643TEST_F(RootWindowControllerTest, DontDeleteWindowsNotOwnedByParent) {
[email protected]0fbfa972013-10-02 19:23:33644 DestroyedWindowObserver observer1;
645 aura::test::TestWindowDelegate delegate1;
646 aura::Window* window1 = new aura::Window(&delegate1);
[email protected]5b251f12013-12-19 01:50:05647 window1->SetType(ui::wm::WINDOW_TYPE_CONTROL);
[email protected]0fbfa972013-10-02 19:23:33648 window1->set_owned_by_parent(false);
649 observer1.SetWindow(window1);
danakjb161836d2015-04-03 05:14:18650 window1->Init(ui::LAYER_NOT_DRAWN);
[email protected]e3225e02013-10-23 20:44:37651 aura::client::ParentWindowWithContext(
652 window1, Shell::GetInstance()->GetPrimaryRootWindow(), gfx::Rect());
[email protected]0fbfa972013-10-02 19:23:33653
654 DestroyedWindowObserver observer2;
655 aura::Window* window2 = new aura::Window(NULL);
656 window2->set_owned_by_parent(false);
657 observer2.SetWindow(window2);
danakjb161836d2015-04-03 05:14:18658 window2->Init(ui::LAYER_NOT_DRAWN);
[email protected]0fbfa972013-10-02 19:23:33659 Shell::GetInstance()->GetPrimaryRootWindow()->AddChild(window2);
660
mswbc0a8b482016-06-30 02:21:14661 Shell::GetPrimaryRootWindowController()->CloseChildWindows();
[email protected]0fbfa972013-10-02 19:23:33662
663 ASSERT_FALSE(observer1.destroyed());
664 delete window1;
665
666 ASSERT_FALSE(observer2.destroyed());
667 delete window2;
668}
669
[email protected]24f5e242014-07-22 02:16:09670class VirtualKeyboardRootWindowControllerTest
671 : public RootWindowControllerTest {
[email protected]eff4c7f2013-08-13 01:45:50672 public:
dcheng1f4538e2014-10-27 23:57:05673 VirtualKeyboardRootWindowControllerTest() {}
674 ~VirtualKeyboardRootWindowControllerTest() override {}
[email protected]eff4c7f2013-08-13 01:45:50675
dcheng1f4538e2014-10-27 23:57:05676 void SetUp() override {
pgal.u-szegedd84534d32014-10-29 12:34:30677 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]eff4c7f2013-08-13 01:45:50678 keyboard::switches::kEnableVirtualKeyboard);
679 test::AshTestBase::SetUp();
yhanada7e20c9b2016-11-25 00:03:19680 keyboard::SetTouchKeyboardEnabled(true);
681 Shell::GetInstance()->CreateKeyboard();
682 }
683
684 void TearDown() override {
685 keyboard::SetTouchKeyboardEnabled(false);
686 test::AshTestBase::TearDown();
[email protected]eff4c7f2013-08-13 01:45:50687 }
688
689 private:
690 DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardRootWindowControllerTest);
691};
692
[email protected]2082d7d2014-05-13 14:44:23693class MockTextInputClient : public ui::DummyTextInputClient {
694 public:
jamescookb8dcef522016-06-25 14:42:55695 MockTextInputClient() : ui::DummyTextInputClient(ui::TEXT_INPUT_TYPE_TEXT) {}
[email protected]2082d7d2014-05-13 14:44:23696
yhanada0ddd3462016-12-08 05:04:18697 void EnsureCaretNotInRect(const gfx::Rect& rect) override {
698 caret_exclude_rect_ = rect;
[email protected]2082d7d2014-05-13 14:44:23699 }
700
yhanada0ddd3462016-12-08 05:04:18701 const gfx::Rect& caret_exclude_rect() const { return caret_exclude_rect_; }
[email protected]2082d7d2014-05-13 14:44:23702
703 private:
yhanada0ddd3462016-12-08 05:04:18704 gfx::Rect caret_exclude_rect_;
[email protected]2082d7d2014-05-13 14:44:23705
706 DISALLOW_COPY_AND_ASSIGN(MockTextInputClient);
707};
708
kevers23f3987d2014-09-17 13:50:12709class TargetHitTestEventHandler : public ui::test::TestEventHandler {
710 public:
711 TargetHitTestEventHandler() {}
712
713 // ui::test::TestEventHandler overrides.
dcheng1f4538e2014-10-27 23:57:05714 void OnMouseEvent(ui::MouseEvent* event) override {
kevers23f3987d2014-09-17 13:50:12715 if (event->type() == ui::ET_MOUSE_PRESSED)
716 ui::test::TestEventHandler::OnMouseEvent(event);
717 event->StopPropagation();
718 }
719
720 private:
721 DISALLOW_COPY_AND_ASSIGN(TargetHitTestEventHandler);
722};
723
[email protected]b6ba05d902013-10-04 21:38:45724// Test for http://crbug.com/297858. Virtual keyboard container should only show
yhanada7e20c9b2016-11-25 00:03:19725// on primary root window if no window has touch capability.
[email protected]b6ba05d902013-10-04 21:38:45726TEST_F(VirtualKeyboardRootWindowControllerTest,
yhanada7e20c9b2016-11-25 00:03:19727 VirtualKeyboardOnPrimaryRootWindowDefault) {
[email protected]b6ba05d902013-10-04 21:38:45728 UpdateDisplay("500x500,500x500");
729
[email protected]c9390bd2013-11-08 20:33:13730 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
[email protected]bf9cdb362013-10-25 19:22:45731 aura::Window* primary_root_window = Shell::GetPrimaryRootWindow();
jamescookb8dcef522016-06-25 14:42:55732 aura::Window* secondary_root_window = root_windows[0] == primary_root_window
733 ? root_windows[1]
734 : root_windows[0];
[email protected]b6ba05d902013-10-04 21:38:45735
[email protected]093b8d642014-04-03 20:59:28736 ASSERT_TRUE(Shell::GetContainer(primary_root_window,
737 kShellWindowId_VirtualKeyboardContainer));
738 ASSERT_FALSE(Shell::GetContainer(secondary_root_window,
739 kShellWindowId_VirtualKeyboardContainer));
[email protected]b6ba05d902013-10-04 21:38:45740}
741
yhanada7e20c9b2016-11-25 00:03:19742// Test for http://crbug.com/303429. Virtual keyboard container should show on
743// a display which has touch capability.
744TEST_F(VirtualKeyboardRootWindowControllerTest,
745 VirtualKeyboardOnTouchableDisplayOnly) {
yhanada7e20c9b2016-11-25 00:03:19746 UpdateDisplay("500x500,500x500");
747 display::Display secondary_display =
748 Shell::GetInstance()->display_manager()->GetSecondaryDisplay();
749 display::test::DisplayManagerTestApi(Shell::GetInstance()->display_manager())
750 .SetTouchSupport(secondary_display.id(),
751 display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE);
752
753 // The primary display doesn't have touch capability and the secondary display
754 // does.
755 ASSERT_NE(display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE,
756 display::Screen::GetScreen()->GetPrimaryDisplay().touch_support());
757 ASSERT_EQ(display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE,
758 Shell::GetInstance()
759 ->display_manager()
760 ->GetSecondaryDisplay()
761 .touch_support());
762
763 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
764 aura::Window* primary_root_window = Shell::GetPrimaryRootWindow();
765 aura::Window* secondary_root_window = root_windows[0] == primary_root_window
766 ? root_windows[1]
767 : root_windows[0];
768
769 keyboard::KeyboardController::GetInstance()->ShowKeyboard(false);
770 ASSERT_FALSE(Shell::GetContainer(primary_root_window,
771 kShellWindowId_VirtualKeyboardContainer));
772 ASSERT_TRUE(Shell::GetContainer(secondary_root_window,
773 kShellWindowId_VirtualKeyboardContainer));
774
775 // Move the focus to the primary display.
776 aura::Window* focusable_window_in_primary_display =
777 CreateTestWindowInShellWithBounds(
778 primary_root_window->GetBoundsInScreen());
779 ASSERT_EQ(primary_root_window,
780 focusable_window_in_primary_display->GetRootWindow());
781 focusable_window_in_primary_display->Focus();
782 ASSERT_TRUE(focusable_window_in_primary_display->HasFocus());
783
784 // Virtual keyboard shows up on the secondary display even if a window in the
785 // primary screen has the focus.
786 keyboard::KeyboardController::GetInstance()->ShowKeyboard(false);
787 EXPECT_FALSE(Shell::GetContainer(primary_root_window,
788 kShellWindowId_VirtualKeyboardContainer));
789 EXPECT_TRUE(Shell::GetContainer(secondary_root_window,
790 kShellWindowId_VirtualKeyboardContainer));
791}
792
793// Test for http://crbug.com/303429. If both of displays have touch capability,
794// virtual keyboard follows the input focus.
795TEST_F(VirtualKeyboardRootWindowControllerTest, FollowInputFocus) {
yhanada7e20c9b2016-11-25 00:03:19796 UpdateDisplay("500x500,500x500");
797 const int64_t primary_display_id =
798 display::Screen::GetScreen()->GetPrimaryDisplay().id();
799 display::test::DisplayManagerTestApi(Shell::GetInstance()->display_manager())
800 .SetTouchSupport(primary_display_id,
801 display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE);
802 const int64_t secondary_display_id =
803 Shell::GetInstance()->display_manager()->GetSecondaryDisplay().id();
804 display::test::DisplayManagerTestApi(Shell::GetInstance()->display_manager())
805 .SetTouchSupport(secondary_display_id,
806 display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE);
807
808 // Both of displays have touch capability.
809 ASSERT_EQ(display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE,
810 display::Screen::GetScreen()->GetPrimaryDisplay().touch_support());
811 ASSERT_EQ(display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE,
812 Shell::GetInstance()
813 ->display_manager()
814 ->GetSecondaryDisplay()
815 .touch_support());
816
817 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
818 aura::Window* primary_root_window = Shell::GetPrimaryRootWindow();
819 aura::Window* secondary_root_window = root_windows[0] == primary_root_window
820 ? root_windows[1]
821 : root_windows[0];
822 aura::Window* focusable_window_in_primary_display =
823 CreateTestWindowInShellWithBounds(
824 primary_root_window->GetBoundsInScreen());
825 ASSERT_EQ(primary_root_window,
826 focusable_window_in_primary_display->GetRootWindow());
827 aura::Window* focusable_window_in_secondary_display =
828 CreateTestWindowInShellWithBounds(
829 secondary_root_window->GetBoundsInScreen());
830 ASSERT_EQ(secondary_root_window,
831 focusable_window_in_secondary_display->GetRootWindow());
832
833 keyboard::KeyboardController::GetInstance()->ShowKeyboard(false);
834 EXPECT_TRUE(Shell::GetContainer(primary_root_window,
835 kShellWindowId_VirtualKeyboardContainer));
836 EXPECT_FALSE(Shell::GetContainer(secondary_root_window,
837 kShellWindowId_VirtualKeyboardContainer));
838
839 // Move the focus to the secondary display.
840 focusable_window_in_secondary_display->Focus();
841 ASSERT_TRUE(focusable_window_in_secondary_display->HasFocus());
842
843 keyboard::KeyboardController::GetInstance()->ShowKeyboard(false);
844 ASSERT_FALSE(Shell::GetContainer(primary_root_window,
845 kShellWindowId_VirtualKeyboardContainer));
846 ASSERT_TRUE(Shell::GetContainer(secondary_root_window,
847 kShellWindowId_VirtualKeyboardContainer));
848
849 // Move back focus to the primary display.
850 focusable_window_in_primary_display->Focus();
851 ASSERT_TRUE(focusable_window_in_primary_display->HasFocus());
852
853 keyboard::KeyboardController::GetInstance()->ShowKeyboard(false);
854 EXPECT_TRUE(Shell::GetContainer(primary_root_window,
855 kShellWindowId_VirtualKeyboardContainer));
856 EXPECT_FALSE(Shell::GetContainer(secondary_root_window,
857 kShellWindowId_VirtualKeyboardContainer));
858}
859
860// Test for http://crbug.com/303429. Even if both of display don't have touch
861// capability, the virtual keyboard shows up on the specified display.
862TEST_F(VirtualKeyboardRootWindowControllerTest,
863 VirtualKeyboardShowOnSpecifiedDisplay) {
yhanada7e20c9b2016-11-25 00:03:19864 UpdateDisplay("500x500,500x500");
865 display::Display secondary_display =
866 Shell::GetInstance()->display_manager()->GetSecondaryDisplay();
867
868 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
869 aura::Window* primary_root_window = Shell::GetPrimaryRootWindow();
870 aura::Window* secondary_root_window = root_windows[0] == primary_root_window
871 ? root_windows[1]
872 : root_windows[0];
873
874 ASSERT_TRUE(Shell::GetContainer(primary_root_window,
875 kShellWindowId_VirtualKeyboardContainer));
876 ASSERT_FALSE(Shell::GetContainer(secondary_root_window,
877 kShellWindowId_VirtualKeyboardContainer));
878
879 const int64_t secondary_display_id = secondary_display.id();
880 keyboard::KeyboardController::GetInstance()->ShowKeyboardInDisplay(
881 secondary_display_id);
882
883 EXPECT_FALSE(Shell::GetContainer(primary_root_window,
884 kShellWindowId_VirtualKeyboardContainer));
885 EXPECT_TRUE(Shell::GetContainer(secondary_root_window,
886 kShellWindowId_VirtualKeyboardContainer));
887}
888
[email protected]eff4c7f2013-08-13 01:45:50889// Test for http://crbug.com/263599. Virtual keyboard should be able to receive
890// events at blocked user session.
891TEST_F(VirtualKeyboardRootWindowControllerTest,
892 ClickVirtualKeyboardInBlockedWindow) {
[email protected]bf9cdb362013-10-25 19:22:45893 aura::Window* root_window = Shell::GetPrimaryRootWindow();
[email protected]093b8d642014-04-03 20:59:28894 aura::Window* keyboard_container =
895 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
[email protected]eff4c7f2013-08-13 01:45:50896 ASSERT_TRUE(keyboard_container);
897 keyboard_container->Show();
898
ben974286a2015-10-10 00:45:12899 aura::Window* keyboard_window =
900 keyboard::KeyboardController::GetInstance()->ui()->GetKeyboardWindow();
[email protected]647b4842013-12-12 14:24:24901 keyboard_container->AddChild(keyboard_window);
[email protected]183e28d2014-01-20 18:18:02902 keyboard_window->set_owned_by_parent(false);
[email protected]647b4842013-12-12 14:24:24903 keyboard_window->SetBounds(gfx::Rect());
[email protected]eff4c7f2013-08-13 01:45:50904 keyboard_window->Show();
[email protected]647b4842013-12-12 14:24:24905
[email protected]3193ea722014-04-23 22:19:19906 ui::test::TestEventHandler handler;
907 root_window->AddPreTargetHandler(&handler);
[email protected]647b4842013-12-12 14:24:24908
[email protected]73c9fd02014-07-28 01:48:52909 ui::test::EventGenerator event_generator(root_window, keyboard_window);
[email protected]eff4c7f2013-08-13 01:45:50910 event_generator.ClickLeftButton();
911 int expected_mouse_presses = 1;
[email protected]3193ea722014-04-23 22:19:19912 EXPECT_EQ(expected_mouse_presses, handler.num_mouse_events() / 2);
[email protected]eff4c7f2013-08-13 01:45:50913
914 for (int block_reason = FIRST_BLOCK_REASON;
jamescookb8dcef522016-06-25 14:42:55915 block_reason < NUMBER_OF_BLOCK_REASONS; ++block_reason) {
[email protected]eff4c7f2013-08-13 01:45:50916 BlockUserSession(static_cast<UserSessionBlockReason>(block_reason));
917 event_generator.ClickLeftButton();
918 expected_mouse_presses++;
[email protected]3193ea722014-04-23 22:19:19919 EXPECT_EQ(expected_mouse_presses, handler.num_mouse_events() / 2);
[email protected]eff4c7f2013-08-13 01:45:50920 UnblockUserSession();
921 }
[email protected]3193ea722014-04-23 22:19:19922 root_window->RemovePreTargetHandler(&handler);
[email protected]eff4c7f2013-08-13 01:45:50923}
924
[email protected]45c66672013-10-01 22:48:56925// Test for http://crbug.com/299787. RootWindowController should delete
926// the old container since the keyboard controller creates a new window in
927// GetWindowContainer().
928TEST_F(VirtualKeyboardRootWindowControllerTest,
929 DeleteOldContainerOnVirtualKeyboardInit) {
[email protected]1025937e2014-02-13 01:25:50930 aura::Window* root_window = Shell::GetPrimaryRootWindow();
[email protected]093b8d642014-04-03 20:59:28931 aura::Window* keyboard_container =
932 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
[email protected]45c66672013-10-01 22:48:56933 ASSERT_TRUE(keyboard_container);
934 // Track the keyboard container window.
935 aura::WindowTracker tracker;
936 tracker.Add(keyboard_container);
jamescooke3d63f62017-01-12 07:12:40937 // Reinitialize the keyboard.
938 Shell::GetInstance()->CreateKeyboard();
[email protected]45c66672013-10-01 22:48:56939 // keyboard_container should no longer be present.
940 EXPECT_FALSE(tracker.Contains(keyboard_container));
941}
942
[email protected]1025937e2014-02-13 01:25:50943// Test for crbug.com/342524. After user login, the work space should restore to
944// full screen.
945TEST_F(VirtualKeyboardRootWindowControllerTest, RestoreWorkspaceAfterLogin) {
946 aura::Window* root_window = Shell::GetPrimaryRootWindow();
[email protected]093b8d642014-04-03 20:59:28947 aura::Window* keyboard_container =
948 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
[email protected]1025937e2014-02-13 01:25:50949 keyboard_container->Show();
950 keyboard::KeyboardController* controller =
[email protected]a0b3fb882014-04-07 19:26:03951 keyboard::KeyboardController::GetInstance();
ben974286a2015-10-10 00:45:12952 aura::Window* keyboard_window = controller->ui()->GetKeyboardWindow();
[email protected]1025937e2014-02-13 01:25:50953 keyboard_container->AddChild(keyboard_window);
954 keyboard_window->set_owned_by_parent(false);
bshea0a57802015-04-08 18:21:29955 keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
956 root_window->bounds(), 100));
[email protected]1025937e2014-02-13 01:25:50957 keyboard_window->Show();
958
oshimaf84b0da722016-04-27 19:47:19959 gfx::Rect before =
960 display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
[email protected]1025937e2014-02-13 01:25:50961
962 // Notify keyboard bounds changing.
bshea0a57802015-04-08 18:21:29963 controller->NotifyKeyboardBoundsChanging(keyboard_container->bounds());
[email protected]1025937e2014-02-13 01:25:50964
[email protected]25df7ad2014-04-30 18:10:25965 if (!keyboard::IsKeyboardOverscrollEnabled()) {
oshimaf84b0da722016-04-27 19:47:19966 gfx::Rect after =
967 display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
[email protected]25df7ad2014-04-30 18:10:25968 EXPECT_LT(after, before);
969 }
[email protected]1025937e2014-02-13 01:25:50970
971 // Mock a login user profile change to reinitialize the keyboard.
jamescooke3d63f62017-01-12 07:12:40972 mojom::SessionInfoPtr info = mojom::SessionInfo::New();
973 info->state = session_manager::SessionState::ACTIVE;
974 WmShell::Get()->session_controller()->SetSessionInfo(std::move(info));
oshimaf84b0da722016-04-27 19:47:19975 EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().work_area(),
976 before);
[email protected]1025937e2014-02-13 01:25:50977}
978
[email protected]602022b2014-03-31 17:07:31979// Ensure that system modal dialogs do not block events targeted at the virtual
980// keyboard.
981TEST_F(VirtualKeyboardRootWindowControllerTest, ClickWithActiveModalDialog) {
982 aura::Window* root_window = Shell::GetPrimaryRootWindow();
[email protected]093b8d642014-04-03 20:59:28983 aura::Window* keyboard_container =
984 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
[email protected]602022b2014-03-31 17:07:31985 ASSERT_TRUE(keyboard_container);
986 keyboard_container->Show();
987
ben974286a2015-10-10 00:45:12988 aura::Window* keyboard_window =
989 keyboard::KeyboardController::GetInstance()->ui()->GetKeyboardWindow();
[email protected]602022b2014-03-31 17:07:31990 keyboard_container->AddChild(keyboard_window);
991 keyboard_window->set_owned_by_parent(false);
bshea0a57802015-04-08 18:21:29992 keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
993 root_window->bounds(), 100));
[email protected]3193ea722014-04-23 22:19:19994
995 ui::test::TestEventHandler handler;
996 root_window->AddPreTargetHandler(&handler);
[email protected]73c9fd02014-07-28 01:48:52997 ui::test::EventGenerator root_window_event_generator(root_window);
998 ui::test::EventGenerator keyboard_event_generator(root_window,
999 keyboard_window);
[email protected]602022b2014-03-31 17:07:311000
jamescookb8dcef522016-06-25 14:42:551001 views::Widget* modal_widget = CreateModalWidget(gfx::Rect(300, 10, 100, 100));
[email protected]602022b2014-03-31 17:07:311002
1003 // Verify that mouse events to the root window are block with a visble modal
1004 // dialog.
1005 root_window_event_generator.ClickLeftButton();
[email protected]3193ea722014-04-23 22:19:191006 EXPECT_EQ(0, handler.num_mouse_events());
[email protected]602022b2014-03-31 17:07:311007
1008 // Verify that event dispatch to the virtual keyboard is unblocked.
1009 keyboard_event_generator.ClickLeftButton();
[email protected]3193ea722014-04-23 22:19:191010 EXPECT_EQ(1, handler.num_mouse_events() / 2);
[email protected]602022b2014-03-31 17:07:311011
1012 modal_widget->Close();
1013
1014 // Verify that mouse events are now unblocked to the root window.
1015 root_window_event_generator.ClickLeftButton();
[email protected]3193ea722014-04-23 22:19:191016 EXPECT_EQ(2, handler.num_mouse_events() / 2);
1017 root_window->RemovePreTargetHandler(&handler);
[email protected]602022b2014-03-31 17:07:311018}
1019
[email protected]2082d7d2014-05-13 14:44:231020// Ensure that the visible area for scrolling the text caret excludes the
1021// region occluded by the on-screen keyboard.
1022TEST_F(VirtualKeyboardRootWindowControllerTest, EnsureCaretInWorkArea) {
1023 keyboard::KeyboardController* keyboard_controller =
1024 keyboard::KeyboardController::GetInstance();
ben974286a2015-10-10 00:45:121025 keyboard::KeyboardUI* ui = keyboard_controller->ui();
[email protected]2082d7d2014-05-13 14:44:231026
1027 MockTextInputClient text_input_client;
ben974286a2015-10-10 00:45:121028 ui::InputMethod* input_method = ui->GetInputMethod();
[email protected]2082d7d2014-05-13 14:44:231029 ASSERT_TRUE(input_method);
shuchen4e09795a2015-06-15 15:07:201030 input_method->SetFocusedTextInputClient(&text_input_client);
[email protected]2082d7d2014-05-13 14:44:231031
1032 aura::Window* root_window = Shell::GetPrimaryRootWindow();
1033 aura::Window* keyboard_container =
1034 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
1035 ASSERT_TRUE(keyboard_container);
1036 keyboard_container->Show();
1037
1038 const int keyboard_height = 100;
ben974286a2015-10-10 00:45:121039 aura::Window* keyboard_window = ui->GetKeyboardWindow();
[email protected]2082d7d2014-05-13 14:44:231040 keyboard_container->AddChild(keyboard_window);
1041 keyboard_window->set_owned_by_parent(false);
bshea0a57802015-04-08 18:21:291042 keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
1043 root_window->bounds(), keyboard_height));
[email protected]2082d7d2014-05-13 14:44:231044
ben974286a2015-10-10 00:45:121045 ui->EnsureCaretInWorkArea();
bshea0a57802015-04-08 18:21:291046 ASSERT_EQ(root_window->bounds().width(),
yhanada0ddd3462016-12-08 05:04:181047 text_input_client.caret_exclude_rect().width());
1048 ASSERT_EQ(keyboard_height, text_input_client.caret_exclude_rect().height());
[email protected]00a386792014-06-16 15:09:201049
shuchen4e09795a2015-06-15 15:07:201050 input_method->SetFocusedTextInputClient(NULL);
[email protected]2082d7d2014-05-13 14:44:231051}
1052
yhanada0ddd3462016-12-08 05:04:181053TEST_F(VirtualKeyboardRootWindowControllerTest,
1054 EnsureCaretInWorkAreaWithMultipleDisplays) {
yhanada0ddd3462016-12-08 05:04:181055 UpdateDisplay("500x500,600x600");
1056 const int64_t primary_display_id =
1057 display::Screen::GetScreen()->GetPrimaryDisplay().id();
1058 const int64_t secondary_display_id =
1059 Shell::GetInstance()->display_manager()->GetSecondaryDisplay().id();
1060 ASSERT_NE(primary_display_id, secondary_display_id);
1061
1062 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1063 ASSERT_EQ(static_cast<size_t>(2), root_windows.size());
1064 aura::Window* primary_root_window = root_windows[0];
1065 aura::Window* secondary_root_window = root_windows[1];
1066
1067 keyboard::KeyboardController* keyboard_controller =
1068 keyboard::KeyboardController::GetInstance();
1069 keyboard::KeyboardUI* ui = keyboard_controller->ui();
1070
1071 MockTextInputClient text_input_client;
1072 ui::InputMethod* input_method = ui->GetInputMethod();
1073 ASSERT_TRUE(input_method);
1074 input_method->SetFocusedTextInputClient(&text_input_client);
1075
1076 const int keyboard_height = 100;
1077 // Check that the keyboard on the primary screen doesn't cover the window on
1078 // the secondary screen.
1079 aura::Window* keyboard_container = Shell::GetContainer(
1080 primary_root_window, kShellWindowId_VirtualKeyboardContainer);
1081 ASSERT_TRUE(keyboard_container);
1082 keyboard_container->Show();
1083 aura::Window* keyboard_window = ui->GetKeyboardWindow();
1084 keyboard_container->AddChild(keyboard_window);
1085 keyboard_window->set_owned_by_parent(false);
1086 keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
1087 primary_root_window->bounds(), keyboard_height));
1088
1089 EXPECT_TRUE(primary_root_window->GetBoundsInScreen().Contains(
1090 text_input_client.caret_exclude_rect()));
1091 EXPECT_FALSE(secondary_root_window->GetBoundsInScreen().Contains(
1092 text_input_client.caret_exclude_rect()));
1093
1094 // Move the keyboard into the secondary display and check that the keyboard
1095 // doesn't cover the window on the primary screen.
1096 keyboard_controller->ShowKeyboardInDisplay(secondary_display_id);
1097 keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
1098 secondary_root_window->bounds(), keyboard_height));
1099
1100 ui->EnsureCaretInWorkArea();
1101 EXPECT_FALSE(primary_root_window->GetBoundsInScreen().Contains(
1102 text_input_client.caret_exclude_rect()));
1103 EXPECT_TRUE(secondary_root_window->GetBoundsInScreen().Contains(
1104 text_input_client.caret_exclude_rect()));
1105
1106 input_method->SetFocusedTextInputClient(nullptr);
1107}
1108
kevers23f3987d2014-09-17 13:50:121109// Tests that the virtual keyboard does not block context menus. The virtual
1110// keyboard should appear in front of most content, but not context menus. See
1111// crbug/377180.
1112TEST_F(VirtualKeyboardRootWindowControllerTest, ZOrderTest) {
1113 UpdateDisplay("800x600");
1114 keyboard::KeyboardController* keyboard_controller =
1115 keyboard::KeyboardController::GetInstance();
ben974286a2015-10-10 00:45:121116 keyboard::KeyboardUI* ui = keyboard_controller->ui();
kevers23f3987d2014-09-17 13:50:121117
1118 aura::Window* root_window = Shell::GetPrimaryRootWindow();
1119 aura::Window* keyboard_container =
1120 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
1121 ASSERT_TRUE(keyboard_container);
1122 keyboard_container->Show();
1123
1124 const int keyboard_height = 200;
ben974286a2015-10-10 00:45:121125 aura::Window* keyboard_window = ui->GetKeyboardWindow();
kevers23f3987d2014-09-17 13:50:121126 keyboard_container->AddChild(keyboard_window);
1127 keyboard_window->set_owned_by_parent(false);
bshea0a57802015-04-08 18:21:291128 gfx::Rect keyboard_bounds = keyboard::FullWidthKeyboardBoundsFromRootBounds(
1129 root_window->bounds(), keyboard_height);
kevers23f3987d2014-09-17 13:50:121130 keyboard_window->SetBounds(keyboard_bounds);
1131 keyboard_window->Show();
1132
1133 ui::test::EventGenerator generator(root_window);
1134
1135 // Cover the screen with two windows: a normal window on the left side and a
1136 // context menu on the right side. When the virtual keyboard is displayed it
1137 // partially occludes the normal window, but not the context menu. Compute
1138 // positions for generating synthetic click events to perform hit tests,
1139 // ensuring the correct window layering. 'top' is above the VK, whereas
1140 // 'bottom' lies within the VK. 'left' is centered in the normal window, and
1141 // 'right' is centered in the context menu.
1142 int window_height = keyboard_bounds.bottom();
1143 int window_width = keyboard_bounds.width() / 2;
1144 int left = window_width / 2;
1145 int right = 3 * window_width / 2;
1146 int top = keyboard_bounds.y() / 2;
1147 int bottom = window_height - keyboard_height / 2;
1148
1149 // Normal window is partially occluded by the virtual keyboard.
1150 aura::test::TestWindowDelegate delegate;
dchenga94547472016-04-08 08:41:111151 std::unique_ptr<aura::Window> normal(
1152 CreateTestWindowInShellWithDelegateAndType(
1153 &delegate, ui::wm::WINDOW_TYPE_NORMAL, 0,
1154 gfx::Rect(0, 0, window_width, window_height)));
kevers23f3987d2014-09-17 13:50:121155 normal->set_owned_by_parent(false);
1156 normal->Show();
1157 TargetHitTestEventHandler normal_handler;
1158 normal->AddPreTargetHandler(&normal_handler);
1159
1160 // Test that only the click on the top portion of the window is picked up. The
1161 // click on the bottom hits the virtual keyboard instead.
1162 generator.MoveMouseTo(left, top);
1163 generator.ClickLeftButton();
1164 EXPECT_EQ(1, normal_handler.num_mouse_events());
1165 generator.MoveMouseTo(left, bottom);
1166 generator.ClickLeftButton();
1167 EXPECT_EQ(1, normal_handler.num_mouse_events());
1168
1169 // Menu overlaps virtual keyboard.
1170 aura::test::TestWindowDelegate delegate2;
dchenga94547472016-04-08 08:41:111171 std::unique_ptr<aura::Window> menu(CreateTestWindowInShellWithDelegateAndType(
1172 &delegate2, ui::wm::WINDOW_TYPE_MENU, 0,
kevers23f3987d2014-09-17 13:50:121173 gfx::Rect(window_width, 0, window_width, window_height)));
1174 menu->set_owned_by_parent(false);
1175 menu->Show();
1176 TargetHitTestEventHandler menu_handler;
1177 menu->AddPreTargetHandler(&menu_handler);
1178
1179 // Test that both clicks register.
1180 generator.MoveMouseTo(right, top);
1181 generator.ClickLeftButton();
1182 EXPECT_EQ(1, menu_handler.num_mouse_events());
1183 generator.MoveMouseTo(right, bottom);
1184 generator.ClickLeftButton();
1185 EXPECT_EQ(2, menu_handler.num_mouse_events());
1186
1187 // Cleanup to ensure that the test windows are destroyed before their
1188 // delegates.
1189 normal.reset();
1190 menu.reset();
1191}
1192
kevers0e450492014-09-30 16:02:311193// Tests that the virtual keyboard correctly resizes with a change to display
1194// orientation. See crbug/417612.
jamescook01bf23e72017-01-09 19:58:151195TEST_F(VirtualKeyboardRootWindowControllerTest, DisplayRotation) {
kevers0e450492014-09-30 16:02:311196 UpdateDisplay("800x600");
1197 aura::Window* root_window = Shell::GetPrimaryRootWindow();
1198 aura::Window* keyboard_container =
1199 Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
1200 ASSERT_TRUE(keyboard_container);
bshea0a57802015-04-08 18:21:291201 keyboard::KeyboardController* keyboard_controller =
1202 keyboard::KeyboardController::GetInstance();
1203 keyboard_controller->ShowKeyboard(false);
ben974286a2015-10-10 00:45:121204 keyboard_controller->ui()->GetKeyboardWindow()->SetBounds(
bshea0a57802015-04-08 18:21:291205 gfx::Rect(0, 400, 800, 200));
1206 EXPECT_EQ("0,400 800x200", keyboard_container->bounds().ToString());
kevers0e450492014-09-30 16:02:311207
1208 UpdateDisplay("600x800");
bshea0a57802015-04-08 18:21:291209 EXPECT_EQ("0,600 600x200", keyboard_container->bounds().ToString());
kevers0e450492014-09-30 16:02:311210}
1211
[email protected]f1853122012-06-27 16:21:261212} // namespace test
1213} // namespace ash