Expose simple API to select a single USB device

The caller just wants a single device. Handle all cases and error
messages internally.

PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
This commit is contained in:
Romain Vimont 2022-02-05 19:12:59 +01:00
parent b88c4aa75e
commit 61969aeb80
4 changed files with 63 additions and 66 deletions

View file

@ -430,32 +430,19 @@ scrcpy(struct scrcpy_options *options) {
} }
assert(serial); assert(serial);
struct sc_usb_device usb_devices[16]; struct sc_usb_device usb_device;
ssize_t count = sc_usb_find_devices(&s->usb, serial, usb_devices, ok = sc_usb_select_device(&s->usb, serial, &usb_device);
ARRAY_LEN(usb_devices)); if (!ok) {
if (count <= 0) {
LOGE("Could not find USB device %s", serial);
sc_usb_destroy(&s->usb); sc_usb_destroy(&s->usb);
sc_acksync_destroy(&s->acksync);
goto aoa_hid_end; goto aoa_hid_end;
} }
if (count > 1) {
LOGE("Multiple (%d) devices with serial %s", (int) count, serial);
sc_usb_devices_destroy_all(usb_devices, count);
sc_usb_destroy(&s->usb);
sc_acksync_destroy(&s->acksync);
goto aoa_hid_end;
}
struct sc_usb_device *usb_device = &usb_devices[0];
LOGI("USB device: %s (%04" PRIx16 ":%04" PRIx16 ") %s %s", LOGI("USB device: %s (%04" PRIx16 ":%04" PRIx16 ") %s %s",
usb_device->serial, usb_device->vid, usb_device->pid, usb_device.serial, usb_device.vid, usb_device.pid,
usb_device->manufacturer, usb_device->product); usb_device.manufacturer, usb_device.product);
ok = sc_usb_connect(&s->usb, usb_device->device, NULL, NULL); ok = sc_usb_connect(&s->usb, usb_device.device, NULL, NULL);
sc_usb_device_destroy(usb_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

@ -83,50 +83,17 @@ scrcpy_otg(struct scrcpy_options *options) {
return false; return false;
} }
struct sc_usb_device usb_devices[16]; struct sc_usb_device usb_device;
ssize_t count = sc_usb_find_devices(&s->usb, serial, usb_devices, ok = sc_usb_select_device(&s->usb, serial, &usb_device);
ARRAY_LEN(usb_devices)); if (!ok) {
if (count < 0) {
LOGE("Could not list USB devices");
goto end; goto end;
} }
if (count == 0) {
if (serial) {
LOGE("Could not find USB device %s", serial);
} else {
LOGE("Could not find any USB device");
}
goto end;
}
if (count > 1) {
if (serial) {
LOGE("Multiple (%d) USB devices with serial %s:", (int) count,
serial);
} else {
LOGE("Multiple (%d) USB devices:", (int) count);
}
for (size_t i = 0; i < (size_t) count; ++i) {
struct sc_usb_device *d = &usb_devices[i];
LOGE(" %-18s (%04" PRIx16 ":%04" PRIx16 ") %s %s",
d->serial, d->vid, d->pid, d->manufacturer, d->product);
}
if (!serial) {
LOGE("Specify the device via -s or --serial");
}
sc_usb_devices_destroy_all(usb_devices, count);
goto end;
}
usb_device_initialized = true;
struct sc_usb_device *usb_device = &usb_devices[0];
LOGI("USB device: %s (%04" PRIx16 ":%04" PRIx16 ") %s %s", LOGI("USB device: %s (%04" PRIx16 ":%04" PRIx16 ") %s %s",
usb_device->serial, usb_device->vid, usb_device->pid, usb_device.serial, usb_device.vid, usb_device.pid,
usb_device->manufacturer, usb_device->product); usb_device.manufacturer, usb_device.product);
ok = sc_usb_connect(&s->usb, usb_device->device, &cbs, NULL); ok = sc_usb_connect(&s->usb, usb_device.device, &cbs, NULL);
if (!ok) { if (!ok) {
goto end; goto end;
} }
@ -173,7 +140,7 @@ scrcpy_otg(struct scrcpy_options *options) {
const char *window_title = options->window_title; const char *window_title = options->window_title;
if (!window_title) { if (!window_title) {
window_title = usb_device->product ? usb_device->product : "scrcpy"; window_title = usb_device.product ? usb_device.product : "scrcpy";
} }
struct sc_screen_otg_params params = { struct sc_screen_otg_params params = {
@ -192,7 +159,7 @@ scrcpy_otg(struct scrcpy_options *options) {
} }
// usb_device not needed anymore // usb_device not needed anymore
sc_usb_device_destroy(usb_device); sc_usb_device_destroy(&usb_device);
usb_device_initialized = false; usb_device_initialized = false;
ret = event_loop(s); ret = event_loop(s);
@ -223,7 +190,7 @@ end:
} }
if (usb_device_initialized) { if (usb_device_initialized) {
sc_usb_device_destroy(usb_device); sc_usb_device_destroy(&usb_device);
} }
sc_usb_destroy(&s->usb); sc_usb_destroy(&s->usb);

View file

@ -96,7 +96,7 @@ sc_usb_devices_destroy_all(struct sc_usb_device *usb_devices, size_t count) {
} }
} }
ssize_t static ssize_t
sc_usb_find_devices(struct sc_usb *usb, const char *serial, sc_usb_find_devices(struct sc_usb *usb, const char *serial,
struct sc_usb_device *devices, size_t len) { struct sc_usb_device *devices, size_t len) {
libusb_device **list; libusb_device **list;
@ -119,6 +119,49 @@ sc_usb_find_devices(struct sc_usb *usb, const char *serial,
return idx; return idx;
} }
bool
sc_usb_select_device(struct sc_usb *usb, const char *serial,
struct sc_usb_device *out_device) {
struct sc_usb_device usb_devices[16];
ssize_t count = sc_usb_find_devices(usb, serial, usb_devices,
ARRAY_LEN(usb_devices));
if (count == -1) {
LOGE("Could not list USB devices");
return false;
}
if (count == 0) {
if (serial) {
LOGE("Could not find USB device %s", serial);
} else {
LOGE("Could not find any USB device");
}
return false;
}
if (count > 1) {
if (serial) {
LOGE("Multiple (%" SC_PRIsizet ") USB devices with serial %s:",
count, serial);
} else {
LOGE("Multiple (%" SC_PRIsizet ") USB devices:", count);
}
for (size_t i = 0; i < (size_t) count; ++i) {
struct sc_usb_device *d = &usb_devices[i];
LOGE(" %-18s (%04" PRIx16 ":%04" PRIx16 ") %s %s",
d->serial, d->vid, d->pid, d->manufacturer, d->product);
}
LOGE("Select a device via -s (--serial)");
sc_usb_devices_destroy_all(usb_devices, count);
return false;
}
assert(count == 1);
// Move usb_devices[0] into out_device (do not destroy usb_devices[0])
*out_device = usb_devices[0];
return true;
}
bool bool
sc_usb_init(struct sc_usb *usb) { sc_usb_init(struct sc_usb *usb) {
usb->handle = NULL; usb->handle = NULL;

View file

@ -61,9 +61,9 @@ sc_usb_init(struct sc_usb *usb);
void void
sc_usb_destroy(struct sc_usb *usb); sc_usb_destroy(struct sc_usb *usb);
ssize_t bool
sc_usb_find_devices(struct sc_usb *usb, const char *serial, sc_usb_select_device(struct sc_usb *usb, const char *serial,
struct sc_usb_device *devices, size_t len); struct sc_usb_device *out_device);
bool bool
sc_usb_connect(struct sc_usb *usb, libusb_device *device, sc_usb_connect(struct sc_usb *usb, libusb_device *device,