OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/input_injector_chromeos.h" | 5 #include "remoting/host/input_injector_chromeos.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" |
| 9 #include "base/location.h" |
| 10 #include "remoting/host/chromeos/point_transformer.h" |
| 11 #include "remoting/host/clipboard.h" |
8 #include "remoting/proto/internal.pb.h" | 12 #include "remoting/proto/internal.pb.h" |
| 13 #include "ui/events/keycodes/dom3/dom_code.h" |
| 14 #include "ui/events/keycodes/dom4/keycode_converter.h" |
| 15 #include "ui/ozone/public/ozone_platform.h" |
| 16 #include "ui/ozone/public/system_input_injector.h" |
9 | 17 |
10 namespace remoting { | 18 namespace remoting { |
11 | 19 |
12 using protocol::ClipboardEvent; | 20 using protocol::ClipboardEvent; |
13 using protocol::KeyEvent; | 21 using protocol::KeyEvent; |
14 using protocol::MouseEvent; | 22 using protocol::MouseEvent; |
15 using protocol::TextEvent; | 23 using protocol::TextEvent; |
16 | 24 |
17 // TODO(kelvinp): Implement this class (See crbug.com/426716). | 25 namespace { |
| 26 |
| 27 ui::EventFlags MouseButtonToUIFlags(MouseEvent::MouseButton button) { |
| 28 switch (button) { |
| 29 case MouseEvent::BUTTON_LEFT: |
| 30 return ui::EF_LEFT_MOUSE_BUTTON; |
| 31 case MouseEvent::BUTTON_RIGHT: |
| 32 return ui::EF_RIGHT_MOUSE_BUTTON; |
| 33 case MouseEvent::BUTTON_MIDDLE: |
| 34 return ui::EF_MIDDLE_MOUSE_BUTTON; |
| 35 default: |
| 36 NOTREACHED(); |
| 37 return ui::EF_NONE; |
| 38 } |
| 39 } |
| 40 |
| 41 } // namespace |
| 42 |
| 43 // This class is run exclusively on the UI thread of the browser process. |
| 44 class InputInjectorChromeos::Core { |
| 45 public: |
| 46 explicit Core(scoped_ptr<ui::SystemInputInjector> delegate_); |
| 47 |
| 48 // Mirrors the public InputInjectorChromeos interface. |
| 49 void InjectClipboardEvent(const ClipboardEvent& event); |
| 50 void InjectKeyEvent(const KeyEvent& event); |
| 51 void InjectTextEvent(const TextEvent& event); |
| 52 void InjectMouseEvent(const MouseEvent& event); |
| 53 void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard); |
| 54 |
| 55 private: |
| 56 scoped_ptr<ui::SystemInputInjector> delegate_; |
| 57 scoped_ptr<Clipboard> clipboard_; |
| 58 |
| 59 // Used to rotate the input coordinates appropriately based on the current |
| 60 // display rotation settings. |
| 61 scoped_ptr<PointTransformer> point_transformer_; |
| 62 |
| 63 DISALLOW_COPY_AND_ASSIGN(Core); |
| 64 }; |
| 65 |
| 66 InputInjectorChromeos::Core::Core(scoped_ptr<ui::SystemInputInjector> delegate) |
| 67 : delegate_(delegate.Pass()), |
| 68 // Implemented by remoting::ClipboardAura. |
| 69 clipboard_(Clipboard::Create()) { |
| 70 DCHECK(delegate); |
| 71 DCHECK(clipboard_); |
| 72 } |
| 73 |
| 74 void InputInjectorChromeos::Core::InjectClipboardEvent( |
| 75 const ClipboardEvent& event) { |
| 76 clipboard_->InjectClipboardEvent(event); |
| 77 } |
| 78 |
| 79 void InputInjectorChromeos::Core::InjectKeyEvent(const KeyEvent& event) { |
| 80 DCHECK(event.has_pressed()); |
| 81 DCHECK(event.has_usb_keycode()); |
| 82 |
| 83 // TODO(kelvinp): Disable AutoRepeat as long as keys are pressed on ChromeOS |
| 84 // when the auto-repeat API is ready to avoid triggering the auto-repeat if |
| 85 // network congestion delays the key-up event from the client |
| 86 // (See crbug.com/425201). |
| 87 |
| 88 ui::DomCode dom_code = |
| 89 ui::KeycodeConverter::UsbKeycodeToDomCode(event.usb_keycode()); |
| 90 |
| 91 // Ignore events which can't be mapped. |
| 92 if (dom_code != ui::DomCode::NONE) { |
| 93 delegate_->InjectKeyPress(dom_code, event.pressed()); |
| 94 } |
| 95 } |
| 96 |
| 97 void InputInjectorChromeos::Core::InjectTextEvent(const TextEvent& event) { |
| 98 // Chrome OS only supports It2Me, which is not supported on mobile clients, so |
| 99 // we don't need to implement text events. |
| 100 NOTIMPLEMENTED(); |
| 101 } |
| 102 |
| 103 void InputInjectorChromeos::Core::InjectMouseEvent(const MouseEvent& event) { |
| 104 if (event.has_button() && event.has_button_down()) { |
| 105 delegate_->InjectMouseButton(MouseButtonToUIFlags(event.button()), |
| 106 event.button_down()); |
| 107 } else if (event.has_wheel_delta_y() || event.has_wheel_delta_x()) { |
| 108 delegate_->InjectMouseWheel(event.wheel_delta_x(), event.wheel_delta_y()); |
| 109 } else { |
| 110 DCHECK(event.has_x() && event.has_y()); |
| 111 delegate_->MoveCursorTo(point_transformer_->ToScreenCoordinates( |
| 112 gfx::PointF(event.x(), event.y()))); |
| 113 } |
| 114 } |
| 115 |
| 116 void InputInjectorChromeos::Core::Start( |
| 117 scoped_ptr<protocol::ClipboardStub> client_clipboard) { |
| 118 clipboard_->Start(client_clipboard.Pass()); |
| 119 point_transformer_.reset(new PointTransformer()); |
| 120 } |
| 121 |
18 InputInjectorChromeos::InputInjectorChromeos( | 122 InputInjectorChromeos::InputInjectorChromeos( |
19 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 123 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
20 : input_task_runner_(task_runner) { | 124 : input_task_runner_(task_runner) { |
21 NOTIMPLEMENTED(); | 125 ui::OzonePlatform* ozone_platform = ui::OzonePlatform::GetInstance(); |
| 126 core_.reset(new Core(ozone_platform->CreateSystemInputInjector())); |
22 } | 127 } |
23 | 128 |
24 InputInjectorChromeos::~InputInjectorChromeos() { | 129 InputInjectorChromeos::~InputInjectorChromeos() { |
25 NOTIMPLEMENTED(); | 130 input_task_runner_->DeleteSoon(FROM_HERE, core_.release()); |
26 } | 131 } |
27 | 132 |
28 void InputInjectorChromeos::InjectClipboardEvent(const ClipboardEvent& event) { | 133 void InputInjectorChromeos::InjectClipboardEvent(const ClipboardEvent& event) { |
29 NOTIMPLEMENTED(); | 134 input_task_runner_->PostTask( |
| 135 FROM_HERE, base::Bind(&Core::InjectClipboardEvent, |
| 136 base::Unretained(core_.get()), event)); |
30 } | 137 } |
31 | 138 |
32 void InputInjectorChromeos::InjectKeyEvent(const KeyEvent& event) { | 139 void InputInjectorChromeos::InjectKeyEvent(const KeyEvent& event) { |
33 NOTIMPLEMENTED(); | 140 input_task_runner_->PostTask( |
| 141 FROM_HERE, |
| 142 base::Bind(&Core::InjectKeyEvent, base::Unretained(core_.get()), event)); |
34 } | 143 } |
35 | 144 |
36 void InputInjectorChromeos::InjectTextEvent(const TextEvent& event) { | 145 void InputInjectorChromeos::InjectTextEvent(const TextEvent& event) { |
37 NOTIMPLEMENTED(); | 146 input_task_runner_->PostTask( |
| 147 FROM_HERE, |
| 148 base::Bind(&Core::InjectTextEvent, base::Unretained(core_.get()), event)); |
38 } | 149 } |
39 | 150 |
40 void InputInjectorChromeos::InjectMouseEvent(const MouseEvent& event) { | 151 void InputInjectorChromeos::InjectMouseEvent(const MouseEvent& event) { |
41 NOTIMPLEMENTED(); | 152 input_task_runner_->PostTask( |
| 153 FROM_HERE, base::Bind(&Core::InjectMouseEvent, |
| 154 base::Unretained(core_.get()), event)); |
42 } | 155 } |
43 | 156 |
44 void InputInjectorChromeos::Start( | 157 void InputInjectorChromeos::Start( |
45 scoped_ptr<protocol::ClipboardStub> client_clipboard) { | 158 scoped_ptr<protocol::ClipboardStub> client_clipboard) { |
46 NOTIMPLEMENTED(); | 159 input_task_runner_->PostTask( |
| 160 FROM_HERE, base::Bind(&Core::Start, base::Unretained(core_.get()), |
| 161 base::Passed(&client_clipboard))); |
47 } | 162 } |
48 | 163 |
49 // static | 164 // static |
50 scoped_ptr<InputInjector> InputInjector::Create( | 165 scoped_ptr<InputInjector> InputInjector::Create( |
51 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, | 166 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
52 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 167 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
53 scoped_ptr<InputInjectorChromeos> injector(new InputInjectorChromeos( | 168 // The Ozone input injector must be called on the UI task runner of the |
54 ui_task_runner)); | 169 // browser process. |
55 return injector.Pass(); | 170 return make_scoped_ptr(new InputInjectorChromeos(ui_task_runner)); |
56 } | 171 } |
57 | 172 |
58 } // namespace remoting | 173 } // namespace remoting |
OLD | NEW |