Handle "show touches" on the device-side
Now that the server can access the Android settings and clean up properly, handle the "show touches" option from the server. The initial state is now correctly restored, even on device disconnection.
This commit is contained in:
parent
dbb0df607c
commit
4668638ee1
9 changed files with 50 additions and 51 deletions
|
@ -429,7 +429,8 @@ device).
|
||||||
|
|
||||||
Android provides this feature in _Developers options_.
|
Android provides this feature in _Developers options_.
|
||||||
|
|
||||||
_Scrcpy_ provides an option to enable this feature on start and disable on exit:
|
_Scrcpy_ provides an option to enable this feature on start and restore the
|
||||||
|
initial value on exit:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
scrcpy --show-touches
|
scrcpy --show-touches
|
||||||
|
|
|
@ -136,7 +136,7 @@ Turn the device screen off immediately.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-t, \-\-show\-touches
|
.B \-t, \-\-show\-touches
|
||||||
Enable "show touches" on start, disable on quit.
|
Enable "show touches" on start, restore the initial value on exit..
|
||||||
|
|
||||||
It only shows physical touches (not clicks from scrcpy).
|
It only shows physical touches (not clicks from scrcpy).
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,8 @@ scrcpy_print_usage(const char *arg0) {
|
||||||
" Turn the device screen off immediately.\n"
|
" Turn the device screen off immediately.\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -t, --show-touches\n"
|
" -t, --show-touches\n"
|
||||||
" Enable \"show touches\" on start, disable on quit.\n"
|
" Enable \"show touches\" on start, restore the initial value\n"
|
||||||
|
" on exit.\n"
|
||||||
" It only shows physical touches (not clicks from scrcpy).\n"
|
" It only shows physical touches (not clicks from scrcpy).\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -v, --version\n"
|
" -v, --version\n"
|
||||||
|
|
|
@ -229,21 +229,6 @@ event_loop(bool display, bool control) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static process_t
|
|
||||||
set_show_touches_enabled(const char *serial, bool enabled) {
|
|
||||||
const char *value = enabled ? "1" : "0";
|
|
||||||
const char *const adb_cmd[] = {
|
|
||||||
"shell", "settings", "put", "system", "show_touches", value
|
|
||||||
};
|
|
||||||
return adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
wait_show_touches(process_t process) {
|
|
||||||
// reap the process, ignore the result
|
|
||||||
process_check_success(process, "show_touches");
|
|
||||||
}
|
|
||||||
|
|
||||||
static SDL_LogPriority
|
static SDL_LogPriority
|
||||||
sdl_priority_from_av_level(int level) {
|
sdl_priority_from_av_level(int level) {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
|
@ -292,19 +277,12 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
.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,
|
||||||
|
.show_touches = options->show_touches,
|
||||||
};
|
};
|
||||||
if (!server_start(&server, options->serial, ¶ms)) {
|
if (!server_start(&server, options->serial, ¶ms)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
process_t proc_show_touches = PROCESS_NONE;
|
|
||||||
bool show_touches_waited;
|
|
||||||
if (options->show_touches) {
|
|
||||||
LOGI("Enable show_touches");
|
|
||||||
proc_show_touches = set_show_touches_enabled(options->serial, true);
|
|
||||||
show_touches_waited = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
bool fps_counter_initialized = false;
|
bool fps_counter_initialized = false;
|
||||||
|
@ -421,11 +399,6 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->show_touches) {
|
|
||||||
wait_show_touches(proc_show_touches);
|
|
||||||
show_touches_waited = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
input_manager.prefer_text = options->prefer_text;
|
input_manager.prefer_text = options->prefer_text;
|
||||||
|
|
||||||
ret = event_loop(options->display, options->control);
|
ret = event_loop(options->display, options->control);
|
||||||
|
@ -482,16 +455,6 @@ end:
|
||||||
fps_counter_destroy(&fps_counter);
|
fps_counter_destroy(&fps_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->show_touches) {
|
|
||||||
if (!show_touches_waited) {
|
|
||||||
// wait the process which enabled "show touches"
|
|
||||||
wait_show_touches(proc_show_touches);
|
|
||||||
}
|
|
||||||
LOGI("Disable show_touches");
|
|
||||||
proc_show_touches = set_show_touches_enabled(options->serial, false);
|
|
||||||
wait_show_touches(proc_show_touches);
|
|
||||||
}
|
|
||||||
|
|
||||||
server_destroy(&server);
|
server_destroy(&server);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -268,6 +268,7 @@ execute_server(struct server *server, const struct server_params *params) {
|
||||||
"true", // always send frame meta (packet boundaries + timestamp)
|
"true", // always send frame meta (packet boundaries + timestamp)
|
||||||
params->control ? "true" : "false",
|
params->control ? "true" : "false",
|
||||||
display_id_string,
|
display_id_string,
|
||||||
|
params->show_touches ? "true" : "false",
|
||||||
};
|
};
|
||||||
#ifdef SERVER_DEBUGGER
|
#ifdef SERVER_DEBUGGER
|
||||||
LOGI("Server debugger waiting for a client on device port "
|
LOGI("Server debugger waiting for a client on device port "
|
||||||
|
|
|
@ -51,6 +51,7 @@ struct server_params {
|
||||||
int8_t lock_video_orientation;
|
int8_t lock_video_orientation;
|
||||||
bool control;
|
bool control;
|
||||||
uint16_t display_id;
|
uint16_t display_id;
|
||||||
|
bool show_touches;
|
||||||
};
|
};
|
||||||
|
|
||||||
// init default values
|
// init default values
|
||||||
|
|
|
@ -19,19 +19,18 @@ public final class CleanUp {
|
||||||
// not instantiable
|
// not instantiable
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void configure() throws IOException {
|
public static void configure(boolean disableShowTouches) throws IOException {
|
||||||
// TODO
|
boolean needProcess = disableShowTouches;
|
||||||
boolean needProcess = false;
|
|
||||||
if (needProcess) {
|
if (needProcess) {
|
||||||
startProcess();
|
startProcess(disableShowTouches);
|
||||||
} else {
|
} else {
|
||||||
// There is no additional clean up to do when scrcpy dies
|
// There is no additional clean up to do when scrcpy dies
|
||||||
unlinkSelf();
|
unlinkSelf();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void startProcess() throws IOException {
|
private static void startProcess(boolean disableShowTouches) throws IOException {
|
||||||
String[] cmd = {"app_process", "/", CleanUp.class.getName()};
|
String[] cmd = {"app_process", "/", CleanUp.class.getName(), String.valueOf(disableShowTouches)};
|
||||||
|
|
||||||
ProcessBuilder builder = new ProcessBuilder(cmd);
|
ProcessBuilder builder = new ProcessBuilder(cmd);
|
||||||
builder.environment().put("CLASSPATH", SERVER_PATH);
|
builder.environment().put("CLASSPATH", SERVER_PATH);
|
||||||
|
@ -57,6 +56,15 @@ public final class CleanUp {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ln.i("Cleaning up");
|
Ln.i("Cleaning up");
|
||||||
// TODO
|
|
||||||
|
boolean disableShowTouches = Boolean.parseBoolean(args[0]);
|
||||||
|
|
||||||
|
if (disableShowTouches) {
|
||||||
|
ServiceManager serviceManager = new ServiceManager();
|
||||||
|
try (ContentProvider settings = serviceManager.getActivityManager().createSettingsProvider()) {
|
||||||
|
Ln.i("Disabling \"show touches\"");
|
||||||
|
settings.putValue(ContentProvider.TABLE_SYSTEM, "show_touches", "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ public class Options {
|
||||||
private boolean sendFrameMeta; // send PTS so that the client may record properly
|
private boolean sendFrameMeta; // send PTS so that the client may record properly
|
||||||
private boolean control;
|
private boolean control;
|
||||||
private int displayId;
|
private int displayId;
|
||||||
|
private boolean showTouches;
|
||||||
|
|
||||||
public int getMaxSize() {
|
public int getMaxSize() {
|
||||||
return maxSize;
|
return maxSize;
|
||||||
|
@ -84,4 +85,12 @@ public class Options {
|
||||||
public void setDisplayId(int displayId) {
|
public void setDisplayId(int displayId) {
|
||||||
this.displayId = displayId;
|
this.displayId = displayId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getShowTouches() {
|
||||||
|
return showTouches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShowTouches(boolean showTouches) {
|
||||||
|
this.showTouches = showTouches;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.genymobile.scrcpy;
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
|
import com.genymobile.scrcpy.wrappers.ContentProvider;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
@ -17,7 +19,16 @@ public final class Server {
|
||||||
Ln.i("Device: " + Build.MANUFACTURER + " " + Build.MODEL + " (Android " + Build.VERSION.RELEASE + ")");
|
Ln.i("Device: " + Build.MANUFACTURER + " " + Build.MODEL + " (Android " + Build.VERSION.RELEASE + ")");
|
||||||
final Device device = new Device(options);
|
final Device device = new Device(options);
|
||||||
|
|
||||||
CleanUp.configure();
|
boolean mustDisableShowTouchesOnCleanUp = false;
|
||||||
|
if (options.getShowTouches()) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CleanUp.configure(mustDisableShowTouchesOnCleanUp);
|
||||||
|
|
||||||
boolean tunnelForward = options.isTunnelForward();
|
boolean tunnelForward = options.isTunnelForward();
|
||||||
try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) {
|
try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) {
|
||||||
|
@ -80,8 +91,9 @@ public final class Server {
|
||||||
"The server version (" + BuildConfig.VERSION_NAME + ") does not match the client " + "(" + clientVersion + ")");
|
"The server version (" + BuildConfig.VERSION_NAME + ") does not match the client " + "(" + clientVersion + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.length != 10) {
|
final int expectedParameters = 11;
|
||||||
throw new IllegalArgumentException("Expecting 10 parameters");
|
if (args.length != expectedParameters) {
|
||||||
|
throw new IllegalArgumentException("Expecting " + expectedParameters + " parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
Options options = new Options();
|
Options options = new Options();
|
||||||
|
@ -114,6 +126,9 @@ public final class Server {
|
||||||
int displayId = Integer.parseInt(args[9]);
|
int displayId = Integer.parseInt(args[9]);
|
||||||
options.setDisplayId(displayId);
|
options.setDisplayId(displayId);
|
||||||
|
|
||||||
|
boolean showTouches = Boolean.parseBoolean(args[10]);
|
||||||
|
options.setShowTouches(showTouches);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue