mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-02 22:29:25 +00:00
add check for presentaion display and prompt about available display id
This commit is contained in:
parent
749e614665
commit
5353dabc9a
5 changed files with 79 additions and 17 deletions
|
@ -60,6 +60,9 @@ scrcpy_print_usage(const char *arg0) {
|
||||||
" -n, --no-control\n"
|
" -n, --no-control\n"
|
||||||
" Disable device control (mirror the device in read-only).\n"
|
" Disable device control (mirror the device in read-only).\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
" -d, --display\n"
|
||||||
|
" Specify the display id to mirror, default 0\n"
|
||||||
|
"\n"
|
||||||
" -N, --no-display\n"
|
" -N, --no-display\n"
|
||||||
" Do not display device (only when screen recording is\n"
|
" Do not display device (only when screen recording is\n"
|
||||||
" enabled).\n"
|
" enabled).\n"
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.genymobile.scrcpy;
|
||||||
|
|
||||||
import com.genymobile.scrcpy.wrappers.InputManager;
|
import com.genymobile.scrcpy.wrappers.InputManager;
|
||||||
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.view.InputDevice;
|
import android.view.InputDevice;
|
||||||
import android.view.InputEvent;
|
import android.view.InputEvent;
|
||||||
|
@ -11,8 +10,6 @@ import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public class Controller {
|
public class Controller {
|
||||||
|
|
||||||
|
@ -222,10 +219,10 @@ public class Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean injectEvent(InputEvent event) {
|
private boolean injectEvent(InputEvent event) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
|
if (device.isSupportInputEvents())
|
||||||
InputManager.setDisplayId(event, device.getDisplayId());
|
return device.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
|
||||||
}
|
else
|
||||||
return device.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean pressBackOrTurnScreenOn() {
|
private boolean pressBackOrTurnScreenOn() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.genymobile.scrcpy;
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
|
import com.genymobile.scrcpy.wrappers.InputManager;
|
||||||
import com.genymobile.scrcpy.wrappers.ServiceManager;
|
import com.genymobile.scrcpy.wrappers.ServiceManager;
|
||||||
import com.genymobile.scrcpy.wrappers.SurfaceControl;
|
import com.genymobile.scrcpy.wrappers.SurfaceControl;
|
||||||
import com.genymobile.scrcpy.wrappers.WindowManager;
|
import com.genymobile.scrcpy.wrappers.WindowManager;
|
||||||
|
@ -22,7 +23,7 @@ public final class Device {
|
||||||
|
|
||||||
private final ServiceManager serviceManager = new ServiceManager();
|
private final ServiceManager serviceManager = new ServiceManager();
|
||||||
|
|
||||||
private final int displayId;
|
private final DisplayInfo displayInfo;
|
||||||
private ScreenInfo screenInfo;
|
private ScreenInfo screenInfo;
|
||||||
private RotationListener rotationListener;
|
private RotationListener rotationListener;
|
||||||
|
|
||||||
|
@ -42,6 +43,12 @@ 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() {
|
public synchronized ScreenInfo getScreenInfo() {
|
||||||
|
@ -77,11 +84,12 @@ public final class Device {
|
||||||
return Build.MODEL;
|
return Build.MODEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDisplayId() {
|
|
||||||
return displayId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean injectInputEvent(InputEvent inputEvent, int mode) {
|
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);
|
return serviceManager.getInputManager().injectInputEvent(inputEvent, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +97,13 @@ public final class Device {
|
||||||
return serviceManager.getPowerManager().isScreenOn();
|
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) {
|
public void registerRotationWatcher(IRotationWatcher rotationWatcher) {
|
||||||
serviceManager.getWindowManager().registerRotationWatcher(rotationWatcher);
|
serviceManager.getWindowManager().registerRotationWatcher(rotationWatcher);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,28 @@
|
||||||
package com.genymobile.scrcpy;
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
public final class DisplayInfo {
|
public final class DisplayInfo {
|
||||||
|
private final int displayId;
|
||||||
private final Size size;
|
private final Size size;
|
||||||
private final int rotation;
|
private final int rotation;
|
||||||
private final int layerStack;
|
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.size = size;
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
this.layerStack = layerStack;
|
this.layerStack = layerStack;
|
||||||
|
this.flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDisplayId() {
|
||||||
|
return displayId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Size getSize() {
|
public Size getSize() {
|
||||||
|
@ -22,5 +36,13 @@ public final class DisplayInfo {
|
||||||
public int getLayerStack() {
|
public int getLayerStack() {
|
||||||
return layerStack;
|
return layerStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPresentation() {
|
||||||
|
return (flags & FLAG_PRESENTATION) == FLAG_PRESENTATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSupportProtectedBuffers() {
|
||||||
|
return (flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) == FLAG_SUPPORTS_PROTECTED_BUFFERS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package com.genymobile.scrcpy.wrappers;
|
package com.genymobile.scrcpy.wrappers;
|
||||||
|
|
||||||
import com.genymobile.scrcpy.DisplayInfo;
|
|
||||||
import com.genymobile.scrcpy.Size;
|
|
||||||
|
|
||||||
import android.os.IInterface;
|
import android.os.IInterface;
|
||||||
|
|
||||||
|
import com.genymobile.scrcpy.DisplayInfo;
|
||||||
|
import com.genymobile.scrcpy.Ln;
|
||||||
|
import com.genymobile.scrcpy.Size;
|
||||||
|
|
||||||
public final class DisplayManager {
|
public final class DisplayManager {
|
||||||
private final IInterface manager;
|
private final IInterface manager;
|
||||||
|
|
||||||
|
@ -21,9 +22,33 @@ public final class DisplayManager {
|
||||||
int height = cls.getDeclaredField("logicalHeight").getInt(displayInfo);
|
int height = cls.getDeclaredField("logicalHeight").getInt(displayInfo);
|
||||||
int rotation = cls.getDeclaredField("rotation").getInt(displayInfo);
|
int rotation = cls.getDeclaredField("rotation").getInt(displayInfo);
|
||||||
int layerStack = cls.getDeclaredField("layerStack").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) {
|
} catch (Exception e) {
|
||||||
throw new AssertionError(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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue