• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         | The bus to report          |
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` specifies the bus that the kernel should report the device as being connected to. The most
72common values are `"usb"` and `"bluetooth"`, but any bus with a `BUS_…` constant in the [Linux
73kernel's input.h][input.h] can be specified using the part of its identifier after `BUS_`. For
74example, to specify the SPI bus type (`BUS_SPI` in the kernel header), use `"spi"` (or `"SPI"`,
75since it's case-insensitive).
76
77Device configuration is used to configure the uinput device. The `type` field provides a `UI_SET_*`
78control code as an integer value or a string label (e.g. `"UI_SET_EVBIT"`), and data is a vector of
79control values to be sent to the uinput device, which depends on the control code.
80
81| Field         |         Type          | Description            |
82|:-------------:|:---------------------:|:-----------------------|
83| `type`        |    integer\|string    | `UI_SET_` control type |
84| `data`        | integer\|string array | control values         |
85
86Due to the sequential nature in which this is parsed, the `type` field must be specified before
87the `data` field in this JSON Object.
88
89Every `register` command will need a `"UI_SET_EVBIT"` configuration entry that lists what types of
90axes it declares. This entry should be the first in the list. For example, if the uinput device has
91`"UI_SET_KEYBIT"` and `"UI_SET_RELBIT"` configuration entries, it will also need a `"UI_SET_EVBIT"`
92entry with data of `["EV_KEY", "EV_REL"]` or the other configuration entries will be ignored.
93
94`ff_effects_max` must be provided if `UI_SET_FFBIT` is used in `configuration`.
95
96`abs_info` fields are provided to set the device axes information. It is an array of below objects:
97
98| Field         |      Type       | Description             |
99|:-------------:|:---------------:|:------------------------|
100| `code`        | integer\|string | Axis code or label      |
101| `info`        |     object      | Axis information object |
102
103The axis information object is defined as below, with the fields having the same meaning as those
104Linux's [`struct input_absinfo`][struct input_absinfo]:
105
106| Field         | Type          | Description                |
107|:-------------:|:-------------:|:-------------------------- |
108| `value`       | integer       | Latest reported value      |
109| `minimum`     | integer       | Minimum value for the axis |
110| `maximum`     | integer       | Maximum value for the axis |
111| `fuzz`        | integer       | fuzz value for noise filter|
112| `flat`        | integer       | values to be discarded     |
113| `resolution`  | integer       | resolution of axis         |
114
115Example:
116
117```json5
118{
119  "id": 1,
120  "command": "register",
121  "name": "Keyboard (Test)",
122  "vid": 0x18d2,
123  "pid": 0x2c42,
124  "bus": "usb",
125  "configuration":[
126        {"type":"UI_SET_EVBIT", "data":["EV_KEY", "EV_FF"]},
127        {"type":"UI_SET_KEYBIT", "data":["KEY_0", "KEY_1", "KEY_2", "KEY_3"]},
128        {"type":"UI_SET_ABSBIT", "data":["ABS_Y", "ABS_WHEEL"]},
129        {"type":"UI_SET_FFBIT", "data":["FF_RUMBLE"]}
130  ],
131  "ff_effects_max" : 1,
132  "abs_info": [
133        {"code":"ABS_Y", "info": {"value":20, "minimum":-255,
134                            "maximum":255, "fuzz":0, "flat":0, "resolution":1}
135        },
136        {"code":"ABS_WHEEL", "info": {"value":-50, "minimum":-255,
137                            "maximum":255, "fuzz":0, "flat":0, "resolution":1}
138        }
139  ]
140}
141```
142
143[input.h]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/third_party/kernel/upstream/include/uapi/linux/input.h?q=BUS_
144[struct input_absinfo]: https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/kernel/uapi/linux/input.h?q=%22struct%20input_absinfo%22
145
146##### Waiting for registration
147
148After the command is sent, there will be a delay before the device is set up by the Android input
149stack, and `uinput` does not wait for that process to finish. Any commands sent to the device during
150that time will be dropped. If you are controlling `uinput` by sending commands through standard
151input from an app, you need to wait for [`onInputDeviceAdded`][onInputDeviceAdded] to be called on
152an `InputDeviceListener` before issuing commands to the device. If you are passing a file to
153`uinput`, add a `delay` after the `register` command to let registration complete. You can add a
154`sync` in certain positions, like at the end of the file to get a response when all commands have
155finished processing.
156
157[onInputDeviceAdded]: https://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
158
159##### Unregistering the device
160
161As soon as EOF is reached (either in interactive mode, or in file mode), the device that was created
162will be unregistered. There is no explicit command for unregistering a device.
163
164#### `delay`
165
166Add a delay between the processing of commands.
167
168The delay will be timed relative to the time base, a reference time which is set when the device is
169registered or by the `updateTimeBase` command. Take the following set of example commands:
170
1711. `register` device
1722. `delay` 500ms
1733. `inject` some events
1744. `delay` 10ms
1755. `inject` more events
176
177If the `register` command is executed at time _X_, the injection at step 3 will be scheduled for
178time _X_+500ms. Since scheduling isn't precise, they might actually be injected a few milliseconds
179later, but regardless of that the injection at step 5 will always be scheduled for _X_+510ms. This
180prevents scheduling delays from building up over time and slowing down the playback of recordings.
181However, it does mean that when you expect to wait for an indeterminate period of time, you should
182send `updateTimeBase` afterwards to prevent following events being scheduled in the past — see that
183command's section for an example.
184
185| Field         | Type          | Description                |
186|:-------------:|:-------------:|:-------------------------- |
187| `id`          | integer       | Device ID                  |
188| `command`     | string        | Must be set to "delay"     |
189| `duration`    | integer       | Delay in milliseconds      |
190
191Example:
192
193```json5
194{
195  "id": 1,
196  "command": "delay",
197  "duration": 10
198}
199```
200
201#### `updateTimeBase`
202
203Update the time base from which the following events are scheduled to the current time. When
204controlling `uinput` over standard input, you should send this command if you want following events
205to be scheduled relative to now, rather than the last injection. See the following example set of
206commands and the times they will be scheduled to run at:
207
2081. `register` (say this occurs at time _X_)
2092. `delay` 500ms
2103. `inject`: scheduled for _X_+500ms
2114. `delay` 10ms
2125. `inject`: scheduled for _X_+510ms
2136. (wait a few seconds)
2147. `updateTimeBase` (say this occurs at time _Y_)
2158. `delay` 10ms
2169. `inject`: scheduled for _Y_+10ms
217
218Without the `updateTimeBase` command, the final injection would be scheduled for _X_+520ms, which
219would be in the past.
220
221This is useful if you are issuing commands in multiple stages with long or unknown delays in between
222them. For example, say you have a test that does the following:
223
2241. `register` a device
2252. `inject` a few events that should launch an app
2263. Wait for the app to launch (an indeterminate amount of time, possibly seconds)
2274. 1000 `inject` commands separated by `delay` commands of 10ms
228
229Without `updateTimeBase`, the `inject` commands of step 4 will be scheduled to start immediately
230after the events from step 2. That time is probably in the past, so many of the 1000 injections will
231be sent immediately. This will likely fill the kernel's event buffers, causing events to be dropped.
232Sending `updateTimeBase` before the `inject` commands in step 4 will schedule them relative to the
233current time, meaning that they will be all injected with the intended 10ms delays between them.
234
235| Field         | Type          | Description                     |
236|:-------------:|:-------------:|:------------------------------- |
237| `id`          | integer       | Device ID                       |
238| `command`     | string        | Must be set to "updateTimeBase" |
239
240#### `inject`
241
242Send an array of uinput event packets to the uinput device
243
244| Field         |         Type          | Description                |
245|:-------------:|:---------------------:|:-------------------------- |
246| `id`          |        integer        | Device ID                  |
247| `command`     |        string         | Must be set to "inject"    |
248| `events`      | integer\|string array | events to inject           |
249
250The `events` parameter is an array of integers in sets of three: a type, an axis code, and an axis
251value, like you'd find in Linux's `struct input_event`. For example, sending presses of the 0 and 1
252keys would look like this:
253
254```json5
255{
256  "id": 1,
257  "command": "inject",
258  "events": ["EV_KEY", "KEY_0", 1,
259             "EV_SYN", "SYN_REPORT", 0,
260             "EV_KEY", "KEY_0", 0,
261             "EV_SYN", "SYN_REPORT", 0,
262             "EV_KEY", "KEY_1", 1,
263             "EV_SYN", "SYN_REPORT", 0,
264             "EV_KEY", "KEY_1", 0,
265             "EV_SYN", "SYN_REPORT", 0
266            ]
267}
268```
269
270#### `sync`
271
272A command used to get a response once the command is processed. When several `inject` and `delay`
273commands are used in a row, the `sync` command can be used to track the progress of the command
274queue.
275
276|    Field    |  Type   | Description                                  |
277|:-----------:|:-------:|:---------------------------------------------|
278|    `id`     | integer | Device ID                                    |
279|  `command`  | string  | Must be set to "sync"                        |
280| `syncToken` | string  | The token used to identify this sync command |
281
282Example:
283
284```json5
285{
286  "id": 1,
287  "command": "syncToken",
288  "syncToken": "finished_injecting_events"
289}
290```
291
292This command will result in the following response when it is processed:
293
294```json5
295{
296  "id": 1,
297  "result": "sync",
298  "syncToken": "finished_injecting_events"
299}
300```
301
302## Notes
303
304The `getevent` utility can used to print out the key events for debugging purposes.
305