| Index: Source/modules/webusb/USBDevice.cpp
|
| diff --git a/Source/modules/webusb/USBDevice.cpp b/Source/modules/webusb/USBDevice.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..11d9e1833b060a7a45ec4dccb3b9ade16f23cfb4
|
| --- /dev/null
|
| +++ b/Source/modules/webusb/USBDevice.cpp
|
| @@ -0,0 +1,271 @@
|
| +// Copyright 2015 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 "config.h"
|
| +#include "modules/webusb/USBDevice.h"
|
| +
|
| +#include "bindings/core/v8/CallbackPromiseAdapter.h"
|
| +#include "bindings/core/v8/ScriptPromise.h"
|
| +#include "bindings/core/v8/ScriptPromiseResolver.h"
|
| +#include "bindings/core/v8/ToV8.h"
|
| +#include "core/dom/DOMArrayBuffer.h"
|
| +#include "core/dom/DOMArrayBufferView.h"
|
| +#include "core/dom/DOMException.h"
|
| +#include "core/dom/ExceptionCode.h"
|
| +#include "modules/webusb/USBControlTransferParameters.h"
|
| +#include "modules/webusb/USBError.h"
|
| +#include "modules/webusb/USBInTransferResult.h"
|
| +#include "modules/webusb/USBOutTransferResult.h"
|
| +#include "public/platform/modules/webusb/WebUSBTransferInfo.h"
|
| +
|
| +namespace blink {
|
| +
|
| +namespace {
|
| +
|
| +DOMException* convertControlTransferParameters(
|
| + WebUSBDevice::TransferDirection direction,
|
| + const USBControlTransferParameters& parameters,
|
| + WebUSBDevice::ControlTransferParameters* webParameters)
|
| +{
|
| + webParameters->direction = direction;
|
| +
|
| + if (parameters.requestType() == "standard")
|
| + webParameters->type = WebUSBDevice::RequestTypeStandard;
|
| + else if (parameters.requestType() == "class")
|
| + webParameters->type = WebUSBDevice::RequestTypeClass;
|
| + else if (parameters.requestType() == "vendor")
|
| + webParameters->type = WebUSBDevice::RequestTypeVendor;
|
| + else
|
| + return DOMException::create(AbortError, "The control transfer requestType parameter is invalid.");
|
| +
|
| + if (parameters.recipient() == "device")
|
| + webParameters->recipient = WebUSBDevice::RequestRecipientDevice;
|
| + else if (parameters.recipient() == "interface")
|
| + webParameters->recipient = WebUSBDevice::RequestRecipientInterface;
|
| + else if (parameters.recipient() == "endpoint")
|
| + webParameters->recipient = WebUSBDevice::RequestRecipientEndpoint;
|
| + else if (parameters.recipient() == "other")
|
| + webParameters->recipient = WebUSBDevice::RequestRecipientOther;
|
| + else
|
| + return DOMException::create(AbortError, "The control transfer recipient parameter is invalid.");
|
| +
|
| + webParameters->request = parameters.request();
|
| + webParameters->value = parameters.value();
|
| + webParameters->index = parameters.index();
|
| + return nullptr;
|
| +}
|
| +
|
| +String convertTransferStatus(const WebUSBTransferInfo::Status& status)
|
| +{
|
| + switch (status) {
|
| + case WebUSBTransferInfo::StatusOk:
|
| + return "ok";
|
| + case WebUSBTransferInfo::StatusStall:
|
| + return "stall";
|
| + case WebUSBTransferInfo::StatusBabble:
|
| + return "babble";
|
| + default:
|
| + ASSERT_NOT_REACHED();
|
| + return "";
|
| + }
|
| +}
|
| +
|
| +class InputTransferResult {
|
| + WTF_MAKE_NONCOPYABLE(InputTransferResult);
|
| +public:
|
| + using WebType = WebUSBTransferInfo;
|
| +
|
| + static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebType> webTransferInfo)
|
| + {
|
| + return USBInTransferResult::create(
|
| + convertTransferStatus(webTransferInfo->status),
|
| + DOMArrayBuffer::create(webTransferInfo->data.data(), webTransferInfo->data.size()));
|
| + }
|
| +
|
| +private:
|
| + InputTransferResult() = delete;
|
| +};
|
| +
|
| +class OutputTransferResult {
|
| + WTF_MAKE_NONCOPYABLE(OutputTransferResult);
|
| +public:
|
| + using WebType = WebUSBTransferInfo;
|
| +
|
| + static USBOutTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebType> webTransferInfo)
|
| + {
|
| + return USBOutTransferResult::create(convertTransferStatus(webTransferInfo->status), webTransferInfo->bytesWritten);
|
| + }
|
| +
|
| +private:
|
| + OutputTransferResult() = delete;
|
| +};
|
| +
|
| +class BufferSource {
|
| + WTF_MAKE_NONCOPYABLE(BufferSource);
|
| +public:
|
| + BufferSource(const ArrayBufferOrArrayBufferView& buffer) : m_buffer(buffer) { }
|
| +
|
| + uint8_t* data() const
|
| + {
|
| + if (m_buffer.isArrayBuffer())
|
| + return static_cast<uint8_t*>(m_buffer.getAsArrayBuffer()->data());
|
| + return static_cast<uint8_t*>(m_buffer.getAsArrayBufferView()->baseAddress());
|
| + }
|
| +
|
| + unsigned size() const
|
| + {
|
| + if (m_buffer.isArrayBuffer())
|
| + return m_buffer.getAsArrayBuffer()->byteLength();
|
| + return m_buffer.getAsArrayBufferView()->byteLength();
|
| + }
|
| +
|
| +private:
|
| + const ArrayBufferOrArrayBufferView& m_buffer;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +USBDevice* USBDevice::create(PassOwnPtr<WebUSBDevice> device)
|
| +{
|
| + return new USBDevice(device);
|
| +}
|
| +
|
| +USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device)
|
| + : m_device(device)
|
| +{
|
| +}
|
| +
|
| +HeapVector<Member<USBConfiguration>> USBDevice::configurations() const
|
| +{
|
| + HeapVector<Member<USBConfiguration>> configurations;
|
| + for (size_t i = 0; i < info().configurations.size(); ++i)
|
| + configurations.append(USBConfiguration::create(this, i));
|
| + return configurations;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::open(ScriptState* scriptState)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + m_device->open(new CallbackPromiseAdapter<void, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::close(ScriptState* scriptState)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + m_device->close(new CallbackPromiseAdapter<void, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::setConfiguration(ScriptState* scriptState, uint8_t configurationValue)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + m_device->setConfiguration(configurationValue, new CallbackPromiseAdapter<void, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interfaceNumber)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + m_device->claimInterface(interfaceNumber, new CallbackPromiseAdapter<void, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t interfaceNumber)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + m_device->releaseInterface(interfaceNumber, new CallbackPromiseAdapter<void, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::setInterface(ScriptState* scriptState, uint8_t interfaceNumber, uint8_t alternateSetting)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + m_device->setInterface(interfaceNumber, alternateSetting, new CallbackPromiseAdapter<void, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBControlTransferParameters& parameters, uint16_t length)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + WebUSBDevice::ControlTransferParameters webParameters;
|
| + DOMException* error = convertControlTransferParameters(WebUSBDevice::TransferDirectionIn, parameters, &webParameters);
|
| + if (error)
|
| + resolver->reject(error);
|
| + else
|
| + m_device->controlTransfer(webParameters, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBControlTransferParameters& parameters)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + WebUSBDevice::ControlTransferParameters webParameters;
|
| + DOMException* error = convertControlTransferParameters(WebUSBDevice::TransferDirectionOut, parameters, &webParameters);
|
| + if (error)
|
| + resolver->reject(error);
|
| + else
|
| + m_device->controlTransfer(webParameters, nullptr, 0, 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +
|
| +ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBControlTransferParameters& parameters, const ArrayBufferOrArrayBufferView& data)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + WebUSBDevice::ControlTransferParameters webParameters;
|
| + DOMException* error = convertControlTransferParameters(WebUSBDevice::TransferDirectionOut, parameters, &webParameters);
|
| + if (error) {
|
| + resolver->reject(error);
|
| + } else {
|
| + BufferSource buffer(data);
|
| + m_device->controlTransfer(webParameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
|
| + }
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, uint8_t endpointNumber)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNumber, unsigned length)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + m_device->transfer(WebUSBDevice::TransferDirectionIn, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointNumber, const ArrayBufferOrArrayBufferView& data)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + BufferSource buffer(data);
|
| + m_device->transfer(WebUSBDevice::TransferDirectionOut, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise USBDevice::reset(ScriptState* scriptState)
|
| +{
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + m_device->reset(new CallbackPromiseAdapter<void, USBError>(resolver));
|
| + return promise;
|
| +}
|
| +
|
| +} // namespace blink
|
|
|