xref: /aosp_15_r20/frameworks/base/cmds/uinput/README.md (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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