summaryrefslogtreecommitdiff
path: root/devel/android-tools-adb/files/patch-adb_client_usb__libusb.cpp
blob: 5598261f5a527280fe00afd72e225ad4fae43c1e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
--- adb/client/usb_libusb.cpp.orig	2017-06-20 10:50:27 UTC
+++ adb/client/usb_libusb.cpp
@@ -30,7 +30,7 @@
 #include <thread>
 #include <unordered_map>
 
-#include <libusb/libusb.h>
+#include <libusb.h>
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
@@ -39,6 +39,9 @@
 
 #include "adb.h"
 #include "adb_utils.h"
+#if !defined(__linux__) && !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__HAIKU__)
+#include "sysdeps/chrono.h"
+#endif
 #include "transport.h"
 #include "usb.h"
 
@@ -89,7 +89,11 @@ struct transfer_info {
 };
 
 namespace libusb {
+#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)
 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(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__HAIKU__)
 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(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__HAIKU__)
 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(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__HAIKU__)
     // 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(__linux__) && !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__HAIKU__)
+    std::unique_lock<std::mutex> lock(device_poll_mutex);
+    device_poll_thread = new std::thread(poll_for_devices);
+#endif
 }
 
 void usb_cleanup() {
+#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__HAIKU__)
     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.