Commit 0fbe4abc authored by Hidehiko Abe's avatar Hidehiko Abe Committed by Commit Bot

exo: Simplifies WaylandKeyboardDelegate lifetime management.

It is just the delegate of Keyboard, so instead of using
the observer, this CL just defers the lifetime management
of WaylandKeyboardDelegate to Keyboard.
This allows us to remove the inheritance of KeyboardObserver
from WaylandKeyboardDelegate.

BUG=1123705
TEST=Ran exo_unittests.

Change-Id: I45b35a016edc3c7bd441223f1b25a28ad1debaa3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2416476
Commit-Queue: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: default avatarJun Mukai <mukai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808192}
parent 424e0563
...@@ -589,14 +589,16 @@ TEST_F(ArcNotificationContentViewTest, AcceptInputTextWithActivate) { ...@@ -589,14 +589,16 @@ TEST_F(ArcNotificationContentViewTest, AcceptInputTextWithActivate) {
ActivateArcNotification(); ActivateArcNotification();
EXPECT_EQ(surface()->window(), GetFocusedWindow()); EXPECT_EQ(surface()->window(), GetFocusedWindow());
MockKeyboardDelegate delegate; auto delegate = std::make_unique<MockKeyboardDelegate>();
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface())) auto* delegate_ptr = delegate.get();
EXPECT_CALL(*delegate, CanAcceptKeyboardEventsForSurface(surface()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
exo::Seat seat; exo::Seat seat;
auto keyboard = std::make_unique<exo::Keyboard>(&delegate, &seat); auto keyboard = std::make_unique<exo::Keyboard>(std::move(delegate), &seat);
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_A, true)); EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_A, true));
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_A); ui::DomCode::US_A);
generator.PressKey(ui::VKEY_A, 0); generator.PressKey(ui::VKEY_A, 0);
...@@ -615,13 +617,15 @@ TEST_F(ArcNotificationContentViewTest, NotAcceptInputTextWithoutActivate) { ...@@ -615,13 +617,15 @@ TEST_F(ArcNotificationContentViewTest, NotAcceptInputTextWithoutActivate) {
CreateAndShowNotificationView(notification); CreateAndShowNotificationView(notification);
EXPECT_FALSE(GetFocusedWindow()); EXPECT_FALSE(GetFocusedWindow());
MockKeyboardDelegate delegate; auto delegate = std::make_unique<MockKeyboardDelegate>();
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface())).Times(0); auto* delegate_ptr = delegate.get();
EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface()))
.Times(0);
exo::Seat seat; exo::Seat seat;
auto keyboard = std::make_unique<exo::Keyboard>(&delegate, &seat); auto keyboard = std::make_unique<exo::Keyboard>(std::move(delegate), &seat);
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, testing::_, testing::_)) EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, testing::_, testing::_))
.Times(0); .Times(0);
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_A); ui::DomCode::US_A);
......
...@@ -165,8 +165,8 @@ bool IsArcSurface(Surface* surface) { ...@@ -165,8 +165,8 @@ bool IsArcSurface(Surface* surface) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Keyboard, public: // Keyboard, public:
Keyboard::Keyboard(KeyboardDelegate* delegate, Seat* seat) Keyboard::Keyboard(std::unique_ptr<KeyboardDelegate> delegate, Seat* seat)
: delegate_(delegate), : delegate_(std::move(delegate)),
seat_(seat), seat_(seat),
expiration_delay_for_pending_key_acks_(base::TimeDelta::FromMilliseconds( expiration_delay_for_pending_key_acks_(base::TimeDelta::FromMilliseconds(
kExpirationDelayForPendingKeyAcksMs)) { kExpirationDelayForPendingKeyAcksMs)) {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef COMPONENTS_EXO_KEYBOARD_H_ #ifndef COMPONENTS_EXO_KEYBOARD_H_
#define COMPONENTS_EXO_KEYBOARD_H_ #define COMPONENTS_EXO_KEYBOARD_H_
#include <vector> #include <memory>
#include "ash/public/cpp/keyboard/keyboard_controller_observer.h" #include "ash/public/cpp/keyboard/keyboard_controller_observer.h"
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
...@@ -36,10 +36,10 @@ class Keyboard : public ui::EventHandler, ...@@ -36,10 +36,10 @@ class Keyboard : public ui::EventHandler,
public SeatObserver, public SeatObserver,
public ash::KeyboardControllerObserver { public ash::KeyboardControllerObserver {
public: public:
Keyboard(KeyboardDelegate* delegate, Seat* seat); Keyboard(std::unique_ptr<KeyboardDelegate> delegate, Seat* seat);
~Keyboard() override; ~Keyboard() override;
KeyboardDelegate* delegate() const { return delegate_; } KeyboardDelegate* delegate() const { return delegate_.get(); }
bool HasDeviceConfigurationDelegate() const; bool HasDeviceConfigurationDelegate() const;
void SetDeviceConfigurationDelegate( void SetDeviceConfigurationDelegate(
...@@ -91,7 +91,7 @@ class Keyboard : public ui::EventHandler, ...@@ -91,7 +91,7 @@ class Keyboard : public ui::EventHandler,
// The delegate instance that all events except for events about device // The delegate instance that all events except for events about device
// configuration are dispatched to. // configuration are dispatched to.
KeyboardDelegate* const delegate_; std::unique_ptr<KeyboardDelegate> delegate_;
// Seat that the Keyboard recieves focus events from. // Seat that the Keyboard recieves focus events from.
Seat* const seat_; Seat* const seat_;
......
...@@ -19,6 +19,8 @@ class Surface; ...@@ -19,6 +19,8 @@ class Surface;
// Handles events on keyboards in context-specific ways. // Handles events on keyboards in context-specific ways.
class KeyboardDelegate { class KeyboardDelegate {
public: public:
virtual ~KeyboardDelegate() = default;
// This should return true if |surface| is a valid target for this keyboard. // This should return true if |surface| is a valid target for this keyboard.
// E.g. the surface is owned by the same client as the keyboard. // E.g. the surface is owned by the same client as the keyboard.
virtual bool CanAcceptKeyboardEventsForSurface(Surface* surface) const = 0; virtual bool CanAcceptKeyboardEventsForSurface(Surface* surface) const = 0;
...@@ -46,9 +48,6 @@ class KeyboardDelegate { ...@@ -46,9 +48,6 @@ class KeyboardDelegate {
virtual void OnKeyRepeatSettingsChanged(bool enabled, virtual void OnKeyRepeatSettingsChanged(bool enabled,
base::TimeDelta delay, base::TimeDelta delay,
base::TimeDelta interval) = 0; base::TimeDelta interval) = 0;
protected:
virtual ~KeyboardDelegate() {}
}; };
} // namespace exo } // namespace exo
......
...@@ -42,7 +42,6 @@ class MockKeyboardDelegate : public KeyboardDelegate { ...@@ -42,7 +42,6 @@ class MockKeyboardDelegate : public KeyboardDelegate {
MockKeyboardDelegate() = default; MockKeyboardDelegate() = default;
// Overridden from KeyboardDelegate: // Overridden from KeyboardDelegate:
MOCK_METHOD(void, OnKeyboardDestroying, (Keyboard*));
MOCK_METHOD(bool, CanAcceptKeyboardEventsForSurface, (Surface*), (const)); MOCK_METHOD(bool, CanAcceptKeyboardEventsForSurface, (Surface*), (const));
MOCK_METHOD(void, MOCK_METHOD(void,
OnKeyboardEnter, OnKeyboardEnter,
...@@ -62,7 +61,6 @@ class MockKeyboardDeviceConfigurationDelegate ...@@ -62,7 +61,6 @@ class MockKeyboardDeviceConfigurationDelegate
MockKeyboardDeviceConfigurationDelegate() = default; MockKeyboardDeviceConfigurationDelegate() = default;
// Overridden from KeyboardDeviceConfigurationDelegate: // Overridden from KeyboardDeviceConfigurationDelegate:
MOCK_METHOD(void, OnKeyboardDestroying, (Keyboard*));
MOCK_METHOD(void, OnKeyboardTypeChanged, (bool)); MOCK_METHOD(void, OnKeyboardTypeChanged, (bool));
}; };
...@@ -85,8 +83,7 @@ class TestShellSurface : public ShellSurface { ...@@ -85,8 +83,7 @@ class TestShellSurface : public ShellSurface {
// key events. https://crbug.com/1008574. // key events. https://crbug.com/1008574.
TEST_F(KeyboardTest, CorrectSeatPressedKeysOnSwitchingDesks) { TEST_F(KeyboardTest, CorrectSeatPressedKeysOnSwitchingDesks) {
Seat seat; Seat seat;
NiceMockKeyboardDelegate delegate; Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat);
// Create 2 desks. // Create 2 desks.
auto* desks_controller = ash::DesksController::Get(); auto* desks_controller = ash::DesksController::Get();
...@@ -160,16 +157,17 @@ TEST_F(KeyboardTest, OnKeyboardEnter) { ...@@ -160,16 +157,17 @@ TEST_F(KeyboardTest, OnKeyboardEnter) {
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
// Keyboard should try to set initial focus to surface. // Keyboard should try to set initial focus to surface.
NiceMockKeyboardDelegate delegate; auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) auto* delegate_ptr = delegate.get();
EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(false)); .WillOnce(testing::Return(false));
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(ui::EF_SHIFT_DOWN)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(ui::EF_SHIFT_DOWN));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>( base::flat_map<ui::DomCode, ui::DomCode>(
{{ui::DomCode::US_A, ui::DomCode::US_A}}))); {{ui::DomCode::US_A, ui::DomCode::US_A}})));
...@@ -181,17 +179,17 @@ TEST_F(KeyboardTest, OnKeyboardEnter) { ...@@ -181,17 +179,17 @@ TEST_F(KeyboardTest, OnKeyboardEnter) {
// Release key after surface lost focus. // Release key after surface lost focus.
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
generator.ReleaseKey(ui::VKEY_A, ui::EF_SHIFT_DOWN); generator.ReleaseKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Key should no longer be pressed when focus returns. // Key should no longer be pressed when focus returns.
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(ui::EF_SHIFT_DOWN)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(ui::EF_SHIFT_DOWN));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>())); base::flat_map<ui::DomCode, ui::DomCode>()));
focus_client->FocusWindow(surface->window()->GetToplevelWindow()); focus_client->FocusWindow(surface->window()->GetToplevelWindow());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
} }
TEST_F(KeyboardTest, OnKeyboardLeave) { TEST_F(KeyboardTest, OnKeyboardLeave) {
...@@ -207,34 +205,37 @@ TEST_F(KeyboardTest, OnKeyboardLeave) { ...@@ -207,34 +205,37 @@ TEST_F(KeyboardTest, OnKeyboardLeave) {
aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
NiceMockKeyboardDelegate delegate; auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
auto* delegate_ptr = delegate.get();
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); auto keyboard = std::make_unique<Keyboard>(std::move(delegate), &seat);
ON_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) ON_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillByDefault(testing::Return(true)); .WillByDefault(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>())); base::flat_map<ui::DomCode, ui::DomCode>()));
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
EXPECT_CALL(delegate, OnKeyboardLeave(surface.get())); EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>())); base::flat_map<ui::DomCode, ui::DomCode>()));
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
EXPECT_CALL(delegate, OnKeyboardLeave(surface.get())); EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));
shell_surface.reset(); shell_surface.reset();
surface.reset(); surface.reset();
testing::Mock::VerifyAndClearExpectations(&delegate); // Verify before destroying keyboard to make sure the expected call
// is made on the methods above, rather than in the destructor.
testing::Mock::VerifyAndClearExpectations(delegate_ptr);
} }
TEST_F(KeyboardTest, OnKeyboardKey) { TEST_F(KeyboardTest, OnKeyboardKey) {
...@@ -250,75 +251,80 @@ TEST_F(KeyboardTest, OnKeyboardKey) { ...@@ -250,75 +251,80 @@ TEST_F(KeyboardTest, OnKeyboardKey) {
aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
NiceMockKeyboardDelegate delegate; auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
auto* delegate_ptr = delegate.get();
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>())); base::flat_map<ui::DomCode, ui::DomCode>()));
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
// This should only generate a press event for KEY_A. // This should only generate a press event for KEY_A.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_A, true)); EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_A, true));
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_A); ui::DomCode::US_A);
generator.PressKey(ui::VKEY_A, 0); generator.PressKey(ui::VKEY_A, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// This should not generate another press event for KEY_A. // This should not generate another press event for KEY_A.
generator.PressKey(ui::VKEY_A, 0); generator.PressKey(ui::VKEY_A, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// This should only generate a single release event for KEY_A. // This should only generate a single release event for KEY_A.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_A, false)); EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_A, false));
generator.ReleaseKey(ui::VKEY_A, 0); generator.ReleaseKey(ui::VKEY_A, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Test key event rewriting. In this case, ARROW_DOWN is rewritten to KEY_END // Test key event rewriting. In this case, ARROW_DOWN is rewritten to KEY_END
// as a result of ALT being pressed. // as a result of ALT being pressed.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::END, true)); EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::END, true));
EXPECT_CALL(delegate, OnKeyboardModifiers(ui::EF_ALT_DOWN)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(ui::EF_ALT_DOWN));
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::ARROW_DOWN); ui::DomCode::ARROW_DOWN);
generator.PressKey(ui::VKEY_END, ui::EF_ALT_DOWN); generator.PressKey(ui::VKEY_END, ui::EF_ALT_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// This should generate a release event for KEY_END as that is the key // This should generate a release event for KEY_END as that is the key
// associated with the key press. // associated with the key press.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::END, false)); EXPECT_CALL(*delegate_ptr,
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); OnKeyboardKey(testing::_, ui::DomCode::END, false));
EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
generator.ReleaseKey(ui::VKEY_DOWN, 0); generator.ReleaseKey(ui::VKEY_DOWN, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Press accelerator after surface lost focus. // Press accelerator after surface lost focus.
EXPECT_CALL(delegate, OnKeyboardLeave(surface.get())); EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_W); ui::DomCode::US_W);
generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN); generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Key should be pressed when focus returns. // Key should be pressed when focus returns.
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(ui::EF_CONTROL_DOWN)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(ui::EF_CONTROL_DOWN));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>( base::flat_map<ui::DomCode, ui::DomCode>(
{{ui::DomCode::US_W, ui::DomCode::US_W}}))); {{ui::DomCode::US_W, ui::DomCode::US_W}})));
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Releasing accelerator when surface has focus should generate event. // Releasing accelerator when surface has focus should generate event.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_W, false)); EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_W, false));
generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN); generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Key events should be ignored when the focused window is not an // Key events should be ignored when the focused window is not an
// exo::Surface. // exo::Surface.
...@@ -326,24 +332,26 @@ TEST_F(KeyboardTest, OnKeyboardKey) { ...@@ -326,24 +332,26 @@ TEST_F(KeyboardTest, OnKeyboardKey) {
gfx::Rect(buffer_size)); gfx::Rect(buffer_size));
// Moving the focus away will trigger the fallback path in GetEffectiveFocus. // Moving the focus away will trigger the fallback path in GetEffectiveFocus.
// TODO(oshima): Consider removing the fallback path. // TODO(oshima): Consider removing the fallback path.
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
focus_client->FocusWindow(window.get()); focus_client->FocusWindow(window.get());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::ARROW_LEFT, true)) OnKeyboardKey(testing::_, ui::DomCode::ARROW_LEFT, true))
.Times(0); .Times(0);
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::ARROW_LEFT); ui::DomCode::ARROW_LEFT);
generator.PressKey(ui::VKEY_LEFT, 0); generator.PressKey(ui::VKEY_LEFT, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::ARROW_LEFT, false)) OnKeyboardKey(testing::_, ui::DomCode::ARROW_LEFT, false))
.Times(0); .Times(0);
generator.ReleaseKey(ui::VKEY_LEFT, 0); generator.ReleaseKey(ui::VKEY_LEFT, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); // Verify before destroying keyboard to make sure the expected call
// is made on the methods above, rather than in the destructor.
testing::Mock::VerifyAndClearExpectations(delegate_ptr);
} }
TEST_F(KeyboardTest, OnKeyboardKey_NotSendKeyIfConsumedByIme) { TEST_F(KeyboardTest, OnKeyboardKey_NotSendKeyIfConsumedByIme) {
...@@ -359,18 +367,19 @@ TEST_F(KeyboardTest, OnKeyboardKey_NotSendKeyIfConsumedByIme) { ...@@ -359,18 +367,19 @@ TEST_F(KeyboardTest, OnKeyboardKey_NotSendKeyIfConsumedByIme) {
aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
NiceMockKeyboardDelegate delegate; auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
auto* delegate_ptr = delegate.get();
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>())); base::flat_map<ui::DomCode, ui::DomCode>()));
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
views::Widget* widget = views::Widget* widget =
...@@ -381,12 +390,12 @@ TEST_F(KeyboardTest, OnKeyboardKey_NotSendKeyIfConsumedByIme) { ...@@ -381,12 +390,12 @@ TEST_F(KeyboardTest, OnKeyboardKey_NotSendKeyIfConsumedByIme) {
// If a text field is focused, a pressed key event is not sent to a client // If a text field is focused, a pressed key event is not sent to a client
// because a key event should be consumed by the IME. // because a key event should be consumed by the IME.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_A, true)) EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_A, true))
.Times(0); .Times(0);
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_A); ui::DomCode::US_A);
generator.PressKey(ui::VKEY_A, 0); generator.PressKey(ui::VKEY_A, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// TODO(yhanada): The below EXPECT_CALL fails because exo::Keyboard currently // TODO(yhanada): The below EXPECT_CALL fails because exo::Keyboard currently
// sends a key release event for the keys which exo::Keyboard sent a pressed // sends a key release event for the keys which exo::Keyboard sent a pressed
...@@ -398,29 +407,33 @@ TEST_F(KeyboardTest, OnKeyboardKey_NotSendKeyIfConsumedByIme) { ...@@ -398,29 +407,33 @@ TEST_F(KeyboardTest, OnKeyboardKey_NotSendKeyIfConsumedByIme) {
// ImeBlocking. // ImeBlocking.
WMHelper::GetInstance()->SetImeBlocked(surface->window()->GetToplevelWindow(), WMHelper::GetInstance()->SetImeBlocked(surface->window()->GetToplevelWindow(),
true); true);
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_B, true)); EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_B, true));
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_B); ui::DomCode::US_B);
generator.PressKey(ui::VKEY_B, 0); generator.PressKey(ui::VKEY_B, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_B, false)); EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_B, false));
generator.ReleaseKey(ui::VKEY_B, 0); generator.ReleaseKey(ui::VKEY_B, 0);
WMHelper::GetInstance()->SetImeBlocked(surface->window()->GetToplevelWindow(), WMHelper::GetInstance()->SetImeBlocked(surface->window()->GetToplevelWindow(),
false); false);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Any key event should be sent to a client if a key event skips IME. // Any key event should be sent to a client if a key event skips IME.
surface->window()->SetProperty(aura::client::kSkipImeProcessing, true); surface->window()->SetProperty(aura::client::kSkipImeProcessing, true);
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_C, true)); EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_C, true));
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_C); ui::DomCode::US_C);
generator.PressKey(ui::VKEY_C, 0); generator.PressKey(ui::VKEY_C, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_C, false)); EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_C, false));
generator.ReleaseKey(ui::VKEY_C, 0); generator.ReleaseKey(ui::VKEY_C, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
input_method->SetFocusedTextInputClient(nullptr); input_method->SetFocusedTextInputClient(nullptr);
} }
...@@ -438,42 +451,48 @@ TEST_F(KeyboardTest, OnKeyboardModifiers) { ...@@ -438,42 +451,48 @@ TEST_F(KeyboardTest, OnKeyboardModifiers) {
aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
NiceMockKeyboardDelegate delegate; auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
auto* delegate_ptr = delegate.get();
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>())); base::flat_map<ui::DomCode, ui::DomCode>()));
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
// This should generate a modifier event. // This should generate a modifier event.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_A, true)); EXPECT_CALL(*delegate_ptr,
EXPECT_CALL(delegate, OnKeyboardModifiers(ui::EF_SHIFT_DOWN)); OnKeyboardKey(testing::_, ui::DomCode::US_A, true));
EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(ui::EF_SHIFT_DOWN));
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_A); ui::DomCode::US_A);
generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN); generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// This should generate another modifier event. // This should generate another modifier event.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_B, true)); EXPECT_CALL(*delegate_ptr,
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_B, true));
EXPECT_CALL(*delegate_ptr,
OnKeyboardModifiers(ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)); OnKeyboardModifiers(ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN));
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_B); ui::DomCode::US_B);
generator.PressKey(ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN); generator.PressKey(ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// This should generate a third modifier event. // This should generate a third modifier event.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_B, false)); EXPECT_CALL(*delegate_ptr,
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); OnKeyboardKey(testing::_, ui::DomCode::US_B, false));
EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
generator.ReleaseKey(ui::VKEY_B, 0); generator.ReleaseKey(ui::VKEY_B, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); // Verify before destroying keyboard to make sure the expected call
// is made on the methods above, rather than in the destructor.
testing::Mock::VerifyAndClearExpectations(delegate_ptr);
} }
TEST_F(KeyboardTest, OnKeyboardTypeChanged) { TEST_F(KeyboardTest, OnKeyboardTypeChanged) {
...@@ -506,9 +525,10 @@ TEST_F(KeyboardTest, OnKeyboardTypeChanged) { ...@@ -506,9 +525,10 @@ TEST_F(KeyboardTest, OnKeyboardTypeChanged) {
ash::Shell::Get()->tablet_mode_controller(); ash::Shell::Get()->tablet_mode_controller();
tablet_mode_controller->SetEnabledForTest(true); tablet_mode_controller->SetEnabledForTest(true);
NiceMockKeyboardDelegate delegate;
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); auto keyboard = std::make_unique<Keyboard>(
std::make_unique<NiceMockKeyboardDelegate>(), &seat);
MockKeyboardDeviceConfigurationDelegate configuration_delegate; MockKeyboardDeviceConfigurationDelegate configuration_delegate;
EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true)); EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
...@@ -554,14 +574,13 @@ TEST_F(KeyboardTest, OnKeyboardTypeChanged_AccessibilityKeyboard) { ...@@ -554,14 +574,13 @@ TEST_F(KeyboardTest, OnKeyboardTypeChanged_AccessibilityKeyboard) {
ui::InputDevice(2, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard")}; ui::InputDevice(2, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard")};
device_data_manager->OnKeyboardDevicesUpdated(keyboards); device_data_manager->OnKeyboardDevicesUpdated(keyboards);
NiceMockKeyboardDelegate delegate;
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);
MockKeyboardDeviceConfigurationDelegate configuration_delegate; MockKeyboardDeviceConfigurationDelegate configuration_delegate;
EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true)); EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
keyboard->SetDeviceConfigurationDelegate(&configuration_delegate); keyboard.SetDeviceConfigurationDelegate(&configuration_delegate);
EXPECT_TRUE(keyboard->HasDeviceConfigurationDelegate()); EXPECT_TRUE(keyboard.HasDeviceConfigurationDelegate());
testing::Mock::VerifyAndClearExpectations(&configuration_delegate); testing::Mock::VerifyAndClearExpectations(&configuration_delegate);
ash::AccessibilityControllerImpl* accessibility_controller = ash::AccessibilityControllerImpl* accessibility_controller =
...@@ -575,6 +594,8 @@ TEST_F(KeyboardTest, OnKeyboardTypeChanged_AccessibilityKeyboard) { ...@@ -575,6 +594,8 @@ TEST_F(KeyboardTest, OnKeyboardTypeChanged_AccessibilityKeyboard) {
// Disable a11y keyboard calls OnKeyboardTypeChanged() with true. // Disable a11y keyboard calls OnKeyboardTypeChanged() with true.
EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true)); EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
accessibility_controller->virtual_keyboard().SetEnabled(false); accessibility_controller->virtual_keyboard().SetEnabled(false);
// Verify before destroying keyboard to make sure the expected call
// is made on the methods above, rather than in the destructor.
testing::Mock::VerifyAndClearExpectations(&configuration_delegate); testing::Mock::VerifyAndClearExpectations(&configuration_delegate);
} }
...@@ -584,13 +605,13 @@ constexpr base::TimeDelta kDelta1000Ms = ...@@ -584,13 +605,13 @@ constexpr base::TimeDelta kDelta1000Ms =
base::TimeDelta::FromMilliseconds(1000); base::TimeDelta::FromMilliseconds(1000);
TEST_F(KeyboardTest, KeyRepeatSettingsLoadDefaults) { TEST_F(KeyboardTest, KeyRepeatSettingsLoadDefaults) {
MockKeyboardDelegate delegate; auto delegate = std::make_unique<MockKeyboardDelegate>();
EXPECT_CALL(delegate, OnKeyRepeatSettingsChanged).Times(0); EXPECT_CALL(*delegate, OnKeyRepeatSettingsChanged).Times(0);
EXPECT_CALL(delegate, EXPECT_CALL(*delegate,
OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms)); OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms));
Seat seat; Seat seat;
Keyboard keyboard(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
} }
TEST_F(KeyboardTest, KeyRepeatSettingsLoadInitially) { TEST_F(KeyboardTest, KeyRepeatSettingsLoadInitially) {
...@@ -599,34 +620,34 @@ TEST_F(KeyboardTest, KeyRepeatSettingsLoadInitially) { ...@@ -599,34 +620,34 @@ TEST_F(KeyboardTest, KeyRepeatSettingsLoadInitially) {
SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000)); SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000));
SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000)); SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000));
MockKeyboardDelegate delegate; auto delegate = std::make_unique<MockKeyboardDelegate>();
EXPECT_CALL(delegate, OnKeyRepeatSettingsChanged).Times(0); EXPECT_CALL(*delegate, OnKeyRepeatSettingsChanged).Times(0);
EXPECT_CALL(delegate, EXPECT_CALL(*delegate,
OnKeyRepeatSettingsChanged(true, kDelta1000Ms, kDelta1000Ms)); OnKeyRepeatSettingsChanged(true, kDelta1000Ms, kDelta1000Ms));
Seat seat; Seat seat;
Keyboard keyboard(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
} }
TEST_F(KeyboardTest, KeyRepeatSettingsUpdateAtRuntime) { TEST_F(KeyboardTest, KeyRepeatSettingsUpdateAtRuntime) {
MockKeyboardDelegate delegate; auto delegate = std::make_unique<MockKeyboardDelegate>();
{ {
testing::InSequence s; testing::InSequence s;
// Initially load defaults. // Initially load defaults.
EXPECT_CALL(delegate, OnKeyRepeatSettingsChanged) EXPECT_CALL(*delegate, OnKeyRepeatSettingsChanged)
.Times(testing::AtLeast(1)); .Times(testing::AtLeast(1));
// Respond to pref changes, in order // Respond to pref changes, in order
EXPECT_CALL(delegate, EXPECT_CALL(*delegate,
OnKeyRepeatSettingsChanged(false, testing::_, testing::_)); OnKeyRepeatSettingsChanged(false, testing::_, testing::_));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate,
OnKeyRepeatSettingsChanged(false, kDelta1000Ms, testing::_)); OnKeyRepeatSettingsChanged(false, kDelta1000Ms, testing::_));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate,
OnKeyRepeatSettingsChanged(false, kDelta1000Ms, kDelta1000Ms)); OnKeyRepeatSettingsChanged(false, kDelta1000Ms, kDelta1000Ms));
} }
Seat seat; Seat seat;
Keyboard keyboard(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
std::string email = "user0@tray"; std::string email = "user0@tray";
SetUserPref(email, ash::prefs::kXkbAutoRepeatEnabled, base::Value(false)); SetUserPref(email, ash::prefs::kXkbAutoRepeatEnabled, base::Value(false));
...@@ -639,12 +660,12 @@ TEST_F(KeyboardTest, KeyRepeatSettingsIgnoredForNonActiveUser) { ...@@ -639,12 +660,12 @@ TEST_F(KeyboardTest, KeyRepeatSettingsIgnoredForNonActiveUser) {
CreateUserSessions(2); CreateUserSessions(2);
// Key repeat settings should be sent exactly once, for the default values. // Key repeat settings should be sent exactly once, for the default values.
MockKeyboardDelegate delegate; auto delegate = std::make_unique<MockKeyboardDelegate>();
EXPECT_CALL(delegate, OnKeyRepeatSettingsChanged).Times(0); EXPECT_CALL(*delegate, OnKeyRepeatSettingsChanged).Times(0);
EXPECT_CALL(delegate, EXPECT_CALL(*delegate,
OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms)); OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms));
Seat seat; Seat seat;
Keyboard keyboard(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
// Set prefs for non-active user; no calls should result. // Set prefs for non-active user; no calls should result.
std::string email = "user1@tray"; std::string email = "user1@tray";
...@@ -663,46 +684,48 @@ TEST_F(KeyboardTest, KeyRepeatSettingsUpdateOnProfileChange) { ...@@ -663,46 +684,48 @@ TEST_F(KeyboardTest, KeyRepeatSettingsUpdateOnProfileChange) {
SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000)); SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000));
SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000)); SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000));
MockKeyboardDelegate delegate; auto delegate = std::make_unique<MockKeyboardDelegate>();
EXPECT_CALL(delegate, OnKeyRepeatSettingsChanged).Times(0); EXPECT_CALL(*delegate, OnKeyRepeatSettingsChanged).Times(0);
{ {
testing::InSequence s; testing::InSequence s;
// Initially, load default prefs for first user. // Initially, load default prefs for first user.
EXPECT_CALL(delegate, EXPECT_CALL(*delegate,
OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms)); OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms));
// Switching user should load new prefs. // Switching user should load new prefs.
EXPECT_CALL(delegate, EXPECT_CALL(*delegate,
OnKeyRepeatSettingsChanged(true, kDelta1000Ms, kDelta1000Ms)); OnKeyRepeatSettingsChanged(true, kDelta1000Ms, kDelta1000Ms));
} }
Seat seat; Seat seat;
Keyboard keyboard(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
SimulateUserLogin(email, user_manager::UserType::USER_TYPE_REGULAR); SimulateUserLogin(email, user_manager::UserType::USER_TYPE_REGULAR);
} }
TEST_F(KeyboardTest, KeyboardObserver) { TEST_F(KeyboardTest, KeyboardObserver) {
NiceMockKeyboardDelegate delegate; // Declare before the keyboard so the mock verification happens
Seat seat; // after the keyboard destruction.
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat);
MockKeyboardObserver observer1; MockKeyboardObserver observer1;
MockKeyboardObserver observer2; MockKeyboardObserver observer2;
keyboard->AddObserver(&observer1); Seat seat;
keyboard->AddObserver(&observer2); Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);
EXPECT_TRUE(keyboard->HasObserver(&observer1));
EXPECT_TRUE(keyboard->HasObserver(&observer2)); keyboard.AddObserver(&observer1);
keyboard.AddObserver(&observer2);
EXPECT_TRUE(keyboard.HasObserver(&observer1));
EXPECT_TRUE(keyboard.HasObserver(&observer2));
testing::Mock::VerifyAndClearExpectations(&observer1); testing::Mock::VerifyAndClearExpectations(&observer1);
testing::Mock::VerifyAndClearExpectations(&observer2); testing::Mock::VerifyAndClearExpectations(&observer2);
keyboard->RemoveObserver(&observer1); keyboard.RemoveObserver(&observer1);
EXPECT_FALSE(keyboard->HasObserver(&observer1)); EXPECT_FALSE(keyboard.HasObserver(&observer1));
EXPECT_TRUE(keyboard->HasObserver(&observer2)); EXPECT_TRUE(keyboard.HasObserver(&observer2));
testing::Mock::VerifyAndClearExpectations(&observer1); testing::Mock::VerifyAndClearExpectations(&observer1);
testing::Mock::VerifyAndClearExpectations(&observer2); testing::Mock::VerifyAndClearExpectations(&observer2);
EXPECT_CALL(observer1, OnKeyboardDestroying(keyboard.get())).Times(0); // Called from the destructor of Keyboard.
EXPECT_CALL(observer2, OnKeyboardDestroying(keyboard.get())); EXPECT_CALL(observer1, OnKeyboardDestroying(&keyboard)).Times(0);
keyboard.reset(); EXPECT_CALL(observer2, OnKeyboardDestroying(&keyboard));
} }
TEST_F(KeyboardTest, NeedKeyboardKeyAcks) { TEST_F(KeyboardTest, NeedKeyboardKeyAcks) {
...@@ -718,15 +741,14 @@ TEST_F(KeyboardTest, NeedKeyboardKeyAcks) { ...@@ -718,15 +741,14 @@ TEST_F(KeyboardTest, NeedKeyboardKeyAcks) {
aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
NiceMockKeyboardDelegate delegate;
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);
EXPECT_FALSE(keyboard->AreKeyboardKeyAcksNeeded()); EXPECT_FALSE(keyboard.AreKeyboardKeyAcksNeeded());
keyboard->SetNeedKeyboardKeyAcks(true); keyboard.SetNeedKeyboardKeyAcks(true);
EXPECT_TRUE(keyboard->AreKeyboardKeyAcksNeeded()); EXPECT_TRUE(keyboard.AreKeyboardKeyAcksNeeded());
keyboard->SetNeedKeyboardKeyAcks(false); keyboard.SetNeedKeyboardKeyAcks(false);
EXPECT_FALSE(keyboard->AreKeyboardKeyAcksNeeded()); EXPECT_FALSE(keyboard.AreKeyboardKeyAcksNeeded());
} }
TEST_F(KeyboardTest, AckKeyboardKey) { TEST_F(KeyboardTest, AckKeyboardKey) {
...@@ -742,24 +764,25 @@ TEST_F(KeyboardTest, AckKeyboardKey) { ...@@ -742,24 +764,25 @@ TEST_F(KeyboardTest, AckKeyboardKey) {
aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
NiceMockKeyboardDelegate delegate; auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
auto* delegate_ptr = delegate.get();
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>())); base::flat_map<ui::DomCode, ui::DomCode>()));
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// If we don't set NeedKeyboardAckKeys to true, accelerators are always passed // If we don't set NeedKeyboardAckKeys to true, accelerators are always passed
// to ShellSurface. // to ShellSurface.
ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
// Press KEY_W with Ctrl. // Press KEY_W with Ctrl.
EXPECT_CALL(delegate, OnKeyboardModifiers(4)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(4));
EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator( EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
ui::VKEY_W, ui::EF_CONTROL_DOWN, ui::VKEY_W, ui::EF_CONTROL_DOWN,
ui::Accelerator::KeyState::PRESSED))) ui::Accelerator::KeyState::PRESSED)))
...@@ -770,45 +793,46 @@ TEST_F(KeyboardTest, AckKeyboardKey) { ...@@ -770,45 +793,46 @@ TEST_F(KeyboardTest, AckKeyboardKey) {
// Release KEY_W. // Release KEY_W.
generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN); generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
testing::Mock::VerifyAndClearExpectations(shell_surface.get()); testing::Mock::VerifyAndClearExpectations(shell_surface.get());
// If we set NeedKeyboardAckKeys to true, only unhandled accelerators are // If we set NeedKeyboardAckKeys to true, only unhandled accelerators are
// passed to ShellSurface. // passed to ShellSurface.
keyboard->SetNeedKeyboardKeyAcks(true); keyboard.SetNeedKeyboardKeyAcks(true);
// Press KEY_W with Ctrl. // Press KEY_W with Ctrl.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_W, true)) EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
.WillOnce(testing::Return(1)); .WillOnce(testing::Return(1));
generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN); generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Send ack for the key press. // Send ack for the key press.
EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator( EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
ui::VKEY_W, ui::EF_CONTROL_DOWN, ui::VKEY_W, ui::EF_CONTROL_DOWN,
ui::Accelerator::KeyState::PRESSED))) ui::Accelerator::KeyState::PRESSED)))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
keyboard->AckKeyboardKey(1, false /* handled */); keyboard.AckKeyboardKey(1, false /* handled */);
testing::Mock::VerifyAndClearExpectations(shell_surface.get()); testing::Mock::VerifyAndClearExpectations(shell_surface.get());
// Release KEY_W. // Release KEY_W.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_W, false)) EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_W, false))
.WillOnce(testing::Return(2)); .WillOnce(testing::Return(2));
generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN); generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Send ack for the key release. // Send ack for the key release.
keyboard->AckKeyboardKey(2, false /* handled */); keyboard.AckKeyboardKey(2, false /* handled */);
// Press KEY_W with Ctrl again. // Press KEY_W with Ctrl again.
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_W, true)) EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
.WillOnce(testing::Return(3)); .WillOnce(testing::Return(3));
generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN); generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Send ack for the key press. // Send ack for the key press.
// AcceleratorPressed is not called when the accelerator is already handled. // AcceleratorPressed is not called when the accelerator is already handled.
keyboard->AckKeyboardKey(3, true /* handled */); keyboard.AckKeyboardKey(3, true /* handled */);
// A repeat key event should not be sent to the client and also should not // A repeat key event should not be sent to the client and also should not
// invoke the accelerator. // invoke the accelerator.
...@@ -829,10 +853,13 @@ TEST_F(KeyboardTest, AckKeyboardKey) { ...@@ -829,10 +853,13 @@ TEST_F(KeyboardTest, AckKeyboardKey) {
testing::Mock::VerifyAndClearExpectations(shell_surface.get()); testing::Mock::VerifyAndClearExpectations(shell_surface.get());
// Release the key and reset modifier_flags. // Release the key and reset modifier_flags.
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_W, false)); EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_W, false));
generator.ReleaseKey(ui::VKEY_W, 0); generator.ReleaseKey(ui::VKEY_W, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); // Verify before destroying keyboard to make sure the expected call
// is made on the methods above, rather than in the destructor.
testing::Mock::VerifyAndClearExpectations(delegate_ptr);
} }
TEST_F(KeyboardTest, AckKeyboardKeyMoveFocus) { TEST_F(KeyboardTest, AckKeyboardKeyMoveFocus) {
...@@ -848,38 +875,39 @@ TEST_F(KeyboardTest, AckKeyboardKeyMoveFocus) { ...@@ -848,38 +875,39 @@ TEST_F(KeyboardTest, AckKeyboardKeyMoveFocus) {
aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
NiceMockKeyboardDelegate delegate; auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
auto* delegate_ptr = delegate.get();
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(0)).Times(1); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0)).Times(1);
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>())); base::flat_map<ui::DomCode, ui::DomCode>()));
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
keyboard->SetNeedKeyboardKeyAcks(true); keyboard.SetNeedKeyboardKeyAcks(true);
// Press KEY_W with Ctrl. // Press KEY_W with Ctrl.
EXPECT_CALL(delegate, OnKeyboardModifiers(4)).Times(1); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(4)).Times(1);
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_W, true)) EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
.WillOnce(testing::Return(1)); .WillOnce(testing::Return(1));
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_W); ui::DomCode::US_W);
generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN); generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Move focus from the window // Move focus from the window
EXPECT_CALL(delegate, OnKeyboardLeave(surface.get())); EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Send ack for the key press. |AcceleratorPressed()| should not be called. // Send ack for the key press. |AcceleratorPressed()| should not be called.
keyboard->AckKeyboardKey(1, false /* handled */); keyboard.AckKeyboardKey(1, false /* handled */);
} }
TEST_F(KeyboardTest, AckKeyboardKeyExpired) { TEST_F(KeyboardTest, AckKeyboardKeyExpired) {
...@@ -895,30 +923,31 @@ TEST_F(KeyboardTest, AckKeyboardKeyExpired) { ...@@ -895,30 +923,31 @@ TEST_F(KeyboardTest, AckKeyboardKeyExpired) {
aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
NiceMockKeyboardDelegate delegate; auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
auto* delegate_ptr = delegate.get();
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>())); base::flat_map<ui::DomCode, ui::DomCode>()));
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
keyboard->SetNeedKeyboardKeyAcks(true); keyboard.SetNeedKeyboardKeyAcks(true);
// Press KEY_W with Ctrl. // Press KEY_W with Ctrl.
EXPECT_CALL(delegate, OnKeyboardModifiers(4)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(4));
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_W, true)) EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
.WillOnce(testing::Return(1)); .WillOnce(testing::Return(1));
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_W); ui::DomCode::US_W);
generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN); generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
// Keyboard processes pending events as if it is handled when it expires, // Keyboard processes pending events as if it is handled when it expires,
// so |AcceleratorPressed()| should not be called. // so |AcceleratorPressed()| should not be called.
...@@ -940,13 +969,16 @@ TEST_F(KeyboardTest, AckKeyboardKeyExpired) { ...@@ -940,13 +969,16 @@ TEST_F(KeyboardTest, AckKeyboardKeyExpired) {
// key should have been treated as handled already and removed from the // key should have been treated as handled already and removed from the
// pending_key_acks_ map. Since the event is no longer in the map, // pending_key_acks_ map. Since the event is no longer in the map,
// |AcceleratorPressed()| should not be called. // |AcceleratorPressed()| should not be called.
keyboard->AckKeyboardKey(1, false /* handled */); keyboard.AckKeyboardKey(1, false /* handled */);
// Release the key and reset modifier_flags. // Release the key and reset modifier_flags.
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_W, false)); EXPECT_CALL(*delegate_ptr,
OnKeyboardKey(testing::_, ui::DomCode::US_W, false));
generator.ReleaseKey(ui::VKEY_W, 0); generator.ReleaseKey(ui::VKEY_W, 0);
testing::Mock::VerifyAndClearExpectations(&delegate); // Verify before destroying keyboard to make sure the expected call
// is made on the methods above, rather than in the destructor.
testing::Mock::VerifyAndClearExpectations(delegate_ptr);
} }
// Test for crbug.com/753539. If action for an accelerator moves the focus to // Test for crbug.com/753539. If action for an accelerator moves the focus to
...@@ -981,36 +1013,37 @@ TEST_F(KeyboardTest, AckKeyboardKeyExpiredWithMovingFocusAccelerator) { ...@@ -981,36 +1013,37 @@ TEST_F(KeyboardTest, AckKeyboardKeyExpiredWithMovingFocusAccelerator) {
aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
focus_client->FocusWindow(nullptr); focus_client->FocusWindow(nullptr);
NiceMockKeyboardDelegate delegate; auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
auto* delegate_ptr = delegate.get();
Seat seat; Seat seat;
auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); Keyboard keyboard(std::move(delegate), &seat);
EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
EXPECT_CALL(delegate, OnKeyboardModifiers(0)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(0));
EXPECT_CALL(delegate, EXPECT_CALL(*delegate_ptr,
OnKeyboardEnter(surface.get(), OnKeyboardEnter(surface.get(),
base::flat_map<ui::DomCode, ui::DomCode>())); base::flat_map<ui::DomCode, ui::DomCode>()));
focus_client->FocusWindow(surface->window()); focus_client->FocusWindow(surface->window());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
keyboard->SetNeedKeyboardKeyAcks(true); keyboard.SetNeedKeyboardKeyAcks(true);
// Press KEY_W with Ctrl. // Press KEY_W with Ctrl.
EXPECT_CALL(delegate, OnKeyboardModifiers(4)); EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(4));
EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_W, true)) EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
.WillOnce(testing::Return(1)); .WillOnce(testing::Return(1));
seat.set_physical_code_for_currently_processing_event_for_testing( seat.set_physical_code_for_currently_processing_event_for_testing(
ui::DomCode::US_W); ui::DomCode::US_W);
generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN); generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(delegate_ptr);
EXPECT_CALL(delegate, OnKeyboardLeave(surface.get())); EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));
// Send ack as unhandled. This will call |AcceleratorPressed| and move the // Send ack as unhandled. This will call |AcceleratorPressed| and move the
// focus. // focus.
keyboard->AckKeyboardKey(1, false /* handled */); keyboard.AckKeyboardKey(1, false /* handled */);
// Wait until |ProcessExpiredPendingKeyAcks| is fired. // Wait until |ProcessExpiredPendingKeyAcks| is fired.
base::RunLoop run_loop; base::RunLoop run_loop;
...@@ -1020,6 +1053,8 @@ TEST_F(KeyboardTest, AckKeyboardKeyExpiredWithMovingFocusAccelerator) { ...@@ -1020,6 +1053,8 @@ TEST_F(KeyboardTest, AckKeyboardKeyExpiredWithMovingFocusAccelerator) {
run_loop.Run(); run_loop.Run();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
// Verify before destroying keyboard to make sure the expected call
// is made on the methods above, rather than in the destructor.
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(&delegate);
} }
} // namespace } // namespace
......
...@@ -42,10 +42,6 @@ WaylandKeyboardDelegate::~WaylandKeyboardDelegate() { ...@@ -42,10 +42,6 @@ WaylandKeyboardDelegate::~WaylandKeyboardDelegate() {
#endif #endif
} }
void WaylandKeyboardDelegate::OnKeyboardDestroying(Keyboard* keyboard) {
delete this;
}
bool WaylandKeyboardDelegate::CanAcceptKeyboardEventsForSurface( bool WaylandKeyboardDelegate::CanAcceptKeyboardEventsForSurface(
Surface* surface) const { Surface* surface) const {
wl_resource* surface_resource = GetSurfaceResource(surface); wl_resource* surface_resource = GetSurfaceResource(surface);
......
...@@ -38,8 +38,7 @@ class SerialTracker; ...@@ -38,8 +38,7 @@ class SerialTracker;
// Keyboard delegate class that accepts events for surfaces owned by the same // Keyboard delegate class that accepts events for surfaces owned by the same
// client as a keyboard resource. // client as a keyboard resource.
class WaylandKeyboardDelegate : public WaylandInputDelegate, class WaylandKeyboardDelegate : public WaylandInputDelegate,
public KeyboardDelegate, public KeyboardDelegate
public KeyboardObserver
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
, ,
public ash::ImeControllerImpl::Observer public ash::ImeControllerImpl::Observer
...@@ -52,7 +51,6 @@ class WaylandKeyboardDelegate : public WaylandInputDelegate, ...@@ -52,7 +51,6 @@ class WaylandKeyboardDelegate : public WaylandInputDelegate,
~WaylandKeyboardDelegate() override; ~WaylandKeyboardDelegate() override;
// Overridden from KeyboardDelegate: // Overridden from KeyboardDelegate:
void OnKeyboardDestroying(Keyboard* keyboard) override;
bool CanAcceptKeyboardEventsForSurface(Surface* surface) const override; bool CanAcceptKeyboardEventsForSurface(Surface* surface) const override;
void OnKeyboardEnter( void OnKeyboardEnter(
Surface* surface, Surface* surface,
......
...@@ -86,27 +86,22 @@ void seat_get_pointer(wl_client* client, wl_resource* resource, uint32_t id) { ...@@ -86,27 +86,22 @@ void seat_get_pointer(wl_client* client, wl_resource* resource, uint32_t id) {
} }
void seat_get_keyboard(wl_client* client, wl_resource* resource, uint32_t id) { void seat_get_keyboard(wl_client* client, wl_resource* resource, uint32_t id) {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS) && BUILDFLAG(USE_XKBCOMMON)
#if BUILDFLAG(USE_XKBCOMMON)
auto* data = GetUserDataAs<WaylandSeat>(resource); auto* data = GetUserDataAs<WaylandSeat>(resource);
uint32_t version = wl_resource_get_version(resource); uint32_t version = wl_resource_get_version(resource);
wl_resource* keyboard_resource = wl_resource* keyboard_resource =
wl_resource_create(client, &wl_keyboard_interface, version, id); wl_resource_create(client, &wl_keyboard_interface, version, id);
WaylandKeyboardDelegate* delegate = auto keyboard =
new WaylandKeyboardDelegate(keyboard_resource, data->serial_tracker); std::make_unique<Keyboard>(std::make_unique<WaylandKeyboardDelegate>(
std::unique_ptr<Keyboard> keyboard = keyboard_resource, data->serial_tracker),
std::make_unique<Keyboard>(delegate, data->seat); data->seat);
keyboard->AddObserver(delegate);
SetImplementation(keyboard_resource, &keyboard_implementation, SetImplementation(keyboard_resource, &keyboard_implementation,
std::move(keyboard)); std::move(keyboard));
#else #else
NOTIMPLEMENTED(); NOTIMPLEMENTED();
#endif // BUILDFLAG(USE_XKBCOMMON) #endif // defined(OS_CHROMEOS) && BUILDFLAG(USE_XKBCOMMON)
#else
NOTIMPLEMENTED();
#endif // defined(OS_CHROMEOS)
} }
void seat_get_touch(wl_client* client, wl_resource* resource, uint32_t id) { void seat_get_touch(wl_client* client, wl_resource* resource, uint32_t id) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment