Skip to content

Commit

Permalink
Add an option to keep the device awake
Browse files Browse the repository at this point in the history
Add an option to prevent the device to sleep:

    scrcpy --stay-awake
    scrcpy -w

The initial state is restored on exit.

Fixes #631 <#631>
  • Loading branch information
rom1v committed May 2, 2020
1 parent 8283273 commit c770243
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 15 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,18 @@ The list of display ids can be retrieved by:
adb shell dumpsys display # search "mDisplayId=" in the output
```

#### Stay awake

To prevent the device to sleep after some delay:

```bash
scrcpy --stay-awake
scrcpy -w
```

The initial state is restored when scrcpy is closed.


#### Turn screen off

It is possible to turn the device screen off while mirroring on start with a
Expand All @@ -410,6 +422,14 @@ Or by pressing `Ctrl`+`o` at any time.

To turn it back on, press `POWER` (or `Ctrl`+`p`).

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

```bash
scrcpy --turn-screen-off --stay-awake
scrcpy -Sw
```


#### Render expired frames

By default, to minimize latency, _scrcpy_ always renders the last decoded frame
Expand Down
4 changes: 4 additions & 0 deletions app/scrcpy.1
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ It only shows physical touches (not clicks from scrcpy).
.B \-v, \-\-version
Print the version of scrcpy.

.TP
.B \-w, \-\-stay-awake
Keep the device on while scrcpy is running.

.TP
.B \-\-window\-borderless
Disable window decorations (display borderless window).
Expand Down
14 changes: 13 additions & 1 deletion app/src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ scrcpy_print_usage(const char *arg0) {
" -v, --version\n"
" Print the version of scrcpy.\n"
"\n"
" -w, --stay-awake\n"
" Keep the device on while scrcpy is running.\n"
"\n"
" --window-borderless\n"
" Disable window decorations (display borderless window).\n"
"\n"
Expand Down Expand Up @@ -497,6 +500,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
{"rotation", required_argument, NULL, OPT_ROTATION},
{"serial", required_argument, NULL, 's'},
{"show-touches", no_argument, NULL, 't'},
{"stay-awake", no_argument, NULL, 'w'},
{"turn-screen-off", no_argument, NULL, 'S'},
{"version", no_argument, NULL, 'v'},
{"window-title", required_argument, NULL, OPT_WINDOW_TITLE},
Expand All @@ -514,7 +518,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
optind = 0; // reset to start from the first argument in tests

int c;
while ((c = getopt_long(argc, argv, "b:c:fF:hm:nNp:r:s:StTv", long_options,
while ((c = getopt_long(argc, argv, "b:c:fF:hm:nNp:r:s:StTvw", long_options,
NULL)) != -1) {
switch (c) {
case 'b':
Expand Down Expand Up @@ -594,6 +598,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
case 'v':
args->version = true;
break;
case 'w':
opts->stay_awake = true;
break;
case OPT_RENDER_EXPIRED_FRAMES:
opts->render_expired_frames = true;
break;
Expand Down Expand Up @@ -676,5 +683,10 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
return false;
}

if (!opts->control && opts->stay_awake) {
LOGE("Could not request to stay awake if control is disabled");
return false;
}

return true;
}
1 change: 1 addition & 0 deletions app/src/scrcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ scrcpy(const struct scrcpy_options *options) {
.control = options->control,
.display_id = options->display_id,
.show_touches = options->show_touches,
.stay_awake = options->stay_awake,
};
if (!server_start(&server, options->serial, &params)) {
return false;
Expand Down
2 changes: 2 additions & 0 deletions app/src/scrcpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct scrcpy_options {
bool prefer_text;
bool window_borderless;
bool mipmaps;
bool stay_awake;
};

#define SCRCPY_OPTIONS_DEFAULT { \
Expand Down Expand Up @@ -72,6 +73,7 @@ struct scrcpy_options {
.prefer_text = false, \
.window_borderless = false, \
.mipmaps = true, \
.stay_awake = false, \
}

bool
Expand Down
1 change: 1 addition & 0 deletions app/src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ execute_server(struct server *server, const struct server_params *params) {
params->control ? "true" : "false",
display_id_string,
params->show_touches ? "true" : "false",
params->stay_awake ? "true" : "false",
};
#ifdef SERVER_DEBUGGER
LOGI("Server debugger waiting for a client on device port "
Expand Down
1 change: 1 addition & 0 deletions app/src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct server_params {
bool control;
uint16_t display_id;
bool show_touches;
bool stay_awake;
};

// init default values
Expand Down
23 changes: 15 additions & 8 deletions server/src/main/java/com/genymobile/scrcpy/CleanUp.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ private CleanUp() {
// not instantiable
}

public static void configure(boolean disableShowTouches) throws IOException {
boolean needProcess = disableShowTouches;
public static void configure(boolean disableShowTouches, int restoreStayOn) throws IOException {
boolean needProcess = disableShowTouches || restoreStayOn != -1;
if (needProcess) {
startProcess(disableShowTouches);
startProcess(disableShowTouches, restoreStayOn);
} else {
// There is no additional clean up to do when scrcpy dies
unlinkSelf();
}
}

private static void startProcess(boolean disableShowTouches) throws IOException {
String[] cmd = {"app_process", "/", CleanUp.class.getName(), String.valueOf(disableShowTouches)};
private static void startProcess(boolean disableShowTouches, int restoreStayOn) throws IOException {
String[] cmd = {"app_process", "/", CleanUp.class.getName(), String.valueOf(disableShowTouches), String.valueOf(restoreStayOn)};

ProcessBuilder builder = new ProcessBuilder(cmd);
builder.environment().put("CLASSPATH", SERVER_PATH);
Expand Down Expand Up @@ -58,12 +58,19 @@ public static void main(String... args) {
Ln.i("Cleaning up");

boolean disableShowTouches = Boolean.parseBoolean(args[0]);
int restoreStayOn = Integer.parseInt(args[1]);

if (disableShowTouches) {
if (disableShowTouches || restoreStayOn != -1) {
ServiceManager serviceManager = new ServiceManager();
try (ContentProvider settings = serviceManager.getActivityManager().createSettingsProvider()) {
Ln.i("Disabling \"show touches\"");
settings.putValue(ContentProvider.TABLE_SYSTEM, "show_touches", "0");
if (disableShowTouches) {
Ln.i("Disabling \"show touches\"");
settings.putValue(ContentProvider.TABLE_SYSTEM, "show_touches", "0");
}
if (restoreStayOn != -1) {
Ln.i("Restoring \"stay awake\"");
settings.putValue(ContentProvider.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(restoreStayOn));
}
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions server/src/main/java/com/genymobile/scrcpy/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class Options {
private boolean control;
private int displayId;
private boolean showTouches;
private boolean stayAwake;

public int getMaxSize() {
return maxSize;
Expand Down Expand Up @@ -93,4 +94,12 @@ public boolean getShowTouches() {
public void setShowTouches(boolean showTouches) {
this.showTouches = showTouches;
}

public boolean getStayAwake() {
return stayAwake;
}

public void setStayAwake(boolean stayAwake) {
this.stayAwake = stayAwake;
}
}
33 changes: 27 additions & 6 deletions server/src/main/java/com/genymobile/scrcpy/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import android.graphics.Rect;
import android.media.MediaCodec;
import android.os.BatteryManager;
import android.os.Build;

import java.io.IOException;
Expand All @@ -20,15 +21,32 @@ private static void scrcpy(Options options) throws IOException {
final Device device = new Device(options);

boolean mustDisableShowTouchesOnCleanUp = false;
if (options.getShowTouches()) {
int restoreStayOn = -1;
if (options.getShowTouches() || options.getStayAwake()) {
try (ContentProvider settings = device.createSettingsProvider()) {
String oldValue = settings.getAndPutValue(ContentProvider.TABLE_SYSTEM, "show_touches", "1");
// If "show touches" was disabled, it must be disabled back on clean up
mustDisableShowTouchesOnCleanUp = !"1".equals(oldValue);
if (options.getShowTouches()) {
String oldValue = settings.getAndPutValue(ContentProvider.TABLE_SYSTEM, "show_touches", "1");
// If "show touches" was disabled, it must be disabled back on clean up
mustDisableShowTouchesOnCleanUp = !"1".equals(oldValue);
}

if (options.getStayAwake()) {
int stayOn = BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS;
String oldValue = settings.getAndPutValue(ContentProvider.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(stayOn));
try {
restoreStayOn = Integer.parseInt(oldValue);
if (restoreStayOn == stayOn) {
// No need to restore
restoreStayOn = -1;
}
} catch (NumberFormatException e) {
restoreStayOn = 0;
}
}
}
}

CleanUp.configure(mustDisableShowTouchesOnCleanUp);
CleanUp.configure(mustDisableShowTouchesOnCleanUp, restoreStayOn);

boolean tunnelForward = options.isTunnelForward();
try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) {
Expand Down Expand Up @@ -91,7 +109,7 @@ private static Options createOptions(String... args) {
"The server version (" + BuildConfig.VERSION_NAME + ") does not match the client " + "(" + clientVersion + ")");
}

final int expectedParameters = 11;
final int expectedParameters = 12;
if (args.length != expectedParameters) {
throw new IllegalArgumentException("Expecting " + expectedParameters + " parameters");
}
Expand Down Expand Up @@ -129,6 +147,9 @@ private static Options createOptions(String... args) {
boolean showTouches = Boolean.parseBoolean(args[10]);
options.setShowTouches(showTouches);

boolean stayAwake = Boolean.parseBoolean(args[11]);
options.setStayAwake(stayAwake);

return options;
}

Expand Down

0 comments on commit c770243

Please sign in to comment.