// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/common/json_message_codec.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
#include "flutter/shell/platform/windows/flutter_windows_engine.h"
#include "flutter/shell/platform/windows/flutter_windows_view.h"
#include "flutter/shell/platform/windows/keyboard_key_channel_handler.h"
#include "flutter/shell/platform/windows/keyboard_key_embedder_handler.h"
#include "flutter/shell/platform/windows/keyboard_key_handler.h"
#include "flutter/shell/platform/windows/keyboard_manager.h"
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
#include "flutter/shell/platform/windows/testing/test_keyboard.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"

#include <functional>
#include <list>
#include <vector>

using testing::_;
using testing::Invoke;
using testing::Return;
using namespace ::flutter::testing::keycodes;

namespace flutter {
namespace testing {

namespace {

constexpr SHORT kStateMaskToggled = 0x01;
constexpr SHORT kStateMaskPressed = 0x80;

constexpr uint64_t kScanCodeBackquote = 0x29;
constexpr uint64_t kScanCodeKeyA = 0x1e;
constexpr uint64_t kScanCodeKeyB = 0x30;
constexpr uint64_t kScanCodeKeyE = 0x12;
constexpr uint64_t kScanCodeKeyF = 0x21;
constexpr uint64_t kScanCodeKeyO = 0x18;
constexpr uint64_t kScanCodeKeyQ = 0x10;
constexpr uint64_t kScanCodeKeyW = 0x11;
constexpr uint64_t kScanCodeDigit1 = 0x02;
constexpr uint64_t kScanCodeDigit2 = 0x03;
constexpr uint64_t kScanCodeDigit6 = 0x07;
// constexpr uint64_t kScanCodeNumpad1 = 0x4f;
// constexpr uint64_t kScanCodeNumLock = 0x45;
constexpr uint64_t kScanCodeControl = 0x1d;
constexpr uint64_t kScanCodeMetaLeft = 0x5b;
constexpr uint64_t kScanCodeMetaRight = 0x5c;
constexpr uint64_t kScanCodeAlt = 0x38;
constexpr uint64_t kScanCodeShiftLeft = 0x2a;
constexpr uint64_t kScanCodeShiftRight = 0x36;
constexpr uint64_t kScanCodeBracketLeft = 0x1a;
constexpr uint64_t kScanCodeArrowLeft = 0x4b;
constexpr uint64_t kScanCodeEnter = 0x1c;
constexpr uint64_t kScanCodeBackspace = 0x0e;

constexpr uint64_t kVirtualDigit1 = 0x31;
constexpr uint64_t kVirtualKeyA = 0x41;
constexpr uint64_t kVirtualKeyB = 0x42;
constexpr uint64_t kVirtualKeyE = 0x45;
constexpr uint64_t kVirtualKeyF = 0x46;
constexpr uint64_t kVirtualKeyO = 0x4f;
constexpr uint64_t kVirtualKeyQ = 0x51;
constexpr uint64_t kVirtualKeyW = 0x57;

constexpr bool kSynthesized = true;
constexpr bool kNotSynthesized = false;

typedef UINT (*MapVirtualKeyLayout)(UINT uCode, UINT uMapType);
typedef std::function<UINT(UINT)> MapVirtualKeyToChar;

UINT LayoutDefault(UINT uCode, UINT uMapType) {
  return MapVirtualKey(uCode, uMapType);
}

UINT LayoutFrench(UINT uCode, UINT uMapType) {
  switch (uMapType) {
    case MAPVK_VK_TO_CHAR:
      switch (uCode) {
        case 0xDD:
          return 0x8000005E;
        default:
          return MapVirtualKey(uCode, MAPVK_VK_TO_CHAR);
      }
    default:
      return MapVirtualKey(uCode, uMapType);
  }
}

class TestKeyboardManager : public KeyboardManager {
 public:
  explicit TestKeyboardManager(WindowDelegate* delegate)
      : KeyboardManager(delegate) {}

  bool DuringRedispatch() { return during_redispatch_; }

 protected:
  void RedispatchEvent(std::unique_ptr<PendingEvent> event) override {
    assert(!during_redispatch_);
    during_redispatch_ = true;
    KeyboardManager::RedispatchEvent(std::move(event));
    during_redispatch_ = false;
  }

 private:
  bool during_redispatch_ = false;
};

// Injecting this kind of keyboard change means that a key state (the true
// state for a key, typically a modifier) should be changed.
struct KeyStateChange {
  uint32_t key;
  bool pressed;
  bool toggled_on;
};

// Injecting this kind of keyboard change does not make any changes to the
// keyboard system, but indicates that a forged event is expected here, and
// that `KeyStateChange`s after this will be applied only after the forged
// event.
//
// See `IsKeyDownAltRight` for explaination for foged events.
struct ExpectForgedMessage {
  explicit ExpectForgedMessage(Win32Message message) : message(message){};

  Win32Message message;
};

struct KeyboardChange {
  // The constructors are intentionally for implicit conversion.

  KeyboardChange(Win32Message message) : type(kMessage) {
    content.message = message;
  }

  KeyboardChange(KeyStateChange change) : type(kKeyStateChange) {
    content.key_state_change = change;
  }

  KeyboardChange(ExpectForgedMessage forged_message)
      : type(kExpectForgedMessage) {
    content.expected_forged_message = forged_message.message;
  }

  enum Type {
    kMessage,
    kKeyStateChange,
    kExpectForgedMessage,
  } type;

  union {
    Win32Message message;
    KeyStateChange key_state_change;
    Win32Message expected_forged_message;
  } content;
};

class TestKeystate {
 public:
  void Set(uint32_t virtual_key, bool pressed, bool toggled_on = false) {
    state_[virtual_key] = (pressed ? kStateMaskPressed : 0) |
                          (toggled_on ? kStateMaskToggled : 0);
  }

  SHORT Get(uint32_t virtual_key) { return state_[virtual_key]; }

 private:
  std::map<uint32_t, SHORT> state_;
};

class MockKeyboardManagerDelegate : public KeyboardManager::WindowDelegate,
                                    protected MockMessageQueue {
 public:
  MockKeyboardManagerDelegate(WindowBindingHandlerDelegate* view,
                              MapVirtualKeyToChar map_vk_to_char)
      : view_(view), map_vk_to_char_(std::move(map_vk_to_char)) {
    keyboard_manager_ = std::make_unique<TestKeyboardManager>(this);
  }
  virtual ~MockKeyboardManagerDelegate() {}

  // |KeyboardManager::WindowDelegate|
  void OnKey(int key,
             int scancode,
             int action,
             char32_t character,
             bool extended,
             bool was_down,
             KeyEventCallback callback) override {
    view_->OnKey(key, scancode, action, character, extended, was_down,
                 callback);
  }

  // |KeyboardManager::WindowDelegate|
  void OnText(const std::u16string& text) override { view_->OnText(text); }

  SHORT GetKeyState(int virtual_key) { return key_state_.Get(virtual_key); }

  void InjectKeyboardChanges(std::vector<KeyboardChange> changes) {
    // First queue all messages to enable peeking.
    for (const KeyboardChange& change : changes) {
      switch (change.type) {
        case KeyboardChange::kMessage:
          PushBack(&change.content.message);
          break;
        default:
          break;
      }
    }
    for (const KeyboardChange& change : changes) {
      switch (change.type) {
        case KeyboardChange::kMessage:
          DispatchFront();
          break;
        case KeyboardChange::kExpectForgedMessage:
          forged_message_expectations_.push_back(ForgedMessageExpectation{
              .message = change.content.expected_forged_message,
          });
          break;
        case KeyboardChange::kKeyStateChange: {
          const KeyStateChange& state_change = change.content.key_state_change;
          if (forged_message_expectations_.empty()) {
            key_state_.Set(state_change.key, state_change.pressed,
                           state_change.toggled_on);
          } else {
            forged_message_expectations_.back()
                .state_changes_afterwards.push_back(state_change);
          }
          break;
        }
        default:
          assert(false);
      }
    }
  }

  std::list<Win32Message>& RedispatchedMessages() {
    return redispatched_messages_;
  }

 protected:
  BOOL Win32PeekMessage(LPMSG lpMsg,
                        UINT wMsgFilterMin,
                        UINT wMsgFilterMax,
                        UINT wRemoveMsg) override {
    return MockMessageQueue::Win32PeekMessage(lpMsg, wMsgFilterMin,
                                              wMsgFilterMax, wRemoveMsg);
  }

  uint32_t Win32MapVkToChar(uint32_t virtual_key) override {
    return map_vk_to_char_(virtual_key);
  }

  // This method is called for each message injected by test cases with
  // `tester.InjectMessages`.
  LRESULT Win32SendMessage(UINT const message,
                           WPARAM const wparam,
                           LPARAM const lparam) override {
    return keyboard_manager_->HandleMessage(message, wparam, lparam)
               ? 0
               : kWmResultDefault;
  }

  // This method is called when the keyboard manager redispatches messages
  // or forges messages (such as CtrlLeft up right before AltGr up).
  UINT Win32DispatchMessage(UINT Msg, WPARAM wParam, LPARAM lParam) override {
    bool handled = keyboard_manager_->HandleMessage(Msg, wParam, lParam);
    if (keyboard_manager_->DuringRedispatch()) {
      redispatched_messages_.push_back(Win32Message{
          .message = Msg,
          .wParam = wParam,
          .lParam = lParam,
      });
      EXPECT_FALSE(handled);
    } else {
      EXPECT_FALSE(forged_message_expectations_.empty());
      ForgedMessageExpectation expectation =
          forged_message_expectations_.front();
      forged_message_expectations_.pop_front();
      EXPECT_EQ(expectation.message.message, Msg);
      EXPECT_EQ(expectation.message.wParam, wParam);
      EXPECT_EQ(expectation.message.lParam, lParam);
      if (expectation.message.expected_result != kWmResultDontCheck) {
        EXPECT_EQ(expectation.message.expected_result,
                  handled ? kWmResultZero : kWmResultDefault);
      }
      for (const KeyStateChange& change :
           expectation.state_changes_afterwards) {
        key_state_.Set(change.key, change.pressed, change.toggled_on);
      }
    }
    return 0;
  }

 private:
  struct ForgedMessageExpectation {
    Win32Message message;
    std::list<KeyStateChange> state_changes_afterwards;
  };

  WindowBindingHandlerDelegate* view_;
  std::unique_ptr<TestKeyboardManager> keyboard_manager_;
  std::list<ForgedMessageExpectation> forged_message_expectations_;
  MapVirtualKeyToChar map_vk_to_char_;
  TestKeystate key_state_;
  std::list<Win32Message> redispatched_messages_;
};

// A FlutterWindowsView that overrides the RegisterKeyboardHandlers function
// to register the keyboard hook handlers that can be spied upon.
class TestFlutterWindowsView : public FlutterWindowsView {
 public:
  typedef std::function<void(const std::u16string& text)> U16StringHandler;

  TestFlutterWindowsView(
      U16StringHandler on_text,
      KeyboardKeyEmbedderHandler::GetKeyStateHandler get_keyboard_state,
      KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan)
      // The WindowBindingHandler is used for window size and such, and doesn't
      // affect keyboard.
      : FlutterWindowsView(
            std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>()),
        get_keyboard_state_(std::move(get_keyboard_state)),
        map_vk_to_scan_(std::move(map_vk_to_scan)),
        on_text_(std::move(on_text)) {}

  void OnText(const std::u16string& text) override { on_text_(text); }

  void HandleMessage(const char* channel,
                     const char* method,
                     const char* args) {
    rapidjson::Document args_doc;
    args_doc.Parse(args);
    assert(!args_doc.HasParseError());

    rapidjson::Document message_doc(rapidjson::kObjectType);
    auto& allocator = message_doc.GetAllocator();
    message_doc.AddMember("method", rapidjson::Value(method, allocator),
                          allocator);
    message_doc.AddMember("args", args_doc, allocator);

    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    message_doc.Accept(writer);

    std::unique_ptr<std::vector<uint8_t>> data =
        JsonMessageCodec::GetInstance().EncodeMessage(message_doc);
    FlutterPlatformMessageResponseHandle response_handle;
    const FlutterPlatformMessage message = {
        sizeof(FlutterPlatformMessage),  // struct_size
        channel,                         // channel
        data->data(),                    // message
        data->size(),                    // message_size
        &response_handle,                // response_handle
    };
    GetEngine()->HandlePlatformMessage(&message);
  }

 protected:
  std::unique_ptr<KeyboardHandlerBase> CreateKeyboardKeyHandler(
      BinaryMessenger* messenger,
      KeyboardKeyEmbedderHandler::GetKeyStateHandler get_key_state,
      KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan)
      override {
    return FlutterWindowsView::CreateKeyboardKeyHandler(
        messenger,
        [this](int virtual_key) { return get_keyboard_state_(virtual_key); },
        [this](int virtual_key, bool extended) {
          return map_vk_to_scan_(virtual_key, extended);
        });
  }

 private:
  U16StringHandler on_text_;
  KeyboardKeyEmbedderHandler::GetKeyStateHandler get_keyboard_state_;
  KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan_;
};

typedef struct {
  enum {
    kKeyCallOnKey,
    kKeyCallOnText,
    kKeyCallTextMethodCall,
  } type;

  // Only one of the following fields should be assigned.
  FlutterKeyEvent key_event;     // For kKeyCallOnKey
  std::u16string text;           // For kKeyCallOnText
  std::string text_method_call;  // For kKeyCallTextMethodCall
} KeyCall;

static std::vector<KeyCall> key_calls;

void clear_key_calls() {
  for (KeyCall& key_call : key_calls) {
    if (key_call.type == KeyCall::kKeyCallOnKey &&
        key_call.key_event.character != nullptr) {
      delete[] key_call.key_event.character;
    }
  }
  key_calls.clear();
}

class KeyboardTester {
 public:
  using ResponseHandler =
      std::function<void(MockKeyResponseController::ResponseCallback)>;

  explicit KeyboardTester()
      : callback_handler_(RespondValue(false)),
        map_virtual_key_layout_(LayoutDefault) {
    view_ = std::make_unique<TestFlutterWindowsView>(
        [](const std::u16string& text) {
          key_calls.push_back(KeyCall{
              .type = KeyCall::kKeyCallOnText,
              .text = text,
          });
        },
        [this](int virtual_key) -> SHORT {
          // `window_` is not initialized yet when this callback is first
          // called.
          return window_ ? window_->GetKeyState(virtual_key) : 0;
        },
        [this](UINT virtual_key, bool extended) -> SHORT {
          return map_virtual_key_layout_(
              virtual_key, extended ? MAPVK_VK_TO_VSC_EX : MAPVK_VK_TO_VSC);
        });
    view_->SetEngine(GetTestEngine(
        [&callback_handler = callback_handler_](
            const FlutterKeyEvent* event,
            MockKeyResponseController::ResponseCallback callback) {
          FlutterKeyEvent clone_event = *event;
          clone_event.character = event->character == nullptr
                                      ? nullptr
                                      : clone_string(event->character);
          key_calls.push_back(KeyCall{
              .type = KeyCall::kKeyCallOnKey,
              .key_event = clone_event,
          });
          callback_handler(event, callback);
        }));
    window_ = std::make_unique<MockKeyboardManagerDelegate>(
        view_.get(), [this](UINT virtual_key) -> SHORT {
          return map_virtual_key_layout_(virtual_key, MAPVK_VK_TO_CHAR);
        });
  }

  TestFlutterWindowsView& GetView() { return *view_; }
  MockKeyboardManagerDelegate& GetWindow() { return *window_; }

  // Set all events to be handled (true) or unhandled (false).
  void Responding(bool response) { callback_handler_ = RespondValue(response); }

  // Manually handle event callback of the onKeyData embedder API.
  //
  // On every onKeyData call, the |handler| will be invoked with the target
  // key data and the result callback. Immediately calling the callback with
  // a boolean is equivalent to setting |Responding| with the boolean. However,
  // |LateResponding| allows storing the callback to call later.
  void LateResponding(
      MockKeyResponseController::EmbedderCallbackHandler handler) {
    callback_handler_ = std::move(handler);
  }

  void SetLayout(MapVirtualKeyLayout layout) {
    map_virtual_key_layout_ = layout == nullptr ? LayoutDefault : layout;
  }

  void InjectKeyboardChanges(std::vector<KeyboardChange> changes) {
    assert(window_ != nullptr);
    window_->InjectKeyboardChanges(changes);
  }

  // Get the number of redispatched messages since the last clear, then clear
  // the counter.
  size_t RedispatchedMessageCountAndClear() {
    auto& messages = window_->RedispatchedMessages();
    size_t count = messages.size();
    messages.clear();
    return count;
  }

 private:
  std::unique_ptr<TestFlutterWindowsView> view_;
  std::unique_ptr<MockKeyboardManagerDelegate> window_;
  MockKeyResponseController::EmbedderCallbackHandler callback_handler_;
  MapVirtualKeyLayout map_virtual_key_layout_;

  // Returns an engine instance configured with dummy project path values, and
  // overridden methods for sending platform messages, so that the engine can
  // respond as if the framework were connected.
  static std::unique_ptr<FlutterWindowsEngine> GetTestEngine(
      MockKeyResponseController::EmbedderCallbackHandler
          embedder_callback_handler) {
    FlutterDesktopEngineProperties properties = {};
    properties.assets_path = L"C:\\foo\\flutter_assets";
    properties.icu_data_path = L"C:\\foo\\icudtl.dat";
    properties.aot_library_path = L"C:\\foo\\aot.so";
    FlutterProjectBundle project(properties);
    auto engine = std::make_unique<FlutterWindowsEngine>(project);

    EngineModifier modifier(engine.get());

    auto key_response_controller =
        std::make_shared<MockKeyResponseController>();
    key_response_controller->SetEmbedderResponse(
        std::move(embedder_callback_handler));
    key_response_controller->SetTextInputResponse(
        [](std::unique_ptr<rapidjson::Document> document) {
          rapidjson::StringBuffer buffer;
          rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
          document->Accept(writer);
          key_calls.push_back(KeyCall{
              .type = KeyCall::kKeyCallTextMethodCall,
              .text_method_call = buffer.GetString(),
          });
        });

    MockEmbedderApiForKeyboard(modifier, key_response_controller);

    engine->Run();
    return engine;
  }

  static MockKeyResponseController::EmbedderCallbackHandler RespondValue(
      bool value) {
    return [value](const FlutterKeyEvent* event,
                   MockKeyResponseController::ResponseCallback callback) {
      callback(value);
    };
  }
};

}  // namespace

// Define compound `expect` in macros. If they're defined in functions, the
// stacktrace wouldn't print where the function is called in the unit tests.

#define EXPECT_CALL_IS_EVENT(_key_call, ...)         \
  EXPECT_EQ(_key_call.type, KeyCall::kKeyCallOnKey); \
  EXPECT_EVENT_EQUALS(_key_call.key_event, __VA_ARGS__);

#define EXPECT_CALL_IS_TEXT(_key_call, u16_string)    \
  EXPECT_EQ(_key_call.type, KeyCall::kKeyCallOnText); \
  EXPECT_EQ(_key_call.text, u16_string);

#define EXPECT_CALL_IS_TEXT_METHOD_CALL(_key_call, json_string) \
  EXPECT_EQ(_key_call.type, KeyCall::kKeyCallTextMethodCall);   \
  EXPECT_STREQ(_key_call.text_method_call.c_str(), json_string);

TEST(KeyboardTest, LowerCaseAHandled) {
  KeyboardTester tester;
  tester.Responding(true);

  // US Keyboard layout

  // Press A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
                       kLogicalKeyA, "a", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);

  // Release A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyA,
                       kLogicalKeyA, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
}

TEST(KeyboardTest, LowerCaseAUnhandled) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
                       kLogicalKeyA, "a", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"a");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyA,
                       kLogicalKeyA, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

TEST(KeyboardTest, ArrowLeftHandled) {
  KeyboardTester tester;
  tester.Responding(true);

  // US Keyboard layout

  // Press ArrowLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{VK_LEFT, kScanCodeArrowLeft, kExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalArrowLeft, kLogicalArrowLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);

  // Release ArrowLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{VK_LEFT, kScanCodeArrowLeft, kExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalArrowLeft,
                       kLogicalArrowLeft, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
}

TEST(KeyboardTest, ArrowLeftUnhandled) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press ArrowLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{VK_LEFT, kScanCodeArrowLeft, kExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalArrowLeft, kLogicalArrowLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release ArrowLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{VK_LEFT, kScanCodeArrowLeft, kExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalArrowLeft,
                       kLogicalArrowLeft, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

TEST(KeyboardTest, ShiftLeftUnhandled) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press ShiftLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LSHIFT, true, false},
      WmKeyDownInfo{VK_SHIFT, kScanCodeShiftLeft, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalShiftLeft, kLogicalShiftLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Hold ShiftLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{VK_SHIFT, kScanCodeShiftLeft, kNotExtended, kWasDown}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeRepeat,
                       kPhysicalShiftLeft, kLogicalShiftLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release ShiftLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LSHIFT, false, true},
      WmKeyUpInfo{VK_SHIFT, kScanCodeShiftLeft, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalShiftLeft,
                       kLogicalShiftLeft, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

TEST(KeyboardTest, ShiftRightUnhandled) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press ShiftRight
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RSHIFT, true, false},
      WmKeyDownInfo{VK_SHIFT, kScanCodeShiftRight, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalShiftRight, kLogicalShiftRight, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release ShiftRight
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RSHIFT, false, true},
      WmKeyUpInfo{VK_SHIFT, kScanCodeShiftRight, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalShiftRight, kLogicalShiftRight, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

TEST(KeyboardTest, CtrlLeftUnhandled) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press CtrlLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, true, false},
      WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release CtrlLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, false, true},
      WmKeyUpInfo{VK_SHIFT, kScanCodeControl, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

TEST(KeyboardTest, CtrlRightUnhandled) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press CtrlRight
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RCONTROL, true, false},
      WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalControlRight, kLogicalControlRight, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release CtrlRight
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RCONTROL, false, true},
      WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalControlRight, kLogicalControlRight, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

TEST(KeyboardTest, AltLeftUnhandled) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press AltLeft. AltLeft is a SysKeyDown event.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LMENU, true, false},
      WmSysKeyDownInfo{VK_MENU, kScanCodeAlt, kNotExtended, kWasUp}.Build(
          kWmResultDefault)});  // Always pass to the default WndProc.

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalAltLeft,
                       kLogicalAltLeft, "", kNotSynthesized);
  clear_key_calls();
  // Don't redispatch sys messages.
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);

  // Release AltLeft. AltLeft is a SysKeyUp event.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LMENU, false, true},
      WmSysKeyUpInfo{VK_MENU, kScanCodeAlt, kNotExtended}.Build(
          kWmResultDefault)});  // Always pass to the default WndProc.

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalAltLeft,
                       kLogicalAltLeft, "", kNotSynthesized);
  clear_key_calls();
  // Don't redispatch sys messages.
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
}

TEST(KeyboardTest, AltRightUnhandled) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press AltRight. AltRight is a SysKeyDown event.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RMENU, true, false},
      WmSysKeyDownInfo{VK_MENU, kScanCodeAlt, kExtended, kWasUp}.Build(
          kWmResultDefault)});  // Always pass to the default WndProc.

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalAltRight, kLogicalAltRight, "",
                       kNotSynthesized);
  clear_key_calls();
  // Don't redispatch sys messages.
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);

  // Release AltRight. AltRight is a SysKeyUp event.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RMENU, false, true},
      WmSysKeyUpInfo{VK_MENU, kScanCodeAlt, kExtended}.Build(
          kWmResultDefault)});  // Always pass to the default WndProc.

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalAltRight,
                       kLogicalAltRight, "", kNotSynthesized);
  clear_key_calls();
  // Don't redispatch sys messages.
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
}

TEST(KeyboardTest, MetaLeftUnhandled) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press MetaLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LWIN, true, false},
      WmKeyDownInfo{VK_LWIN, kScanCodeMetaLeft, kExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalMetaLeft, kLogicalMetaLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release MetaLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LWIN, false, true},
      WmKeyUpInfo{VK_LWIN, kScanCodeMetaLeft, kExtended}.Build(kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalMetaLeft,
                       kLogicalMetaLeft, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

TEST(KeyboardTest, MetaRightUnhandled) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press MetaRight
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RWIN, true, false},
      WmKeyDownInfo{VK_RWIN, kScanCodeMetaRight, kExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalMetaRight, kLogicalMetaRight, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release MetaRight
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RWIN, false, true},
      WmKeyUpInfo{VK_RWIN, kScanCodeMetaRight, kExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalMetaRight,
                       kLogicalMetaRight, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// Press Shift-A. This is special because Win32 gives 'A' as character for the
// KeyA press.
TEST(KeyboardTest, ShiftLeftKeyA) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press ShiftLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LSHIFT, true, true},
      WmKeyDownInfo{VK_SHIFT, kScanCodeShiftLeft, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalShiftLeft, kLogicalShiftLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Press A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'A', kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
                       kLogicalKeyA, "A", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"A");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release ShiftLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LSHIFT, false, true},
      WmKeyUpInfo{VK_SHIFT, kScanCodeShiftLeft, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalShiftLeft,
                       kLogicalShiftLeft, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyA,
                       kLogicalKeyA, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// Press Ctrl-A. This is special because Win32 gives 0x01 as character for the
// KeyA press.
TEST(KeyboardTest, CtrlLeftKeyA) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press ControlLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, true, true},
      WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Press A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{0x01, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
                       kLogicalKeyA, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyA,
                       kLogicalKeyA, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release ControlLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, false, true},
      WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// Press Ctrl-1. This is special because it yields no WM_CHAR for the 1.
TEST(KeyboardTest, CtrlLeftDigit1) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press ControlLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, true, true},
      WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Press 1
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended, kWasUp}
          .Build(kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalDigit1,
                       kLogicalDigit1, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release 1
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalDigit1,
                       kLogicalDigit1, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release ControlLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, false, true},
      WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// Press 1 on a French keyboard. This is special because it yields WM_CHAR
// with char_code '&'.
TEST(KeyboardTest, Digit1OnFrenchLayout) {
  KeyboardTester tester;
  tester.Responding(false);

  tester.SetLayout(LayoutFrench);

  // Press 1
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended, kWasUp}
          .Build(kWmResultZero),
      WmCharInfo{'&', kScanCodeDigit1, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalDigit1,
                       kLogicalDigit1, "&", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"&");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release 1
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalDigit1,
                       kLogicalDigit1, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// This tests AltGr-Q on a German keyboard, which should print '@'.
TEST(KeyboardTest, AltGrModifiedKey) {
  KeyboardTester tester;
  tester.Responding(false);

  // German Keyboard layout

  // Press AltGr, which Win32 precedes with a ContrlLeft down.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, true, true},
      WmKeyDownInfo{VK_LCONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      KeyStateChange{VK_RMENU, true, true},
      WmKeyDownInfo{VK_MENU, kScanCodeAlt, kExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeDown,
                       kPhysicalAltRight, kLogicalAltRight, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Press Q
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyQ, kScanCodeKeyQ, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'@', kScanCodeKeyQ, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyQ,
                       kLogicalKeyQ, "@", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"@");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release Q
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyQ, kScanCodeKeyQ, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyQ,
                       kLogicalKeyQ, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release AltGr. Win32 doesn't dispatch ControlLeft up. Instead Flutter will
  // forge one. The AltGr is a system key, therefore will be handled by Win32's
  // default WndProc.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, false, true},
      ExpectForgedMessage{
          WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
              kWmResultZero)},
      KeyStateChange{VK_RMENU, false, true},
      WmSysKeyUpInfo{VK_MENU, kScanCodeAlt, kExtended}.Build(
          kWmResultDefault)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeUp, kPhysicalAltRight,
                       kLogicalAltRight, "", kNotSynthesized);
  clear_key_calls();
  // The sys key up must not be redispatched. The forged ControlLeft up will.
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// Test the following two key sequences at the same time:
//
// 1. Tap AltGr, then tap AltGr.
// 2. Tap AltGr, hold CtrlLeft, tap AltGr, release CtrlLeft.
//
// The two sequences are indistinguishable until the very end when a CtrlLeft
// up event might or might not follow.
//
//   Sequence 1: CtrlLeft down, AltRight down, AltRight up
//   Sequence 2: CtrlLeft down, AltRight down, AltRight up, CtrlLeft up
//
// This is because pressing AltGr alone causes Win32 to send a fake "CtrlLeft
// down" event first (see |IsKeyDownAltRight| for detailed explanation).
TEST(KeyboardTest, AltGrTwice) {
  KeyboardTester tester;
  tester.Responding(false);

  // 1. AltGr down.

  // The key down event causes a ControlLeft down and a AltRight (extended
  // AltLeft) down.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, true, true},
      WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      KeyStateChange{VK_RMENU, true, true},
      WmKeyDownInfo{VK_MENU, kScanCodeAlt, kExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeDown,
                       kPhysicalAltRight, kLogicalAltRight, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // 2. AltGr up.

  // The key up event only causes a AltRight (extended AltLeft) up.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, false, true},
      ExpectForgedMessage{
          WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
              kWmResultZero)},
      KeyStateChange{VK_RMENU, false, true},
      WmSysKeyUpInfo{VK_MENU, kScanCodeAlt, kExtended}.Build(
          kWmResultDefault)});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeUp, kPhysicalAltRight,
                       kLogicalAltRight, "", kNotSynthesized);
  clear_key_calls();
  // The sys key up must not be redispatched. The forged ControlLeft up will.
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // 3. AltGr down (or: ControlLeft down then AltRight down.)

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, true, false},
      WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      KeyStateChange{VK_RMENU, true, true},
      WmKeyDownInfo{VK_MENU, kScanCodeAlt, kExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeDown,
                       kPhysicalAltRight, kLogicalAltRight, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // 4. AltGr up.

  // The key up event only causes a AltRight (extended AltLeft) up.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, false, false},
      ExpectForgedMessage{
          WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
              kWmResultZero)},
      KeyStateChange{VK_RMENU, false, false},
      WmSysKeyUpInfo{VK_MENU, kScanCodeAlt, kExtended}.Build(
          kWmResultDefault)});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kNotSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeUp, kPhysicalAltRight,
                       kLogicalAltRight, "", kNotSynthesized);
  clear_key_calls();
  // The sys key up must not be redispatched. The forged ControlLeft up will.
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // 5. For key sequence 2: a real ControlLeft up.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
          kWmResultZero)});
  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, 0, 0, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
}

// This tests dead key ^ then E on a French keyboard, which should be combined
// into ê.
TEST(KeyboardTest, DeadKeyThatCombines) {
  KeyboardTester tester;
  tester.Responding(false);

  tester.SetLayout(LayoutFrench);

  // Press ^¨ (US: Left bracket)
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{0xDD, kScanCodeBracketLeft, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmDeadCharInfo{'^', kScanCodeBracketLeft, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalBracketLeft, kLogicalBracketRight, "^",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release ^¨
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{0xDD, kScanCodeBracketLeft, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalBracketLeft, kLogicalBracketRight, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Press E
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyE, kScanCodeKeyE, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{0xEA, kScanCodeKeyE, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyE,
                       kLogicalKeyE, "ê", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"ê");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release E
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyE, kScanCodeKeyE, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyE,
                       kLogicalKeyE, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// This tests dead key ^ then E on a US INTL keyboard, which should be combined
// into ê.
//
// It is different from French AZERTY because the character that the ^ key is
// mapped to does not contain the dead key character somehow.
TEST(KeyboardTest, DeadKeyWithoutDeadMaskThatCombines) {
  KeyboardTester tester;
  tester.Responding(false);

  // Press ShiftLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LSHIFT, true, true},
      WmKeyDownInfo{VK_SHIFT, kScanCodeShiftLeft, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalShiftLeft, kLogicalShiftLeft, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Press 6^
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{'6', kScanCodeDigit6, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmDeadCharInfo{'^', kScanCodeDigit6, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalDigit6,
                       kLogicalDigit6, "6", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release 6^
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{'6', kScanCodeDigit6, kNotExtended}.Build(kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalDigit6,
                       kLogicalDigit6, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release ShiftLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LSHIFT, false, true},
      WmKeyUpInfo{VK_SHIFT, kScanCodeShiftLeft, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalShiftLeft,
                       kLogicalShiftLeft, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Press E
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyE, kScanCodeKeyE, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{0xEA, kScanCodeKeyE, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyE,
                       kLogicalKeyE, "ê", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"ê");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release E
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyE, kScanCodeKeyE, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyE,
                       kLogicalKeyE, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// This tests dead key ^ then & (US: 1) on a French keyboard, which do not
// combine and should output "^&".
TEST(KeyboardTest, DeadKeyThatDoesNotCombine) {
  KeyboardTester tester;
  tester.Responding(false);

  tester.SetLayout(LayoutFrench);

  // Press ^¨ (US: Left bracket)
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{0xDD, kScanCodeBracketLeft, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmDeadCharInfo{'^', kScanCodeBracketLeft, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalBracketLeft, kLogicalBracketRight, "^",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release ^¨
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{0xDD, kScanCodeBracketLeft, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalBracketLeft, kLogicalBracketRight, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Press 1
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended, kWasUp}
          .Build(kWmResultZero),
      WmCharInfo{'^', kScanCodeDigit1, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'&', kScanCodeDigit1, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 3);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalDigit1,
                       kLogicalDigit1, "^", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"^");
  EXPECT_CALL_IS_TEXT(key_calls[2], u"&");
  clear_key_calls();
  // TODO(dkwingsmt): This count should probably be 3. Currently the '^'
  // message is redispatched due to being part of the KeyDown session, which is
  // not handled by the framework, while the '&' message is not redispatched
  // for being a standalone message. We should resolve this inconsistency.
  // https://github.com/flutter/flutter/issues/98306
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release 1
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalDigit1,
                       kLogicalDigit1, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// This tests dead key `, then dead key `, then e.
//
// It should output ``e, instead of `è.
TEST(KeyboardTest, DeadKeyTwiceThenLetter) {
  KeyboardTester tester;
  tester.Responding(false);

  // US INTL layout.

  // Press `
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{0xC0, kScanCodeBackquote, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmDeadCharInfo{'`', kScanCodeBackquote, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalBackquote, kLogicalBackquote, "`",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release `
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{0xC0, kScanCodeBackquote, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalBackquote,
                       kLogicalBackquote, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Press ` again.
  // The response should be slow.
  std::vector<MockKeyResponseController::ResponseCallback> recorded_callbacks;
  tester.LateResponding(
      [&recorded_callbacks](
          const FlutterKeyEvent* event,
          MockKeyResponseController::ResponseCallback callback) {
        recorded_callbacks.push_back(callback);
      });

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{0xC0, kScanCodeBackquote, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'`', kScanCodeBackquote, kNotExtended, kWasUp, kBeingReleased,
                 kNoContext, 1, /*bit25*/ true}
          .Build(kWmResultZero),
      WmCharInfo{'`', kScanCodeBackquote, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(recorded_callbacks.size(), 1);
  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalBackquote, kLogicalBackquote, "`",
                       kNotSynthesized);
  clear_key_calls();
  // Key down event responded with false.
  recorded_callbacks.front()(false);
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_TEXT(key_calls[0], u"`");
  EXPECT_CALL_IS_TEXT(key_calls[1], u"`");
  clear_key_calls();
  // TODO(dkwingsmt): This count should probably be 3. See the comment above
  // that is marked with the same issue.
  // https://github.com/flutter/flutter/issues/98306
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  tester.Responding(false);

  // Release `
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{0xC0, kScanCodeBackquote, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalBackquote,
                       kLogicalBackquote, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// This tests when the resulting character needs to be combined with surrogates.
TEST(KeyboardTest, MultibyteCharacter) {
  KeyboardTester tester;
  tester.Responding(false);

  // Gothic Keyboard layout. (We need a layout that yields non-BMP characters
  // without IME, which is actually very rare.)

  // Press key W of a US keyboard, which should yield character '𐍅'.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyW, kScanCodeKeyW, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{0xd800, kScanCodeKeyW, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{0xdf45, kScanCodeKeyW, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  const char* st = key_calls[0].key_event.character;

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyW,
                       kLogicalKeyW, "𐍅", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"𐍅");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 3);

  // Release W
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyW, kScanCodeKeyW, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyW,
                       kLogicalKeyW, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

TEST(KeyboardTest, SynthesizeModifiers) {
  KeyboardTester tester;
  tester.Responding(false);

  // Two dummy events used to trigger synthesization.
  Win32Message event1 =
      WmKeyDownInfo{VK_BACK, kScanCodeBackspace, kNotExtended, kWasUp}.Build(
          kWmResultZero);
  Win32Message event2 =
      WmKeyUpInfo{VK_BACK, kScanCodeBackspace, kNotExtended}.Build(
          kWmResultZero);

  // ShiftLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LSHIFT, true, true}, event1});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalShiftLeft, kLogicalShiftLeft, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LSHIFT, false, true}, event2});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalShiftLeft,
                       kLogicalShiftLeft, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // ShiftRight
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RSHIFT, true, true}, event1});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalShiftRight, kLogicalShiftRight, "",
                       kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RSHIFT, false, true}, event2});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalShiftRight, kLogicalShiftRight, "",
                       kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // ControlLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, true, true}, event1});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LCONTROL, false, true}, event2});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalControlLeft, kLogicalControlLeft, "",
                       kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // ControlRight
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RCONTROL, true, true}, event1});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalControlRight, kLogicalControlRight, "",
                       kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RCONTROL, false, true}, event2});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalControlRight, kLogicalControlRight, "",
                       kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // AltLeft
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LMENU, true, true}, event1});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalAltLeft,
                       kLogicalAltLeft, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LMENU, false, true}, event2});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalAltLeft,
                       kLogicalAltLeft, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // AltRight
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RMENU, true, true}, event1});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalAltRight, kLogicalAltRight, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RMENU, false, true}, event2});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalAltRight,
                       kLogicalAltRight, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // MetaLeft
  tester.InjectKeyboardChanges(
      std::vector<KeyboardChange>{KeyStateChange{VK_LWIN, true, true}, event1});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalMetaLeft, kLogicalMetaLeft, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LWIN, false, true}, event2});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalMetaLeft,
                       kLogicalMetaLeft, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // MetaRight
  tester.InjectKeyboardChanges(
      std::vector<KeyboardChange>{KeyStateChange{VK_RWIN, true, true}, event1});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalMetaRight, kLogicalMetaRight, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RWIN, false, true}, event2});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalMetaRight,
                       kLogicalMetaRight, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // CapsLock, phase 0 -> 2 -> 0.
  // (For phases, see |SynchronizeCritialToggledStates|.)
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_CAPITAL, false, true}, event1});
  EXPECT_EQ(key_calls.size(), 3);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalCapsLock, kLogicalCapsLock, "", kSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeUp, kPhysicalCapsLock,
                       kLogicalCapsLock, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_CAPITAL, false, false}, event2});
  EXPECT_EQ(key_calls.size(), 3);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalCapsLock, kLogicalCapsLock, "", kSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeUp, kPhysicalCapsLock,
                       kLogicalCapsLock, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // ScrollLock, phase 0 -> 1 -> 3
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_SCROLL, true, true}, event1});
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalScrollLock, kLogicalScrollLock, "",
                       kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_SCROLL, true, false}, event2});
  EXPECT_EQ(key_calls.size(), 3);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp,
                       kPhysicalScrollLock, kLogicalScrollLock, "",
                       kSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeDown,
                       kPhysicalScrollLock, kLogicalScrollLock, "",
                       kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // NumLock, phase 0 -> 3 -> 2
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_NUMLOCK, true, false}, event1});
  // TODO(dkwingsmt): Synthesizing from phase 0 to 3 should yield a full key
  // tap and a key down. Fix the algorithm so that the following result becomes
  // 4 keycalls with an extra pair of key down and up.
  // https://github.com/flutter/flutter/issues/98533
  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalNumLock,
                       kLogicalNumLock, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_NUMLOCK, false, true}, event2});
  EXPECT_EQ(key_calls.size(), 4);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalNumLock,
                       kLogicalNumLock, "", kSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeDown, kPhysicalNumLock,
                       kLogicalNumLock, "", kSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[2], kFlutterKeyEventTypeUp, kPhysicalNumLock,
                       kLogicalNumLock, "", kSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
}

// Pressing extended keys during IME events should work properly by not sending
// any events.
//
// Regression test for https://github.com/flutter/flutter/issues/95888 .
TEST(KeyboardTest, ImeExtendedEventsAreIgnored) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout.

  // There should be preceding key events to make the keyboard into IME mode.
  // Omit them in this test since they are not relavent.

  // Press CtrlRight in IME mode.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_RCONTROL, true, false},
      WmKeyDownInfo{VK_PROCESSKEY, kScanCodeControl, kExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, 0, 0, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
}

// Ensures that synthesization works correctly when a Shift key is pressed and
// (only) its up event is labeled as an IME event (VK_PROCESSKEY).
//
// Regression test for https://github.com/flutter/flutter/issues/104169. These
// are real messages recorded when pressing Shift-2 using Microsoft Pinyin IME
// on Win 10 Enterprise, which crashed the app before the fix.
TEST(KeyboardTest, UpOnlyImeEventsAreCorrectlyHandled) {
  KeyboardTester tester;
  tester.Responding(true);

  // US Keyboard layout.

  // Press CtrlRight in IME mode.
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      KeyStateChange{VK_LSHIFT, true, false},
      WmKeyDownInfo{VK_SHIFT, kScanCodeShiftLeft, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmKeyDownInfo{VK_PROCESSKEY, kScanCodeDigit2, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      KeyStateChange{VK_LSHIFT, false, true},
      WmKeyUpInfo{VK_PROCESSKEY, kScanCodeShiftLeft, kNotExtended}.Build(
          kWmResultZero),
      WmKeyUpInfo{'2', kScanCodeDigit2, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 4);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalShiftLeft, kLogicalShiftLeft, "",
                       kNotSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeDown, 0, 0, "",
                       kNotSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[2], kFlutterKeyEventTypeUp, kPhysicalShiftLeft,
                       kLogicalShiftLeft, "", kNotSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[3], kFlutterKeyEventTypeDown, 0, 0, "",
                       kNotSynthesized);
  clear_key_calls();
}

// Regression test for a crash in an earlier implementation.
//
// In real life, the framework responds slowly. The next real event might
// arrive earlier than the framework response, and if the 2nd event has an
// identical hash as the one waiting for response, an earlier implementation
// will crash upon the response.
TEST(KeyboardTest, SlowFrameworkResponse) {
  KeyboardTester tester;

  std::vector<MockKeyResponseController::ResponseCallback> recorded_callbacks;

  // Store callbacks to manually call them.
  tester.LateResponding(
      [&recorded_callbacks](
          const FlutterKeyEvent* event,
          MockKeyResponseController::ResponseCallback callback) {
        recorded_callbacks.push_back(callback);
      });

  // Press A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  // Hold A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasDown}.Build(
          kWmResultZero),
      WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasDown}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
                       kLogicalKeyA, "a", kNotSynthesized);
  EXPECT_EQ(recorded_callbacks.size(), 1);
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);

  // The first response.
  recorded_callbacks.front()(false);

  EXPECT_EQ(key_calls.size(), 3);
  EXPECT_EQ(recorded_callbacks.size(), 2);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"a");
  EXPECT_CALL_IS_EVENT(key_calls[2], kFlutterKeyEventTypeRepeat, kPhysicalKeyA,
                       kLogicalKeyA, "a", kNotSynthesized);
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // The second response.
  recorded_callbacks.back()(false);

  EXPECT_EQ(key_calls.size(), 4);
  EXPECT_CALL_IS_TEXT(key_calls[3], u"a");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
}

// Regression test for https://github.com/flutter/flutter/issues/84210.
//
// When the framework response is slow during a sequence of identical messages,
// make sure the real messages are not mistaken as redispatched messages,
// in order to not mess up the order of events.
//
// In this test we use:
//
//   KeyA down, KeyA up, (down event responded with false), KeyA down, KeyA up,
//
// The code must not take the 2nd real key down events as a redispatched event.
TEST(KeyboardTest, SlowFrameworkResponseForIdenticalEvents) {
  KeyboardTester tester;

  std::vector<MockKeyResponseController::ResponseCallback> recorded_callbacks;

  // Store callbacks to manually call them.
  tester.LateResponding(
      [&recorded_callbacks](
          const FlutterKeyEvent* event,
          MockKeyResponseController::ResponseCallback callback) {
        recorded_callbacks.push_back(callback);
      });

  // Press A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
                       kLogicalKeyA, "a", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);

  // Release A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 0);
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);

  // The first down event responded with false.
  EXPECT_EQ(recorded_callbacks.size(), 1);
  recorded_callbacks.front()(false);

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_TEXT(key_calls[0], u"a");
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeUp, kPhysicalKeyA,
                       kLogicalKeyA, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Press A again
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  // Nothing more was dispatched because the first up event hasn't been
  // responded yet.
  EXPECT_EQ(recorded_callbacks.size(), 2);
  EXPECT_EQ(key_calls.size(), 0);
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);

  // The first up event responded with false, which was redispatched, and caused
  // the down event to be dispatched.
  recorded_callbacks.back()(false);
  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
                       kLogicalKeyA, "a", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(recorded_callbacks.size(), 3);
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Release A again
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 0);
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
}

TEST(KeyboardTest, TextInputSubmit) {
  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  tester.GetView().HandleMessage(
      "flutter/textinput", "TextInput.setClient",
      R"|([108, {"inputAction": "TextInputAction.none"}])|");

  // Press Enter
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{VK_RETURN, kScanCodeEnter, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'\n', kScanCodeEnter, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalEnter,
                       kLogicalEnter, "", kNotSynthesized);
  EXPECT_CALL_IS_TEXT_METHOD_CALL(
      key_calls[1],
      "{"
      R"|("method":"TextInputClient.performAction",)|"
      R"|("args":[108,"TextInputAction.none"])|"
      "}");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release Enter
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{VK_RETURN, kScanCodeEnter, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalEnter,
                       kLogicalEnter, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Make sure OnText is not obstructed after pressing Enter.
  //
  // Regression test for https://github.com/flutter/flutter/issues/97706.

  // Press A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
                       kLogicalKeyA, "a", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"a");
  clear_key_calls();

  // Release A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyA,
                       kLogicalKeyA, "", kNotSynthesized);
  clear_key_calls();
}

TEST(KeyboardTest, VietnameseTelexAddDiacriticWithFastResponse) {
  // In this test, the user presses the folloing keys:
  //
  //   Key         Current text
  //  ===========================
  //   A           a
  //   F           à
  //
  // And the Backspace event is responded immediately.

  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
                       kLogicalKeyA, "a", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"a");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyA,
                       kLogicalKeyA, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  // Press F, which is translated to:
  //
  // Backspace down, char & up, then VK_PACKET('à').
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{VK_BACK, kScanCodeBackspace, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{0x8, kScanCodeBackspace, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmKeyUpInfo{VK_BACK, kScanCodeBackspace, kNotExtended}.Build(
          kWmResultZero),
      WmKeyDownInfo{VK_PACKET, 0, kNotExtended, kWasUp}.Build(kWmResultDefault),
      WmCharInfo{0xe0 /*'à'*/, 0, kNotExtended, kWasUp}.Build(kWmResultZero),
      WmKeyUpInfo{VK_PACKET, 0, kNotExtended}.Build(kWmResultDefault)});

  EXPECT_EQ(key_calls.size(), 3);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalBackspace, kLogicalBackspace, "",
                       kNotSynthesized);
  EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeUp, kPhysicalBackspace,
                       kLogicalBackspace, "", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[2], u"à");
  clear_key_calls();
  // TODO(dkwingsmt): This count should probably be 4. Currently the CHAR 0x8
  // message is redispatched due to being part of the KeyDown session, which is
  // not handled by the framework, while the 'à' message is not redispatched
  // for being a standalone message. We should resolve this inconsistency.
  // https://github.com/flutter/flutter/issues/98306
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 3);

  // Release F
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyF, kScanCodeKeyF, kNotExtended,
                  /* overwrite_prev_state_0 */ true}
          .Build(kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, 0, 0, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
}

void VietnameseTelexAddDiacriticWithSlowResponse(bool backspace_response) {
  // In this test, the user presses the folloing keys:
  //
  //   Key         Current text
  //  ===========================
  //   A           a
  //   F           à
  //
  // And the Backspace down event is responded slowly with `backspace_response`.

  KeyboardTester tester;
  tester.Responding(false);

  // US Keyboard layout

  // Press A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasUp}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 2);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
                       kLogicalKeyA, "a", kNotSynthesized);
  EXPECT_CALL_IS_TEXT(key_calls[1], u"a");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);

  // Release A
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended}.Build(
          kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalKeyA,
                       kLogicalKeyA, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  std::vector<MockKeyResponseController::ResponseCallback> recorded_callbacks;
  tester.LateResponding(
      [&recorded_callbacks](
          const FlutterKeyEvent* event,
          MockKeyResponseController::ResponseCallback callback) {
        recorded_callbacks.push_back(callback);
      });

  // Press F, which is translated to:
  //
  // Backspace down, char & up, VK_PACKET('à').
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{VK_BACK, kScanCodeBackspace, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmCharInfo{0x8, kScanCodeBackspace, kNotExtended, kWasUp}.Build(
          kWmResultZero),
      WmKeyUpInfo{VK_BACK, kScanCodeBackspace, kNotExtended}.Build(
          kWmResultZero),
      WmKeyDownInfo{VK_PACKET, 0, kNotExtended, kWasUp}.Build(kWmResultDefault),
      WmCharInfo{0xe0 /*'à'*/, 0, kNotExtended, kWasUp}.Build(kWmResultZero),
      WmKeyUpInfo{VK_PACKET, 0, kNotExtended}.Build(kWmResultDefault)});

  // The Backspace event has not responded yet, therefore the char message must
  // hold. This is because when the framework is handling the Backspace event,
  // it will send a setEditingState message that updates the text state that has
  // the last character deleted  (denoted by `string1`). Processing the char
  // message before then will cause the final text to set to `string1`.
  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown,
                       kPhysicalBackspace, kLogicalBackspace, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);

  EXPECT_EQ(recorded_callbacks.size(), 1);
  recorded_callbacks[0](backspace_response);

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeUp, kPhysicalBackspace,
                       kLogicalBackspace, "", kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(),
            backspace_response ? 0 : 2);

  recorded_callbacks[1](false);
  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_TEXT(key_calls[0], u"à");
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);

  tester.Responding(false);

  // Release F
  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyUpInfo{kVirtualKeyF, kScanCodeKeyF, kNotExtended,
                  /* overwrite_prev_state_0 */ true}
          .Build(kWmResultZero)});

  EXPECT_EQ(key_calls.size(), 1);
  EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, 0, 0, "",
                       kNotSynthesized);
  clear_key_calls();
  EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
}

TEST(KeyboardTest, VietnameseTelexAddDiacriticWithSlowFalseResponse) {
  VietnameseTelexAddDiacriticWithSlowResponse(false);
}

TEST(KeyboardTest, VietnameseTelexAddDiacriticWithSlowTrueResponse) {
  VietnameseTelexAddDiacriticWithSlowResponse(true);
}

// Ensure that the scancode-less key events issued by Narrator
// when toggling caps lock don't violate assert statements.
TEST(KeyboardTest, DoubleCapsLock) {
  KeyboardTester tester;
  tester.Responding(false);

  tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
      WmKeyDownInfo{VK_CAPITAL, 0, kNotExtended}.Build(),
      WmKeyUpInfo{VK_CAPITAL, 0, kNotExtended}.Build()});

  clear_key_calls();
}

}  // namespace testing
}  // namespace flutter
