Commit 43c5c906 authored by reillyg's avatar reillyg Committed by Commit bot

Move string descriptor getters from UsbDeviceHandle to UsbDevice.

The common string descriptors: iManufacturer, iProduct and iSerialNumber
should be accessible without opening the device. On Linux these can be
read out of sysfs without having access to the usbfs device node. This
is critical on Chrome OS because otherwise the permission broker needs
to be asked for permission to access the device. On other platforms we
fall back to opening the device temporarily. This will stop being the
case on OS X when libusb is no longer used and on Windows this will be
part of the initial enumeration process.

BUG=
TBR=dgozman@chromium.org

Review URL: https://codereview.chromium.org/601073002

Cr-Commit-Position: refs/heads/master@{#296802}
parent d0956cf3
...@@ -158,11 +158,7 @@ bool SavedDevicesService::SavedDevices::IsRegistered( ...@@ -158,11 +158,7 @@ bool SavedDevicesService::SavedDevices::IsRegistered(
continue; continue;
} }
if (!have_serial_number) { if (!have_serial_number) {
scoped_refptr<UsbDeviceHandle> device_handle = device->Open(); if (!device->GetSerialNumber(&serial_number)) {
if (!device_handle.get()) {
break;
}
if (!device_handle->GetSerial(&serial_number)) {
break; break;
} }
have_serial_number = true; have_serial_number = true;
......
...@@ -25,88 +25,27 @@ using device::UsbEndpointDirection; ...@@ -25,88 +25,27 @@ using device::UsbEndpointDirection;
using device::UsbTransferCallback; using device::UsbTransferCallback;
using testing::Return; using testing::Return;
class MockUsbDeviceHandle : public UsbDeviceHandle {
public:
MockUsbDeviceHandle(const std::string& serial_number)
: UsbDeviceHandle(), serial_number_(serial_number) {}
MOCK_CONST_METHOD0(GetDevice, scoped_refptr<UsbDevice>());
MOCK_METHOD0(Close, void());
MOCK_METHOD10(ControlTransfer,
void(UsbEndpointDirection direction,
TransferRequestType request_type,
TransferRecipient recipient,
uint8 request,
uint16 value,
uint16 index,
net::IOBuffer* buffer,
size_t length,
unsigned int timeout,
const UsbTransferCallback& callback));
MOCK_METHOD6(BulkTransfer,
void(UsbEndpointDirection direction,
uint8 endpoint,
net::IOBuffer* buffer,
size_t length,
unsigned int timeout,
const UsbTransferCallback& callback));
MOCK_METHOD6(InterruptTransfer,
void(UsbEndpointDirection direction,
uint8 endpoint,
net::IOBuffer* buffer,
size_t length,
unsigned int timeout,
const UsbTransferCallback& callback));
MOCK_METHOD8(IsochronousTransfer,
void(UsbEndpointDirection direction,
uint8 endpoint,
net::IOBuffer* buffer,
size_t length,
unsigned int packets,
unsigned int packet_length,
unsigned int timeout,
const UsbTransferCallback& callback));
MOCK_METHOD0(ResetDevice, bool());
MOCK_METHOD1(ClaimInterface, bool(int interface_number));
MOCK_METHOD1(ReleaseInterface, bool(int interface_number));
MOCK_METHOD2(SetInterfaceAlternateSetting,
bool(int interface_number, int alternate_setting));
MOCK_METHOD1(GetManufacturer, bool(base::string16* manufacturer));
MOCK_METHOD1(GetProduct, bool(base::string16* product));
bool GetSerial(base::string16* serial) OVERRIDE {
if (serial_number_.empty()) {
return false;
}
*serial = base::UTF8ToUTF16(serial_number_);
return true;
}
private:
virtual ~MockUsbDeviceHandle() {}
const std::string serial_number_;
};
class MockUsbDevice : public UsbDevice { class MockUsbDevice : public UsbDevice {
public: public:
MockUsbDevice(const std::string& serial_number, uint32 unique_id) MockUsbDevice(const std::string& serial_number, uint32 unique_id)
: UsbDevice(0, 0, unique_id), serial_number_(serial_number) {} : UsbDevice(0, 0, unique_id), serial_number_(serial_number) {}
MOCK_METHOD0(Open, scoped_refptr<UsbDeviceHandle>());
MOCK_METHOD1(Close, bool(scoped_refptr<UsbDeviceHandle>)); MOCK_METHOD1(Close, bool(scoped_refptr<UsbDeviceHandle>));
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
MOCK_METHOD2(RequestUsbAccess, void(int, const base::Callback<void(bool)>&)); MOCK_METHOD2(RequestUsbAccess, void(int, const base::Callback<void(bool)>&));
#endif #endif
MOCK_METHOD0(GetConfiguration, const device::UsbConfigDescriptor&()); MOCK_METHOD0(GetConfiguration, const device::UsbConfigDescriptor&());
MOCK_METHOD1(GetManufacturer, bool(base::string16*));
MOCK_METHOD1(GetProduct, bool(base::string16*));
bool GetSerialNumber(base::string16* serial) OVERRIDE {
if (serial_number_.empty()) {
return false;
}
scoped_refptr<UsbDeviceHandle> Open() OVERRIDE { *serial = base::UTF8ToUTF16(serial_number_);
return new MockUsbDeviceHandle(serial_number_); return true;
} }
void NotifyDisconnect() { UsbDevice::NotifyDisconnect(); } void NotifyDisconnect() { UsbDevice::NotifyDisconnect(); }
......
...@@ -144,20 +144,8 @@ class MockUsbDeviceHandle : public UsbDeviceHandle { ...@@ -144,20 +144,8 @@ class MockUsbDeviceHandle : public UsbDeviceHandle {
} }
virtual bool ResetDevice() OVERRIDE { return true; } virtual bool ResetDevice() OVERRIDE { return true; }
virtual bool GetStringDescriptor(uint8_t string_id, base::string16* content) {
virtual bool GetManufacturer(base::string16* manufacturer) OVERRIDE { return false;
*manufacturer = base::UTF8ToUTF16(kDeviceManufacturer);
return true;
}
virtual bool GetProduct(base::string16* product) OVERRIDE {
*product = base::UTF8ToUTF16(kDeviceModel);
return true;
}
virtual bool GetSerial(base::string16* serial) OVERRIDE {
*serial = base::UTF8ToUTF16(kDeviceSerial);
return true;
} }
// Async IO. Can be called on any thread. // Async IO. Can be called on any thread.
...@@ -379,6 +367,21 @@ class MockUsbDevice : public UsbDevice { ...@@ -379,6 +367,21 @@ class MockUsbDevice : public UsbDevice {
return config_desc_; return config_desc_;
} }
virtual bool GetManufacturer(base::string16* manufacturer) OVERRIDE {
*manufacturer = base::UTF8ToUTF16(kDeviceManufacturer);
return true;
}
virtual bool GetProduct(base::string16* product) OVERRIDE {
*product = base::UTF8ToUTF16(kDeviceModel);
return true;
}
virtual bool GetSerialNumber(base::string16* serial) OVERRIDE {
*serial = base::UTF8ToUTF16(kDeviceSerial);
return true;
}
virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE { virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE {
return true; return true;
} }
......
...@@ -96,7 +96,7 @@ scoped_refptr<AndroidUsbDevice> ClaimInterface( ...@@ -96,7 +96,7 @@ scoped_refptr<AndroidUsbDevice> ClaimInterface(
return NULL; return NULL;
base::string16 serial; base::string16 serial;
if (!usb_handle->GetSerial(&serial) || serial.empty()) if (!usb_handle->GetDevice()->GetSerialNumber(&serial) || serial.empty())
return NULL; return NULL;
return new AndroidUsbDevice(rsa_key, return new AndroidUsbDevice(rsa_key,
......
...@@ -100,7 +100,7 @@ class HidConnectionTest : public testing::Test { ...@@ -100,7 +100,7 @@ class HidConnectionTest : public testing::Test {
for (std::vector<HidDeviceInfo>::iterator it = devices.begin(); for (std::vector<HidDeviceInfo>::iterator it = devices.begin();
it != devices.end(); it != devices.end();
++it) { ++it) {
if (it->serial_number == test_gadget_->GetSerial()) { if (it->serial_number == test_gadget_->GetSerialNumber()) {
device_id_ = it->device_id; device_id_ = it->device_id;
break; break;
} }
......
...@@ -35,7 +35,7 @@ class UsbTestGadget { ...@@ -35,7 +35,7 @@ class UsbTestGadget {
virtual bool SetType(Type type) = 0; virtual bool SetType(Type type) = 0;
virtual UsbDevice* GetDevice() const = 0; virtual UsbDevice* GetDevice() const = 0;
virtual std::string GetSerial() const = 0; virtual std::string GetSerialNumber() const = 0;
protected: protected:
UsbTestGadget() {} UsbTestGadget() {}
......
...@@ -71,7 +71,7 @@ class UsbTestGadgetImpl : public UsbTestGadget { ...@@ -71,7 +71,7 @@ class UsbTestGadgetImpl : public UsbTestGadget {
virtual bool Reconnect() OVERRIDE; virtual bool Reconnect() OVERRIDE;
virtual bool SetType(Type type) OVERRIDE; virtual bool SetType(Type type) OVERRIDE;
virtual UsbDevice* GetDevice() const OVERRIDE; virtual UsbDevice* GetDevice() const OVERRIDE;
virtual std::string GetSerial() const OVERRIDE; virtual std::string GetSerialNumber() const OVERRIDE;
protected: protected:
UsbTestGadgetImpl(); UsbTestGadgetImpl();
...@@ -166,7 +166,7 @@ UsbDevice* UsbTestGadgetImpl::GetDevice() const { ...@@ -166,7 +166,7 @@ UsbDevice* UsbTestGadgetImpl::GetDevice() const {
return device_.get(); return device_.get();
} }
std::string UsbTestGadgetImpl::GetSerial() const { std::string UsbTestGadgetImpl::GetSerialNumber() const {
return device_address_; return device_address_;
} }
...@@ -205,13 +205,8 @@ bool UsbTestGadgetImpl::FindUnclaimed() { ...@@ -205,13 +205,8 @@ bool UsbTestGadgetImpl::FindUnclaimed() {
devices.begin(); iter != devices.end(); ++iter) { devices.begin(); iter != devices.end(); ++iter) {
const scoped_refptr<UsbDevice> &device = *iter; const scoped_refptr<UsbDevice> &device = *iter;
if (device->vendor_id() == 0x18D1 && device->product_id() == 0x58F0) { if (device->vendor_id() == 0x18D1 && device->product_id() == 0x58F0) {
scoped_refptr<UsbDeviceHandle> handle = device->Open();
if (handle.get() == NULL) {
continue;
}
base::string16 serial_utf16; base::string16 serial_utf16;
if (!handle->GetSerial(&serial_utf16)) { if (!device->GetSerialNumber(&serial_utf16)) {
continue; continue;
} }
...@@ -340,7 +335,7 @@ bool UsbTestGadgetImpl::Update() { ...@@ -340,7 +335,7 @@ bool UsbTestGadgetImpl::Update() {
bool UsbTestGadgetImpl::FindClaimed() { bool UsbTestGadgetImpl::FindClaimed() {
CHECK(!device_.get()); CHECK(!device_.get());
std::string expected_serial = GetSerial(); std::string expected_serial = GetSerialNumber();
std::vector<scoped_refptr<UsbDevice> > devices; std::vector<scoped_refptr<UsbDevice> > devices;
usb_service_->GetDevices(&devices); usb_service_->GetDevices(&devices);
...@@ -362,13 +357,8 @@ bool UsbTestGadgetImpl::FindClaimed() { ...@@ -362,13 +357,8 @@ bool UsbTestGadgetImpl::FindClaimed() {
continue; continue;
} }
scoped_refptr<UsbDeviceHandle> handle(device->Open());
if (handle.get() == NULL) {
continue;
}
base::string16 serial_utf16; base::string16 serial_utf16;
if (!handle->GetSerial(&serial_utf16)) { if (!device->GetSerialNumber(&serial_utf16)) {
continue; continue;
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/strings/string16.h"
namespace device { namespace device {
...@@ -54,6 +55,18 @@ class UsbDevice : public base::RefCountedThreadSafe<UsbDevice> { ...@@ -54,6 +55,18 @@ class UsbDevice : public base::RefCountedThreadSafe<UsbDevice> {
// Blocking method. Must be called on FILE thread. // Blocking method. Must be called on FILE thread.
virtual const UsbConfigDescriptor& GetConfiguration() = 0; virtual const UsbConfigDescriptor& GetConfiguration() = 0;
// Gets the manufacturer string of the device, or returns false.
// Blocking method. Must be called on FILE thread.
virtual bool GetManufacturer(base::string16* manufacturer) = 0;
// Gets the product string of the device, or returns false.
// Blocking method. Must be called on FILE thread.
virtual bool GetProduct(base::string16* product) = 0;
// Gets the serial number string of the device, or returns false.
// Blocking method. Must be called on FILE thread.
virtual bool GetSerialNumber(base::string16* serial) = 0;
void AddObserver(Observer* obs) { observer_list_.AddObserver(obs); } void AddObserver(Observer* obs) { observer_list_.AddObserver(obs); }
void RemoveObserver(Observer* obs) { observer_list_.RemoveObserver(obs); } void RemoveObserver(Observer* obs) { observer_list_.RemoveObserver(obs); }
......
...@@ -30,6 +30,9 @@ class MockUsbDevice : public UsbDevice { ...@@ -30,6 +30,9 @@ class MockUsbDevice : public UsbDevice {
MOCK_METHOD2(RequestUsbAccess, void(int, const base::Callback<void(bool)>&)); MOCK_METHOD2(RequestUsbAccess, void(int, const base::Callback<void(bool)>&));
#endif #endif
MOCK_METHOD0(GetConfiguration, const UsbConfigDescriptor&()); MOCK_METHOD0(GetConfiguration, const UsbConfigDescriptor&());
MOCK_METHOD1(GetManufacturer, bool(base::string16*));
MOCK_METHOD1(GetProduct, bool(base::string16*));
MOCK_METHOD1(GetSerialNumber, bool(base::string16*));
private: private:
virtual ~MockUsbDevice() {} virtual ~MockUsbDevice() {}
......
...@@ -56,9 +56,10 @@ class UsbDeviceHandle : public base::RefCountedThreadSafe<UsbDeviceHandle> { ...@@ -56,9 +56,10 @@ class UsbDeviceHandle : public base::RefCountedThreadSafe<UsbDeviceHandle> {
virtual bool SetInterfaceAlternateSetting(int interface_number, virtual bool SetInterfaceAlternateSetting(int interface_number,
int alternate_setting) = 0; int alternate_setting) = 0;
virtual bool ResetDevice() = 0; virtual bool ResetDevice() = 0;
virtual bool GetManufacturer(base::string16* manufacturer) = 0;
virtual bool GetProduct(base::string16* product) = 0; // Gets the string descriptor with the given index from the device, or returns
virtual bool GetSerial(base::string16* serial) = 0; // false. This method is blocking and must be called on the FILE thread.
virtual bool GetStringDescriptor(uint8 string_id, base::string16* string) = 0;
// Async IO. Can be called on any thread. // Async IO. Can be called on any thread.
virtual void ControlTransfer(UsbEndpointDirection direction, virtual void ControlTransfer(UsbEndpointDirection direction,
......
This diff is collapsed.
...@@ -40,9 +40,9 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle { ...@@ -40,9 +40,9 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle {
virtual bool SetInterfaceAlternateSetting(int interface_number, virtual bool SetInterfaceAlternateSetting(int interface_number,
int alternate_setting) OVERRIDE; int alternate_setting) OVERRIDE;
virtual bool ResetDevice() OVERRIDE; virtual bool ResetDevice() OVERRIDE;
virtual bool GetManufacturer(base::string16* manufacturer) OVERRIDE; virtual bool GetStringDescriptor(uint8 string_id,
virtual bool GetProduct(base::string16* product) OVERRIDE; base::string16* string) OVERRIDE;
virtual bool GetSerial(base::string16* serial) OVERRIDE;
virtual void ControlTransfer(UsbEndpointDirection direction, virtual void ControlTransfer(UsbEndpointDirection direction,
TransferRequestType request_type, TransferRequestType request_type,
TransferRecipient recipient, TransferRecipient recipient,
...@@ -132,7 +132,6 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle { ...@@ -132,7 +132,6 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle {
void CompleteTransfer(PlatformUsbTransferHandle transfer); void CompleteTransfer(PlatformUsbTransferHandle transfer);
bool GetSupportedLanguages(); bool GetSupportedLanguages();
bool GetStringDescriptor(uint8 string_id, base::string16* string);
// Informs the object to drop internal references. // Informs the object to drop internal references.
void InternalClose(); void InternalClose();
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include "base/location.h" #include "base/location.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h" #include "base/thread_task_runner_handle.h"
#include "device/usb/usb_context.h" #include "device/usb/usb_context.h"
#include "device/usb/usb_descriptors.h" #include "device/usb/usb_descriptors.h"
...@@ -23,6 +25,10 @@ ...@@ -23,6 +25,10 @@
#include "chromeos/dbus/permission_broker_client.h" #include "chromeos/dbus/permission_broker_client.h"
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
#if defined(OS_LINUX)
#include "device/udev_linux/udev.h"
#endif // defined(OS_LINUX)
namespace device { namespace device {
namespace { namespace {
...@@ -123,6 +129,44 @@ UsbDeviceImpl::UsbDeviceImpl( ...@@ -123,6 +129,44 @@ UsbDeviceImpl::UsbDeviceImpl(
ui_task_runner_(ui_task_runner) { ui_task_runner_(ui_task_runner) {
CHECK(platform_device) << "platform_device cannot be NULL"; CHECK(platform_device) << "platform_device cannot be NULL";
libusb_ref_device(platform_device); libusb_ref_device(platform_device);
#if defined(OS_LINUX)
ScopedUdevPtr udev(udev_new());
ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev.get()));
udev_enumerate_add_match_subsystem(enumerate.get(), "usb");
if (udev_enumerate_scan_devices(enumerate.get()) != 0) {
return;
}
std::string bus_number =
base::IntToString(libusb_get_bus_number(platform_device));
std::string device_address =
base::IntToString(libusb_get_device_address(platform_device));
udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate.get());
for (udev_list_entry* i = devices; i != NULL;
i = udev_list_entry_get_next(i)) {
ScopedUdevDevicePtr device(
udev_device_new_from_syspath(udev.get(), udev_list_entry_get_name(i)));
if (device) {
const char* value = udev_device_get_sysattr_value(device.get(), "busnum");
if (!value || bus_number != value) {
continue;
}
value = udev_device_get_sysattr_value(device.get(), "devnum");
if (!value || device_address != value) {
continue;
}
value = udev_device_get_sysattr_value(device.get(), "manufacturer");
manufacturer_ = value ? value : "";
value = udev_device_get_sysattr_value(device.get(), "product");
product_ = value ? value : "";
value = udev_device_get_sysattr_value(device.get(), "serial");
serial_number_ = value ? value : "";
break;
}
}
#endif
} }
UsbDeviceImpl::~UsbDeviceImpl() { UsbDeviceImpl::~UsbDeviceImpl() {
...@@ -275,6 +319,100 @@ const UsbConfigDescriptor& UsbDeviceImpl::GetConfiguration() { ...@@ -275,6 +319,100 @@ const UsbConfigDescriptor& UsbDeviceImpl::GetConfiguration() {
return current_configuration_; return current_configuration_;
} }
bool UsbDeviceImpl::GetManufacturer(base::string16* manufacturer) {
DCHECK(thread_checker_.CalledOnValidThread());
#if defined(OS_LINUX)
if (manufacturer_.empty()) {
return false;
}
*manufacturer = base::UTF8ToUTF16(manufacturer_);
return true;
#else
// This is a non-blocking call as libusb has the descriptor in memory.
libusb_device_descriptor desc;
const int rv = libusb_get_device_descriptor(platform_device_, &desc);
if (rv != LIBUSB_SUCCESS) {
VLOG(1) << "Failed to read device descriptor: "
<< ConvertPlatformUsbErrorToString(rv);
return false;
}
if (desc.iManufacturer == 0) {
return false;
}
scoped_refptr<UsbDeviceHandle> device_handle = Open();
if (device_handle.get()) {
return device_handle->GetStringDescriptor(desc.iManufacturer, manufacturer);
}
return false;
#endif
}
bool UsbDeviceImpl::GetProduct(base::string16* product) {
DCHECK(thread_checker_.CalledOnValidThread());
#if defined(OS_LINUX)
if (product_.empty()) {
return false;
}
*product = base::UTF8ToUTF16(product_);
return true;
#else
// This is a non-blocking call as libusb has the descriptor in memory.
libusb_device_descriptor desc;
const int rv = libusb_get_device_descriptor(platform_device_, &desc);
if (rv != LIBUSB_SUCCESS) {
VLOG(1) << "Failed to read device descriptor: "
<< ConvertPlatformUsbErrorToString(rv);
return false;
}
if (desc.iProduct == 0) {
return false;
}
scoped_refptr<UsbDeviceHandle> device_handle = Open();
if (device_handle.get()) {
return device_handle->GetStringDescriptor(desc.iProduct, product);
}
return false;
#endif
}
bool UsbDeviceImpl::GetSerialNumber(base::string16* serial_number) {
DCHECK(thread_checker_.CalledOnValidThread());
#if defined(OS_LINUX)
if (serial_number_.empty()) {
return false;
}
*serial_number = base::UTF8ToUTF16(serial_number_);
return true;
#else
// This is a non-blocking call as libusb has the descriptor in memory.
libusb_device_descriptor desc;
const int rv = libusb_get_device_descriptor(platform_device_, &desc);
if (rv != LIBUSB_SUCCESS) {
VLOG(1) << "Failed to read device descriptor: "
<< ConvertPlatformUsbErrorToString(rv);
return false;
}
if (desc.iSerialNumber == 0) {
return false;
}
scoped_refptr<UsbDeviceHandle> device_handle = Open();
if (device_handle.get()) {
return device_handle->GetStringDescriptor(desc.iSerialNumber,
serial_number);
}
return false;
#endif
}
void UsbDeviceImpl::OnDisconnect() { void UsbDeviceImpl::OnDisconnect() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
HandlesVector handles; HandlesVector handles;
......
...@@ -39,6 +39,9 @@ class UsbDeviceImpl : public UsbDevice { ...@@ -39,6 +39,9 @@ class UsbDeviceImpl : public UsbDevice {
virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE; virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE;
virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE; virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE;
virtual const UsbConfigDescriptor& GetConfiguration() OVERRIDE; virtual const UsbConfigDescriptor& GetConfiguration() OVERRIDE;
virtual bool GetManufacturer(base::string16* manufacturer) OVERRIDE;
virtual bool GetProduct(base::string16* product) OVERRIDE;
virtual bool GetSerialNumber(base::string16* serial_number) OVERRIDE;
protected: protected:
friend class UsbServiceImpl; friend class UsbServiceImpl;
...@@ -60,6 +63,15 @@ class UsbDeviceImpl : public UsbDevice { ...@@ -60,6 +63,15 @@ class UsbDeviceImpl : public UsbDevice {
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
PlatformUsbDevice platform_device_; PlatformUsbDevice platform_device_;
#if defined(OS_LINUX)
// On Linux these properties are read from sysfs when the device is enumerated
// to avoid hitting the permission broker on Chrome OS for a real string
// descriptor request.
std::string manufacturer_;
std::string product_;
std::string serial_number_;
#endif
// The active configuration descriptor is not read immediately but cached for // The active configuration descriptor is not read immediately but cached for
// later use. // later use.
bool current_configuration_cached_; bool current_configuration_cached_;
......
...@@ -29,23 +29,16 @@ TEST_F(UsbServiceTest, ClaimGadget) { ...@@ -29,23 +29,16 @@ TEST_F(UsbServiceTest, ClaimGadget) {
scoped_ptr<UsbTestGadget> gadget = UsbTestGadget::Claim(); scoped_ptr<UsbTestGadget> gadget = UsbTestGadget::Claim();
ASSERT_TRUE(gadget.get()); ASSERT_TRUE(gadget.get());
scoped_refptr<UsbDeviceHandle> handle = gadget->GetDevice()->Open(); scoped_refptr<UsbDevice> device = gadget->GetDevice();
base::string16 utf16; base::string16 utf16;
ASSERT_TRUE(handle->GetManufacturer(&utf16)); ASSERT_TRUE(device->GetManufacturer(&utf16));
ASSERT_EQ("Google Inc.", base::UTF16ToUTF8(utf16));
// Check again to make sure string descriptor caching works.
ASSERT_EQ("Google Inc.", base::UTF16ToUTF8(utf16)); ASSERT_EQ("Google Inc.", base::UTF16ToUTF8(utf16));
ASSERT_TRUE(handle->GetProduct(&utf16)); ASSERT_TRUE(device->GetProduct(&utf16));
ASSERT_EQ("Test Gadget (default state)", base::UTF16ToUTF8(utf16));
// Check again to make sure string descriptor caching works.
ASSERT_EQ("Test Gadget (default state)", base::UTF16ToUTF8(utf16)); ASSERT_EQ("Test Gadget (default state)", base::UTF16ToUTF8(utf16));
ASSERT_TRUE(handle->GetSerial(&utf16)); ASSERT_TRUE(device->GetSerialNumber(&utf16));
ASSERT_EQ(gadget->GetSerial(), base::UTF16ToUTF8(utf16)); ASSERT_EQ(gadget->GetSerialNumber(), base::UTF16ToUTF8(utf16));
// Check again to make sure string descriptor caching works.
ASSERT_EQ(gadget->GetSerial(), base::UTF16ToUTF8(utf16));
} }
TEST_F(UsbServiceTest, DisconnectAndReconnect) { TEST_F(UsbServiceTest, DisconnectAndReconnect) {
......
...@@ -87,13 +87,11 @@ class MockUsbDeviceHandle : public UsbDeviceHandle { ...@@ -87,13 +87,11 @@ class MockUsbDeviceHandle : public UsbDeviceHandle {
const UsbTransferCallback& callback)); const UsbTransferCallback& callback));
MOCK_METHOD0(ResetDevice, bool()); MOCK_METHOD0(ResetDevice, bool());
MOCK_METHOD2(GetStringDescriptor, bool(uint8_t, base::string16*));
MOCK_METHOD1(ClaimInterface, bool(const int interface_number)); MOCK_METHOD1(ClaimInterface, bool(const int interface_number));
MOCK_METHOD1(ReleaseInterface, bool(const int interface_number)); MOCK_METHOD1(ReleaseInterface, bool(const int interface_number));
MOCK_METHOD2(SetInterfaceAlternateSetting, MOCK_METHOD2(SetInterfaceAlternateSetting,
bool(const int interface_number, const int alternate_setting)); bool(const int interface_number, const int alternate_setting));
MOCK_METHOD1(GetManufacturer, bool(base::string16* manufacturer));
MOCK_METHOD1(GetProduct, bool(base::string16* product));
MOCK_METHOD1(GetSerial, bool(base::string16* serial));
virtual scoped_refptr<UsbDevice> GetDevice() const OVERRIDE { virtual scoped_refptr<UsbDevice> GetDevice() const OVERRIDE {
return device_; return device_;
...@@ -133,6 +131,9 @@ class MockUsbDevice : public UsbDevice { ...@@ -133,6 +131,9 @@ class MockUsbDevice : public UsbDevice {
#endif // OS_CHROMEOS #endif // OS_CHROMEOS
MOCK_METHOD0(GetConfiguration, const UsbConfigDescriptor&()); MOCK_METHOD0(GetConfiguration, const UsbConfigDescriptor&());
MOCK_METHOD1(GetManufacturer, bool(base::string16* manufacturer));
MOCK_METHOD1(GetProduct, bool(base::string16* product));
MOCK_METHOD1(GetSerialNumber, bool(base::string16* serial_number));
private: private:
MockUsbDeviceHandle* mock_handle_; MockUsbDeviceHandle* mock_handle_;
......
...@@ -33,7 +33,6 @@ namespace { ...@@ -33,7 +33,6 @@ namespace {
const char kErrorInitService[] = "Failed to initialize USB service."; const char kErrorInitService[] = "Failed to initialize USB service.";
const char kErrorNoDevice[] = "No such device."; const char kErrorNoDevice[] = "No such device.";
const char kErrorOpen[] = "Failed to open device.";
} // namespace } // namespace
...@@ -120,23 +119,17 @@ void UsbPrivateGetDeviceInfoFunction::AsyncWorkStart() { ...@@ -120,23 +119,17 @@ void UsbPrivateGetDeviceInfoFunction::AsyncWorkStart() {
device_info.product_name.reset(new std::string(name)); device_info.product_name.reset(new std::string(name));
} }
scoped_refptr<UsbDeviceHandle> device_handle = device->Open();
if (!device_handle.get()) {
CompleteWithError(kErrorOpen);
return;
}
base::string16 utf16; base::string16 utf16;
if (device_handle->GetManufacturer(&utf16)) { if (device->GetManufacturer(&utf16)) {
device_info.manufacturer_string.reset( device_info.manufacturer_string.reset(
new std::string(base::UTF16ToUTF8(utf16))); new std::string(base::UTF16ToUTF8(utf16)));
} }
if (device_handle->GetProduct(&utf16)) { if (device->GetProduct(&utf16)) {
device_info.product_string.reset(new std::string(base::UTF16ToUTF8(utf16))); device_info.product_string.reset(new std::string(base::UTF16ToUTF8(utf16)));
} }
if (device_handle->GetSerial(&utf16)) { if (device->GetSerialNumber(&utf16)) {
device_info.serial_string.reset(new std::string(base::UTF16ToUTF8(utf16))); device_info.serial_string.reset(new std::string(base::UTF16ToUTF8(utf16)));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment