From 63b60440fdd223f8fe42b791fd64c9d8a9d9c0f3 Mon Sep 17 00:00:00 2001 From: Alex Burdusel Date: Sun, 21 Nov 2021 21:39:47 +0200 Subject: [PATCH] Inject text via ADB keyboard as fallback to injecting key event --- .../com/genymobile/scrcpy/Controller.java | 10 ++++- .../java/com/genymobile/scrcpy/Device.java | 37 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/Controller.java b/server/src/main/java/com/genymobile/scrcpy/Controller.java index 481c512fc4..614f7de6a6 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Controller.java +++ b/server/src/main/java/com/genymobile/scrcpy/Controller.java @@ -165,11 +165,17 @@ private int injectText(String text) { int successCount = 0; for (char c : text.toCharArray()) { if (!injectChar(c)) { - Ln.w("Could not inject char u+" + String.format("%04x", (int) c)); - continue; + continue; } successCount++; } + if (successCount == 0) { + if (device.injectViaAdbKeyboard(text)) { + return text.length(); + } else { + Ln.w("Could not inject text " + text); + } + } return successCount; } diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java index 763a7fadbd..4469ccf123 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Device.java +++ b/server/src/main/java/com/genymobile/scrcpy/Device.java @@ -17,6 +17,9 @@ import android.view.KeyCharacterMap; import android.view.KeyEvent; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; public final class Device { @@ -210,6 +213,40 @@ public boolean injectKeyEvent(int action, int keyCode, int repeat, int metaState return injectKeyEvent(action, keyCode, repeat, metaState, displayId, injectMode); } + /** + * @param text the text to inject via ADB Keyboard + * @return true if the text was successfully injected, false otherwise + */ + public boolean injectViaAdbKeyboard(String text) { + try { + Runtime runtime = Runtime.getRuntime(); + Process checkImeProc = runtime.exec("settings get secure default_input_method"); + String selectedIme = null; + try (BufferedReader checkImeInput = new BufferedReader( + new InputStreamReader(checkImeProc.getInputStream()))) { + String line; + while ((line = checkImeInput.readLine()) != null) { + if (selectedIme != null) { + Ln.e("Found multiple IME"); + return false; + } + selectedIme = line; + } + } + if (Objects.equals(selectedIme, "com.android.adbkeyboard/.AdbIME")) { + Process broadcastProc = runtime.exec( + "am broadcast -a ADB_INPUT_TEXT --es msg " + text); + return broadcastProc.waitFor() == 0; + } else { + Ln.i("ADB Keyboard needs to be installed and selected as default input to send text through it"); + } + return false; + } catch (Throwable throwable) { + Ln.e("Encountered error while trying ti send char through IME", throwable); + return false; + } + } + public static boolean pressReleaseKeycode(int keyCode, int displayId, int injectMode) { return injectKeyEvent(KeyEvent.ACTION_DOWN, keyCode, 0, 0, displayId, injectMode) && injectKeyEvent(KeyEvent.ACTION_UP, keyCode, 0, 0, displayId, injectMode);