Use vector for listing USB devices
This avoids the hardcoded maximum number of USB devices detected (16). Refs #3029 <https://github.com/Genymobile/scrcpy/pull/3029> PR #3035 <https://github.com/Genymobile/scrcpy/pull/3035>
This commit is contained in:
parent
c070723bc8
commit
1790e88278
1 changed files with 33 additions and 25 deletions
|
@ -3,6 +3,9 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
#include "util/vector.h"
|
||||||
|
|
||||||
|
struct sc_vec_usb_devices SC_VECTOR(struct sc_usb_device);
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
read_string(libusb_device_handle *handle, uint8_t desc_index) {
|
read_string(libusb_device_handle *handle, uint8_t desc_index) {
|
||||||
|
@ -85,33 +88,39 @@ sc_usb_device_move(struct sc_usb_device *dst, struct sc_usb_device *src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sc_usb_devices_destroy_all(struct sc_usb_device *usb_devices, size_t count) {
|
sc_usb_devices_destroy(struct sc_vec_usb_devices *usb_devices) {
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < usb_devices->size; ++i) {
|
||||||
sc_usb_device_destroy(&usb_devices[i]);
|
sc_usb_device_destroy(&usb_devices->data[i]);
|
||||||
}
|
}
|
||||||
|
sc_vector_destroy(usb_devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static bool
|
||||||
sc_usb_list_devices(struct sc_usb *usb, struct sc_usb_device *devices,
|
sc_usb_list_devices(struct sc_usb *usb, struct sc_vec_usb_devices *out_vec) {
|
||||||
size_t len) {
|
|
||||||
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) {
|
||||||
LOGE("List USB devices: libusb error: %s", libusb_strerror(count));
|
LOGE("List USB devices: libusb error: %s", libusb_strerror(count));
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t idx = 0;
|
for (size_t i = 0; i < (size_t) count; ++i) {
|
||||||
for (size_t i = 0; i < (size_t) count && idx < len; ++i) {
|
|
||||||
libusb_device *device = list[i];
|
libusb_device *device = list[i];
|
||||||
|
|
||||||
if (sc_usb_read_device(device, &devices[idx])) {
|
struct sc_usb_device usb_device;
|
||||||
++idx;
|
if (sc_usb_read_device(device, &usb_device)) {
|
||||||
|
bool ok = sc_vector_push(out_vec, usb_device);
|
||||||
|
if (!ok) {
|
||||||
|
LOG_OOM();
|
||||||
|
LOGE("Could not push usb_device to vector");
|
||||||
|
sc_usb_device_destroy(&usb_device);
|
||||||
|
// continue anyway
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_free_device_list(list, 1);
|
libusb_free_device_list(list, 1);
|
||||||
return idx;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -157,29 +166,28 @@ sc_usb_devices_log(enum sc_log_level level, struct sc_usb_device *devices,
|
||||||
bool
|
bool
|
||||||
sc_usb_select_device(struct sc_usb *usb, const char *serial,
|
sc_usb_select_device(struct sc_usb *usb, const char *serial,
|
||||||
struct sc_usb_device *out_device) {
|
struct sc_usb_device *out_device) {
|
||||||
struct sc_usb_device usb_devices[16];
|
struct sc_vec_usb_devices vec = SC_VECTOR_INITIALIZER;
|
||||||
ssize_t count =
|
bool ok = sc_usb_list_devices(usb, &vec);
|
||||||
sc_usb_list_devices(usb, usb_devices, ARRAY_LEN(usb_devices));
|
if (!ok) {
|
||||||
if (count == -1) {
|
|
||||||
LOGE("Could not list USB devices");
|
LOGE("Could not list USB devices");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == 0) {
|
if (vec.size == 0) {
|
||||||
LOGE("Could not find any USB device");
|
LOGE("Could not find any USB device");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 =
|
size_t sel_count =
|
||||||
sc_usb_devices_select(usb_devices, count, serial, &sel_idx);
|
sc_usb_devices_select(vec.data, vec.size, serial, &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 serial is provided
|
||||||
assert(serial);
|
assert(serial);
|
||||||
LOGE("Could not find USB device %s", serial);
|
LOGE("Could not find USB device %s", serial);
|
||||||
sc_usb_devices_log(SC_LOG_LEVEL_ERROR, usb_devices, count);
|
sc_usb_devices_log(SC_LOG_LEVEL_ERROR, vec.data, vec.size);
|
||||||
sc_usb_devices_destroy_all(usb_devices, count);
|
sc_usb_devices_destroy(&vec);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,21 +198,21 @@ sc_usb_select_device(struct sc_usb *usb, const char *serial,
|
||||||
} else {
|
} else {
|
||||||
LOGE("Multiple (%" SC_PRIsizet ") USB devices:", sel_count);
|
LOGE("Multiple (%" SC_PRIsizet ") USB devices:", sel_count);
|
||||||
}
|
}
|
||||||
sc_usb_devices_log(SC_LOG_LEVEL_ERROR, usb_devices, count);
|
sc_usb_devices_log(SC_LOG_LEVEL_ERROR, vec.data, vec.size);
|
||||||
LOGE("Select a device via -s (--serial)");
|
LOGE("Select a device via -s (--serial)");
|
||||||
sc_usb_devices_destroy_all(usb_devices, count);
|
sc_usb_devices_destroy(&vec);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(sel_count == 1); // sel_idx is valid only if sel_count == 1
|
assert(sel_count == 1); // sel_idx is valid only if sel_count == 1
|
||||||
struct sc_usb_device *device = &usb_devices[sel_idx];
|
struct sc_usb_device *device = &vec.data[sel_idx];
|
||||||
|
|
||||||
LOGD("USB device found:");
|
LOGD("USB device found:");
|
||||||
sc_usb_devices_log(SC_LOG_LEVEL_DEBUG, usb_devices, count);
|
sc_usb_devices_log(SC_LOG_LEVEL_DEBUG, vec.data, vec.size);
|
||||||
|
|
||||||
// Move device into out_device (do not destroy device)
|
// Move device into out_device (do not destroy device)
|
||||||
sc_usb_device_move(out_device, device);
|
sc_usb_device_move(out_device, device);
|
||||||
sc_usb_devices_destroy_all(usb_devices, count);
|
sc_usb_devices_destroy(&vec);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue