Add UHID gamepad support

Similar to UHID keyboard and mouse, but for gamepads.

Can be enabled with --gamepad=uhid or -G.

It is not enabled by default because not all devices support UHID
(there is a permission error on old Android versions).

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
This commit is contained in:
Romain Vimont
2024-09-06 23:08:08 +02:00
parent 64a25f6e9d
commit f9d1a333a0
11 changed files with 200 additions and 8 deletions

View File

@@ -215,6 +215,9 @@ public class Controller implements AsyncProcessor {
case ControlMessage.TYPE_UHID_INPUT:
getUhidManager().writeInput(msg.getId(), msg.getData());
break;
case ControlMessage.TYPE_UHID_DESTROY:
getUhidManager().close(msg.getId());
break;
case ControlMessage.TYPE_OPEN_HARD_KEYBOARD_SETTINGS:
openHardKeyboardSettings();
break;

View File

@@ -95,6 +95,12 @@ public final class UhidManager {
}
}
private void unregisterUhidListener(FileDescriptor fd) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
queue.removeOnFileDescriptorEventListener(fd);
}
}
private static byte[] extractHidOutputData(ByteBuffer buffer) {
/*
* #define UHID_DATA_MAX 4096
@@ -199,9 +205,15 @@ public final class UhidManager {
}
public void close(int id) {
FileDescriptor fd = fds.get(id);
assert fd != null;
close(fd);
// Linux: Documentation/hid/uhid.rst
// If you close() the fd, the device is automatically unregistered and destroyed internally.
FileDescriptor fd = fds.remove(id);
if (fd != null) {
unregisterUhidListener(fd);
close(fd);
} else {
Ln.w("Closing unknown UHID device: " + id);
}
}
public void closeAll() {