blob: 610c6d4047496106fd8a8182602d1d92a8740825 [file] [log] [blame]
bsheeaae09a2014-09-22 23:16:521// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ash/virtual_keyboard_controller.h"
6
dcheng22724952015-12-31 03:17:547#include <utility>
rsadambbaf2c82015-01-07 17:54:138#include <vector>
9
bsheeaae09a2014-09-22 23:16:5210#include "ash/shell.h"
rsadamc727b6a2014-10-31 18:59:3311#include "ash/system/chromeos/virtual_keyboard/virtual_keyboard_observer.h"
bsheeaae09a2014-09-22 23:16:5212#include "ash/test/ash_test_base.h"
13#include "ash/wm/maximize_mode/maximize_mode_controller.h"
rsadambbaf2c82015-01-07 17:54:1314#include "ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard.h"
rsadamf478ba762015-01-16 01:08:1115#include "ash_switches.h"
rsadam9172bc8a2014-10-29 23:37:3816#include "base/command_line.h"
dnicoara78a734702014-11-04 19:54:3817#include "ui/events/devices/device_data_manager.h"
18#include "ui/events/devices/device_hotplug_event_observer.h"
19#include "ui/events/devices/input_device.h"
20#include "ui/events/devices/keyboard_device.h"
21#include "ui/events/devices/touchscreen_device.h"
rsadam9172bc8a2014-10-29 23:37:3822#include "ui/keyboard/keyboard_export.h"
23#include "ui/keyboard/keyboard_switches.h"
bsheeaae09a2014-09-22 23:16:5224#include "ui/keyboard/keyboard_util.h"
25
26namespace ash {
27namespace test {
28
rsadam9172bc8a2014-10-29 23:37:3829class VirtualKeyboardControllerTest : public AshTestBase {
30 public:
31 VirtualKeyboardControllerTest() {}
dcheng222b9c72015-01-16 00:48:0132 ~VirtualKeyboardControllerTest() override {}
bsheeaae09a2014-09-22 23:16:5233
rsadam9172bc8a2014-10-29 23:37:3834 void UpdateTouchscreenDevices(
35 std::vector<ui::TouchscreenDevice> touchscreen_devices) {
36 ui::DeviceHotplugEventObserver* manager =
37 ui::DeviceDataManager::GetInstance();
38 manager->OnTouchscreenDevicesUpdated(touchscreen_devices);
39 }
40
41 void UpdateKeyboardDevices(std::vector<ui::KeyboardDevice> keyboard_devices) {
42 ui::DeviceHotplugEventObserver* manager =
43 ui::DeviceDataManager::GetInstance();
44 manager->OnKeyboardDevicesUpdated(keyboard_devices);
45 }
46
rsadambbaf2c82015-01-07 17:54:1347 // Sets the event blocker on the maximized window controller.
48 void SetEventBlocker(
49 scoped_ptr<ScopedDisableInternalMouseAndKeyboard> blocker) {
kpschoedel16ce3d882015-04-27 16:59:0050 Shell::GetInstance()->maximize_mode_controller()->event_blocker_ =
dcheng22724952015-12-31 03:17:5451 std::move(blocker);
rsadambbaf2c82015-01-07 17:54:1352 }
53
rsadam9172bc8a2014-10-29 23:37:3854 void SetUp() override {
flackr512a1032015-12-07 15:43:0555 base::CommandLine::ForCurrentProcess()->AppendSwitch(
56 keyboard::switches::kDisableSmartVirtualKeyboard);
rsadam9172bc8a2014-10-29 23:37:3857 AshTestBase::SetUp();
58 UpdateKeyboardDevices(std::vector<ui::KeyboardDevice>());
59 UpdateTouchscreenDevices(std::vector<ui::TouchscreenDevice>());
60 }
61
62 private:
63 DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardControllerTest);
64};
65
bsheeaae09a2014-09-22 23:16:5266TEST_F(VirtualKeyboardControllerTest, EnabledDuringMaximizeMode) {
67 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
rsadam9172bc8a2014-10-29 23:37:3868 // Toggle maximized mode on.
69 Shell::GetInstance()
70 ->maximize_mode_controller()
71 ->EnableMaximizeModeWindowManager(true);
bsheeaae09a2014-09-22 23:16:5272 EXPECT_TRUE(keyboard::IsKeyboardEnabled());
rsadam9172bc8a2014-10-29 23:37:3873 // Toggle maximized mode off.
74 Shell::GetInstance()
75 ->maximize_mode_controller()
76 ->EnableMaximizeModeWindowManager(false);
77 EXPECT_FALSE(keyboard::IsKeyboardEnabled());
78}
79
rsadambbaf2c82015-01-07 17:54:1380// Mock event blocker that enables the internal keyboard when it's destructor
81// is called.
82class MockEventBlocker : public ScopedDisableInternalMouseAndKeyboard {
83 public:
84 MockEventBlocker() {}
85 ~MockEventBlocker() override {
86 std::vector<ui::KeyboardDevice> keyboards;
kpschoedel16ce3d882015-04-27 16:59:0087 keyboards.push_back(ui::KeyboardDevice(
88 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard"));
rsadambbaf2c82015-01-07 17:54:1389 ui::DeviceHotplugEventObserver* manager =
90 ui::DeviceDataManager::GetInstance();
91 manager->OnKeyboardDevicesUpdated(keyboards);
92 }
93
94 private:
95 DISALLOW_COPY_AND_ASSIGN(MockEventBlocker);
96};
97
98// Tests that reenabling keyboard devices while shutting down does not
99// cause the Virtual Keyboard Controller to crash. See crbug.com/446204.
100TEST_F(VirtualKeyboardControllerTest, RestoreKeyboardDevices) {
101 // Toggle maximized mode on.
102 Shell::GetInstance()
103 ->maximize_mode_controller()
104 ->EnableMaximizeModeWindowManager(true);
kpschoedel16ce3d882015-04-27 16:59:00105 scoped_ptr<ScopedDisableInternalMouseAndKeyboard> blocker(
106 new MockEventBlocker);
dcheng22724952015-12-31 03:17:54107 SetEventBlocker(std::move(blocker));
rsadambbaf2c82015-01-07 17:54:13108}
109
rsadamc727b6a2014-10-31 18:59:33110class VirtualKeyboardControllerAutoTest : public VirtualKeyboardControllerTest,
111 public VirtualKeyboardObserver {
rsadam9172bc8a2014-10-29 23:37:38112 public:
rsadamc727b6a2014-10-31 18:59:33113 VirtualKeyboardControllerAutoTest() : notified_(false), suppressed_(false) {}
114 ~VirtualKeyboardControllerAutoTest() override {}
115
rsadam9172bc8a2014-10-29 23:37:38116 void SetUp() override {
rsadam47e23d22014-12-15 18:11:37117 AshTestBase::SetUp();
118 // Set the current list of devices to empty so that they don't interfere
119 // with the test.
120 UpdateKeyboardDevices(std::vector<ui::KeyboardDevice>());
121 UpdateTouchscreenDevices(std::vector<ui::TouchscreenDevice>());
rsadamc727b6a2014-10-31 18:59:33122 Shell::GetInstance()->system_tray_notifier()->AddVirtualKeyboardObserver(
123 this);
rsadam9172bc8a2014-10-29 23:37:38124 }
rsadamc727b6a2014-10-31 18:59:33125
126 void TearDown() override {
127 Shell::GetInstance()->system_tray_notifier()->RemoveVirtualKeyboardObserver(
128 this);
129 AshTestBase::TearDown();
130 }
131
132 void OnKeyboardSuppressionChanged(bool suppressed) override {
133 notified_ = true;
134 suppressed_ = suppressed;
135 }
136
137 void ResetObserver() {
138 suppressed_ = false;
139 notified_ = false;
140 }
141
142 bool IsVirtualKeyboardSuppressed() { return suppressed_; }
143
144 bool notified() { return notified_; }
145
146 private:
147 // Whether the observer method was called.
148 bool notified_;
149
150 // Whether the keeyboard is suppressed.
151 bool suppressed_;
152
153 DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardControllerAutoTest);
rsadam9172bc8a2014-10-29 23:37:38154};
155
156// Tests that the onscreen keyboard is disabled if an internal keyboard is
rsadamd4f6a0b2015-03-02 23:50:08157// present and maximized mode is disabled.
rsadam9172bc8a2014-10-29 23:37:38158TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfInternalKeyboardPresent) {
159 std::vector<ui::TouchscreenDevice> screens;
kpschoedel16ce3d882015-04-27 16:59:00160 screens.push_back(
161 ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
162 "Touchscreen", gfx::Size(1024, 768), 0));
rsadam9172bc8a2014-10-29 23:37:38163 UpdateTouchscreenDevices(screens);
164 std::vector<ui::KeyboardDevice> keyboards;
kpschoedel16ce3d882015-04-27 16:59:00165 keyboards.push_back(ui::KeyboardDevice(
166 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard"));
rsadam9172bc8a2014-10-29 23:37:38167 UpdateKeyboardDevices(keyboards);
168 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
169 // Remove the internal keyboard. Virtual keyboard should now show.
170 UpdateKeyboardDevices(std::vector<ui::KeyboardDevice>());
171 EXPECT_TRUE(keyboard::IsKeyboardEnabled());
172 // Replug in the internal keyboard. Virtual keyboard should hide.
173 UpdateKeyboardDevices(keyboards);
174 EXPECT_FALSE(keyboard::IsKeyboardEnabled());
175}
176
177TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfNoTouchScreen) {
178 std::vector<ui::TouchscreenDevice> devices;
179 // Add a touchscreen. Keyboard should deploy.
kpschoedel16ce3d882015-04-27 16:59:00180 devices.push_back(
181 ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL,
182 "Touchscreen", gfx::Size(800, 600), 0));
rsadam9172bc8a2014-10-29 23:37:38183 UpdateTouchscreenDevices(devices);
184 EXPECT_TRUE(keyboard::IsKeyboardEnabled());
185 // Remove touchscreen. Keyboard should hide.
186 UpdateTouchscreenDevices(std::vector<ui::TouchscreenDevice>());
bsheeaae09a2014-09-22 23:16:52187 EXPECT_FALSE(keyboard::IsKeyboardEnabled());
188}
189
rsadamc727b6a2014-10-31 18:59:33190TEST_F(VirtualKeyboardControllerAutoTest, SuppressedIfExternalKeyboardPresent) {
191 std::vector<ui::TouchscreenDevice> screens;
kpschoedel16ce3d882015-04-27 16:59:00192 screens.push_back(
193 ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
194 "Touchscreen", gfx::Size(1024, 768), 0));
rsadamc727b6a2014-10-31 18:59:33195 UpdateTouchscreenDevices(screens);
196 std::vector<ui::KeyboardDevice> keyboards;
kpschoedel16ce3d882015-04-27 16:59:00197 keyboards.push_back(ui::KeyboardDevice(
198 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard"));
rsadamc727b6a2014-10-31 18:59:33199 UpdateKeyboardDevices(keyboards);
200 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
201 ASSERT_TRUE(notified());
202 ASSERT_TRUE(IsVirtualKeyboardSuppressed());
203 // Toggle show keyboard. Keyboard should be visible.
204 ResetObserver();
205 Shell::GetInstance()
206 ->virtual_keyboard_controller()
207 ->ToggleIgnoreExternalKeyboard();
208 ASSERT_TRUE(keyboard::IsKeyboardEnabled());
209 ASSERT_TRUE(notified());
210 ASSERT_TRUE(IsVirtualKeyboardSuppressed());
211 // Toggle show keyboard. Keyboard should be hidden.
212 ResetObserver();
213 Shell::GetInstance()
214 ->virtual_keyboard_controller()
215 ->ToggleIgnoreExternalKeyboard();
216 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
217 ASSERT_TRUE(notified());
218 ASSERT_TRUE(IsVirtualKeyboardSuppressed());
219 // Remove external keyboard. Should be notified that the keyboard is not
220 // suppressed.
221 ResetObserver();
222 UpdateKeyboardDevices(std::vector<ui::KeyboardDevice>());
223 ASSERT_TRUE(keyboard::IsKeyboardEnabled());
224 ASSERT_TRUE(notified());
225 ASSERT_FALSE(IsVirtualKeyboardSuppressed());
226}
227
rsadamf9719972014-11-05 02:57:59228// Tests handling multiple keyboards. Catches crbug.com/430252
229TEST_F(VirtualKeyboardControllerAutoTest, HandleMultipleKeyboardsPresent) {
230 std::vector<ui::KeyboardDevice> keyboards;
kpschoedel16ce3d882015-04-27 16:59:00231 keyboards.push_back(ui::KeyboardDevice(
232 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard"));
233 keyboards.push_back(ui::KeyboardDevice(
234 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard"));
235 keyboards.push_back(ui::KeyboardDevice(
236 3, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard"));
rsadamf9719972014-11-05 02:57:59237 UpdateKeyboardDevices(keyboards);
238 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
239}
240
rsadamd4f6a0b2015-03-02 23:50:08241// Tests maximized mode interaction without disabling the internal keyboard.
242TEST_F(VirtualKeyboardControllerAutoTest, EnabledDuringMaximizeMode) {
243 std::vector<ui::TouchscreenDevice> screens;
kpschoedel16ce3d882015-04-27 16:59:00244 screens.push_back(
245 ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
246 "Touchscreen", gfx::Size(1024, 768), 0));
rsadamd4f6a0b2015-03-02 23:50:08247 UpdateTouchscreenDevices(screens);
248 std::vector<ui::KeyboardDevice> keyboards;
kpschoedel16ce3d882015-04-27 16:59:00249 keyboards.push_back(ui::KeyboardDevice(
250 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
rsadamd4f6a0b2015-03-02 23:50:08251 UpdateKeyboardDevices(keyboards);
252 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
253 // Toggle maximized mode on.
254 Shell::GetInstance()
255 ->maximize_mode_controller()
256 ->EnableMaximizeModeWindowManager(true);
257 ASSERT_TRUE(keyboard::IsKeyboardEnabled());
258 // Toggle maximized mode off.
259 Shell::GetInstance()
260 ->maximize_mode_controller()
261 ->EnableMaximizeModeWindowManager(false);
262 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
263}
264
265// Tests that keyboard gets suppressed in maximized mode.
266TEST_F(VirtualKeyboardControllerAutoTest, SuppressedInMaximizedMode) {
267 std::vector<ui::TouchscreenDevice> screens;
kpschoedel16ce3d882015-04-27 16:59:00268 screens.push_back(
269 ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
270 "Touchscreen", gfx::Size(1024, 768), 0));
rsadamd4f6a0b2015-03-02 23:50:08271 UpdateTouchscreenDevices(screens);
272 std::vector<ui::KeyboardDevice> keyboards;
kpschoedel16ce3d882015-04-27 16:59:00273 keyboards.push_back(ui::KeyboardDevice(
274 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
275 keyboards.push_back(ui::KeyboardDevice(
276 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "Keyboard"));
rsadamd4f6a0b2015-03-02 23:50:08277 UpdateKeyboardDevices(keyboards);
278 // Toggle maximized mode on.
279 Shell::GetInstance()
280 ->maximize_mode_controller()
281 ->EnableMaximizeModeWindowManager(true);
282 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
283 ASSERT_TRUE(notified());
284 ASSERT_TRUE(IsVirtualKeyboardSuppressed());
285 // Toggle show keyboard. Keyboard should be visible.
286 ResetObserver();
287 Shell::GetInstance()
288 ->virtual_keyboard_controller()
289 ->ToggleIgnoreExternalKeyboard();
290 ASSERT_TRUE(keyboard::IsKeyboardEnabled());
291 ASSERT_TRUE(notified());
292 ASSERT_TRUE(IsVirtualKeyboardSuppressed());
293 // Toggle show keyboard. Keyboard should be hidden.
294 ResetObserver();
295 Shell::GetInstance()
296 ->virtual_keyboard_controller()
297 ->ToggleIgnoreExternalKeyboard();
298 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
299 ASSERT_TRUE(notified());
300 ASSERT_TRUE(IsVirtualKeyboardSuppressed());
301 // Remove external keyboard. Should be notified that the keyboard is not
302 // suppressed.
303 ResetObserver();
304 keyboards.pop_back();
305 UpdateKeyboardDevices(keyboards);
306 ASSERT_TRUE(keyboard::IsKeyboardEnabled());
307 ASSERT_TRUE(notified());
308 ASSERT_FALSE(IsVirtualKeyboardSuppressed());
309 // Toggle maximized mode oFF.
310 Shell::GetInstance()
311 ->maximize_mode_controller()
312 ->EnableMaximizeModeWindowManager(false);
313 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
314}
315
rsadamf478ba762015-01-16 01:08:11316class VirtualKeyboardControllerAlwaysEnabledTest
317 : public VirtualKeyboardControllerAutoTest {
318 public:
319 VirtualKeyboardControllerAlwaysEnabledTest()
320 : VirtualKeyboardControllerAutoTest() {}
321 ~VirtualKeyboardControllerAlwaysEnabledTest() override {}
322
323 void SetUp() override {
324 base::CommandLine::ForCurrentProcess()->AppendSwitch(
325 keyboard::switches::kEnableVirtualKeyboard);
326 VirtualKeyboardControllerAutoTest::SetUp();
327 }
328
329 private:
330 DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardControllerAlwaysEnabledTest);
331};
332
333// Tests that the controller cannot suppress the keyboard if the virtual
334// keyboard always enabled flag is active.
335TEST_F(VirtualKeyboardControllerAlwaysEnabledTest, DoesNotSuppressKeyboard) {
336 std::vector<ui::TouchscreenDevice> screens;
kpschoedel16ce3d882015-04-27 16:59:00337 screens.push_back(
338 ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
339 "Touchscreen", gfx::Size(1024, 768), 0));
rsadamf478ba762015-01-16 01:08:11340 UpdateTouchscreenDevices(screens);
341 std::vector<ui::KeyboardDevice> keyboards;
kpschoedel16ce3d882015-04-27 16:59:00342 keyboards.push_back(ui::KeyboardDevice(
343 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard"));
rsadamf478ba762015-01-16 01:08:11344 UpdateKeyboardDevices(keyboards);
345 ASSERT_TRUE(keyboard::IsKeyboardEnabled());
346}
347
bsheeaae09a2014-09-22 23:16:52348} // namespace test
349} // namespace ash