diff options
-rw-r--r-- | chrome/browser/devtools/device/usb/android_usb_browsertest.cc | 154 | ||||
-rw-r--r-- | chrome/browser/devtools/device/usb/android_usb_device.cc | 88 | ||||
-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 | 151 | ||||
-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 | ||||
-rw-r--r-- | extensions/browser/api/usb/usb_api.cc | 108 | ||||
-rw-r--r-- | extensions/browser/api/usb/usb_api.h | 1 | ||||
-rw-r--r-- | extensions/browser/api/usb/usb_apitest.cc | 21 |
20 files changed, 459 insertions, 843 deletions
diff --git a/chrome/browser/devtools/device/usb/android_usb_browsertest.cc b/chrome/browser/devtools/device/usb/android_usb_browsertest.cc index ca52178..5852546 100644 --- a/chrome/browser/devtools/device/usb/android_usb_browsertest.cc +++ b/chrome/browser/devtools/device/usb/android_usb_browsertest.cc @@ -12,9 +12,9 @@ #include "chrome/test/base/in_process_browser_test.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_utils.h" +#include "device/usb/usb_descriptors.h" #include "device/usb/usb_device.h" #include "device/usb/usb_device_handle.h" -#include "device/usb/usb_interface.h" #include "device/usb/usb_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,7 +25,6 @@ using device::UsbDeviceHandle; using device::UsbEndpointDescriptor; using device::UsbEndpointDirection; using device::UsbInterfaceDescriptor; -using device::UsbInterfaceAltSettingDescriptor; using device::UsbService; using device::UsbSynchronizationType; using device::UsbTransferCallback; @@ -104,125 +103,6 @@ const char* GetMockShellResponse(std::string command) { return ""; } -class MockUsbEndpointDescriptor : public UsbEndpointDescriptor { - public: - virtual int GetAddress() const OVERRIDE { return address_; } - - virtual UsbEndpointDirection GetDirection() const OVERRIDE { - return direction_; - } - - virtual int GetMaximumPacketSize() const OVERRIDE { - return maximum_packet_size_; - } - - virtual UsbSynchronizationType GetSynchronizationType() const OVERRIDE { - return usb_synchronization_type_; - } - - virtual UsbTransferType GetTransferType() const OVERRIDE { - return usb_transfer_type_; - } - virtual UsbUsageType GetUsageType() const OVERRIDE { return usb_usage_type_; } - - virtual int GetPollingInterval() const OVERRIDE { return polling_interval_; } - - int address_; - UsbEndpointDirection direction_; - int maximum_packet_size_; - UsbSynchronizationType usb_synchronization_type_; - UsbTransferType usb_transfer_type_; - UsbUsageType usb_usage_type_; - int polling_interval_; - - private: - virtual ~MockUsbEndpointDescriptor() {} -}; - -template <class T> -class MockUsbInterfaceAltSettingDescriptor - : public UsbInterfaceAltSettingDescriptor { - public: - MockUsbInterfaceAltSettingDescriptor(int interface_number, - int alternate_setting) - : interface_number_(interface_number), - alternate_setting_(alternate_setting) {} - - virtual size_t GetNumEndpoints() const OVERRIDE { - // See IsAndroidInterface function in android_usb_device.cc - return 2; - } - - virtual scoped_refptr<const UsbEndpointDescriptor> GetEndpoint( - size_t index) const OVERRIDE { - EXPECT_GT(static_cast<size_t>(2), index); - MockUsbEndpointDescriptor* result = new MockUsbEndpointDescriptor(); - result->address_ = index + 1; - result->usb_transfer_type_ = device::USB_TRANSFER_BULK; - result->direction_ = ((index == 0) ? device::USB_DIRECTION_INBOUND - : device::USB_DIRECTION_OUTBOUND); - result->maximum_packet_size_ = 1 << 20; // 1Mb maximum packet size - return result; - } - - virtual int GetInterfaceNumber() const OVERRIDE { return interface_number_; } - - virtual int GetAlternateSetting() const OVERRIDE { - return alternate_setting_; - } - - virtual int GetInterfaceClass() const OVERRIDE { return T::kClass; } - - virtual int GetInterfaceSubclass() const OVERRIDE { return T::kSubclass; } - - virtual int GetInterfaceProtocol() const OVERRIDE { return T::kProtocol; } - - protected: - virtual ~MockUsbInterfaceAltSettingDescriptor() {}; - - private: - const int interface_number_; - const int alternate_setting_; -}; - -template <class T> -class MockUsbInterfaceDescriptor : public UsbInterfaceDescriptor { - public: - explicit MockUsbInterfaceDescriptor(int interface_number) - : interface_number_(interface_number) {} - - virtual size_t GetNumAltSettings() const OVERRIDE { - // See IsAndroidInterface function in android_usb_device.cc - return 1; - } - virtual scoped_refptr<const UsbInterfaceAltSettingDescriptor> GetAltSetting( - size_t index) const OVERRIDE { - EXPECT_EQ(static_cast<size_t>(0), index); - return new MockUsbInterfaceAltSettingDescriptor<T>(interface_number_, 0); - } - - protected: - const int interface_number_; - virtual ~MockUsbInterfaceDescriptor() {} -}; - -template <class T> -class MockUsbConfigDescriptor : public UsbConfigDescriptor { - public: - MockUsbConfigDescriptor() {} - - virtual size_t GetNumInterfaces() const OVERRIDE { return 1; } - - virtual scoped_refptr<const UsbInterfaceDescriptor> GetInterface( - size_t index) const OVERRIDE { - EXPECT_EQ(static_cast<size_t>(0), index); - return new MockUsbInterfaceDescriptor<T>(index); - } - - protected: - virtual ~MockUsbConfigDescriptor() {}; -}; - template <class T> class MockUsbDevice; @@ -467,14 +347,37 @@ class MockUsbDeviceHandle : public UsbDeviceHandle { template <class T> class MockUsbDevice : public UsbDevice { public: - MockUsbDevice() : UsbDevice(0, 0, 0) {} + MockUsbDevice() : UsbDevice(0, 0, 0) { + UsbEndpointDescriptor bulk_in; + bulk_in.address = 0x81; + bulk_in.direction = device::USB_DIRECTION_INBOUND; + bulk_in.maximum_packet_size = 512; + bulk_in.transfer_type = device::USB_TRANSFER_BULK; + + UsbEndpointDescriptor bulk_out; + bulk_out.address = 0x01; + bulk_out.direction = device::USB_DIRECTION_OUTBOUND; + bulk_out.maximum_packet_size = 512; + bulk_out.transfer_type = device::USB_TRANSFER_BULK; + + UsbInterfaceDescriptor interface_desc; + interface_desc.interface_number = 0; + interface_desc.alternate_setting = 0; + interface_desc.interface_class = T::kClass; + interface_desc.interface_subclass = T::kSubclass; + interface_desc.interface_protocol = T::kProtocol; + interface_desc.endpoints.push_back(bulk_in); + interface_desc.endpoints.push_back(bulk_out); + + config_desc_.interfaces.push_back(interface_desc); + } virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE { return new MockUsbDeviceHandle<T>(this); } - virtual scoped_refptr<UsbConfigDescriptor> ListInterfaces() OVERRIDE { - return new MockUsbConfigDescriptor<T>(); + virtual const UsbConfigDescriptor& GetConfiguration() OVERRIDE { + return config_desc_; } virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE { @@ -497,6 +400,9 @@ class MockUsbDevice : public UsbDevice { protected: virtual ~MockUsbDevice() {} + + private: + UsbConfigDescriptor config_desc_; }; class MockUsbService : public UsbService { diff --git a/chrome/browser/devtools/device/usb/android_usb_device.cc b/chrome/browser/devtools/device/usb/android_usb_device.cc index 8ef9416..55b47c7 100644 --- a/chrome/browser/devtools/device/usb/android_usb_device.cc +++ b/chrome/browser/devtools/device/usb/android_usb_device.cc @@ -19,8 +19,8 @@ #include "content/public/browser/browser_thread.h" #include "crypto/rsa_private_key.h" #include "device/core/device_client.h" +#include "device/usb/usb_descriptors.h" #include "device/usb/usb_device.h" -#include "device/usb/usb_interface.h" #include "device/usb/usb_service.h" #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" @@ -29,7 +29,6 @@ using device::UsbConfigDescriptor; using device::UsbDevice; using device::UsbDeviceHandle; -using device::UsbInterfaceAltSettingDescriptor; using device::UsbInterfaceDescriptor; using device::UsbEndpointDescriptor; using device::UsbService; @@ -59,17 +58,12 @@ typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet; base::LazyInstance<std::vector<AndroidUsbDevice*> >::Leaky g_devices = LAZY_INSTANCE_INITIALIZER; -bool IsAndroidInterface(scoped_refptr<const UsbInterfaceDescriptor> interface) { - if (interface->GetNumAltSettings() == 0) - return false; - - scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc = - interface->GetAltSetting(0); - - if (idesc->GetInterfaceClass() != kAdbClass || - idesc->GetInterfaceSubclass() != kAdbSubclass || - idesc->GetInterfaceProtocol() != kAdbProtocol || - idesc->GetNumEndpoints() != 2) { +bool IsAndroidInterface(const UsbInterfaceDescriptor& interface) { + if (interface.alternate_setting != 0 || + interface.interface_class != kAdbClass || + interface.interface_subclass != kAdbSubclass || + interface.interface_protocol != kAdbProtocol || + interface.endpoints.size() != 2) { return false; } return true; @@ -78,40 +72,40 @@ bool IsAndroidInterface(scoped_refptr<const UsbInterfaceDescriptor> interface) { scoped_refptr<AndroidUsbDevice> ClaimInterface( crypto::RSAPrivateKey* rsa_key, scoped_refptr<UsbDeviceHandle> usb_handle, - scoped_refptr<const UsbInterfaceDescriptor> interface, - int interface_id) { - scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc = - interface->GetAltSetting(0); - + const UsbInterfaceDescriptor& interface) { int inbound_address = 0; int outbound_address = 0; int zero_mask = 0; - for (size_t i = 0; i < idesc->GetNumEndpoints(); ++i) { - scoped_refptr<const UsbEndpointDescriptor> edesc = - idesc->GetEndpoint(i); - if (edesc->GetTransferType() != device::USB_TRANSFER_BULK) + for (UsbEndpointDescriptor::Iterator endpointIt = interface.endpoints.begin(); + endpointIt != interface.endpoints.end(); + ++endpointIt) { + if (endpointIt->transfer_type != device::USB_TRANSFER_BULK) continue; - if (edesc->GetDirection() == device::USB_DIRECTION_INBOUND) - inbound_address = edesc->GetAddress(); + if (endpointIt->direction == device::USB_DIRECTION_INBOUND) + inbound_address = endpointIt->address; else - outbound_address = edesc->GetAddress(); - zero_mask = edesc->GetMaximumPacketSize() - 1; + outbound_address = endpointIt->address; + zero_mask = endpointIt->maximum_packet_size - 1; } if (inbound_address == 0 || outbound_address == 0) return NULL; - if (!usb_handle->ClaimInterface(interface_id)) + if (!usb_handle->ClaimInterface(interface.interface_number)) return NULL; base::string16 serial; if (!usb_handle->GetSerial(&serial) || serial.empty()) return NULL; - return new AndroidUsbDevice(rsa_key, usb_handle, base::UTF16ToASCII(serial), - inbound_address, outbound_address, zero_mask, - interface_id); + return new AndroidUsbDevice(rsa_key, + usb_handle, + base::UTF16ToASCII(serial), + inbound_address, + outbound_address, + zero_mask, + interface.interface_number); } uint32 Checksum(const std::string& data) { @@ -207,12 +201,11 @@ static void OpenAndroidDeviceOnFileThread( bool success) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); if (success) { - scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces(); + const UsbConfigDescriptor& config = device->GetConfiguration(); scoped_refptr<UsbDeviceHandle> usb_handle = device->Open(); if (usb_handle.get()) { scoped_refptr<AndroidUsbDevice> android_device = - ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id), - interface_id); + ClaimInterface(rsa_key, usb_handle, config.interfaces[interface_id]); if (android_device.get()) devices->push_back(android_device.get()); else @@ -229,15 +222,17 @@ static int CountOnFileThread() { if (service != NULL) service->GetDevices(&usb_devices); int device_count = 0; - for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); - ++it) { - scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); - if (!config.get()) - continue; - - for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { - if (IsAndroidInterface(config->GetInterface(j))) + for (UsbDevices::iterator deviceIt = usb_devices.begin(); + deviceIt != usb_devices.end(); + ++deviceIt) { + const UsbConfigDescriptor& config = (*deviceIt)->GetConfiguration(); + + for (UsbInterfaceDescriptor::Iterator ifaceIt = config.interfaces.begin(); + ifaceIt != config.interfaces.end(); + ++ifaceIt) { + if (IsAndroidInterface(*ifaceIt)) { ++device_count; + } } } return device_count; @@ -264,16 +259,13 @@ static void EnumerateOnFileThread( for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); ++it) { - scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); - if (!config.get()) { - barrier.Run(); - continue; - } + const UsbConfigDescriptor& config = (*it)->GetConfiguration(); bool has_android_interface = false; - for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { - if (!IsAndroidInterface(config->GetInterface(j))) + for (size_t j = 0; j < config.interfaces.size(); ++j) { + if (!IsAndroidInterface(config.interfaces[j])) { continue; + } // Request permission on Chrome OS. #if defined(OS_CHROMEOS) 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..d0dc780 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,76 @@ 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); + 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_ diff --git a/extensions/browser/api/usb/usb_api.cc b/extensions/browser/api/usb/usb_api.cc index 53f5c5b..22e19c4 100644 --- a/extensions/browser/api/usb/usb_api.cc +++ b/extensions/browser/api/usb/usb_api.cc @@ -56,7 +56,6 @@ using device::UsbDeviceFilter; using device::UsbDeviceHandle; using device::UsbEndpointDescriptor; using device::UsbEndpointDirection; -using device::UsbInterfaceAltSettingDescriptor; using device::UsbInterfaceDescriptor; using device::UsbService; using device::UsbSynchronizationType; @@ -761,75 +760,58 @@ void UsbListInterfacesFunction::AsyncWorkStart() { if (!device_handle.get()) return; - scoped_refptr<UsbConfigDescriptor> config = - device_handle->GetDevice()->ListInterfaces(); + const UsbConfigDescriptor& config = + device_handle->GetDevice()->GetConfiguration(); - if (!config.get()) { - SetError(kErrorCannotListInterfaces); - AsyncWorkCompleted(); - return; - } + scoped_ptr<base::ListValue> result(new base::ListValue()); - result_.reset(new base::ListValue()); - - for (size_t i = 0, num_interfaces = config->GetNumInterfaces(); - i < num_interfaces; - ++i) { - scoped_refptr<const UsbInterfaceDescriptor> usb_interface( - config->GetInterface(i)); - for (size_t j = 0, num_descriptors = usb_interface->GetNumAltSettings(); - j < num_descriptors; - ++j) { - scoped_refptr<const UsbInterfaceAltSettingDescriptor> descriptor = - usb_interface->GetAltSetting(j); - std::vector<linked_ptr<EndpointDescriptor> > endpoints; - for (size_t k = 0, num_endpoints = descriptor->GetNumEndpoints(); - k < num_endpoints; - k++) { - scoped_refptr<const UsbEndpointDescriptor> endpoint = - descriptor->GetEndpoint(k); - linked_ptr<EndpointDescriptor> endpoint_desc(new EndpointDescriptor()); - - TransferType type; - Direction direction; - SynchronizationType synchronization; - UsageType usage; - - if (!ConvertTransferTypeSafely(endpoint->GetTransferType(), &type) || - !ConvertDirectionSafely(endpoint->GetDirection(), &direction) || - !ConvertSynchronizationTypeSafely( - endpoint->GetSynchronizationType(), &synchronization) || - !ConvertUsageTypeSafely(endpoint->GetUsageType(), &usage)) { - SetError(kErrorCannotListInterfaces); - AsyncWorkCompleted(); - return; - } - - endpoint_desc->address = endpoint->GetAddress(); - endpoint_desc->type = type; - endpoint_desc->direction = direction; - endpoint_desc->maximum_packet_size = endpoint->GetMaximumPacketSize(); - endpoint_desc->synchronization = synchronization; - endpoint_desc->usage = usage; - - int* polling_interval = new int; - endpoint_desc->polling_interval.reset(polling_interval); - *polling_interval = endpoint->GetPollingInterval(); - - endpoints.push_back(endpoint_desc); + for (UsbInterfaceDescriptor::Iterator interfaceIt = config.interfaces.begin(); + interfaceIt != config.interfaces.end(); + ++interfaceIt) { + std::vector<linked_ptr<EndpointDescriptor> > endpoints; + + for (UsbEndpointDescriptor::Iterator endpointIt = + interfaceIt->endpoints.begin(); + endpointIt != interfaceIt->endpoints.end(); + ++endpointIt) { + linked_ptr<EndpointDescriptor> endpoint_desc(new EndpointDescriptor()); + + TransferType type; + Direction direction; + SynchronizationType synchronization; + UsageType usage; + + if (!ConvertTransferTypeSafely(endpointIt->transfer_type, &type) || + !ConvertDirectionSafely(endpointIt->direction, &direction) || + !ConvertSynchronizationTypeSafely(endpointIt->synchronization_type, + &synchronization) || + !ConvertUsageTypeSafely(endpointIt->usage_type, &usage)) { + SetError(kErrorCannotListInterfaces); + AsyncWorkCompleted(); + return; } - result_->Append( - PopulateInterfaceDescriptor(descriptor->GetInterfaceNumber(), - descriptor->GetAlternateSetting(), - descriptor->GetInterfaceClass(), - descriptor->GetInterfaceSubclass(), - descriptor->GetInterfaceProtocol(), - &endpoints)); + endpoint_desc->address = endpointIt->address; + endpoint_desc->type = type; + endpoint_desc->direction = direction; + endpoint_desc->maximum_packet_size = endpointIt->maximum_packet_size; + endpoint_desc->synchronization = synchronization; + endpoint_desc->usage = usage; + endpoint_desc->polling_interval.reset( + new int(endpointIt->polling_interval)); + + endpoints.push_back(endpoint_desc); } + + result->Append(PopulateInterfaceDescriptor(interfaceIt->interface_number, + interfaceIt->alternate_setting, + interfaceIt->interface_class, + interfaceIt->interface_subclass, + interfaceIt->interface_protocol, + &endpoints)); } - SetResult(result_.release()); + SetResult(result.release()); AsyncWorkCompleted(); } diff --git a/extensions/browser/api/usb/usb_api.h b/extensions/browser/api/usb/usb_api.h index fd02d80..2a0a6ef 100644 --- a/extensions/browser/api/usb/usb_api.h +++ b/extensions/browser/api/usb/usb_api.h @@ -168,7 +168,6 @@ class UsbListInterfacesFunction : public UsbAsyncApiFunction { bool ConvertUsageTypeSafely(const device::UsbUsageType& input, extensions::core_api::usb::UsageType* output); - scoped_ptr<base::ListValue> result_; scoped_ptr<extensions::core_api::usb::ListInterfaces::Params> parameters_; }; diff --git a/extensions/browser/api/usb/usb_apitest.cc b/extensions/browser/api/usb/usb_apitest.cc index c3cd1a1..eea26c5 100644 --- a/extensions/browser/api/usb/usb_apitest.cc +++ b/extensions/browser/api/usb/usb_apitest.cc @@ -14,6 +14,7 @@ using testing::AnyNumber; using testing::_; using testing::Return; +using testing::ReturnRef; using content::BrowserThread; using device::UsbConfigDescriptor; using device::UsbDevice; @@ -106,16 +107,6 @@ class MockUsbDeviceHandle : public UsbDeviceHandle { virtual ~MockUsbDeviceHandle() {} }; -class MockUsbConfigDescriptor : public UsbConfigDescriptor { - public: - MOCK_CONST_METHOD0(GetNumInterfaces, size_t()); - MOCK_CONST_METHOD1(GetInterface, - scoped_refptr<const UsbInterfaceDescriptor>(size_t index)); - - protected: - virtual ~MockUsbConfigDescriptor() {} -}; - class MockUsbDevice : public UsbDevice { public: explicit MockUsbDevice(MockUsbDeviceHandle* mock_handle) @@ -141,7 +132,7 @@ class MockUsbDevice : public UsbDevice { } #endif // OS_CHROMEOS - MOCK_METHOD0(ListInterfaces, scoped_refptr<UsbConfigDescriptor>()); + MOCK_METHOD0(GetConfiguration, const UsbConfigDescriptor&()); private: MockUsbDeviceHandle* mock_handle_; @@ -225,12 +216,10 @@ IN_PROC_BROWSER_TEST_F(UsbApiTest, ResetDevice) { } IN_PROC_BROWSER_TEST_F(UsbApiTest, ListInterfaces) { - scoped_refptr<MockUsbConfigDescriptor> mock_descriptor = - new MockUsbConfigDescriptor(); + UsbConfigDescriptor config_descriptor; EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber()); - EXPECT_CALL(*mock_descriptor.get(), GetNumInterfaces()).WillOnce(Return(0)); - EXPECT_CALL(*mock_device_.get(), ListInterfaces()) - .WillOnce(Return(mock_descriptor)); + EXPECT_CALL(*mock_device_.get(), GetConfiguration()) + .WillOnce(ReturnRef(config_descriptor)); ASSERT_TRUE(RunExtensionTest("usb/list_interfaces")); } |