Expose sync mode for injecting events

Expose the inject input event mode so that it is possible to wait for
the events to be "finished". This will be necessary to read the
clipboard content only after the COPY or CUT key event is handled.

PR #2834 <https://github.com/Genymobile/scrcpy/pull/2834>
This commit is contained in:
Romain Vimont 2021-11-29 21:46:29 +01:00
parent dc19ae334d
commit bfcb9d06c3
2 changed files with 26 additions and 21 deletions

View file

@ -55,7 +55,7 @@ public class Controller {
public void control() throws IOException { public void control() throws IOException {
// on start, power on the device // on start, power on the device
if (!Device.isScreenOn()) { if (!Device.isScreenOn()) {
device.pressReleaseKeycode(KeyEvent.KEYCODE_POWER); device.pressReleaseKeycode(KeyEvent.KEYCODE_POWER, Device.INJECT_MODE_ASYNC);
// dirty hack // dirty hack
// After POWER is injected, the device is powered on asynchronously. // After POWER is injected, the device is powered on asynchronously.
@ -144,7 +144,7 @@ public class Controller {
if (keepPowerModeOff && action == KeyEvent.ACTION_UP && (keycode == KeyEvent.KEYCODE_POWER || keycode == KeyEvent.KEYCODE_WAKEUP)) { if (keepPowerModeOff && action == KeyEvent.ACTION_UP && (keycode == KeyEvent.KEYCODE_POWER || keycode == KeyEvent.KEYCODE_WAKEUP)) {
schedulePowerModeOff(); schedulePowerModeOff();
} }
return device.injectKeyEvent(action, keycode, repeat, metaState); return device.injectKeyEvent(action, keycode, repeat, metaState, Device.INJECT_MODE_ASYNC);
} }
private boolean injectChar(char c) { private boolean injectChar(char c) {
@ -155,7 +155,7 @@ public class Controller {
return false; return false;
} }
for (KeyEvent event : events) { for (KeyEvent event : events) {
if (!device.injectEvent(event)) { if (!device.injectEvent(event, Device.INJECT_MODE_ASYNC)) {
return false; return false;
} }
} }
@ -219,7 +219,7 @@ public class Controller {
MotionEvent event = MotionEvent MotionEvent event = MotionEvent
.obtain(lastTouchDown, now, action, pointerCount, pointerProperties, pointerCoords, 0, buttons, 1f, 1f, DEFAULT_DEVICE_ID, 0, source, .obtain(lastTouchDown, now, action, pointerCount, pointerProperties, pointerCoords, 0, buttons, 1f, 1f, DEFAULT_DEVICE_ID, 0, source,
0); 0);
return device.injectEvent(event); return device.injectEvent(event, Device.INJECT_MODE_ASYNC);
} }
private boolean injectScroll(Position position, int hScroll, int vScroll) { private boolean injectScroll(Position position, int hScroll, int vScroll) {
@ -242,7 +242,7 @@ public class Controller {
MotionEvent event = MotionEvent MotionEvent event = MotionEvent
.obtain(lastTouchDown, now, MotionEvent.ACTION_SCROLL, 1, pointerProperties, pointerCoords, 0, 0, 1f, 1f, DEFAULT_DEVICE_ID, 0, .obtain(lastTouchDown, now, MotionEvent.ACTION_SCROLL, 1, pointerProperties, pointerCoords, 0, 0, 1f, 1f, DEFAULT_DEVICE_ID, 0,
InputDevice.SOURCE_MOUSE, 0); InputDevice.SOURCE_MOUSE, 0);
return device.injectEvent(event); return device.injectEvent(event, Device.INJECT_MODE_ASYNC);
} }
/** /**
@ -260,7 +260,7 @@ public class Controller {
private boolean pressBackOrTurnScreenOn(int action) { private boolean pressBackOrTurnScreenOn(int action) {
if (Device.isScreenOn()) { if (Device.isScreenOn()) {
return device.injectKeyEvent(action, KeyEvent.KEYCODE_BACK, 0, 0); return device.injectKeyEvent(action, KeyEvent.KEYCODE_BACK, 0, 0, Device.INJECT_MODE_ASYNC);
} }
// Screen is off // Screen is off
@ -273,7 +273,7 @@ public class Controller {
if (keepPowerModeOff) { if (keepPowerModeOff) {
schedulePowerModeOff(); schedulePowerModeOff();
} }
return device.pressReleaseKeycode(KeyEvent.KEYCODE_POWER); return device.pressReleaseKeycode(KeyEvent.KEYCODE_POWER, Device.INJECT_MODE_ASYNC);
} }
private boolean setClipboard(String text, boolean paste, long sequence) { private boolean setClipboard(String text, boolean paste, long sequence) {
@ -284,7 +284,7 @@ public class Controller {
// On Android >= 7, also press the PASTE key if requested // On Android >= 7, also press the PASTE key if requested
if (paste && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && device.supportsInputEvents()) { if (paste && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && device.supportsInputEvents()) {
device.pressReleaseKeycode(KeyEvent.KEYCODE_PASTE); device.pressReleaseKeycode(KeyEvent.KEYCODE_PASTE, Device.INJECT_MODE_ASYNC);
} }
if (sequence != ControlMessage.SEQUENCE_INVALID) { if (sequence != ControlMessage.SEQUENCE_INVALID) {

View file

@ -24,6 +24,10 @@ public final class Device {
public static final int POWER_MODE_OFF = SurfaceControl.POWER_MODE_OFF; public static final int POWER_MODE_OFF = SurfaceControl.POWER_MODE_OFF;
public static final int POWER_MODE_NORMAL = SurfaceControl.POWER_MODE_NORMAL; public static final int POWER_MODE_NORMAL = SurfaceControl.POWER_MODE_NORMAL;
public static final int INJECT_MODE_ASYNC = InputManager.INJECT_INPUT_EVENT_MODE_ASYNC;
public static final int INJECT_MODE_WAIT_FOR_RESULT = InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT;
public static final int INJECT_MODE_WAIT_FOR_FINISH = InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH;
public static final int LOCK_VIDEO_ORIENTATION_UNLOCKED = -1; public static final int LOCK_VIDEO_ORIENTATION_UNLOCKED = -1;
public static final int LOCK_VIDEO_ORIENTATION_INITIAL = -2; public static final int LOCK_VIDEO_ORIENTATION_INITIAL = -2;
@ -164,7 +168,7 @@ public final class Device {
return supportsInputEvents; return supportsInputEvents;
} }
public static boolean injectEvent(InputEvent inputEvent, int displayId) { public static boolean injectEvent(InputEvent inputEvent, int displayId, int injectMode) {
if (!supportsInputEvents(displayId)) { if (!supportsInputEvents(displayId)) {
throw new AssertionError("Could not inject input event if !supportsInputEvents()"); throw new AssertionError("Could not inject input event if !supportsInputEvents()");
} }
@ -173,30 +177,31 @@ public final class Device {
return false; return false;
} }
return SERVICE_MANAGER.getInputManager().injectInputEvent(inputEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); return SERVICE_MANAGER.getInputManager().injectInputEvent(inputEvent, injectMode);
} }
public boolean injectEvent(InputEvent event) { public boolean injectEvent(InputEvent event, int injectMode) {
return injectEvent(event, displayId); return injectEvent(event, displayId, injectMode);
} }
public static boolean injectKeyEvent(int action, int keyCode, int repeat, int metaState, int displayId) { public static boolean injectKeyEvent(int action, int keyCode, int repeat, int metaState, int displayId, int injectMode) {
long now = SystemClock.uptimeMillis(); long now = SystemClock.uptimeMillis();
KeyEvent event = new KeyEvent(now, now, action, keyCode, repeat, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, KeyEvent event = new KeyEvent(now, now, action, keyCode, repeat, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
InputDevice.SOURCE_KEYBOARD); InputDevice.SOURCE_KEYBOARD);
return injectEvent(event, displayId); return injectEvent(event, displayId, injectMode);
} }
public boolean injectKeyEvent(int action, int keyCode, int repeat, int metaState) { public boolean injectKeyEvent(int action, int keyCode, int repeat, int metaState, int injectMode) {
return injectKeyEvent(action, keyCode, repeat, metaState, displayId); return injectKeyEvent(action, keyCode, repeat, metaState, displayId, injectMode);
} }
public static boolean pressReleaseKeycode(int keyCode, int displayId) { public static boolean pressReleaseKeycode(int keyCode, int displayId, int injectMode) {
return injectKeyEvent(KeyEvent.ACTION_DOWN, keyCode, 0, 0, displayId) && injectKeyEvent(KeyEvent.ACTION_UP, keyCode, 0, 0, displayId); return injectKeyEvent(KeyEvent.ACTION_DOWN, keyCode, 0, 0, displayId, injectMode)
&& injectKeyEvent(KeyEvent.ACTION_UP, keyCode, 0, 0, displayId, injectMode);
} }
public boolean pressReleaseKeycode(int keyCode) { public boolean pressReleaseKeycode(int keyCode, int injectMode) {
return pressReleaseKeycode(keyCode, displayId); return pressReleaseKeycode(keyCode, displayId, injectMode);
} }
public static boolean isScreenOn() { public static boolean isScreenOn() {
@ -272,7 +277,7 @@ public final class Device {
if (!isScreenOn()) { if (!isScreenOn()) {
return true; return true;
} }
return pressReleaseKeycode(KeyEvent.KEYCODE_POWER, displayId); return pressReleaseKeycode(KeyEvent.KEYCODE_POWER, displayId, Device.INJECT_MODE_ASYNC);
} }
/** /**