summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreillyg <reillyg@chromium.org>2014-09-13 22:19:25 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-13 22:19:26 -0700
commit2532566fa1fd111bf006a5d2943cd19b599d023e (patch)
tree5a15e915aab7a246f041d4ba499bf51f937de4c9
parent3fbb31c269107128c4d2e3b20311a3978a6c0059 (diff)
downloadchromium_src-2532566fa1fd111bf006a5d2943cd19b599d023e.zip
chromium_src-2532566fa1fd111bf006a5d2943cd19b599d023e.tar.gz
chromium_src-2532566fa1fd111bf006a5d2943cd19b599d023e.tar.bz2
Add chrome.usb.getConfiguration and expose extra descriptors.
Adds a new API function, chrome.usb.getConfiguration, that returns all the data from the device's configuration descriptor instead of just the interfaces as chrome.usb.listInterfaces does. Each level of the descriptor hierarchy also gets an "extra_data" field which contains all of the miscellaneous descriptors assocated with a configuration, interface or endpoint. BUG=382908 Review URL: https://codereview.chromium.org/558373002
-rw-r--r--extensions/browser/api/usb/usb_api.cc354
-rw-r--r--extensions/browser/api/usb/usb_api.h27
-rw-r--r--extensions/browser/extension_function_histogram_value.h1
-rw-r--r--extensions/common/api/usb.idl28
-rw-r--r--tools/metrics/histograms/histograms.xml1
5 files changed, 209 insertions, 202 deletions
diff --git a/extensions/browser/api/usb/usb_api.cc b/extensions/browser/api/usb/usb_api.cc
index 22e19c4..2c2b490 100644
--- a/extensions/browser/api/usb/usb_api.cc
+++ b/extensions/browser/api/usb/usb_api.cc
@@ -27,6 +27,7 @@ namespace FindDevices = usb::FindDevices;
namespace GetDevices = usb::GetDevices;
namespace InterruptTransfer = usb::InterruptTransfer;
namespace IsochronousTransfer = usb::IsochronousTransfer;
+namespace GetConfiguration = usb::GetConfiguration;
namespace ListInterfaces = usb::ListInterfaces;
namespace OpenDevice = usb::OpenDevice;
namespace ReleaseInterface = usb::ReleaseInterface;
@@ -35,8 +36,7 @@ namespace ResetDevice = usb::ResetDevice;
namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting;
using content::BrowserThread;
-using std::string;
-using std::vector;
+using usb::ConfigDescriptor;
using usb::ControlTransferInfo;
using usb::ConnectionHandle;
using usb::Device;
@@ -84,8 +84,6 @@ const char kErrorOverflow[] = "Inbound transfer overflow.";
const char kErrorStalled[] = "Transfer stalled.";
const char kErrorTimeout[] = "Transfer timed out.";
const char kErrorTransferLength[] = "Transfer length is insufficient.";
-
-const char kErrorCannotListInterfaces[] = "Error listing interfaces.";
const char kErrorCannotClaimInterface[] = "Error claiming interface.";
const char kErrorCannotReleaseInterface[] = "Error releasing interface.";
const char kErrorCannotSetInterfaceAlternateSetting[] =
@@ -93,9 +91,6 @@ const char kErrorCannotSetInterfaceAlternateSetting[] =
const char kErrorConvertDirection[] = "Invalid transfer direction.";
const char kErrorConvertRecipient[] = "Invalid transfer recipient.";
const char kErrorConvertRequestType[] = "Invalid request type.";
-const char kErrorConvertSynchronizationType[] = "Invalid synchronization type";
-const char kErrorConvertTransferType[] = "Invalid endpoint type.";
-const char kErrorConvertUsageType[] = "Invalid usage type.";
const char kErrorMalformedParameters[] = "Error parsing parameters.";
const char kErrorNoDevice[] = "No such device.";
const char kErrorPermissionDenied[] = "Permission to access device was denied";
@@ -112,81 +107,8 @@ const size_t kMaxTransferLength = 100 * 1024 * 1024;
const int kMaxPackets = 4 * 1024 * 1024;
const int kMaxPacketLength = 64 * 1024;
-bool ConvertDirectionToApi(const UsbEndpointDirection& input,
- Direction* output) {
- switch (input) {
- case device::USB_DIRECTION_INBOUND:
- *output = usb::DIRECTION_IN;
- return true;
- case device::USB_DIRECTION_OUTBOUND:
- *output = usb::DIRECTION_OUT;
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-bool ConvertSynchronizationTypeToApi(const UsbSynchronizationType& input,
- usb::SynchronizationType* output) {
- switch (input) {
- case device::USB_SYNCHRONIZATION_NONE:
- *output = usb::SYNCHRONIZATION_TYPE_NONE;
- return true;
- case device::USB_SYNCHRONIZATION_ASYNCHRONOUS:
- *output = usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS;
- return true;
- case device::USB_SYNCHRONIZATION_ADAPTIVE:
- *output = usb::SYNCHRONIZATION_TYPE_ADAPTIVE;
- return true;
- case device::USB_SYNCHRONIZATION_SYNCHRONOUS:
- *output = usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS;
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-bool ConvertTransferTypeToApi(const UsbTransferType& input,
- usb::TransferType* output) {
- switch (input) {
- case device::USB_TRANSFER_CONTROL:
- *output = usb::TRANSFER_TYPE_CONTROL;
- return true;
- case device::USB_TRANSFER_INTERRUPT:
- *output = usb::TRANSFER_TYPE_INTERRUPT;
- return true;
- case device::USB_TRANSFER_ISOCHRONOUS:
- *output = usb::TRANSFER_TYPE_ISOCHRONOUS;
- return true;
- case device::USB_TRANSFER_BULK:
- *output = usb::TRANSFER_TYPE_BULK;
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-bool ConvertUsageTypeToApi(const UsbUsageType& input, usb::UsageType* output) {
- switch (input) {
- case device::USB_USAGE_DATA:
- *output = usb::USAGE_TYPE_DATA;
- return true;
- case device::USB_USAGE_FEEDBACK:
- *output = usb::USAGE_TYPE_FEEDBACK;
- return true;
- case device::USB_USAGE_EXPLICIT_FEEDBACK:
- *output = usb::USAGE_TYPE_EXPLICITFEEDBACK;
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-bool ConvertDirection(const Direction& input, UsbEndpointDirection* output) {
+bool ConvertDirectionFromApi(const Direction& input,
+ UsbEndpointDirection* output) {
switch (input) {
case usb::DIRECTION_IN:
*output = device::USB_DIRECTION_INBOUND;
@@ -200,8 +122,8 @@ bool ConvertDirection(const Direction& input, UsbEndpointDirection* output) {
}
}
-bool ConvertRequestType(const RequestType& input,
- UsbDeviceHandle::TransferRequestType* output) {
+bool ConvertRequestTypeFromApi(const RequestType& input,
+ UsbDeviceHandle::TransferRequestType* output) {
switch (input) {
case usb::REQUEST_TYPE_STANDARD:
*output = UsbDeviceHandle::STANDARD;
@@ -221,8 +143,8 @@ bool ConvertRequestType(const RequestType& input,
}
}
-bool ConvertRecipient(const Recipient& input,
- UsbDeviceHandle::TransferRecipient* output) {
+bool ConvertRecipientFromApi(const Recipient& input,
+ UsbDeviceHandle::TransferRecipient* output) {
switch (input) {
case usb::RECIPIENT_DEVICE:
*output = UsbDeviceHandle::DEVICE;
@@ -286,7 +208,7 @@ scoped_refptr<net::IOBuffer> CreateBufferForTransfer(
return NULL;
}
-const char* ConvertTransferStatusToErrorString(const UsbTransferStatus status) {
+const char* ConvertTransferStatusToApi(const UsbTransferStatus status) {
switch (status) {
case device::USB_TRANSFER_COMPLETED:
return "";
@@ -380,21 +302,121 @@ base::Value* PopulateDevice(UsbDevice* device) {
return result.ToValue().release();
}
-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_protocol;
- descriptor.endpoints = *endpoints;
- return descriptor.ToValue().release();
+TransferType ConvertTransferTypeToApi(const UsbTransferType& input) {
+ switch (input) {
+ case device::USB_TRANSFER_CONTROL:
+ return usb::TRANSFER_TYPE_CONTROL;
+ case device::USB_TRANSFER_INTERRUPT:
+ return usb::TRANSFER_TYPE_INTERRUPT;
+ case device::USB_TRANSFER_ISOCHRONOUS:
+ return usb::TRANSFER_TYPE_ISOCHRONOUS;
+ case device::USB_TRANSFER_BULK:
+ return usb::TRANSFER_TYPE_BULK;
+ default:
+ NOTREACHED();
+ return usb::TRANSFER_TYPE_NONE;
+ }
+}
+
+Direction ConvertDirectionToApi(const UsbEndpointDirection& input) {
+ switch (input) {
+ case device::USB_DIRECTION_INBOUND:
+ return usb::DIRECTION_IN;
+ case device::USB_DIRECTION_OUTBOUND:
+ return usb::DIRECTION_OUT;
+ default:
+ NOTREACHED();
+ return usb::DIRECTION_NONE;
+ }
+}
+
+SynchronizationType ConvertSynchronizationTypeToApi(
+ const UsbSynchronizationType& input) {
+ switch (input) {
+ case device::USB_SYNCHRONIZATION_NONE:
+ return usb::SYNCHRONIZATION_TYPE_NONE;
+ case device::USB_SYNCHRONIZATION_ASYNCHRONOUS:
+ return usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS;
+ case device::USB_SYNCHRONIZATION_ADAPTIVE:
+ return usb::SYNCHRONIZATION_TYPE_ADAPTIVE;
+ case device::USB_SYNCHRONIZATION_SYNCHRONOUS:
+ return usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS;
+ default:
+ NOTREACHED();
+ return usb::SYNCHRONIZATION_TYPE_NONE;
+ }
+}
+
+UsageType ConvertUsageTypeToApi(const UsbUsageType& input) {
+ switch (input) {
+ case device::USB_USAGE_DATA:
+ return usb::USAGE_TYPE_DATA;
+ case device::USB_USAGE_FEEDBACK:
+ return usb::USAGE_TYPE_FEEDBACK;
+ case device::USB_USAGE_EXPLICIT_FEEDBACK:
+ return usb::USAGE_TYPE_EXPLICITFEEDBACK;
+ default:
+ NOTREACHED();
+ return usb::USAGE_TYPE_NONE;
+ }
+}
+
+void ConvertEndpointDescriptor(const UsbEndpointDescriptor& input,
+ EndpointDescriptor* output) {
+ output->address = input.address;
+ output->type = ConvertTransferTypeToApi(input.transfer_type);
+ output->direction = ConvertDirectionToApi(input.direction);
+ output->maximum_packet_size = input.maximum_packet_size;
+ output->synchronization =
+ ConvertSynchronizationTypeToApi(input.synchronization_type);
+ output->usage = ConvertUsageTypeToApi(input.usage_type);
+ output->polling_interval.reset(new int(input.polling_interval));
+ if (input.extra_data.size() > 0) {
+ output->extra_data =
+ std::string(reinterpret_cast<const char*>(&input.extra_data[0]),
+ input.extra_data.size());
+ }
+}
+
+void ConvertInterfaceDescriptor(const UsbInterfaceDescriptor& input,
+ InterfaceDescriptor* output) {
+ output->interface_number = input.interface_number;
+ output->alternate_setting = input.alternate_setting;
+ output->interface_class = input.interface_class;
+ output->interface_subclass = input.interface_subclass;
+ output->interface_protocol = input.interface_protocol;
+ for (UsbEndpointDescriptor::Iterator endpointIt = input.endpoints.begin();
+ endpointIt != input.endpoints.end();
+ ++endpointIt) {
+ linked_ptr<EndpointDescriptor> endpoint(new EndpointDescriptor);
+ ConvertEndpointDescriptor(*endpointIt, endpoint.get());
+ output->endpoints.push_back(endpoint);
+ }
+ if (input.extra_data.size() > 0) {
+ output->extra_data =
+ std::string(reinterpret_cast<const char*>(&input.extra_data[0]),
+ input.extra_data.size());
+ }
+}
+
+void ConvertConfigDescriptor(const UsbConfigDescriptor& input,
+ ConfigDescriptor* output) {
+ output->configuration_value = input.configuration_value;
+ output->self_powered = input.self_powered;
+ output->remote_wakeup = input.remote_wakeup;
+ output->max_power = input.maximum_power;
+ for (UsbInterfaceDescriptor::Iterator interfaceIt = input.interfaces.begin();
+ interfaceIt != input.interfaces.end();
+ ++interfaceIt) {
+ linked_ptr<InterfaceDescriptor> interface(new InterfaceDescriptor);
+ ConvertInterfaceDescriptor(*interfaceIt, interface.get());
+ output->interfaces.push_back(interface);
+ }
+ if (input.extra_data.size() > 0) {
+ output->extra_data =
+ std::string(reinterpret_cast<const char*>(&input.extra_data[0]),
+ input.extra_data.size());
+ }
}
} // namespace
@@ -516,7 +538,7 @@ void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status,
scoped_refptr<net::IOBuffer> data,
size_t length) {
if (status != device::USB_TRANSFER_COMPLETED)
- SetError(ConvertTransferStatusToErrorString(status));
+ SetError(ConvertTransferStatusToApi(status));
SetResult(CreateTransferInfo(status, data, length));
AsyncWorkCompleted();
@@ -525,7 +547,7 @@ void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status,
bool UsbAsyncApiTransferFunction::ConvertDirectionSafely(
const Direction& input,
UsbEndpointDirection* output) {
- const bool converted = ConvertDirection(input, output);
+ const bool converted = ConvertDirectionFromApi(input, output);
if (!converted)
SetError(kErrorConvertDirection);
return converted;
@@ -534,7 +556,7 @@ bool UsbAsyncApiTransferFunction::ConvertDirectionSafely(
bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely(
const RequestType& input,
UsbDeviceHandle::TransferRequestType* output) {
- const bool converted = ConvertRequestType(input, output);
+ const bool converted = ConvertRequestTypeFromApi(input, output);
if (!converted)
SetError(kErrorConvertRequestType);
return converted;
@@ -543,7 +565,7 @@ bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely(
bool UsbAsyncApiTransferFunction::ConvertRecipientSafely(
const Recipient& input,
UsbDeviceHandle::TransferRecipient* output) {
- const bool converted = ConvertRecipient(input, output);
+ const bool converted = ConvertRecipientFromApi(input, output);
if (!converted)
SetError(kErrorConvertRecipient);
return converted;
@@ -742,113 +764,63 @@ void UsbOpenDeviceFunction::AsyncWorkStart() {
AsyncWorkCompleted();
}
-UsbListInterfacesFunction::UsbListInterfacesFunction() {
+UsbGetConfigurationFunction::UsbGetConfigurationFunction() {
}
-UsbListInterfacesFunction::~UsbListInterfacesFunction() {
+UsbGetConfigurationFunction::~UsbGetConfigurationFunction() {
}
-bool UsbListInterfacesFunction::Prepare() {
- parameters_ = ListInterfaces::Params::Create(*args_);
+bool UsbGetConfigurationFunction::Prepare() {
+ parameters_ = GetConfiguration::Params::Create(*args_);
EXTENSION_FUNCTION_VALIDATE(parameters_.get());
return true;
}
-void UsbListInterfacesFunction::AsyncWorkStart() {
+void UsbGetConfigurationFunction::AsyncWorkStart() {
scoped_refptr<UsbDeviceHandle> device_handle =
GetDeviceHandleOrCompleteWithError(parameters_->handle);
- if (!device_handle.get())
+ if (!device_handle.get()) {
return;
-
- const UsbConfigDescriptor& config =
- device_handle->GetDevice()->GetConfiguration();
-
- scoped_ptr<base::ListValue> result(new base::ListValue());
-
- 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;
- }
-
- 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());
+ ConfigDescriptor config;
+ ConvertConfigDescriptor(device_handle->GetDevice()->GetConfiguration(),
+ &config);
+
+ SetResult(config.ToValue().release());
AsyncWorkCompleted();
}
-bool UsbListInterfacesFunction::ConvertDirectionSafely(
- const UsbEndpointDirection& input,
- usb::Direction* output) {
- const bool converted = ConvertDirectionToApi(input, output);
- if (!converted)
- SetError(kErrorConvertDirection);
- return converted;
+UsbListInterfacesFunction::UsbListInterfacesFunction() {
}
-bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely(
- const UsbSynchronizationType& input,
- usb::SynchronizationType* output) {
- const bool converted = ConvertSynchronizationTypeToApi(input, output);
- if (!converted)
- SetError(kErrorConvertSynchronizationType);
- return converted;
+UsbListInterfacesFunction::~UsbListInterfacesFunction() {
}
-bool UsbListInterfacesFunction::ConvertTransferTypeSafely(
- const UsbTransferType& input,
- usb::TransferType* output) {
- const bool converted = ConvertTransferTypeToApi(input, output);
- if (!converted)
- SetError(kErrorConvertTransferType);
- return converted;
+bool UsbListInterfacesFunction::Prepare() {
+ parameters_ = ListInterfaces::Params::Create(*args_);
+ EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+ return true;
}
-bool UsbListInterfacesFunction::ConvertUsageTypeSafely(
- const UsbUsageType& input,
- usb::UsageType* output) {
- const bool converted = ConvertUsageTypeToApi(input, output);
- if (!converted)
- SetError(kErrorConvertUsageType);
- return converted;
+void UsbListInterfacesFunction::AsyncWorkStart() {
+ scoped_refptr<UsbDeviceHandle> device_handle =
+ GetDeviceHandleOrCompleteWithError(parameters_->handle);
+ if (!device_handle.get()) {
+ return;
+ }
+
+ ConfigDescriptor config;
+ ConvertConfigDescriptor(device_handle->GetDevice()->GetConfiguration(),
+ &config);
+
+ scoped_ptr<base::ListValue> result(new base::ListValue);
+ for (size_t i = 0; i < config.interfaces.size(); ++i) {
+ result->Append(config.interfaces[i]->ToValue().release());
+ }
+
+ SetResult(result.release());
+ AsyncWorkCompleted();
}
UsbCloseDeviceFunction::UsbCloseDeviceFunction() {
diff --git a/extensions/browser/api/usb/usb_api.h b/extensions/browser/api/usb/usb_api.h
index 2a0a6ef..8bd673f 100644
--- a/extensions/browser/api/usb/usb_api.h
+++ b/extensions/browser/api/usb/usb_api.h
@@ -144,6 +144,22 @@ class UsbOpenDeviceFunction : public UsbAsyncApiFunction {
scoped_ptr<extensions::core_api::usb::OpenDevice::Params> parameters_;
};
+class UsbGetConfigurationFunction : public UsbAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("usb.getConfiguration", USB_GETCONFIGURATION)
+
+ UsbGetConfigurationFunction();
+
+ protected:
+ virtual ~UsbGetConfigurationFunction();
+
+ virtual bool Prepare() OVERRIDE;
+ virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+ scoped_ptr<extensions::core_api::usb::GetConfiguration::Params> parameters_;
+};
+
class UsbListInterfacesFunction : public UsbAsyncApiFunction {
public:
DECLARE_EXTENSION_FUNCTION("usb.listInterfaces", USB_LISTINTERFACES)
@@ -157,17 +173,6 @@ class UsbListInterfacesFunction : public UsbAsyncApiFunction {
virtual void AsyncWorkStart() OVERRIDE;
private:
- bool ConvertDirectionSafely(const device::UsbEndpointDirection& input,
- extensions::core_api::usb::Direction* output);
- bool ConvertSynchronizationTypeSafely(
- const device::UsbSynchronizationType& input,
- extensions::core_api::usb::SynchronizationType* output);
- bool ConvertTransferTypeSafely(
- const device::UsbTransferType& input,
- extensions::core_api::usb::TransferType* output);
- bool ConvertUsageTypeSafely(const device::UsbUsageType& input,
- extensions::core_api::usb::UsageType* output);
-
scoped_ptr<extensions::core_api::usb::ListInterfaces::Params> parameters_;
};
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 61db879..fc1ba2b7 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -952,6 +952,7 @@ enum HistogramValue {
EASYUNLOCKPRIVATE_GETSIGNINCHALLENGE,
EASYUNLOCKPRIVATE_TRYSIGNINSECRET,
ACCESSIBILITY_PRIVATE_SETFOCUSRING,
+ USB_GETCONFIGURATION,
// Last entry: Add new entries above and ensure to update
// tools/metrics/histograms/histograms.xml.
ENUM_BOUNDARY
diff --git a/extensions/common/api/usb.idl b/extensions/common/api/usb.idl
index 18dd1f3..af6d550 100644
--- a/extensions/common/api/usb.idl
+++ b/extensions/common/api/usb.idl
@@ -60,6 +60,8 @@ namespace usb {
UsageType? usage;
// Polling interval (interrupt and isochronous only).
long? pollingInterval;
+ // Extra descriptor data associated with this endpoint.
+ ArrayBuffer extra_data;
};
[noinline_doc] dictionary InterfaceDescriptor {
@@ -77,6 +79,25 @@ namespace usb {
DOMString? description;
// Available endpoints.
EndpointDescriptor[] endpoints;
+ // Extra descriptor data associated with this interface.
+ ArrayBuffer extra_data;
+ };
+
+ [noinline_doc] dictionary ConfigDescriptor {
+ // The configuration number.
+ long configurationValue;
+ // Description of the configuration.
+ DOMString? description;
+ // The device is self-powered.
+ boolean selfPowered;
+ // The device supports remote wakeup.
+ boolean remoteWakeup;
+ // The maximum power needed by this device in milliamps (mA).
+ long maxPower;
+ // Available interfaces.
+ InterfaceDescriptor[] interfaces;
+ // Extra descriptor data associated with this configuration.
+ ArrayBuffer extra_data;
};
dictionary ControlTransferInfo {
@@ -181,6 +202,7 @@ namespace usb {
callback RequestAccessCallback = void (boolean success);
callback OpenDeviceCallback = void (ConnectionHandle handle);
callback FindDevicesCallback = void (ConnectionHandle[] handles);
+ callback GetConfigurationCallback = void (ConfigDescriptor config);
callback ListInterfacesCallback = void (InterfaceDescriptor[] descriptors);
callback CloseDeviceCallback = void ();
callback TransferCallback = void (TransferResultInfo info);
@@ -232,6 +254,12 @@ namespace usb {
static void closeDevice(ConnectionHandle handle,
optional CloseDeviceCallback callback);
+ // Gets the configuration descriptor for the currently selected
+ // configuration.
+ // |handle|: An open connection to the device.
+ static void getConfiguration(ConnectionHandle handle,
+ GetConfigurationCallback callback);
+
// Lists all interfaces on a USB device.
// |handle|: An open connection to the device.
static void listInterfaces(ConnectionHandle handle,
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 759fb73..fea147b 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -41549,6 +41549,7 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="891" label="EASYUNLOCKPRIVATE_GETSIGNINCHALLENGE"/>
<int value="892" label="EASYUNLOCKPRIVATE_TRYSIGNINSECRET"/>
<int value="893" label="ACCESSIBILITY_PRIVATE_SETFOCUSRING"/>
+ <int value="894" label="USB_GETCONFIGURATION"/>
</enum>
<enum name="ExtensionInstallCause" type="int">