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