From d613b10efcdf0d1cf76e30871e136ba0ff444e6e Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Mon, 25 May 2020 02:29:23 +0200 Subject: [PATCH] Add a new method for text injection On Android >= 7, inject text using the clipboard. This is faster and allows to inject UTF-8. --- .../com/genymobile/scrcpy/Controller.java | 4 +++ .../java/com/genymobile/scrcpy/Device.java | 27 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/Controller.java b/server/src/main/java/com/genymobile/scrcpy/Controller.java index ab7b6c40..8ea42c07 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Controller.java +++ b/server/src/main/java/com/genymobile/scrcpy/Controller.java @@ -149,6 +149,10 @@ public class Controller { } private int injectText(String text) { + if (device.injectTextPaste(text)) { + // The best method (fastest and UTF-8) worked! + return text.length(); + } int successCount = 0; for (char c : text.toCharArray()) { if (!injectChar(c)) { diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java index 3a98ebd2..a5f7bfe7 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Device.java +++ b/server/src/main/java/com/genymobile/scrcpy/Device.java @@ -186,6 +186,27 @@ public final class Device { return injectKeycode(keyCode, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); } + public boolean injectTextPaste(String text) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + return false; + } + + // On Android >= 7, we can inject UTF-8 text as follow: + // - set the clipboard + // - inject the PASTE key event + // - restore the clipboard + + String clipboardBackup = getClipboardText(); + isSettingClipboard.set(true); + + rawSetClipboardText(text); + boolean ok = injectKeycode(KeyEvent.KEYCODE_PASTE, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT); + rawSetClipboardText(clipboardBackup); + + isSettingClipboard.set(false); + return ok; + } + public boolean isScreenOn() { return serviceManager.getPowerManager().isScreenOn(); } @@ -214,9 +235,13 @@ public final class Device { return s.toString(); } + private boolean rawSetClipboardText(String text) { + return serviceManager.getClipboardManager().setText(text); + } + public boolean setClipboardText(String text) { isSettingClipboard.set(true); - boolean ok = serviceManager.getClipboardManager().setText(text); + boolean ok = rawSetClipboardText(text); isSettingClipboard.set(false); return ok; }