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

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: Rebase of PS10 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
« no previous file with comments | « chrome/browser/extensions/api/usb/usb_api.h ('k') | chrome/browser/extensions/api/usb/usb_apitest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 ce991e8a26cf243fdbc0d087c9b39edc4d1f9639..a1da7ba987c7b79fe92311995c715764442fb8b8 100644
--- a/chrome/browser/extensions/api/usb/usb_api.cc
+++ b/chrome/browser/extensions/api/usb/usb_api.cc
@@ -19,6 +19,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;
@@ -35,10 +36,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 {
@@ -53,6 +59,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 =
@@ -60,6 +67,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 =
@@ -79,20 +90,96 @@ 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:
+ 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:
+ 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:
+ 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:
+ NOTREACHED();
+ return false;
+ }
+}
+
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:
+ NOTREACHED();
return false;
}
- NOTREACHED();
- return false;
}
static bool ConvertRequestType(const RequestType& input,
@@ -111,10 +198,9 @@ static bool ConvertRequestType(const RequestType& input,
*output = UsbDevice::RESERVED;
return true;
default:
+ NOTREACHED();
return false;
}
- NOTREACHED();
- return false;
}
static bool ConvertRecipient(const Recipient& input,
@@ -133,10 +219,9 @@ static bool ConvertRecipient(const Recipient& input,
*output = UsbDevice::OTHER;
return true;
default:
+ NOTREACHED();
return false;
}
- NOTREACHED();
- return false;
}
template<class T>
@@ -159,7 +244,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;
@@ -170,9 +255,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;
@@ -201,10 +286,10 @@ static const char* ConvertTransferStatusToErrorString(
return kErrorOverflow;
case USB_TRANSFER_LENGTH_SHORT:
return kErrorTransferLength;
+ default:
+ NOTREACHED();
+ return "";
}
-
- NOTREACHED();
- return "";
}
static base::DictionaryValue* CreateTransferInfo(
@@ -226,6 +311,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 {
@@ -275,7 +374,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);
@@ -365,6 +464,131 @@ 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 resource = GetUsbDeviceResource(
+ parameters_->device.handle);
+ if (!resource) {
+ CompleteWithError(kErrorNoDevice);
+ return;
+ }
+
+ config_ = new UsbConfigDescriptor();
+ resource->device()->ListInterfaces(config_, base::Bind(
+ &UsbListInterfacesFunction::OnCompleted, this));
+}
+
+void UsbListInterfacesFunction::OnCompleted(bool success) {
+ if (!success) {
+ SetError(kErrorCannotListInterfaces);
+ AsyncWorkCompleted();
+ return;
+ }
+
+ result_.reset(new base::ListValue());
+
+ 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();
+ j < numDescriptors; ++j) {
+ 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() {}
@@ -500,7 +724,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;
@@ -549,7 +773,7 @@ void UsbBulkTransferFunction::AsyncWorkStart() {
const GenericTransferInfo& transfer = parameters_->transfer_info;
- UsbDevice::TransferDirection direction;
+ UsbEndpointDirection direction;
size_t size = 0;
if (!ConvertDirectionSafely(transfer.direction, &direction)) {
@@ -593,7 +817,7 @@ void UsbInterruptTransferFunction::AsyncWorkStart() {
const GenericTransferInfo& transfer = parameters_->transfer_info;
- UsbDevice::TransferDirection direction;
+ UsbEndpointDirection direction;
size_t size = 0;
if (!ConvertDirectionSafely(transfer.direction, &direction)) {
@@ -639,7 +863,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();
« no previous file with comments | « chrome/browser/extensions/api/usb/usb_api.h ('k') | chrome/browser/extensions/api/usb/usb_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698