1 // 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.
5 #include "ash/virtual_keyboard_controller.h"
10 #include "ash/system/chromeos/virtual_keyboard/virtual_keyboard_observer.h"
11 #include "ash/test/ash_test_base.h"
12 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
13 #include "ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard.h"
14 #include "base/command_line.h"
15 #include "ui/events/devices/device_data_manager.h"
16 #include "ui/events/devices/device_hotplug_event_observer.h"
17 #include "ui/events/devices/input_device.h"
18 #include "ui/events/devices/keyboard_device.h"
19 #include "ui/events/devices/touchscreen_device.h"
20 #include "ui/keyboard/keyboard_export.h"
21 #include "ui/keyboard/keyboard_switches.h"
22 #include "ui/keyboard/keyboard_util.h"
27 class VirtualKeyboardControllerTest
: public AshTestBase
{
29 VirtualKeyboardControllerTest() {}
30 virtual ~VirtualKeyboardControllerTest() {}
32 void UpdateTouchscreenDevices(
33 std::vector
<ui::TouchscreenDevice
> touchscreen_devices
) {
34 ui::DeviceHotplugEventObserver
* manager
=
35 ui::DeviceDataManager::GetInstance();
36 manager
->OnTouchscreenDevicesUpdated(touchscreen_devices
);
39 void UpdateKeyboardDevices(std::vector
<ui::KeyboardDevice
> keyboard_devices
) {
40 ui::DeviceHotplugEventObserver
* manager
=
41 ui::DeviceDataManager::GetInstance();
42 manager
->OnKeyboardDevicesUpdated(keyboard_devices
);
45 // Sets the event blocker on the maximized window controller.
47 scoped_ptr
<ScopedDisableInternalMouseAndKeyboard
> blocker
) {
49 ->maximize_mode_controller()
50 ->event_blocker_
= blocker
.Pass();
53 void SetUp() override
{
55 UpdateKeyboardDevices(std::vector
<ui::KeyboardDevice
>());
56 UpdateTouchscreenDevices(std::vector
<ui::TouchscreenDevice
>());
60 DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardControllerTest
);
63 TEST_F(VirtualKeyboardControllerTest
, EnabledDuringMaximizeMode
) {
64 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
65 // Toggle maximized mode on.
67 ->maximize_mode_controller()
68 ->EnableMaximizeModeWindowManager(true);
69 EXPECT_TRUE(keyboard::IsKeyboardEnabled());
70 // Toggle maximized mode off.
72 ->maximize_mode_controller()
73 ->EnableMaximizeModeWindowManager(false);
74 EXPECT_FALSE(keyboard::IsKeyboardEnabled());
77 // Mock event blocker that enables the internal keyboard when it's destructor
79 class MockEventBlocker
: public ScopedDisableInternalMouseAndKeyboard
{
82 ~MockEventBlocker() override
{
83 std::vector
<ui::KeyboardDevice
> keyboards
;
84 keyboards
.push_back(ui::KeyboardDevice(
85 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL
, "keyboard"));
86 ui::DeviceHotplugEventObserver
* manager
=
87 ui::DeviceDataManager::GetInstance();
88 manager
->OnKeyboardDevicesUpdated(keyboards
);
92 DISALLOW_COPY_AND_ASSIGN(MockEventBlocker
);
95 // Tests that reenabling keyboard devices while shutting down does not
96 // cause the Virtual Keyboard Controller to crash. See crbug.com/446204.
97 TEST_F(VirtualKeyboardControllerTest
, RestoreKeyboardDevices
) {
98 // Toggle maximized mode on.
100 ->maximize_mode_controller()
101 ->EnableMaximizeModeWindowManager(true);
102 scoped_ptr
<ScopedDisableInternalMouseAndKeyboard
>
103 blocker(new MockEventBlocker
);
104 SetEventBlocker(blocker
.Pass());
107 class VirtualKeyboardControllerAutoTest
: public VirtualKeyboardControllerTest
,
108 public VirtualKeyboardObserver
{
110 VirtualKeyboardControllerAutoTest() : notified_(false), suppressed_(false) {}
111 ~VirtualKeyboardControllerAutoTest() override
{}
113 void SetUp() override
{
114 base::CommandLine::ForCurrentProcess()->AppendSwitch(
115 keyboard::switches::kEnableAutoVirtualKeyboard
);
116 AshTestBase::SetUp();
117 // Set the current list of devices to empty so that they don't interfere
119 UpdateKeyboardDevices(std::vector
<ui::KeyboardDevice
>());
120 UpdateTouchscreenDevices(std::vector
<ui::TouchscreenDevice
>());
121 Shell::GetInstance()->system_tray_notifier()->AddVirtualKeyboardObserver(
125 void TearDown() override
{
126 Shell::GetInstance()->system_tray_notifier()->RemoveVirtualKeyboardObserver(
128 AshTestBase::TearDown();
131 void OnKeyboardSuppressionChanged(bool suppressed
) override
{
133 suppressed_
= suppressed
;
136 void ResetObserver() {
141 bool IsVirtualKeyboardSuppressed() { return suppressed_
; }
143 bool notified() { return notified_
; }
146 // Whether the observer method was called.
149 // Whether the keeyboard is suppressed.
152 DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardControllerAutoTest
);
155 // Tests that the onscreen keyboard is disabled if an internal keyboard is
157 TEST_F(VirtualKeyboardControllerAutoTest
, DisabledIfInternalKeyboardPresent
) {
158 std::vector
<ui::TouchscreenDevice
> screens
;
160 ui::TouchscreenDevice(1,
161 ui::InputDeviceType::INPUT_DEVICE_INTERNAL
,
163 gfx::Size(1024, 768)));
164 UpdateTouchscreenDevices(screens
);
165 std::vector
<ui::KeyboardDevice
> keyboards
;
166 keyboards
.push_back(ui::KeyboardDevice(
167 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL
, "keyboard"));
168 UpdateKeyboardDevices(keyboards
);
169 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
170 // Remove the internal keyboard. Virtual keyboard should now show.
171 UpdateKeyboardDevices(std::vector
<ui::KeyboardDevice
>());
172 EXPECT_TRUE(keyboard::IsKeyboardEnabled());
173 // Replug in the internal keyboard. Virtual keyboard should hide.
174 UpdateKeyboardDevices(keyboards
);
175 EXPECT_FALSE(keyboard::IsKeyboardEnabled());
178 TEST_F(VirtualKeyboardControllerAutoTest
, DisabledIfNoTouchScreen
) {
179 std::vector
<ui::TouchscreenDevice
> devices
;
180 // Add a touchscreen. Keyboard should deploy.
182 ui::TouchscreenDevice(1,
183 ui::InputDeviceType::INPUT_DEVICE_EXTERNAL
,
185 gfx::Size(800, 600)));
186 UpdateTouchscreenDevices(devices
);
187 EXPECT_TRUE(keyboard::IsKeyboardEnabled());
188 // Remove touchscreen. Keyboard should hide.
189 UpdateTouchscreenDevices(std::vector
<ui::TouchscreenDevice
>());
190 EXPECT_FALSE(keyboard::IsKeyboardEnabled());
193 TEST_F(VirtualKeyboardControllerAutoTest
, SuppressedIfExternalKeyboardPresent
) {
194 std::vector
<ui::TouchscreenDevice
> screens
;
196 ui::TouchscreenDevice(1,
197 ui::InputDeviceType::INPUT_DEVICE_INTERNAL
,
199 gfx::Size(1024, 768)));
200 UpdateTouchscreenDevices(screens
);
201 std::vector
<ui::KeyboardDevice
> keyboards
;
202 keyboards
.push_back(ui::KeyboardDevice(
203 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL
, "keyboard"));
204 UpdateKeyboardDevices(keyboards
);
205 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
206 ASSERT_TRUE(notified());
207 ASSERT_TRUE(IsVirtualKeyboardSuppressed());
208 // Toggle show keyboard. Keyboard should be visible.
211 ->virtual_keyboard_controller()
212 ->ToggleIgnoreExternalKeyboard();
213 ASSERT_TRUE(keyboard::IsKeyboardEnabled());
214 ASSERT_TRUE(notified());
215 ASSERT_TRUE(IsVirtualKeyboardSuppressed());
216 // Toggle show keyboard. Keyboard should be hidden.
219 ->virtual_keyboard_controller()
220 ->ToggleIgnoreExternalKeyboard();
221 ASSERT_FALSE(keyboard::IsKeyboardEnabled());
222 ASSERT_TRUE(notified());
223 ASSERT_TRUE(IsVirtualKeyboardSuppressed());
224 // Remove external keyboard. Should be notified that the keyboard is not
227 UpdateKeyboardDevices(std::vector
<ui::KeyboardDevice
>());
228 ASSERT_TRUE(keyboard::IsKeyboardEnabled());
229 ASSERT_TRUE(notified());
230 ASSERT_FALSE(IsVirtualKeyboardSuppressed());
233 // Tests handling multiple keyboards. Catches crbug.com/430252
234 TEST_F(VirtualKeyboardControllerAutoTest
, HandleMultipleKeyboardsPresent
) {
235 std::vector
<ui::KeyboardDevice
> keyboards
;
236 keyboards
.push_back(ui::KeyboardDevice(
237 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL
, "keyboard"));
238 keyboards
.push_back(ui::KeyboardDevice(
239 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL
, "keyboard"));
240 keyboards
.push_back(ui::KeyboardDevice(
241 3, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL
, "keyboard"));
242 UpdateKeyboardDevices(keyboards
);
243 ASSERT_FALSE(keyboard::IsKeyboardEnabled());