mirror of https://github.com/Genymobile/scrcpy
Add --screen-off-timeout
Change the Android "screen off timeout" (the idle delay before the screen automatically turns off) and restore the initial value on exit. PR #5447 <https://github.com/Genymobile/scrcpy/pull/5447>
This commit is contained in:
parent
d3db9c4065
commit
eff5b4b219
|
@ -77,6 +77,7 @@ _scrcpy() {
|
|||
--rotation=
|
||||
-s --serial=
|
||||
-S --turn-screen-off
|
||||
--screen-off-timeout=
|
||||
--shortcut-mod=
|
||||
--start-app=
|
||||
-t --show-touches
|
||||
|
|
|
@ -80,6 +80,7 @@ arguments=(
|
|||
'--require-audio=[Make scrcpy fail if audio is enabled but does not work]'
|
||||
{-s,--serial=}'[The device serial number \(mandatory for multiple devices only\)]:serial:($("${ADB-adb}" devices | awk '\''$2 == "device" {print $1}'\''))'
|
||||
{-S,--turn-screen-off}'[Turn the device screen off immediately]'
|
||||
'--screen-off-timeout=[Set the screen off timeout in seconds]'
|
||||
'--shortcut-mod=[\[key1,key2+key3,...\] Specify the modifiers to use for scrcpy shortcuts]:shortcut mod:(lctrl rctrl lalt ralt lsuper rsuper)'
|
||||
'--start-app=[Start an Android app]'
|
||||
{-t,--show-touches}'[Show physical touches]'
|
||||
|
|
|
@ -106,6 +106,7 @@ enum {
|
|||
OPT_NEW_DISPLAY,
|
||||
OPT_LIST_APPS,
|
||||
OPT_START_APP,
|
||||
OPT_SCREEN_OFF_TIMEOUT,
|
||||
};
|
||||
|
||||
struct sc_option {
|
||||
|
@ -793,6 +794,13 @@ static const struct sc_option options[] = {
|
|||
.longopt = "turn-screen-off",
|
||||
.text = "Turn the device screen off immediately.",
|
||||
},
|
||||
{
|
||||
.longopt_id = OPT_SCREEN_OFF_TIMEOUT,
|
||||
.longopt = "screen-off-timeout",
|
||||
.argdesc = "seconds",
|
||||
.text = "Set the screen off timeout while scrcpy is running (restore "
|
||||
"the initial value on exit).",
|
||||
},
|
||||
{
|
||||
.longopt_id = OPT_SHORTCUT_MOD,
|
||||
.longopt = "shortcut-mod",
|
||||
|
@ -2155,6 +2163,20 @@ parse_time_limit(const char *s, sc_tick *tick) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_screen_off_timeout(const char *s, sc_tick *tick) {
|
||||
long value;
|
||||
// value in seconds, but must fit in 31 bits in milliseconds
|
||||
bool ok = parse_integer_arg(s, &value, false, 0, 0x7FFFFFFF / 1000,
|
||||
"screen off timeout");
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*tick = SC_TICK_FROM_SEC(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_pause_on_exit(const char *s, enum sc_pause_on_exit *pause_on_exit) {
|
||||
if (!s || !strcmp(s, "true")) {
|
||||
|
@ -2730,6 +2752,12 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||
case OPT_START_APP:
|
||||
opts->start_app = optarg;
|
||||
break;
|
||||
case OPT_SCREEN_OFF_TIMEOUT:
|
||||
if (!parse_screen_off_timeout(optarg,
|
||||
&opts->screen_off_timeout)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// getopt prints the error message on stderr
|
||||
return false;
|
||||
|
|
|
@ -62,6 +62,7 @@ const struct scrcpy_options scrcpy_options_default = {
|
|||
.audio_buffer = -1, // depends on the audio format,
|
||||
.audio_output_buffer = SC_TICK_FROM_MS(5),
|
||||
.time_limit = 0,
|
||||
.screen_off_timeout = -1,
|
||||
#ifdef HAVE_V4L2
|
||||
.v4l2_device = NULL,
|
||||
.v4l2_buffer = 0,
|
||||
|
|
|
@ -265,6 +265,7 @@ struct scrcpy_options {
|
|||
sc_tick audio_buffer;
|
||||
sc_tick audio_output_buffer;
|
||||
sc_tick time_limit;
|
||||
sc_tick screen_off_timeout;
|
||||
#ifdef HAVE_V4L2
|
||||
const char *v4l2_device;
|
||||
sc_tick v4l2_buffer;
|
||||
|
|
|
@ -428,6 +428,7 @@ scrcpy(struct scrcpy_options *options) {
|
|||
.video_bit_rate = options->video_bit_rate,
|
||||
.audio_bit_rate = options->audio_bit_rate,
|
||||
.max_fps = options->max_fps,
|
||||
.screen_off_timeout = options->screen_off_timeout,
|
||||
.lock_video_orientation = options->lock_video_orientation,
|
||||
.control = options->control,
|
||||
.display_id = options->display_id,
|
||||
|
|
|
@ -320,6 +320,11 @@ execute_server(struct sc_server *server,
|
|||
if (params->stay_awake) {
|
||||
ADD_PARAM("stay_awake=true");
|
||||
}
|
||||
if (params->screen_off_timeout != -1) {
|
||||
assert(params->screen_off_timeout >= 0);
|
||||
uint64_t ms = SC_TICK_TO_MS(params->screen_off_timeout);
|
||||
ADD_PARAM("screen_off_timeout=%" PRIu64, ms);
|
||||
}
|
||||
if (params->video_codec_options) {
|
||||
VALIDATE_STRING(params->video_codec_options);
|
||||
ADD_PARAM("video_codec_options=%s", params->video_codec_options);
|
||||
|
|
|
@ -45,6 +45,7 @@ struct sc_server_params {
|
|||
uint32_t video_bit_rate;
|
||||
uint32_t audio_bit_rate;
|
||||
const char *max_fps; // float to be parsed by the server
|
||||
sc_tick screen_off_timeout;
|
||||
int8_t lock_video_orientation;
|
||||
bool control;
|
||||
uint32_t display_id;
|
||||
|
|
|
@ -71,6 +71,31 @@ adb shell cmd display power-on 0
|
|||
```
|
||||
|
||||
|
||||
## Screen off timeout
|
||||
|
||||
The Android screen automatically turns off after some delay.
|
||||
|
||||
To change this delay while scrcpy is running:
|
||||
|
||||
```bash
|
||||
scrcpy --screen-off-timeout=300 # 300 seconds (5 minutes)
|
||||
```
|
||||
|
||||
The initial value is restored on exit.
|
||||
|
||||
It is possible to change this setting manually:
|
||||
|
||||
```bash
|
||||
# get the current screen_off_timeout value
|
||||
adb shell settings get system screen_off_timeout
|
||||
# set a new value (in milliseconds)
|
||||
adb shell settings put system screen_off_timeout 30000
|
||||
```
|
||||
|
||||
Note that the Android value is in milliseconds, but the scrcpy command line
|
||||
argument is in seconds.
|
||||
|
||||
|
||||
## Show touches
|
||||
|
||||
For presentations, it may be useful to show physical touches (on the physical
|
||||
|
|
|
@ -73,10 +73,29 @@ public final class CleanUp {
|
|||
}
|
||||
}
|
||||
|
||||
int restoreScreenOffTimeout = -1;
|
||||
int screenOffTimeout = options.getScreenOffTimeout();
|
||||
if (screenOffTimeout != -1) {
|
||||
try {
|
||||
String oldValue = Settings.getAndPutValue(Settings.TABLE_SYSTEM, "screen_off_timeout", String.valueOf(screenOffTimeout));
|
||||
try {
|
||||
int currentScreenOffTimeout = Integer.parseInt(oldValue);
|
||||
// Restore only if the current value is different
|
||||
if (currentScreenOffTimeout != screenOffTimeout) {
|
||||
restoreScreenOffTimeout = currentScreenOffTimeout;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// ignore
|
||||
}
|
||||
} catch (SettingsException e) {
|
||||
Ln.e("Could not change \"screen_off_timeout\"", e);
|
||||
}
|
||||
}
|
||||
|
||||
boolean powerOffScreen = options.getPowerOffScreenOnClose();
|
||||
|
||||
try {
|
||||
run(displayId, restoreStayOn, disableShowTouches, powerOffScreen);
|
||||
run(displayId, restoreStayOn, disableShowTouches, powerOffScreen, restoreScreenOffTimeout);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
} catch (IOException e) {
|
||||
|
@ -84,7 +103,8 @@ public final class CleanUp {
|
|||
}
|
||||
}
|
||||
|
||||
private void run(int displayId, int restoreStayOn, boolean disableShowTouches, boolean powerOffScreen) throws IOException, InterruptedException {
|
||||
private void run(int displayId, int restoreStayOn, boolean disableShowTouches, boolean powerOffScreen, int restoreScreenOffTimeout)
|
||||
throws IOException, InterruptedException {
|
||||
String[] cmd = {
|
||||
"app_process",
|
||||
"/",
|
||||
|
@ -93,6 +113,7 @@ public final class CleanUp {
|
|||
String.valueOf(restoreStayOn),
|
||||
String.valueOf(disableShowTouches),
|
||||
String.valueOf(powerOffScreen),
|
||||
String.valueOf(restoreScreenOffTimeout),
|
||||
};
|
||||
|
||||
ProcessBuilder builder = new ProcessBuilder(cmd);
|
||||
|
@ -139,6 +160,7 @@ public final class CleanUp {
|
|||
int restoreStayOn = Integer.parseInt(args[1]);
|
||||
boolean disableShowTouches = Boolean.parseBoolean(args[2]);
|
||||
boolean powerOffScreen = Boolean.parseBoolean(args[3]);
|
||||
int restoreScreenOffTimeout = Integer.parseInt(args[4]);
|
||||
|
||||
// Dynamic option
|
||||
boolean restoreDisplayPower = false;
|
||||
|
@ -175,6 +197,15 @@ public final class CleanUp {
|
|||
}
|
||||
}
|
||||
|
||||
if (restoreScreenOffTimeout != -1) {
|
||||
Ln.i("Restoring \"screen off timeout\"");
|
||||
try {
|
||||
Settings.putValue(Settings.TABLE_SYSTEM, "screen_off_timeout", String.valueOf(restoreScreenOffTimeout));
|
||||
} catch (SettingsException e) {
|
||||
Ln.e("Could not restore \"screen_off_timeout\"", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (displayId != Device.DISPLAY_ID_NONE && Device.isScreenOn(displayId)) {
|
||||
if (powerOffScreen) {
|
||||
Ln.i("Power off screen");
|
||||
|
|
|
@ -45,6 +45,7 @@ public class Options {
|
|||
private boolean cameraHighSpeed;
|
||||
private boolean showTouches;
|
||||
private boolean stayAwake;
|
||||
private int screenOffTimeout = -1;
|
||||
private List<CodecOption> videoCodecOptions;
|
||||
private List<CodecOption> audioCodecOptions;
|
||||
|
||||
|
@ -174,6 +175,10 @@ public class Options {
|
|||
return stayAwake;
|
||||
}
|
||||
|
||||
public int getScreenOffTimeout() {
|
||||
return screenOffTimeout;
|
||||
}
|
||||
|
||||
public List<CodecOption> getVideoCodecOptions() {
|
||||
return videoCodecOptions;
|
||||
}
|
||||
|
@ -363,6 +368,12 @@ public class Options {
|
|||
case "stay_awake":
|
||||
options.stayAwake = Boolean.parseBoolean(value);
|
||||
break;
|
||||
case "screen_off_timeout":
|
||||
options.screenOffTimeout = Integer.parseInt(value);
|
||||
if (options.screenOffTimeout < -1) {
|
||||
throw new IllegalArgumentException("Invalid screen off timeout: " + options.screenOffTimeout);
|
||||
}
|
||||
break;
|
||||
case "video_codec_options":
|
||||
options.videoCodecOptions = CodecOption.parse(value);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue