From 40febf4a91f0d9c9d9e1a6390930639b3bf5a70e Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sun, 14 Mar 2021 18:03:42 +0100 Subject: [PATCH] Use device id 0 for touch/mouse events Virtual device is only for keyboard sources, not mouse or touchscreen sources. Here is the value of InputDevice.getDevice(-1).toString(): Input Device -1: Virtual Descriptor: ... Generation: 2 Location: built-in Keyboard Type: alphabetic Has Vibrator: false Has mic: false Sources: 0x301 ( keyboard dpad ) InputDevice.getDeviceId() documentation says: > An id of zero indicates that the event didn't come from a physical > device and maps to the default keymap. However, injecting events with a device id of 0 causes event.getDevice() to be null on the client-side. Commit 26529d377fe8aae2fd1ffa91405aa801a0ce8a57 used -1 as a workaround to avoid a NPE on a specific Android TV device. But this is a bug in the device system, which wrongly assumes that input device may not be null. A similar issue was present in Flutter, but it is now fixed: - - On the other hand, using an id of -1 for touchscreen events (which is invalid) causes issues for some apps: Therefore, use a device id of 0. An alternative could be to find an existing device matching the source, like "adb shell input" does. See getInputDeviceId(): But it seems better to indicate that the event didn't come from a physical device, and it would not solve #962 anyway, because an Android TV has no touchscreen. Refs #962 Fixes #2125 --- server/src/main/java/com/genymobile/scrcpy/Controller.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/Controller.java b/server/src/main/java/com/genymobile/scrcpy/Controller.java index d8059b43..2c5a1277 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Controller.java +++ b/server/src/main/java/com/genymobile/scrcpy/Controller.java @@ -14,7 +14,7 @@ import java.util.concurrent.TimeUnit; public class Controller { - private static final int DEVICE_ID_VIRTUAL = -1; + private static final int DEFAULT_DEVICE_ID = 0; private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor(); @@ -210,7 +210,7 @@ public class Controller { int source = nonPrimaryButtonPressed ? InputDevice.SOURCE_MOUSE : InputDevice.SOURCE_TOUCHSCREEN; MotionEvent event = MotionEvent - .obtain(lastTouchDown, now, action, pointerCount, pointerProperties, pointerCoords, 0, buttons, 1f, 1f, DEVICE_ID_VIRTUAL, 0, source, + .obtain(lastTouchDown, now, action, pointerCount, pointerProperties, pointerCoords, 0, buttons, 1f, 1f, DEFAULT_DEVICE_ID, 0, source, 0); return device.injectEvent(event); } @@ -233,7 +233,7 @@ public class Controller { coords.setAxisValue(MotionEvent.AXIS_VSCROLL, vScroll); MotionEvent event = MotionEvent - .obtain(lastTouchDown, now, MotionEvent.ACTION_SCROLL, 1, pointerProperties, pointerCoords, 0, 0, 1f, 1f, DEVICE_ID_VIRTUAL, 0, + .obtain(lastTouchDown, now, MotionEvent.ACTION_SCROLL, 1, pointerProperties, pointerCoords, 0, 0, 1f, 1f, DEFAULT_DEVICE_ID, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); return device.injectEvent(event); }