// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/exo/keyboard.h"

#include "ash/accelerators/accelerator_controller_impl.h"
#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/constants/app_types.h"
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/keyboard/keyboard_controller_impl.h"
#include "ash/public/cpp/external_arc/overlay/arc_overlay_manager.h"
#include "ash/shell.h"
#include "ash/test/ash_test_helper.h"
#include "ash/test/test_widget_builder.h"
#include "ash/test/test_window_builder.h"
#include "ash/wm/desks/desks_controller.h"
#include "ash/wm/desks/desks_test_util.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "components/exo/buffer.h"
#include "components/exo/keyboard_delegate.h"
#include "components/exo/keyboard_device_configuration_delegate.h"
#include "components/exo/keyboard_modifiers.h"
#include "components/exo/keyboard_observer.h"
#include "components/exo/seat.h"
#include "components/exo/shell_surface.h"
#include "components/exo/surface.h"
#include "components/exo/test/exo_test_base.h"
#include "components/exo/test/exo_test_helper.h"
#include "components/exo/test/shell_surface_builder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/focus_client.h"
#include "ui/base/accelerators/test_accelerator_target.h"
#include "ui/base/ime/constants.h"
#include "ui/base/ime/dummy_text_input_client.h"
#include "ui/base/ime/events.h"
#include "ui/events/devices/device_data_manager.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/ozone/events_ozone.h"
#include "ui/events/test/event_generator.h"
#include "ui/events/types/event_type.h"
#include "ui/views/controls/textfield/textfield.h"

namespace exo {
namespace {

// XKB mod masks for the default keymap.
constexpr uint32_t kShiftMask = 1 << 0;
constexpr uint32_t kControlMask = 1 << 2;
constexpr uint32_t kAltMask = 1 << 3;
constexpr uint32_t kNumLockMask = 1 << 4;
constexpr uint32_t kCommandMask = 1 << 6;

class KeyboardTest : public test::ExoTestBase {
 public:
  KeyboardTest()
      : test::ExoTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
  ~KeyboardTest() override = default;
};

class KeyboardKeyTest : public KeyboardTest,
                        public testing::WithParamInterface<bool> {
 public:
  void SetUp() override {
    if (GetParam()) {
      feature_list_.InitAndEnableFeature(
          ash::features::kExoConsumedByImeByFlag);
    } else {
      feature_list_.InitAndDisableFeature(
          ash::features::kExoConsumedByImeByFlag);
    }
    KeyboardTest::SetUp();
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

INSTANTIATE_TEST_SUITE_P(, KeyboardKeyTest, ::testing::Bool());

class MockKeyboardDelegate : public KeyboardDelegate {
 public:
  MockKeyboardDelegate() = default;

  // Overridden from KeyboardDelegate:
  MOCK_METHOD(bool, CanAcceptKeyboardEventsForSurface, (Surface*), (const));
  MOCK_METHOD(void,
              OnKeyboardEnter,
              (Surface*, (const base::flat_map<ui::DomCode, KeyState>&)));
  MOCK_METHOD(void, OnKeyboardLeave, (Surface*));
  MOCK_METHOD(uint32_t, OnKeyboardKey, (base::TimeTicks, ui::DomCode, bool));
  MOCK_METHOD(void, OnKeyboardModifiers, (const KeyboardModifiers&));
  MOCK_METHOD(void,
              OnKeyRepeatSettingsChanged,
              (bool, base::TimeDelta, base::TimeDelta));
  MOCK_METHOD(void, OnKeyboardLayoutUpdated, (base::StringPiece));
};
using NiceMockKeyboardDelegate = ::testing::NiceMock<MockKeyboardDelegate>;

class MockKeyboardDeviceConfigurationDelegate
    : public KeyboardDeviceConfigurationDelegate {
 public:
  MockKeyboardDeviceConfigurationDelegate() = default;

  // Overridden from KeyboardDeviceConfigurationDelegate:
  MOCK_METHOD(void, OnKeyboardTypeChanged, (bool));
};

class MockKeyboardObserver : public KeyboardObserver {
 public:
  MockKeyboardObserver() = default;

  // Overridden from KeyboardObserver:
  MOCK_METHOD(void, OnKeyboardDestroying, (Keyboard*));
  MOCK_METHOD(void, OnKeyboardKey, (base::TimeTicks, ui::DomCode, bool));
};
using NiceMockKeyboardObserver = ::testing::NiceMock<MockKeyboardObserver>;

class TestShellSurface : public ShellSurface {
 public:
  explicit TestShellSurface(Surface* surface) : ShellSurface(surface) {}

  MOCK_METHOD(bool, AcceleratorPressed, (const ui::Accelerator& accelerator));
};

// This event handler moves the focus to the given window when receiving a key
// event.
class TestEventHandler : public ui::EventHandler {
 public:
  explicit TestEventHandler(aura::Window* focus_window)
      : focus_window_(focus_window) {}
  TestEventHandler(const TestEventHandler&) = delete;
  TestEventHandler& operator=(const TestEventHandler&) = delete;

  void OnKeyEvent(ui::KeyEvent* event) override {
    aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow())
        ->FocusWindow(focus_window_);
  }

  raw_ptr<aura::Window, ExperimentalAsh> focus_window_;
};

// Verifies that switching desks via alt-tab doesn't prevent Seat from receiving
// key events. https://crbug.com/1008574.
TEST_F(KeyboardTest, CorrectSeatPressedKeysOnSwitchingDesks) {
  Seat seat;
  Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);

  // Create 2 desks.
  auto* desks_controller = ash::DesksController::Get();
  desks_controller->NewDesk(ash::DesksCreationRemovalSource::kButton);
  ASSERT_EQ(2u, desks_controller->desks().size());
  ash::Desk* desk_1 = desks_controller->desks()[0].get();
  const ash::Desk* desk_2 = desks_controller->desks()[1].get();
  // Desk 1 has a normal window.
  auto win0 = CreateAppWindow(gfx::Rect(0, 0, 250, 100));

  // Desk 2 has an exo surface window.
  ash::ActivateDesk(desk_2);
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();

  // Go back to desk 1, and trigger an alt-tab (releasing alt first). This would
  // trigger activating the exo surface window on desk 2, which would lead to a
  // desk switch animation. During the animation, expect that Seat gets all the
  // keys in `OnKeyEvent()`, and the |pressed_keys_| map is correctly updated.
  ash::ActivateDesk(desk_1);
  auto displatch_key_event = [&](ui::EventType type, ui::KeyboardCode key_code,
                                 ui::DomCode code, int flags) {
    ui::KeyEvent key_event{type, key_code, code, flags};
    seat.WillProcessEvent(&key_event);
    GetEventGenerator()->Dispatch(&key_event);

    EXPECT_EQ(type != ui::ET_KEY_RELEASED, seat.pressed_keys().count(code));

    seat.DidProcessEvent(&key_event);
  };

  ash::DeskSwitchAnimationWaiter waiter;
  displatch_key_event(ui::ET_KEY_PRESSED, ui::VKEY_MENU, ui::DomCode::ALT_LEFT,
                      /*flags=*/0);
  displatch_key_event(ui::ET_KEY_PRESSED, ui::VKEY_TAB, ui::DomCode::TAB,
                      /*flags=*/ui::EF_ALT_DOWN);
  displatch_key_event(ui::ET_KEY_RELEASED, ui::VKEY_MENU, ui::DomCode::ALT_LEFT,
                      /*flags=*/0);
  displatch_key_event(ui::ET_KEY_RELEASED, ui::VKEY_TAB, ui::DomCode::TAB,
                      /*flags=*/0);

  EXPECT_TRUE(seat.pressed_keys().empty());
  EXPECT_EQ(desk_2, desks_controller->GetTargetActiveDesk());
  waiter.Wait();
}

TEST_F(KeyboardTest, OnKeyboardEnter) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  Seat seat;
  // Pressing key before Keyboard instance is created and surface has
  // received focus.
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_A);
  generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(surface->window());

  // Keyboard should try to set initial focus to surface.
  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(false));
  Keyboard keyboard(std::move(delegate), &seat);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Set up expectation for the key release.
  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>(
                                   {{ui::DomCode::US_A,
                                     KeyState{ui::DomCode::US_A, false}}})));
  focus_client->FocusWindow(nullptr);
  focus_client->FocusWindow(surface->window());
  // Surface should maintain keyboard focus when moved to top-level window.
  focus_client->FocusWindow(surface->window()->GetToplevelWindow());

  // Release key after surface lost focus.
  focus_client->FocusWindow(nullptr);
  generator.ReleaseKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Key should no longer be pressed when focus returns.
  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
                                 kShiftMask | kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window()->GetToplevelWindow());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}

TEST_F(KeyboardTest, OnKeyboardLeave) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  Seat seat;
  auto keyboard = std::make_unique<Keyboard>(std::move(delegate), &seat);
  ON_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillByDefault(testing::Return(true));

  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface));
  focus_client->FocusWindow(nullptr);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface));
  shell_surface.reset();
  // 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_P(KeyboardKeyTest, OnKeyboardKey) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  NiceMockKeyboardObserver observer;
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  keyboard.AddObserver(&observer);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  // This should only generate a press event for KEY_A.
  {
    testing::InSequence s;
    EXPECT_CALL(observer, 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(
      ui::DomCode::US_A);
  generator.PressKey(ui::VKEY_A, 0);
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // This should not generate another press event for KEY_A.
  generator.PressKey(ui::VKEY_A, 0);
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // This should only generate a single release event for KEY_A.
  {
    testing::InSequence s;
    EXPECT_CALL(observer, OnKeyboardKey(testing::_, ui::DomCode::US_A, false));
    EXPECT_CALL(*delegate_ptr,
                OnKeyboardKey(testing::_, ui::DomCode::US_A, false));
  }
  generator.ReleaseKey(ui::VKEY_A, 0);
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Test key event rewriting. In this case, ARROW_DOWN is rewritten to KEY_END
  // as a result of ALT being pressed.
  {
    testing::InSequence s;
    EXPECT_CALL(observer, OnKeyboardKey(testing::_, ui::DomCode::END, true));
    EXPECT_CALL(*delegate_ptr,
                OnKeyboardKey(testing::_, ui::DomCode::END, true));
  }
  EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
                                 kAltMask | kNumLockMask, 0, 0, 0}));
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::ARROW_DOWN);
  generator.PressKey(ui::VKEY_END, ui::EF_ALT_DOWN);
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // This should generate a release event for KEY_END as that is the key
  // associated with the key press.
  {
    testing::InSequence s;
    EXPECT_CALL(observer, OnKeyboardKey(testing::_, ui::DomCode::END, false));
    EXPECT_CALL(*delegate_ptr,
                OnKeyboardKey(testing::_, ui::DomCode::END, false));
  }
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  generator.ReleaseKey(ui::VKEY_DOWN, 0);
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Press accelerator after surface lost focus.
  EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface));
  focus_client->FocusWindow(nullptr);
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_W);
  generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Key should be pressed when focus returns.
  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
                                 kControlMask | kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>(
                                   {{ui::DomCode::US_W,
                                     KeyState{ui::DomCode::US_W, false}}})));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Releasing accelerator when surface has focus should generate event.
  {
    testing::InSequence s;
    EXPECT_CALL(observer, 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);
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Key events should be ignored when the focused window is not an
  // exo::Surface.
  std::unique_ptr<aura::Window> window =
      ash::ChildTestWindowBuilder(shell_surface->GetWidget()->GetNativeWindow(),
                                  surface->window()->bounds())
          .Build();
  // Moving the focus away will reset the focused surface.
  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .Times(0);
  focus_client->FocusWindow(window.get());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
  EXPECT_FALSE(seat.GetFocusedSurface());
  EXPECT_FALSE(keyboard.focused_surface_for_testing());

  EXPECT_CALL(observer,
              OnKeyboardKey(testing::_, ui::DomCode::ARROW_LEFT, true))
      .Times(0);
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::ARROW_LEFT, true))
      .Times(0);
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::ARROW_LEFT);
  generator.PressKey(ui::VKEY_LEFT, 0);
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  EXPECT_CALL(observer,
              OnKeyboardKey(testing::_, ui::DomCode::ARROW_LEFT, false))
      .Times(0);
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::ARROW_LEFT, false))
      .Times(0);
  generator.ReleaseKey(ui::VKEY_LEFT, 0);
  // Verify before destroying keyboard to make sure the expected call
  // is made on the methods above, rather than in the destructor.
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}

TEST_P(KeyboardKeyTest, OnKeyboardKey_NotSendKeyIfConsumedByIme) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  NiceMockKeyboardObserver observer;
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  keyboard.AddObserver(&observer);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  views::Widget* widget =
      views::Widget::GetTopLevelWidgetForNativeView(surface->window());
  ui::InputMethod* input_method = widget->GetInputMethod();
  ui::DummyTextInputClient client{ui::TEXT_INPUT_TYPE_TEXT};
  input_method->SetFocusedTextInputClient(&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.
  // However, the observer should receive OnKeyboardKey, always.
  EXPECT_CALL(observer, OnKeyboardKey(testing::_, ui::DomCode::US_A, true));
  EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_A, true))
      .Times(0);
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_A);

  {
    ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
    ui::SetKeyboardImeFlags(&event, ui::kPropertyKeyboardImeHandledFlag);
    event.set_source_device_id(0);
    generator.Dispatch(&event);
  }
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // 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
  // event for. It might causes a never-ending key repeat in the client.
  // EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_A, false));
  EXPECT_CALL(observer, OnKeyboardKey(testing::_, ui::DomCode::US_A, false));
  generator.ReleaseKey(ui::VKEY_A, 0);
  testing::Mock::VerifyAndClearExpectations(&observer);

  // Any key event should be sent to a client if a key event skips IME.
  surface->window()->SetProperty(aura::client::kSkipImeProcessing, true);
  {
    testing::InSequence s;
    EXPECT_CALL(observer, 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(
      ui::DomCode::US_C);
  generator.PressKey(ui::VKEY_C, 0);
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  {
    testing::InSequence s;
    EXPECT_CALL(observer, OnKeyboardKey(testing::_, ui::DomCode::US_C, false));
    EXPECT_CALL(*delegate_ptr,
                OnKeyboardKey(testing::_, ui::DomCode::US_C, false));
  }
  generator.ReleaseKey(ui::VKEY_C, 0);
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  input_method->SetFocusedTextInputClient(nullptr);
}

TEST_P(KeyboardKeyTest, OnKeyboardKey_KeyboardInhibit) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  // Set lacros attribute now for testing. This can be removed, when
  // all clients are migrated into this model.
  surface->window()->SetProperty(aura::client::kAppType,
                                 static_cast<int>(ash::AppType::LACROS));

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  // Register accelerator to be triggered.
  ui::TestAcceleratorTarget accelerator_target;
  {
    ui::Accelerator accelerator(ui::VKEY_P,
                                ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN);
    ash::AcceleratorControllerImpl* controller =
        ash::Shell::Get()->accelerator_controller();
    controller->Register({accelerator}, &accelerator_target);
  }

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  NiceMockKeyboardObserver observer;
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  keyboard.AddObserver(&observer);
  keyboard.SetNeedKeyboardKeyAcks(true);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  // This should only generate a press event for KEY_P.
  accelerator_target.ResetCounts();
  EXPECT_CALL(observer,
              OnKeyboardKey(testing::_, ui::DomCode::US_P, testing::_))
      .Times(0);
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::US_P, testing::_))
      .Times(0);
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_P);
  generator.PressKey(ui::VKEY_P, ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN);
  EXPECT_EQ(1, accelerator_target.accelerator_count());
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Set keyboard-shortcut-inhibited, so the key event should be sent to app.
  surface->SetKeyboardShortcutsInhibited(true);
  accelerator_target.ResetCounts();
  {
    testing::InSequence s;
    EXPECT_CALL(observer, OnKeyboardKey(testing::_, ui::DomCode::US_P, true));
    EXPECT_CALL(*delegate_ptr,
                OnKeyboardKey(testing::_, ui::DomCode::US_P, true));
  }
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_P);
  generator.PressKey(ui::VKEY_P, ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN);
  EXPECT_EQ(0, accelerator_target.accelerator_count());
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}

TEST_F(KeyboardTest, KeyboardKey_SuppressAutoRepeat) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  // Set lacros attribute now for testing. This can be removed, when
  // all clients are migrated into this model.
  surface->window()->SetProperty(aura::client::kAppType,
                                 static_cast<int>(ash::AppType::LACROS));

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  NiceMockKeyboardObserver observer;
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  keyboard.AddObserver(&observer);
  keyboard.SetNeedKeyboardKeyAcks(true);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  // Send KeyEvent annotated the auto repeat suppression.
  {
    testing::InSequence s;
    EXPECT_CALL(*delegate_ptr,
                OnKeyRepeatSettingsChanged(false, testing::_, testing::_))
        .Times(1);
    EXPECT_CALL(observer,
                OnKeyboardKey(testing::_, ui::DomCode::US_X, testing::_))
        .Times(1);
    EXPECT_CALL(*delegate_ptr,
                OnKeyboardKey(testing::_, ui::DomCode::US_X, testing::_))
        .Times(1);
  }
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_X);
  {
    ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_X, 0);
    event.set_source_device_id(ui::ED_UNKNOWN_DEVICE);
    {
      ui::Event::Properties properties;
      ui::SetKeyboardImeFlagProperty(&properties,
                                     ui::kPropertyKeyboardImeIgnoredFlag);
      ui::SetKeyEventSuppressAutoRepeat(properties);
      event.SetProperties(properties);
    }
    generator.Dispatch(&event);
  }
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Following KeyEvent without the annotation will re-enable
  // auto-repeat.
  {
    testing::InSequence s;
    EXPECT_CALL(*delegate_ptr,
                OnKeyRepeatSettingsChanged(true, testing::_, testing::_))
        .Times(1);
    EXPECT_CALL(observer,
                OnKeyboardKey(testing::_, ui::DomCode::US_Y, testing::_))
        .Times(1);
    EXPECT_CALL(*delegate_ptr,
                OnKeyboardKey(testing::_, ui::DomCode::US_Y, testing::_))
        .Times(1);
  }
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_Y);
  {
    ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_Y, 0);
    event.set_source_device_id(ui::ED_UNKNOWN_DEVICE);
    {
      ui::Event::Properties properties;
      ui::SetKeyboardImeFlagProperty(&properties,
                                     ui::kPropertyKeyboardImeIgnoredFlag);
      event.SetProperties(properties);
    }
    generator.Dispatch(&event);
  }
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}

TEST_F(KeyboardTest, FocusWithArcOverlay) {
  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  // Just allow any surface to receive focus.
  EXPECT_CALL(*delegate, CanAcceptKeyboardEventsForSurface(::testing::_))
      .WillRepeatedly(testing::Return(true));
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);

  // TODO(oshima): Create a TestExoWindowBuilder.
  class TestPropertyResolver : public exo::WMHelper::AppPropertyResolver {
   public:
    TestPropertyResolver() = default;
    ~TestPropertyResolver() override = default;
    void PopulateProperties(
        const Params& params,
        ui::PropertyHandler& out_properties_container) override {
      out_properties_container.SetProperty(
          aura::client::kAppType, static_cast<int>(ash::AppType::ARC_APP));
    }
  };
  WMHelper::GetInstance()->RegisterAppPropertyResolver(
      std::make_unique<TestPropertyResolver>());

  ash::ArcOverlayManager arc_overlay_manager_;

  auto* widget1 = ash::TestWidgetBuilder()
                      .SetBounds(gfx::Rect(200, 200))
                      .BuildOwnedByNativeWidget();
  views::Textfield* textfield1 = new views::Textfield();
  widget1->GetContentsView()->AddChildView(textfield1);
  textfield1->SetBounds(0, 0, 100, 100);

  auto* widget2 = ash::TestWidgetBuilder()
                      .SetBounds(gfx::Rect(200, 200))
                      .BuildOwnedByNativeWidget();

  auto hold = arc_overlay_manager_.RegisterHostWindow(
      "test", widget1->GetNativeWindow());

  auto surface = std::make_unique<Surface>();
  auto shell_surface = std::make_unique<ShellSurface>(surface.get());
  gfx::Size buffer_size(10, 10);
  std::unique_ptr<Buffer> buffer(
      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  surface->SetClientSurfaceId("billing_id:test");
  surface->Attach(buffer.get());
  surface->Commit();
  EXPECT_TRUE(shell_surface->GetWidget());

  // The overlay should have the focus when created.
  EXPECT_EQ(keyboard.focused_surface_for_testing(), surface.get());

  widget2->Activate();
  EXPECT_FALSE(keyboard.focused_surface_for_testing());

  // Activating the host widget should set the focus back to the overlay.
  widget1->Activate();
  EXPECT_EQ(keyboard.focused_surface_for_testing(), surface.get());

  constexpr char kFocusedViewClassName[] = "OverlayNativeViewHost";
  EXPECT_STREQ(kFocusedViewClassName,
               widget1->GetFocusManager()->GetFocusedView()->GetClassName());

  // Tabbing should not move the focus away from the overlay.
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  generator.PressKey(ui::VKEY_TAB, 0);

  EXPECT_STREQ(kFocusedViewClassName,
               widget1->GetFocusManager()->GetFocusedView()->GetClassName());
  EXPECT_EQ(keyboard.focused_surface_for_testing(), surface.get());

  hold.RunAndReset();
  widget1->CloseNow();
}

TEST_F(KeyboardTest, OnKeyboardModifiers) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  // This should generate a modifier event.
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::US_A, true));
  EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
                                 kShiftMask | kNumLockMask, 0, 0, 0}));
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_A);
  generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // This should generate another modifier event.
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::US_B, true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{
                  kShiftMask | kAltMask | kNumLockMask, 0, 0, 0}));
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_B);
  generator.PressKey(ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // This should generate a third modifier event.
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::US_B, false));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  generator.ReleaseKey(ui::VKEY_B, 0);
  // 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) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  ui::DeviceHotplugEventObserver* device_data_manager =
      ui::DeviceDataManager::GetInstance();
  ASSERT_TRUE(device_data_manager != nullptr);
  // Make sure that DeviceDataManager has one external keyboard...
  const std::vector<ui::KeyboardDevice> keyboards{
      ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard")};
  device_data_manager->OnKeyboardDevicesUpdated(keyboards);
  // and a touch screen.
  const std::vector<ui::TouchscreenDevice> touch_screen{
      ui::TouchscreenDevice(3, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
                            "touch", gfx::Size(600, 400), 1)};
  device_data_manager->OnTouchscreenDevicesUpdated(touch_screen);

  ash::TabletModeController* tablet_mode_controller =
      ash::Shell::Get()->tablet_mode_controller();
  tablet_mode_controller->SetEnabledForTest(true);

  Seat seat;
  auto keyboard = std::make_unique<Keyboard>(
      std::make_unique<NiceMockKeyboardDelegate>(), &seat);

  MockKeyboardDeviceConfigurationDelegate configuration_delegate;

  EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
  keyboard->SetDeviceConfigurationDelegate(&configuration_delegate);
  EXPECT_TRUE(keyboard->HasDeviceConfigurationDelegate());
  testing::Mock::VerifyAndClearExpectations(&configuration_delegate);

  // Removing all keyboard devices in tablet mode calls
  // OnKeyboardTypeChanged() with false.
  EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(false));
  device_data_manager->OnKeyboardDevicesUpdated(
      std::vector<ui::KeyboardDevice>({}));
  testing::Mock::VerifyAndClearExpectations(&configuration_delegate);

  // Re-adding keyboards calls OnKeyboardTypeChanged() with true.
  EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
  device_data_manager->OnKeyboardDevicesUpdated(keyboards);
  testing::Mock::VerifyAndClearExpectations(&configuration_delegate);

  keyboard.reset();

  tablet_mode_controller->SetEnabledForTest(false);
}

TEST_F(KeyboardTest, OnKeyboardTypeChanged_AccessibilityKeyboard) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  ui::DeviceHotplugEventObserver* device_data_manager =
      ui::DeviceDataManager::GetInstance();
  ASSERT_TRUE(device_data_manager != nullptr);
  // Make sure that DeviceDataManager has one external keyboard.
  const std::vector<ui::KeyboardDevice> keyboards{
      ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard")};
  device_data_manager->OnKeyboardDevicesUpdated(keyboards);

  Seat seat;
  Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);
  MockKeyboardDeviceConfigurationDelegate configuration_delegate;

  EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
  keyboard.SetDeviceConfigurationDelegate(&configuration_delegate);
  EXPECT_TRUE(keyboard.HasDeviceConfigurationDelegate());
  testing::Mock::VerifyAndClearExpectations(&configuration_delegate);

  ash::AccessibilityControllerImpl* accessibility_controller =
      ash::Shell::Get()->accessibility_controller();

  // Enable a11y keyboard calls OnKeyboardTypeChanged() with false.
  EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(false));
  accessibility_controller->virtual_keyboard().SetEnabled(true);
  testing::Mock::VerifyAndClearExpectations(&configuration_delegate);

  // Disable a11y keyboard calls OnKeyboardTypeChanged() with true.
  EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true));
  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);
}

constexpr base::TimeDelta kDelta50Ms = base::Milliseconds(50);
constexpr base::TimeDelta kDelta500Ms = base::Milliseconds(500);
constexpr base::TimeDelta kDelta1000Ms = base::Milliseconds(1000);

TEST_F(KeyboardTest, KeyRepeatSettingsUninitialized) {
  Seat seat;

  // Simulate unsigned login state.
  auto* keyboard_controller = ash::Shell::Get()->keyboard_controller();
  keyboard_controller->OnSigninScreenPrefServiceInitialized(nullptr);

  // If KeyboardController is not initialized with prefs,
  // no key-repeat setting event should be triggered.
  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(testing::_, testing::_, testing::_))
      .Times(0);
  Keyboard keyboard(std::move(delegate), &seat);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Then, when the pref is initialized, key repeat setting event should be
  // triggered.
  TestingPrefServiceSimple pref_service;
  ash::KeyboardControllerImpl::RegisterProfilePrefs(pref_service.registry(),
                                                    /*country=*/"");

  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(testing::_, testing::_, testing::_));
  keyboard_controller->OnSigninScreenPrefServiceInitialized(&pref_service);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Unset the pref_service before its destruction just for tearing down.
  keyboard_controller->OnSigninScreenPrefServiceInitialized(nullptr);
}

TEST_F(KeyboardTest, KeyRepeatSettingsLoadDefaults) {
  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  EXPECT_CALL(*delegate,
              OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms));

  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
}

TEST_F(KeyboardTest, KeyRepeatSettingsLoadInitially) {
  std::string email = "user0@tray";
  SetUserPref(email, ash::prefs::kXkbAutoRepeatEnabled, base::Value(true));
  SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000));
  SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000));

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(true, kDelta1000Ms, kDelta1000Ms));
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  // 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, KeyRepeatSettingsUpdateAtRuntime) {
  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  // Initially load defaults.
  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(testing::_, testing::_, testing::_));
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Make sure that setting prefs triggers the corresponding delegate calls.
  const std::string email = "user0@tray";

  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(false, testing::_, testing::_));
  SetUserPref(email, ash::prefs::kXkbAutoRepeatEnabled, base::Value(false));
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(false, kDelta1000Ms, testing::_));
  SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000));
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(false, kDelta1000Ms, kDelta1000Ms));
  SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000));
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}

TEST_F(KeyboardTest, KeyRepeatSettingsIgnoredForNonActiveUser) {
  // Simulate two users, with the first user as active.
  CreateUserSessions(2);

  // Key repeat settings should be sent exactly once, for the default values.
  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms));
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Set prefs for non-active user; no calls should result.
  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(testing::_, testing::_, testing::_))
      .Times(0);
  const std::string email = "user1@tray";
  SetUserPref(email, ash::prefs::kXkbAutoRepeatEnabled, base::Value(true));
  SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000));
  SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000));
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}

TEST_F(KeyboardTest, KeyRepeatSettingsUpdateOnProfileChange) {
  // Simulate two users, with the first user as active.
  CreateUserSessions(2);

  // Second user has different preferences.
  std::string email = "user1@tray";
  SetUserPref(email, ash::prefs::kXkbAutoRepeatEnabled, base::Value(true));
  SetUserPref(email, ash::prefs::kXkbAutoRepeatDelay, base::Value(1000));
  SetUserPref(email, ash::prefs::kXkbAutoRepeatInterval, base::Value(1000));

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  // Initially, load default prefs for first user.
  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(true, kDelta500Ms, kDelta50Ms));
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Switching user should load new prefs.
  EXPECT_CALL(*delegate_ptr,
              OnKeyRepeatSettingsChanged(true, kDelta1000Ms, kDelta1000Ms));
  SimulateUserLogin(email, user_manager::UserType::USER_TYPE_REGULAR);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}

TEST_F(KeyboardTest, KeyboardLayout) {
  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  // Initially, update to the current keyboard layout.
  EXPECT_CALL(*delegate_ptr, OnKeyboardLayoutUpdated(testing::_));
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Updating the keyboard layout should trigger the delegate call.
  EXPECT_CALL(*delegate_ptr, OnKeyboardLayoutUpdated(testing::_));
  keyboard.OnKeyboardLayoutNameChanged("ja-jp");
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}

TEST_F(KeyboardTest, KeyboardObserver) {
  // Declare before the keyboard so the mock verification happens
  // after the keyboard destruction.
  MockKeyboardObserver observer1;
  MockKeyboardObserver observer2;

  Seat seat;
  Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);

  keyboard.AddObserver(&observer1);
  keyboard.AddObserver(&observer2);
  EXPECT_TRUE(keyboard.HasObserver(&observer1));
  EXPECT_TRUE(keyboard.HasObserver(&observer2));
  testing::Mock::VerifyAndClearExpectations(&observer1);
  testing::Mock::VerifyAndClearExpectations(&observer2);

  keyboard.RemoveObserver(&observer1);
  EXPECT_FALSE(keyboard.HasObserver(&observer1));
  EXPECT_TRUE(keyboard.HasObserver(&observer2));
  testing::Mock::VerifyAndClearExpectations(&observer1);
  testing::Mock::VerifyAndClearExpectations(&observer2);

  // Called from the destructor of Keyboard.
  EXPECT_CALL(observer1, OnKeyboardDestroying(&keyboard)).Times(0);
  EXPECT_CALL(observer2, OnKeyboardDestroying(&keyboard));
}

TEST_F(KeyboardTest, NeedKeyboardKeyAcks) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  Seat seat;
  Keyboard keyboard(std::make_unique<NiceMockKeyboardDelegate>(), &seat);

  EXPECT_FALSE(keyboard.AreKeyboardKeyAcksNeeded());
  keyboard.SetNeedKeyboardKeyAcks(true);
  EXPECT_TRUE(keyboard.AreKeyboardKeyAcksNeeded());
  keyboard.SetNeedKeyboardKeyAcks(false);
  EXPECT_FALSE(keyboard.AreKeyboardKeyAcksNeeded());
}

TEST_F(KeyboardTest, AckKeyboardKey) {
  auto surface = std::make_unique<Surface>();
  auto shell_surface = std::make_unique<TestShellSurface>(surface.get());
  gfx::Size buffer_size(10, 10);
  std::unique_ptr<Buffer> buffer(
      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  surface->Attach(buffer.get());
  surface->Commit();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface.get(), base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // If we don't set NeedKeyboardAckKeys to true, accelerators are always passed
  // to ShellSurface.
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  // Press KEY_W with Ctrl.
  EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
                                        ui::VKEY_W, ui::EF_CONTROL_DOWN,
                                        ui::Accelerator::KeyState::PRESSED)))
      .WillOnce(testing::Return(true));
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_W);
  generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);

  // Release KEY_W.
  generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
  testing::Mock::VerifyAndClearExpectations(shell_surface.get());

  // If we set NeedKeyboardAckKeys to true, only unhandled accelerators are
  // passed to ShellSurface.
  keyboard.SetNeedKeyboardKeyAcks(true);

  // Press KEY_W with Ctrl.
  EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
      .WillOnce(testing::Return(1));
  generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Send ack for the key press.
  EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
                                        ui::VKEY_W, ui::EF_CONTROL_DOWN,
                                        ui::Accelerator::KeyState::PRESSED)))
      .WillOnce(testing::Return(true));
  keyboard.AckKeyboardKey(1, false /* handled */);
  testing::Mock::VerifyAndClearExpectations(shell_surface.get());

  // Release KEY_W.
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::US_W, false))
      .WillOnce(testing::Return(2));
  generator.ReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Send ack for the key release.
  keyboard.AckKeyboardKey(2, false /* handled */);

  // Press KEY_W with Ctrl again.
  EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
      .WillOnce(testing::Return(3));
  generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Send ack for the key press.
  // AcceleratorPressed is not called when the accelerator is already handled.
  keyboard.AckKeyboardKey(3, true /* handled */);

  // A repeat key event should not be sent to the client and also should not
  // invoke the accelerator.
  EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
                                        ui::VKEY_W, ui::EF_CONTROL_DOWN,
                                        ui::Accelerator::KeyState::PRESSED)))
      .Times(0);
  generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT);
  testing::Mock::VerifyAndClearExpectations(shell_surface.get());

  // Another key press event while holding the key is also ignored and should
  // not invoke the accelerator.
  EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
                                        ui::VKEY_W, ui::EF_CONTROL_DOWN,
                                        ui::Accelerator::KeyState::PRESSED)))
      .Times(0);
  generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  testing::Mock::VerifyAndClearExpectations(shell_surface.get());

  // Release the key and reset modifier_flags.
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::US_W, false));
  generator.ReleaseKey(ui::VKEY_W, 0);
  // 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) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  keyboard.SetNeedKeyboardKeyAcks(true);

  // Press KEY_W with Ctrl.
  EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
                                 kControlMask | kNumLockMask, 0, 0, 0}))
      .Times(1);
  EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
      .WillOnce(testing::Return(1));
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_W);
  generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Move focus from the window
  EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface));
  focus_client->FocusWindow(nullptr);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Send ack for the key press. |AcceleratorPressed()| should not be called.
  keyboard.AckKeyboardKey(1, false /* handled */);
}

TEST_F(KeyboardTest, AckKeyboardKeyExpired) {
  std::unique_ptr<Surface> surface(new Surface);
  auto shell_surface = std::make_unique<TestShellSurface>(surface.get());
  gfx::Size buffer_size(10, 10);
  std::unique_ptr<Buffer> buffer(
      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  surface->Attach(buffer.get());
  surface->Commit();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface.get(), base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  keyboard.SetNeedKeyboardKeyAcks(true);

  // Press KEY_W with Ctrl.
  EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
                                 kControlMask | kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
      .WillOnce(testing::Return(1));
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_W);
  generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Keyboard processes pending events as if it is handled when it expires,
  // so |AcceleratorPressed()| should not be called.
  EXPECT_CALL(*shell_surface.get(), AcceleratorPressed(ui::Accelerator(
                                        ui::VKEY_W, ui::EF_CONTROL_DOWN,
                                        ui::Accelerator::KeyState::PRESSED)))
      .Times(0);

  // Wait until |ProcessExpiredPendingKeyAcks| is fired.
  task_environment()->FastForwardBy(base::Milliseconds(1000));

  // Send ack for the key press as if it was not handled. In the normal case,
  // |AcceleratorPressed()| should be called, but since the timeout passed, 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,
  // |AcceleratorPressed()| should not be called.
  keyboard.AckKeyboardKey(1, false /* handled */);

  // Release the key and reset modifier_flags.
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::US_W, false));
  generator.ReleaseKey(ui::VKEY_W, 0);
  // 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, AckKeyboardKeyAcceleratorOnRelease) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  // Set lacros attribute now for testing. This can be removed, when
  // all clients are migrated into this model.
  surface->window()->SetProperty(aura::client::kAppType,
                                 static_cast<int>(ash::AppType::LACROS));

  // Register accelerator to be triggered.
  ui::TestAcceleratorTarget accelerator_target;
  {
    ui::Accelerator accelerator(ui::VKEY_LWIN, 0,
                                ui::Accelerator::KeyState::RELEASED);
    ash::AcceleratorControllerImpl* controller =
        ash::Shell::Get()->accelerator_controller();
    controller->Register({accelerator}, &accelerator_target);
  }

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  keyboard.SetNeedKeyboardKeyAcks(true);

  // Press SEARCH key.
  EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
                                 kCommandMask | kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::META_LEFT, true))
      .WillOnce(testing::Return(1));

  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::META_LEFT);
  generator.PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  // SEARCH key can be used as a modifier, so it is handled in release event.
  // Thus accelerator handler should not be triggered.
  EXPECT_EQ(0, accelerator_target.accelerator_count());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Send ack for the key press as if it was not handled.
  keyboard.AckKeyboardKey(1, false /* handled */);

  // Wait until |ProcessExpiredPendingKeyAcks| is fired.
  task_environment()->FastForwardBy(base::Milliseconds(1000));

  // Release the key and reset modifier_flags.
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardKey(testing::_, ui::DomCode::META_LEFT, false))
      .WillOnce(testing::Return(2));
  generator.ReleaseKey(ui::VKEY_LWIN, 0);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
  // Now the accelerator should be handled.
  EXPECT_EQ(1, accelerator_target.accelerator_count());

  // Then, on ack key, even if application does not process the key event,
  // accelerator key should not be handled (because it is already done).
  keyboard.AckKeyboardKey(2, false /* handled */);
  EXPECT_EQ(1, accelerator_target.accelerator_count());

  // 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
// another window, it causes clearing the map of pending key acks in Keyboard.
// We can't assume that an iterator of the map is valid after processing an
// accelerator.
class TestShellSurfaceWithMovingFocusAccelerator : public ShellSurface {
 public:
  explicit TestShellSurfaceWithMovingFocusAccelerator(Surface* surface)
      : ShellSurface(surface) {}

  bool AcceleratorPressed(const ui::Accelerator& accelerator) override {
    aura::client::FocusClient* focus_client =
        aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
    focus_client->FocusWindow(nullptr);
    return true;
  }
};

TEST_F(KeyboardTest, AckKeyboardKeyExpiredWithMovingFocusAccelerator) {
  std::unique_ptr<Surface> surface(new Surface);
  auto shell_surface =
      std::make_unique<TestShellSurfaceWithMovingFocusAccelerator>(
          surface.get());
  gfx::Size buffer_size(10, 10);
  std::unique_ptr<Buffer> buffer(
      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  surface->Attach(buffer.get());
  surface->Commit();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface.get()))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface.get(), base::flat_map<ui::DomCode, KeyState>()));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  keyboard.SetNeedKeyboardKeyAcks(true);

  // Press KEY_W with Ctrl.
  EXPECT_CALL(*delegate_ptr, OnKeyboardModifiers(KeyboardModifiers{
                                 kControlMask | kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(*delegate_ptr, OnKeyboardKey(testing::_, ui::DomCode::US_W, true))
      .WillOnce(testing::Return(1));
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_W);
  generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  EXPECT_CALL(*delegate_ptr, OnKeyboardLeave(surface.get()));

  // Send ack as unhandled. This will call |AcceleratorPressed| and move the
  // focus.
  keyboard.AckKeyboardKey(1, false /* handled */);

  // Wait until |ProcessExpiredPendingKeyAcks| is fired.
  task_environment()->FastForwardBy(base::Milliseconds(1000));

  // 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);
}

TEST_F(KeyboardTest, OnKeyboardKey_ChangeFocusInPreTargetHandler) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();
  auto normal_window = CreateAppWindow(gfx::Rect(0, 0, 100, 100));
  TestEventHandler handler{shell_surface->GetWidget()->GetNativeView()};

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  NiceMockKeyboardObserver observer;
  Seat seat;
  Keyboard keyboard(std::move(delegate), &seat);
  keyboard.AddObserver(&observer);

  // Focus the non-exo window.
  focus_client->FocusWindow(normal_window.get());

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  // Keyboard should not get a key event sent to the non-exo window.
  generator.PressKey(ui::VKEY_A, 0);
  generator.ReleaseKey(ui::VKEY_A, 0);
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  // Sending a key event causes a focus change.
  // It calls OnKeyboardEnter, but OnKeyboardKey should not be called because
  // the event's target is |normal_window|.
  wm_helper()->AddPreTargetHandler(&handler);

  EXPECT_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*delegate_ptr,
              OnKeyboardModifiers(KeyboardModifiers{kNumLockMask, 0, 0, 0}));
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>()));

  generator.PressKey(ui::VKEY_A, 0);
  EXPECT_EQ(shell_surface->GetWidget()->GetNativeView(),
            focus_client->GetFocusedWindow());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);

  wm_helper()->RemovePreTargetHandler(&handler);
}

TEST_F(KeyboardTest, SystemKeysNotSentAsPressedKeys) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->root_surface();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);

  Seat seat;

  // Pressing keys before Keyboard instance is created and surface has
  // received focus.
  ui::test::EventGenerator* generator = GetEventGenerator();
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_A);
  generator->PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::LAUNCH_APP1);
  generator->PressKey(ui::VKEY_MEDIA_LAUNCH_APP1, 0);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  auto keyboard = std::make_unique<Keyboard>(std::move(delegate), &seat);
  ON_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillByDefault(testing::Return(true));

  // LAUNCH_APP1 should be filtered out before sending OnKeyboardEnter.
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(surface, base::flat_map<ui::DomCode, KeyState>(
                                   {{ui::DomCode::US_A,
                                     KeyState{ui::DomCode::US_A, false}}})));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}

TEST_F(KeyboardTest, CanConsumeSystemKeysSentAsPressedKeys) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->root_surface();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  focus_client->FocusWindow(nullptr);
  ash::WindowState::Get(surface->window()->GetToplevelWindow())
      ->SetCanConsumeSystemKeys(true);
  Seat seat;

  // Pressing keys before Keyboard instance is created and surface has
  // received focus.
  ui::test::EventGenerator* generator = GetEventGenerator();
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::US_A);
  generator->PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
  seat.set_physical_code_for_currently_processing_event_for_testing(
      ui::DomCode::LAUNCH_APP1);
  generator->PressKey(ui::VKEY_MEDIA_LAUNCH_APP1, 0);

  auto delegate = std::make_unique<NiceMockKeyboardDelegate>();
  auto* delegate_ptr = delegate.get();
  auto keyboard = std::make_unique<Keyboard>(std::move(delegate), &seat);
  ON_CALL(*delegate_ptr, CanAcceptKeyboardEventsForSurface(surface))
      .WillByDefault(testing::Return(true));

  // LAUNCH_APP1 should not be filtered out before sending OnKeyboardEnter.
  EXPECT_CALL(
      *delegate_ptr,
      OnKeyboardEnter(
          surface, base::flat_map<ui::DomCode, KeyState>({
                       {ui::DomCode::US_A, KeyState{ui::DomCode::US_A, false}},
                       {ui::DomCode::LAUNCH_APP1,
                        KeyState{ui::DomCode::LAUNCH_APP1, false}},
                   })));
  focus_client->FocusWindow(surface->window());
  testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}
}  // namespace
}  // namespace exo
