diff options
author | reillyg <reillyg@chromium.org> | 2014-09-12 22:37:18 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-13 05:38:58 +0000 |
commit | 2191196d13b2896f5ba7bc1c6a3371cb86a7e8eb (patch) | |
tree | 199ea1a33cdf1f5078ef37c54c43da266224c3ea /device | |
parent | 9cc636333cf526081f64a315343e9c3b7f396695 (diff) | |
download | chromium_src-2191196d13b2896f5ba7bc1c6a3371cb86a7e8eb.zip chromium_src-2191196d13b2896f5ba7bc1c6a3371cb86a7e8eb.tar.gz chromium_src-2191196d13b2896f5ba7bc1c6a3371cb86a7e8eb.tar.bz2 |
Reland: Convert device::UsbConfigDescriptor and friends to structs.
These classes do not need to be classes and expecially don't need to be
abstract classes as this leads to a complicated implementation and
complicated tests. All USB devices no matter the platform will have the
same descriptor data.
This change follows the model of device::HidDeviceInfo.
Relanding this patch (reverted in crrev.com/294640) after restoring the
call to libusb_free_config_descriptor that was removed during
refactoring and caused failures in the Linux ASan LSan tests.
BUG=
Review URL: https://codereview.chromium.org/568943002
Cr-Commit-Position: refs/heads/master@{#294734}
Diffstat (limited to 'device')
-rw-r--r-- | device/usb/BUILD.gn | 5 | ||||
-rw-r--r-- | device/usb/usb.gyp | 5 | ||||
-rw-r--r-- | device/usb/usb_descriptors.cc | 43 | ||||
-rw-r--r-- | device/usb/usb_descriptors.h | 83 | ||||
-rw-r--r-- | device/usb/usb_device.h | 7 | ||||
-rw-r--r-- | device/usb/usb_device_filter.cc | 28 | ||||
-rw-r--r-- | device/usb/usb_device_filter_unittest.cc | 153 | ||||
-rw-r--r-- | device/usb/usb_device_handle.h | 2 | ||||
-rw-r--r-- | device/usb/usb_device_handle_impl.cc | 41 | ||||
-rw-r--r-- | device/usb/usb_device_handle_impl.h | 7 | ||||
-rw-r--r-- | device/usb/usb_device_impl.cc | 153 | ||||
-rw-r--r-- | device/usb/usb_device_impl.h | 8 | ||||
-rw-r--r-- | device/usb/usb_interface.h | 112 | ||||
-rw-r--r-- | device/usb/usb_interface_impl.cc | 168 | ||||
-rw-r--r-- | device/usb/usb_interface_impl.h | 117 |
15 files changed, 341 insertions, 591 deletions
diff --git a/device/usb/BUILD.gn b/device/usb/BUILD.gn index 0e97bfe..385bcb9 100644 --- a/device/usb/BUILD.gn +++ b/device/usb/BUILD.gn @@ -9,6 +9,8 @@ source_set("usb") { sources = [ "usb_context.cc", "usb_context.h", + "usb_descriptors.cc", + "usb_descriptors.h", "usb_device_impl.cc", "usb_device_impl.h", "usb_device.h", @@ -21,9 +23,6 @@ source_set("usb") { "usb_error.h", "usb_ids.cc", "usb_ids.h", - "usb_interface.h", - "usb_interface_impl.cc", - "usb_interface_impl.h", "usb_service.h", "usb_service_impl.cc", generated_ids, diff --git a/device/usb/usb.gyp b/device/usb/usb.gyp index 81bdf40..f0b5275 100644 --- a/device/usb/usb.gyp +++ b/device/usb/usb.gyp @@ -19,6 +19,8 @@ 'sources': [ 'usb_context.cc', 'usb_context.h', + 'usb_descriptors.cc', + 'usb_descriptors.h', 'usb_device_impl.cc', 'usb_device_impl.h', 'usb_device.h', @@ -31,9 +33,6 @@ 'usb_error.h', 'usb_ids.cc', 'usb_ids.h', - 'usb_interface.h', - 'usb_interface_impl.cc', - 'usb_interface_impl.h', 'usb_service.h', 'usb_service_impl.cc', ], diff --git a/device/usb/usb_descriptors.cc b/device/usb/usb_descriptors.cc new file mode 100644 index 0000000..d68d60e --- /dev/null +++ b/device/usb/usb_descriptors.cc @@ -0,0 +1,43 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/usb/usb_descriptors.h" + +namespace device { + +UsbEndpointDescriptor::UsbEndpointDescriptor() + : address(0), + direction(USB_DIRECTION_INBOUND), + maximum_packet_size(0), + synchronization_type(USB_SYNCHRONIZATION_NONE), + transfer_type(USB_TRANSFER_CONTROL), + usage_type(USB_USAGE_DATA), + polling_interval(0) { +} + +UsbEndpointDescriptor::~UsbEndpointDescriptor() { +} + +UsbInterfaceDescriptor::UsbInterfaceDescriptor() + : interface_number(0), + alternate_setting(0), + interface_class(0), + interface_subclass(0), + interface_protocol(0) { +} + +UsbInterfaceDescriptor::~UsbInterfaceDescriptor() { +} + +UsbConfigDescriptor::UsbConfigDescriptor() + : configuration_value(0), + self_powered(false), + remote_wakeup(false), + maximum_power(0) { +} + +UsbConfigDescriptor::~UsbConfigDescriptor() { +} + +} // namespace device diff --git a/device/usb/usb_descriptors.h b/device/usb/usb_descriptors.h new file mode 100644 index 0000000..2881aba --- /dev/null +++ b/device/usb/usb_descriptors.h @@ -0,0 +1,83 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_USB_USB_DESCRIPTORS_H_ +#define DEVICE_USB_USB_DESCRIPTORS_H_ + +#include <stdint.h> +#include <vector> + +namespace device { + +enum UsbTransferType { + USB_TRANSFER_CONTROL = 0, + USB_TRANSFER_ISOCHRONOUS, + USB_TRANSFER_BULK, + USB_TRANSFER_INTERRUPT, +}; + +enum UsbEndpointDirection { + USB_DIRECTION_INBOUND = 0, + USB_DIRECTION_OUTBOUND, +}; + +enum UsbSynchronizationType { + USB_SYNCHRONIZATION_NONE = 0, + USB_SYNCHRONIZATION_ASYNCHRONOUS, + USB_SYNCHRONIZATION_ADAPTIVE, + USB_SYNCHRONIZATION_SYNCHRONOUS, +}; + +enum UsbUsageType { + USB_USAGE_DATA = 0, + USB_USAGE_FEEDBACK, + USB_USAGE_EXPLICIT_FEEDBACK +}; + +struct UsbEndpointDescriptor { + UsbEndpointDescriptor(); + ~UsbEndpointDescriptor(); + + typedef std::vector<UsbEndpointDescriptor>::const_iterator Iterator; + + uint8_t address; + UsbEndpointDirection direction; + uint16_t maximum_packet_size; + UsbSynchronizationType synchronization_type; + UsbTransferType transfer_type; + UsbUsageType usage_type; + uint16_t polling_interval; + std::vector<uint8_t> extra_data; +}; + +struct UsbInterfaceDescriptor { + UsbInterfaceDescriptor(); + ~UsbInterfaceDescriptor(); + + typedef std::vector<UsbInterfaceDescriptor>::const_iterator Iterator; + + uint8_t interface_number; + uint8_t alternate_setting; + uint8_t interface_class; + uint8_t interface_subclass; + uint8_t interface_protocol; + std::vector<UsbEndpointDescriptor> endpoints; + std::vector<uint8_t> extra_data; +}; + +struct UsbConfigDescriptor { + UsbConfigDescriptor(); + ~UsbConfigDescriptor(); + + uint8_t configuration_value; + bool self_powered; + bool remote_wakeup; + uint16_t maximum_power; + std::vector<UsbInterfaceDescriptor> interfaces; + std::vector<uint8_t> extra_data; +}; + +} // namespace device + +#endif // DEVICE_USB_USB_DESCRIPTORS_H_ diff --git a/device/usb/usb_device.h b/device/usb/usb_device.h index 586fd19..a012025 100644 --- a/device/usb/usb_device.h +++ b/device/usb/usb_device.h @@ -12,7 +12,7 @@ namespace device { class UsbDeviceHandle; -class UsbConfigDescriptor; +struct UsbConfigDescriptor; // A UsbDevice object represents a detected USB device, providing basic // information about it. For further manipulation of the device, a @@ -44,10 +44,9 @@ class UsbDevice : public base::RefCountedThreadSafe<UsbDevice> { // Blocking method. Must be called on FILE thread. virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) = 0; - // Lists the interfaces provided by the device and fills the given - // UsbConfigDescriptor. + // Gets the UsbConfigDescriptor for the active device configuration. // Blocking method. Must be called on FILE thread. - virtual scoped_refptr<UsbConfigDescriptor> ListInterfaces() = 0; + virtual const UsbConfigDescriptor& GetConfiguration() = 0; protected: UsbDevice(uint16 vendor_id, uint16 product_id, uint32 unique_id) diff --git a/device/usb/usb_device_filter.cc b/device/usb/usb_device_filter.cc index cc919e2..2d3f157 100644 --- a/device/usb/usb_device_filter.cc +++ b/device/usb/usb_device_filter.cc @@ -5,8 +5,8 @@ #include "device/usb/usb_device_filter.h" #include "base/values.h" +#include "device/usb/usb_descriptors.h" #include "device/usb/usb_device.h" -#include "device/usb/usb_interface.h" namespace device { @@ -69,27 +69,21 @@ bool UsbDeviceFilter::Matches(scoped_refptr<UsbDevice> device) const { if (interface_class_set_) { bool foundMatch = false; - scoped_refptr<const UsbConfigDescriptor> config = device->ListInterfaces(); + const UsbConfigDescriptor& config = device->GetConfiguration(); // TODO(reillyg): Check device configuration if the class is not defined at // a per-interface level. This is not really important because most devices // have per-interface classes. The only counter-examples I know of are hubs. - for (size_t i = 0; i < config->GetNumInterfaces() && !foundMatch; ++i) { - scoped_refptr<const UsbInterfaceDescriptor> iface = - config->GetInterface(i); - - for (size_t j = 0; j < iface->GetNumAltSettings() && !foundMatch; ++j) { - scoped_refptr<const UsbInterfaceAltSettingDescriptor> altSetting = - iface->GetAltSetting(j); - - if (altSetting->GetInterfaceClass() == interface_class_ && - (!interface_subclass_set_ || - (altSetting->GetInterfaceSubclass() == interface_subclass_ && - (!interface_protocol_set_ || - altSetting->GetInterfaceProtocol() == interface_protocol_)))) { - foundMatch = true; - } + for (UsbInterfaceDescriptor::Iterator ifaceIt = config.interfaces.begin(); + ifaceIt != config.interfaces.end() && !foundMatch; + ++ifaceIt) { + if (ifaceIt->interface_class == interface_class_ && + (!interface_subclass_set_ || + (ifaceIt->interface_subclass == interface_subclass_ && + (!interface_protocol_set_ || + ifaceIt->interface_protocol == interface_protocol_)))) { + foundMatch = true; } } diff --git a/device/usb/usb_device_filter_unittest.cc b/device/usb/usb_device_filter_unittest.cc index 1fdccd4..90097f6 100644 --- a/device/usb/usb_device_filter_unittest.cc +++ b/device/usb/usb_device_filter_unittest.cc @@ -5,156 +5,55 @@ #include <vector> #include "base/memory/ref_counted.h" +#include "device/usb/usb_descriptors.h" #include "device/usb/usb_device.h" #include "device/usb/usb_device_filter.h" #include "device/usb/usb_device_handle.h" -#include "device/usb/usb_interface.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace device { namespace { -class MockUsbInterfaceAltSettingDescriptor - : public UsbInterfaceAltSettingDescriptor { - public: - MockUsbInterfaceAltSettingDescriptor(int interface_number, - int alternate_setting, - int interface_class, - int interface_subclass, - int interface_protocol) - : interface_number_(interface_number), - alternate_setting_(alternate_setting), - interface_class_(interface_class), - interface_subclass_(interface_subclass), - interface_protocol_(interface_protocol) {} - - virtual size_t GetNumEndpoints() const OVERRIDE { return 0; } - virtual scoped_refptr<const UsbEndpointDescriptor> GetEndpoint( - size_t index) const OVERRIDE { - return NULL; - } - virtual int GetInterfaceNumber() const OVERRIDE { return interface_number_; } - virtual int GetAlternateSetting() const OVERRIDE { - return alternate_setting_; - } - virtual int GetInterfaceClass() const OVERRIDE { return interface_class_; } - virtual int GetInterfaceSubclass() const OVERRIDE { - return interface_subclass_; - } - virtual int GetInterfaceProtocol() const OVERRIDE { - return interface_protocol_; - } - - protected: - virtual ~MockUsbInterfaceAltSettingDescriptor() {} - - private: - int interface_number_; - int alternate_setting_; - int interface_class_; - int interface_subclass_; - int interface_protocol_; -}; - -typedef std::vector<scoped_refptr<UsbInterfaceAltSettingDescriptor> > - UsbInterfaceAltSettingDescriptorList; - -class MockUsbInterfaceDescriptor : public UsbInterfaceDescriptor { - public: - MockUsbInterfaceDescriptor( - const UsbInterfaceAltSettingDescriptorList& alt_settings) - : alt_settings_(alt_settings) {} - - virtual size_t GetNumAltSettings() const OVERRIDE { - return alt_settings_.size(); - } - virtual scoped_refptr<const UsbInterfaceAltSettingDescriptor> GetAltSetting( - size_t index) const OVERRIDE { - return alt_settings_[index]; - } - - protected: - virtual ~MockUsbInterfaceDescriptor() {} - - private: - UsbInterfaceAltSettingDescriptorList alt_settings_; -}; - -typedef std::vector<scoped_refptr<UsbInterfaceDescriptor> > - UsbInterfaceDescriptorList; - -class MockUsbConfigDescriptor : public UsbConfigDescriptor { - public: - MockUsbConfigDescriptor(const UsbInterfaceDescriptorList& interfaces) - : interfaces_(interfaces) {} - - virtual size_t GetNumInterfaces() const OVERRIDE { - return interfaces_.size(); - } - virtual scoped_refptr<const UsbInterfaceDescriptor> GetInterface( - size_t index) const OVERRIDE { - return interfaces_[index]; - } - - protected: - virtual ~MockUsbConfigDescriptor() {} - - private: - UsbInterfaceDescriptorList interfaces_; -}; +using testing::NiceMock; +using testing::ReturnRef; class MockUsbDevice : public UsbDevice { public: - MockUsbDevice(uint16 vendor_id, - uint16 product_id, - uint32 unique_id, - scoped_refptr<UsbConfigDescriptor> config_desc) - : UsbDevice(vendor_id, product_id, unique_id), - config_desc_(config_desc) {} - - virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE { return NULL; } - virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE { - NOTREACHED(); - return true; - } -#if defined(OS_CHROMEOS) - virtual void RequestUsbAccess( - int interface_id, - const base::Callback<void(bool success)>& callback) OVERRIDE { - NOTREACHED(); - } -#endif // OS_CHROMEOS - virtual scoped_refptr<UsbConfigDescriptor> ListInterfaces() OVERRIDE { - return config_desc_; - } + MockUsbDevice(uint16 vendor_id, uint16 product_id, uint32 unique_id) + : UsbDevice(vendor_id, product_id, unique_id) {} - protected: - virtual ~MockUsbDevice() {} + MOCK_METHOD0(Open, scoped_refptr<UsbDeviceHandle>()); + MOCK_METHOD1(Close, bool(scoped_refptr<UsbDeviceHandle>)); +#if defined(OS_CHROMEOS) + MOCK_METHOD2(RequestUsbAccess, void(int, const base::Callback<void(bool)>&)); +#endif + MOCK_METHOD0(GetConfiguration, const UsbConfigDescriptor&()); private: - scoped_refptr<UsbConfigDescriptor> config_desc_; + virtual ~MockUsbDevice() {} }; class UsbFilterTest : public testing::Test { public: virtual void SetUp() OVERRIDE { - UsbInterfaceAltSettingDescriptorList alt_settings; - alt_settings.push_back(make_scoped_refptr( - new MockUsbInterfaceAltSettingDescriptor(1, 0, 0xFF, 0x42, 1))); - - UsbInterfaceDescriptorList interfaces; - interfaces.push_back( - make_scoped_refptr(new MockUsbInterfaceDescriptor(alt_settings))); - - scoped_refptr<UsbConfigDescriptor> config_desc( - new MockUsbConfigDescriptor(interfaces)); - - android_phone_ = new MockUsbDevice(0x18d1, 0x4ee2, 0, config_desc); + UsbInterfaceDescriptor interface; + interface.interface_number = 1; + interface.alternate_setting = 0; + interface.interface_class = 0xFF; + interface.interface_subclass = 0x42; + interface.interface_protocol = 0x01; + config_.interfaces.push_back(interface); + + android_phone_ = new MockUsbDevice(0x18d1, 0x4ee2, 0); + ON_CALL(*android_phone_.get(), GetConfiguration()) + .WillByDefault(ReturnRef(config_)); } protected: - scoped_refptr<UsbDevice> android_phone_; + UsbConfigDescriptor config_; + scoped_refptr<MockUsbDevice> android_phone_; }; TEST_F(UsbFilterTest, MatchAny) { diff --git a/device/usb/usb_device_handle.h b/device/usb/usb_device_handle.h index be7de09..08d97f8 100644 --- a/device/usb/usb_device_handle.h +++ b/device/usb/usb_device_handle.h @@ -12,7 +12,7 @@ #include "base/memory/ref_counted.h" #include "base/strings/string16.h" #include "base/threading/thread_checker.h" -#include "device/usb/usb_interface.h" +#include "device/usb/usb_descriptors.h" #include "net/base/io_buffer.h" namespace device { diff --git a/device/usb/usb_device_handle_impl.cc b/device/usb/usb_device_handle_impl.cc index c88fb9b..2d8c690 100644 --- a/device/usb/usb_device_handle_impl.cc +++ b/device/usb/usb_device_handle_impl.cc @@ -15,9 +15,9 @@ #include "base/synchronization/lock.h" #include "base/thread_task_runner_handle.h" #include "device/usb/usb_context.h" +#include "device/usb/usb_descriptors.h" #include "device/usb/usb_device_impl.h" #include "device/usb/usb_error.h" -#include "device/usb/usb_interface.h" #include "device/usb/usb_service.h" #include "third_party/libusb/src/libusb/libusb.h" @@ -182,18 +182,16 @@ void UsbDeviceHandleImpl::Transfer::Complete(UsbTransferStatus status, } } -UsbDeviceHandleImpl::UsbDeviceHandleImpl( - scoped_refptr<UsbContext> context, - UsbDeviceImpl* device, - PlatformUsbDeviceHandle handle, - scoped_refptr<UsbConfigDescriptor> interfaces) +UsbDeviceHandleImpl::UsbDeviceHandleImpl(scoped_refptr<UsbContext> context, + UsbDeviceImpl* device, + PlatformUsbDeviceHandle handle, + const UsbConfigDescriptor& config) : device_(device), handle_(handle), - interfaces_(interfaces), + config_(config), context_(context), task_runner_(base::ThreadTaskRunnerHandle::Get()) { DCHECK(handle) << "Cannot create device with NULL handle."; - DCHECK(interfaces_.get()) << "Unable to list interfaces"; } UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { @@ -661,16 +659,23 @@ void UsbDeviceHandleImpl::IsochronousTransfer( void UsbDeviceHandleImpl::RefreshEndpointMap() { DCHECK(thread_checker_.CalledOnValidThread()); endpoint_map_.clear(); - for (ClaimedInterfaceMap::iterator it = claimed_interfaces_.begin(); - it != claimed_interfaces_.end(); - ++it) { - scoped_refptr<const UsbInterfaceAltSettingDescriptor> interface_desc = - interfaces_->GetInterface(it->first) - ->GetAltSetting(it->second->alternate_setting()); - for (size_t i = 0; i < interface_desc->GetNumEndpoints(); i++) { - scoped_refptr<const UsbEndpointDescriptor> endpoint = - interface_desc->GetEndpoint(i); - endpoint_map_[endpoint->GetAddress()] = it->first; + for (ClaimedInterfaceMap::iterator claimedIt = claimed_interfaces_.begin(); + claimedIt != claimed_interfaces_.end(); + ++claimedIt) { + for (UsbInterfaceDescriptor::Iterator ifaceIt = config_.interfaces.begin(); + ifaceIt != config_.interfaces.end(); + ++ifaceIt) { + if (ifaceIt->interface_number == claimedIt->first && + ifaceIt->alternate_setting == + claimedIt->second->alternate_setting()) { + for (UsbEndpointDescriptor::Iterator endpointIt = + ifaceIt->endpoints.begin(); + endpointIt != ifaceIt->endpoints.end(); + ++endpointIt) { + endpoint_map_[endpointIt->address] = claimedIt->first; + } + break; + } } } } diff --git a/device/usb/usb_device_handle_impl.h b/device/usb/usb_device_handle_impl.h index e4e5163..0498f26 100644 --- a/device/usb/usb_device_handle_impl.h +++ b/device/usb/usb_device_handle_impl.h @@ -13,7 +13,6 @@ #include "base/strings/string16.h" #include "base/threading/thread_checker.h" #include "device/usb/usb_device_handle.h" -#include "device/usb/usb_interface.h" #include "net/base/io_buffer.h" #include "third_party/libusb/src/libusb/libusb.h" @@ -24,7 +23,7 @@ class SingleThreadTaskRunner; namespace device { class UsbContext; -class UsbConfigDescriptor; +struct UsbConfigDescriptor; class UsbDeviceImpl; typedef libusb_device_handle* PlatformUsbDeviceHandle; @@ -89,7 +88,7 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle { UsbDeviceHandleImpl(scoped_refptr<UsbContext> context, UsbDeviceImpl* device, PlatformUsbDeviceHandle handle, - scoped_refptr<UsbConfigDescriptor> interfaces); + const UsbConfigDescriptor& config); virtual ~UsbDeviceHandleImpl(); @@ -143,7 +142,7 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle { PlatformUsbDeviceHandle handle_; - scoped_refptr<UsbConfigDescriptor> interfaces_; + const UsbConfigDescriptor& config_; std::vector<uint16> languages_; std::map<uint8, base::string16> strings_; diff --git a/device/usb/usb_device_impl.cc b/device/usb/usb_device_impl.cc index 03c8ee0..84f7143 100644 --- a/device/usb/usb_device_impl.cc +++ b/device/usb/usb_device_impl.cc @@ -12,9 +12,9 @@ #include "base/stl_util.h" #include "base/thread_task_runner_handle.h" #include "device/usb/usb_context.h" +#include "device/usb/usb_descriptors.h" #include "device/usb/usb_device_handle_impl.h" #include "device/usb/usb_error.h" -#include "device/usb/usb_interface_impl.h" #include "third_party/libusb/src/libusb/libusb.h" #if defined(OS_CHROMEOS) @@ -23,6 +23,8 @@ #include "chromeos/dbus/permission_broker_client.h" #endif // defined(OS_CHROMEOS) +namespace device { + namespace { #if defined(OS_CHROMEOS) @@ -34,9 +36,67 @@ void OnRequestUsbAccessReplied( } #endif // defined(OS_CHROMEOS) -} // namespace +UsbEndpointDirection GetDirection( + const libusb_endpoint_descriptor* descriptor) { + switch (descriptor->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) { + case LIBUSB_ENDPOINT_IN: + return USB_DIRECTION_INBOUND; + case LIBUSB_ENDPOINT_OUT: + return USB_DIRECTION_OUTBOUND; + default: + NOTREACHED(); + return USB_DIRECTION_INBOUND; + } +} -namespace device { +UsbSynchronizationType GetSynchronizationType( + const libusb_endpoint_descriptor* descriptor) { + switch (descriptor->bmAttributes & LIBUSB_ISO_SYNC_TYPE_MASK) { + case LIBUSB_ISO_SYNC_TYPE_NONE: + return USB_SYNCHRONIZATION_NONE; + case LIBUSB_ISO_SYNC_TYPE_ASYNC: + return USB_SYNCHRONIZATION_ASYNCHRONOUS; + case LIBUSB_ISO_SYNC_TYPE_ADAPTIVE: + return USB_SYNCHRONIZATION_ADAPTIVE; + case LIBUSB_ISO_SYNC_TYPE_SYNC: + return USB_SYNCHRONIZATION_SYNCHRONOUS; + default: + NOTREACHED(); + return USB_SYNCHRONIZATION_NONE; + } +} + +UsbTransferType GetTransferType(const libusb_endpoint_descriptor* descriptor) { + switch (descriptor->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return USB_TRANSFER_CONTROL; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return USB_TRANSFER_ISOCHRONOUS; + case LIBUSB_TRANSFER_TYPE_BULK: + return USB_TRANSFER_BULK; + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return USB_TRANSFER_INTERRUPT; + default: + NOTREACHED(); + return USB_TRANSFER_CONTROL; + } +} + +UsbUsageType GetUsageType(const libusb_endpoint_descriptor* descriptor) { + switch (descriptor->bmAttributes & LIBUSB_ISO_USAGE_TYPE_MASK) { + case LIBUSB_ISO_USAGE_TYPE_DATA: + return USB_USAGE_DATA; + case LIBUSB_ISO_USAGE_TYPE_FEEDBACK: + return USB_USAGE_FEEDBACK; + case LIBUSB_ISO_USAGE_TYPE_IMPLICIT: + return USB_USAGE_EXPLICIT_FEEDBACK; + default: + NOTREACHED(); + return USB_USAGE_DATA; + } +} + +} // namespace UsbDeviceImpl::UsbDeviceImpl( scoped_refptr<UsbContext> context, @@ -47,6 +107,7 @@ UsbDeviceImpl::UsbDeviceImpl( uint32 unique_id) : UsbDevice(vendor_id, product_id, unique_id), platform_device_(platform_device), + current_configuration_cached_(false), context_(context), ui_task_runner_(ui_task_runner) { CHECK(platform_device) << "platform_device cannot be NULL"; @@ -101,11 +162,12 @@ scoped_refptr<UsbDeviceHandle> UsbDeviceImpl::Open() { PlatformUsbDeviceHandle handle; const int rv = libusb_open(platform_device_, &handle); if (LIBUSB_SUCCESS == rv) { - scoped_refptr<UsbConfigDescriptor> interfaces = ListInterfaces(); - if (!interfaces.get()) + GetConfiguration(); + if (!current_configuration_cached_) { return NULL; + } scoped_refptr<UsbDeviceHandleImpl> device_handle = - new UsbDeviceHandleImpl(context_, this, handle, interfaces); + new UsbDeviceHandleImpl(context_, this, handle, current_configuration_); handles_.push_back(device_handle); return device_handle; } else { @@ -128,19 +190,78 @@ bool UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) { return false; } -scoped_refptr<UsbConfigDescriptor> UsbDeviceImpl::ListInterfaces() { +const UsbConfigDescriptor& UsbDeviceImpl::GetConfiguration() { DCHECK(thread_checker_.CalledOnValidThread()); - PlatformUsbConfigDescriptor platform_config; - const int rv = - libusb_get_active_config_descriptor(platform_device_, &platform_config); - if (rv == LIBUSB_SUCCESS) { - return new UsbConfigDescriptorImpl(platform_config); - } else { - VLOG(1) << "Failed to get config descriptor: " - << ConvertPlatformUsbErrorToString(rv); - return NULL; + if (!current_configuration_cached_) { + libusb_config_descriptor* platform_config; + const int rv = + libusb_get_active_config_descriptor(platform_device_, &platform_config); + if (rv != LIBUSB_SUCCESS) { + VLOG(1) << "Failed to get config descriptor: " + << ConvertPlatformUsbErrorToString(rv); + return current_configuration_; + } + + current_configuration_.configuration_value = + platform_config->bConfigurationValue; + current_configuration_.self_powered = + (platform_config->bmAttributes & 0x40) != 0; + current_configuration_.remote_wakeup = + (platform_config->bmAttributes & 0x20) != 0; + current_configuration_.maximum_power = platform_config->MaxPower * 2; + + for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) { + const struct libusb_interface* platform_interface = + &platform_config->interface[i]; + for (int j = 0; j < platform_interface->num_altsetting; ++j) { + const struct libusb_interface_descriptor* platform_alt_setting = + &platform_interface->altsetting[j]; + UsbInterfaceDescriptor interface; + + interface.interface_number = platform_alt_setting->bInterfaceNumber; + interface.alternate_setting = platform_alt_setting->bAlternateSetting; + interface.interface_class = platform_alt_setting->bInterfaceClass; + interface.interface_subclass = platform_alt_setting->bInterfaceSubClass; + interface.interface_protocol = platform_alt_setting->bInterfaceProtocol; + + for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) { + const struct libusb_endpoint_descriptor* platform_endpoint = + &platform_alt_setting->endpoint[k]; + UsbEndpointDescriptor endpoint; + + endpoint.address = platform_endpoint->bEndpointAddress; + endpoint.direction = GetDirection(platform_endpoint); + endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize; + endpoint.synchronization_type = + GetSynchronizationType(platform_endpoint); + endpoint.transfer_type = GetTransferType(platform_endpoint); + endpoint.usage_type = GetUsageType(platform_endpoint); + endpoint.polling_interval = platform_endpoint->bInterval; + endpoint.extra_data = std::vector<uint8_t>( + platform_endpoint->extra, + platform_endpoint->extra + platform_endpoint->extra_length); + + interface.endpoints.push_back(endpoint); + } + + interface.extra_data = std::vector<uint8_t>( + platform_alt_setting->extra, + platform_alt_setting->extra + platform_alt_setting->extra_length); + + current_configuration_.interfaces.push_back(interface); + } + } + + current_configuration_.extra_data = std::vector<uint8_t>( + platform_config->extra, + platform_config->extra + platform_config->extra_length); + + libusb_free_config_descriptor(platform_config); + current_configuration_cached_ = true; } + + return current_configuration_; } void UsbDeviceImpl::OnDisconnect() { diff --git a/device/usb/usb_device_impl.h b/device/usb/usb_device_impl.h index 1ece2e0..e95c8db 100644 --- a/device/usb/usb_device_impl.h +++ b/device/usb/usb_device_impl.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/callback.h" #include "base/threading/thread_checker.h" +#include "device/usb/usb_descriptors.h" #include "device/usb/usb_device.h" struct libusb_device; @@ -37,7 +38,7 @@ class UsbDeviceImpl : public UsbDevice { #endif // OS_CHROMEOS virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE; virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE; - virtual scoped_refptr<UsbConfigDescriptor> ListInterfaces() OVERRIDE; + virtual const UsbConfigDescriptor& GetConfiguration() OVERRIDE; protected: friend class UsbServiceImpl; @@ -59,6 +60,11 @@ class UsbDeviceImpl : public UsbDevice { base::ThreadChecker thread_checker_; PlatformUsbDevice platform_device_; + // The active configuration descriptor is not read immediately but cached for + // later use. + bool current_configuration_cached_; + UsbConfigDescriptor current_configuration_; + // Retain the context so that it will not be released before UsbDevice. scoped_refptr<UsbContext> context_; diff --git a/device/usb/usb_interface.h b/device/usb/usb_interface.h deleted file mode 100644 index 9285718..0000000 --- a/device/usb/usb_interface.h +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef DEVICE_USB_USB_INTERFACE_H_ -#define DEVICE_USB_USB_INTERFACE_H_ - -#include "base/memory/ref_counted.h" - -namespace device { - -enum UsbTransferType { - USB_TRANSFER_CONTROL = 0, - USB_TRANSFER_ISOCHRONOUS, - USB_TRANSFER_BULK, - USB_TRANSFER_INTERRUPT, -}; - -enum UsbEndpointDirection { - USB_DIRECTION_INBOUND = 0, - USB_DIRECTION_OUTBOUND, -}; - -enum UsbSynchronizationType { - USB_SYNCHRONIZATION_NONE = 0, - USB_SYNCHRONIZATION_ASYNCHRONOUS, - USB_SYNCHRONIZATION_ADAPTIVE, - USB_SYNCHRONIZATION_SYNCHRONOUS, -}; - -enum UsbUsageType { - USB_USAGE_DATA = 0, - USB_USAGE_FEEDBACK, - USB_USAGE_EXPLICIT_FEEDBACK -}; - -class UsbEndpointDescriptor - : public base::RefCounted<const UsbEndpointDescriptor> { - public: - virtual int GetAddress() const = 0; - virtual UsbEndpointDirection GetDirection() const = 0; - virtual int GetMaximumPacketSize() const = 0; - virtual UsbSynchronizationType GetSynchronizationType() const = 0; - virtual UsbTransferType GetTransferType() const = 0; - virtual UsbUsageType GetUsageType() const = 0; - virtual int GetPollingInterval() const = 0; - - protected: - friend class base::RefCounted<const UsbEndpointDescriptor>; - - UsbEndpointDescriptor() {}; - virtual ~UsbEndpointDescriptor() {}; - - DISALLOW_COPY_AND_ASSIGN(UsbEndpointDescriptor); -}; - -class UsbInterfaceAltSettingDescriptor - : public base::RefCounted<const UsbInterfaceAltSettingDescriptor> { - public: - virtual size_t GetNumEndpoints() const = 0; - virtual scoped_refptr<const UsbEndpointDescriptor> GetEndpoint( - size_t index) const = 0; - - virtual int GetInterfaceNumber() const = 0; - virtual int GetAlternateSetting() const = 0; - virtual int GetInterfaceClass() const = 0; - virtual int GetInterfaceSubclass() const = 0; - virtual int GetInterfaceProtocol() const = 0; - - protected: - friend class base::RefCounted<const UsbInterfaceAltSettingDescriptor>; - - UsbInterfaceAltSettingDescriptor() {}; - virtual ~UsbInterfaceAltSettingDescriptor() {}; - - DISALLOW_COPY_AND_ASSIGN(UsbInterfaceAltSettingDescriptor); -}; - -class UsbInterfaceDescriptor - : public base::RefCounted<const UsbInterfaceDescriptor> { - public: - virtual size_t GetNumAltSettings() const = 0; - virtual scoped_refptr<const UsbInterfaceAltSettingDescriptor> GetAltSetting( - size_t index) const = 0; - - protected: - friend class base::RefCounted<const UsbInterfaceDescriptor>; - - UsbInterfaceDescriptor() {}; - virtual ~UsbInterfaceDescriptor() {}; - - DISALLOW_COPY_AND_ASSIGN(UsbInterfaceDescriptor); -}; - -class UsbConfigDescriptor : public base::RefCounted<UsbConfigDescriptor> { - public: - virtual size_t GetNumInterfaces() const = 0; - virtual scoped_refptr<const UsbInterfaceDescriptor> GetInterface( - size_t index) const = 0; - - protected: - friend class base::RefCounted<UsbConfigDescriptor>; - - UsbConfigDescriptor() {}; - virtual ~UsbConfigDescriptor() {}; - - DISALLOW_COPY_AND_ASSIGN(UsbConfigDescriptor); -}; - -} // namespace device - -#endif // DEVICE_USB_USB_INTERFACE_H_ diff --git a/device/usb/usb_interface_impl.cc b/device/usb/usb_interface_impl.cc deleted file mode 100644 index af3d0e3..0000000 --- a/device/usb/usb_interface_impl.cc +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "device/usb/usb_interface_impl.h" - -#include "base/logging.h" -#include "third_party/libusb/src/libusb/libusb.h" - -namespace device { - -UsbEndpointDescriptorImpl::UsbEndpointDescriptorImpl( - scoped_refptr<const UsbConfigDescriptor> config, - PlatformUsbEndpointDescriptor descriptor) - : config_(config), descriptor_(descriptor) { -} - -UsbEndpointDescriptorImpl::~UsbEndpointDescriptorImpl() { -} - -int UsbEndpointDescriptorImpl::GetAddress() const { - return descriptor_->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK; -} - -UsbEndpointDirection UsbEndpointDescriptorImpl::GetDirection() const { - switch (descriptor_->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) { - case LIBUSB_ENDPOINT_IN: - return USB_DIRECTION_INBOUND; - case LIBUSB_ENDPOINT_OUT: - return USB_DIRECTION_OUTBOUND; - default: - NOTREACHED(); - return USB_DIRECTION_INBOUND; - } -} - -int UsbEndpointDescriptorImpl::GetMaximumPacketSize() const { - return descriptor_->wMaxPacketSize; -} - -UsbSynchronizationType UsbEndpointDescriptorImpl::GetSynchronizationType() - const { - switch (descriptor_->bmAttributes & LIBUSB_ISO_SYNC_TYPE_MASK) { - case LIBUSB_ISO_SYNC_TYPE_NONE: - return USB_SYNCHRONIZATION_NONE; - case LIBUSB_ISO_SYNC_TYPE_ASYNC: - return USB_SYNCHRONIZATION_ASYNCHRONOUS; - case LIBUSB_ISO_SYNC_TYPE_ADAPTIVE: - return USB_SYNCHRONIZATION_ADAPTIVE; - case LIBUSB_ISO_SYNC_TYPE_SYNC: - return USB_SYNCHRONIZATION_SYNCHRONOUS; - default: - NOTREACHED(); - return USB_SYNCHRONIZATION_NONE; - } -} - -UsbTransferType UsbEndpointDescriptorImpl::GetTransferType() const { - switch (descriptor_->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) { - case LIBUSB_TRANSFER_TYPE_CONTROL: - return USB_TRANSFER_CONTROL; - case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: - return USB_TRANSFER_ISOCHRONOUS; - case LIBUSB_TRANSFER_TYPE_BULK: - return USB_TRANSFER_BULK; - case LIBUSB_TRANSFER_TYPE_INTERRUPT: - return USB_TRANSFER_INTERRUPT; - default: - NOTREACHED(); - return USB_TRANSFER_CONTROL; - } -} - -UsbUsageType UsbEndpointDescriptorImpl::GetUsageType() const { - switch (descriptor_->bmAttributes & LIBUSB_ISO_USAGE_TYPE_MASK) { - case LIBUSB_ISO_USAGE_TYPE_DATA: - return USB_USAGE_DATA; - case LIBUSB_ISO_USAGE_TYPE_FEEDBACK: - return USB_USAGE_FEEDBACK; - case LIBUSB_ISO_USAGE_TYPE_IMPLICIT: - return USB_USAGE_EXPLICIT_FEEDBACK; - default: - NOTREACHED(); - return USB_USAGE_DATA; - } -} - -int UsbEndpointDescriptorImpl::GetPollingInterval() const { - return descriptor_->bInterval; -} - -UsbInterfaceAltSettingDescriptorImpl::UsbInterfaceAltSettingDescriptorImpl( - scoped_refptr<const UsbConfigDescriptor> config, - PlatformUsbInterfaceDescriptor descriptor) - : config_(config), descriptor_(descriptor) { -} - -UsbInterfaceAltSettingDescriptorImpl::~UsbInterfaceAltSettingDescriptorImpl() { -} - -size_t UsbInterfaceAltSettingDescriptorImpl::GetNumEndpoints() const { - return descriptor_->bNumEndpoints; -} - -scoped_refptr<const UsbEndpointDescriptor> -UsbInterfaceAltSettingDescriptorImpl::GetEndpoint(size_t index) const { - return new UsbEndpointDescriptorImpl(config_, &descriptor_->endpoint[index]); -} - -int UsbInterfaceAltSettingDescriptorImpl::GetInterfaceNumber() const { - return descriptor_->bInterfaceNumber; -} - -int UsbInterfaceAltSettingDescriptorImpl::GetAlternateSetting() const { - return descriptor_->bAlternateSetting; -} - -int UsbInterfaceAltSettingDescriptorImpl::GetInterfaceClass() const { - return descriptor_->bInterfaceClass; -} - -int UsbInterfaceAltSettingDescriptorImpl::GetInterfaceSubclass() const { - return descriptor_->bInterfaceSubClass; -} - -int UsbInterfaceAltSettingDescriptorImpl::GetInterfaceProtocol() const { - return descriptor_->bInterfaceProtocol; -} - -UsbInterfaceDescriptorImpl::UsbInterfaceDescriptorImpl( - scoped_refptr<const UsbConfigDescriptor> config, - PlatformUsbInterface usbInterface) - : config_(config), interface_(usbInterface) { -} - -UsbInterfaceDescriptorImpl::~UsbInterfaceDescriptorImpl() { -} - -size_t UsbInterfaceDescriptorImpl::GetNumAltSettings() const { - return interface_->num_altsetting; -} - -scoped_refptr<const UsbInterfaceAltSettingDescriptor> -UsbInterfaceDescriptorImpl::GetAltSetting(size_t index) const { - return new UsbInterfaceAltSettingDescriptorImpl( - config_, &interface_->altsetting[index]); -} - -UsbConfigDescriptorImpl::UsbConfigDescriptorImpl( - PlatformUsbConfigDescriptor config) - : config_(config) { - DCHECK(config); -} - -UsbConfigDescriptorImpl::~UsbConfigDescriptorImpl() { - libusb_free_config_descriptor(config_); -} - -size_t UsbConfigDescriptorImpl::GetNumInterfaces() const { - return config_->bNumInterfaces; -} - -scoped_refptr<const UsbInterfaceDescriptor> -UsbConfigDescriptorImpl::GetInterface(size_t index) const { - return new UsbInterfaceDescriptorImpl(this, &config_->interface[index]); -} - -} // namespace device diff --git a/device/usb/usb_interface_impl.h b/device/usb/usb_interface_impl.h deleted file mode 100644 index 0f6b913..0000000 --- a/device/usb/usb_interface_impl.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef DEVICE_USB_USB_INTERFACE_IMPL_H_ -#define DEVICE_USB_USB_INTERFACE_IMPL_H_ - -#include "base/memory/ref_counted.h" -#include "device/usb/usb_interface.h" - -struct libusb_config_descriptor; -struct libusb_endpoint_descriptor; -struct libusb_interface; -struct libusb_interface_descriptor; - -namespace device { - -typedef libusb_config_descriptor* PlatformUsbConfigDescriptor; -typedef const libusb_endpoint_descriptor* PlatformUsbEndpointDescriptor; -typedef const libusb_interface* PlatformUsbInterface; -typedef const libusb_interface_descriptor* PlatformUsbInterfaceDescriptor; - -class UsbConfigDescriptorImpl; -class UsbInterfaceAltSettingDescriptor; - -class UsbEndpointDescriptorImpl : public UsbEndpointDescriptor { - public: - virtual int GetAddress() const OVERRIDE; - virtual UsbEndpointDirection GetDirection() const OVERRIDE; - virtual int GetMaximumPacketSize() const OVERRIDE; - virtual UsbSynchronizationType GetSynchronizationType() const OVERRIDE; - virtual UsbTransferType GetTransferType() const OVERRIDE; - virtual UsbUsageType GetUsageType() const OVERRIDE; - virtual int GetPollingInterval() const OVERRIDE; - - private: - friend class base::RefCounted<const UsbEndpointDescriptorImpl>; - friend class UsbInterfaceAltSettingDescriptorImpl; - - UsbEndpointDescriptorImpl(scoped_refptr<const UsbConfigDescriptor> config, - PlatformUsbEndpointDescriptor descriptor); - virtual ~UsbEndpointDescriptorImpl(); - - scoped_refptr<const UsbConfigDescriptor> config_; - PlatformUsbEndpointDescriptor descriptor_; - - DISALLOW_COPY_AND_ASSIGN(UsbEndpointDescriptorImpl); -}; - -class UsbInterfaceAltSettingDescriptorImpl - : public UsbInterfaceAltSettingDescriptor { - public: - virtual size_t GetNumEndpoints() const OVERRIDE; - virtual scoped_refptr<const UsbEndpointDescriptor> GetEndpoint( - size_t index) const OVERRIDE; - - virtual int GetInterfaceNumber() const OVERRIDE; - virtual int GetAlternateSetting() const OVERRIDE; - virtual int GetInterfaceClass() const OVERRIDE; - virtual int GetInterfaceSubclass() const OVERRIDE; - virtual int GetInterfaceProtocol() const OVERRIDE; - - private: - friend class UsbInterfaceDescriptorImpl; - - UsbInterfaceAltSettingDescriptorImpl( - scoped_refptr<const UsbConfigDescriptor> config, - PlatformUsbInterfaceDescriptor descriptor); - virtual ~UsbInterfaceAltSettingDescriptorImpl(); - - scoped_refptr<const UsbConfigDescriptor> config_; - PlatformUsbInterfaceDescriptor descriptor_; - - DISALLOW_COPY_AND_ASSIGN(UsbInterfaceAltSettingDescriptorImpl); -}; - -class UsbInterfaceDescriptorImpl : public UsbInterfaceDescriptor { - public: - virtual size_t GetNumAltSettings() const OVERRIDE; - virtual scoped_refptr<const UsbInterfaceAltSettingDescriptor> GetAltSetting( - size_t index) const OVERRIDE; - - private: - friend class base::RefCounted<const UsbInterfaceDescriptorImpl>; - friend class UsbConfigDescriptorImpl; - - UsbInterfaceDescriptorImpl(scoped_refptr<const UsbConfigDescriptor> config, - PlatformUsbInterface usbInterface); - virtual ~UsbInterfaceDescriptorImpl(); - - scoped_refptr<const UsbConfigDescriptor> config_; - PlatformUsbInterface interface_; - - DISALLOW_COPY_AND_ASSIGN(UsbInterfaceDescriptorImpl); -}; - -class UsbConfigDescriptorImpl : public UsbConfigDescriptor { - public: - virtual size_t GetNumInterfaces() const OVERRIDE; - virtual scoped_refptr<const UsbInterfaceDescriptor> GetInterface( - size_t index) const OVERRIDE; - - private: - friend class base::RefCounted<UsbConfigDescriptor>; - friend class UsbDeviceImpl; - - explicit UsbConfigDescriptorImpl(PlatformUsbConfigDescriptor config); - virtual ~UsbConfigDescriptorImpl(); - - PlatformUsbConfigDescriptor config_; - - DISALLOW_COPY_AND_ASSIGN(UsbConfigDescriptorImpl); -}; - -} // namespace device - -#endif // DEVICE_USB_USB_INTERFACE_IMPL_H_ |