From e970b4bda38f5749d08bd100f2cc7eb3313b700e Mon Sep 17 00:00:00 2001 From: Vladimir Chebotarev Date: Thu, 10 Sep 2020 03:09:19 +0300 Subject: [PATCH] Using ADBKeyboard for injecting text. --- app/src/cli.c | 5 +++ app/src/scrcpy.c | 1 + app/src/scrcpy.h | 2 ++ app/src/server.c | 1 + app/src/server.h | 1 + .../com/genymobile/scrcpy/Controller.java | 32 +++++++++++++------ .../java/com/genymobile/scrcpy/Options.java | 9 ++++++ .../java/com/genymobile/scrcpy/Server.java | 7 ++-- 8 files changed, 46 insertions(+), 12 deletions(-) diff --git a/app/src/cli.c b/app/src/cli.c index f01b7941..de47bf8c 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -668,6 +668,7 @@ guess_record_format(const char *filename) { #define OPT_FORWARD_ALL_CLICKS 1023 #define OPT_LEGACY_PASTE 1024 #define OPT_ENCODER_NAME 1025 +#define OPT_USE_ADB_KEYBOARD 1026 bool scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { @@ -709,6 +710,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { {"show-touches", no_argument, NULL, 't'}, {"stay-awake", no_argument, NULL, 'w'}, {"turn-screen-off", no_argument, NULL, 'S'}, + {"use-adb-keyboard", no_argument, NULL, OPT_USE_ADB_KEYBOARD}, {"verbosity", required_argument, NULL, 'V'}, {"version", no_argument, NULL, 'v'}, {"window-title", required_argument, NULL, OPT_WINDOW_TITLE}, @@ -794,6 +796,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { case 'S': opts->turn_screen_off = true; break; + case OPT_USE_ADB_KEYBOARD: + opts->use_adb_keyboard = true; + break; case 't': opts->show_touches = true; break; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index a543e11c..eef5b9e6 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -320,6 +320,7 @@ scrcpy(const struct scrcpy_options *options) { .codec_options = options->codec_options, .encoder_name = options->encoder_name, .force_adb_forward = options->force_adb_forward, + .use_adb_keyboard = options->use_adb_keyboard, }; if (!server_start(&server, options->serial, ¶ms)) { return false; diff --git a/app/src/scrcpy.h b/app/src/scrcpy.h index 8548d1f7..f58fd1bf 100644 --- a/app/src/scrcpy.h +++ b/app/src/scrcpy.h @@ -82,6 +82,7 @@ struct scrcpy_options { bool forward_key_repeat; bool forward_all_clicks; bool legacy_paste; + bool use_adb_keyboard; }; #define SCRCPY_OPTIONS_DEFAULT { \ @@ -129,6 +130,7 @@ struct scrcpy_options { .forward_key_repeat = true, \ .forward_all_clicks = false, \ .legacy_paste = false, \ + .use_adb_keyboard = false, \ } bool diff --git a/app/src/server.c b/app/src/server.c index 9267356b..42a94d63 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -295,6 +295,7 @@ execute_server(struct server *server, const struct server_params *params) { params->stay_awake ? "true" : "false", params->codec_options ? params->codec_options : "-", params->encoder_name ? params->encoder_name : "-", + params->use_adb_keyboard ? "true" : "false", }; #ifdef SERVER_DEBUGGER LOGI("Server debugger waiting for a client on device port " diff --git a/app/src/server.h b/app/src/server.h index 30ce09bc..133341e7 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -59,6 +59,7 @@ struct server_params { bool show_touches; bool stay_awake; bool force_adb_forward; + bool use_adb_keyboard; }; // init default values diff --git a/server/src/main/java/com/genymobile/scrcpy/Controller.java b/server/src/main/java/com/genymobile/scrcpy/Controller.java index 84780239..4b7e362a 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Controller.java +++ b/server/src/main/java/com/genymobile/scrcpy/Controller.java @@ -20,6 +20,7 @@ public class Controller { private final Device device; private final DesktopConnection connection; + private final Options options; private final DeviceMessageSender sender; private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); @@ -31,9 +32,10 @@ public class Controller { private boolean keepPowerModeOff; - public Controller(Device device, DesktopConnection connection) { + public Controller(Device device, DesktopConnection connection, Options options) { this.device = device; this.connection = connection; + this.options = options; initPointers(); sender = new DeviceMessageSender(connection); } @@ -145,18 +147,28 @@ public class Controller { } private boolean injectChar(char c) { - String decomposed = KeyComposition.decompose(c); - char[] chars = decomposed != null ? decomposed.toCharArray() : new char[]{c}; - KeyEvent[] events = charMap.getEvents(chars); - if (events == null) { - return false; - } - for (KeyEvent event : events) { - if (!device.injectEvent(event)) { + if (options.useADBKeyboard()) { + // Process latin keys the same way in order to provide same reaction speed. + try { + Process process = Runtime.getRuntime().exec("am broadcast -a ADB_INPUT_CHARS --eia chars " + String.valueOf((int) c)); + return process.waitFor() == 0; + } catch (Throwable throwable) { return false; } + } else { + String decomposed = KeyComposition.decompose(c); + char[] chars = decomposed != null ? decomposed.toCharArray() : new char[]{c}; + KeyEvent[] events = charMap.getEvents(chars); + if (events == null) { + return false; + } + for (KeyEvent event : events) { + if (!device.injectEvent(event)) { + return false; + } + } + return true; } - return true; } private int injectText(String text) { diff --git a/server/src/main/java/com/genymobile/scrcpy/Options.java b/server/src/main/java/com/genymobile/scrcpy/Options.java index 150d06a8..c6efbe3b 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Options.java +++ b/server/src/main/java/com/genymobile/scrcpy/Options.java @@ -17,6 +17,7 @@ public class Options { private boolean stayAwake; private String codecOptions; private String encoderName; + private boolean useADBKeyboard; public Ln.Level getLogLevel() { return logLevel; @@ -129,4 +130,12 @@ public class Options { public void setEncoderName(String encoderName) { this.encoderName = encoderName; } + + public boolean useADBKeyboard() { + return useADBKeyboard; + } + + public void setUseADBKeyboard(boolean useADBKeyboard) { + this.useADBKeyboard = useADBKeyboard; + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index f501d3d8..a9ba9926 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -59,7 +59,7 @@ public final class Server { options.getEncoderName()); if (options.getControl()) { - final Controller controller = new Controller(device, connection); + final Controller controller = new Controller(device, connection, options); // asynchronous startController(controller); @@ -122,7 +122,7 @@ public final class Server { "The server version (" + BuildConfig.VERSION_NAME + ") does not match the client " + "(" + clientVersion + ")"); } - final int expectedParameters = 15; + final int expectedParameters = 16; if (args.length != expectedParameters) { throw new IllegalArgumentException("Expecting " + expectedParameters + " parameters"); } @@ -172,6 +172,9 @@ public final class Server { String encoderName = "-".equals(args[14]) ? null : args[14]; options.setEncoderName(encoderName); + boolean useADBKeyboard = Boolean.parseBoolean(args[15]); + options.setUseADBKeyboard(useADBKeyboard); + return options; }