This commit is contained in:
JerryXiao 2023-09-10 01:14:00 +08:00
parent 85a9871082
commit 54fb05837a
Signed by: Jerry
GPG key ID: 22618F758B5BE2E5
2 changed files with 31 additions and 6 deletions

View file

@ -552,9 +552,12 @@ static const struct sc_option options[] = {
.longopt_id = OPT_VIRTUAL_DISPLAY, .longopt_id = OPT_VIRTUAL_DISPLAY,
.longopt = "virtual-display", .longopt = "virtual-display",
.argdesc = "properties", .argdesc = "properties",
.optional_arg = true,
.text = "Start a new virtual display for your applications to " .text = "Start a new virtual display for your applications to "
"launch into. Requires Android version >= 10." "launch into. Requires Android version >= 10. "
"Display size and DPI may be specified. e.g. 1920x1080dpi300" "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', .shortopt = 's',
@ -2005,7 +2008,7 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
opts->su_quirk = true; opts->su_quirk = true;
break; break;
case OPT_VIRTUAL_DISPLAY: case OPT_VIRTUAL_DISPLAY:
opts->virtual_display_params = optarg; opts->virtual_display_params = optarg ?: "";
break; break;
default: default:
// getopt prints the error message on stderr // getopt prints the error message on stderr

View file

@ -3,6 +3,7 @@ package com.genymobile.scrcpy.wrappers;
import com.genymobile.scrcpy.Command; import com.genymobile.scrcpy.Command;
import com.genymobile.scrcpy.DisplayInfo; import com.genymobile.scrcpy.DisplayInfo;
import com.genymobile.scrcpy.FakeContext; import com.genymobile.scrcpy.FakeContext;
import com.genymobile.scrcpy.IO;
import com.genymobile.scrcpy.Ln; import com.genymobile.scrcpy.Ln;
import com.genymobile.scrcpy.Size; import com.genymobile.scrcpy.Size;
@ -12,7 +13,10 @@ import android.os.Build;
import android.view.Display; import android.view.Display;
import android.view.Surface; import android.view.Surface;
import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -29,10 +33,11 @@ public final class DisplayManager {
final int VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED = 1 << 12; final int VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED = 1 << 12;
try { try {
if (displayParams == null || displayParams.isEmpty()) displayParams = "1920x1080dpi300"; 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 width = Integer.parseInt(resolution.split("x")[0]);
int height = Integer.parseInt(resolution.split("x")[1]); 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()); 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); SurfaceTexture surfaceTexture = new SurfaceTexture(false);
Surface surface = new Surface(surfaceTexture); Surface surface = new Surface(surfaceTexture);
@ -43,9 +48,26 @@ public final class DisplayManager {
| android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE | android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE
| VIRTUAL_DISPLAY_FLAG_TRUSTED | VIRTUAL_DISPLAY_FLAG_TRUSTED
| VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED); | VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED);
Ln.i(String.format("Display: %d", display[0].getDisplay().getDisplayId()));
// start launcher // start launcher
// TODO: replace shell commands with proper android framework api call // 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<String> 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]; return display[0];
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError(e); throw new AssertionError(e);