1 // Copyright 2015 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 "components/exo/keyboard.h"
6
7 #include "ash/accessibility/accessibility_controller_impl.h"
8 #include "ash/public/cpp/ash_pref_names.h"
9 #include "ash/shell.h"
10 #include "ash/test/ash_test_helper.h"
11 #include "ash/wm/desks/desks_controller.h"
12 #include "ash/wm/desks/desks_test_util.h"
13 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
14 #include "base/macros.h"
15 #include "base/run_loop.h"
16 #include "components/exo/buffer.h"
17 #include "components/exo/keyboard_delegate.h"
18 #include "components/exo/keyboard_device_configuration_delegate.h"
19 #include "components/exo/keyboard_modifiers.h"
20 #include "components/exo/keyboard_observer.h"
21 #include "components/exo/seat.h"
22 #include "components/exo/shell_surface.h"
23 #include "components/exo/surface.h"
24 #include "components/exo/test/exo_test_base.h"
25 #include "components/exo/test/exo_test_helper.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "ui/aura/client/aura_constants.h"
28 #include "ui/aura/client/focus_client.h"
29 #include "ui/base/ime/dummy_text_input_client.h"
30 #include "ui/events/devices/device_data_manager.h"
31 #include "ui/events/event_constants.h"
32 #include "ui/events/keycodes/dom/dom_code.h"
33 #include "ui/events/test/event_generator.h"
34 #include "ui/events/types/event_type.h"
35
36 namespace exo {
37 namespace {
38
39 // XKB mod masks for the default keymap.
40 constexpr uint32_t kShiftMask = 1 << 0;
41 constexpr uint32_t kControlMask = 1 << 2;
42 constexpr uint32_t kAltMask = 1 << 3;
43 constexpr uint32_t kNumLockMask = 1 << 4;
44
45 using KeyboardTest = test::ExoTestBase;
46
47 class MockKeyboardDelegate : public KeyboardDelegate {
48 public:
49 MockKeyboardDelegate() = default;
50
51 // Overridden from KeyboardDelegate:
52 MOCK_METHOD(bool, CanAcceptKeyboardEventsForSurface, (Surface*), (const));
53 MOCK_METHOD(void,
54 OnKeyboardEnter,
55 (Surface*, (const base::flat_map<ui::DomCode, ui::DomCode>&)));
56 MOCK_METHOD(void, OnKeyboardLeave, (Surface*));
57 MOCK_METHOD(uint32_t, OnKeyboardKey, (base::TimeTicks, ui::DomCode, bool));
58 MOCK_METHOD(void, OnKeyboardModifiers, (const KeyboardModifiers&));
59 MOCK_METHOD(void,
60 OnKeyRepeatSettingsChanged,
61 (bool, base::TimeDelta, base::TimeDelta));
62 MOCK_METHOD(void, OnKeyboardLayoutUpdated, (base::StringPiece));
63 };
64 using NiceMockKeyboardDelegate = ::testing::NiceMock<MockKeyboardDelegate>;
65
66 class MockKeyboardDeviceConfigurationDelegate
67 : public KeyboardDeviceConfigurationDelegate {
68 public:
69 MockKeyboardDeviceConfigurationDelegate() = default;
70
71 // Overridden from KeyboardDeviceConfigurationDelegate:
72 MOCK_METHOD(void, OnKeyboardTypeChanged, (bool));
73 };
74
75 class MockKeyboardObserver : public KeyboardObserver {
76 public:
77 MockKeyboardObserver() = default;
78
79 // Overridden from KeyboardObserver:
80 MOCK_METHOD(void, OnKeyboardDestroying, (Keyboard*));
81 };
82
83 class TestShellSurface : public ShellSurface {
84 public:
TestShellSurface(Surface * surface)85 explicit TestShellSurface(Surface* surface) : ShellSurface(surface) {}
86
87 MOCK_METHOD(bool, AcceleratorPressed, (const ui::Accelerator& accelerator));
88 };
89
90 // Verifies that switching desks via alt-tab doesn't prevent Seat from receiving
91 // key events. https://crbug.com/1008574.
TEST_F(KeyboardTest,CorrectSeatPressedKeysOnSwitchingDesks)92 TEST_F(KeyboardTest, CorrectSeatPressedKeysOnSwitchingDesks) {
93 Seat seat;
94 Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);
95
96 // Create 2 desks.
97 auto* desks_controller = ash::DesksController::Get();
98 desks_controller->NewDesk(ash::DesksCreationRemovalSource::kButton);
99 ASSERT_EQ(2u, desks_controller->desks().size());
100 ash::Desk* desk_1 = desks_controller->desks()[0].get();
101 const ash::Desk* desk_2 = desks_controller->desks()[1].get();
102 // Desk 1 has a normal window.
103 auto win0 = CreateAppWindow(gfx::Rect(0, 0, 250, 100));
104
105 // Desk 2 has an exo surface window.
106 ash::ActivateDesk(desk_2);
107 std::unique_ptr<Surface> surface(new Surface);
108 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
109 gfx::Size buffer_size(10, 10);
110 std::unique_ptr<Buffer> buffer(
111 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
112 surface->Attach(buffer.get());
113 surface->Commit();
114
115 // Go back to desk 1, and trigger an alt-tab (releasing alt first). This would
116 // trigger activating the exo surface window on desk 2, which would lead to a
117 // desk switch animation. During the animation, expect that Seat gets all the
118 // keys in `OnKeyEvent()`, and the |pressed_keys_| map is correctly updated.
119 ash::ActivateDesk(desk_1);
120 auto displatch_key_event = [&](ui::EventType type, ui::KeyboardCode key_code,
121 ui::DomCode code, int flags) {
122 ui::KeyEvent key_event{type, key_code, code, flags};
123 seat.WillProcessEvent(&key_event);
124 GetEventGenerator()->Dispatch(&key_event);
125
126 EXPECT_EQ(type != ui::ET_KEY_RELEASED, seat.pressed_keys().count(code));
127
128 seat.DidProcessEvent(&key_event);
129 };
130
131 ash::DeskSwitchAnimationWaiter waiter;
132 displatch_key_event(ui::ET_KEY_PRESSED, ui::VKEY_MENU, ui::DomCode::ALT_LEFT,
133 /*flags=*/0);
134 displatch_key_event(ui::ET_KEY_PRESSED, ui::VKEY_TAB, ui::DomCode::TAB,
135 /*flags=*/ui::EF_ALT_DOWN);
136 displatch_key_event(ui::ET_KEY_RELEASED, ui::VKEY_MENU, ui::DomCode::ALT_LEFT,
137 /*flags=*/0);
138 displatch_key_event(ui::ET_KEY_RELEASED, ui::VKEY_TAB, ui::DomCode::TAB,
139 /*flags=*/0);
140
141 EXPECT_TRUE(seat.pressed_keys().empty());
142 EXPECT_EQ(desk_2, desks_controller->GetTargetActiveDesk());
143 waiter.Wait();
144 }
145
TEST_F(KeyboardTest,OnKeyboardEnter)146 TEST_F(KeyboardTest, OnKeyboardEnter) {
147 std::unique_ptr<Surface> surface(new Surface);
148 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
149 gfx::Size buffer_size(10, 10);
150 std::unique_ptr<Buffer> buffer(
151 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
152 surface->Attach(buffer.get());
153 surface->Commit();
154
155 Seat seat;
156 // Pressing key before Keyboard instance is created and surface has
157 // received focus.
158 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
159 seat.set_physical_code_for_currently_processing_event_for_testing(
160 ui::DomCode::US_A);
161 generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
162
163 aura::client::FocusClient* focus_client =
164 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
165 focus_client->FocusWindow(surface->window());
166
167 // Keyboard should try to set initial focus to surface.
168 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
169 auto* delegate_ptr = delegate.get();
170 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
171 .WillOnce(testing::Return(false));
172 Keyboard keyboard(std::move(delegate), &seat);
173 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
174
175 // Set up expectation for the key release.
176 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
177 .WillOnce(testing::Return(true));
178 EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
179 kShiftMask | kNumLockMask, 0, 0, 0}));
180 EXPECT_CALL(*delegate_ptr,
181 OnKeyboardEnter(surface.get(),
182 base::flat_map<ui::DomCode, ui::DomCode>(
183 {{ui::DomCode::US_A, ui::DomCode::US_A}})));
184 focus_client->FocusWindow(nullptr);
185 focus_client->FocusWindow(surface->window());
186 // Surface should maintain keyboard focus when moved to top-level window.
187 focus_client->FocusWindow(surface->window()->GetToplevelWindow());
188
189 // Release key after surface lost focus.
190 focus_client->FocusWindow(nullptr);
191 generator.ReleaseKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
192 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
193
194 // Key should no longer be pressed when focus returns.
195 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
196 .WillOnce(testing::Return(true));
197 EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
198 kShiftMask | kNumLockMask, 0, 0, 0}));
199 EXPECT_CALL(*delegate_ptr,
200 OnKeyboardEnter(surface.get(),
201 base::flat_map<ui::DomCode, ui::DomCode>()));
202 focus_client->FocusWindow(surface->window()->GetToplevelWindow());
203 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
204 }
205
TEST_F(KeyboardTest,OnKeyboardLeave)206 TEST_F(KeyboardTest, OnKeyboardLeave) {
207 std::unique_ptr<Surface> surface(new Surface);
208 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
209 gfx::Size buffer_size(10, 10);
210 std::unique_ptr<Buffer> buffer(
211 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
212 surface->Attach(buffer.get());
213 surface->Commit();
214
215 aura::client::FocusClient* focus_client =
216 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
217 focus_client->FocusWindow(nullptr);
218
219 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
220 auto* delegate_ptr = delegate.get();
221 Seat seat;
222 auto keyboard = std::make_unique<Keyboard>(std::move(delegate), &seat);
223 ON_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
224 .WillByDefault(testing::Return(true));
225
226 EXPECT_CALL(*delegate_ptr,
227 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
228 EXPECT_CALL(*delegate_ptr,
229 OnKeyboardEnter(surface.get(),
230 base::flat_map<ui::DomCode, ui::DomCode>()));
231 focus_client->FocusWindow(surface->window());
232 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
233
234 EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));
235 focus_client->FocusWindow(nullptr);
236 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
237
238 EXPECT_CALL(*delegate_ptr,
239 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
240 EXPECT_CALL(*delegate_ptr,
241 OnKeyboardEnter(surface.get(),
242 base::flat_map<ui::DomCode, ui::DomCode>()));
243 focus_client->FocusWindow(surface->window());
244 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
245
246 EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));
247 shell_surface.reset();
248 surface.reset();
249 // Verify before destroying keyboard to make sure the expected call
250 // is made on the methods above, rather than in the destructor.
251 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
252 }
253
TEST_F(KeyboardTest,OnKeyboardKey)254 TEST_F(KeyboardTest, OnKeyboardKey) {
255 std::unique_ptr<Surface> surface(new Surface);
256 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
257 gfx::Size buffer_size(10, 10);
258 std::unique_ptr<Buffer> buffer(
259 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
260 surface->Attach(buffer.get());
261 surface->Commit();
262
263 aura::client::FocusClient* focus_client =
264 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
265 focus_client->FocusWindow(nullptr);
266
267 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
268 auto* delegate_ptr = delegate.get();
269 Seat seat;
270 Keyboard keyboard(std::move(delegate), &seat);
271
272 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
273 .WillOnce(testing::Return(true));
274 EXPECT_CALL(*delegate_ptr,
275 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
276 EXPECT_CALL(*delegate_ptr,
277 OnKeyboardEnter(surface.get(),
278 base::flat_map<ui::DomCode, ui::DomCode>()));
279 focus_client->FocusWindow(surface->window());
280 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
281
282 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
283 // This should only generate a press event for KEY_A.
284 EXPECT_CALL(*delegate_ptr,
285 OnKeyboardKey(testing::_, ui::DomCode::US_A, true));
286 seat.set_physical_code_for_currently_processing_event_for_testing(
287 ui::DomCode::US_A);
288 generator.PressKey(ui::VKEY_A, 0);
289 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
290
291 // This should not generate another press event for KEY_A.
292 generator.PressKey(ui::VKEY_A, 0);
293 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
294
295 // This should only generate a single release event for KEY_A.
296 EXPECT_CALL(*delegate_ptr,
297 OnKeyboardKey(testing::_, ui::DomCode::US_A, false));
298 generator.ReleaseKey(ui::VKEY_A, 0);
299 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
300
301 // Test key event rewriting. In this case, ARROW_DOWN is rewritten to KEY_END
302 // as a result of ALT being pressed.
303 EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::END, true));
304 EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
305 kAltMask | kNumLockMask, 0, 0, 0}));
306 seat.set_physical_code_for_currently_processing_event_for_testing(
307 ui::DomCode::ARROW_DOWN);
308 generator.PressKey(ui::VKEY_END, ui::EF_ALT_DOWN);
309 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
310
311 // This should generate a release event for KEY_END as that is the key
312 // associated with the key press.
313 EXPECT_CALL(*delegate_ptr,
314 OnKeyboardKey(testing::_, ui::DomCode::END, false));
315 EXPECT_CALL(*delegate_ptr,
316 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
317 generator.ReleaseKey(ui::VKEY_DOWN, 0);
318 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
319
320 // Press accelerator after surface lost focus.
321 EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));
322 focus_client->FocusWindow(nullptr);
323 seat.set_physical_code_for_currently_processing_event_for_testing(
324 ui::DomCode::US_W);
325 generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
326 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
327
328 // Key should be pressed when focus returns.
329 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
330 .WillOnce(testing::Return(true));
331 EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
332 kControlMask | kNumLockMask, 0, 0, 0}));
333 EXPECT_CALL(*delegate_ptr,
334 OnKeyboardEnter(surface.get(),
335 base::flat_map<ui::DomCode, ui::DomCode>(
336 {{ui::DomCode::US_W, ui::DomCode::US_W}})));
337 focus_client->FocusWindow(surface->window());
338 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
339
340 // Releasing accelerator when surface has focus should generate event.
341 EXPECT_CALL(*delegate_ptr,
342 OnKeyboardKey(testing::_, ui::DomCode::US_W, false));
343 generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
344 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
345
346 // Key events should be ignored when the focused window is not an
347 // exo::Surface.
348 auto window = CreateChildWindow(shell_surface->GetWidget()->GetNativeWindow(),
349 gfx::Rect(buffer_size));
350 // Moving the focus away will trigger the fallback path in GetEffectiveFocus.
351 // TODO(oshima): Consider removing the fallback path.
352 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
353 .WillOnce(testing::Return(true));
354 focus_client->FocusWindow(window.get());
355 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
356
357 EXPECT_CALL(*delegate_ptr,
358 OnKeyboardKey(testing::_, ui::DomCode::ARROW_LEFT, true))
359 .Times(0);
360 seat.set_physical_code_for_currently_processing_event_for_testing(
361 ui::DomCode::ARROW_LEFT);
362 generator.PressKey(ui::VKEY_LEFT, 0);
363 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
364
365 EXPECT_CALL(*delegate_ptr,
366 OnKeyboardKey(testing::_, ui::DomCode::ARROW_LEFT, false))
367 .Times(0);
368 generator.ReleaseKey(ui::VKEY_LEFT, 0);
369 // Verify before destroying keyboard to make sure the expected call
370 // is made on the methods above, rather than in the destructor.
371 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
372 }
373
TEST_F(KeyboardTest,OnKeyboardKey_NotSendKeyIfConsumedByIme)374 TEST_F(KeyboardTest, OnKeyboardKey_NotSendKeyIfConsumedByIme) {
375 std::unique_ptr<Surface> surface(new Surface);
376 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
377 gfx::Size buffer_size(10, 10);
378 std::unique_ptr<Buffer> buffer(
379 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
380 surface->Attach(buffer.get());
381 surface->Commit();
382
383 aura::client::FocusClient* focus_client =
384 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
385 focus_client->FocusWindow(nullptr);
386
387 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
388 auto* delegate_ptr = delegate.get();
389 Seat seat;
390 Keyboard keyboard(std::move(delegate), &seat);
391
392 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
393 .WillOnce(testing::Return(true));
394 EXPECT_CALL(*delegate_ptr,
395 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
396 EXPECT_CALL(*delegate_ptr,
397 OnKeyboardEnter(surface.get(),
398 base::flat_map<ui::DomCode, ui::DomCode>()));
399 focus_client->FocusWindow(surface->window());
400 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
401
402 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
403 views::Widget* widget =
404 views::Widget::GetTopLevelWidgetForNativeView(surface->window());
405 ui::InputMethod* input_method = widget->GetInputMethod();
406 ui::DummyTextInputClient client{ui::TEXT_INPUT_TYPE_TEXT};
407 input_method->SetFocusedTextInputClient(&client);
408
409 // If a text field is focused, a pressed key event is not sent to a client
410 // because a key event should be consumed by the IME.
411 EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_A, true))
412 .Times(0);
413 seat.set_physical_code_for_currently_processing_event_for_testing(
414 ui::DomCode::US_A);
415 generator.PressKey(ui::VKEY_A, 0);
416 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
417
418 // TODO(yhanada): The below EXPECT_CALL fails because exo::Keyboard currently
419 // sends a key release event for the keys which exo::Keyboard sent a pressed
420 // event for. It might causes a never-ending key repeat in the client.
421 // EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_A, false));
422 generator.ReleaseKey(ui::VKEY_A, 0);
423
424 // Any key event should be sent to a client if the focused window is marked as
425 // ImeBlocking.
426 WMHelper::GetInstance()->SetImeBlocked(surface->window()->GetToplevelWindow(),
427 true);
428 EXPECT_CALL(*delegate_ptr,
429 OnKeyboardKey(testing::_, ui::DomCode::US_B, true));
430 seat.set_physical_code_for_currently_processing_event_for_testing(
431 ui::DomCode::US_B);
432 generator.PressKey(ui::VKEY_B, 0);
433 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
434
435 EXPECT_CALL(*delegate_ptr,
436 OnKeyboardKey(testing::_, ui::DomCode::US_B, false));
437 generator.ReleaseKey(ui::VKEY_B, 0);
438 WMHelper::GetInstance()->SetImeBlocked(surface->window()->GetToplevelWindow(),
439 false);
440 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
441
442 // Any key event should be sent to a client if a key event skips IME.
443 surface->window()->SetProperty(aura::client::kSkipImeProcessing, true);
444 EXPECT_CALL(*delegate_ptr,
445 OnKeyboardKey(testing::_, ui::DomCode::US_C, true));
446 seat.set_physical_code_for_currently_processing_event_for_testing(
447 ui::DomCode::US_C);
448 generator.PressKey(ui::VKEY_C, 0);
449 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
450
451 EXPECT_CALL(*delegate_ptr,
452 OnKeyboardKey(testing::_, ui::DomCode::US_C, false));
453 generator.ReleaseKey(ui::VKEY_C, 0);
454 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
455
456 input_method->SetFocusedTextInputClient(nullptr);
457 }
458
TEST_F(KeyboardTest,OnKeyboardModifiers)459 TEST_F(KeyboardTest, OnKeyboardModifiers) {
460 std::unique_ptr<Surface> surface(new Surface);
461 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
462 gfx::Size buffer_size(10, 10);
463 std::unique_ptr<Buffer> buffer(
464 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
465 surface->Attach(buffer.get());
466 surface->Commit();
467
468 aura::client::FocusClient* focus_client =
469 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
470 focus_client->FocusWindow(nullptr);
471
472 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
473 auto* delegate_ptr = delegate.get();
474 Seat seat;
475 Keyboard keyboard(std::move(delegate), &seat);
476
477 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
478 .WillOnce(testing::Return(true));
479 EXPECT_CALL(*delegate_ptr,
480 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
481 EXPECT_CALL(*delegate_ptr,
482 OnKeyboardEnter(surface.get(),
483 base::flat_map<ui::DomCode, ui::DomCode>()));
484 focus_client->FocusWindow(surface->window());
485 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
486
487 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
488 // This should generate a modifier event.
489 EXPECT_CALL(*delegate_ptr,
490 OnKeyboardKey(testing::_, ui::DomCode::US_A, true));
491 EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
492 kShiftMask | kNumLockMask, 0, 0, 0}));
493 seat.set_physical_code_for_currently_processing_event_for_testing(
494 ui::DomCode::US_A);
495 generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
496 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
497
498 // This should generate another modifier event.
499 EXPECT_CALL(*delegate_ptr,
500 OnKeyboardKey(testing::_, ui::DomCode::US_B, true));
501 EXPECT_CALL(*delegate_ptr,
502 OnKeyboardModifiers(KeyboardModifiers{
503 kShiftMask | kAltMask | kNumLockMask, 0, 0, 0}));
504 seat.set_physical_code_for_currently_processing_event_for_testing(
505 ui::DomCode::US_B);
506 generator.PressKey(ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
507 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
508
509 // This should generate a third modifier event.
510 EXPECT_CALL(*delegate_ptr,
511 OnKeyboardKey(testing::_, ui::DomCode::US_B, false));
512 EXPECT_CALL(*delegate_ptr,
513 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
514 generator.ReleaseKey(ui::VKEY_B, 0);
515 // Verify before destroying keyboard to make sure the expected call
516 // is made on the methods above, rather than in the destructor.
517 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
518 }
519
TEST_F(KeyboardTest,OnKeyboardTypeChanged)520 TEST_F(KeyboardTest, OnKeyboardTypeChanged) {
521 std::unique_ptr<Surface> surface(new Surface);
522 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
523 gfx::Size buffer_size(10, 10);
524 std::unique_ptr<Buffer> buffer(
525 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
526 surface->Attach(buffer.get());
527 surface->Commit();
528
529 aura::client::FocusClient* focus_client =
530 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
531 focus_client->FocusWindow(nullptr);
532
533 ui::DeviceHotplugEventObserver* device_data_manager =
534 ui::DeviceDataManager::GetInstance();
535 ASSERT_TRUE(device_data_manager != nullptr);
536 // Make sure that DeviceDataManager has one external keyboard...
537 const std::vector<ui::InputDevice> keyboards{
538 ui::InputDevice(2, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard")};
539 device_data_manager->OnKeyboardDevicesUpdated(keyboards);
540 // and a touch screen.
541 const std::vector<ui::TouchscreenDevice> touch_screen{
542 ui::TouchscreenDevice(3, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
543 "touch", gfx::Size(600, 400), 1)};
544 device_data_manager->OnTouchscreenDevicesUpdated(touch_screen);
545
546 ash::TabletModeController* tablet_mode_controller =
547 ash::Shell::Get()->tablet_mode_controller();
548 tablet_mode_controller->SetEnabledForTest(true);
549
550 Seat seat;
551 auto keyboard = std::make_unique<Keyboard>(
552 std::make_unique<NiceMockKeyboardDelegate>(), &seat);
553
554 MockKeyboardDeviceConfigurationDelegate configuration_delegate;
555
556 EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
557 keyboard->SetDeviceConfigurationDelegate(&configuration_delegate);
558 EXPECT_TRUE(keyboard->HasDeviceConfigurationDelegate());
559 testing::Mock::VerifyAndClearExpectations(&configuration_delegate);
560
561 // Removing all keyboard devices in tablet mode calls
562 // OnKeyboardTypeChanged() with false.
563 EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(false));
564 device_data_manager->OnKeyboardDevicesUpdated(
565 std::vector<ui::InputDevice>({}));
566 testing::Mock::VerifyAndClearExpectations(&configuration_delegate);
567
568 // Re-adding keyboards calls OnKeyboardTypeChanged() with true.
569 EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
570 device_data_manager->OnKeyboardDevicesUpdated(keyboards);
571 testing::Mock::VerifyAndClearExpectations(&configuration_delegate);
572
573 keyboard.reset();
574
575 tablet_mode_controller->SetEnabledForTest(false);
576 }
577
TEST_F(KeyboardTest,OnKeyboardTypeChanged_AccessibilityKeyboard)578 TEST_F(KeyboardTest, OnKeyboardTypeChanged_AccessibilityKeyboard) {
579 std::unique_ptr<Surface> surface(new Surface);
580 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
581 gfx::Size buffer_size(10, 10);
582 std::unique_ptr<Buffer> buffer(
583 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
584 surface->Attach(buffer.get());
585 surface->Commit();
586
587 aura::client::FocusClient* focus_client =
588 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
589 focus_client->FocusWindow(nullptr);
590
591 ui::DeviceHotplugEventObserver* device_data_manager =
592 ui::DeviceDataManager::GetInstance();
593 ASSERT_TRUE(device_data_manager != nullptr);
594 // Make sure that DeviceDataManager has one external keyboard.
595 const std::vector<ui::InputDevice> keyboards{
596 ui::InputDevice(2, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard")};
597 device_data_manager->OnKeyboardDevicesUpdated(keyboards);
598
599 Seat seat;
600 Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);
601 MockKeyboardDeviceConfigurationDelegate configuration_delegate;
602
603 EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
604 keyboard.SetDeviceConfigurationDelegate(&configuration_delegate);
605 EXPECT_TRUE(keyboard.HasDeviceConfigurationDelegate());
606 testing::Mock::VerifyAndClearExpectations(&configuration_delegate);
607
608 ash::AccessibilityControllerImpl* accessibility_controller =
609 ash::Shell::Get()->accessibility_controller();
610
611 // Enable a11y keyboard calls OnKeyboardTypeChanged() with false.
612 EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(false));
613 accessibility_controller->virtual_keyboard().SetEnabled(true);
614 testing::Mock::VerifyAndClearExpectations(&configuration_delegate);
615
616 // Disable a11y keyboard calls OnKeyboardTypeChanged() with true.
617 EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
618 accessibility_controller->virtual_keyboard().SetEnabled(false);
619 // Verify before destroying keyboard to make sure the expected call
620 // is made on the methods above, rather than in the destructor.
621 testing::Mock::VerifyAndClearExpectations(&configuration_delegate);
622 }
623
624 constexpr base::TimeDelta kDelta50Ms = base::TimeDelta::FromMilliseconds(50);
625 constexpr base::TimeDelta kDelta500Ms = base::TimeDelta::FromMilliseconds(500);
626 constexpr base::TimeDelta kDelta1000Ms =
627 base::TimeDelta::FromMilliseconds(1000);
628
TEST_F(KeyboardTest,KeyRepeatSettingsLoadDefaults)629 TEST_F(KeyboardTest, KeyRepeatSettingsLoadDefaults) {
630 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
631 EXPECT_CALL(*delegate,
632 OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms));
633
634 Seat seat;
635 Keyboard keyboard(std::move(delegate), &seat);
636 }
637
TEST_F(KeyboardTest,KeyRepeatSettingsLoadInitially)638 TEST_F(KeyboardTest, KeyRepeatSettingsLoadInitially) {
639 std::string email = "user0@tray";
640 SetUserPref(email, ash::prefs::kXkbAutoRepeatEnabled, base::Value(true));
641 SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000));
642 SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000));
643
644 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
645 auto* delegate_ptr = delegate.get();
646 EXPECT_CALL(*delegate_ptr,
647 OnKeyRepeatSettingsChanged(true, kDelta1000Ms, kDelta1000Ms));
648 Seat seat;
649 Keyboard keyboard(std::move(delegate), &seat);
650 // Verify before destroying keyboard to make sure the expected call
651 // is made on the methods above, rather than in the destructor.
652 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
653 }
654
TEST_F(KeyboardTest,KeyRepeatSettingsUpdateAtRuntime)655 TEST_F(KeyboardTest, KeyRepeatSettingsUpdateAtRuntime) {
656 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
657 auto* delegate_ptr = delegate.get();
658 // Initially load defaults.
659 EXPECT_CALL(*delegate_ptr,
660 OnKeyRepeatSettingsChanged(testing::_, testing::_, testing::_));
661 Seat seat;
662 Keyboard keyboard(std::move(delegate), &seat);
663 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
664
665 // Make sure that setting prefs triggers the corresponding delegate calls.
666 const std::string email = "user0@tray";
667
668 EXPECT_CALL(*delegate_ptr,
669 OnKeyRepeatSettingsChanged(false, testing::_, testing::_));
670 SetUserPref(email, ash::prefs::kXkbAutoRepeatEnabled, base::Value(false));
671 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
672
673 EXPECT_CALL(*delegate_ptr,
674 OnKeyRepeatSettingsChanged(false, kDelta1000Ms, testing::_));
675 SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000));
676 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
677
678 EXPECT_CALL(*delegate_ptr,
679 OnKeyRepeatSettingsChanged(false, kDelta1000Ms, kDelta1000Ms));
680 SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000));
681 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
682 }
683
TEST_F(KeyboardTest,KeyRepeatSettingsIgnoredForNonActiveUser)684 TEST_F(KeyboardTest, KeyRepeatSettingsIgnoredForNonActiveUser) {
685 // Simulate two users, with the first user as active.
686 CreateUserSessions(2);
687
688 // Key repeat settings should be sent exactly once, for the default values.
689 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
690 auto* delegate_ptr = delegate.get();
691 EXPECT_CALL(*delegate_ptr,
692 OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms));
693 Seat seat;
694 Keyboard keyboard(std::move(delegate), &seat);
695 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
696
697 // Set prefs for non-active user; no calls should result.
698 EXPECT_CALL(*delegate_ptr,
699 OnKeyRepeatSettingsChanged(testing::_, testing::_, testing::_))
700 .Times(0);
701 const std::string email = "user1@tray";
702 SetUserPref(email, ash::prefs::kXkbAutoRepeatEnabled, base::Value(true));
703 SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000));
704 SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000));
705 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
706 }
707
TEST_F(KeyboardTest,KeyRepeatSettingsUpdateOnProfileChange)708 TEST_F(KeyboardTest, KeyRepeatSettingsUpdateOnProfileChange) {
709 // Simulate two users, with the first user as active.
710 CreateUserSessions(2);
711
712 // Second user has different preferences.
713 std::string email = "user1@tray";
714 SetUserPref(email, ash::prefs::kXkbAutoRepeatEnabled, base::Value(true));
715 SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000));
716 SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000));
717
718 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
719 auto* delegate_ptr = delegate.get();
720 // Initially, load default prefs for first user.
721 EXPECT_CALL(*delegate_ptr,
722 OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms));
723 Seat seat;
724 Keyboard keyboard(std::move(delegate), &seat);
725 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
726
727 // Switching user should load new prefs.
728 EXPECT_CALL(*delegate_ptr,
729 OnKeyRepeatSettingsChanged(true, kDelta1000Ms, kDelta1000Ms));
730 SimulateUserLogin(email, user_manager::UserType::USER_TYPE_REGULAR);
731 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
732 }
733
TEST_F(KeyboardTest,KeyboardLayout)734 TEST_F(KeyboardTest, KeyboardLayout) {
735 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
736 auto* delegate_ptr = delegate.get();
737 // Initially, update to the current keyboard layout.
738 EXPECT_CALL(*delegate_ptr, OnKeyboardLayoutUpdated(testing::_));
739 Seat seat;
740 Keyboard keyboard(std::move(delegate), &seat);
741 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
742
743 // Updating the keyboard layout should trigger the delegate call.
744 EXPECT_CALL(*delegate_ptr, OnKeyboardLayoutUpdated(testing::_));
745 keyboard.OnKeyboardLayoutNameChanged("ja-jp");
746 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
747 }
748
TEST_F(KeyboardTest,KeyboardObserver)749 TEST_F(KeyboardTest, KeyboardObserver) {
750 // Declare before the keyboard so the mock verification happens
751 // after the keyboard destruction.
752 MockKeyboardObserver observer1;
753 MockKeyboardObserver observer2;
754
755 Seat seat;
756 Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);
757
758 keyboard.AddObserver(&observer1);
759 keyboard.AddObserver(&observer2);
760 EXPECT_TRUE(keyboard.HasObserver(&observer1));
761 EXPECT_TRUE(keyboard.HasObserver(&observer2));
762 testing::Mock::VerifyAndClearExpectations(&observer1);
763 testing::Mock::VerifyAndClearExpectations(&observer2);
764
765 keyboard.RemoveObserver(&observer1);
766 EXPECT_FALSE(keyboard.HasObserver(&observer1));
767 EXPECT_TRUE(keyboard.HasObserver(&observer2));
768 testing::Mock::VerifyAndClearExpectations(&observer1);
769 testing::Mock::VerifyAndClearExpectations(&observer2);
770
771 // Called from the destructor of Keyboard.
772 EXPECT_CALL(observer1, OnKeyboardDestroying(&keyboard)).Times(0);
773 EXPECT_CALL(observer2, OnKeyboardDestroying(&keyboard));
774 }
775
TEST_F(KeyboardTest,NeedKeyboardKeyAcks)776 TEST_F(KeyboardTest, NeedKeyboardKeyAcks) {
777 std::unique_ptr<Surface> surface(new Surface);
778 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
779 gfx::Size buffer_size(10, 10);
780 std::unique_ptr<Buffer> buffer(
781 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
782 surface->Attach(buffer.get());
783 surface->Commit();
784
785 aura::client::FocusClient* focus_client =
786 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
787 focus_client->FocusWindow(nullptr);
788
789 Seat seat;
790 Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);
791
792 EXPECT_FALSE(keyboard.AreKeyboardKeyAcksNeeded());
793 keyboard.SetNeedKeyboardKeyAcks(true);
794 EXPECT_TRUE(keyboard.AreKeyboardKeyAcksNeeded());
795 keyboard.SetNeedKeyboardKeyAcks(false);
796 EXPECT_FALSE(keyboard.AreKeyboardKeyAcksNeeded());
797 }
798
TEST_F(KeyboardTest,AckKeyboardKey)799 TEST_F(KeyboardTest, AckKeyboardKey) {
800 std::unique_ptr<Surface> surface(new Surface);
801 auto shell_surface = std::make_unique<TestShellSurface>(surface.get());
802 gfx::Size buffer_size(10, 10);
803 std::unique_ptr<Buffer> buffer(
804 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
805 surface->Attach(buffer.get());
806 surface->Commit();
807
808 aura::client::FocusClient* focus_client =
809 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
810 focus_client->FocusWindow(nullptr);
811
812 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
813 auto* delegate_ptr = delegate.get();
814 Seat seat;
815 Keyboard keyboard(std::move(delegate), &seat);
816 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
817
818 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
819 .WillOnce(testing::Return(true));
820 EXPECT_CALL(*delegate_ptr,
821 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
822 EXPECT_CALL(*delegate_ptr,
823 OnKeyboardEnter(surface.get(),
824 base::flat_map<ui::DomCode, ui::DomCode>()));
825 focus_client->FocusWindow(surface->window());
826 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
827
828 // If we don't set NeedKeyboardAckKeys to true, accelerators are always passed
829 // to ShellSurface.
830 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
831 // Press KEY_W with Ctrl.
832 EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
833 kControlMask | kNumLockMask, 0, 0, 0}));
834 EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
835 ui::VKEY_W, ui::EF_CONTROL_DOWN,
836 ui::Accelerator::KeyState::PRESSED)))
837 .WillOnce(testing::Return(true));
838 seat.set_physical_code_for_currently_processing_event_for_testing(
839 ui::DomCode::US_W);
840 generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
841
842 // Release KEY_W.
843 generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
844 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
845 testing::Mock::VerifyAndClearExpectations(shell_surface.get());
846
847 // If we set NeedKeyboardAckKeys to true, only unhandled accelerators are
848 // passed to ShellSurface.
849 keyboard.SetNeedKeyboardKeyAcks(true);
850
851 // Press KEY_W with Ctrl.
852 EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
853 .WillOnce(testing::Return(1));
854 generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
855 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
856
857 // Send ack for the key press.
858 EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
859 ui::VKEY_W, ui::EF_CONTROL_DOWN,
860 ui::Accelerator::KeyState::PRESSED)))
861 .WillOnce(testing::Return(true));
862 keyboard.AckKeyboardKey(1, false /* handled */);
863 testing::Mock::VerifyAndClearExpectations(shell_surface.get());
864
865 // Release KEY_W.
866 EXPECT_CALL(*delegate_ptr,
867 OnKeyboardKey(testing::_, ui::DomCode::US_W, false))
868 .WillOnce(testing::Return(2));
869 generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
870 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
871
872 // Send ack for the key release.
873 keyboard.AckKeyboardKey(2, false /* handled */);
874
875 // Press KEY_W with Ctrl again.
876 EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
877 .WillOnce(testing::Return(3));
878 generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
879 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
880
881 // Send ack for the key press.
882 // AcceleratorPressed is not called when the accelerator is already handled.
883 keyboard.AckKeyboardKey(3, true /* handled */);
884
885 // A repeat key event should not be sent to the client and also should not
886 // invoke the accelerator.
887 EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
888 ui::VKEY_W, ui::EF_CONTROL_DOWN,
889 ui::Accelerator::KeyState::PRESSED)))
890 .Times(0);
891 generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT);
892 testing::Mock::VerifyAndClearExpectations(shell_surface.get());
893
894 // Another key press event while holding the key is also ignored and should
895 // not invoke the accelerator.
896 EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
897 ui::VKEY_W, ui::EF_CONTROL_DOWN,
898 ui::Accelerator::KeyState::PRESSED)))
899 .Times(0);
900 generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
901 testing::Mock::VerifyAndClearExpectations(shell_surface.get());
902
903 // Release the key and reset modifier_flags.
904 EXPECT_CALL(*delegate_ptr,
905 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
906 EXPECT_CALL(*delegate_ptr,
907 OnKeyboardKey(testing::_, ui::DomCode::US_W, false));
908 generator.ReleaseKey(ui::VKEY_W, 0);
909 // Verify before destroying keyboard to make sure the expected call
910 // is made on the methods above, rather than in the destructor.
911 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
912 }
913
TEST_F(KeyboardTest,AckKeyboardKeyMoveFocus)914 TEST_F(KeyboardTest, AckKeyboardKeyMoveFocus) {
915 std::unique_ptr<Surface> surface(new Surface);
916 auto shell_surface = std::make_unique<TestShellSurface>(surface.get());
917 gfx::Size buffer_size(10, 10);
918 std::unique_ptr<Buffer> buffer(
919 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
920 surface->Attach(buffer.get());
921 surface->Commit();
922
923 aura::client::FocusClient* focus_client =
924 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
925 focus_client->FocusWindow(nullptr);
926
927 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
928 auto* delegate_ptr = delegate.get();
929 Seat seat;
930 Keyboard keyboard(std::move(delegate), &seat);
931
932 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
933 .WillOnce(testing::Return(true));
934 EXPECT_CALL(*delegate_ptr,
935 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
936 EXPECT_CALL(*delegate_ptr,
937 OnKeyboardEnter(surface.get(),
938 base::flat_map<ui::DomCode, ui::DomCode>()));
939 focus_client->FocusWindow(surface->window());
940 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
941
942 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
943 keyboard.SetNeedKeyboardKeyAcks(true);
944
945 // Press KEY_W with Ctrl.
946 EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
947 kControlMask | kNumLockMask, 0, 0, 0}))
948 .Times(1);
949 EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
950 .WillOnce(testing::Return(1));
951 seat.set_physical_code_for_currently_processing_event_for_testing(
952 ui::DomCode::US_W);
953 generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
954 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
955
956 // Move focus from the window
957 EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));
958 focus_client->FocusWindow(nullptr);
959 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
960
961 // Send ack for the key press. |AcceleratorPressed()| should not be called.
962 keyboard.AckKeyboardKey(1, false /* handled */);
963 }
964
TEST_F(KeyboardTest,AckKeyboardKeyExpired)965 TEST_F(KeyboardTest, AckKeyboardKeyExpired) {
966 std::unique_ptr<Surface> surface(new Surface);
967 auto shell_surface = std::make_unique<TestShellSurface>(surface.get());
968 gfx::Size buffer_size(10, 10);
969 std::unique_ptr<Buffer> buffer(
970 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
971 surface->Attach(buffer.get());
972 surface->Commit();
973
974 aura::client::FocusClient* focus_client =
975 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
976 focus_client->FocusWindow(nullptr);
977
978 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
979 auto* delegate_ptr = delegate.get();
980 Seat seat;
981 Keyboard keyboard(std::move(delegate), &seat);
982
983 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
984 .WillOnce(testing::Return(true));
985 EXPECT_CALL(*delegate_ptr,
986 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
987 EXPECT_CALL(*delegate_ptr,
988 OnKeyboardEnter(surface.get(),
989 base::flat_map<ui::DomCode, ui::DomCode>()));
990 focus_client->FocusWindow(surface->window());
991 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
992
993 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
994 keyboard.SetNeedKeyboardKeyAcks(true);
995
996 // Press KEY_W with Ctrl.
997 EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
998 kControlMask | kNumLockMask, 0, 0, 0}));
999 EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
1000 .WillOnce(testing::Return(1));
1001 seat.set_physical_code_for_currently_processing_event_for_testing(
1002 ui::DomCode::US_W);
1003 generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
1004 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
1005
1006 // Keyboard processes pending events as if it is handled when it expires,
1007 // so |AcceleratorPressed()| should not be called.
1008 EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
1009 ui::VKEY_W, ui::EF_CONTROL_DOWN,
1010 ui::Accelerator::KeyState::PRESSED)))
1011 .Times(0);
1012
1013 // Wait until |ProcessExpiredPendingKeyAcks| is fired.
1014 base::RunLoop run_loop;
1015 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1016 FROM_HERE, run_loop.QuitClosure(),
1017 base::TimeDelta::FromMilliseconds(1000));
1018 run_loop.Run();
1019 base::RunLoop().RunUntilIdle();
1020
1021 // Send ack for the key press as if it was not handled. In the normal case,
1022 // |AcceleratorPressed()| should be called, but since the timeout passed, the
1023 // key should have been treated as handled already and removed from the
1024 // pending_key_acks_ map. Since the event is no longer in the map,
1025 // |AcceleratorPressed()| should not be called.
1026 keyboard.AckKeyboardKey(1, false /* handled */);
1027
1028 // Release the key and reset modifier_flags.
1029 EXPECT_CALL(*delegate_ptr,
1030 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
1031 EXPECT_CALL(*delegate_ptr,
1032 OnKeyboardKey(testing::_, ui::DomCode::US_W, false));
1033 generator.ReleaseKey(ui::VKEY_W, 0);
1034 // Verify before destroying keyboard to make sure the expected call
1035 // is made on the methods above, rather than in the destructor.
1036 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
1037 }
1038
1039 // Test for crbug.com/753539. If action for an accelerator moves the focus to
1040 // another window, it causes clearing the map of pending key acks in Keyboard.
1041 // We can't assume that an iterator of the map is valid after processing an
1042 // accelerator.
1043 class TestShellSurfaceWithMovingFocusAccelerator : public ShellSurface {
1044 public:
TestShellSurfaceWithMovingFocusAccelerator(Surface * surface)1045 explicit TestShellSurfaceWithMovingFocusAccelerator(Surface* surface)
1046 : ShellSurface(surface) {}
1047
AcceleratorPressed(const ui::Accelerator & accelerator)1048 bool AcceleratorPressed(const ui::Accelerator& accelerator) override {
1049 aura::client::FocusClient* focus_client =
1050 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
1051 focus_client->FocusWindow(nullptr);
1052 return true;
1053 }
1054 };
1055
TEST_F(KeyboardTest,AckKeyboardKeyExpiredWithMovingFocusAccelerator)1056 TEST_F(KeyboardTest, AckKeyboardKeyExpiredWithMovingFocusAccelerator) {
1057 std::unique_ptr<Surface> surface(new Surface);
1058 auto shell_surface =
1059 std::make_unique<TestShellSurfaceWithMovingFocusAccelerator>(
1060 surface.get());
1061 gfx::Size buffer_size(10, 10);
1062 std::unique_ptr<Buffer> buffer(
1063 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
1064 surface->Attach(buffer.get());
1065 surface->Commit();
1066
1067 aura::client::FocusClient* focus_client =
1068 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
1069 focus_client->FocusWindow(nullptr);
1070
1071 auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
1072 auto* delegate_ptr = delegate.get();
1073 Seat seat;
1074 Keyboard keyboard(std::move(delegate), &seat);
1075
1076 EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
1077 .WillOnce(testing::Return(true));
1078 EXPECT_CALL(*delegate_ptr,
1079 OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
1080 EXPECT_CALL(*delegate_ptr,
1081 OnKeyboardEnter(surface.get(),
1082 base::flat_map<ui::DomCode, ui::DomCode>()));
1083 focus_client->FocusWindow(surface->window());
1084 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
1085
1086 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
1087 keyboard.SetNeedKeyboardKeyAcks(true);
1088
1089 // Press KEY_W with Ctrl.
1090 EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
1091 kControlMask | kNumLockMask, 0, 0, 0}));
1092 EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
1093 .WillOnce(testing::Return(1));
1094 seat.set_physical_code_for_currently_processing_event_for_testing(
1095 ui::DomCode::US_W);
1096 generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
1097 testing::Mock::VerifyAndClearExpectations(delegate_ptr);
1098
1099 EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));
1100
1101 // Send ack as unhandled. This will call |AcceleratorPressed| and move the
1102 // focus.
1103 keyboard.AckKeyboardKey(1, false /* handled */);
1104
1105 // Wait until |ProcessExpiredPendingKeyAcks| is fired.
1106 base::RunLoop run_loop;
1107 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1108 FROM_HERE, run_loop.QuitClosure(),
1109 base::TimeDelta::FromMilliseconds(1000));
1110 run_loop.Run();
1111 base::RunLoop().RunUntilIdle();
1112
1113 // Verify before destroying keyboard to make sure the expected call
1114 // is made on the methods above, rather than in the destructor.
1115 testing::Mock::VerifyAndClearExpectations(&delegate);
1116 }
1117 } // namespace
1118 } // namespace exo
1119