Use current adb port (if any) for --tcpip

If the current adb port is not 5555 (typically 0 because it is not in
TCP/IP mode), --tcpip automatically executes (among other commands):

    adb tcpip 5555

In case adb was already listening on another port, this command forced
to listen on 5555, and the connection should still succeed.

But this reconfiguration might be inconvenient for the user. If adb is
already in TCP/IP mode, use the current enabled port without
reconfiguration.

Fixes #3591 <https://github.com/Genymobile/scrcpy/issues/3591>
This commit is contained in:
Romain Vimont 2022-11-24 09:04:42 +01:00
parent 6469b55861
commit bd1deffa70
4 changed files with 54 additions and 41 deletions

View file

@ -395,8 +395,8 @@ address), connect the device over USB, then run:
scrcpy --tcpip # without arguments scrcpy --tcpip # without arguments
``` ```
It will automatically find the device IP address, enable TCP/IP mode, then It will automatically find the device IP address and adb port, enable TCP/IP
connect to the device before starting. mode if necessary, then connect to the device before starting.
##### Manual ##### Manual

View file

@ -275,7 +275,7 @@ Configure and reconnect the device over TCP/IP.
If a destination address is provided, then scrcpy connects to this address before starting. The device must listen on the given TCP port (default is 5555). If a destination address is provided, then scrcpy connects to this address before starting. The device must listen on the given TCP port (default is 5555).
If no destination address is provided, then scrcpy attempts to find the IP address of the current device (typically connected over USB), enables TCP/IP mode, then connects to this address before starting. If no destination address is provided, then scrcpy attempts to find the IP address and adb port of the current device (typically connected over USB), enables TCP/IP mode if necessary, then connects to this address before starting.
.TP .TP
.B \-S, \-\-turn\-screen\-off .B \-S, \-\-turn\-screen\-off

View file

@ -19,6 +19,8 @@
#define SC_SERVER_PATH_DEFAULT PREFIX "/share/scrcpy/" SC_SERVER_FILENAME #define SC_SERVER_PATH_DEFAULT PREFIX "/share/scrcpy/" SC_SERVER_FILENAME
#define SC_DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar" #define SC_DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar"
#define SC_ADB_PORT_DEFAULT 5555
static char * static char *
get_server_path(void) { get_server_path(void) {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
@ -513,27 +515,36 @@ sc_server_on_terminated(void *userdata) {
LOGD("Server terminated"); LOGD("Server terminated");
} }
static bool static uint16_t
is_tcpip_mode_enabled(struct sc_server *server, const char *serial) { get_adb_tcp_port(struct sc_server *server, const char *serial) {
struct sc_intr *intr = &server->intr; struct sc_intr *intr = &server->intr;
char *current_port = char *current_port =
sc_adb_getprop(intr, serial, "service.adb.tcp.port", SC_ADB_SILENT); sc_adb_getprop(intr, serial, "service.adb.tcp.port", SC_ADB_SILENT);
if (!current_port) { if (!current_port) {
return false; return 0;
} }
// Is the device is listening on TCP on port 5555? long value;
bool enabled = !strcmp("5555", current_port); bool ok = sc_str_parse_integer(current_port, &value);
free(current_port); free(current_port);
return enabled; if (!ok) {
return 0;
}
if (value < 0 || value > 0xFFFF) {
return 0;
}
return value;
} }
static bool static bool
wait_tcpip_mode_enabled(struct sc_server *server, const char *serial, wait_tcpip_mode_enabled(struct sc_server *server, const char *serial,
unsigned attempts, sc_tick delay) { uint16_t expected_port, unsigned attempts,
if (is_tcpip_mode_enabled(server, serial)) { sc_tick delay) {
LOGI("TCP/IP mode enabled"); uint16_t adb_port = get_adb_tcp_port(server, serial);
if (adb_port == expected_port) {
return true; return true;
} }
@ -547,28 +558,23 @@ wait_tcpip_mode_enabled(struct sc_server *server, const char *serial,
return false; return false;
} }
if (is_tcpip_mode_enabled(server, serial)) { adb_port = get_adb_tcp_port(server, serial);
LOGI("TCP/IP mode enabled"); if (adb_port == expected_port) {
return true; return true;
} }
} while (--attempts); } while (--attempts);
return false; return false;
} }
char * static char *
append_port_5555(const char *ip) { append_port(const char *ip, uint16_t port) {
size_t len = strlen(ip); char *ip_port;
int ret = asprintf(&ip_port, "%s:%" PRIu16, ip, port);
// sizeof counts the final '\0' if (ret == -1) {
char *ip_port = malloc(len + sizeof(":5555"));
if (!ip_port) {
LOG_OOM(); LOG_OOM();
return NULL; return NULL;
} }
memcpy(ip_port, ip, len);
memcpy(ip_port + len, ":5555", sizeof(":5555"));
return ip_port; return ip_port;
} }
@ -586,34 +592,36 @@ sc_server_switch_to_tcpip(struct sc_server *server, const char *serial) {
return NULL; return NULL;
} }
char *ip_port = append_port_5555(ip); uint16_t adb_port = get_adb_tcp_port(server, serial);
free(ip); if (adb_port) {
if (!ip_port) { LOGI("TCP/IP mode already enabled on port %" PRIu16, adb_port);
return NULL; } else {
} LOGI("Enabling TCP/IP mode on port " SC_STR(SC_ADB_PORT_DEFAULT) "...");
bool tcp_mode = is_tcpip_mode_enabled(server, serial); bool ok = sc_adb_tcpip(intr, serial, SC_ADB_PORT_DEFAULT,
SC_ADB_NO_STDOUT);
if (!tcp_mode) {
bool ok = sc_adb_tcpip(intr, serial, 5555, SC_ADB_NO_STDOUT);
if (!ok) { if (!ok) {
LOGE("Could not restart adbd in TCP/IP mode"); LOGE("Could not restart adbd in TCP/IP mode");
goto error; free(ip);
return NULL;
} }
unsigned attempts = 40; unsigned attempts = 40;
sc_tick delay = SC_TICK_FROM_MS(250); sc_tick delay = SC_TICK_FROM_MS(250);
ok = wait_tcpip_mode_enabled(server, serial, attempts, delay); ok = wait_tcpip_mode_enabled(server, serial, SC_ADB_PORT_DEFAULT,
attempts, delay);
if (!ok) { if (!ok) {
goto error; free(ip);
}
}
return ip_port;
error:
free(ip_port);
return NULL; return NULL;
}
adb_port = SC_ADB_PORT_DEFAULT;
LOGI("TCP/IP mode enabled on port " SC_STR(SC_ADB_PORT_DEFAULT));
}
char *ip_port = append_port(ip, adb_port);
free(ip);
return ip_port;
} }
static bool static bool
@ -640,7 +648,8 @@ sc_server_configure_tcpip_known_address(struct sc_server *server,
const char *addr) { const char *addr) {
// Append ":5555" if no port is present // Append ":5555" if no port is present
bool contains_port = strchr(addr, ':'); bool contains_port = strchr(addr, ':');
char *ip_port = contains_port ? strdup(addr) : append_port_5555(addr); char *ip_port = contains_port ? strdup(addr)
: append_port(addr, SC_ADB_PORT_DEFAULT);
if (!ip_port) { if (!ip_port) {
LOG_OOM(); LOG_OOM();
return false; return false;

View file

@ -6,6 +6,10 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
/* Stringify a numeric value */
#define SC_STR(s) SC_XSTR(s)
#define SC_XSTR(s) #s
/** /**
* Like strncpy(), except: * Like strncpy(), except:
* - it copies at most n-1 chars * - it copies at most n-1 chars