Skip to content

Commit

Permalink
Keep the screen off on powering on
Browse files Browse the repository at this point in the history
PR #1577 <#1577>
Fixes #1573 <#1573>

Signed-off-by: Romain Vimont <[email protected]>
  • Loading branch information
brunoais authored and rom1v committed Aug 3, 2020
1 parent 84f1d9e commit cf9d449
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,12 @@ scrcpy -S

Or by pressing <kbd>MOD</kbd>+<kbd>o</kbd> at any time.

To turn it back on, press <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>o</kbd> (or
`POWER`, <kbd>MOD</kbd>+<kbd>p</kbd>).
To turn it back on, press <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>o</kbd>.

On Android, the `POWER` button always turns the screen on. For convenience, if
`POWER` is sent via scrcpy (via right-click or <kbd>Ctrl</kbd>+<kbd>p</kbd>), it
will force to turn the screen off after a small delay (on a best effort basis).
The physical `POWER` button will still cause the screen to be turned on.

It can be useful to also prevent the device to sleep:

Expand Down
27 changes: 27 additions & 0 deletions server/src/main/java/com/genymobile/scrcpy/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@
import android.view.MotionEvent;

import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Controller {

private static final int DEVICE_ID_VIRTUAL = -1;

private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor();

private final Device device;
private final DesktopConnection connection;
private final DeviceMessageSender sender;
Expand All @@ -24,6 +29,8 @@ public class Controller {
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;

public Controller(Device device, DesktopConnection connection) {
this.device = device;
this.connection = connection;
Expand Down Expand Up @@ -117,6 +124,7 @@ private void handleEvent() throws IOException {
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"));
}
}
Expand All @@ -130,6 +138,9 @@ private void handleEvent() throws IOException {
}

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();
}
return device.injectKeyEvent(action, keycode, repeat, metaState);
}

Expand Down Expand Up @@ -223,8 +234,24 @@ private boolean injectScroll(Position position, int hScroll, int vScroll) {
return device.injectEvent(event);
}

/**
* Schedule a call to set power mode to off after a small delay.
*/
private static void schedulePowerModeOff() {
EXECUTOR.schedule(new Runnable() {
@Override
public void run() {
Ln.i("Forcing screen off");
Device.setScreenPowerMode(Device.POWER_MODE_OFF);
}
}, 200, TimeUnit.MILLISECONDS);
}

private boolean pressBackOrTurnScreenOn() {
int keycode = device.isScreenOn() ? KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_WAKEUP;
if (keepPowerModeOff && keycode == KeyEvent.KEYCODE_WAKEUP) {
schedulePowerModeOff();
}
return device.injectKeycode(keycode);
}

Expand Down

0 comments on commit cf9d449

Please sign in to comment.