ports/devel/android-tools-adb/files/patch-adb_client_usb__libusb.cpp

130 lines
4.1 KiB
C++

--- adb/client/usb_libusb.cpp.orig 2017-06-20 10:50:27 UTC
+++ adb/client/usb_libusb.cpp
@@ -22,13 +22,14 @@
#include <atomic>
#include <chrono>
+#include <condition_variable>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_map>
-#include <libusb/libusb.h>
+#include <libusb.h>
#include <android-base/file.h>
#include <android-base/logging.h>
@@ -89,7 +89,11 @@ struct transfer_info {
};
namespace libusb {
+#if defined(__linux__) || defined(__APPLE__)
struct usb_handle : public ::usb_handle {
+#else
+struct usb_handle {
+#endif
usb_handle(const std::string& device_address, const std::string& serial,
unique_device_handle&& device_handle, uint8_t interface, uint8_t bulk_in,
uint8_t bulk_out, size_t zero_mask, size_t max_packet_size)
@@ -152,7 +156,14 @@ struct usb_handle : public ::usb_handle {
static auto& usb_handles = *new std::unordered_map<std::string, std::unique_ptr<usb_handle>>();
static auto& usb_handles_mutex = *new std::mutex();
+#if defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000102
static libusb_hotplug_callback_handle hotplug_handle;
+#else
+static std::thread* device_poll_thread = nullptr;
+static bool terminate_device_poll_thread = false;
+static auto& device_poll_mutex = *new std::mutex();
+static auto& device_poll_cv = *new std::condition_variable();
+#endif
static std::string get_device_address(libusb_device* device) {
return StringPrintf("usb:%d:%d", libusb_get_bus_number(device),
@@ -380,6 +391,7 @@ static void process_device(libusb_device* device) {
LOG(INFO) << "registered new usb device '" << device_serial << "'";
}
+#if defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000102
static std::atomic<int> connecting_devices(0);
static void device_connected(libusb_device* device) {
@@ -449,7 +461,31 @@ static int hotplug_callback(libusb_context*, libusb_de
hotplug_queue.Push({event, device});
return 0;
}
+#else
+static void poll_for_devices() {
+ libusb_device** list;
+ adb_thread_setname("device poll");
+ while (true) {
+ const ssize_t device_count = libusb_get_device_list(nullptr, &list);
+ LOG(VERBOSE) << "found " << device_count << " attached devices";
+
+ for (ssize_t i = 0; i < device_count; ++i) {
+ process_device(list[i]);
+ }
+
+ libusb_free_device_list(list, 1);
+
+ adb_notify_device_scan_complete();
+
+ std::unique_lock<std::mutex> lock(device_poll_mutex);
+ if (device_poll_cv.wait_for(lock, 500ms, []() { return terminate_device_poll_thread; })) {
+ return;
+ }
+ }
+}
+#endif
+
void usb_init() {
LOG(DEBUG) << "initializing libusb...";
int rc = libusb_init(nullptr);
@@ -457,6 +493,7 @@ void usb_init() {
LOG(FATAL) << "failed to initialize libusb: " << libusb_error_name(rc);
}
+#if defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000102
// Register the hotplug callback.
rc = libusb_hotplug_register_callback(
nullptr, static_cast<libusb_hotplug_event>(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
@@ -467,6 +504,7 @@ void usb_init() {
if (rc != LIBUSB_SUCCESS) {
LOG(FATAL) << "failed to register libusb hotplug callback";
}
+#endif
// Spawn a thread for libusb_handle_events.
std::thread([]() {
@@ -475,10 +513,28 @@ void usb_init() {
libusb_handle_events(nullptr);
}
}).detach();
+
+#if !defined(LIBUSB_API_VERSION) || LIBUSB_API_VERSION < 0x01000102
+ std::unique_lock<std::mutex> lock(device_poll_mutex);
+ device_poll_thread = new std::thread(poll_for_devices);
+#endif
}
void usb_cleanup() {
+#if defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000102
libusb_hotplug_deregister_callback(nullptr, hotplug_handle);
+#else
+ {
+ std::unique_lock<std::mutex> lock(device_poll_mutex);
+ terminate_device_poll_thread = true;
+
+ if (!device_poll_thread) {
+ return;
+ }
+ }
+ device_poll_cv.notify_all();
+ device_poll_thread->join();
+#endif
}
// Dispatch a libusb transfer, unlock |device_lock|, and then wait for the result.