Merge "adb: get libusb compiling on Windows."
am: 6f29887c71
Change-Id: I354661e49907a7091e6823b1ff5544234a03c6af
diff --git a/adb/Android.mk b/adb/Android.mk
index 2b6df70..d76d175 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -101,6 +101,8 @@
sysdeps_win32.cpp \
sysdeps/win32/errno.cpp \
sysdeps/win32/stat.cpp \
+ client/usb_dispatch.cpp \
+ client/usb_libusb.cpp \
client/usb_windows.cpp \
LIBADB_TEST_windows_SRCS := \
@@ -159,9 +161,7 @@
# Even though we're building a static library (and thus there's no link step for
# this to take effect), this adds the includes to our path.
-LOCAL_STATIC_LIBRARIES := libcrypto_utils libcrypto libbase libmdnssd
-LOCAL_STATIC_LIBRARIES_linux := libusb
-LOCAL_STATIC_LIBRARIES_darwin := libusb
+LOCAL_STATIC_LIBRARIES := libcrypto_utils libcrypto libbase libmdnssd libusb
LOCAL_C_INCLUDES_windows := development/host/windows/usb/api/
LOCAL_MULTILIB := first
@@ -230,9 +230,7 @@
libdiagnose_usb \
libmdnssd \
libgmock_host \
-
-LOCAL_STATIC_LIBRARIES_linux := libusb
-LOCAL_STATIC_LIBRARIES_darwin := libusb
+ libusb \
# Set entrypoint to wmain from sysdeps_win32.cpp instead of main
LOCAL_LDFLAGS_windows := -municode
@@ -298,14 +296,12 @@
libdiagnose_usb \
liblog \
libmdnssd \
+ libusb \
# Don't use libcutils on Windows.
LOCAL_STATIC_LIBRARIES_darwin := libcutils
LOCAL_STATIC_LIBRARIES_linux := libcutils
-LOCAL_STATIC_LIBRARIES_darwin += libusb
-LOCAL_STATIC_LIBRARIES_linux += libusb
-
LOCAL_CXX_STL := libc++_static
# Don't add anything here, we don't want additional shared dependencies
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index 8120199..a5e6f23 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -41,8 +41,6 @@
#include "transport.h"
#include "usb.h"
-using namespace std::literals;
-
using android::base::StringPrintf;
// RAII wrappers for libusb.
@@ -222,7 +220,7 @@
// Use size_t for interface_num so <iostream>s don't mangle it.
size_t interface_num;
- uint16_t zero_mask;
+ uint16_t zero_mask = 0;
uint8_t bulk_in = 0, bulk_out = 0;
size_t packet_size = 0;
bool found_adb = false;
@@ -372,9 +370,9 @@
#endif
}
- auto result =
- std::make_unique<usb_handle>(device_address, device_serial, std::move(handle),
- interface_num, bulk_in, bulk_out, zero_mask, packet_size);
+ std::unique_ptr<usb_handle> result(new usb_handle(device_address, device_serial,
+ std::move(handle), interface_num, bulk_in,
+ bulk_out, zero_mask, packet_size));
usb_handle* usb_handle_raw = result.get();
{
@@ -397,7 +395,7 @@
// hack around this by inserting a sleep.
auto thread = std::thread([device]() {
std::string device_path = get_device_dev_path(device);
- std::this_thread::sleep_for(1s);
+ std::this_thread::sleep_for(std::chrono::seconds(1));
process_device(device);
if (--connecting_devices == 0) {
@@ -448,8 +446,8 @@
}
}
-static int hotplug_callback(libusb_context*, libusb_device* device, libusb_hotplug_event event,
- void*) {
+static LIBUSB_CALL int hotplug_callback(libusb_context*, libusb_device* device,
+ libusb_hotplug_event event, void*) {
// We're called with the libusb lock taken. Call these on a separate thread outside of this
// function so that the usb_handle mutex is always taken before the libusb mutex.
static std::once_flag once;
@@ -493,59 +491,60 @@
libusb_hotplug_deregister_callback(nullptr, hotplug_handle);
}
+static LIBUSB_CALL void transfer_callback(libusb_transfer* transfer) {
+ transfer_info* info = static_cast<transfer_info*>(transfer->user_data);
+
+ LOG(DEBUG) << info->name << " transfer callback entered";
+
+ // Make sure that the original submitter has made it to the condition_variable wait.
+ std::unique_lock<std::mutex> lock(info->mutex);
+
+ LOG(DEBUG) << info->name << " callback successfully acquired lock";
+
+ if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
+ LOG(WARNING) << info->name << " transfer failed: " << libusb_error_name(transfer->status);
+ info->Notify();
+ return;
+ }
+
+ // usb_read() can return when receiving some data.
+ if (info->is_bulk_out && transfer->actual_length != transfer->length) {
+ LOG(DEBUG) << info->name << " transfer incomplete, resubmitting";
+ transfer->length -= transfer->actual_length;
+ transfer->buffer += transfer->actual_length;
+ int rc = libusb_submit_transfer(transfer);
+ if (rc != 0) {
+ LOG(WARNING) << "failed to submit " << info->name
+ << " transfer: " << libusb_error_name(rc);
+ transfer->status = LIBUSB_TRANSFER_ERROR;
+ info->Notify();
+ }
+ return;
+ }
+
+ if (should_perform_zero_transfer(transfer->endpoint, transfer->length, info->zero_mask)) {
+ LOG(DEBUG) << "submitting zero-length write";
+ transfer->length = 0;
+ int rc = libusb_submit_transfer(transfer);
+ if (rc != 0) {
+ LOG(WARNING) << "failed to submit zero-length write: " << libusb_error_name(rc);
+ transfer->status = LIBUSB_TRANSFER_ERROR;
+ info->Notify();
+ }
+ return;
+ }
+
+ LOG(VERBOSE) << info->name << "transfer fully complete";
+ info->Notify();
+}
+
// Dispatch a libusb transfer, unlock |device_lock|, and then wait for the result.
static int perform_usb_transfer(usb_handle* h, transfer_info* info,
std::unique_lock<std::mutex> device_lock) {
libusb_transfer* transfer = info->transfer;
transfer->user_data = info;
- transfer->callback = [](libusb_transfer* transfer) {
- transfer_info* info = static_cast<transfer_info*>(transfer->user_data);
-
- LOG(DEBUG) << info->name << " transfer callback entered";
-
- // Make sure that the original submitter has made it to the condition_variable wait.
- std::unique_lock<std::mutex> lock(info->mutex);
-
- LOG(DEBUG) << info->name << " callback successfully acquired lock";
-
- if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
- LOG(WARNING) << info->name
- << " transfer failed: " << libusb_error_name(transfer->status);
- info->Notify();
- return;
- }
-
- // usb_read() can return when receiving some data.
- if (info->is_bulk_out && transfer->actual_length != transfer->length) {
- LOG(DEBUG) << info->name << " transfer incomplete, resubmitting";
- transfer->length -= transfer->actual_length;
- transfer->buffer += transfer->actual_length;
- int rc = libusb_submit_transfer(transfer);
- if (rc != 0) {
- LOG(WARNING) << "failed to submit " << info->name
- << " transfer: " << libusb_error_name(rc);
- transfer->status = LIBUSB_TRANSFER_ERROR;
- info->Notify();
- }
- return;
- }
-
- if (should_perform_zero_transfer(transfer->endpoint, transfer->length, info->zero_mask)) {
- LOG(DEBUG) << "submitting zero-length write";
- transfer->length = 0;
- int rc = libusb_submit_transfer(transfer);
- if (rc != 0) {
- LOG(WARNING) << "failed to submit zero-length write: " << libusb_error_name(rc);
- transfer->status = LIBUSB_TRANSFER_ERROR;
- info->Notify();
- }
- return;
- }
-
- LOG(VERBOSE) << info->name << "transfer fully complete";
- info->Notify();
- };
+ transfer->callback = transfer_callback;
LOG(DEBUG) << "locking " << info->name << " transfer_info mutex";
std::unique_lock<std::mutex> lock(info->mutex);
diff --git a/adb/client/usb_windows.cpp b/adb/client/usb_windows.cpp
index 61981b1..9751ebf 100644
--- a/adb/client/usb_windows.cpp
+++ b/adb/client/usb_windows.cpp
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <algorithm>
#include <mutex>
#include <thread>
@@ -40,6 +41,8 @@
#include "sysdeps/chrono.h"
#include "transport.h"
+namespace native {
+
/** Structure usb_handle describes our connection to the usb device via
AdbWinApi.dll. This structure is returned from usb_open() routine and
is expected in each subsequent call that is accessing the device.
@@ -48,13 +51,7 @@
rely on AdbWinApi.dll's handle validation and AdbCloseHandle(endpoint)'s
ability to break a thread out of pipe IO.
*/
-struct usb_handle {
- /// Previous entry in the list of opened usb handles
- usb_handle* prev;
-
- /// Next entry in the list of opened usb handles
- usb_handle* next;
-
+struct usb_handle : public ::usb_handle {
/// Handle to USB interface
ADBAPIHANDLE adb_interface;
@@ -78,9 +75,7 @@
static const GUID usb_class_id = ANDROID_USB_CLASS_ID;
/// List of opened usb handles
-static usb_handle handle_list = {
- .prev = &handle_list, .next = &handle_list,
-};
+static std::vector<usb_handle*> handle_list;
/// Locker for the list of opened usb handles
static std::mutex& usb_lock = *new std::mutex();
@@ -131,11 +126,9 @@
int usb_close(usb_handle* handle);
int known_device_locked(const wchar_t* dev_name) {
- usb_handle* usb;
-
if (NULL != dev_name) {
// Iterate through the list looking for the name match.
- for (usb = handle_list.next; usb != &handle_list; usb = usb->next) {
+ for (usb_handle* usb : handle_list) {
// In Windows names are not case sensetive!
if ((NULL != usb->interface_name) && (0 == wcsicmp(usb->interface_name, dev_name))) {
return 1;
@@ -168,10 +161,7 @@
}
// Not in the list. Add this handle to the list.
- handle->next = &handle_list;
- handle->prev = handle_list.prev;
- handle->prev->next = handle;
- handle->next->prev = handle;
+ handle_list.push_back(handle);
return 1;
}
@@ -274,10 +264,6 @@
goto fail;
}
- // Set linkers back to the handle
- ret->next = ret;
- ret->prev = ret;
-
// Create interface.
ret->adb_interface = AdbCreateInterfaceByName(interface_name);
if (NULL == ret->adb_interface) {
@@ -484,13 +470,8 @@
// Remove handle from the list
{
std::lock_guard<std::mutex> lock(usb_lock);
-
- if ((handle->next != handle) && (handle->prev != handle)) {
- handle->next->prev = handle->prev;
- handle->prev->next = handle->next;
- handle->prev = handle;
- handle->next = handle;
- }
+ handle_list.erase(std::remove(handle_list.begin(), handle_list.end(), handle),
+ handle_list.end());
}
// Cleanup handle
@@ -623,7 +604,9 @@
// Need to acquire lock to safely walk the list which might be modified
// by another thread.
std::lock_guard<std::mutex> lock(usb_lock);
- for (usb_handle* usb = handle_list.next; usb != &handle_list; usb = usb->next) {
+ for (usb_handle* usb : handle_list) {
usb_kick_locked(usb);
}
}
+
+} // namespace native
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index a00ed5e..c3ac344 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -195,7 +195,7 @@
}
bool should_use_libusb() {
-#if defined(_WIN32) || !ADB_HOST
+#if !ADB_HOST
return false;
#else
static bool enable = getenv("ADB_LIBUSB") && strcmp(getenv("ADB_LIBUSB"), "1") == 0;
diff --git a/adb/usb.h b/adb/usb.h
index f428ede..cd83c42 100644
--- a/adb/usb.h
+++ b/adb/usb.h
@@ -29,8 +29,8 @@
void usb_kick(handle_ref_type h); \
size_t usb_get_max_packet_size(handle_ref_type)
-#if defined(_WIN32) || !ADB_HOST
-// Windows and the daemon have a single implementation.
+#if !ADB_HOST
+// The daemon has a single implementation.
struct usb_handle;
ADB_USB_INTERFACE(usb_handle*);