Commit b8876671 authored by Erik Jensen's avatar Erik Jensen Committed by Commit Bot

remoting: Implement initial keyboard layout monitor for Windows.

This uses various Windows APIs to try to glean information about the
current layout. Unfortunately, there appears to be no way to get some of
the needed information in a clean fashion through these APIs, so the
implementation uses various guesses and hacks to try to infer it. In the
future, I'd like to look into reading the layout directly from the
layout files, which contain mapping tables that provide all of the
needed information in a known format.

This currently runs in the network process. That means it can't monitor
active window changes and thus never sends an updated layout after the
initial connection. A follow up CL will run the monitor in the desktop
process and communicate the result back via IPC.

Bug: 1026029
Change-Id: Iaba9c0bb0ef2c60fac249a9af392f9434b9c5f93
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1918356
Commit-Queue: Erik Jensen <rkjnsn@chromium.org>
Reviewed-by: default avatarYuwei Huang <yuweih@chromium.org>
Reviewed-by: default avatarGary Kacmarcik <garykac@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720819}
parent a603a371
...@@ -215,6 +215,13 @@ void ChromotingClient::SetCursorShape( ...@@ -215,6 +215,13 @@ void ChromotingClient::SetCursorShape(
user_interface_->GetCursorShapeStub()->SetCursorShape(cursor_shape); user_interface_->GetCursorShapeStub()->SetCursorShape(cursor_shape);
} }
void ChromotingClient::SetKeyboardLayout(
const protocol::KeyboardLayout& layout) {
DCHECK(thread_checker_.CalledOnValidThread());
user_interface_->GetKeyboardLayoutStub()->SetKeyboardLayout(layout);
}
void ChromotingClient::OnConnectionState( void ChromotingClient::OnConnectionState(
protocol::ConnectionToHost::State state, protocol::ConnectionToHost::State state,
protocol::ErrorCode error) { protocol::ErrorCode error) {
......
...@@ -98,6 +98,9 @@ class ChromotingClient : public SignalStrategy::Listener, ...@@ -98,6 +98,9 @@ class ChromotingClient : public SignalStrategy::Listener,
// CursorShapeStub implementation for receiving cursor shape updates. // CursorShapeStub implementation for receiving cursor shape updates.
void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override; void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override;
// KeyboardLayoutStub implementation for sending keyboard layout to client.
void SetKeyboardLayout(const protocol::KeyboardLayout& layout) override;
// ConnectionToHost::HostEventCallback implementation. // ConnectionToHost::HostEventCallback implementation.
void OnConnectionState(protocol::ConnectionToHost::State state, void OnConnectionState(protocol::ConnectionToHost::State state,
protocol::ErrorCode error) override; protocol::ErrorCode error) override;
......
...@@ -95,7 +95,8 @@ struct SessionContext { ...@@ -95,7 +95,8 @@ struct SessionContext {
} // namespace } // namespace
class ChromotingSession::Core : public ClientUserInterface, class ChromotingSession::Core : public ClientUserInterface,
public protocol::ClipboardStub { public protocol::ClipboardStub,
public protocol::KeyboardLayoutStub {
public: public:
Core(ChromotingClientRuntime* runtime, Core(ChromotingClientRuntime* runtime,
std::unique_ptr<ClientTelemetryLogger> logger, std::unique_ptr<ClientTelemetryLogger> logger,
...@@ -134,10 +135,14 @@ class ChromotingSession::Core : public ClientUserInterface, ...@@ -134,10 +135,14 @@ class ChromotingSession::Core : public ClientUserInterface,
const webrtc::DesktopVector& dpi) override; const webrtc::DesktopVector& dpi) override;
protocol::ClipboardStub* GetClipboardStub() override; protocol::ClipboardStub* GetClipboardStub() override;
protocol::CursorShapeStub* GetCursorShapeStub() override; protocol::CursorShapeStub* GetCursorShapeStub() override;
protocol::KeyboardLayoutStub* GetKeyboardLayoutStub() override;
// CursorShapeStub implementation. // ClipboardStub implementation.
void InjectClipboardEvent(const protocol::ClipboardEvent& event) override; void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;
// KeyboardLayoutStub implementation.
void SetKeyboardLayout(const protocol::KeyboardLayout& layout) override;
base::WeakPtr<Core> GetWeakPtr(); base::WeakPtr<Core> GetWeakPtr();
private: private:
...@@ -445,11 +450,20 @@ protocol::CursorShapeStub* ChromotingSession::Core::GetCursorShapeStub() { ...@@ -445,11 +450,20 @@ protocol::CursorShapeStub* ChromotingSession::Core::GetCursorShapeStub() {
return session_context_->cursor_shape_stub.get(); return session_context_->cursor_shape_stub.get();
} }
protocol::KeyboardLayoutStub* ChromotingSession::Core::GetKeyboardLayoutStub() {
return this;
}
void ChromotingSession::Core::InjectClipboardEvent( void ChromotingSession::Core::InjectClipboardEvent(
const protocol::ClipboardEvent& event) { const protocol::ClipboardEvent& event) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
void ChromotingSession::Core::SetKeyboardLayout(
const protocol::KeyboardLayout& layout) {
NOTIMPLEMENTED();
}
base::WeakPtr<ChromotingSession::Core> ChromotingSession::Core::GetWeakPtr() { base::WeakPtr<ChromotingSession::Core> ChromotingSession::Core::GetWeakPtr() {
return weak_ptr_; return weak_ptr_;
} }
......
...@@ -22,6 +22,7 @@ namespace protocol { ...@@ -22,6 +22,7 @@ namespace protocol {
class ClipboardStub; class ClipboardStub;
class CursorShapeStub; class CursorShapeStub;
class ExtensionMessage; class ExtensionMessage;
class KeyboardLayoutStub;
class PairingResponse; class PairingResponse;
} // namespace protocol } // namespace protocol
...@@ -63,6 +64,9 @@ class ClientUserInterface { ...@@ -63,6 +64,9 @@ class ClientUserInterface {
// Get the view's CursorShapeStub implementation. // Get the view's CursorShapeStub implementation.
virtual protocol::CursorShapeStub* GetCursorShapeStub() = 0; virtual protocol::CursorShapeStub* GetCursorShapeStub() = 0;
// Get the view's KeyboardLayoutStub implementation.
virtual protocol::KeyboardLayoutStub* GetKeyboardLayoutStub() = 0;
}; };
} // namespace remoting } // namespace remoting
......
...@@ -236,6 +236,11 @@ static_library("common") { ...@@ -236,6 +236,11 @@ static_library("common") {
"ipc_video_frame_capturer.h", "ipc_video_frame_capturer.h",
"it2me_desktop_environment.cc", "it2me_desktop_environment.cc",
"it2me_desktop_environment.h", "it2me_desktop_environment.h",
"keyboard_layout_monitor.cc",
"keyboard_layout_monitor.h",
"keyboard_layout_monitor_linux.cc",
"keyboard_layout_monitor_mac.cc",
"keyboard_layout_monitor_win.cc",
"me2me_desktop_environment.cc", "me2me_desktop_environment.cc",
"me2me_desktop_environment.h", "me2me_desktop_environment.h",
"mouse_cursor_monitor_proxy.cc", "mouse_cursor_monitor_proxy.cc",
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "remoting/host/file_transfer/file_transfer_message_handler.h" #include "remoting/host/file_transfer/file_transfer_message_handler.h"
#include "remoting/host/host_extension_session.h" #include "remoting/host/host_extension_session.h"
#include "remoting/host/input_injector.h" #include "remoting/host/input_injector.h"
#include "remoting/host/keyboard_layout_monitor.h"
#include "remoting/host/mouse_shape_pump.h" #include "remoting/host/mouse_shape_pump.h"
#include "remoting/host/screen_controls.h" #include "remoting/host/screen_controls.h"
#include "remoting/host/screen_resolution.h" #include "remoting/host/screen_resolution.h"
...@@ -378,6 +379,12 @@ void ClientSession::OnConnectionChannelsConnected() { ...@@ -378,6 +379,12 @@ void ClientSession::OnConnectionChannelsConnected() {
new MouseShapePump(desktop_environment_->CreateMouseCursorMonitor(), new MouseShapePump(desktop_environment_->CreateMouseCursorMonitor(),
connection_->client_stub())); connection_->client_stub()));
// Create KeyboardLayoutMonitor to send keyboard layout.
keyboard_layout_monitor_ = KeyboardLayoutMonitor::Create(
base::BindRepeating(&protocol::KeyboardLayoutStub::SetKeyboardLayout,
base::Unretained(connection_->client_stub())));
keyboard_layout_monitor_->Start();
if (pending_video_layout_message_) { if (pending_video_layout_message_) {
connection_->client_stub()->SetVideoLayout(*pending_video_layout_message_); connection_->client_stub()->SetVideoLayout(*pending_video_layout_message_);
pending_video_layout_message_.reset(); pending_video_layout_message_.reset();
...@@ -406,6 +413,7 @@ void ClientSession::OnConnectionClosed(protocol::ErrorCode error) { ...@@ -406,6 +413,7 @@ void ClientSession::OnConnectionClosed(protocol::ErrorCode error) {
// longer valid once ConnectionToClient calls OnConnectionClosed(). // longer valid once ConnectionToClient calls OnConnectionClosed().
audio_stream_.reset(); audio_stream_.reset();
video_stream_.reset(); video_stream_.reset();
keyboard_layout_monitor_.reset();
mouse_shape_pump_.reset(); mouse_shape_pump_.reset();
client_clipboard_factory_.InvalidateWeakPtrs(); client_clipboard_factory_.InvalidateWeakPtrs();
input_injector_.reset(); input_injector_.reset();
......
...@@ -47,6 +47,7 @@ class AudioStream; ...@@ -47,6 +47,7 @@ class AudioStream;
class DesktopEnvironment; class DesktopEnvironment;
class DesktopEnvironmentFactory; class DesktopEnvironmentFactory;
class InputInjector; class InputInjector;
class KeyboardLayoutMonitor;
class MouseShapePump; class MouseShapePump;
class ScreenControls; class ScreenControls;
...@@ -240,6 +241,7 @@ class ClientSession : public protocol::HostStub, ...@@ -240,6 +241,7 @@ class ClientSession : public protocol::HostStub,
std::unique_ptr<protocol::VideoStream> video_stream_; std::unique_ptr<protocol::VideoStream> video_stream_;
std::unique_ptr<protocol::AudioStream> audio_stream_; std::unique_ptr<protocol::AudioStream> audio_stream_;
std::unique_ptr<MouseShapePump> mouse_shape_pump_; std::unique_ptr<MouseShapePump> mouse_shape_pump_;
std::unique_ptr<KeyboardLayoutMonitor> keyboard_layout_monitor_;
// The set of all capabilities supported by the client. // The set of all capabilities supported by the client.
std::unique_ptr<std::string> client_capabilities_; std::unique_ptr<std::string> client_capabilities_;
......
// 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 "base/containers/span.h"
#include "ui/events/keycodes/dom/dom_code.h"
namespace remoting {
namespace {
const ui::DomCode kSupportedKeysArray[] = {
ui::DomCode::ALT_LEFT,
ui::DomCode::ALT_RIGHT,
ui::DomCode::ARROW_DOWN,
ui::DomCode::ARROW_RIGHT,
ui::DomCode::ARROW_LEFT,
ui::DomCode::ARROW_UP,
ui::DomCode::BACKQUOTE,
ui::DomCode::BACKSLASH,
ui::DomCode::BACKSPACE,
ui::DomCode::BRACKET_LEFT,
ui::DomCode::BRACKET_RIGHT,
ui::DomCode::CAPS_LOCK,
ui::DomCode::COMMA,
ui::DomCode::CONTEXT_MENU,
ui::DomCode::CONTROL_LEFT,
ui::DomCode::CONTROL_RIGHT,
ui::DomCode::CONVERT,
ui::DomCode::DEL,
ui::DomCode::DIGIT0,
ui::DomCode::DIGIT1,
ui::DomCode::DIGIT2,
ui::DomCode::DIGIT3,
ui::DomCode::DIGIT4,
ui::DomCode::DIGIT5,
ui::DomCode::DIGIT6,
ui::DomCode::DIGIT7,
ui::DomCode::DIGIT8,
ui::DomCode::DIGIT9,
ui::DomCode::END,
ui::DomCode::ENTER,
ui::DomCode::EQUAL,
ui::DomCode::ESCAPE,
ui::DomCode::F1,
ui::DomCode::F2,
ui::DomCode::F3,
ui::DomCode::F4,
ui::DomCode::F5,
ui::DomCode::F6,
ui::DomCode::F7,
ui::DomCode::F8,
ui::DomCode::F9,
ui::DomCode::F10,
ui::DomCode::F11,
ui::DomCode::F12,
ui::DomCode::HOME,
ui::DomCode::INSERT,
ui::DomCode::INTL_BACKSLASH,
ui::DomCode::INTL_RO,
ui::DomCode::INTL_YEN,
ui::DomCode::KANA_MODE,
ui::DomCode::LANG1,
ui::DomCode::LANG2,
ui::DomCode::META_LEFT,
ui::DomCode::META_RIGHT,
ui::DomCode::MINUS,
ui::DomCode::NON_CONVERT,
ui::DomCode::NUM_LOCK,
ui::DomCode::NUMPAD0,
ui::DomCode::NUMPAD1,
ui::DomCode::NUMPAD2,
ui::DomCode::NUMPAD3,
ui::DomCode::NUMPAD4,
ui::DomCode::NUMPAD5,
ui::DomCode::NUMPAD6,
ui::DomCode::NUMPAD7,
ui::DomCode::NUMPAD8,
ui::DomCode::NUMPAD9,
ui::DomCode::NUMPAD_ADD,
ui::DomCode::NUMPAD_COMMA,
ui::DomCode::NUMPAD_DECIMAL,
ui::DomCode::NUMPAD_DIVIDE,
ui::DomCode::NUMPAD_ENTER,
ui::DomCode::NUMPAD_EQUAL,
ui::DomCode::NUMPAD_MULTIPLY,
ui::DomCode::NUMPAD_SUBTRACT,
ui::DomCode::PAGE_DOWN,
ui::DomCode::PAGE_UP,
ui::DomCode::PAUSE,
ui::DomCode::PERIOD,
ui::DomCode::PRINT_SCREEN,
ui::DomCode::QUOTE,
ui::DomCode::SCROLL_LOCK,
ui::DomCode::SEMICOLON,
ui::DomCode::SHIFT_LEFT,
ui::DomCode::SHIFT_RIGHT,
ui::DomCode::SLASH,
ui::DomCode::SPACE,
ui::DomCode::TAB,
ui::DomCode::US_A,
ui::DomCode::US_B,
ui::DomCode::US_C,
ui::DomCode::US_D,
ui::DomCode::US_E,
ui::DomCode::US_F,
ui::DomCode::US_G,
ui::DomCode::US_H,
ui::DomCode::US_I,
ui::DomCode::US_J,
ui::DomCode::US_K,
ui::DomCode::US_L,
ui::DomCode::US_M,
ui::DomCode::US_N,
ui::DomCode::US_O,
ui::DomCode::US_P,
ui::DomCode::US_Q,
ui::DomCode::US_R,
ui::DomCode::US_S,
ui::DomCode::US_T,
ui::DomCode::US_U,
ui::DomCode::US_V,
ui::DomCode::US_W,
ui::DomCode::US_X,
ui::DomCode::US_Y,
ui::DomCode::US_Z,
};
} // namespace
// static
const base::span<const ui::DomCode> KeyboardLayoutMonitor::kSupportedKeys(
kSupportedKeysArray);
} // namespace remoting
// 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.
#ifndef REMOTING_HOST_KEYBOARD_LAYOUT_MONITOR_H_
#define REMOTING_HOST_KEYBOARD_LAYOUT_MONITOR_H_
#include <memory>
#include "base/callback_forward.h"
#include "base/containers/span.h"
#include "ui/events/keycodes/dom/dom_code.h"
namespace remoting {
namespace protocol {
class KeyboardLayout;
} // namespace protocol
// KeyboardLayoutMonitor implementations are responsible for monitoring the
// active keyboard layout within the CRD session on the host, and triggering a
// callback whenever it changes.
class KeyboardLayoutMonitor {
public:
virtual ~KeyboardLayoutMonitor() = default;
KeyboardLayoutMonitor(const KeyboardLayoutMonitor&) = delete;
KeyboardLayoutMonitor& operator=(const KeyboardLayoutMonitor&) = delete;
// Starts monitoring the keyboard layout. This will generate a callback with
// the current layout, and an additional callback whenever the layout is
// changed. The callback is guaranteed not be be called after the
// KeyboardLayoutMonitor is destroyed.
virtual void Start() = 0;
// Creates a platform-specific KeyboardLayoutMonitor.
static std::unique_ptr<KeyboardLayoutMonitor> Create(
base::RepeatingCallback<void(const protocol::KeyboardLayout&)>);
protected:
KeyboardLayoutMonitor() = default;
// Physical keys to include in the keyboard map.
static const base::span<const ui::DomCode> kSupportedKeys;
};
} // namespace remoting
#endif // REMOTING_HOST_KEYBOARD_LAYOUT_MONITOR_H_
// 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 "base/callback.h"
namespace remoting {
namespace {
class KeyboardLayoutMonitorLinux : public KeyboardLayoutMonitor {
public:
KeyboardLayoutMonitorLinux(
base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback) {
}
~KeyboardLayoutMonitorLinux() override = default;
void Start() override {
// TODO(rkjnsn): Poll keyboard layout on Linux.
}
};
} // namespace
std::unique_ptr<KeyboardLayoutMonitor> KeyboardLayoutMonitor::Create(
base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback) {
return std::make_unique<KeyboardLayoutMonitorLinux>(std::move(callback));
}
} // namespace remoting
// 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 "base/callback.h"
namespace remoting {
namespace {
class KeyboardLayoutMonitorMac : public KeyboardLayoutMonitor {
public:
KeyboardLayoutMonitorMac(
base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback) {
}
~KeyboardLayoutMonitorMac() override = default;
void Start() override {
// TODO(rkjnsn): Poll keyboard layout on Mac.
}
};
} // namespace
std::unique_ptr<KeyboardLayoutMonitor> KeyboardLayoutMonitor::Create(
base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback) {
return std::make_unique<KeyboardLayoutMonitorMac>(std::move(callback));
}
} // namespace remoting
This diff is collapsed.
...@@ -70,6 +70,9 @@ class TestClientStub : public protocol::ClientStub { ...@@ -70,6 +70,9 @@ class TestClientStub : public protocol::ClientStub {
// protocol::CursorShapeStub implementation. // protocol::CursorShapeStub implementation.
void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override; void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override;
// protocol::KeyboardLayoutStub implementation.
void SetKeyboardLayout(const protocol::KeyboardLayout& layout) override;
void WaitForDeliverHostMessage(base::TimeDelta max_timeout); void WaitForDeliverHostMessage(base::TimeDelta max_timeout);
void CheckHostDataMessage(int id, const std::string& data); void CheckHostDataMessage(int id, const std::string& data);
...@@ -105,6 +108,9 @@ void TestClientStub::InjectClipboardEvent( ...@@ -105,6 +108,9 @@ void TestClientStub::InjectClipboardEvent(
void TestClientStub::SetCursorShape( void TestClientStub::SetCursorShape(
const protocol::CursorShapeInfo& cursor_shape) {} const protocol::CursorShapeInfo& cursor_shape) {}
void TestClientStub::SetKeyboardLayout(const protocol::KeyboardLayout& layout) {
}
void TestClientStub::WaitForDeliverHostMessage(base::TimeDelta max_timeout) { void TestClientStub::WaitForDeliverHostMessage(base::TimeDelta max_timeout) {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, run_loop_->QuitClosure(), max_timeout); FROM_HERE, run_loop_->QuitClosure(), max_timeout);
......
...@@ -152,8 +152,9 @@ message KeyboardLayout { ...@@ -152,8 +152,9 @@ message KeyboardLayout {
// Next ID: 2 // Next ID: 2
message KeyBehavior { message KeyBehavior {
// Maps shift level to key action. // Maps 0-based shift level to key action. (Note: because this is zero-
map<int32, KeyAction> actions = 1; // based, it will be one less than the corresponding ISO shift level.)
map<uint32, KeyAction> actions = 1;
} }
// Map USB code to key behavior. // Map USB code to key behavior.
......
...@@ -27,6 +27,7 @@ message ControlMessage { ...@@ -27,6 +27,7 @@ message ControlMessage {
optional ExtensionMessage extension_message = 9; optional ExtensionMessage extension_message = 9;
optional VideoLayout video_layout = 10; optional VideoLayout video_layout = 10;
optional SelectDesktopDisplayRequest select_display = 11; optional SelectDesktopDisplayRequest select_display = 11;
optional KeyboardLayout keyboard_layout = 12;
} }
// Defines an event message on the event channel. // Defines an event message on the event channel.
......
...@@ -93,9 +93,6 @@ enum LayoutKeyFunction { ...@@ -93,9 +93,6 @@ enum LayoutKeyFunction {
MUHENKAN = 55; // NonConvert MUHENKAN = 55; // NonConvert
KATAKANA_HIRAGANA_ROMAJI = 56; // KanaMode KATAKANA_HIRAGANA_ROMAJI = 56; // KanaMode
KANA = 57; // Lang1 (Mac keyboard) KANA = 57; // Lang1 (Mac keyboard)
// Note: Windows only identifies the key as "Caps Lock", so the Windows host
// currently sends the CAPS_LOCK function even for shift level 1 (unshifted)
// and doesn't use this function.
EISU = 58; // Unshifted CapsLock (Windows), Lang2 (Mac keyboard) EISU = 58; // Unshifted CapsLock (Windows), Lang2 (Mac keyboard)
// Korean // Korean
HAN_YEONG = 59; // Lang1 HAN_YEONG = 59; // Lang1
......
...@@ -94,6 +94,7 @@ static_library("protocol") { ...@@ -94,6 +94,7 @@ static_library("protocol") {
"jingle_session.h", "jingle_session.h",
"jingle_session_manager.cc", "jingle_session_manager.cc",
"jingle_session_manager.h", "jingle_session_manager.h",
"keyboard_layout_stub.h",
"me2me_host_authenticator_factory.cc", "me2me_host_authenticator_factory.cc",
"me2me_host_authenticator_factory.h", "me2me_host_authenticator_factory.h",
"message_decoder.cc", "message_decoder.cc",
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "remoting/protocol/clipboard_stub.h" #include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/cursor_shape_stub.h" #include "remoting/protocol/cursor_shape_stub.h"
#include "remoting/protocol/keyboard_layout_stub.h"
namespace remoting { namespace remoting {
namespace protocol { namespace protocol {
...@@ -23,7 +24,8 @@ class PairingResponse; ...@@ -23,7 +24,8 @@ class PairingResponse;
class VideoLayout; class VideoLayout;
class ClientStub : public ClipboardStub, class ClientStub : public ClipboardStub,
public CursorShapeStub { public CursorShapeStub,
public KeyboardLayoutStub {
public: public:
ClientStub() {} ClientStub() {}
~ClientStub() override {} ~ClientStub() override {}
......
...@@ -78,6 +78,12 @@ void HostControlDispatcher::SetCursorShape( ...@@ -78,6 +78,12 @@ void HostControlDispatcher::SetCursorShape(
message_pipe()->Send(&message, base::Closure()); message_pipe()->Send(&message, base::Closure());
} }
void HostControlDispatcher::SetKeyboardLayout(const KeyboardLayout& layout) {
ControlMessage message;
message.mutable_keyboard_layout()->CopyFrom(layout);
message_pipe()->Send(&message, base::Closure());
}
void HostControlDispatcher::OnIncomingMessage( void HostControlDispatcher::OnIncomingMessage(
std::unique_ptr<CompoundBuffer> buffer) { std::unique_ptr<CompoundBuffer> buffer) {
DCHECK(clipboard_stub_); DCHECK(clipboard_stub_);
......
...@@ -40,6 +40,9 @@ class HostControlDispatcher : public ChannelDispatcherBase, ...@@ -40,6 +40,9 @@ class HostControlDispatcher : public ChannelDispatcherBase,
// CursorShapeStub implementation for sending cursor shape to client. // CursorShapeStub implementation for sending cursor shape to client.
void SetCursorShape(const CursorShapeInfo& cursor_shape) override; void SetCursorShape(const CursorShapeInfo& cursor_shape) override;
// KeyboardLayoutStub implementation for sending keyboard layout to client.
void SetKeyboardLayout(const KeyboardLayout& layout) override;
// Sets the ClipboardStub that will be called for each incoming clipboard // Sets the ClipboardStub that will be called for each incoming clipboard
// message. |clipboard_stub| must outlive this object. // message. |clipboard_stub| must outlive this object.
void set_clipboard_stub(ClipboardStub* clipboard_stub) { void set_clipboard_stub(ClipboardStub* clipboard_stub) {
......
// 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.
// Interface for an object that receives keyboard layout events.
#ifndef REMOTING_PROTOCOL_KEYBOARD_LAYOUT_STUB_H_
#define REMOTING_PROTOCOL_KEYBOARD_LAYOUT_STUB_H_
#include "base/macros.h"
namespace remoting {
namespace protocol {
class KeyboardLayout;
// Interface used to inform the client when the host's keyboard layout changes.
class KeyboardLayoutStub {
public:
virtual ~KeyboardLayoutStub() = default;
KeyboardLayoutStub(const KeyboardLayoutStub&) = delete;
KeyboardLayoutStub& operator=(const KeyboardLayoutStub&) = delete;
virtual void SetKeyboardLayout(const KeyboardLayout& keyboard_layout) = 0;
protected:
KeyboardLayoutStub() = default;
};
} // namespace protocol
} // namespace remoting
#endif // REMOTING_PROTOCOL_KEYBOARD_LAYOUT_STUB_H_
...@@ -159,6 +159,9 @@ class MockClientStub : public ClientStub { ...@@ -159,6 +159,9 @@ class MockClientStub : public ClientStub {
// CursorShapeStub mock implementation. // CursorShapeStub mock implementation.
MOCK_METHOD1(SetCursorShape, void(const CursorShapeInfo& cursor_shape)); MOCK_METHOD1(SetCursorShape, void(const CursorShapeInfo& cursor_shape));
// KeyboardLayoutStub mock implementation.
MOCK_METHOD1(SetKeyboardLayout, void(const KeyboardLayout& layout));
private: private:
DISALLOW_COPY_AND_ASSIGN(MockClientStub); DISALLOW_COPY_AND_ASSIGN(MockClientStub);
}; };
......
...@@ -203,6 +203,7 @@ class FakeConnectionEventLogger::CounterClientStub ...@@ -203,6 +203,7 @@ class FakeConnectionEventLogger::CounterClientStub
void InjectClipboardEvent(const protocol::ClipboardEvent& event) override {} void InjectClipboardEvent(const protocol::ClipboardEvent& event) override {}
void SetCapabilities(const protocol::Capabilities& capabilities) override {} void SetCapabilities(const protocol::Capabilities& capabilities) override {}
void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override {} void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override {}
void SetKeyboardLayout(const protocol::KeyboardLayout& layout) override {}
void SetPairingResponse(const protocol::PairingResponse& response) override {} void SetPairingResponse(const protocol::PairingResponse& response) override {}
void SetVideoLayout(const protocol::VideoLayout& video_layout) override {} void SetVideoLayout(const protocol::VideoLayout& video_layout) override {}
}; };
......
...@@ -155,6 +155,9 @@ class ProtocolPerfTest ...@@ -155,6 +155,9 @@ class ProtocolPerfTest
protocol::CursorShapeStub* GetCursorShapeStub() override { protocol::CursorShapeStub* GetCursorShapeStub() override {
return &cursor_shape_stub_; return &cursor_shape_stub_;
} }
protocol::KeyboardLayoutStub* GetKeyboardLayoutStub() override {
return nullptr;
}
// protocol::FrameConsumer interface. // protocol::FrameConsumer interface.
std::unique_ptr<webrtc::DesktopFrame> AllocateFrame( std::unique_ptr<webrtc::DesktopFrame> AllocateFrame(
......
...@@ -266,6 +266,11 @@ protocol::CursorShapeStub* TestChromotingClient::GetCursorShapeStub() { ...@@ -266,6 +266,11 @@ protocol::CursorShapeStub* TestChromotingClient::GetCursorShapeStub() {
return this; return this;
} }
protocol::KeyboardLayoutStub* TestChromotingClient::GetKeyboardLayoutStub() {
VLOG(1) << "TestChromotingClient::GetKeyboardLayoutStub() Called";
return this;
}
void TestChromotingClient::InjectClipboardEvent( void TestChromotingClient::InjectClipboardEvent(
const protocol::ClipboardEvent& event) { const protocol::ClipboardEvent& event) {
VLOG(1) << "TestChromotingClient::InjectClipboardEvent() Called"; VLOG(1) << "TestChromotingClient::InjectClipboardEvent() Called";
...@@ -276,5 +281,10 @@ void TestChromotingClient::SetCursorShape( ...@@ -276,5 +281,10 @@ void TestChromotingClient::SetCursorShape(
VLOG(1) << "TestChromotingClient::SetCursorShape() Called"; VLOG(1) << "TestChromotingClient::SetCursorShape() Called";
} }
void TestChromotingClient::SetKeyboardLayout(
const protocol::KeyboardLayout& layout) {
VLOG(1) << "TestChromotingClient::SetKeyboardLayout() Called";
}
} // namespace test } // namespace test
} // namespace remoting } // namespace remoting
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "remoting/client/client_user_interface.h" #include "remoting/client/client_user_interface.h"
#include "remoting/protocol/clipboard_filter.h" #include "remoting/protocol/clipboard_filter.h"
#include "remoting/protocol/cursor_shape_stub.h" #include "remoting/protocol/cursor_shape_stub.h"
#include "remoting/protocol/keyboard_layout_stub.h"
#include "remoting/test/remote_connection_observer.h" #include "remoting/test/remote_connection_observer.h"
namespace remoting { namespace remoting {
...@@ -40,7 +41,8 @@ struct ConnectionSetupInfo; ...@@ -40,7 +41,8 @@ struct ConnectionSetupInfo;
// A VideoRenderer can be passed in to customize the connection. // A VideoRenderer can be passed in to customize the connection.
class TestChromotingClient : public ClientUserInterface, class TestChromotingClient : public ClientUserInterface,
public protocol::ClipboardStub, public protocol::ClipboardStub,
public protocol::CursorShapeStub { public protocol::CursorShapeStub,
public protocol::KeyboardLayoutStub {
public: public:
TestChromotingClient(); TestChromotingClient();
explicit TestChromotingClient( explicit TestChromotingClient(
...@@ -90,6 +92,7 @@ class TestChromotingClient : public ClientUserInterface, ...@@ -90,6 +92,7 @@ class TestChromotingClient : public ClientUserInterface,
const webrtc::DesktopVector& dpi) override; const webrtc::DesktopVector& dpi) override;
protocol::ClipboardStub* GetClipboardStub() override; protocol::ClipboardStub* GetClipboardStub() override;
protocol::CursorShapeStub* GetCursorShapeStub() override; protocol::CursorShapeStub* GetCursorShapeStub() override;
protocol::KeyboardLayoutStub* GetKeyboardLayoutStub() override;
// protocol::ClipboardStub interface. // protocol::ClipboardStub interface.
void InjectClipboardEvent(const protocol::ClipboardEvent& event) override; void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;
...@@ -97,6 +100,9 @@ class TestChromotingClient : public ClientUserInterface, ...@@ -97,6 +100,9 @@ class TestChromotingClient : public ClientUserInterface,
// protocol::CursorShapeStub interface. // protocol::CursorShapeStub interface.
void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override; void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override;
// protocol::KeyboardLayoutStub interface.
void SetKeyboardLayout(const protocol::KeyboardLayout& layout) override;
// Tracks the current connection state. // Tracks the current connection state.
protocol::ConnectionToHost::State connection_to_host_state_; protocol::ConnectionToHost::State connection_to_host_state_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment