1*d57664e9SAndroid Build Coastguard Worker# Usage 2*d57664e9SAndroid Build Coastguard Worker 3*d57664e9SAndroid Build Coastguard WorkerThere are two ways to use the `uinput` command: 4*d57664e9SAndroid Build Coastguard Worker 5*d57664e9SAndroid Build Coastguard Worker* **Recommended:** `uinput -` reads commands from standard input until End-of-File (Ctrl+D) is sent. 6*d57664e9SAndroid Build Coastguard Worker This mode can be used interactively from a terminal or used to control uinput from another program 7*d57664e9SAndroid Build Coastguard Worker or app (such as the CTS tests via [`UinputDevice`][UinputDevice]). 8*d57664e9SAndroid Build Coastguard Worker* `uinput <filename>` reads commands from a file instead of standard input. 9*d57664e9SAndroid Build Coastguard Worker 10*d57664e9SAndroid Build Coastguard WorkerThere are also two supported input formats, described in the sections below. The tool will 11*d57664e9SAndroid Build Coastguard Workerautomatically detect which format is being used. 12*d57664e9SAndroid Build Coastguard Worker 13*d57664e9SAndroid Build Coastguard Worker[UinputDevice]: https://cs.android.com/android/platform/superproject/main/+/main:cts/libs/input/src/com/android/cts/input/UinputDevice.java 14*d57664e9SAndroid Build Coastguard Worker 15*d57664e9SAndroid Build Coastguard Worker## evemu recording format (recommended) 16*d57664e9SAndroid Build Coastguard Worker 17*d57664e9SAndroid Build Coastguard Worker`uinput` supports the evemu format, as used by the [FreeDesktop project's evemu suite][FreeDesktop]. 18*d57664e9SAndroid Build Coastguard WorkerThis is a simple text-based format compatible with recording and replay tools on other platforms. 19*d57664e9SAndroid Build Coastguard WorkerHowever, it only supports playback of events from one device from a single recording. Recordings can 20*d57664e9SAndroid Build Coastguard Workerbe made using the `evemu-record` command on Android or other Linux-based OSes. 21*d57664e9SAndroid Build Coastguard Worker 22*d57664e9SAndroid Build Coastguard Worker[FreeDesktop]: https://gitlab.freedesktop.org/libevdev/evemu 23*d57664e9SAndroid Build Coastguard Worker 24*d57664e9SAndroid Build Coastguard Worker## JSON-like format 25*d57664e9SAndroid Build Coastguard Worker 26*d57664e9SAndroid Build Coastguard WorkerThe other supported format is JSON-based, though the parser is in [lenient mode] to allow comments, 27*d57664e9SAndroid Build Coastguard Workerand integers can be specified in hexadecimal (e.g. `0xABCD`). The input file (or standard input) can 28*d57664e9SAndroid Build Coastguard Workercontain multiple commands, which will be executed in sequence. Simply add multiple JSON objects to 29*d57664e9SAndroid Build Coastguard Workerthe file, one after the other without separators: 30*d57664e9SAndroid Build Coastguard Worker 31*d57664e9SAndroid Build Coastguard Worker```json5 32*d57664e9SAndroid Build Coastguard Worker{ 33*d57664e9SAndroid Build Coastguard Worker "id": 1, 34*d57664e9SAndroid Build Coastguard Worker "command": "register", 35*d57664e9SAndroid Build Coastguard Worker // ... 36*d57664e9SAndroid Build Coastguard Worker} 37*d57664e9SAndroid Build Coastguard Worker{ 38*d57664e9SAndroid Build Coastguard Worker "id": 1, 39*d57664e9SAndroid Build Coastguard Worker "command": "delay", 40*d57664e9SAndroid Build Coastguard Worker // ... 41*d57664e9SAndroid Build Coastguard Worker} 42*d57664e9SAndroid Build Coastguard Worker``` 43*d57664e9SAndroid Build Coastguard Worker 44*d57664e9SAndroid Build Coastguard WorkerMany examples of command files can be found [in the CTS tests][cts-example-jsons]. 45*d57664e9SAndroid Build Coastguard Worker 46*d57664e9SAndroid Build Coastguard Worker[lenient mode]: https://developer.android.com/reference/android/util/JsonReader#setLenient(boolean) 47*d57664e9SAndroid Build Coastguard Worker[cts-example-jsons]: https://cs.android.com/android/platform/superproject/main/+/main:cts/tests/tests/hardware/res/raw/ 48*d57664e9SAndroid Build Coastguard Worker 49*d57664e9SAndroid Build Coastguard Worker### Command reference 50*d57664e9SAndroid Build Coastguard Worker 51*d57664e9SAndroid Build Coastguard Worker#### `register` 52*d57664e9SAndroid Build Coastguard Worker 53*d57664e9SAndroid Build Coastguard WorkerRegister a new uinput device 54*d57664e9SAndroid Build Coastguard Worker 55*d57664e9SAndroid Build Coastguard Worker| Field | Type | Description | 56*d57664e9SAndroid Build Coastguard Worker|:----------------:|:--------------:|:-------------------------- | 57*d57664e9SAndroid Build Coastguard Worker| `id` | integer | Device ID | 58*d57664e9SAndroid Build Coastguard Worker| `command` | string | Must be set to "register" | 59*d57664e9SAndroid Build Coastguard Worker| `name` | string | Device name | 60*d57664e9SAndroid Build Coastguard Worker| `vid` | 16-bit integer | Vendor ID | 61*d57664e9SAndroid Build Coastguard Worker| `pid` | 16-bit integer | Product ID | 62*d57664e9SAndroid Build Coastguard Worker| `bus` | string | Bus that device should use | 63*d57664e9SAndroid Build Coastguard Worker| `port` | string | `phys` value to report | 64*d57664e9SAndroid Build Coastguard Worker| `configuration` | object array | uinput device configuration| 65*d57664e9SAndroid Build Coastguard Worker| `ff_effects_max` | integer | `ff_effects_max` value | 66*d57664e9SAndroid Build Coastguard Worker| `abs_info` | array | Absolute axes information | 67*d57664e9SAndroid Build Coastguard Worker 68*d57664e9SAndroid Build Coastguard Worker`id` is used for matching the subsequent commands to a specific device to avoid ambiguity when 69*d57664e9SAndroid Build Coastguard Workermultiple devices are registered. 70*d57664e9SAndroid Build Coastguard Worker 71*d57664e9SAndroid Build Coastguard Worker`bus` is used to determine how the uinput device is connected to the host. The options are `"usb"` 72*d57664e9SAndroid Build Coastguard Workerand `"bluetooth"`. 73*d57664e9SAndroid Build Coastguard Worker 74*d57664e9SAndroid Build Coastguard WorkerDevice configuration is used to configure the uinput device. The `type` field provides a `UI_SET_*` 75*d57664e9SAndroid Build Coastguard Workercontrol code as an integer value or a string label (e.g. `"UI_SET_EVBIT"`), and data is a vector of 76*d57664e9SAndroid Build Coastguard Workercontrol values to be sent to the uinput device, which depends on the control code. 77*d57664e9SAndroid Build Coastguard Worker 78*d57664e9SAndroid Build Coastguard Worker| Field | Type | Description | 79*d57664e9SAndroid Build Coastguard Worker|:-------------:|:---------------------:|:-----------------------| 80*d57664e9SAndroid Build Coastguard Worker| `type` | integer\|string | `UI_SET_` control type | 81*d57664e9SAndroid Build Coastguard Worker| `data` | integer\|string array | control values | 82*d57664e9SAndroid Build Coastguard Worker 83*d57664e9SAndroid Build Coastguard WorkerDue to the sequential nature in which this is parsed, the `type` field must be specified before 84*d57664e9SAndroid Build Coastguard Workerthe `data` field in this JSON Object. 85*d57664e9SAndroid Build Coastguard Worker 86*d57664e9SAndroid Build Coastguard WorkerEvery `register` command will need a `"UI_SET_EVBIT"` configuration entry that lists what types of 87*d57664e9SAndroid Build Coastguard Workeraxes it declares. This entry should be the first in the list. For example, if the uinput device has 88*d57664e9SAndroid Build Coastguard Worker`"UI_SET_KEYBIT"` and `"UI_SET_RELBIT"` configuration entries, it will also need a `"UI_SET_EVBIT"` 89*d57664e9SAndroid Build Coastguard Workerentry with data of `["EV_KEY", "EV_REL"]` or the other configuration entries will be ignored. 90*d57664e9SAndroid Build Coastguard Worker 91*d57664e9SAndroid Build Coastguard Worker`ff_effects_max` must be provided if `UI_SET_FFBIT` is used in `configuration`. 92*d57664e9SAndroid Build Coastguard Worker 93*d57664e9SAndroid Build Coastguard Worker`abs_info` fields are provided to set the device axes information. It is an array of below objects: 94*d57664e9SAndroid Build Coastguard Worker 95*d57664e9SAndroid Build Coastguard Worker| Field | Type | Description | 96*d57664e9SAndroid Build Coastguard Worker|:-------------:|:---------------:|:------------------------| 97*d57664e9SAndroid Build Coastguard Worker| `code` | integer\|string | Axis code or label | 98*d57664e9SAndroid Build Coastguard Worker| `info` | object | Axis information object | 99*d57664e9SAndroid Build Coastguard Worker 100*d57664e9SAndroid Build Coastguard WorkerThe axis information object is defined as below, with the fields having the same meaning as those 101*d57664e9SAndroid Build Coastguard WorkerLinux's [`struct input_absinfo`][struct input_absinfo]: 102*d57664e9SAndroid Build Coastguard Worker 103*d57664e9SAndroid Build Coastguard Worker| Field | Type | Description | 104*d57664e9SAndroid Build Coastguard Worker|:-------------:|:-------------:|:-------------------------- | 105*d57664e9SAndroid Build Coastguard Worker| `value` | integer | Latest reported value | 106*d57664e9SAndroid Build Coastguard Worker| `minimum` | integer | Minimum value for the axis | 107*d57664e9SAndroid Build Coastguard Worker| `maximum` | integer | Maximum value for the axis | 108*d57664e9SAndroid Build Coastguard Worker| `fuzz` | integer | fuzz value for noise filter| 109*d57664e9SAndroid Build Coastguard Worker| `flat` | integer | values to be discarded | 110*d57664e9SAndroid Build Coastguard Worker| `resolution` | integer | resolution of axis | 111*d57664e9SAndroid Build Coastguard Worker 112*d57664e9SAndroid Build Coastguard WorkerExample: 113*d57664e9SAndroid Build Coastguard Worker 114*d57664e9SAndroid Build Coastguard Worker```json5 115*d57664e9SAndroid Build Coastguard Worker{ 116*d57664e9SAndroid Build Coastguard Worker "id": 1, 117*d57664e9SAndroid Build Coastguard Worker "command": "register", 118*d57664e9SAndroid Build Coastguard Worker "name": "Keyboard (Test)", 119*d57664e9SAndroid Build Coastguard Worker "vid": 0x18d2, 120*d57664e9SAndroid Build Coastguard Worker "pid": 0x2c42, 121*d57664e9SAndroid Build Coastguard Worker "bus": "usb", 122*d57664e9SAndroid Build Coastguard Worker "configuration":[ 123*d57664e9SAndroid Build Coastguard Worker {"type":"UI_SET_EVBIT", "data":["EV_KEY", "EV_FF"]}, 124*d57664e9SAndroid Build Coastguard Worker {"type":"UI_SET_KEYBIT", "data":["KEY_0", "KEY_1", "KEY_2", "KEY_3"]}, 125*d57664e9SAndroid Build Coastguard Worker {"type":"UI_SET_ABSBIT", "data":["ABS_Y", "ABS_WHEEL"]}, 126*d57664e9SAndroid Build Coastguard Worker {"type":"UI_SET_FFBIT", "data":["FF_RUMBLE"]} 127*d57664e9SAndroid Build Coastguard Worker ], 128*d57664e9SAndroid Build Coastguard Worker "ff_effects_max" : 1, 129*d57664e9SAndroid Build Coastguard Worker "abs_info": [ 130*d57664e9SAndroid Build Coastguard Worker {"code":"ABS_Y", "info": {"value":20, "minimum":-255, 131*d57664e9SAndroid Build Coastguard Worker "maximum":255, "fuzz":0, "flat":0, "resolution":1} 132*d57664e9SAndroid Build Coastguard Worker }, 133*d57664e9SAndroid Build Coastguard Worker {"code":"ABS_WHEEL", "info": {"value":-50, "minimum":-255, 134*d57664e9SAndroid Build Coastguard Worker "maximum":255, "fuzz":0, "flat":0, "resolution":1} 135*d57664e9SAndroid Build Coastguard Worker } 136*d57664e9SAndroid Build Coastguard Worker ] 137*d57664e9SAndroid Build Coastguard Worker} 138*d57664e9SAndroid Build Coastguard Worker``` 139*d57664e9SAndroid Build Coastguard Worker 140*d57664e9SAndroid Build Coastguard Worker[struct input_absinfo]: https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/kernel/uapi/linux/input.h?q=%22struct%20input_absinfo%22 141*d57664e9SAndroid Build Coastguard Worker 142*d57664e9SAndroid Build Coastguard Worker##### Waiting for registration 143*d57664e9SAndroid Build Coastguard Worker 144*d57664e9SAndroid Build Coastguard WorkerAfter the command is sent, there will be a delay before the device is set up by the Android input 145*d57664e9SAndroid Build Coastguard Workerstack, and `uinput` does not wait for that process to finish. Any commands sent to the device during 146*d57664e9SAndroid Build Coastguard Workerthat time will be dropped. If you are controlling `uinput` by sending commands through standard 147*d57664e9SAndroid Build Coastguard Workerinput from an app, you need to wait for [`onInputDeviceAdded`][onInputDeviceAdded] to be called on 148*d57664e9SAndroid Build Coastguard Workeran `InputDeviceListener` before issuing commands to the device. If you are passing a file to 149*d57664e9SAndroid Build Coastguard Worker`uinput`, add a `delay` after the `register` command to let registration complete. You can add a 150*d57664e9SAndroid Build Coastguard Worker`sync` in certain positions, like at the end of the file to get a response when all commands have 151*d57664e9SAndroid Build Coastguard Workerfinished processing. 152*d57664e9SAndroid Build Coastguard Worker 153*d57664e9SAndroid Build Coastguard Worker[onInputDeviceAdded]: https://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html 154*d57664e9SAndroid Build Coastguard Worker 155*d57664e9SAndroid Build Coastguard Worker##### Unregistering the device 156*d57664e9SAndroid Build Coastguard Worker 157*d57664e9SAndroid Build Coastguard WorkerAs soon as EOF is reached (either in interactive mode, or in file mode), the device that was created 158*d57664e9SAndroid Build Coastguard Workerwill be unregistered. There is no explicit command for unregistering a device. 159*d57664e9SAndroid Build Coastguard Worker 160*d57664e9SAndroid Build Coastguard Worker#### `delay` 161*d57664e9SAndroid Build Coastguard Worker 162*d57664e9SAndroid Build Coastguard WorkerAdd a delay between the processing of commands. 163*d57664e9SAndroid Build Coastguard Worker 164*d57664e9SAndroid Build Coastguard WorkerThe delay will be timed relative to the time base, a reference time which is set when the device is 165*d57664e9SAndroid Build Coastguard Workerregistered or by the `updateTimeBase` command. Take the following set of example commands: 166*d57664e9SAndroid Build Coastguard Worker 167*d57664e9SAndroid Build Coastguard Worker1. `register` device 168*d57664e9SAndroid Build Coastguard Worker2. `delay` 500ms 169*d57664e9SAndroid Build Coastguard Worker3. `inject` some events 170*d57664e9SAndroid Build Coastguard Worker4. `delay` 10ms 171*d57664e9SAndroid Build Coastguard Worker5. `inject` more events 172*d57664e9SAndroid Build Coastguard Worker 173*d57664e9SAndroid Build Coastguard WorkerIf the `register` command is executed at time _X_, the injection at step 3 will be scheduled for 174*d57664e9SAndroid Build Coastguard Workertime _X_+500ms. Since scheduling isn't precise, they might actually be injected a few milliseconds 175*d57664e9SAndroid Build Coastguard Workerlater, but regardless of that the injection at step 5 will always be scheduled for _X_+510ms. This 176*d57664e9SAndroid Build Coastguard Workerprevents scheduling delays from building up over time and slowing down the playback of recordings. 177*d57664e9SAndroid Build Coastguard WorkerHowever, it does mean that when you expect to wait for an indeterminate period of time, you should 178*d57664e9SAndroid Build Coastguard Workersend `updateTimeBase` afterwards to prevent following events being scheduled in the past — see that 179*d57664e9SAndroid Build Coastguard Workercommand's section for an example. 180*d57664e9SAndroid Build Coastguard Worker 181*d57664e9SAndroid Build Coastguard Worker| Field | Type | Description | 182*d57664e9SAndroid Build Coastguard Worker|:-------------:|:-------------:|:-------------------------- | 183*d57664e9SAndroid Build Coastguard Worker| `id` | integer | Device ID | 184*d57664e9SAndroid Build Coastguard Worker| `command` | string | Must be set to "delay" | 185*d57664e9SAndroid Build Coastguard Worker| `duration` | integer | Delay in milliseconds | 186*d57664e9SAndroid Build Coastguard Worker 187*d57664e9SAndroid Build Coastguard WorkerExample: 188*d57664e9SAndroid Build Coastguard Worker 189*d57664e9SAndroid Build Coastguard Worker```json5 190*d57664e9SAndroid Build Coastguard Worker{ 191*d57664e9SAndroid Build Coastguard Worker "id": 1, 192*d57664e9SAndroid Build Coastguard Worker "command": "delay", 193*d57664e9SAndroid Build Coastguard Worker "duration": 10 194*d57664e9SAndroid Build Coastguard Worker} 195*d57664e9SAndroid Build Coastguard Worker``` 196*d57664e9SAndroid Build Coastguard Worker 197*d57664e9SAndroid Build Coastguard Worker#### `updateTimeBase` 198*d57664e9SAndroid Build Coastguard Worker 199*d57664e9SAndroid Build Coastguard WorkerUpdate the time base from which the following events are scheduled to the current time. When 200*d57664e9SAndroid Build Coastguard Workercontrolling `uinput` over standard input, you should send this command if you want following events 201*d57664e9SAndroid Build Coastguard Workerto be scheduled relative to now, rather than the last injection. See the following example set of 202*d57664e9SAndroid Build Coastguard Workercommands and the times they will be scheduled to run at: 203*d57664e9SAndroid Build Coastguard Worker 204*d57664e9SAndroid Build Coastguard Worker1. `register` (say this occurs at time _X_) 205*d57664e9SAndroid Build Coastguard Worker2. `delay` 500ms 206*d57664e9SAndroid Build Coastguard Worker3. `inject`: scheduled for _X_+500ms 207*d57664e9SAndroid Build Coastguard Worker4. `delay` 10ms 208*d57664e9SAndroid Build Coastguard Worker5. `inject`: scheduled for _X_+510ms 209*d57664e9SAndroid Build Coastguard Worker6. (wait a few seconds) 210*d57664e9SAndroid Build Coastguard Worker7. `updateTimeBase` (say this occurs at time _Y_) 211*d57664e9SAndroid Build Coastguard Worker8. `delay` 10ms 212*d57664e9SAndroid Build Coastguard Worker9. `inject`: scheduled for _Y_+10ms 213*d57664e9SAndroid Build Coastguard Worker 214*d57664e9SAndroid Build Coastguard WorkerWithout the `updateTimeBase` command, the final injection would be scheduled for _X_+520ms, which 215*d57664e9SAndroid Build Coastguard Workerwould be in the past. 216*d57664e9SAndroid Build Coastguard Worker 217*d57664e9SAndroid Build Coastguard WorkerThis is useful if you are issuing commands in multiple stages with long or unknown delays in between 218*d57664e9SAndroid Build Coastguard Workerthem. For example, say you have a test that does the following: 219*d57664e9SAndroid Build Coastguard Worker 220*d57664e9SAndroid Build Coastguard Worker1. `register` a device 221*d57664e9SAndroid Build Coastguard Worker2. `inject` a few events that should launch an app 222*d57664e9SAndroid Build Coastguard Worker3. Wait for the app to launch (an indeterminate amount of time, possibly seconds) 223*d57664e9SAndroid Build Coastguard Worker4. 1000 `inject` commands separated by `delay` commands of 10ms 224*d57664e9SAndroid Build Coastguard Worker 225*d57664e9SAndroid Build Coastguard WorkerWithout `updateTimeBase`, the `inject` commands of step 4 will be scheduled to start immediately 226*d57664e9SAndroid Build Coastguard Workerafter the events from step 2. That time is probably in the past, so many of the 1000 injections will 227*d57664e9SAndroid Build Coastguard Workerbe sent immediately. This will likely fill the kernel's event buffers, causing events to be dropped. 228*d57664e9SAndroid Build Coastguard WorkerSending `updateTimeBase` before the `inject` commands in step 4 will schedule them relative to the 229*d57664e9SAndroid Build Coastguard Workercurrent time, meaning that they will be all injected with the intended 10ms delays between them. 230*d57664e9SAndroid Build Coastguard Worker 231*d57664e9SAndroid Build Coastguard Worker| Field | Type | Description | 232*d57664e9SAndroid Build Coastguard Worker|:-------------:|:-------------:|:------------------------------- | 233*d57664e9SAndroid Build Coastguard Worker| `id` | integer | Device ID | 234*d57664e9SAndroid Build Coastguard Worker| `command` | string | Must be set to "updateTimeBase" | 235*d57664e9SAndroid Build Coastguard Worker 236*d57664e9SAndroid Build Coastguard Worker#### `inject` 237*d57664e9SAndroid Build Coastguard Worker 238*d57664e9SAndroid Build Coastguard WorkerSend an array of uinput event packets to the uinput device 239*d57664e9SAndroid Build Coastguard Worker 240*d57664e9SAndroid Build Coastguard Worker| Field | Type | Description | 241*d57664e9SAndroid Build Coastguard Worker|:-------------:|:---------------------:|:-------------------------- | 242*d57664e9SAndroid Build Coastguard Worker| `id` | integer | Device ID | 243*d57664e9SAndroid Build Coastguard Worker| `command` | string | Must be set to "inject" | 244*d57664e9SAndroid Build Coastguard Worker| `events` | integer\|string array | events to inject | 245*d57664e9SAndroid Build Coastguard Worker 246*d57664e9SAndroid Build Coastguard WorkerThe `events` parameter is an array of integers in sets of three: a type, an axis code, and an axis 247*d57664e9SAndroid Build Coastguard Workervalue, like you'd find in Linux's `struct input_event`. For example, sending presses of the 0 and 1 248*d57664e9SAndroid Build Coastguard Workerkeys would look like this: 249*d57664e9SAndroid Build Coastguard Worker 250*d57664e9SAndroid Build Coastguard Worker```json5 251*d57664e9SAndroid Build Coastguard Worker{ 252*d57664e9SAndroid Build Coastguard Worker "id": 1, 253*d57664e9SAndroid Build Coastguard Worker "command": "inject", 254*d57664e9SAndroid Build Coastguard Worker "events": ["EV_KEY", "KEY_0", 1, 255*d57664e9SAndroid Build Coastguard Worker "EV_SYN", "SYN_REPORT", 0, 256*d57664e9SAndroid Build Coastguard Worker "EV_KEY", "KEY_0", 0, 257*d57664e9SAndroid Build Coastguard Worker "EV_SYN", "SYN_REPORT", 0, 258*d57664e9SAndroid Build Coastguard Worker "EV_KEY", "KEY_1", 1, 259*d57664e9SAndroid Build Coastguard Worker "EV_SYN", "SYN_REPORT", 0, 260*d57664e9SAndroid Build Coastguard Worker "EV_KEY", "KEY_1", 0, 261*d57664e9SAndroid Build Coastguard Worker "EV_SYN", "SYN_REPORT", 0 262*d57664e9SAndroid Build Coastguard Worker ] 263*d57664e9SAndroid Build Coastguard Worker} 264*d57664e9SAndroid Build Coastguard Worker``` 265*d57664e9SAndroid Build Coastguard Worker 266*d57664e9SAndroid Build Coastguard Worker#### `sync` 267*d57664e9SAndroid Build Coastguard Worker 268*d57664e9SAndroid Build Coastguard WorkerA command used to get a response once the command is processed. When several `inject` and `delay` 269*d57664e9SAndroid Build Coastguard Workercommands are used in a row, the `sync` command can be used to track the progress of the command 270*d57664e9SAndroid Build Coastguard Workerqueue. 271*d57664e9SAndroid Build Coastguard Worker 272*d57664e9SAndroid Build Coastguard Worker| Field | Type | Description | 273*d57664e9SAndroid Build Coastguard Worker|:-----------:|:-------:|:---------------------------------------------| 274*d57664e9SAndroid Build Coastguard Worker| `id` | integer | Device ID | 275*d57664e9SAndroid Build Coastguard Worker| `command` | string | Must be set to "sync" | 276*d57664e9SAndroid Build Coastguard Worker| `syncToken` | string | The token used to identify this sync command | 277*d57664e9SAndroid Build Coastguard Worker 278*d57664e9SAndroid Build Coastguard WorkerExample: 279*d57664e9SAndroid Build Coastguard Worker 280*d57664e9SAndroid Build Coastguard Worker```json5 281*d57664e9SAndroid Build Coastguard Worker{ 282*d57664e9SAndroid Build Coastguard Worker "id": 1, 283*d57664e9SAndroid Build Coastguard Worker "command": "syncToken", 284*d57664e9SAndroid Build Coastguard Worker "syncToken": "finished_injecting_events" 285*d57664e9SAndroid Build Coastguard Worker} 286*d57664e9SAndroid Build Coastguard Worker``` 287*d57664e9SAndroid Build Coastguard Worker 288*d57664e9SAndroid Build Coastguard WorkerThis command will result in the following response when it is processed: 289*d57664e9SAndroid Build Coastguard Worker 290*d57664e9SAndroid Build Coastguard Worker```json5 291*d57664e9SAndroid Build Coastguard Worker{ 292*d57664e9SAndroid Build Coastguard Worker "id": 1, 293*d57664e9SAndroid Build Coastguard Worker "result": "sync", 294*d57664e9SAndroid Build Coastguard Worker "syncToken": "finished_injecting_events" 295*d57664e9SAndroid Build Coastguard Worker} 296*d57664e9SAndroid Build Coastguard Worker``` 297*d57664e9SAndroid Build Coastguard Worker 298*d57664e9SAndroid Build Coastguard Worker## Notes 299*d57664e9SAndroid Build Coastguard Worker 300*d57664e9SAndroid Build Coastguard WorkerThe `getevent` utility can used to print out the key events for debugging purposes. 301