diff --git a/app/src/cli.c b/app/src/cli.c index d61f924c..c2b49473 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -552,9 +552,12 @@ static const struct sc_option options[] = { .longopt_id = OPT_VIRTUAL_DISPLAY, .longopt = "virtual-display", .argdesc = "properties", + .optional_arg = true, .text = "Start a new virtual display for your applications to " - "launch into. Requires Android version >= 10." - "Display size and DPI may be specified. e.g. 1920x1080dpi300" + "launch into. Requires Android version >= 10. " + "Display size and DPI may be specified. e.g. 1920x1080dpi300\n" + "Comma separated extra launch arguments may be passed to am start.\n" + "e.g. 1920x1080dpi300,-a,android.intent.action.MAIN,-n,com.android.settings/.applications.ManageApplications" }, { .shortopt = 's', @@ -2005,7 +2008,7 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], opts->su_quirk = true; break; case OPT_VIRTUAL_DISPLAY: - opts->virtual_display_params = optarg; + opts->virtual_display_params = optarg ?: ""; break; default: // getopt prints the error message on stderr diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/DisplayManager.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/DisplayManager.java index 00149264..76914548 100644 --- a/server/src/main/java/com/genymobile/scrcpy/wrappers/DisplayManager.java +++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/DisplayManager.java @@ -3,6 +3,7 @@ package com.genymobile.scrcpy.wrappers; import com.genymobile.scrcpy.Command; import com.genymobile.scrcpy.DisplayInfo; import com.genymobile.scrcpy.FakeContext; +import com.genymobile.scrcpy.IO; import com.genymobile.scrcpy.Ln; import com.genymobile.scrcpy.Size; @@ -12,7 +13,10 @@ import android.os.Build; import android.view.Display; import android.view.Surface; +import java.io.IOException; import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -29,10 +33,11 @@ public final class DisplayManager { final int VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED = 1 << 12; try { if (displayParams == null || displayParams.isEmpty()) displayParams = "1920x1080dpi300"; - String resolution = displayParams.toLowerCase().split("dpi")[0]; + String[] displayParamsArray = displayParams.split(","); + String resolution = displayParamsArray[0].toLowerCase().split("dpi")[0]; int width = Integer.parseInt(resolution.split("x")[0]); int height = Integer.parseInt(resolution.split("x")[1]); - int dpi = Integer.parseInt(displayParams.toLowerCase().split("dpi")[1]); + int dpi = Integer.parseInt(displayParamsArray[0].toLowerCase().split("dpi")[1]); android.hardware.display.DisplayManager displayManager = (android.hardware.display.DisplayManager)Class.forName("android.hardware.display.DisplayManager").getConstructor(Class.forName("android.content.Context")).newInstance(FakeContext.get()); SurfaceTexture surfaceTexture = new SurfaceTexture(false); Surface surface = new Surface(surfaceTexture); @@ -43,9 +48,26 @@ public final class DisplayManager { | android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE | VIRTUAL_DISPLAY_FLAG_TRUSTED | VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED); + Ln.i(String.format("Display: %d", display[0].getDisplay().getDisplayId())); // start launcher // TODO: replace shell commands with proper android framework api call - Command.exec("am", "start", "--user", "0", "--display", Integer.toString(display[0].getDisplay().getDisplayId()), "-a", "android.intent.action.MAIN", "-c", "android.intent.category.HOME", "-c", "android.intent.category.DEFAULT"); + String[] cmd; + if (displayParamsArray.length == 1) { + cmd = new String[]{"am", "start", "--user", "0", "--display", Integer.toString(display[0].getDisplay().getDisplayId()), "-a", "android.intent.action.MAIN", "-c", "android.intent.category.HOME", "-c", "android.intent.category.DEFAULT"}; + } + else { + ArrayList command = new ArrayList<>(Arrays.asList("am", "start", "--display", Integer.toString(display[0].getDisplay().getDisplayId()))); + command.addAll(Arrays.asList(Arrays.copyOfRange(displayParamsArray, 1, displayParamsArray.length))); + cmd = command.toArray(new String[0]); + } + Process process = Runtime.getRuntime().exec(cmd); + String output = IO.toString(process.getInputStream()); + String error = IO.toString(process.getErrorStream()); + int exitCode = process.waitFor(); + if (exitCode != 0) { + throw new IOException("Command " + Arrays.toString(cmd) + " returned with value " + exitCode); + } + Ln.i(String.format("stdout: %s\nstderr: %s", output.trim(), error.trim())); return display[0]; } catch (Exception e) { throw new AssertionError(e);