Merge "libBacktraceOffline: try both .debug_frame and .ARM.exidx on arm."
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*);
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index cae6e13..3183b80 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -63,7 +63,7 @@
 namespace.sphal.isolated = true
 namespace.sphal.visible = true
 namespace.sphal.search.paths = /vendor/${LIB}/egl:/vendor/${LIB}/hw:/vendor/${LIB}
-namespace.sphal.permitted.paths = /vendor/${LIB}:/system/${LIB}/vndk-sp/hw
+namespace.sphal.permitted.paths = /vendor/${LIB}:/system/${LIB}/vndk-sp${VNDK_VER}/hw
 
 namespace.sphal.asan.search.paths = /data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}:/vendor/${LIB}
 namespace.sphal.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}
@@ -91,10 +91,10 @@
 ###############################################################################
 namespace.rs.isolated = true
 namespace.rs.visible = true
-namespace.rs.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/vendor/${LIB}
+namespace.rs.search.paths = /vendor/${LIB}/vndk-sp${VNDK_VER}:/system/${LIB}/vndk-sp${VNDK_VER}:/vendor/${LIB}
 namespace.rs.permitted.paths = /vendor/${LIB}:/data
 
-namespace.rs.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/vendor/${LIB}:/vendor/${LIB}
+namespace.rs.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp${VNDK_VER}:/vendor/${LIB}/vndk-sp${VNDK_VER}:/data/asan/system/${LIB}/vndk-sp${VNDK_VER}:/system/${LIB}/vndk-sp${VNDK_VER}:/data/asan/vendor/${LIB}:/vendor/${LIB}
 namespace.rs.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data
 
 namespace.rs.links = default,vndk
@@ -108,10 +108,10 @@
 ###############################################################################
 namespace.vndk.isolated = true
 namespace.vndk.visible = true
-namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
+namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp${VNDK_VER}:/system/${LIB}/vndk-sp${VNDK_VER}
 namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl
 
-namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
+namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp${VNDK_VER}:/vendor/${LIB}/vndk-sp${VNDK_VER}:/data/asan/system/${LIB}/vndk-sp${VNDK_VER}:/system/${LIB}/vndk-sp${VNDK_VER}
 namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl
 
 # When these NDK libs are required inside this namespace, then it is redirected
@@ -128,6 +128,6 @@
 ###############################################################################
 [vendor]
 namespace.default.isolated = false
-namespace.default.search.paths = /odm/${LIB}/hw:/odm/${LIB}/egl:/odm/${LIB}:/vendor/${LIB}/hw:/vendor/${LIB}/egl:/vendor/${LIB}:/system/${LIB}/vndk:/odm/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/system/${LIB}
+namespace.default.search.paths = /odm/${LIB}/hw:/odm/${LIB}/egl:/odm/${LIB}:/vendor/${LIB}/hw:/vendor/${LIB}/egl:/vendor/${LIB}:/system/${LIB}/vndk${VNDK_VER}:/odm/${LIB}/vndk-sp${VNDK_VER}:/vendor/${LIB}/vndk-sp${VNDK_VER}:/system/${LIB}/vndk-sp${VNDK_VER}:/system/${LIB}
 
-namespace.default.asan.search.paths = /data/asan/odm/${LIB}/hw:/odm/${LIB}/hw:/data/asan/odm/${LIB}/egl:/odm/${LIB}/egl:/data/asan/odm/${LIB}:/odm/${LIB}:/data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/odm/${LIB}/vndk-sp:/odm/${LIB}/vndk-sp:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB}
+namespace.default.asan.search.paths = /data/asan/odm/${LIB}/hw:/odm/${LIB}/hw:/data/asan/odm/${LIB}/egl:/odm/${LIB}/egl:/data/asan/odm/${LIB}:/odm/${LIB}:/data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/system/${LIB}/vndk${VNDK_VER}:/system/${LIB}/vndk${VNDK_VER}:/data/asan/odm/${LIB}/vndk-sp${VNDK_VER}:/odm/${LIB}/vndk-sp${VNDK_VER}:/data/asan/vendor/${LIB}/vndk-sp${VNDK_VER}:/vendor/${LIB}/vndk-sp${VNDK_VER}:/data/asan/system/${LIB}/vndk-sp${VNDK_VER}:/system/${LIB}/vndk-sp${VNDK_VER}:/data/asan/system/${LIB}:/system/${LIB}