Adapt "turn screen off" for Android 15
Android 15 introduced an easy way to set the display power:
<fd8b5efc7f
%5E!/#F17>
Refs #3927 <https://github.com/Genymobile/scrcpy/issues/3927>
Refs <https://issuetracker.google.com/issues/303565669>
PR #5418 <https://github.com/Genymobile/scrcpy/pull/5418>
This commit is contained in:
parent
569c37cec1
commit
58ba00fa06
@ -143,7 +143,7 @@ public final class CleanUp {
|
|||||||
Device.powerOffScreen(displayId);
|
Device.powerOffScreen(displayId);
|
||||||
} else if (restoreDisplayPower) {
|
} else if (restoreDisplayPower) {
|
||||||
Ln.i("Restoring display power");
|
Ln.i("Restoring display power");
|
||||||
Device.setDisplayPower(true);
|
Device.setDisplayPower(displayId, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
|||||||
case ControlMessage.TYPE_SET_DISPLAY_POWER:
|
case ControlMessage.TYPE_SET_DISPLAY_POWER:
|
||||||
if (supportsInputEvents && displayId != Device.DISPLAY_ID_NONE) {
|
if (supportsInputEvents && displayId != Device.DISPLAY_ID_NONE) {
|
||||||
boolean on = msg.getOn();
|
boolean on = msg.getOn();
|
||||||
boolean setDisplayPowerOk = Device.setDisplayPower(on);
|
boolean setDisplayPowerOk = Device.setDisplayPower(displayId, on);
|
||||||
if (setDisplayPowerOk) {
|
if (setDisplayPowerOk) {
|
||||||
keepDisplayPowerOff = !on;
|
keepDisplayPowerOff = !on;
|
||||||
Ln.i("Device display turned " + (on ? "on" : "off"));
|
Ln.i("Device display turned " + (on ? "on" : "off"));
|
||||||
@ -312,7 +312,7 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
|||||||
private boolean injectKeycode(int action, int keycode, int repeat, int metaState) {
|
private boolean injectKeycode(int action, int keycode, int repeat, int metaState) {
|
||||||
if (keepDisplayPowerOff && action == KeyEvent.ACTION_UP && (keycode == KeyEvent.KEYCODE_POWER || keycode == KeyEvent.KEYCODE_WAKEUP)) {
|
if (keepDisplayPowerOff && action == KeyEvent.ACTION_UP && (keycode == KeyEvent.KEYCODE_POWER || keycode == KeyEvent.KEYCODE_WAKEUP)) {
|
||||||
assert displayId != Device.DISPLAY_ID_NONE;
|
assert displayId != Device.DISPLAY_ID_NONE;
|
||||||
scheduleDisplayPowerOff();
|
scheduleDisplayPowerOff(displayId);
|
||||||
}
|
}
|
||||||
return injectKeyEvent(action, keycode, repeat, metaState, Device.INJECT_MODE_ASYNC);
|
return injectKeyEvent(action, keycode, repeat, metaState, Device.INJECT_MODE_ASYNC);
|
||||||
}
|
}
|
||||||
@ -491,10 +491,10 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
|||||||
/**
|
/**
|
||||||
* Schedule a call to set display power to off after a small delay.
|
* Schedule a call to set display power to off after a small delay.
|
||||||
*/
|
*/
|
||||||
private static void scheduleDisplayPowerOff() {
|
private static void scheduleDisplayPowerOff(int displayId) {
|
||||||
EXECUTOR.schedule(() -> {
|
EXECUTOR.schedule(() -> {
|
||||||
Ln.i("Forcing display off");
|
Ln.i("Forcing display off");
|
||||||
Device.setDisplayPower(false);
|
Device.setDisplayPower(displayId, false);
|
||||||
}, 200, TimeUnit.MILLISECONDS);
|
}, 200, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,7 +512,7 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
|||||||
|
|
||||||
if (keepDisplayPowerOff) {
|
if (keepDisplayPowerOff) {
|
||||||
assert displayId != Device.DISPLAY_ID_NONE;
|
assert displayId != Device.DISPLAY_ID_NONE;
|
||||||
scheduleDisplayPowerOff();
|
scheduleDisplayPowerOff(displayId);
|
||||||
}
|
}
|
||||||
return pressReleaseKeycode(KeyEvent.KEYCODE_POWER, Device.INJECT_MODE_ASYNC);
|
return pressReleaseKeycode(KeyEvent.KEYCODE_POWER, Device.INJECT_MODE_ASYNC);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,13 @@ public final class Device {
|
|||||||
return clipboardManager.setText(text);
|
return clipboardManager.setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean setDisplayPower(boolean on) {
|
public static boolean setDisplayPower(int displayId, boolean on) {
|
||||||
|
assert displayId != Device.DISPLAY_ID_NONE;
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= AndroidVersions.API_35_ANDROID_15) {
|
||||||
|
return ServiceManager.getDisplayManager().requestDisplayPower(displayId, on);
|
||||||
|
}
|
||||||
|
|
||||||
boolean applyToMultiPhysicalDisplays = Build.VERSION.SDK_INT >= AndroidVersions.API_29_ANDROID_10;
|
boolean applyToMultiPhysicalDisplays = Build.VERSION.SDK_INT >= AndroidVersions.API_29_ANDROID_10;
|
||||||
|
|
||||||
if (applyToMultiPhysicalDisplays
|
if (applyToMultiPhysicalDisplays
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genymobile.scrcpy.wrappers;
|
package com.genymobile.scrcpy.wrappers;
|
||||||
|
|
||||||
|
import com.genymobile.scrcpy.AndroidVersions;
|
||||||
import com.genymobile.scrcpy.FakeContext;
|
import com.genymobile.scrcpy.FakeContext;
|
||||||
import com.genymobile.scrcpy.device.DisplayInfo;
|
import com.genymobile.scrcpy.device.DisplayInfo;
|
||||||
import com.genymobile.scrcpy.device.Size;
|
import com.genymobile.scrcpy.device.Size;
|
||||||
@ -7,6 +8,7 @@ import com.genymobile.scrcpy.util.Command;
|
|||||||
import com.genymobile.scrcpy.util.Ln;
|
import com.genymobile.scrcpy.util.Ln;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.display.VirtualDisplay;
|
import android.hardware.display.VirtualDisplay;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
@ -22,6 +24,7 @@ import java.util.regex.Pattern;
|
|||||||
public final class DisplayManager {
|
public final class DisplayManager {
|
||||||
private final Object manager; // instance of hidden class android.hardware.display.DisplayManagerGlobal
|
private final Object manager; // instance of hidden class android.hardware.display.DisplayManagerGlobal
|
||||||
private Method createVirtualDisplayMethod;
|
private Method createVirtualDisplayMethod;
|
||||||
|
private Method requestDisplayPowerMethod;
|
||||||
|
|
||||||
static DisplayManager create() {
|
static DisplayManager create() {
|
||||||
try {
|
try {
|
||||||
@ -137,4 +140,22 @@ public final class DisplayManager {
|
|||||||
android.hardware.display.DisplayManager dm = ctor.newInstance(FakeContext.get());
|
android.hardware.display.DisplayManager dm = ctor.newInstance(FakeContext.get());
|
||||||
return dm.createVirtualDisplay(name, width, height, dpi, surface, flags);
|
return dm.createVirtualDisplay(name, width, height, dpi, surface, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Method getRequestDisplayPowerMethod() throws NoSuchMethodException {
|
||||||
|
if (requestDisplayPowerMethod == null) {
|
||||||
|
requestDisplayPowerMethod = manager.getClass().getMethod("requestDisplayPower", int.class, boolean.class);
|
||||||
|
}
|
||||||
|
return requestDisplayPowerMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(AndroidVersions.API_35_ANDROID_15)
|
||||||
|
public boolean requestDisplayPower(int displayId, boolean on) {
|
||||||
|
try {
|
||||||
|
Method method = getRequestDisplayPowerMethod();
|
||||||
|
return (boolean) method.invoke(manager, displayId, on);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
Ln.e("Could not invoke method", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user