Usage

There are two ways to use the uinput command:

  • Recommended: uinput - reads commands from standard input until End-of-File (Ctrl+D) is sent. This mode can be used interactively from a terminal or used to control uinput from another program or app (such as the CTS tests via UinputDevice).
  • uinput <filename> reads commands from a file instead of standard input.

Command format

Input commands should be in JSON format, though the parser is in lenient mode to allow comments, and integers can be specified in hexadecimal (e.g. 0xABCD). The input file (or standard input) can contain multiple commands, which will be executed in sequence. Simply add multiple JSON objects to the file, one after the other without separators:

{
  "id": 1,
  "command": "register",
  // ...
}
{
  "id": 1,
  "command": "delay",
  // ...
}

Many examples of command files can be found in the CTS tests.

Command reference

register

Register a new uinput device

FieldTypeDescription
idintegerDevice ID
commandstringMust be set to "register"
namestringDevice name
vid16-bit integerVendor ID
pid16-bit integerProduct ID
busstringBus that device should use
portstringphys value to report
configurationobject arrayuinput device configuration
ff_effects_maxintegerff_effects_max value
abs_infoarrayAbsolute axes information

id is used for matching the subsequent commands to a specific device to avoid ambiguity when multiple devices are registered.

bus is used to determine how the uinput device is connected to the host. The options are "usb" and "bluetooth".

Device configuration is used to configure the uinput device. The type field provides a UI_SET_* control code as an integer value or a string label (e.g. "UI_SET_EVBIT"), and data is a vector of control values to be sent to the uinput device, which depends on the control code.

FieldTypeDescription
typeinteger|stringUI_SET_ control type
datainteger|string arraycontrol values

Due to the sequential nature in which this is parsed, the type field must be specified before the data field in this JSON Object.

ff_effects_max must be provided if UI_SET_FFBIT is used in configuration.

abs_info fields are provided to set the device axes information. It is an array of below objects:

FieldTypeDescription
codeinteger|stringAxis code or label
infoobjectAxis information object

The axis information object is defined as below, with the fields having the same meaning as those Linux's struct input_absinfo:

FieldTypeDescription
valueintegerLatest reported value
minimumintegerMinimum value for the axis
maximumintegerMaximum value for the axis
fuzzintegerfuzz value for noise filter
flatintegervalues to be discarded
resolutionintegerresolution of axis

Example:

{
  "id": 1,
  "command": "register",
  "name": "Keyboard (Test)",
  "vid": 0x18d2,
  "pid": 0x2c42,
  "bus": "usb",
  "configuration":[
        {"type":"UI_SET_EVBIT", "data":["EV_KEY", "EV_FF"]},
        {"type":"UI_SET_KEYBIT", "data":["KEY_0", "KEY_1", "KEY_2", "KEY_3"]},
        {"type":"UI_SET_ABSBIT", "data":["ABS_Y", "ABS_WHEEL"]},
        {"type":"UI_SET_FFBIT", "data":["FF_RUMBLE"]}
  ],
  "ff_effects_max" : 1,
  "abs_info": [
        {"code":"ABS_Y", "info": {"value":20, "minimum":-255,
                            "maximum":255, "fuzz":0, "flat":0, "resolution":1}
        },
        {"code":"ABS_WHEEL", "info": {"value":-50, "minimum":-255,
                            "maximum":255, "fuzz":0, "flat":0, "resolution":1}
        }
  ]
}

Waiting for registration

After the command is sent, there will be a delay before the device is set up by the Android input stack, and uinput does not wait for that process to finish. Any commands sent to the device during that time will be dropped. If you are controlling uinput by sending commands through standard input from an app, you need to wait for onInputDeviceAdded to be called on an InputDeviceListener before issuing commands to the device. If you are passing a file to uinput, add a delay after the register command to let registration complete. You can add a sync in certain positions, like at the end of the file to get a response when all commands have finished processing.

Unregistering the device

As soon as EOF is reached (either in interactive mode, or in file mode), the device that was created will be unregistered. There is no explicit command for unregistering a device.

delay

Add a delay to command processing

FieldTypeDescription
idintegerDevice ID
commandstringMust be set to "delay"
durationintegerDelay in milliseconds

Example:

{
  "id": 1,
  "command": "delay",
  "duration": 10
}

inject

Send an array of uinput event packets to the uinput device

FieldTypeDescription
idintegerDevice ID
commandstringMust be set to "inject"
eventsinteger|string arrayevents to inject

The events parameter is an array of integers in sets of three: a type, an axis code, and an axis value, like you'd find in Linux's struct input_event. For example, sending presses of the 0 and 1 keys would look like this:

{
  "id": 1,
  "command": "inject",
  "events": ["EV_KEY", "KEY_0", 1,
             "EV_SYN", "SYN_REPORT", 0,
             "EV_KEY", "KEY_0", 0,
             "EV_SYN", "SYN_REPORT", 0,
             "EV_KEY", "KEY_1", 1,
             "EV_SYN", "SYN_REPORT", 0,
             "EV_KEY", "KEY_1", 0,
             "EV_SYN", "SYN_REPORT", 0
            ]
}

sync

A command used to get a response once the command is processed. When several inject and delay commands are used in a row, the sync command can be used to track the progress of the command queue.

FieldTypeDescription
idintegerDevice ID
commandstringMust be set to "sync"
syncTokenstringThe token used to identify this sync command

Example:

{
  "id": 1,
  "command": "syncToken",
  "syncToken": "finished_injecting_events"
}

This command will result in the following response when it is processed:

{
  "id": 1,
  "result": "sync",
  "syncToken": "finished_injecting_events"
}

Notes

The getevent utility can used to print out the key events for debugging purposes.