Skip to content

Commit

Permalink
Add support for USB HID keyboard over AOAv2
Browse files Browse the repository at this point in the history
This provides a better input experience, by simulating a physical
keyboard. It converts SDL keyboard events to proper HID events, and send
them over AOAv2.

This is a rewriting and bugfix of the origin code from @amosbird:
<#279 (comment)>

The feature is enabled the command line option -K or --keyboard-hid, and
is only available on Linux, over USB.

Refs <https://source.android.com/devices/accessories/aoa2#hid-support>
Refs <https://www.usb.org/sites/default/files/hid1_11.pdf>

Signed-off-by: Romain Vimont <rom@rom1v.com>
  • Loading branch information
AlynxZhou authored and rom1v committed Oct 21, 2021
1 parent 9d63ca5 commit 76b88ca
Show file tree
Hide file tree
Showing 11 changed files with 945 additions and 13 deletions.
10 changes: 6 additions & 4 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ First, you need to install the required packages:
# for Debian/Ubuntu
sudo apt install ffmpeg libsdl2-2.0-0 adb wget \
gcc git pkg-config meson ninja-build libsdl2-dev \
libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev
libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev \
libusb-1.0-0 libusb-dev
```

Then clone the repo and execute the installation script
Expand Down Expand Up @@ -88,11 +89,12 @@ Install the required packages from your package manager.

```bash
# runtime dependencies
sudo apt install ffmpeg libsdl2-2.0-0 adb
sudo apt install ffmpeg libsdl2-2.0-0 adb libusb-1.0-0

# client build dependencies
sudo apt install gcc git pkg-config meson ninja-build libsdl2-dev \
libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev
libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev \
libusb-dev

# server build dependencies
sudo apt install openjdk-11-jdk
Expand All @@ -114,7 +116,7 @@ pip3 install meson
sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm

# client build dependencies
sudo dnf install SDL2-devel ffms2-devel meson gcc make
sudo dnf install SDL2-devel ffms2-devel libusb-devel meson gcc make

# server build dependencies
sudo dnf install java-devel
Expand Down
45 changes: 43 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,43 @@ content (if supported by the app) relative to the center of the screen.
Concretely, scrcpy generates additional touch events from a "virtual finger" at
a location inverted through the center of the screen.

#### Text injection

#### Text injection preference
Scrcpy supports two keyboard input methods:
- default Android key or text injection: it works everywhere, but is
limited to ASCII.
- physical keyboard simulation(USB HID over AOAv2): provides a better
experience (virtual keyboard disabled, works for non-ASCII characters and
IME), but only over USB, and currently only supported on Linux.

##### Physical keyboard simulation

On Linux, scrcpy can simulate a USB physical keyboard on Android to provide a
better input experience (using [HID over AOAv2]).

[hid-aoav2]: https://source.android.com/devices/accessories/aoa2#hid-support

To enable this mode:

```bash
scrcpy --keyboard-hid
scrcpy -K # short version
```

If it fails for some reason (for example because the device is not connected via
USB), it automatically fallbacks to the default mode (with a log in the
console). This allows to use the same command line options when connected over
USB and TCP/IP.

In this mode, raw key events (scancodes) are sent to the device, independently
of the host key mapping. Therefore, if your keyboard layout does not match, it
must be configured on the Android device, in Settings → System → Languages and
input → [Physical keyboard].

[Physical keyboard]: https://github.com/Genymobile/scrcpy/pull/2632#issuecomment-923756915


##### Text injection preference

There are two kinds of [events][textevents] generated when typing text:
- _key events_, signaling that a key is pressed or released;
Expand All @@ -690,11 +725,14 @@ scrcpy --prefer-text

(but this will break keyboard behavior in games)

This option has no effect on HID keyboard (all key events are sent as
scancodes in this mode).

[textevents]: https://blog.rom1v.com/2018/03/introducing-scrcpy/#handle-text-input
[prefertext]: https://github.com/Genymobile/scrcpy/issues/650#issuecomment-512945343


#### Key repeat
##### Key repeat

By default, holding a key down generates repeated key events. This can cause
performance problems in some games, where these events are useless anyway.
Expand All @@ -705,6 +743,9 @@ To avoid forwarding repeated key events:
scrcpy --no-key-repeat
```

This option has no effect on HID keyboard (key repeat is handled by Android
directly in this mode).


#### Right-click and middle-click

Expand Down
16 changes: 15 additions & 1 deletion app/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ if v4l2_support
src += [ 'src/v4l2_sink.c' ]
endif

aoa_hid_support = host_machine.system() == 'linux'
if aoa_hid_support
src += [
'src/aoa_hid.c',
'src/hid_keyboard.c',
]
endif

check_functions = [
'strdup'
]
Expand All @@ -62,8 +70,11 @@ if not get_option('crossbuild_windows')
dependencies += dependency('libavdevice')
endif

else
if aoa_hid_support
dependencies += dependency('libusb-1.0')
endif

else
# cross-compile mingw32 build (from Linux to Windows)
prebuilt_sdl2 = meson.get_cross_property('prebuilt_sdl2')
sdl2_bin_dir = meson.current_source_dir() + '/../prebuilt-deps/' + prebuilt_sdl2 + '/bin'
Expand Down Expand Up @@ -140,6 +151,9 @@ conf.set('SERVER_DEBUGGER_METHOD_NEW', get_option('server_debugger_method') == '
# enable V4L2 support (linux only)
conf.set('HAVE_V4L2', v4l2_support)

# enable HID over AOA support (linux only)
conf.set('HAVE_AOA_HID', aoa_hid_support)

configure_file(configuration: conf, output: 'config.h')

src_dir = include_directories('src')
Expand Down
8 changes: 8 additions & 0 deletions app/scrcpy.1
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ Start in fullscreen.
.B \-h, \-\-help
Print this help.

.TP
.B \-K, \-\-keyboard\-hid
Simulate a physical keyboard by using HID over AOAv2.

This provides a better experience for IME users, and allows to generate non-ASCII characters, contrary to the default injection method.

It may only work over USB, and is currently only supported on Linux.

.TP
.B \-\-legacy\-paste
Inject computer clipboard text as a sequence of key events on Ctrl+v (like MOD+Shift+v).
Expand Down
Loading

0 comments on commit 76b88ca

Please sign in to comment.