Report USB device disconnection when detected
USB device disconnection is detected via a hotplug callback when it is supported. In addition, report disconnection on libusb calls returning LIBUSB_ERROR_NO_DEVICE or LIBUSB_ERROR_NOT_FOUND. This allows to detect disconnection after a libusb call when hotplug is not available. PR #3011 <https://github.com/Genymobile/scrcpy/pull/3011>
This commit is contained in:
parent
3ee3f8dc02
commit
be1936bb85
3 changed files with 30 additions and 2 deletions
|
@ -95,6 +95,7 @@ sc_aoa_register_hid(struct sc_aoa *aoa, uint16_t accessory_id,
|
|||
DEFAULT_TIMEOUT);
|
||||
if (result < 0) {
|
||||
LOGE("REGISTER_HID: libusb error: %s", libusb_strerror(result));
|
||||
sc_usb_check_disconnected(aoa->usb, result);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -131,6 +132,7 @@ sc_aoa_set_hid_report_desc(struct sc_aoa *aoa, uint16_t accessory_id,
|
|||
DEFAULT_TIMEOUT);
|
||||
if (result < 0) {
|
||||
LOGE("SET_HID_REPORT_DESC: libusb error: %s", libusb_strerror(result));
|
||||
sc_usb_check_disconnected(aoa->usb, result);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -173,6 +175,7 @@ sc_aoa_send_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) {
|
|||
DEFAULT_TIMEOUT);
|
||||
if (result < 0) {
|
||||
LOGE("SEND_HID_EVENT: libusb error: %s", libusb_strerror(result));
|
||||
sc_usb_check_disconnected(aoa->usb, result);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -195,6 +198,7 @@ sc_aoa_unregister_hid(struct sc_aoa *aoa, const uint16_t accessory_id) {
|
|||
DEFAULT_TIMEOUT);
|
||||
if (result < 0) {
|
||||
LOGE("UNREGISTER_HID: libusb error: %s", libusb_strerror(result));
|
||||
sc_usb_check_disconnected(aoa->usb, result);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -216,6 +216,24 @@ sc_usb_destroy(struct sc_usb *usb) {
|
|||
libusb_exit(usb->context);
|
||||
}
|
||||
|
||||
static void
|
||||
sc_usb_report_disconnected(struct sc_usb *usb) {
|
||||
if (usb->cbs && !atomic_flag_test_and_set(&usb->disconnection_notified)) {
|
||||
assert(usb->cbs && usb->cbs->on_disconnected);
|
||||
usb->cbs->on_disconnected(usb, usb->cbs_userdata);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
sc_usb_check_disconnected(struct sc_usb *usb, int result) {
|
||||
if (result == LIBUSB_ERROR_NO_DEVICE || result == LIBUSB_ERROR_NOT_FOUND) {
|
||||
sc_usb_report_disconnected(usb);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
sc_usb_libusb_callback(libusb_context *ctx, libusb_device *device,
|
||||
libusb_hotplug_event event, void *userdata) {
|
||||
|
@ -232,8 +250,7 @@ sc_usb_libusb_callback(libusb_context *ctx, libusb_device *device,
|
|||
return 0;
|
||||
}
|
||||
|
||||
assert(usb->cbs && usb->cbs->on_disconnected);
|
||||
usb->cbs->on_disconnected(usb, usb->cbs_userdata);
|
||||
sc_usb_report_disconnected(usb);
|
||||
|
||||
// Do not automatically deregister the callback by returning 1. Instead,
|
||||
// manually deregister to interrupt libusb_handle_events() from the libusb
|
||||
|
@ -307,6 +324,7 @@ sc_usb_connect(struct sc_usb *usb, libusb_device *device,
|
|||
|
||||
if (cbs) {
|
||||
atomic_init(&usb->stopped, false);
|
||||
usb->disconnection_notified = (atomic_flag) ATOMIC_FLAG_INIT;
|
||||
if (sc_usb_register_callback(usb)) {
|
||||
// Create a thread to process libusb events, so that device
|
||||
// disconnection could be detected immediately
|
||||
|
|
|
@ -22,6 +22,7 @@ struct sc_usb {
|
|||
sc_thread libusb_event_thread;
|
||||
|
||||
atomic_bool stopped; // only used if cbs != NULL
|
||||
atomic_flag disconnection_notified;
|
||||
};
|
||||
|
||||
struct sc_usb_callbacks {
|
||||
|
@ -73,6 +74,11 @@ sc_usb_connect(struct sc_usb *usb, libusb_device *device,
|
|||
void
|
||||
sc_usb_disconnect(struct sc_usb *usb);
|
||||
|
||||
// A client should call this function with the return value of a libusb call
|
||||
// to detect disconnection immediately
|
||||
bool
|
||||
sc_usb_check_disconnected(struct sc_usb *usb, int result);
|
||||
|
||||
void
|
||||
sc_usb_stop(struct sc_usb *usb);
|
||||
|
||||
|
|
Loading…
Reference in a new issue