| Index: remoting/host/input_injector_chromeos.cc
|
| diff --git a/remoting/host/input_injector_chromeos.cc b/remoting/host/input_injector_chromeos.cc
|
| index a18b1cd2ce73f51bdc47074c20c9be0878a0ee1f..85ec86fc97cf4ef6fb5d04df7383155493297f74 100644
|
| --- a/remoting/host/input_injector_chromeos.cc
|
| +++ b/remoting/host/input_injector_chromeos.cc
|
| @@ -4,8 +4,16 @@
|
|
|
| #include "remoting/host/input_injector_chromeos.h"
|
|
|
| -#include "base/logging.h"
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/location.h"
|
| +#include "remoting/host/chromeos/point_transformer.h"
|
| +#include "remoting/host/clipboard.h"
|
| #include "remoting/proto/internal.pb.h"
|
| +#include "ui/events/keycodes/dom3/dom_code.h"
|
| +#include "ui/events/keycodes/dom4/keycode_converter.h"
|
| +#include "ui/ozone/public/ozone_platform.h"
|
| +#include "ui/ozone/public/system_input_injector.h"
|
|
|
| namespace remoting {
|
|
|
| @@ -14,45 +22,152 @@ using protocol::KeyEvent;
|
| using protocol::MouseEvent;
|
| using protocol::TextEvent;
|
|
|
| -// TODO(kelvinp): Implement this class (See crbug.com/426716).
|
| +namespace {
|
| +
|
| +ui::EventFlags MouseButtonToUIFlags(MouseEvent::MouseButton button) {
|
| + switch (button) {
|
| + case MouseEvent::BUTTON_LEFT:
|
| + return ui::EF_LEFT_MOUSE_BUTTON;
|
| + case MouseEvent::BUTTON_RIGHT:
|
| + return ui::EF_RIGHT_MOUSE_BUTTON;
|
| + case MouseEvent::BUTTON_MIDDLE:
|
| + return ui::EF_MIDDLE_MOUSE_BUTTON;
|
| + default:
|
| + NOTREACHED();
|
| + return ui::EF_NONE;
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// This class is run exclusively on the UI thread of the browser process.
|
| +class InputInjectorChromeos::Core {
|
| + public:
|
| + explicit Core(scoped_ptr<ui::SystemInputInjector> delegate_);
|
| +
|
| + // Mirrors the public InputInjectorChromeos interface.
|
| + void InjectClipboardEvent(const ClipboardEvent& event);
|
| + void InjectKeyEvent(const KeyEvent& event);
|
| + void InjectTextEvent(const TextEvent& event);
|
| + void InjectMouseEvent(const MouseEvent& event);
|
| + void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard);
|
| +
|
| + private:
|
| + scoped_ptr<ui::SystemInputInjector> delegate_;
|
| + scoped_ptr<Clipboard> clipboard_;
|
| +
|
| + // Used to rotate the input coordinates appropriately based on the current
|
| + // display rotation settings.
|
| + scoped_ptr<PointTransformer> point_transformer_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Core);
|
| +};
|
| +
|
| +InputInjectorChromeos::Core::Core(scoped_ptr<ui::SystemInputInjector> delegate)
|
| + : delegate_(delegate.Pass()),
|
| + // Implemented by remoting::ClipboardAura.
|
| + clipboard_(Clipboard::Create()) {
|
| + DCHECK(delegate);
|
| + DCHECK(clipboard_);
|
| +}
|
| +
|
| +void InputInjectorChromeos::Core::InjectClipboardEvent(
|
| + const ClipboardEvent& event) {
|
| + clipboard_->InjectClipboardEvent(event);
|
| +}
|
| +
|
| +void InputInjectorChromeos::Core::InjectKeyEvent(const KeyEvent& event) {
|
| + DCHECK(event.has_pressed());
|
| + DCHECK(event.has_usb_keycode());
|
| +
|
| + // TODO(kelvinp): Disable AutoRepeat as long as keys are pressed on ChromeOS
|
| + // when the auto-repeat API is ready to avoid triggering the auto-repeat if
|
| + // network congestion delays the key-up event from the client
|
| + // (See crbug.com/425201).
|
| +
|
| + ui::DomCode dom_code =
|
| + ui::KeycodeConverter::UsbKeycodeToDomCode(event.usb_keycode());
|
| +
|
| + // Ignore events which can't be mapped.
|
| + if (dom_code != ui::DomCode::NONE) {
|
| + delegate_->InjectKeyPress(dom_code, event.pressed());
|
| + }
|
| +}
|
| +
|
| +void InputInjectorChromeos::Core::InjectTextEvent(const TextEvent& event) {
|
| + // Chrome OS only supports It2Me, which is not supported on mobile clients, so
|
| + // we don't need to implement text events.
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void InputInjectorChromeos::Core::InjectMouseEvent(const MouseEvent& event) {
|
| + if (event.has_button() && event.has_button_down()) {
|
| + delegate_->InjectMouseButton(MouseButtonToUIFlags(event.button()),
|
| + event.button_down());
|
| + } else if (event.has_wheel_delta_y() || event.has_wheel_delta_x()) {
|
| + delegate_->InjectMouseWheel(event.wheel_delta_x(), event.wheel_delta_y());
|
| + } else {
|
| + DCHECK(event.has_x() && event.has_y());
|
| + delegate_->MoveCursorTo(point_transformer_->ToScreenCoordinates(
|
| + gfx::PointF(event.x(), event.y())));
|
| + }
|
| +}
|
| +
|
| +void InputInjectorChromeos::Core::Start(
|
| + scoped_ptr<protocol::ClipboardStub> client_clipboard) {
|
| + clipboard_->Start(client_clipboard.Pass());
|
| + point_transformer_.reset(new PointTransformer());
|
| +}
|
| +
|
| InputInjectorChromeos::InputInjectorChromeos(
|
| scoped_refptr<base::SingleThreadTaskRunner> task_runner)
|
| : input_task_runner_(task_runner) {
|
| - NOTIMPLEMENTED();
|
| + ui::OzonePlatform* ozone_platform = ui::OzonePlatform::GetInstance();
|
| + core_.reset(new Core(ozone_platform->CreateSystemInputInjector()));
|
| }
|
|
|
| InputInjectorChromeos::~InputInjectorChromeos() {
|
| - NOTIMPLEMENTED();
|
| + input_task_runner_->DeleteSoon(FROM_HERE, core_.release());
|
| }
|
|
|
| void InputInjectorChromeos::InjectClipboardEvent(const ClipboardEvent& event) {
|
| - NOTIMPLEMENTED();
|
| + input_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&Core::InjectClipboardEvent,
|
| + base::Unretained(core_.get()), event));
|
| }
|
|
|
| void InputInjectorChromeos::InjectKeyEvent(const KeyEvent& event) {
|
| - NOTIMPLEMENTED();
|
| + input_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&Core::InjectKeyEvent, base::Unretained(core_.get()), event));
|
| }
|
|
|
| void InputInjectorChromeos::InjectTextEvent(const TextEvent& event) {
|
| - NOTIMPLEMENTED();
|
| + input_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&Core::InjectTextEvent, base::Unretained(core_.get()), event));
|
| }
|
|
|
| void InputInjectorChromeos::InjectMouseEvent(const MouseEvent& event) {
|
| - NOTIMPLEMENTED();
|
| + input_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&Core::InjectMouseEvent,
|
| + base::Unretained(core_.get()), event));
|
| }
|
|
|
| void InputInjectorChromeos::Start(
|
| scoped_ptr<protocol::ClipboardStub> client_clipboard) {
|
| - NOTIMPLEMENTED();
|
| + input_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&Core::Start, base::Unretained(core_.get()),
|
| + base::Passed(&client_clipboard)));
|
| }
|
|
|
| // static
|
| scoped_ptr<InputInjector> InputInjector::Create(
|
| scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
|
| scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
|
| - scoped_ptr<InputInjectorChromeos> injector(new InputInjectorChromeos(
|
| - ui_task_runner));
|
| - return injector.Pass();
|
| + // The Ozone input injector must be called on the UI task runner of the
|
| + // browser process.
|
| + return make_scoped_ptr(new InputInjectorChromeos(ui_task_runner));
|
| }
|
|
|
| } // namespace remoting
|
|
|