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