mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-04-22 04:25:01 +00:00
Add fallback to get DisplayInfo
PR #3416 <https://github.com/Genymobile/scrcpy/pull/3416> Signed-off-by: Romain Vimont <rom@rom1v.com>
This commit is contained in:
parent
e5e210506f
commit
212e4fe9f1
3 changed files with 75 additions and 1 deletions
|
@ -30,4 +30,14 @@ public final class Command {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String execReadOutput(String... cmd) throws IOException, InterruptedException {
|
||||
Process process = Runtime.getRuntime().exec(cmd);
|
||||
String output = IO.toString(process.getInputStream());
|
||||
int exitCode = process.waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new IOException("Command " + Arrays.toString(cmd) + " returned with value " + exitCode);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ import android.system.OsConstants;
|
|||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Scanner;
|
||||
|
||||
public final class IO {
|
||||
private IO() {
|
||||
|
@ -37,4 +39,13 @@ public final class IO {
|
|||
public static void writeFully(FileDescriptor fd, byte[] buffer, int offset, int len) throws IOException {
|
||||
writeFully(fd, ByteBuffer.wrap(buffer, offset, len));
|
||||
}
|
||||
|
||||
public static String toString(InputStream inputStream) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Scanner scanner = new Scanner(inputStream);
|
||||
while (scanner.hasNextLine()) {
|
||||
builder.append(scanner.nextLine()).append('\n');
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
package com.genymobile.scrcpy.wrappers;
|
||||
|
||||
import com.genymobile.scrcpy.Command;
|
||||
import com.genymobile.scrcpy.DisplayInfo;
|
||||
import com.genymobile.scrcpy.Ln;
|
||||
import com.genymobile.scrcpy.Size;
|
||||
|
||||
import android.view.Display;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class DisplayManager {
|
||||
private final Object manager; // instance of hidden class android.hardware.display.DisplayManagerGlobal
|
||||
|
||||
|
@ -10,11 +18,56 @@ public final class DisplayManager {
|
|||
this.manager = manager;
|
||||
}
|
||||
|
||||
private static DisplayInfo parseDisplayInfo(String dumpsysDisplayOutput, int displayId) {
|
||||
Pattern regex = Pattern.compile(
|
||||
"^ mBaseDisplayInfo=DisplayInfo\\{\".*\", displayId " + displayId + "(, FLAG_.*)?, real ([0-9]+) x ([0-9]+).*, rotation ([0-9]+)"
|
||||
+ ".*, layerStack ([0-9]+)",
|
||||
Pattern.MULTILINE);
|
||||
Matcher m = regex.matcher(dumpsysDisplayOutput);
|
||||
if (!m.find()) {
|
||||
return null;
|
||||
}
|
||||
int flags = parseDisplayFlags(m.group(1));
|
||||
int width = Integer.parseInt(m.group(2));
|
||||
int height = Integer.parseInt(m.group(3));
|
||||
int rotation = Integer.parseInt(m.group(4));
|
||||
int layerStack = Integer.parseInt(m.group(5));
|
||||
|
||||
return new DisplayInfo(displayId, new Size(width, height), rotation, layerStack, flags);
|
||||
}
|
||||
|
||||
private static DisplayInfo getDisplayInfoFromDumpsysDisplay(int displayId) {
|
||||
try {
|
||||
String dumpsysDisplayOutput = Command.execReadOutput("dumpsys", "display");
|
||||
return parseDisplayInfo(dumpsysDisplayOutput, displayId);
|
||||
} catch (Exception e) {
|
||||
Ln.e("Could not get display info from \"dumpsys display\" output", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static int parseDisplayFlags(String text) {
|
||||
Pattern regex = Pattern.compile("FLAG_[A-Z_]+");
|
||||
Matcher m = regex.matcher(text);
|
||||
int flags = 0;
|
||||
while (m.find()) {
|
||||
String flagString = m.group();
|
||||
try {
|
||||
Field filed = Display.class.getDeclaredField(flagString);
|
||||
flags |= filed.getInt(null);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
// Silently ignore, some flags reported by "dumpsys display" are @TestApi
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
public DisplayInfo getDisplayInfo(int displayId) {
|
||||
try {
|
||||
Object displayInfo = manager.getClass().getMethod("getDisplayInfo", int.class).invoke(manager, displayId);
|
||||
if (displayInfo == null) {
|
||||
return null;
|
||||
// fallback when displayInfo is null
|
||||
return getDisplayInfoFromDumpsysDisplay(displayId);
|
||||
}
|
||||
Class<?> cls = displayInfo.getClass();
|
||||
// width and height already take the rotation into account
|
||||
|
|
Loading…
Add table
Reference in a new issue