// Copyright 2019 The Chromium 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 "remoting/host/keyboard_layout_monitor.h"

#include <windows.h>
#include <ime.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/no_destructor.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_local.h"
#include "base/timer/timer.h"
#include "remoting/proto/control.pb.h"
#include "third_party/webrtc/modules/desktop_capture/win/desktop.h"
#include "third_party/webrtc/modules/desktop_capture/win/scoped_thread_desktop.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/keycode_converter.h"

namespace remoting {

namespace {

constexpr base::TimeDelta POLL_INTERVAL =
    base::TimeDelta::FromMilliseconds(1000);
// If second is equivalent to first (generates the same functions/characters at
// all shift levels), second will be removed from the map.
constexpr std::pair<ui::DomCode, ui::DomCode> POSSIBLE_EQUIVALENTS[] = {
    // These are equivalent on the US QWERTY layout, among others.
    {ui::DomCode::BACKSLASH, ui::DomCode::INTL_BACKSLASH}};

class KeyboardLayoutMonitorWin : public KeyboardLayoutMonitor {
 public:
  KeyboardLayoutMonitorWin(
      base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback,
      scoped_refptr<base::SingleThreadTaskRunner> input_task_runner);
  ~KeyboardLayoutMonitorWin() override;
  void Start() override;

 private:
  // Check the current layout, and invoke the callback if it has changed.
  void QueryLayout();
  void ResetTimer();
  static void QueryLayoutOnInputThread(
      scoped_refptr<base::SequencedTaskRunner> reply_sequence,
      base::WeakPtr<KeyboardLayoutMonitorWin> monitor,
      HKL previous_layout);
  void OnLayoutChanged(HKL new_layout, protocol::KeyboardLayout layout_details);

  HKL previous_layout_ = nullptr;
  base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback_;
  base::RetainingOneShotTimer timer_;
  scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
  base::WeakPtrFactory<KeyboardLayoutMonitorWin> weak_ptr_factory_;
};

KeyboardLayoutMonitorWin::KeyboardLayoutMonitorWin(
    base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback,
    scoped_refptr<base::SingleThreadTaskRunner> input_task_runner)
    : callback_(std::move(callback)),
      input_task_runner_(std::move(input_task_runner)),
      weak_ptr_factory_(this) {}

KeyboardLayoutMonitorWin::~KeyboardLayoutMonitorWin() = default;

void KeyboardLayoutMonitorWin::Start() {
  timer_.Start(FROM_HERE, POLL_INTERVAL, this,
               &KeyboardLayoutMonitorWin::QueryLayout);
}

void ClearDeadKeys(HKL layout);
bool IsNumpadKey(ui::DomCode code);
UINT TranslateVirtualKey(bool numlock_state,
                         bool shift_state,
                         UINT virtual_key,
                         ui::DomCode code);
protocol::LayoutKeyFunction VirtualKeyToLayoutKeyFunction(UINT virtual_key,
                                                          LANGID lang);

void KeyboardLayoutMonitorWin::QueryLayout() {
  // Only reset the timer once the task has completed. This ensures that a delay
  // on the input thread doesn't result in us queuing up a bunch of redundant
  // tasks.
  input_task_runner_->PostTaskAndReply(
      FROM_HERE,
      base::BindOnce(&QueryLayoutOnInputThread,
                     base::SequencedTaskRunnerHandle::Get(),
                     weak_ptr_factory_.GetWeakPtr(), previous_layout_),
      base::BindOnce(&KeyboardLayoutMonitorWin::ResetTimer,
                     weak_ptr_factory_.GetWeakPtr()));
}

void KeyboardLayoutMonitorWin::ResetTimer() {
  timer_.Reset();
}

// static
void KeyboardLayoutMonitorWin::QueryLayoutOnInputThread(
    scoped_refptr<base::SequencedTaskRunner> reply_sequence,
    base::WeakPtr<KeyboardLayoutMonitorWin> monitor,
    HKL previous_layout) {
  // Switch to the active desktop.
  webrtc::ScopedThreadDesktop desktop;
  std::unique_ptr<webrtc::Desktop> input_desktop(
      webrtc::Desktop::GetInputDesktop());
  if (input_desktop && !desktop.IsSame(*input_desktop)) {
    desktop.SetThreadDesktop(input_desktop.release());
  }

  // Get the keyboard layout for the active window.
  DWORD thread_id = 0;
  HWND foreground_window = GetForegroundWindow();
  if (foreground_window) {
    thread_id = GetWindowThreadProcessId(foreground_window, nullptr);
  } else if (previous_layout != 0) {
    // There's no currently active window, so keep using the previous layout.
    return;
  }
  // If there is no previous layout and there's no active window
  // (thread_id == 0), this will return the layout associated with this
  // thread, which is better than nothing.
  HKL layout = GetKeyboardLayout(thread_id);
  if (layout == previous_layout) {
    return;
  }

  protocol::KeyboardLayout layout_message;
  // TODO(rkjnsn): Windows doesn't provide an API to read the keyboard layout
  // directly. We can use the various key translation functions to mostly get
  // the information we need, but it requires some hacks, could miss some edge
  // cases, and modifies the system keyboard state. Windows keyboard layouts
  // consist of DLLs providing data tables in a reasonable straight-forward
  // format, so it may make sense to look at reading them directly.

  // It would be nice if we could use MapVirtualKeyEx to translate virtual
  // keys to characters, as it neither is affected by nor modifies the system
  // keyboard state. Unfortunately, it provides no way to specify shift
  // states, so it can only be used to retrieve the unshifted character for a
  // given key. Instead, we use ToUnicodeEx, which is affected by (and
  // affects) the system keyboard state, so we start by clearing any queued-up
  // dead keys.
  ClearDeadKeys(layout);

  // Keyboard layouts have a KLLF_ALTGR flag that indicated whether the right
  // alt key is AltGr (and thus generates Ctrl+Alt). Unfortunately, there
  // doesn't seem to be any way to determine whether the current layout sets
  // this flag using the Windows API. As a hack/workaround, we assume that
  // right Alt == AltGr if and only if there are keys that generate characters
  // when both Ctrl and Alt modifiers are set. This is by no means guaranteed,
  // but is expected to be true for common layouts.
  bool has_altgr = false;

  // Keys/shift levels that function as right Alt. These will be updated to
  // AltGr if the keyboard appears to use it. (Most keyboards will have at
  // most one of these.)
  std::vector<std::pair<std::uint32_t, int>> right_alts;

  for (ui::DomCode key : KeyboardLayoutMonitor::kSupportedKeys) {
    // These keys cannot be injected properly on Windows with the APIs we use.
    //
    // The USB keyboard driver translates NumLock to the scancode 0x45, but it
    // is delivered to applications as 0xE045. Meanwhile, Pause is translated
    // to the scancode sequence 0xE1 0x1D 0x45 0xE1 0x9D 0xC5, but is delivered
    // to applications as a plain 0x45.
    //
    // Injecting 0x45 using SendInput does get interpreted by Windows as
    // VK_NUMLOCK, but is not translated to 0xE045 before being delivered to
    // applications as it is with a physical keyboard. As a result, Chrome (for
    // example) reports a key value of "NumLock" but a code value of "Pause".
    //
    // Injecting 0xE045, on the otherhand, does not get interpreted as
    // VK_NUMLOCK, so Chrome sees reports a code value of "NumLock", but a key
    // value of "Unidentified".
    //
    // I have not been able to determine any way to use SendInput to inject an
    // event that Windows interprets as VK_PAUSE.
    //
    // NumpadEqual also behaves inconsistently when injected, but in a
    // different way: while when input using a physical keyboard, the
    // corresponding scancode (0x59) is always interpreted as VK_CLEAR
    // regardless of the num lock state. When injected, however, Windows
    // translates the key to VK_NUMPAD5 when numlock is enabled. Since the
    // virtual keyboard considers num lock always to be enabled, this
    // effectively results in an extra 5 key in the NumpadEqual position, which
    // is both redundant and confusing. Given that most keyboards lack this key,
    // and those that do have it label it '=', it seems easiest just to exclude
    // it for now. In the future, we could consider adding support to it for
    // keyboard layouts that treat is as something other than VK_CLEAR, if such
    // layouts turn out to exist. (Why Windows maps the USB 'Keypad =' key to
    // scancode 0x59 in the first place, even though 0x59 does not generate an
    // '=' character, is unclear.)
    if (key == ui::DomCode::NUM_LOCK || key == ui::DomCode::PAUSE ||
        key == ui::DomCode::NUMPAD_EQUAL) {
      continue;
    }

    std::uint32_t usb_code = ui::KeycodeConverter::DomCodeToUsbKeycode(key);
    int scancode = ui::KeycodeConverter::DomCodeToNativeKeycode(key);
    UINT virtual_key = MapVirtualKeyEx(scancode, MAPVK_VSC_TO_VK_EX, layout);
    if (virtual_key == 0) {
      // This key is not mapped in the current layout.
      continue;
    }

    if (virtual_key == VK_CAPITAL || virtual_key == VK_NUMLOCK) {
      // Don't send caps or numlock keys until we decide how to handle them.
      // (We currently skip the key in the NumLock position above due to
      // difficulties injecting it, but the user still may have mapped a
      // different key to that function.)
      continue;
    }

    google::protobuf::Map<google::protobuf::uint32,
                          protocol::KeyboardLayout_KeyAction>& key_actions =
        *(*layout_message.mutable_keys())[usb_code].mutable_actions();

    for (int shift_level = 0; shift_level < 4; ++shift_level) {
      // Mimic Windows's handling of number pad key.
      UINT translated_key = TranslateVirtualKey(
          /* numlock_state */ true, shift_level & 1, virtual_key, key);

      // First check if the key generates a character.
      BYTE key_state[256] = {0};
      // Modifiers set the high-order bit when pressed.
      key_state[VK_SHIFT] = (shift_level & 1) << 7;
      key_state[VK_CONTROL] = key_state[VK_MENU] = (shift_level & 2) << 6;
      // Locks set the low-order bit when toggled on.
      // For now, generate a layout with numlock always on and caps lock
      // always off.
      // TODO(rkjnsn): Update this when we decide how we want to handle locks
      // for the on-screen keyboard.
      key_state[VK_NUMLOCK] = 1;
      key_state[VK_CAPITAL] = 0;
      WCHAR char_buffer[16];
      // According to the documentation, ToUnicodeEx usually does the
      // translation solely based on the virtual key, but can use bit 15 of the
      // scancode to distinguish between a keypress and a key release. This
      // suggests that the expected format for scancode is the upper word of
      // lParam from a WM_CHAR, where the top bit similarly distinguished press
      // versus release. In any event, passing |scancode| as the second
      // parameter here would thus cause extended scancodes (which have the 15th
      // bit set) to erroneously be interpreted as key-up events and not
      // generate the appropriate character. Rather than attempting to munge the
      // scancode into whatever format ToUnicodeEx expects, passing 0 seems to
      // work just fine.
      int size = ToUnicodeEx(translated_key, 0, key_state, char_buffer,
                             base::size(char_buffer), 0, layout);
      if (size < 0) {
        // We don't handle dead keys specially for the layout, but we do
        // need to clear them from the system keyboard state.
        ClearDeadKeys(layout);
        size = -size;
      }
      if (size > 0) {
        if (size == 1 && char_buffer[0] < 0x20) {
          // Handle known control characters.
          protocol::LayoutKeyFunction function =
              protocol::LayoutKeyFunction::UNKNOWN;
          switch (char_buffer[0]) {
            case 0x08:
              function = protocol::LayoutKeyFunction::BACKSPACE;
              break;
            case 0x09:
              function = protocol::LayoutKeyFunction::TAB;
              break;
            case 0x0D:
              function = protocol::LayoutKeyFunction::ENTER;
              break;
            case 0x1B:
              function = protocol::LayoutKeyFunction::ESCAPE;
              break;
          }
          if (function != protocol::LayoutKeyFunction::UNKNOWN) {
            key_actions[shift_level].set_function(function);
            continue;
          }
        }
        // The key generated at least one character.
        key_actions[shift_level].set_character(
            base::WideToUTF8(base::WStringPiece(char_buffer, size)));
        if (shift_level > 2) {
          has_altgr = true;
        }
        continue;
      }

      // If the key didn't generate a character, translate it based on the
      // virtual key value.
      key_actions[shift_level].set_function(VirtualKeyToLayoutKeyFunction(
          translated_key, reinterpret_cast<std::uintptr_t>(layout) & 0xFFFF));
      if (translated_key == VK_RMENU) {
        right_alts.emplace_back(usb_code, shift_level);
      }
    }
  }

  // If any ctrl+alt+key sequence generated a character, assume right Alt is
  // AltGr.
  if (has_altgr) {
    for (std::pair<std::uint32_t, int> right_alt : right_alts) {
      (*(*layout_message.mutable_keys())[right_alt.first]
            .mutable_actions())[right_alt.second]
          .set_function(protocol::LayoutKeyFunction::ALT_GR);
    }
  } else {
    // Remove higher shift levels since there's no way to generate them.
    for (auto& key : *layout_message.mutable_keys()) {
      key.second.mutable_actions()->erase(2);
      key.second.mutable_actions()->erase(3);
    }
  }

  // Some layouts have equivalent keys. Remove the redundant keys to make the
  // layout cleaner.
  auto* keys = layout_message.mutable_keys();
  for (const std::pair<ui::DomCode, ui::DomCode>& possible_equivalent :
       POSSIBLE_EQUIVALENTS) {
    std::uint32_t code1 =
        ui::KeycodeConverter::DomCodeToUsbKeycode(possible_equivalent.first);
    std::uint32_t code2 =
        ui::KeycodeConverter::DomCodeToUsbKeycode(possible_equivalent.second);
    auto key_behavior1 = keys->find(code1);
    auto key_behavior2 = keys->find(code2);
    if (key_behavior1 != keys->end() && key_behavior2 != keys->end() &&
        key_behavior1->second.SerializeAsString() ==
            key_behavior2->second.SerializeAsString()) {
      keys->erase(key_behavior2);
    }
  }

  // There seem to be a number of keys that are mapped to a virtual key in the
  // layout but don't do anything useful. E.g., the US QWERTY layout maps
  // NonConvert, which isn't on a standard US keyboard, to VK_OEM_PA1, which
  // doesn't appear to be useful. To avoid cluttering the on-screen keyboard
  // with blank, useless keys, just omit unknown keys for now. We can revisit
  // this if folks send feedback about useful keys being missing.
  for (auto it = keys->begin(); it != keys->end();) {
    bool has_action = false;
    for (const auto& action : it->second.actions()) {
      if (action.second.has_character() ||
          (action.second.has_function() &&
           action.second.function() != protocol::LayoutKeyFunction::UNKNOWN)) {
        has_action = true;
      }
    }
    if (!has_action) {
      it = keys->erase(it);
    } else {
      ++it;
    }
  }

  reply_sequence->PostTask(
      FROM_HERE,
      base::BindOnce(&KeyboardLayoutMonitorWin::OnLayoutChanged,
                     std::move(monitor), layout, std::move(layout_message)));
}

void KeyboardLayoutMonitorWin::OnLayoutChanged(
    HKL new_layout,
    protocol::KeyboardLayout layout_details) {
  previous_layout_ = new_layout;
  callback_.Run(std::move(layout_details));
}

void ClearDeadKeys(HKL layout) {
  // ToUnicodeEx both is affected by and modifies the current keyboard state,
  // which includes the list of currently stored dead keys. Pressing space
  // translates previously pressed dead keys to characters, clearing the dead-
  // key buffer.
  BYTE key_state[256] = {0};
  WCHAR char_buffer[16];
  ToUnicodeEx(VK_SPACE,
              ui::KeycodeConverter::DomCodeToNativeKeycode(ui::DomCode::SPACE),
              key_state, char_buffer, base::size(char_buffer), 0, layout);
}

bool IsNumpadKey(ui::DomCode code) {
  // Windows keyboard layouts map number pad keys to virtual keys based on
  // their function when num lock is off. E.g., 4 on the number pad generates
  // VK_LEFT, the same as the left arrow key. To distinguish them, the layout
  // sets the KBDNUMPAD flag on the numlock versions, allowing Windows to
  // translate VK_LEFT to VK_NUMPAD4 when numlock is enabled only for the keys
  // on the number pad. Unfortunately, the state of the KBDNUMPAD flag for a
  // given scan code does not appear to be accessible via the Windows API, so
  // for now just assume that all layouts use the same scan codes for the
  // number pad.
  // TODO(rkjnsn): Figure out if there's a better way to determine this.

  switch (code) {
    case ui::DomCode::NUMPAD0:
    case ui::DomCode::NUMPAD1:
    case ui::DomCode::NUMPAD2:
    case ui::DomCode::NUMPAD3:
    case ui::DomCode::NUMPAD4:
    case ui::DomCode::NUMPAD5:
    case ui::DomCode::NUMPAD6:
    case ui::DomCode::NUMPAD7:
    case ui::DomCode::NUMPAD8:
    case ui::DomCode::NUMPAD9:
    case ui::DomCode::NUMPAD_DECIMAL:
      return true;
    default:
      return false;
  }
}

UINT TranslateVirtualKey(bool numlock_state,
                         bool shift_state,
                         UINT virtual_key,
                         ui::DomCode code) {
  // Windows only translates numpad keys when num lock is on and shift is not
  // pressed. (Pressing shift when num lock is on will get you navigation, but
  // pressing shift when num lock is off will not get you numbers.)
  if (!numlock_state || shift_state || !IsNumpadKey(code)) {
    return virtual_key;
  }
  switch (virtual_key) {
    case VK_DELETE:
      return VK_DECIMAL;
    case VK_INSERT:
      return VK_NUMPAD0;
    case VK_END:
      return VK_NUMPAD1;
    case VK_DOWN:
      return VK_NUMPAD2;
    case VK_NEXT:
      return VK_NUMPAD3;
    case VK_LEFT:
      return VK_NUMPAD4;
    case VK_CLEAR:
      return VK_NUMPAD5;
    case VK_RIGHT:
      return VK_NUMPAD6;
    case VK_HOME:
      return VK_NUMPAD7;
    case VK_UP:
      return VK_NUMPAD8;
    case VK_PRIOR:
      return VK_NUMPAD9;
    default:
      return virtual_key;
  }
}

protocol::LayoutKeyFunction VirtualKeyToLayoutKeyFunction(UINT virtual_key,
                                                          LANGID lang) {
  switch (virtual_key) {
    case VK_LCONTROL:
    case VK_RCONTROL:
      return protocol::LayoutKeyFunction::CONTROL;
    case VK_LMENU:
    case VK_RMENU:
      return protocol::LayoutKeyFunction::ALT;
    case VK_LSHIFT:
    case VK_RSHIFT:
      return protocol::LayoutKeyFunction::SHIFT;
    case VK_LWIN:
    case VK_RWIN:
      return protocol::LayoutKeyFunction::META;
    case VK_NUMLOCK:
      return protocol::LayoutKeyFunction::NUM_LOCK;
    case VK_CAPITAL:
      return protocol::LayoutKeyFunction::CAPS_LOCK;
    case VK_SCROLL:
      return protocol::LayoutKeyFunction::SCROLL_LOCK;
    case VK_BACK:
      return protocol::LayoutKeyFunction::BACKSPACE;
    case VK_RETURN:
      return protocol::LayoutKeyFunction::ENTER;
    case VK_TAB:
      return protocol::LayoutKeyFunction::TAB;
    case VK_INSERT:
      return protocol::LayoutKeyFunction::INSERT;
    case VK_DELETE:
      return protocol::LayoutKeyFunction::DELETE_;
    case VK_HOME:
      return protocol::LayoutKeyFunction::HOME;
    case VK_END:
      return protocol::LayoutKeyFunction::END;
    case VK_PRIOR:
      return protocol::LayoutKeyFunction::PAGE_UP;
    case VK_NEXT:
      return protocol::LayoutKeyFunction::PAGE_DOWN;
    case VK_CLEAR:
      return protocol::LayoutKeyFunction::CLEAR;
    case VK_UP:
      return protocol::LayoutKeyFunction::ARROW_UP;
    case VK_DOWN:
      return protocol::LayoutKeyFunction::ARROW_DOWN;
    case VK_LEFT:
      return protocol::LayoutKeyFunction::ARROW_LEFT;
    case VK_RIGHT:
      return protocol::LayoutKeyFunction::ARROW_RIGHT;
    case VK_F1:
      return protocol::LayoutKeyFunction::F1;
    case VK_F2:
      return protocol::LayoutKeyFunction::F2;
    case VK_F3:
      return protocol::LayoutKeyFunction::F3;
    case VK_F4:
      return protocol::LayoutKeyFunction::F4;
    case VK_F5:
      return protocol::LayoutKeyFunction::F5;
    case VK_F6:
      return protocol::LayoutKeyFunction::F6;
    case VK_F7:
      return protocol::LayoutKeyFunction::F7;
    case VK_F8:
      return protocol::LayoutKeyFunction::F8;
    case VK_F9:
      return protocol::LayoutKeyFunction::F9;
    case VK_F10:
      return protocol::LayoutKeyFunction::F10;
    case VK_F11:
      return protocol::LayoutKeyFunction::F11;
    case VK_F12:
      return protocol::LayoutKeyFunction::F12;
    case VK_F13:
      return protocol::LayoutKeyFunction::F13;
    case VK_F14:
      return protocol::LayoutKeyFunction::F14;
    case VK_F15:
      return protocol::LayoutKeyFunction::F15;
    case VK_F16:
      return protocol::LayoutKeyFunction::F16;
    case VK_F17:
      return protocol::LayoutKeyFunction::F17;
    case VK_F18:
      return protocol::LayoutKeyFunction::F18;
    case VK_F19:
      return protocol::LayoutKeyFunction::F19;
    case VK_F20:
      return protocol::LayoutKeyFunction::F20;
    case VK_F21:
      return protocol::LayoutKeyFunction::F21;
    case VK_F22:
      return protocol::LayoutKeyFunction::F22;
    case VK_F23:
      return protocol::LayoutKeyFunction::F23;
    case VK_F24:
      return protocol::LayoutKeyFunction::F24;
    case VK_ESCAPE:
      return protocol::LayoutKeyFunction::ESCAPE;
    case VK_APPS:
      return protocol::LayoutKeyFunction::CONTEXT_MENU;
    case VK_PAUSE:
      return protocol::LayoutKeyFunction::PAUSE;
    case VK_SNAPSHOT:
      return protocol::LayoutKeyFunction::PRINT_SCREEN;
  }

  // Handle language-specific keys.
  if (PRIMARYLANGID(lang) == 0x11) {  // Japanese
    switch (virtual_key) {
      case VK_DBE_SBCSCHAR:
        return protocol::LayoutKeyFunction::HANKAKU_ZENKAKU_KANJI;
      case VK_CONVERT:
        return protocol::LayoutKeyFunction::HENKAN;
      case VK_NONCONVERT:
        return protocol::LayoutKeyFunction::MUHENKAN;
      case VK_DBE_KATAKANA:
      case VK_DBE_HIRAGANA:
        // TODO(rkjnsn): Make sure it makes sense to use the same key cap for
        // both of these.
        return protocol::LayoutKeyFunction::KATAKANA_HIRAGANA_ROMAJI;
      case VK_DBE_ALPHANUMERIC:
        return protocol::LayoutKeyFunction::EISU;
    }
  } else if (PRIMARYLANGID(lang) == 0x12) {  // Korean
    switch (virtual_key) {
      case VK_HANJA:
        return protocol::LayoutKeyFunction::HANJA;
      case VK_HANGUL:
        return protocol::LayoutKeyFunction::HAN_YEONG;
    }
  }

  return protocol::LayoutKeyFunction::UNKNOWN;
}

}  // namespace

std::unique_ptr<KeyboardLayoutMonitor> KeyboardLayoutMonitor::Create(
    base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback,
    scoped_refptr<base::SingleThreadTaskRunner> input_task_runner) {
  return std::make_unique<KeyboardLayoutMonitorWin>(
      std::move(callback), std::move(input_task_runner));
}

}  // namespace remoting
