Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
54fb05837a |
2 changed files with 31 additions and 6 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue