Jorge E. Moreira | ccd5745 | 2017-09-29 15:19:07 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2017 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #include "host/frontend/vnc_server/virtual_inputs.h" |
Greg Hartman | 70ac1d2 | 2017-10-18 12:30:36 -0700 | [diff] [blame] | 18 | #include <gflags/gflags.h> |
Jorge E. Moreira | 02ccbd5 | 2018-01-25 16:57:48 -0800 | [diff] [blame] | 19 | #include <linux/input.h> |
| 20 | #include <linux/uinput.h> |
Greg Hartman | ca7fb19 | 2017-09-28 16:14:12 -0700 | [diff] [blame] | 21 | |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 22 | #include <cstdint> |
Jorge E. Moreira | 2430701 | 2017-09-22 14:35:21 -0700 | [diff] [blame] | 23 | #include <mutex> |
Jorge E. Moreira | 02ccbd5 | 2018-01-25 16:57:48 -0800 | [diff] [blame] | 24 | #include "keysyms.h" |
Greg Hartman | ca7fb19 | 2017-09-28 16:14:12 -0700 | [diff] [blame] | 25 | |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 26 | #include <common/libs/fs/shared_select.h> |
| 27 | #include <host/libs/config/cuttlefish_config.h> |
| 28 | |
Greg Hartman | 153b106 | 2017-11-11 12:09:21 -0800 | [diff] [blame] | 29 | using cvd::vnc::VirtualInputs; |
Cody Schuffelen | 134ff03 | 2019-11-22 00:25:32 -0800 | [diff] [blame^] | 30 | using vsoc::input_events::InputEventsRegionView; |
Greg Hartman | ca7fb19 | 2017-09-28 16:14:12 -0700 | [diff] [blame] | 31 | |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 32 | DEFINE_int32(touch_fd, -1, |
| 33 | "A fd for a socket where to accept touch connections"); |
| 34 | |
| 35 | DEFINE_int32(keyboard_fd, -1, |
| 36 | "A fd for a socket where to accept keyboard connections"); |
| 37 | |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 38 | DEFINE_bool(write_virtio_input, false, |
| 39 | "Whether to write the virtio_input struct over the socket"); |
| 40 | |
Greg Hartman | ca7fb19 | 2017-09-28 16:14:12 -0700 | [diff] [blame] | 41 | namespace { |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 42 | // Necessary to define here as the virtio_input.h header is not available |
| 43 | // in the host glibc. |
| 44 | struct virtio_input_event { |
| 45 | std::uint16_t type; |
| 46 | std::uint16_t code; |
| 47 | std::int32_t value; |
| 48 | }; |
| 49 | |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 50 | void AddKeyMappings(std::map<uint32_t, uint16_t>* key_mapping) { |
Jorge E. Moreira | 02ccbd5 | 2018-01-25 16:57:48 -0800 | [diff] [blame] | 51 | (*key_mapping)[cvd::xk::AltLeft] = KEY_LEFTALT; |
| 52 | (*key_mapping)[cvd::xk::ControlLeft] = KEY_LEFTCTRL; |
| 53 | (*key_mapping)[cvd::xk::ShiftLeft] = KEY_LEFTSHIFT; |
| 54 | (*key_mapping)[cvd::xk::AltRight] = KEY_RIGHTALT; |
| 55 | (*key_mapping)[cvd::xk::ControlRight] = KEY_RIGHTCTRL; |
| 56 | (*key_mapping)[cvd::xk::ShiftRight] = KEY_RIGHTSHIFT; |
| 57 | (*key_mapping)[cvd::xk::MetaLeft] = KEY_LEFTMETA; |
| 58 | (*key_mapping)[cvd::xk::MetaRight] = KEY_RIGHTMETA; |
| 59 | (*key_mapping)[cvd::xk::MultiKey] = KEY_COMPOSE; |
Greg Hartman | ca7fb19 | 2017-09-28 16:14:12 -0700 | [diff] [blame] | 60 | |
Jorge E. Moreira | 02ccbd5 | 2018-01-25 16:57:48 -0800 | [diff] [blame] | 61 | (*key_mapping)[cvd::xk::CapsLock] = KEY_CAPSLOCK; |
| 62 | (*key_mapping)[cvd::xk::NumLock] = KEY_NUMLOCK; |
| 63 | (*key_mapping)[cvd::xk::ScrollLock] = KEY_SCROLLLOCK; |
| 64 | |
| 65 | (*key_mapping)[cvd::xk::BackSpace] = KEY_BACKSPACE; |
| 66 | (*key_mapping)[cvd::xk::Tab] = KEY_TAB; |
| 67 | (*key_mapping)[cvd::xk::Return] = KEY_ENTER; |
| 68 | (*key_mapping)[cvd::xk::Escape] = KEY_ESC; |
| 69 | |
| 70 | (*key_mapping)[' '] = KEY_SPACE; |
| 71 | (*key_mapping)['!'] = KEY_1; |
| 72 | (*key_mapping)['"'] = KEY_APOSTROPHE; |
| 73 | (*key_mapping)['#'] = KEY_3; |
| 74 | (*key_mapping)['$'] = KEY_4; |
| 75 | (*key_mapping)['%'] = KEY_5; |
| 76 | (*key_mapping)['^'] = KEY_6; |
| 77 | (*key_mapping)['&'] = KEY_7; |
| 78 | (*key_mapping)['\''] = KEY_APOSTROPHE; |
| 79 | (*key_mapping)['('] = KEY_9; |
| 80 | (*key_mapping)[')'] = KEY_0; |
| 81 | (*key_mapping)['*'] = KEY_8; |
| 82 | (*key_mapping)['+'] = KEY_EQUAL; |
| 83 | (*key_mapping)[','] = KEY_COMMA; |
| 84 | (*key_mapping)['-'] = KEY_MINUS; |
| 85 | (*key_mapping)['.'] = KEY_DOT; |
| 86 | (*key_mapping)['/'] = KEY_SLASH; |
| 87 | (*key_mapping)['0'] = KEY_0; |
| 88 | (*key_mapping)['1'] = KEY_1; |
| 89 | (*key_mapping)['2'] = KEY_2; |
| 90 | (*key_mapping)['3'] = KEY_3; |
| 91 | (*key_mapping)['4'] = KEY_4; |
| 92 | (*key_mapping)['5'] = KEY_5; |
| 93 | (*key_mapping)['6'] = KEY_6; |
| 94 | (*key_mapping)['7'] = KEY_7; |
| 95 | (*key_mapping)['8'] = KEY_8; |
| 96 | (*key_mapping)['9'] = KEY_9; |
| 97 | (*key_mapping)[':'] = KEY_SEMICOLON; |
| 98 | (*key_mapping)[';'] = KEY_SEMICOLON; |
| 99 | (*key_mapping)['<'] = KEY_COMMA; |
| 100 | (*key_mapping)['='] = KEY_EQUAL; |
| 101 | (*key_mapping)['>'] = KEY_DOT; |
| 102 | (*key_mapping)['?'] = KEY_SLASH; |
| 103 | (*key_mapping)['@'] = KEY_2; |
| 104 | (*key_mapping)['A'] = KEY_A; |
| 105 | (*key_mapping)['B'] = KEY_B; |
| 106 | (*key_mapping)['C'] = KEY_C; |
| 107 | (*key_mapping)['D'] = KEY_D; |
| 108 | (*key_mapping)['E'] = KEY_E; |
| 109 | (*key_mapping)['F'] = KEY_F; |
| 110 | (*key_mapping)['G'] = KEY_G; |
| 111 | (*key_mapping)['H'] = KEY_H; |
| 112 | (*key_mapping)['I'] = KEY_I; |
| 113 | (*key_mapping)['J'] = KEY_J; |
| 114 | (*key_mapping)['K'] = KEY_K; |
| 115 | (*key_mapping)['L'] = KEY_L; |
| 116 | (*key_mapping)['M'] = KEY_M; |
| 117 | (*key_mapping)['N'] = KEY_N; |
| 118 | (*key_mapping)['O'] = KEY_O; |
| 119 | (*key_mapping)['P'] = KEY_P; |
| 120 | (*key_mapping)['Q'] = KEY_Q; |
| 121 | (*key_mapping)['R'] = KEY_R; |
| 122 | (*key_mapping)['S'] = KEY_S; |
| 123 | (*key_mapping)['T'] = KEY_T; |
| 124 | (*key_mapping)['U'] = KEY_U; |
| 125 | (*key_mapping)['V'] = KEY_V; |
| 126 | (*key_mapping)['W'] = KEY_W; |
| 127 | (*key_mapping)['X'] = KEY_X; |
| 128 | (*key_mapping)['Y'] = KEY_Y; |
| 129 | (*key_mapping)['Z'] = KEY_Z; |
| 130 | (*key_mapping)['['] = KEY_LEFTBRACE; |
| 131 | (*key_mapping)['\\'] = KEY_BACKSLASH; |
| 132 | (*key_mapping)[']'] = KEY_RIGHTBRACE; |
| 133 | (*key_mapping)['-'] = KEY_MINUS; |
| 134 | (*key_mapping)['_'] = KEY_MINUS; |
| 135 | (*key_mapping)['`'] = KEY_GRAVE; |
| 136 | (*key_mapping)['a'] = KEY_A; |
| 137 | (*key_mapping)['b'] = KEY_B; |
| 138 | (*key_mapping)['c'] = KEY_C; |
| 139 | (*key_mapping)['d'] = KEY_D; |
| 140 | (*key_mapping)['e'] = KEY_E; |
| 141 | (*key_mapping)['f'] = KEY_F; |
| 142 | (*key_mapping)['g'] = KEY_G; |
| 143 | (*key_mapping)['h'] = KEY_H; |
| 144 | (*key_mapping)['i'] = KEY_I; |
| 145 | (*key_mapping)['j'] = KEY_J; |
| 146 | (*key_mapping)['k'] = KEY_K; |
| 147 | (*key_mapping)['l'] = KEY_L; |
| 148 | (*key_mapping)['m'] = KEY_M; |
| 149 | (*key_mapping)['n'] = KEY_N; |
| 150 | (*key_mapping)['o'] = KEY_O; |
| 151 | (*key_mapping)['p'] = KEY_P; |
| 152 | (*key_mapping)['q'] = KEY_Q; |
| 153 | (*key_mapping)['r'] = KEY_R; |
| 154 | (*key_mapping)['s'] = KEY_S; |
| 155 | (*key_mapping)['t'] = KEY_T; |
| 156 | (*key_mapping)['u'] = KEY_U; |
| 157 | (*key_mapping)['v'] = KEY_V; |
| 158 | (*key_mapping)['w'] = KEY_W; |
| 159 | (*key_mapping)['x'] = KEY_X; |
| 160 | (*key_mapping)['y'] = KEY_Y; |
| 161 | (*key_mapping)['z'] = KEY_Z; |
| 162 | (*key_mapping)['{'] = KEY_LEFTBRACE; |
| 163 | (*key_mapping)['\\'] = KEY_BACKSLASH; |
| 164 | (*key_mapping)['|'] = KEY_BACKSLASH; |
| 165 | (*key_mapping)['}'] = KEY_RIGHTBRACE; |
| 166 | (*key_mapping)['~'] = KEY_GRAVE; |
| 167 | |
| 168 | (*key_mapping)[cvd::xk::F1] = KEY_F1; |
| 169 | (*key_mapping)[cvd::xk::F2] = KEY_F2; |
| 170 | (*key_mapping)[cvd::xk::F3] = KEY_F3; |
| 171 | (*key_mapping)[cvd::xk::F4] = KEY_F4; |
| 172 | (*key_mapping)[cvd::xk::F5] = KEY_F5; |
| 173 | (*key_mapping)[cvd::xk::F6] = KEY_F6; |
| 174 | (*key_mapping)[cvd::xk::F7] = KEY_F7; |
| 175 | (*key_mapping)[cvd::xk::F8] = KEY_F8; |
| 176 | (*key_mapping)[cvd::xk::F9] = KEY_F9; |
| 177 | (*key_mapping)[cvd::xk::F10] = KEY_F10; |
| 178 | (*key_mapping)[cvd::xk::F11] = KEY_F11; |
| 179 | (*key_mapping)[cvd::xk::F12] = KEY_F12; |
| 180 | (*key_mapping)[cvd::xk::F13] = KEY_F13; |
| 181 | (*key_mapping)[cvd::xk::F14] = KEY_F14; |
| 182 | (*key_mapping)[cvd::xk::F15] = KEY_F15; |
| 183 | (*key_mapping)[cvd::xk::F16] = KEY_F16; |
| 184 | (*key_mapping)[cvd::xk::F17] = KEY_F17; |
| 185 | (*key_mapping)[cvd::xk::F18] = KEY_F18; |
| 186 | (*key_mapping)[cvd::xk::F19] = KEY_F19; |
| 187 | (*key_mapping)[cvd::xk::F20] = KEY_F20; |
| 188 | (*key_mapping)[cvd::xk::F21] = KEY_F21; |
| 189 | (*key_mapping)[cvd::xk::F22] = KEY_F22; |
| 190 | (*key_mapping)[cvd::xk::F23] = KEY_F23; |
| 191 | (*key_mapping)[cvd::xk::F24] = KEY_F24; |
| 192 | |
| 193 | (*key_mapping)[cvd::xk::Keypad0] = KEY_KP0; |
| 194 | (*key_mapping)[cvd::xk::Keypad1] = KEY_KP1; |
| 195 | (*key_mapping)[cvd::xk::Keypad2] = KEY_KP2; |
| 196 | (*key_mapping)[cvd::xk::Keypad3] = KEY_KP3; |
| 197 | (*key_mapping)[cvd::xk::Keypad4] = KEY_KP4; |
| 198 | (*key_mapping)[cvd::xk::Keypad5] = KEY_KP5; |
| 199 | (*key_mapping)[cvd::xk::Keypad6] = KEY_KP6; |
| 200 | (*key_mapping)[cvd::xk::Keypad7] = KEY_KP7; |
| 201 | (*key_mapping)[cvd::xk::Keypad8] = KEY_KP8; |
| 202 | (*key_mapping)[cvd::xk::Keypad9] = KEY_KP9; |
| 203 | (*key_mapping)[cvd::xk::KeypadMultiply] = KEY_KPASTERISK; |
| 204 | (*key_mapping)[cvd::xk::KeypadSubtract] = KEY_KPMINUS; |
| 205 | (*key_mapping)[cvd::xk::KeypadAdd] = KEY_KPPLUS; |
| 206 | (*key_mapping)[cvd::xk::KeypadDecimal] = KEY_KPDOT; |
| 207 | (*key_mapping)[cvd::xk::KeypadEnter] = KEY_KPENTER; |
| 208 | (*key_mapping)[cvd::xk::KeypadDivide] = KEY_KPSLASH; |
| 209 | (*key_mapping)[cvd::xk::KeypadEqual] = KEY_KPEQUAL; |
| 210 | (*key_mapping)[cvd::xk::PlusMinus] = KEY_KPPLUSMINUS; |
| 211 | |
| 212 | (*key_mapping)[cvd::xk::SysReq] = KEY_SYSRQ; |
| 213 | (*key_mapping)[cvd::xk::LineFeed] = KEY_LINEFEED; |
| 214 | (*key_mapping)[cvd::xk::Home] = KEY_HOME; |
| 215 | (*key_mapping)[cvd::xk::Up] = KEY_UP; |
| 216 | (*key_mapping)[cvd::xk::PageUp] = KEY_PAGEUP; |
| 217 | (*key_mapping)[cvd::xk::Left] = KEY_LEFT; |
| 218 | (*key_mapping)[cvd::xk::Right] = KEY_RIGHT; |
| 219 | (*key_mapping)[cvd::xk::End] = KEY_END; |
| 220 | (*key_mapping)[cvd::xk::Down] = KEY_DOWN; |
| 221 | (*key_mapping)[cvd::xk::PageDown] = KEY_PAGEDOWN; |
| 222 | (*key_mapping)[cvd::xk::Insert] = KEY_INSERT; |
| 223 | (*key_mapping)[cvd::xk::Delete] = KEY_DELETE; |
| 224 | (*key_mapping)[cvd::xk::Pause] = KEY_PAUSE; |
| 225 | (*key_mapping)[cvd::xk::KeypadSeparator] = KEY_KPCOMMA; |
| 226 | (*key_mapping)[cvd::xk::Yen] = KEY_YEN; |
| 227 | (*key_mapping)[cvd::xk::Cancel] = KEY_STOP; |
| 228 | (*key_mapping)[cvd::xk::Redo] = KEY_AGAIN; |
| 229 | (*key_mapping)[cvd::xk::Undo] = KEY_UNDO; |
| 230 | (*key_mapping)[cvd::xk::Find] = KEY_FIND; |
| 231 | (*key_mapping)[cvd::xk::Print] = KEY_PRINT; |
| 232 | (*key_mapping)[cvd::xk::VolumeDown] = KEY_VOLUMEDOWN; |
| 233 | (*key_mapping)[cvd::xk::Mute] = KEY_MUTE; |
| 234 | (*key_mapping)[cvd::xk::VolumeUp] = KEY_VOLUMEUP; |
| 235 | (*key_mapping)[cvd::xk::Menu] = KEY_MENU; |
| 236 | (*key_mapping)[cvd::xk::VNCMenu] = KEY_MENU; |
| 237 | } |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 238 | |
| 239 | void InitInputEvent(struct input_event* evt, uint16_t type, uint16_t code, |
| 240 | int32_t value) { |
| 241 | evt->type = type; |
| 242 | evt->code = code; |
| 243 | evt->value = value; |
| 244 | } |
| 245 | |
Jorge E. Moreira | 02ccbd5 | 2018-01-25 16:57:48 -0800 | [diff] [blame] | 246 | } // namespace |
| 247 | |
Cody Schuffelen | 134ff03 | 2019-11-22 00:25:32 -0800 | [diff] [blame^] | 248 | class VSoCVirtualInputs : public VirtualInputs { |
| 249 | public: |
| 250 | VSoCVirtualInputs() |
| 251 | : input_events_region_view_{ |
| 252 | vsoc::input_events::InputEventsRegionView::GetInstance( |
| 253 | vsoc::GetDomain().c_str())} { |
| 254 | if (!input_events_region_view_) { |
| 255 | LOG(FATAL) << "Failed to open Input events region view"; |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | void GenerateKeyPressEvent(int code, bool down) override { |
| 260 | if (keymapping_.count(code)) { |
| 261 | input_events_region_view_->HandleKeyboardEvent(down, keymapping_[code]); |
| 262 | } else { |
| 263 | LOG(ERROR) << "Unknown keycode" << code; |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | void PressPowerButton(bool down) override { |
| 268 | input_events_region_view_->HandlePowerButtonEvent(down); |
| 269 | } |
| 270 | |
| 271 | void HandlePointerEvent(bool touch_down, int x, int y) override { |
| 272 | input_events_region_view_->HandleSingleTouchEvent(touch_down, x, y); |
| 273 | } |
| 274 | |
| 275 | private: |
| 276 | vsoc::input_events::InputEventsRegionView* input_events_region_view_{}; |
| 277 | }; |
| 278 | |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 279 | class SocketVirtualInputs : public VirtualInputs { |
| 280 | public: |
| 281 | SocketVirtualInputs() |
| 282 | : client_connector_([this]() { ClientConnectorLoop(); }) {} |
| 283 | |
| 284 | void GenerateKeyPressEvent(int key_code, bool down) override { |
| 285 | struct input_event events[2]; |
| 286 | InitInputEvent(&events[0], EV_KEY, keymapping_[key_code], down); |
| 287 | InitInputEvent(&events[1], EV_SYN, 0, 0); |
| 288 | |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 289 | SendEvents(keyboard_socket_, events); |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 290 | } |
| 291 | |
| 292 | void PressPowerButton(bool down) override { |
| 293 | struct input_event events[2]; |
| 294 | InitInputEvent(&events[0], EV_KEY, KEY_POWER, down); |
| 295 | InitInputEvent(&events[1], EV_SYN, 0, 0); |
| 296 | |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 297 | SendEvents(keyboard_socket_, events); |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 298 | } |
| 299 | |
| 300 | void HandlePointerEvent(bool touch_down, int x, int y) override { |
| 301 | // TODO(b/124121375): Use multitouch when available |
| 302 | struct input_event events[4]; |
| 303 | InitInputEvent(&events[0], EV_ABS, ABS_X, x); |
| 304 | InitInputEvent(&events[1], EV_ABS, ABS_Y, y); |
| 305 | InitInputEvent(&events[2], EV_KEY, BTN_TOUCH, touch_down); |
| 306 | InitInputEvent(&events[3], EV_SYN, 0, 0); |
| 307 | |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 308 | SendEvents(touch_socket_, events); |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 309 | } |
| 310 | |
| 311 | private: |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 312 | template<size_t num_events> |
| 313 | void SendEvents(cvd::SharedFD socket, struct input_event (&event_buffer)[num_events]) { |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 314 | std::lock_guard<std::mutex> lock(socket_mutex_); |
| 315 | if (!socket->IsOpen()) { |
| 316 | // This is unlikely as it would only happen between the start of the vnc |
| 317 | // server and the connection of the VMM to the socket. |
| 318 | // If it happens, just drop the events as the VM is not yet ready to |
| 319 | // handle it. |
| 320 | return; |
| 321 | } |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 322 | |
| 323 | if (FLAGS_write_virtio_input) { |
| 324 | struct virtio_input_event virtio_events[num_events]; |
| 325 | for (size_t i = 0; i < num_events; i++) { |
| 326 | virtio_events[i] = (struct virtio_input_event) { |
| 327 | .type = event_buffer[i].type, |
| 328 | .code = event_buffer[i].code, |
| 329 | .value = event_buffer[i].value, |
| 330 | }; |
| 331 | } |
| 332 | auto ret = socket->Write(virtio_events, sizeof(virtio_events)); |
| 333 | if (ret < 0) { |
| 334 | LOG(ERROR) << "Error sending input events: " << socket->StrError(); |
| 335 | } |
| 336 | } else { |
| 337 | auto ret = socket->Write(event_buffer, sizeof(event_buffer)); |
| 338 | if (ret < 0) { |
| 339 | LOG(ERROR) << "Error sending input events: " << socket->StrError(); |
| 340 | } |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 341 | } |
| 342 | } |
| 343 | |
| 344 | void ClientConnectorLoop() { |
| 345 | auto touch_server = cvd::SharedFD::Dup(FLAGS_touch_fd); |
| 346 | close(FLAGS_touch_fd); |
| 347 | FLAGS_touch_fd = -1; |
| 348 | |
| 349 | auto keyboard_server = cvd::SharedFD::Dup(FLAGS_keyboard_fd); |
| 350 | close(FLAGS_keyboard_fd); |
| 351 | FLAGS_keyboard_fd = -1; |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 352 | LOG(INFO) << "Input socket host accepting connections..."; |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 353 | |
| 354 | while (1) { |
| 355 | cvd::SharedFDSet read_set; |
| 356 | read_set.Set(touch_server); |
| 357 | read_set.Set(keyboard_server); |
| 358 | cvd::Select(&read_set, nullptr, nullptr, nullptr); |
| 359 | { |
| 360 | std::lock_guard<std::mutex> lock(socket_mutex_); |
| 361 | if (read_set.IsSet(touch_server)) { |
| 362 | touch_socket_ = cvd::SharedFD::Accept(*touch_server); |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 363 | LOG(INFO) << "connected to touch"; |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 364 | } |
| 365 | if (read_set.IsSet(keyboard_server)) { |
| 366 | keyboard_socket_ = cvd::SharedFD::Accept(*keyboard_server); |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 367 | LOG(INFO) << "connected to keyboard"; |
Jorge E. Moreira | c87c2c7 | 2019-03-06 16:12:23 -0800 | [diff] [blame] | 368 | } |
| 369 | } |
| 370 | } |
| 371 | } |
| 372 | cvd::SharedFD touch_socket_; |
| 373 | cvd::SharedFD keyboard_socket_; |
| 374 | std::thread client_connector_; |
| 375 | std::mutex socket_mutex_; |
| 376 | }; |
| 377 | |
| 378 | VirtualInputs::VirtualInputs() { AddKeyMappings(&keymapping_); } |
| 379 | |
| 380 | VirtualInputs* VirtualInputs::Get() { |
Cody Schuffelen | 038d4d9 | 2019-11-04 15:09:03 -0800 | [diff] [blame] | 381 | return new SocketVirtualInputs(); |
Jorge E. Moreira | 2430701 | 2017-09-22 14:35:21 -0700 | [diff] [blame] | 382 | } |