Introduce adb device selector
Currently, a device is selected either from a specific serial, or if it is the only one connected. In order to support selecting the only device connected via USB or via TCP/IP separately, introduce a new selection structure. PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
This commit is contained in:
parent
5ed13ef477
commit
146f65d7b2
3 changed files with 85 additions and 38 deletions
|
@ -424,39 +424,49 @@ sc_adb_list_devices(struct sc_intr *intr, unsigned flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
sc_adb_accept_device(const struct sc_adb_device *device, const char *serial) {
|
sc_adb_accept_device(const struct sc_adb_device *device,
|
||||||
if (!serial) {
|
const struct sc_adb_device_selector *selector) {
|
||||||
|
switch (selector->type) {
|
||||||
|
case SC_ADB_DEVICE_SELECT_ALL:
|
||||||
return true;
|
return true;
|
||||||
}
|
case SC_ADB_DEVICE_SELECT_SERIAL:
|
||||||
|
assert(selector->serial);
|
||||||
char *device_serial_colon = strchr(device->serial, ':');
|
char *device_serial_colon = strchr(device->serial, ':');
|
||||||
if (device_serial_colon) {
|
if (device_serial_colon) {
|
||||||
// The device serial is an IP:port...
|
// The device serial is an IP:port...
|
||||||
char *serial_colon = strchr(serial, ':');
|
char *serial_colon = strchr(selector->serial, ':');
|
||||||
if (!serial_colon) {
|
if (!serial_colon) {
|
||||||
// But the requested serial has no ':', so only consider the IP part
|
// But the requested serial has no ':', so only consider
|
||||||
// of the device serial. This allows to use "192.168.1.1" to match
|
// the IP part of the device serial. This allows to use
|
||||||
// any "192.168.1.1:port".
|
// "192.168.1.1" to match any "192.168.1.1:port".
|
||||||
size_t serial_len = strlen(serial);
|
size_t serial_len = strlen(selector->serial);
|
||||||
size_t device_ip_len = device_serial_colon - device->serial;
|
size_t device_ip_len = device_serial_colon - device->serial;
|
||||||
if (serial_len != device_ip_len) {
|
if (serial_len != device_ip_len) {
|
||||||
// They are not equal, they don't even have the same length
|
// They are not equal, they don't even have the same
|
||||||
|
// length
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return !strncmp(serial, device->serial, device_ip_len);
|
return !strncmp(selector->serial, device->serial,
|
||||||
|
device_ip_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return !strcmp(selector->serial, device->serial);
|
||||||
|
default:
|
||||||
|
assert(!"Missing SC_ADB_DEVICE_SELECT_* handling");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return !strcmp(serial, device->serial);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
sc_adb_devices_select(struct sc_adb_device *devices, size_t len,
|
sc_adb_devices_select(struct sc_adb_device *devices, size_t len,
|
||||||
const char *serial, size_t *idx_out) {
|
const struct sc_adb_device_selector *selector,
|
||||||
|
size_t *idx_out) {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
for (size_t i = 0; i < len; ++i) {
|
for (size_t i = 0; i < len; ++i) {
|
||||||
struct sc_adb_device *device = &devices[i];
|
struct sc_adb_device *device = &devices[i];
|
||||||
device->selected = sc_adb_accept_device(device, serial);
|
device->selected = sc_adb_accept_device(device, selector);
|
||||||
if (device->selected) {
|
if (device->selected) {
|
||||||
if (idx_out && !count) {
|
if (idx_out && !count) {
|
||||||
*idx_out = i;
|
*idx_out = i;
|
||||||
|
@ -502,8 +512,9 @@ sc_adb_device_check_state(struct sc_adb_device *device,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_adb_select_device(struct sc_intr *intr, const char *serial, unsigned flags,
|
sc_adb_select_device(struct sc_intr *intr,
|
||||||
struct sc_adb_device *out_device) {
|
const struct sc_adb_device_selector *selector,
|
||||||
|
unsigned flags, struct sc_adb_device *out_device) {
|
||||||
struct sc_adb_device devices[16];
|
struct sc_adb_device devices[16];
|
||||||
ssize_t count =
|
ssize_t count =
|
||||||
sc_adb_list_devices(intr, flags, devices, ARRAY_LEN(devices));
|
sc_adb_list_devices(intr, flags, devices, ARRAY_LEN(devices));
|
||||||
|
@ -518,23 +529,42 @@ sc_adb_select_device(struct sc_intr *intr, const char *serial, unsigned flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sel_idx; // index of the single matching device if sel_count == 1
|
size_t sel_idx; // index of the single matching device if sel_count == 1
|
||||||
size_t sel_count = sc_adb_devices_select(devices, count, serial, &sel_idx);
|
size_t sel_count =
|
||||||
|
sc_adb_devices_select(devices, count, selector, &sel_idx);
|
||||||
|
|
||||||
if (sel_count == 0) {
|
if (sel_count == 0) {
|
||||||
// if count > 0 && sel_count == 0, then necessarily a serial is provided
|
// if count > 0 && sel_count == 0, then necessarily a selection is
|
||||||
assert(serial);
|
// requested
|
||||||
LOGE("Could not find ADB device %s", serial);
|
assert(selector->type != SC_ADB_DEVICE_SELECT_ALL);
|
||||||
|
|
||||||
|
switch (selector->type) {
|
||||||
|
case SC_ADB_DEVICE_SELECT_SERIAL:
|
||||||
|
assert(selector->serial);
|
||||||
|
LOGE("Could not find ADB device %s:", selector->serial);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(!"Unexpected selector type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
sc_adb_devices_log(SC_LOG_LEVEL_ERROR, devices, count);
|
sc_adb_devices_log(SC_LOG_LEVEL_ERROR, devices, count);
|
||||||
sc_adb_devices_destroy_all(devices, count);
|
sc_adb_devices_destroy_all(devices, count);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sel_count > 1) {
|
if (sel_count > 1) {
|
||||||
if (serial) {
|
switch (selector->type) {
|
||||||
LOGE("Multiple (%" SC_PRIsizet ") ADB devices with serial %s:",
|
case SC_ADB_DEVICE_SELECT_ALL:
|
||||||
sel_count, serial);
|
|
||||||
} else {
|
|
||||||
LOGE("Multiple (%" SC_PRIsizet ") ADB devices:", sel_count);
|
LOGE("Multiple (%" SC_PRIsizet ") ADB devices:", sel_count);
|
||||||
|
break;
|
||||||
|
case SC_ADB_DEVICE_SELECT_SERIAL:
|
||||||
|
assert(selector->serial);
|
||||||
|
LOGE("Multiple (%" SC_PRIsizet ") ADB devices with serial %s:",
|
||||||
|
sel_count, selector->serial);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(!"Unexpected selector type");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
sc_adb_devices_log(SC_LOG_LEVEL_ERROR, devices, count);
|
sc_adb_devices_log(SC_LOG_LEVEL_ERROR, devices, count);
|
||||||
LOGE("Select a device via -s (--serial)");
|
LOGE("Select a device via -s (--serial)");
|
||||||
|
|
|
@ -18,6 +18,16 @@
|
||||||
const char *
|
const char *
|
||||||
sc_adb_get_executable(void);
|
sc_adb_get_executable(void);
|
||||||
|
|
||||||
|
enum sc_adb_device_selector_type {
|
||||||
|
SC_ADB_DEVICE_SELECT_ALL,
|
||||||
|
SC_ADB_DEVICE_SELECT_SERIAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sc_adb_device_selector {
|
||||||
|
enum sc_adb_device_selector_type type;
|
||||||
|
const char *serial;
|
||||||
|
};
|
||||||
|
|
||||||
sc_pid
|
sc_pid
|
||||||
sc_adb_execute(const char *const argv[], unsigned flags);
|
sc_adb_execute(const char *const argv[], unsigned flags);
|
||||||
|
|
||||||
|
@ -79,8 +89,9 @@ sc_adb_disconnect(struct sc_intr *intr, const char *ip_port, unsigned flags);
|
||||||
* Return true if a single matching device is found, and write it to out_device.
|
* Return true if a single matching device is found, and write it to out_device.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
sc_adb_select_device(struct sc_intr *intr, const char *serial, unsigned flags,
|
sc_adb_select_device(struct sc_intr *intr,
|
||||||
struct sc_adb_device *out_device);
|
const struct sc_adb_device_selector *selector,
|
||||||
|
unsigned flags, struct sc_adb_device *out_device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute `adb getprop <prop>`
|
* Execute `adb getprop <prop>`
|
||||||
|
|
|
@ -687,9 +687,15 @@ run_server(void *data) {
|
||||||
bool need_initial_serial = !params->tcpip_dst;
|
bool need_initial_serial = !params->tcpip_dst;
|
||||||
|
|
||||||
if (need_initial_serial) {
|
if (need_initial_serial) {
|
||||||
|
struct sc_adb_device_selector selector;
|
||||||
|
if (params->req_serial) {
|
||||||
|
selector.type = SC_ADB_DEVICE_SELECT_SERIAL;
|
||||||
|
selector.serial = params->req_serial;
|
||||||
|
} else {
|
||||||
|
selector.type = SC_ADB_DEVICE_SELECT_ALL;
|
||||||
|
}
|
||||||
struct sc_adb_device device;
|
struct sc_adb_device device;
|
||||||
ok = sc_adb_select_device(&server->intr, params->req_serial, 0,
|
ok = sc_adb_select_device(&server->intr, &selector, 0, &device);
|
||||||
&device);
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue