Find a list of devices instead of a single one

Several devices may match the requested serial, but above all, this
paves the way to list all devices (when no serial is provided).

PR #2974 <https://github.com/Genymobile/scrcpy/pull/2974>
This commit is contained in:
Romain Vimont 2022-01-26 22:08:55 +01:00
parent d8b37fe189
commit 1c17f57c10
3 changed files with 41 additions and 20 deletions

View file

@ -432,21 +432,32 @@ scrcpy(struct scrcpy_options *options) {
} }
assert(serial); assert(serial);
struct sc_usb_device usb_device; struct sc_usb_device usb_devices[16];
ok = sc_usb_find_device(&s->usb, serial, &usb_device); ssize_t count = sc_usb_find_devices(&s->usb, serial, usb_devices,
if (!ok) { ARRAY_LEN(usb_devices));
if (count <= 0) {
LOGE("Could not find USB device %s", serial); LOGE("Could not find USB device %s", serial);
sc_usb_destroy(&s->usb); sc_usb_destroy(&s->usb);
sc_acksync_destroy(&s->acksync); sc_acksync_destroy(&s->acksync);
goto aoa_hid_end; goto aoa_hid_end;
} }
LOGI("USB device: %s (%04" PRIx16 ":%04" PRIx16 ") %s %s", if (count > 1) {
usb_device.serial, usb_device.vid, usb_device.pid, LOGE("Multiple (%d) devices with serial %s", (int) count, serial);
usb_device.manufacturer, usb_device.product); sc_usb_device_destroy_all(usb_devices, count);
sc_usb_destroy(&s->usb);
sc_acksync_destroy(&s->acksync);
goto aoa_hid_end;
}
ok = sc_usb_connect(&s->usb, usb_device.device); struct sc_usb_device *usb_device = &usb_devices[0];
sc_usb_device_destroy(&usb_device);
LOGI("USB device: %s (%04" PRIx16 ":%04" PRIx16 ") %s %s",
usb_device->serial, usb_device->vid, usb_device->pid,
usb_device->manufacturer, usb_device->product);
ok = sc_usb_connect(&s->usb, usb_device->device);
sc_usb_device_destroy(usb_device);
if (!ok) { if (!ok) {
LOGE("Failed to connect to USB device %s", serial); LOGE("Failed to connect to USB device %s", serial);
sc_usb_destroy(&s->usb); sc_usb_destroy(&s->usb);

View file

@ -80,29 +80,36 @@ sc_usb_device_destroy(struct sc_usb_device *usb_device) {
free(usb_device->product); free(usb_device->product);
} }
bool void
sc_usb_find_device(struct sc_usb *usb, const char *serial, sc_usb_device_destroy_all(struct sc_usb_device *usb_devices, size_t count) {
struct sc_usb_device *out) { for (size_t i = 0; i < count; ++i) {
sc_usb_device_destroy(&usb_devices[i]);
}
}
ssize_t
sc_usb_find_devices(struct sc_usb *usb, const char *serial,
struct sc_usb_device *devices, size_t len) {
assert(serial); assert(serial);
libusb_device **list; libusb_device **list;
ssize_t count = libusb_get_device_list(usb->context, &list); ssize_t count = libusb_get_device_list(usb->context, &list);
if (count < 0) { if (count < 0) {
log_libusb_error((enum libusb_error) count); log_libusb_error((enum libusb_error) count);
return false; return -1;
} }
for (size_t i = 0; i < (size_t) count; ++i) { size_t idx = 0;
for (size_t i = 0; i < (size_t) count && idx < len; ++i) {
libusb_device *device = list[i]; libusb_device *device = list[i];
if (accept_device(device, serial, out)) { if (accept_device(device, serial, &devices[idx])) {
libusb_free_device_list(list, 1); ++idx;
return true;
} }
} }
libusb_free_device_list(list, 1); libusb_free_device_list(list, 1);
return false; return idx;
} }
static libusb_device_handle * static libusb_device_handle *

View file

@ -23,15 +23,18 @@ struct sc_usb_device {
void void
sc_usb_device_destroy(struct sc_usb_device *usb_device); sc_usb_device_destroy(struct sc_usb_device *usb_device);
void
sc_usb_device_destroy_all(struct sc_usb_device *usb_devices, size_t count);
bool bool
sc_usb_init(struct sc_usb *usb); sc_usb_init(struct sc_usb *usb);
void void
sc_usb_destroy(struct sc_usb *usb); sc_usb_destroy(struct sc_usb *usb);
bool ssize_t
sc_usb_find_device(struct sc_usb *usb, const char *serial, sc_usb_find_devices(struct sc_usb *usb, const char *serial,
struct sc_usb_device *out); struct sc_usb_device *devices, size_t len);
bool bool
sc_usb_connect(struct sc_usb *usb, libusb_device *device); sc_usb_connect(struct sc_usb *usb, libusb_device *device);