Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b44385f6 authored by Josh Gao's avatar Josh Gao Committed by android-build-merger
Browse files

Merge "adb: properly handle libusb_clear_halt failure."

am: 761ae047

Change-Id: Ie45ec4c1786d851aa8c50de44d80bda13a27c099
parents 20a74298 761ae047
Loading
Loading
Loading
Loading
+180 −180
Original line number Diff line number Diff line
@@ -184,16 +184,7 @@ static bool should_perform_zero_transfer(uint8_t endpoint, size_t write_length,
           (write_length & zero_mask) == 0;
}

static void poll_for_devices() {
    libusb_device** list;
    adb_thread_setname("device poll");
    while (!terminate_device_poll_thread) {
        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) {
            libusb_device* device = list[i];
static void process_device(libusb_device* device) {
    std::string device_address = get_device_address(device);
    std::string device_serial;

@@ -201,23 +192,24 @@ static void poll_for_devices() {
    libusb_device_descriptor device_desc;
    int rc = libusb_get_device_descriptor(device, &device_desc);
    if (rc != 0) {
                LOG(WARNING) << "failed to get device descriptor for device at " << device_address
                             << ": " << libusb_error_name(rc);
        LOG(WARNING) << "failed to get device descriptor for device at " << device_address << ": "
                     << libusb_error_name(rc);
        return;
    }

    if (device_desc.bDeviceClass != LIBUSB_CLASS_PER_INTERFACE) {
        // Assume that all Android devices have the device class set to per interface.
        // TODO: Is this assumption valid?
        LOG(VERBOSE) << "skipping device with incorrect class at " << device_address;
                continue;
        return;
    }

    libusb_config_descriptor* config_raw;
    rc = libusb_get_active_config_descriptor(device, &config_raw);
    if (rc != 0) {
                LOG(WARNING) << "failed to get active config descriptor for device at "
                             << device_address << ": " << libusb_error_name(rc);
                continue;
        LOG(WARNING) << "failed to get active config descriptor for device at " << device_address
                     << ": " << libusb_error_name(rc);
        return;
    }
    const unique_config_descriptor config(config_raw);

@@ -233,27 +225,25 @@ static void poll_for_devices() {
        if (interface.num_altsetting != 1) {
            // Assume that interfaces with alternate settings aren't adb interfaces.
            // TODO: Is this assumption valid?
                    LOG(VERBOSE) << "skipping interface with incorrect num_altsetting at "
                                 << device_address << " (interface " << interface_num << ")";
                    continue;
            LOG(VERBOSE) << "skipping interface with incorrect num_altsetting at " << device_address
                         << " (interface " << interface_num << ")";
            return;
        }

        const libusb_interface_descriptor& interface_desc = interface.altsetting[0];
                if (!is_adb_interface(interface_desc.bInterfaceClass,
                                      interface_desc.bInterfaceSubClass,
        if (!is_adb_interface(interface_desc.bInterfaceClass, interface_desc.bInterfaceSubClass,
                              interface_desc.bInterfaceProtocol)) {
                    LOG(VERBOSE) << "skipping non-adb interface at " << device_address
                                 << " (interface " << interface_num << ")";
                    continue;
            LOG(VERBOSE) << "skipping non-adb interface at " << device_address << " (interface "
                         << interface_num << ")";
            return;
        }

                LOG(VERBOSE) << "found potential adb interface at " << device_address
                             << " (interface " << interface_num << ")";
        LOG(VERBOSE) << "found potential adb interface at " << device_address << " (interface "
                     << interface_num << ")";

        bool found_in = false;
        bool found_out = false;
                for (size_t endpoint_num = 0; endpoint_num < interface_desc.bNumEndpoints;
                     ++endpoint_num) {
        for (size_t endpoint_num = 0; endpoint_num < interface_desc.bNumEndpoints; ++endpoint_num) {
            const auto& endpoint_desc = interface_desc.endpoint[endpoint_num];
            const uint8_t endpoint_addr = endpoint_desc.bEndpointAddress;
            const uint8_t endpoint_attr = endpoint_desc.bmAttributes;
@@ -261,7 +251,7 @@ static void poll_for_devices() {
            const uint8_t transfer_type = endpoint_attr & LIBUSB_TRANSFER_TYPE_MASK;

            if (transfer_type != LIBUSB_TRANSFER_TYPE_BULK) {
                        continue;
                return;
            }

            if (endpoint_is_output(endpoint_addr) && !found_out) {
@@ -288,14 +278,13 @@ static void poll_for_devices() {
        } else {
            LOG(VERBOSE) << "rejecting potential adb interface at " << device_address
                         << "(interface " << interface_num << "): missing bulk endpoints "
                                 << "(found_in = " << found_in << ", found_out = " << found_out
                                 << ")";
                         << "(found_in = " << found_in << ", found_out = " << found_out << ")";
        }
    }

    if (!found_adb) {
        LOG(VERBOSE) << "skipping device with no adb interfaces at " << device_address;
                continue;
        return;
    }

    {
@@ -303,7 +292,7 @@ static void poll_for_devices() {
        if (usb_handles.find(device_address) != usb_handles.end()) {
            LOG(VERBOSE) << "device at " << device_address
                         << " has already been registered, skipping";
                    continue;
            return;
        }
    }

@@ -316,25 +305,25 @@ static void poll_for_devices() {
                   << StringPrintf("bulk_in = %#x, bulk_out = %#x", bulk_in, bulk_out);

        device_serial.resize(255);
                rc = libusb_get_string_descriptor_ascii(
                    handle_raw, device_desc.iSerialNumber,
                    reinterpret_cast<unsigned char*>(&device_serial[0]), device_serial.length());
        rc = libusb_get_string_descriptor_ascii(handle_raw, device_desc.iSerialNumber,
                                                reinterpret_cast<unsigned char*>(&device_serial[0]),
                                                device_serial.length());
        if (rc == 0) {
            LOG(WARNING) << "received empty serial from device at " << device_address;
                    continue;
            return;
        } else if (rc < 0) {
            LOG(WARNING) << "failed to get serial from device at " << device_address
                         << libusb_error_name(rc);
                    continue;
            return;
        }
        device_serial.resize(rc);

        // WARNING: this isn't released via RAII.
        rc = libusb_claim_interface(handle.get(), interface_num);
        if (rc != 0) {
                    LOG(WARNING) << "failed to claim adb interface for device '" << device_serial
                                 << "'" << libusb_error_name(rc);
                    continue;
            LOG(WARNING) << "failed to claim adb interface for device '" << device_serial << "'"
                         << libusb_error_name(rc);
            return;
        }

        for (uint8_t endpoint : {bulk_in, bulk_out}) {
@@ -344,7 +333,7 @@ static void poll_for_devices() {
                             << "' endpoint 0x" << std::hex << endpoint << ": "
                             << libusb_error_name(rc);
                libusb_release_interface(handle.get(), interface_num);
                        continue;
                return;
            }
        }
    } else {
@@ -355,8 +344,7 @@ static void poll_for_devices() {
#if defined(__linux__)
        // libusb doesn't think we should be messing around with devices we don't have
        // write access to, but Linux at least lets us get the serial number anyway.
                if (!android::base::ReadFileToString(get_device_serial_path(device),
                                                     &device_serial)) {
        if (!android::base::ReadFileToString(get_device_serial_path(device), &device_serial)) {
            // We don't actually want to treat an unknown serial as an error because
            // devices aren't able to communicate a serial number in early bringup.
            // http://b/20883914
@@ -366,13 +354,13 @@ static void poll_for_devices() {
#else
        // On Mac OS and Windows, we're screwed. But I don't think this situation actually
        // happens on those OSes.
                continue;
        return;
#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);
    auto result =
        std::make_unique<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();

    {
@@ -380,11 +368,23 @@ static void poll_for_devices() {
        usb_handles[device_address] = std::move(result);
    }

            register_usb_transport(usb_handle_raw, device_serial.c_str(), device_address.c_str(),
                                   writable);
    register_usb_transport(usb_handle_raw, device_serial.c_str(), device_address.c_str(), writable);

    LOG(INFO) << "registered new usb device '" << device_serial << "'";
}

static void poll_for_devices() {
    libusb_device** list;
    adb_thread_setname("device poll");
    while (!terminate_device_poll_thread) {
        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();