Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6189)

Unified Diff: chrome/browser/extensions/api/usb/usb_api.cc

Issue 12471013: Add chrome.usb.listInterfaces API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Response to Bei's PS1 comments Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/usb/usb_api.cc
diff --git a/chrome/browser/extensions/api/usb/usb_api.cc b/chrome/browser/extensions/api/usb/usb_api.cc
index 587fc7bdffe322a73835c8b79d487b04d0fb654f..4fdb0682b563fd0af2e078499413515b2dd8e2cf 100644
--- a/chrome/browser/extensions/api/usb/usb_api.cc
+++ b/chrome/browser/extensions/api/usb/usb_api.cc
@@ -18,6 +18,7 @@
namespace BulkTransfer = extensions::api::usb::BulkTransfer;
namespace ClaimInterface = extensions::api::usb::ClaimInterface;
+namespace ListInterfaces = extensions::api::usb::ListInterfaces;
namespace CloseDevice = extensions::api::usb::CloseDevice;
namespace ControlTransfer = extensions::api::usb::ControlTransfer;
namespace FindDevices = extensions::api::usb::FindDevices;
@@ -33,10 +34,15 @@ using std::vector;
using usb::ControlTransferInfo;
using usb::Device;
using usb::Direction;
+using usb::EndpointDescriptor;
using usb::GenericTransferInfo;
+using usb::InterfaceDescriptor;
using usb::IsochronousTransferInfo;
using usb::Recipient;
using usb::RequestType;
+using usb::SynchronizationType;
+using usb::TransferType;
+using usb::UsageType;
namespace {
@@ -51,6 +57,7 @@ static const char* kErrorStalled = "Transfer stalled.";
static const char* kErrorTimeout = "Transfer timed out.";
static const char* kErrorTransferLength = "Transfer length is insufficient.";
+static const char* kErrorCannotListInterfaces = "Error listing interfaces.";
static const char* kErrorCannotClaimInterface = "Error claiming interface.";
static const char* kErrorCannotReleaseInterface = "Error releasing interface.";
static const char* kErrorCannotSetInterfaceAlternateSetting =
@@ -58,6 +65,10 @@ static const char* kErrorCannotSetInterfaceAlternateSetting =
static const char* kErrorConvertDirection = "Invalid transfer direction.";
static const char* kErrorConvertRecipient = "Invalid transfer recipient.";
static const char* kErrorConvertRequestType = "Invalid request type.";
+static const char* kErrorConvertSynchronizationType =
+ "Invalid synchronization type";
+static const char* kErrorConvertTransferType = "Invalid endpoint type.";
+static const char* kErrorConvertUsageType = "Invalid usage type.";
static const char* kErrorMalformedParameters = "Error parsing parameters.";
static const char* kErrorNoDevice = "No such device.";
static const char* kErrorPermissionDenied =
@@ -75,14 +86,95 @@ static const int kMaxPacketLength = 64 * 1024;
static UsbDevice* device_for_test_ = NULL;
+static bool ConvertDirectionToApi(const UsbEndpointDirection& input,
+ Direction* output) {
+ switch (input) {
+ case USB_DIRECTION_INBOUND:
+ *output = usb::DIRECTION_IN;
+ return true;
+ case USB_DIRECTION_OUTBOUND:
+ *output = usb::DIRECTION_OUT;
+ return true;
+ default:
+ return false;
+ }
+ NOTREACHED();
+ return false;
+}
+
+static bool ConvertSynchronizationTypeToApi(
+ const UsbSynchronizationType& input,
+ extensions::api::usb::SynchronizationType* output) {
+ switch (input) {
+ case USB_SYNCHRONIZATION_NONE:
+ *output = usb::SYNCHRONIZATION_TYPE_NONE;
+ return true;
+ case USB_SYNCHRONIZATION_ASYNCHRONOUS:
+ *output = usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS;
+ return true;
+ case USB_SYNCHRONIZATION_ADAPTIVE:
+ *output = usb::SYNCHRONIZATION_TYPE_ADAPTIVE;
+ return true;
+ case USB_SYNCHRONIZATION_SYNCHRONOUS:
+ *output = usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS;
+ return true;
+ default:
+ return false;
+ }
+ NOTREACHED();
+ return false;
+}
+
+static bool ConvertTransferTypeToApi(
+ const UsbTransferType& input,
+ extensions::api::usb::TransferType* output) {
+ switch (input) {
+ case USB_TRANSFER_CONTROL:
+ *output = usb::TRANSFER_TYPE_CONTROL;
+ return true;
+ case USB_TRANSFER_INTERRUPT:
+ *output = usb::TRANSFER_TYPE_INTERRUPT;
+ return true;
+ case USB_TRANSFER_ISOCHRONOUS:
+ *output = usb::TRANSFER_TYPE_ISOCHRONOUS;
+ return true;
+ case USB_TRANSFER_BULK:
+ *output = usb::TRANSFER_TYPE_BULK;
+ return true;
+ default:
+ return false;
+ }
+ NOTREACHED();
+ return false;
+}
+
+static bool ConvertUsageTypeToApi(const UsbUsageType& input,
+ extensions::api::usb::UsageType* output) {
+ switch (input) {
+ case USB_USAGE_DATA:
+ *output = usb::USAGE_TYPE_DATA;
+ return true;
+ case USB_USAGE_FEEDBACK:
+ *output = usb::USAGE_TYPE_FEEDBACK;
+ return true;
+ case USB_USAGE_EXPLICIT_FEEDBACK:
+ *output = usb::USAGE_TYPE_EXPLICITFEEDBACK;
+ return true;
+ default:
+ return false;
+ }
+ NOTREACHED();
+ return false;
Kenny Root (Google) 2013/05/08 02:29:34 Looks like I did that and accidentally reverted it
+}
+
static bool ConvertDirection(const Direction& input,
- UsbDevice::TransferDirection* output) {
+ UsbEndpointDirection* output) {
switch (input) {
case usb::DIRECTION_IN:
- *output = UsbDevice::INBOUND;
+ *output = USB_DIRECTION_INBOUND;
return true;
case usb::DIRECTION_OUT:
- *output = UsbDevice::OUTBOUND;
+ *output = USB_DIRECTION_OUTBOUND;
return true;
default:
return false;
@@ -155,7 +247,7 @@ static bool GetTransferSize(const T& input, size_t* output) {
template<class T>
static scoped_refptr<net::IOBuffer> CreateBufferForTransfer(
- const T& input, UsbDevice::TransferDirection direction, size_t size) {
+ const T& input, UsbEndpointDirection direction, size_t size) {
if (size >= kMaxTransferLength)
return NULL;
@@ -166,9 +258,9 @@ static scoped_refptr<net::IOBuffer> CreateBufferForTransfer(
scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max(
static_cast<size_t>(1), size));
- if (direction == UsbDevice::INBOUND) {
+ if (direction == USB_DIRECTION_INBOUND) {
return buffer;
- } else if (direction == UsbDevice::OUTBOUND) {
+ } else if (direction == USB_DIRECTION_OUTBOUND) {
if (input.data.get() && size <= input.data->size()) {
memcpy(buffer->data(), input.data->data(), size);
return buffer;
@@ -222,6 +314,20 @@ static base::Value* PopulateDevice(int handle, int vendor_id, int product_id) {
return device.ToValue().release();
}
+static base::Value* PopulateInterfaceDescriptor(int interface_number,
+ int alternate_setting, int interface_class, int interface_subclass,
+ int interface_protocol,
+ std::vector<linked_ptr<EndpointDescriptor> >* endpoints) {
+ InterfaceDescriptor descriptor;
+ descriptor.interface_number = interface_number;
+ descriptor.alternate_setting = alternate_setting;
+ descriptor.interface_class = interface_class;
+ descriptor.interface_subclass = interface_subclass;
+ descriptor.interface_protocol = interface_subclass;
+ descriptor.endpoints = *endpoints;
+ return descriptor.ToValue().release();
+}
+
} // namespace
namespace extensions {
@@ -271,7 +377,7 @@ void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status,
}
bool UsbAsyncApiTransferFunction::ConvertDirectionSafely(
- const Direction& input, UsbDevice::TransferDirection* output) {
+ const Direction& input, UsbEndpointDirection* output) {
const bool converted = ConvertDirection(input, output);
if (!converted)
SetError(kErrorConvertDirection);
@@ -361,6 +467,128 @@ void UsbFindDevicesFunction::OnCompleted() {
AsyncWorkCompleted();
}
+UsbListInterfacesFunction::UsbListInterfacesFunction() {}
+
+UsbListInterfacesFunction::~UsbListInterfacesFunction() {}
+
+bool UsbListInterfacesFunction::Prepare() {
+ parameters_ = ListInterfaces::Params::Create(*args_);
+ EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+ return true;
+}
+
+void UsbListInterfacesFunction::AsyncWorkStart() {
+ UsbDeviceResource* const device = GetUsbDeviceResource(
+ parameters_->device.handle);
+ if (!device) {
+ CompleteWithError(kErrorNoDevice);
+ return;
+ }
+
+ device->device()->ListInterfaces(config_, base::Bind(
+ &UsbListInterfacesFunction::OnCompleted, this));
+}
+
+void UsbListInterfacesFunction::OnCompleted(bool success) {
+ if (!success) {
+ SetError(kErrorCannotListInterfaces);
+ AsyncWorkCompleted();
+ return;
+ }
+
+ for (size_t i = 0, numInterfaces = config_->GetNumInterfaces();
+ i < numInterfaces; ++i) {
+ scoped_refptr<const UsbInterface> usbInterface(config_->GetInterface(i));
+ for (size_t j = 0, numDescriptors = usbInterface->GetNumAltSettings();
+ i < numDescriptors; ++i) {
+ scoped_refptr<const UsbInterfaceDescriptor> descriptor
+ = usbInterface->GetAltSetting(j);
+ std::vector<linked_ptr<EndpointDescriptor> > endpoints;
+ for (size_t k = 0, numEndpoints = descriptor->GetNumEndpoints();
+ k < numEndpoints; 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);
+ }
+
+ result_->Append(PopulateInterfaceDescriptor(
+ descriptor->GetInterfaceNumber(),
+ descriptor->GetAlternateSetting(),
+ descriptor->GetInterfaceClass(),
+ descriptor->GetInterfaceSubclass(),
+ descriptor->GetInterfaceProtocol(),
+ &endpoints));
+ }
+ }
+
+ SetResult(result_.release());
+ AsyncWorkCompleted();
+}
+
+bool UsbListInterfacesFunction::ConvertDirectionSafely(
+ const UsbEndpointDirection& input,
+ extensions::api::usb::Direction* output) {
+ const bool converted = ConvertDirectionToApi(input, output);
+ if (!converted)
+ SetError(kErrorConvertDirection);
+ return converted;
+}
+
+bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely(
+ const UsbSynchronizationType& input,
+ extensions::api::usb::SynchronizationType* output) {
+ const bool converted = ConvertSynchronizationTypeToApi(input, output);
+ if (!converted)
+ SetError(kErrorConvertSynchronizationType);
+ return converted;
+}
+
+bool UsbListInterfacesFunction::ConvertTransferTypeSafely(
+ const UsbTransferType& input,
+ extensions::api::usb::TransferType* output) {
+ const bool converted = ConvertTransferTypeToApi(input, output);
+ if (!converted)
+ SetError(kErrorConvertTransferType);
+ return converted;
+}
+
+bool UsbListInterfacesFunction::ConvertUsageTypeSafely(
+ const UsbUsageType& input,
+ extensions::api::usb::UsageType* output) {
+ const bool converted = ConvertUsageTypeToApi(input, output);
+ if (!converted)
+ SetError(kErrorConvertUsageType);
+ return converted;
+}
+
UsbCloseDeviceFunction::UsbCloseDeviceFunction() {}
UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {}
@@ -493,7 +721,7 @@ void UsbControlTransferFunction::AsyncWorkStart() {
const ControlTransferInfo& transfer = parameters_->transfer_info;
- UsbDevice::TransferDirection direction;
+ UsbEndpointDirection direction;
UsbDevice::TransferRequestType request_type;
UsbDevice::TransferRecipient recipient;
size_t size = 0;
@@ -542,7 +770,7 @@ void UsbBulkTransferFunction::AsyncWorkStart() {
const GenericTransferInfo& transfer = parameters_->transfer_info;
- UsbDevice::TransferDirection direction;
+ UsbEndpointDirection direction;
size_t size = 0;
if (!ConvertDirectionSafely(transfer.direction, &direction)) {
@@ -586,7 +814,7 @@ void UsbInterruptTransferFunction::AsyncWorkStart() {
const GenericTransferInfo& transfer = parameters_->transfer_info;
- UsbDevice::TransferDirection direction;
+ UsbEndpointDirection direction;
size_t size = 0;
if (!ConvertDirectionSafely(transfer.direction, &direction)) {
@@ -632,7 +860,7 @@ void UsbIsochronousTransferFunction::AsyncWorkStart() {
const GenericTransferInfo& generic_transfer = transfer.transfer_info;
size_t size = 0;
- UsbDevice::TransferDirection direction;
+ UsbEndpointDirection direction;
if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) {
AsyncWorkCompleted();

Powered by Google App Engine
This is Rietveld 408576698