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=
|
--rotation=
|
||||||
-s --serial=
|
-s --serial=
|
||||||
-S --turn-screen-off
|
-S --turn-screen-off
|
||||||
|
--screen-off-timeout=
|
||||||
--shortcut-mod=
|
--shortcut-mod=
|
||||||
--start-app=
|
--start-app=
|
||||||
-t --show-touches
|
-t --show-touches
|
||||||
|
@ -80,6 +80,7 @@ arguments=(
|
|||||||
'--require-audio=[Make scrcpy fail if audio is enabled but does not work]'
|
'--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,--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]'
|
{-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)'
|
'--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]'
|
'--start-app=[Start an Android app]'
|
||||||
{-t,--show-touches}'[Show physical touches]'
|
{-t,--show-touches}'[Show physical touches]'
|
||||||
|
@ -106,6 +106,7 @@ enum {
|
|||||||
OPT_NEW_DISPLAY,
|
OPT_NEW_DISPLAY,
|
||||||
OPT_LIST_APPS,
|
OPT_LIST_APPS,
|
||||||
OPT_START_APP,
|
OPT_START_APP,
|
||||||
|
OPT_SCREEN_OFF_TIMEOUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sc_option {
|
struct sc_option {
|
||||||
@ -793,6 +794,13 @@ static const struct sc_option options[] = {
|
|||||||
.longopt = "turn-screen-off",
|
.longopt = "turn-screen-off",
|
||||||
.text = "Turn the device screen off immediately.",
|
.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_id = OPT_SHORTCUT_MOD,
|
||||||
.longopt = "shortcut-mod",
|
.longopt = "shortcut-mod",
|
||||||
@ -2155,6 +2163,20 @@ parse_time_limit(const char *s, sc_tick *tick) {
|
|||||||
return true;
|
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
|
static bool
|
||||||
parse_pause_on_exit(const char *s, enum sc_pause_on_exit *pause_on_exit) {
|
parse_pause_on_exit(const char *s, enum sc_pause_on_exit *pause_on_exit) {
|
||||||
if (!s || !strcmp(s, "true")) {
|
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:
|
case OPT_START_APP:
|
||||||
opts->start_app = optarg;
|
opts->start_app = optarg;
|
||||||
break;
|
break;
|
||||||
|
case OPT_SCREEN_OFF_TIMEOUT:
|
||||||
|
if (!parse_screen_off_timeout(optarg,
|
||||||
|
&opts->screen_off_timeout)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// getopt prints the error message on stderr
|
// getopt prints the error message on stderr
|
||||||
return false;
|
return false;
|
||||||
|
@ -62,6 +62,7 @@ const struct scrcpy_options scrcpy_options_default = {
|
|||||||
.audio_buffer = -1, // depends on the audio format,
|
.audio_buffer = -1, // depends on the audio format,
|
||||||
.audio_output_buffer = SC_TICK_FROM_MS(5),
|
.audio_output_buffer = SC_TICK_FROM_MS(5),
|
||||||
.time_limit = 0,
|
.time_limit = 0,
|
||||||
|
.screen_off_timeout = -1,
|
||||||
#ifdef HAVE_V4L2
|
#ifdef HAVE_V4L2
|
||||||
.v4l2_device = NULL,
|
.v4l2_device = NULL,
|
||||||
.v4l2_buffer = 0,
|
.v4l2_buffer = 0,
|
||||||
|
@ -265,6 +265,7 @@ struct scrcpy_options {
|
|||||||
sc_tick audio_buffer;
|
sc_tick audio_buffer;
|
||||||
sc_tick audio_output_buffer;
|
sc_tick audio_output_buffer;
|
||||||
sc_tick time_limit;
|
sc_tick time_limit;
|
||||||
|
sc_tick screen_off_timeout;
|
||||||
#ifdef HAVE_V4L2
|
#ifdef HAVE_V4L2
|
||||||
const char *v4l2_device;
|
const char *v4l2_device;
|
||||||
sc_tick v4l2_buffer;
|
sc_tick v4l2_buffer;
|
||||||
|
@ -428,6 +428,7 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
.video_bit_rate = options->video_bit_rate,
|
.video_bit_rate = options->video_bit_rate,
|
||||||
.audio_bit_rate = options->audio_bit_rate,
|
.audio_bit_rate = options->audio_bit_rate,
|
||||||
.max_fps = options->max_fps,
|
.max_fps = options->max_fps,
|
||||||
|
.screen_off_timeout = options->screen_off_timeout,
|
||||||
.lock_video_orientation = options->lock_video_orientation,
|
.lock_video_orientation = options->lock_video_orientation,
|
||||||
.control = options->control,
|
.control = options->control,
|
||||||
.display_id = options->display_id,
|
.display_id = options->display_id,
|
||||||
|
@ -320,6 +320,11 @@ execute_server(struct sc_server *server,
|
|||||||
if (params->stay_awake) {
|
if (params->stay_awake) {
|
||||||
ADD_PARAM("stay_awake=true");
|
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) {
|
if (params->video_codec_options) {
|
||||||
VALIDATE_STRING(params->video_codec_options);
|
VALIDATE_STRING(params->video_codec_options);
|
||||||
ADD_PARAM("video_codec_options=%s", 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 video_bit_rate;
|
||||||
uint32_t audio_bit_rate;
|
uint32_t audio_bit_rate;
|
||||||
const char *max_fps; // float to be parsed by the server
|
const char *max_fps; // float to be parsed by the server
|
||||||
|
sc_tick screen_off_timeout;
|
||||||
int8_t lock_video_orientation;
|
int8_t lock_video_orientation;
|
||||||
bool control;
|
bool control;
|
||||||
uint32_t display_id;
|
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
|
## Show touches
|
||||||
|
|
||||||
For presentations, it may be useful to show physical touches (on the physical
|
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();
|
boolean powerOffScreen = options.getPowerOffScreenOnClose();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
run(displayId, restoreStayOn, disableShowTouches, powerOffScreen);
|
run(displayId, restoreStayOn, disableShowTouches, powerOffScreen, restoreScreenOffTimeout);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// ignore
|
// ignore
|
||||||
} catch (IOException e) {
|
} 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 = {
|
String[] cmd = {
|
||||||
"app_process",
|
"app_process",
|
||||||
"/",
|
"/",
|
||||||
@ -93,6 +113,7 @@ public final class CleanUp {
|
|||||||
String.valueOf(restoreStayOn),
|
String.valueOf(restoreStayOn),
|
||||||
String.valueOf(disableShowTouches),
|
String.valueOf(disableShowTouches),
|
||||||
String.valueOf(powerOffScreen),
|
String.valueOf(powerOffScreen),
|
||||||
|
String.valueOf(restoreScreenOffTimeout),
|
||||||
};
|
};
|
||||||
|
|
||||||
ProcessBuilder builder = new ProcessBuilder(cmd);
|
ProcessBuilder builder = new ProcessBuilder(cmd);
|
||||||
@ -139,6 +160,7 @@ public final class CleanUp {
|
|||||||
int restoreStayOn = Integer.parseInt(args[1]);
|
int restoreStayOn = Integer.parseInt(args[1]);
|
||||||
boolean disableShowTouches = Boolean.parseBoolean(args[2]);
|
boolean disableShowTouches = Boolean.parseBoolean(args[2]);
|
||||||
boolean powerOffScreen = Boolean.parseBoolean(args[3]);
|
boolean powerOffScreen = Boolean.parseBoolean(args[3]);
|
||||||
|
int restoreScreenOffTimeout = Integer.parseInt(args[4]);
|
||||||
|
|
||||||
// Dynamic option
|
// Dynamic option
|
||||||
boolean restoreDisplayPower = false;
|
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 (displayId != Device.DISPLAY_ID_NONE && Device.isScreenOn(displayId)) {
|
||||||
if (powerOffScreen) {
|
if (powerOffScreen) {
|
||||||
Ln.i("Power off screen");
|
Ln.i("Power off screen");
|
||||||
|
@ -45,6 +45,7 @@ public class Options {
|
|||||||
private boolean cameraHighSpeed;
|
private boolean cameraHighSpeed;
|
||||||
private boolean showTouches;
|
private boolean showTouches;
|
||||||
private boolean stayAwake;
|
private boolean stayAwake;
|
||||||
|
private int screenOffTimeout = -1;
|
||||||
private List<CodecOption> videoCodecOptions;
|
private List<CodecOption> videoCodecOptions;
|
||||||
private List<CodecOption> audioCodecOptions;
|
private List<CodecOption> audioCodecOptions;
|
||||||
|
|
||||||
@ -174,6 +175,10 @@ public class Options {
|
|||||||
return stayAwake;
|
return stayAwake;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getScreenOffTimeout() {
|
||||||
|
return screenOffTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
public List<CodecOption> getVideoCodecOptions() {
|
public List<CodecOption> getVideoCodecOptions() {
|
||||||
return videoCodecOptions;
|
return videoCodecOptions;
|
||||||
}
|
}
|
||||||
@ -363,6 +368,12 @@ public class Options {
|
|||||||
case "stay_awake":
|
case "stay_awake":
|
||||||
options.stayAwake = Boolean.parseBoolean(value);
|
options.stayAwake = Boolean.parseBoolean(value);
|
||||||
break;
|
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":
|
case "video_codec_options":
|
||||||
options.videoCodecOptions = CodecOption.parse(value);
|
options.videoCodecOptions = CodecOption.parse(value);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user