Refactor display power mode

Accept a single boolean "on" rather than a "mode" (which, in practice,
could only take 2 values: NORMAL and OFF).

Also rename "screen power mode" to "display power".

PR #5418 <https://github.com/Genymobile/scrcpy/pull/5418>
This commit is contained in:
Romain Vimont 2024-10-28 23:56:17 +01:00
commit 58a0fbbf2e
11 changed files with 71 additions and 93 deletions

View file

@ -19,7 +19,7 @@ public final class CleanUp {
private static final int MSG_TYPE_MASK = 0b11;
private static final int MSG_TYPE_RESTORE_STAY_ON = 0;
private static final int MSG_TYPE_DISABLE_SHOW_TOUCHES = 1;
private static final int MSG_TYPE_RESTORE_NORMAL_POWER_MODE = 2;
private static final int MSG_TYPE_RESTORE_DISPLAY_POWER = 2;
private static final int MSG_TYPE_POWER_OFF_SCREEN = 3;
private static final int MSG_PARAM_SHIFT = 2;
@ -63,8 +63,8 @@ public final class CleanUp {
return sendMessage(MSG_TYPE_DISABLE_SHOW_TOUCHES, disableOnExit ? 1 : 0);
}
public boolean setRestoreNormalPowerMode(boolean restoreOnExit) {
return sendMessage(MSG_TYPE_RESTORE_NORMAL_POWER_MODE, restoreOnExit ? 1 : 0);
public boolean setRestoreDisplayPower(boolean restoreOnExit) {
return sendMessage(MSG_TYPE_RESTORE_DISPLAY_POWER, restoreOnExit ? 1 : 0);
}
public boolean setPowerOffScreen(boolean powerOffScreenOnExit) {
@ -86,7 +86,7 @@ public final class CleanUp {
int restoreStayOn = -1;
boolean disableShowTouches = false;
boolean restoreNormalPowerMode = false;
boolean restoreDisplayPower = false;
boolean powerOffScreen = false;
try {
@ -102,8 +102,8 @@ public final class CleanUp {
case MSG_TYPE_DISABLE_SHOW_TOUCHES:
disableShowTouches = param != 0;
break;
case MSG_TYPE_RESTORE_NORMAL_POWER_MODE:
restoreNormalPowerMode = param != 0;
case MSG_TYPE_RESTORE_DISPLAY_POWER:
restoreDisplayPower = param != 0;
break;
case MSG_TYPE_POWER_OFF_SCREEN:
powerOffScreen = param != 0;
@ -143,9 +143,9 @@ public final class CleanUp {
Ln.i("Power off screen");
Device.powerOffScreen(displayId);
}
} else if (restoreNormalPowerMode) {
Ln.i("Restoring normal power mode");
Device.setScreenPowerMode(Device.POWER_MODE_NORMAL);
} else if (restoreDisplayPower) {
Ln.i("Restoring display power");
Device.setDisplayPower(true);
}
}

View file

@ -17,7 +17,7 @@ public final class ControlMessage {
public static final int TYPE_COLLAPSE_PANELS = 7;
public static final int TYPE_GET_CLIPBOARD = 8;
public static final int TYPE_SET_CLIPBOARD = 9;
public static final int TYPE_SET_SCREEN_POWER_MODE = 10;
public static final int TYPE_SET_DISPLAY_POWER = 10;
public static final int TYPE_ROTATE_DEVICE = 11;
public static final int TYPE_UHID_CREATE = 12;
public static final int TYPE_UHID_INPUT = 13;
@ -34,7 +34,7 @@ public final class ControlMessage {
private int type;
private String text;
private int metaState; // KeyEvent.META_*
private int action; // KeyEvent.ACTION_* or MotionEvent.ACTION_* or POWER_MODE_*
private int action; // KeyEvent.ACTION_* or MotionEvent.ACTION_*
private int keycode; // KeyEvent.KEYCODE_*
private int actionButton; // MotionEvent.BUTTON_*
private int buttons; // MotionEvent.BUTTON_*
@ -49,6 +49,7 @@ public final class ControlMessage {
private long sequence;
private int id;
private byte[] data;
private boolean on;
private ControlMessage() {
}
@ -116,13 +117,10 @@ public final class ControlMessage {
return msg;
}
/**
* @param mode one of the {@code Device.SCREEN_POWER_MODE_*} constants
*/
public static ControlMessage createSetScreenPowerMode(int mode) {
public static ControlMessage createSetDisplayPower(boolean on) {
ControlMessage msg = new ControlMessage();
msg.type = TYPE_SET_SCREEN_POWER_MODE;
msg.action = mode;
msg.type = TYPE_SET_DISPLAY_POWER;
msg.on = on;
return msg;
}
@ -234,4 +232,8 @@ public final class ControlMessage {
public byte[] getData() {
return data;
}
public boolean getOn() {
return on;
}
}

View file

@ -39,8 +39,8 @@ public class ControlMessageReader {
return parseGetClipboard();
case ControlMessage.TYPE_SET_CLIPBOARD:
return parseSetClipboard();
case ControlMessage.TYPE_SET_SCREEN_POWER_MODE:
return parseSetScreenPowerMode();
case ControlMessage.TYPE_SET_DISPLAY_POWER:
return parseSetDisplayPower();
case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL:
case ControlMessage.TYPE_EXPAND_SETTINGS_PANEL:
case ControlMessage.TYPE_COLLAPSE_PANELS:
@ -134,9 +134,9 @@ public class ControlMessageReader {
return ControlMessage.createSetClipboard(sequence, text, paste);
}
private ControlMessage parseSetScreenPowerMode() throws IOException {
int mode = dis.readUnsignedByte();
return ControlMessage.createSetScreenPowerMode(mode);
private ControlMessage parseSetDisplayPower() throws IOException {
boolean on = dis.readBoolean();
return ControlMessage.createSetDisplayPower(on);
}
private ControlMessage parseUhidCreate() throws IOException {

View file

@ -91,7 +91,7 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
private final MotionEvent.PointerProperties[] pointerProperties = new MotionEvent.PointerProperties[PointersState.MAX_POINTERS];
private final MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[PointersState.MAX_POINTERS];
private boolean keepPowerModeOff;
private boolean keepDisplayPowerOff;
public Controller(int displayId, ControlChannel controlChannel, CleanUp cleanUp, boolean clipboardAutosync, boolean powerOn) {
this.displayId = displayId;
@ -270,16 +270,16 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
case ControlMessage.TYPE_SET_CLIPBOARD:
setClipboard(msg.getText(), msg.getPaste(), msg.getSequence());
break;
case ControlMessage.TYPE_SET_SCREEN_POWER_MODE:
case ControlMessage.TYPE_SET_DISPLAY_POWER:
if (supportsInputEvents) {
int mode = msg.getAction();
boolean setPowerModeOk = Device.setScreenPowerMode(mode);
if (setPowerModeOk) {
keepPowerModeOff = mode == Device.POWER_MODE_OFF;
Ln.i("Device screen turned " + (mode == Device.POWER_MODE_OFF ? "off" : "on"));
boolean on = msg.getOn();
boolean setDisplayPowerOk = Device.setDisplayPower(on);
if (setDisplayPowerOk) {
keepDisplayPowerOff = !on;
Ln.i("Device display turned " + (on ? "on" : "off"));
if (cleanUp != null) {
boolean mustRestoreOnExit = mode != Device.POWER_MODE_NORMAL;
cleanUp.setRestoreNormalPowerMode(mustRestoreOnExit);
boolean mustRestoreOnExit = !on;
cleanUp.setRestoreDisplayPower(mustRestoreOnExit);
}
}
}
@ -310,8 +310,8 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
}
private boolean injectKeycode(int action, int keycode, int repeat, int metaState) {
if (keepPowerModeOff && action == KeyEvent.ACTION_UP && (keycode == KeyEvent.KEYCODE_POWER || keycode == KeyEvent.KEYCODE_WAKEUP)) {
schedulePowerModeOff();
if (keepDisplayPowerOff && action == KeyEvent.ACTION_UP && (keycode == KeyEvent.KEYCODE_POWER || keycode == KeyEvent.KEYCODE_WAKEUP)) {
scheduleDisplayPowerOff();
}
return injectKeyEvent(action, keycode, repeat, metaState, Device.INJECT_MODE_ASYNC);
}
@ -488,12 +488,12 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
}
/**
* Schedule a call to set power mode to off after a small delay.
* Schedule a call to set display power to off after a small delay.
*/
private static void schedulePowerModeOff() {
private static void scheduleDisplayPowerOff() {
EXECUTOR.schedule(() -> {
Ln.i("Forcing screen off");
Device.setScreenPowerMode(Device.POWER_MODE_OFF);
Ln.i("Forcing display off");
Device.setDisplayPower(false);
}, 200, TimeUnit.MILLISECONDS);
}
@ -509,8 +509,8 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
return true;
}
if (keepPowerModeOff) {
schedulePowerModeOff();
if (keepDisplayPowerOff) {
scheduleDisplayPowerOff();
}
return pressReleaseKeycode(KeyEvent.KEYCODE_POWER, Device.INJECT_MODE_ASYNC);
}

View file

@ -126,10 +126,7 @@ public final class Device {
return clipboardManager.setText(text);
}
/**
* @param mode one of the {@code POWER_MODE_*} constants
*/
public static boolean setScreenPowerMode(int mode) {
public static boolean setDisplayPower(boolean on) {
boolean applyToMultiPhysicalDisplays = Build.VERSION.SDK_INT >= AndroidVersions.API_29_ANDROID_10;
if (applyToMultiPhysicalDisplays
@ -142,6 +139,7 @@ public final class Device {
applyToMultiPhysicalDisplays = false;
}
int mode = on ? POWER_MODE_NORMAL : POWER_MODE_OFF;
if (applyToMultiPhysicalDisplays) {
// On Android 14, these internal methods have been moved to DisplayControl
boolean useDisplayControl =

View file

@ -1,7 +1,5 @@
package com.genymobile.scrcpy.control;
import com.genymobile.scrcpy.device.Device;
import android.view.KeyEvent;
import android.view.MotionEvent;
import org.junit.Assert;
@ -285,19 +283,19 @@ public class ControlMessageReaderTest {
}
@Test
public void testParseSetScreenPowerMode() throws IOException {
public void testParseSetDisplayPower() throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeByte(ControlMessage.TYPE_SET_SCREEN_POWER_MODE);
dos.writeByte(Device.POWER_MODE_NORMAL);
dos.writeByte(ControlMessage.TYPE_SET_DISPLAY_POWER);
dos.writeBoolean(true);
byte[] packet = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(packet);
ControlMessageReader reader = new ControlMessageReader(bis);
ControlMessage event = reader.read();
Assert.assertEquals(ControlMessage.TYPE_SET_SCREEN_POWER_MODE, event.getType());
Assert.assertEquals(Device.POWER_MODE_NORMAL, event.getAction());
Assert.assertEquals(ControlMessage.TYPE_SET_DISPLAY_POWER, event.getType());
Assert.assertTrue(event.getOn());
Assert.assertEquals(-1, bis.read()); // EOS
}