mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-12-17 05:24:19 +01:00
Mention physical gamepad names for UHID devices
Initialize UHID devices with a custom name: - "scrcpy: $GAMEPAD_NAME" for gamepads - "scrcpy" for keyboard and mouse (or if no gamepad name is available) The name may appear in Android apps. PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
This commit is contained in:
@@ -131,10 +131,11 @@ public final class ControlMessage {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public static ControlMessage createUhidCreate(int id, byte[] reportDesc) {
|
||||
public static ControlMessage createUhidCreate(int id, String name, byte[] reportDesc) {
|
||||
ControlMessage msg = new ControlMessage();
|
||||
msg.type = TYPE_UHID_CREATE;
|
||||
msg.id = id;
|
||||
msg.text = name;
|
||||
msg.data = reportDesc;
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -75,11 +75,16 @@ public class ControlMessageReader {
|
||||
return value;
|
||||
}
|
||||
|
||||
private String parseString() throws IOException {
|
||||
byte[] data = parseByteArray(4);
|
||||
private String parseString(int sizeBytes) throws IOException {
|
||||
assert sizeBytes > 0 && sizeBytes <= 4;
|
||||
byte[] data = parseByteArray(sizeBytes);
|
||||
return new String(data, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private String parseString() throws IOException {
|
||||
return parseString(4);
|
||||
}
|
||||
|
||||
private byte[] parseByteArray(int sizeBytes) throws IOException {
|
||||
int len = parseBufferLength(sizeBytes);
|
||||
byte[] data = new byte[len];
|
||||
@@ -134,8 +139,9 @@ public class ControlMessageReader {
|
||||
|
||||
private ControlMessage parseUhidCreate() throws IOException {
|
||||
int id = dis.readUnsignedShort();
|
||||
String name = parseString(1);
|
||||
byte[] data = parseByteArray(2);
|
||||
return ControlMessage.createUhidCreate(id, data);
|
||||
return ControlMessage.createUhidCreate(id, name, data);
|
||||
}
|
||||
|
||||
private ControlMessage parseUhidInput() throws IOException {
|
||||
|
||||
@@ -210,7 +210,7 @@ public class Controller implements AsyncProcessor {
|
||||
device.rotateDevice();
|
||||
break;
|
||||
case ControlMessage.TYPE_UHID_CREATE:
|
||||
getUhidManager().open(msg.getId(), msg.getData());
|
||||
getUhidManager().open(msg.getId(), msg.getText(), msg.getData());
|
||||
break;
|
||||
case ControlMessage.TYPE_UHID_INPUT:
|
||||
getUhidManager().writeInput(msg.getId(), msg.getData());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.genymobile.scrcpy.control;
|
||||
|
||||
import com.genymobile.scrcpy.util.Ln;
|
||||
import com.genymobile.scrcpy.util.StringUtils;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.HandlerThread;
|
||||
@@ -46,7 +47,7 @@ public final class UhidManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void open(int id, byte[] reportDesc) throws IOException {
|
||||
public void open(int id, String name, byte[] reportDesc) throws IOException {
|
||||
try {
|
||||
FileDescriptor fd = Os.open("/dev/uhid", OsConstants.O_RDWR, 0);
|
||||
try {
|
||||
@@ -56,7 +57,7 @@ public final class UhidManager {
|
||||
close(old);
|
||||
}
|
||||
|
||||
byte[] req = buildUhidCreate2Req(reportDesc);
|
||||
byte[] req = buildUhidCreate2Req(name, reportDesc);
|
||||
Os.write(fd, req, 0, req.length);
|
||||
|
||||
registerUhidListener(id, fd);
|
||||
@@ -146,7 +147,7 @@ public final class UhidManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] buildUhidCreate2Req(byte[] reportDesc) {
|
||||
private static byte[] buildUhidCreate2Req(String name, byte[] reportDesc) {
|
||||
/*
|
||||
* struct uhid_event {
|
||||
* uint32_t type;
|
||||
@@ -171,8 +172,14 @@ public final class UhidManager {
|
||||
byte[] empty = new byte[256];
|
||||
ByteBuffer buf = ByteBuffer.allocate(280 + reportDesc.length).order(ByteOrder.nativeOrder());
|
||||
buf.putInt(UHID_CREATE2);
|
||||
buf.put("scrcpy".getBytes(StandardCharsets.US_ASCII));
|
||||
buf.put(empty, 0, 256 - "scrcpy".length());
|
||||
|
||||
String actualName = name.isEmpty() ? "scrcpy" : "scrcpy: " + name;
|
||||
byte[] utf8Name = actualName.getBytes(StandardCharsets.UTF_8);
|
||||
int len = StringUtils.getUtf8TruncationIndex(utf8Name, 127);
|
||||
assert len <= 127;
|
||||
buf.put(utf8Name, 0, len);
|
||||
buf.put(empty, 0, 256 - len);
|
||||
|
||||
buf.putShort((short) reportDesc.length);
|
||||
buf.putShort(BUS_VIRTUAL);
|
||||
buf.putInt(0); // vendor id
|
||||
|
||||
@@ -324,8 +324,10 @@ public class ControlMessageReaderTest {
|
||||
DataOutputStream dos = new DataOutputStream(bos);
|
||||
dos.writeByte(ControlMessage.TYPE_UHID_CREATE);
|
||||
dos.writeShort(42); // id
|
||||
dos.writeByte(3); // name size
|
||||
dos.write("ABC".getBytes(StandardCharsets.US_ASCII));
|
||||
byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
dos.writeShort(data.length); // size
|
||||
dos.writeShort(data.length); // report desc size
|
||||
dos.write(data);
|
||||
byte[] packet = bos.toByteArray();
|
||||
|
||||
@@ -335,6 +337,7 @@ public class ControlMessageReaderTest {
|
||||
ControlMessage event = reader.read();
|
||||
Assert.assertEquals(ControlMessage.TYPE_UHID_CREATE, event.getType());
|
||||
Assert.assertEquals(42, event.getId());
|
||||
Assert.assertEquals("ABC", event.getText());
|
||||
Assert.assertArrayEquals(data, event.getData());
|
||||
|
||||
Assert.assertEquals(-1, bis.read()); // EOS
|
||||
|
||||
Reference in New Issue
Block a user