add check for presentaion display and prompt about available display id

This commit is contained in:
evigurskiy 2020-03-21 13:42:45 +03:00
parent 1a122fcce9
commit dfdff5d720
5 changed files with 82 additions and 21 deletions

View file

@ -54,6 +54,9 @@ scrcpy_print_usage(const char *arg0) {
" -n, --no-control\n"
" Disable device control (mirror the device in read-only).\n"
"\n"
" -d, --display\n"
" Specify the display id to mirror, default 0\n"
"\n"
" -N, --no-display\n"
" Do not display device (only when screen recording is\n"
" enabled).\n"

View file

@ -2,7 +2,6 @@ package com.genymobile.scrcpy;
import com.genymobile.scrcpy.wrappers.InputManager;
import android.os.Build;
import android.os.SystemClock;
import android.view.InputDevice;
import android.view.InputEvent;
@ -11,8 +10,6 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Controller {
@ -222,10 +219,10 @@ public class Controller {
}
private boolean injectEvent(InputEvent event) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
InputManager.setDisplayId(event, device.getDisplayId());
}
return device.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
if (device.isSupportInputEvents())
return device.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
else
return false;
}
private boolean pressBackOrTurnScreenOn() {

View file

@ -1,5 +1,6 @@
package com.genymobile.scrcpy;
import com.genymobile.scrcpy.wrappers.InputManager;
import com.genymobile.scrcpy.wrappers.ServiceManager;
import com.genymobile.scrcpy.wrappers.SurfaceControl;
import com.genymobile.scrcpy.wrappers.WindowManager;
@ -22,13 +23,13 @@ public final class Device {
private final ServiceManager serviceManager = new ServiceManager();
private final int displayId;
private final DisplayInfo displayInfo;
private ScreenInfo screenInfo;
private RotationListener rotationListener;
public Device(Options options) {
displayId = options.getDisplayId();
screenInfo = computeScreenInfo(options.getCrop(), options.getMaxSize(), options.getDisplayId());
displayInfo = serviceManager.getDisplayManager().getDisplayInfo(options.getDisplayId());
screenInfo = computeScreenInfo(displayInfo, options.getCrop(), options.getMaxSize());
registerRotationWatcher(new IRotationWatcher.Stub() {
@Override
public void onRotationChanged(int rotation) throws RemoteException {
@ -42,14 +43,19 @@ public final class Device {
}
}
});
if (!displayInfo.isSupportProtectedBuffers()) {
Ln.w("Display doesn't have FLAG_SUPPORTS_PROTECTED_BUFFERS flag, mirroring can be restricted");
}
if (!isSupportInputEvents()) {
Ln.w("Input events for display with flag FLAG_PRESENTATION, can be supported since API 29");
}
}
public synchronized ScreenInfo getScreenInfo() {
return screenInfo;
}
private ScreenInfo computeScreenInfo(Rect crop, int maxSize, int displayId) {
DisplayInfo displayInfo = serviceManager.getDisplayManager().getDisplayInfo(displayId);
private ScreenInfo computeScreenInfo(DisplayInfo displayInfo, Rect crop, int maxSize) {
boolean rotated = (displayInfo.getRotation() & 1) != 0;
Size deviceSize = displayInfo.getSize();
Rect contentRect = new Rect(0, 0, deviceSize.getWidth(), deviceSize.getHeight());
@ -123,11 +129,12 @@ public final class Device {
return Build.MODEL;
}
public int getDisplayId() {
return displayId;
}
public boolean injectInputEvent(InputEvent inputEvent, int mode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
InputManager.setDisplayId(inputEvent, displayInfo.getDisplayId());
}
return serviceManager.getInputManager().injectInputEvent(inputEvent, mode);
}
@ -135,6 +142,13 @@ public final class Device {
return serviceManager.getPowerManager().isScreenOn();
}
public boolean isSupportInputEvents(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
return true;
else
return !displayInfo.isPresentation();
}
public void registerRotationWatcher(IRotationWatcher rotationWatcher) {
serviceManager.getWindowManager().registerRotationWatcher(rotationWatcher);
}

View file

@ -1,14 +1,28 @@
package com.genymobile.scrcpy;
public final class DisplayInfo {
private final int displayId;
private final Size size;
private final int rotation;
private final int layerStack;
private final int flags;
public DisplayInfo(Size size, int rotation, int layerStack) {
public static final int DEFAULT_DISPLAY = 0x00000000;
public static final int FLAG_PRESENTATION = 0x00000008;
public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 0x00000001;
public DisplayInfo(int displayId, Size size, int rotation, int layerStack, int flags) {
this.displayId = displayId;
this.size = size;
this.rotation = rotation;
this.layerStack = layerStack;
this.flags = flags;
}
public int getDisplayId() {
return displayId;
}
public Size getSize() {
@ -22,5 +36,13 @@ public final class DisplayInfo {
public int getLayerStack() {
return layerStack;
}
public boolean isPresentation() {
return (flags & FLAG_PRESENTATION) == FLAG_PRESENTATION;
}
public boolean isSupportProtectedBuffers() {
return (flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) == FLAG_SUPPORTS_PROTECTED_BUFFERS;
}
}

View file

@ -1,10 +1,11 @@
package com.genymobile.scrcpy.wrappers;
import com.genymobile.scrcpy.DisplayInfo;
import com.genymobile.scrcpy.Size;
import android.os.IInterface;
import com.genymobile.scrcpy.DisplayInfo;
import com.genymobile.scrcpy.Ln;
import com.genymobile.scrcpy.Size;
public final class DisplayManager {
private final IInterface manager;
@ -21,9 +22,33 @@ public final class DisplayManager {
int height = cls.getDeclaredField("logicalHeight").getInt(displayInfo);
int rotation = cls.getDeclaredField("rotation").getInt(displayInfo);
int layerStack = cls.getDeclaredField("layerStack").getInt(displayInfo);
return new DisplayInfo(new Size(width, height), rotation, layerStack);
int flags = cls.getDeclaredField("flags").getInt(displayInfo);
return new DisplayInfo(displayId, new Size(width, height), rotation, layerStack, flags);
} catch (Exception e) {
if (e instanceof NullPointerException) suggestFix(displayId, getDisplayIds());
throw new AssertionError(e);
}
}
public int[] getDisplayIds() {
try {
return (int[]) manager.getClass().getMethod("getDisplayIds").invoke(manager);
} catch (Exception e) {
throw new AssertionError(e);
}
}
private void suggestFix(int displayId, int[] displayIds) {
if (displayIds == null || displayIds.length == 0)
return;
StringBuilder sb = new StringBuilder();
sb.append("Failed to get displayId=[")
.append(displayId)
.append("]\nTry to user one of these available display ids:\n");
for (int id : displayIds) {
sb.append("scrcpy --display ").append(id).append("\n");
}
Ln.e(sb.toString());
}
}