| Index: components/usb_service/usb_device_handle_impl.cc
|
| diff --git a/components/usb_service/usb_device_handle_impl.cc b/components/usb_service/usb_device_handle_impl.cc
|
| index c78a976c0a202a47c289101ca4f24854fb85c153..ceaaf5fb3f385eecd92aa36617454824b89645bc 100644
|
| --- a/components/usb_service/usb_device_handle_impl.cc
|
| +++ b/components/usb_service/usb_device_handle_impl.cc
|
| @@ -196,7 +196,7 @@ UsbDeviceHandleImpl::UsbDeviceHandleImpl(
|
| context_(context) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK(handle) << "Cannot create device with NULL handle.";
|
| - DCHECK(interfaces_) << "Unabled to list interfaces";
|
| + DCHECK(interfaces_) << "Unable to list interfaces";
|
| }
|
|
|
| UsbDeviceHandleImpl::~UsbDeviceHandleImpl() {
|
| @@ -372,64 +372,143 @@ bool UsbDeviceHandleImpl::ResetDevice() {
|
| return rv == LIBUSB_SUCCESS;
|
| }
|
|
|
| -bool UsbDeviceHandleImpl::GetSerial(base::string16* serial) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - PlatformUsbDevice device = libusb_get_device(handle_);
|
| - libusb_device_descriptor desc;
|
| -
|
| - const int rv = libusb_get_device_descriptor(device, &desc);
|
| - if (rv != LIBUSB_SUCCESS) {
|
| - VLOG(1) << "Failed to read device descriptor: " << ConvertErrorToString(rv);
|
| - return false;
|
| +bool UsbDeviceHandleImpl::GetSupportedLanguages() {
|
| + if (!languages_.empty()) {
|
| + return true;
|
| }
|
|
|
| - if (desc.iSerialNumber == 0)
|
| + uint16 languages[256];
|
| + int size = libusb_get_string_descriptor(
|
| + handle_,
|
| + 0,
|
| + 0,
|
| + reinterpret_cast<unsigned char*>(&languages[0]),
|
| + sizeof(languages));
|
| + if (size < 0) {
|
| + VLOG(1) << "Failed to get list of supported languages: "
|
| + << ConvertErrorToString(size);
|
| + return false;
|
| + } else if (size < 2) {
|
| + VLOG(1) << "String descriptor zero has no header.";
|
| + return false;
|
| + } else if ((languages[0] & 0xff) != size) {
|
| + VLOG(1) << "String descriptor zero size mismatch: " << (languages[0] & 0xff)
|
| + << " != " << size;
|
| + return false;
|
| + } else if ((languages[0] >> 8) != LIBUSB_DT_STRING) {
|
| + VLOG(1) << "String descriptor zero is not a string descriptor.";
|
| return false;
|
| + }
|
|
|
| - // Getting supported language ID.
|
| - uint16 langid[128] = {0};
|
| + languages_.assign(languages[1], languages[(size - 2) / 2]);
|
| + return true;
|
| +}
|
|
|
| - int size =
|
| - libusb_get_string_descriptor(handle_,
|
| - 0,
|
| - 0,
|
| - reinterpret_cast<unsigned char*>(&langid[0]),
|
| - sizeof(langid));
|
| - if (size < 0) {
|
| - VLOG(1) << "Failed to get language IDs: " << ConvertErrorToString(size);
|
| +bool UsbDeviceHandleImpl::GetStringDescriptor(uint8 string_id,
|
| + base::string16* string) {
|
| + if (!GetSupportedLanguages()) {
|
| return false;
|
| }
|
|
|
| - int language_count = (size - 2) / 2;
|
| + std::map<uint8, base::string16>::const_iterator it = strings_.find(string_id);
|
| + if (it != strings_.end()) {
|
| + *string = it->second;
|
| + return true;
|
| + }
|
|
|
| - for (int i = 1; i <= language_count; ++i) {
|
| + for (size_t i = 0; i < languages_.size(); ++i) {
|
| // Get the string using language ID.
|
| - base::char16 text[256] = {0};
|
| - size =
|
| + uint16 language_id = languages_[i];
|
| + base::char16 text[256];
|
| + int size =
|
| libusb_get_string_descriptor(handle_,
|
| - desc.iSerialNumber,
|
| - langid[i],
|
| + string_id,
|
| + language_id,
|
| reinterpret_cast<unsigned char*>(&text[0]),
|
| sizeof(text));
|
| if (size < 0) {
|
| - VLOG(1) << "Failed to get serial number (langid " << langid[i] << "): "
|
| - << ConvertErrorToString(size);
|
| + VLOG(1) << "Failed to get string descriptor " << string_id << " (langid "
|
| + << language_id << "): " << ConvertErrorToString(size);
|
| continue;
|
| - }
|
| - if (size <= 2)
|
| + } else if (size < 2) {
|
| + VLOG(1) << "String descriptor " << string_id << " (langid " << language_id
|
| + << ") has no header.";
|
| continue;
|
| - if ((text[0] >> 8) != LIBUSB_DT_STRING)
|
| + } else if ((text[0] >> 8) != LIBUSB_DT_STRING) {
|
| + VLOG(1) << "String descriptor " << string_id << " (langid " << language_id
|
| + << ") is not a string descriptor.";
|
| continue;
|
| - if ((text[0] & 255) > size)
|
| + } else if ((text[0] & 0xff) != size) {
|
| + VLOG(1) << "String descriptor " << string_id << " (langid " << language_id
|
| + << ") size mismatch: " << (text[0] & 0xff) << " != " << size;
|
| continue;
|
| + }
|
|
|
| - size = size / 2 - 1;
|
| - *serial = base::string16(text + 1, size);
|
| + *string = base::string16(text + 1, (size - 2) / 2);
|
| + strings_[string_id] = *string;
|
| return true;
|
| }
|
| +
|
| return false;
|
| }
|
|
|
| +bool UsbDeviceHandleImpl::GetManufacturer(base::string16* manufacturer) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + PlatformUsbDevice device = libusb_get_device(handle_);
|
| + libusb_device_descriptor desc;
|
| +
|
| + // This is a non-blocking call as libusb has the descriptor in memory.
|
| + const int rv = libusb_get_device_descriptor(device, &desc);
|
| + if (rv != LIBUSB_SUCCESS) {
|
| + VLOG(1) << "Failed to read device descriptor: " << ConvertErrorToString(rv);
|
| + return false;
|
| + }
|
| +
|
| + if (desc.iManufacturer == 0) {
|
| + return false;
|
| + }
|
| +
|
| + return GetStringDescriptor(desc.iManufacturer, manufacturer);
|
| +}
|
| +
|
| +bool UsbDeviceHandleImpl::GetProduct(base::string16* product) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + PlatformUsbDevice device = libusb_get_device(handle_);
|
| + libusb_device_descriptor desc;
|
| +
|
| + // This is a non-blocking call as libusb has the descriptor in memory.
|
| + const int rv = libusb_get_device_descriptor(device, &desc);
|
| + if (rv != LIBUSB_SUCCESS) {
|
| + VLOG(1) << "Failed to read device descriptor: " << ConvertErrorToString(rv);
|
| + return false;
|
| + }
|
| +
|
| + if (desc.iProduct == 0) {
|
| + return false;
|
| + }
|
| +
|
| + return GetStringDescriptor(desc.iProduct, product);
|
| +}
|
| +
|
| +bool UsbDeviceHandleImpl::GetSerial(base::string16* serial) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + PlatformUsbDevice device = libusb_get_device(handle_);
|
| + libusb_device_descriptor desc;
|
| +
|
| + // This is a non-blocking call as libusb has the descriptor in memory.
|
| + const int rv = libusb_get_device_descriptor(device, &desc);
|
| + if (rv != LIBUSB_SUCCESS) {
|
| + VLOG(1) << "Failed to read device descriptor: " << ConvertErrorToString(rv);
|
| + return false;
|
| + }
|
| +
|
| + if (desc.iSerialNumber == 0) {
|
| + return false;
|
| + }
|
| +
|
| + return GetStringDescriptor(desc.iSerialNumber, serial);
|
| +}
|
| +
|
| void UsbDeviceHandleImpl::ControlTransfer(
|
| const UsbEndpointDirection direction,
|
| const TransferRequestType request_type,
|
|
|