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

Unified Diff: third_party/WebKit/Source/modules/webusb/USBDevice.cpp

Issue 1850023002: Consume Mojo services directly in Blink's WebUSB implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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: third_party/WebKit/Source/modules/webusb/USBDevice.cpp
diff --git a/third_party/WebKit/Source/modules/webusb/USBDevice.cpp b/third_party/WebKit/Source/modules/webusb/USBDevice.cpp
index b57aa4dd666c2cc1bca35998247a9483c6bcbbdf..dc4472a4b892c7fcad28270311eb98ae187fc584 100644
--- a/third_party/WebKit/Source/modules/webusb/USBDevice.cpp
+++ b/third_party/WebKit/Source/modules/webusb/USBDevice.cpp
@@ -4,7 +4,6 @@
#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"
@@ -15,12 +14,10 @@
#include "core/dom/ExceptionCode.h"
#include "modules/webusb/USBConfiguration.h"
#include "modules/webusb/USBControlTransferParameters.h"
-#include "modules/webusb/USBError.h"
#include "modules/webusb/USBInTransferResult.h"
#include "modules/webusb/USBIsochronousInTransferResult.h"
#include "modules/webusb/USBIsochronousOutTransferResult.h"
#include "modules/webusb/USBOutTransferResult.h"
-#include "public/platform/modules/webusb/WebUSBTransferInfo.h"
#include "wtf/Assertions.h"
namespace blink {
@@ -28,21 +25,45 @@ namespace blink {
namespace {
const char kDeviceStateChangeInProgress[] = "An operation that changes the device state is in progress.";
+const char kDeviceUnavailable[] = "Device unavailable.";
const char kInterfaceNotFound[] = "The interface number provided is not supported by the device in its current configuration.";
const char kInterfaceStateChangeInProgress[] = "An operation that changes interface state is in progress.";
const char kOpenRequired[] = "The device must be opened first.";
const char kVisibiltyError[] = "Connection is only allowed while the page is visible. This is a temporary measure until we are able to effectively communicate to the user that the page is connected to a device.";
+DOMException* convertFatalTransferStatus(const device::usb::blink::TransferStatus& status)
+{
+ switch (status) {
+ case device::usb::blink::TransferStatus::TRANSFER_ERROR:
+ return DOMException::create(NetworkError, "A transfer error has occured.");
+ case device::usb::blink::TransferStatus::PERMISSION_DENIED:
+ return DOMException::create(SecurityError, "The transfer was not allowed.");
+ case device::usb::blink::TransferStatus::TIMEOUT:
+ return DOMException::create(TimeoutError, "The transfer timed out.");
+ case device::usb::blink::TransferStatus::CANCELLED:
+ return DOMException::create(AbortError, "The transfer was cancelled.");
+ case device::usb::blink::TransferStatus::DISCONNECT:
+ return DOMException::create(NotFoundError, kDeviceUnavailable);
+ case device::usb::blink::TransferStatus::COMPLETED:
+ case device::usb::blink::TransferStatus::STALLED:
+ case device::usb::blink::TransferStatus::BABBLE:
+ case device::usb::blink::TransferStatus::SHORT_PACKET:
+ return nullptr;
+ default:
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+}
-
-String convertTransferStatus(const WebUSBTransferInfo::Status& status)
+String convertTransferStatus(const device::usb::blink::TransferStatus& status)
{
switch (status) {
- case WebUSBTransferInfo::Status::Ok:
+ case device::usb::blink::TransferStatus::COMPLETED:
+ case device::usb::blink::TransferStatus::SHORT_PACKET:
return "ok";
- case WebUSBTransferInfo::Status::Stall:
+ case device::usb::blink::TransferStatus::STALLED:
return "stall";
- case WebUSBTransferInfo::Status::Babble:
+ case device::usb::blink::TransferStatus::BABBLE:
return "babble";
default:
ASSERT_NOT_REACHED();
@@ -50,257 +71,450 @@ String convertTransferStatus(const WebUSBTransferInfo::Status& status)
}
}
-class OpenClosePromiseAdapter : public WebCallbacks<void, const WebUSBError&> {
+mojo::WTFArray<uint8_t> convertBufferSource(const ArrayBufferOrArrayBufferView& buffer)
+{
+ ASSERT(!buffer.isNull());
+ Vector<uint8_t> vector;
+ if (buffer.isArrayBuffer())
+ vector.append(static_cast<uint8_t*>(buffer.getAsArrayBuffer()->data()), buffer.getAsArrayBuffer()->byteLength());
+ else
+ vector.append(static_cast<uint8_t*>(buffer.getAsArrayBufferView()->baseAddress()), buffer.getAsArrayBufferView()->byteLength());
+ return mojo::WTFArray<uint8_t>(std::move(vector));
+}
+
+template <typename Callback>
+class PromiseAdapterBase : public Callback::Runnable {
+ WTF_MAKE_NONCOPYABLE(PromiseAdapterBase);
+
public:
- OpenClosePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, bool desiredState)
- : m_device(device)
- , m_resolver(resolver)
- , m_desiredState(desiredState)
+ PromiseAdapterBase(ScriptPromiseResolver* resolver) : m_resolver(resolver)
{
}
- void onSuccess() override
+ virtual ~PromiseAdapterBase()
{
- if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
- return;
+ if (active())
+ m_resolver->reject(DOMException::create(NotFoundError, kDeviceUnavailable));
+ }
- m_device->onDeviceOpenedOrClosed(m_desiredState);
- if (m_device->page()->isPageVisible()) {
- m_resolver->resolve();
- } else {
- m_device->pageVisibilityChanged();
- m_resolver->reject(DOMException::create(SecurityError, kVisibiltyError));
- return;
- }
+ void resolve(void) const
+ {
+ ASSERT(active());
+ m_resolver->resolve();
+ m_resolver = nullptr;
}
- void onError(const WebUSBError& e) override
+ template <typename T>
+ void resolve(T value) const
{
- if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
- return;
- m_device->onDeviceOpenedOrClosed(!m_desiredState);
- m_resolver->reject(USBError::take(m_resolver, e));
+ ASSERT(active());
+ m_resolver->resolve(value);
+ m_resolver = nullptr;
+ }
+
+ template <typename T>
+ void reject(T value) const
+ {
+ ASSERT(active());
+ m_resolver->reject(value);
+ m_resolver = nullptr;
+ }
+
+ bool active() const
+ {
+ return m_resolver && m_resolver->getExecutionContext() && !m_resolver->getExecutionContext()->activeDOMObjectsAreStopped();
+ }
+
+ Callback callback()
+ {
+ return Callback(this);
+ }
+
+private:
+ // This field is mutable so that resolve() and reject() can be called from
+ // a mojo::Callback::Runnable's const Run() method.
+ mutable Persistent<ScriptPromiseResolver> m_resolver;
+};
+
+class OpenPromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::OpenCallback> {
+ WTF_MAKE_NONCOPYABLE(OpenPromiseAdapter);
+
+public:
+ OpenPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver)
+ : PromiseAdapterBase(resolver)
+ , m_device(device)
+ {
+ }
+
+ void Run(device::usb::blink::OpenDeviceError error) const override
+ {
+ if (active()) {
+ switch (error) {
+ case device::usb::blink::OpenDeviceError::ALREADY_OPEN:
+ ASSERT_NOT_REACHED();
+ // fall through
+ case device::usb::blink::OpenDeviceError::OK:
esprehn 2016/04/06 20:10:45 The verbosity of the prefix makes all this code ha
Reilly Grant (use Gerrit) 2016/04/06 22:30:07 Added "namespace usb = device::usb::blink;" to sho
+ m_device->onDeviceOpenedOrClosed(true);
+ if (m_device->page()->isPageVisible()) {
+ resolve();
+ } else {
+ m_device->pageVisibilityChanged();
+ reject(DOMException::create(SecurityError, kVisibiltyError));
+ }
+ break;
+ case device::usb::blink::OpenDeviceError::ACCESS_DENIED:
+ m_device->onDeviceOpenedOrClosed(false);
+ reject(DOMException::create(SecurityError, "Access denied."));
+ break;
+ }
+ }
}
private:
Persistent<USBDevice> m_device;
- Persistent<ScriptPromiseResolver> m_resolver;
- bool m_desiredState; // true: open, false: closed
};
-class SelectConfigurationPromiseAdapter : public WebCallbacks<void, const WebUSBError&> {
+class ClosePromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::CloseCallback> {
+ WTF_MAKE_NONCOPYABLE(ClosePromiseAdapter);
+
public:
- SelectConfigurationPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t configurationIndex)
- : m_device(device)
- , m_resolver(resolver)
- , m_configurationIndex(configurationIndex)
+ ClosePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver)
+ : PromiseAdapterBase(resolver)
+ , m_device(device)
{
}
- void onSuccess() override
+ void Run() const override
+ {
+ if (active()) {
+ m_device->onDeviceOpenedOrClosed(false);
+ resolve();
+ }
+ }
+
+private:
+ Persistent<USBDevice> m_device;
+};
+
+class SelectConfigurationPromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::SetConfigurationCallback> {
+ WTF_MAKE_NONCOPYABLE(SelectConfigurationPromiseAdapter);
+
+public:
+ SelectConfigurationPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t configurationIndex)
+ : PromiseAdapterBase(resolver)
+ , m_device(device)
+ , m_configurationIndex(configurationIndex)
{
- if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
- return;
- m_device->onConfigurationSelected(true /* success */, m_configurationIndex);
- m_resolver->resolve();
}
- void onError(const WebUSBError& e) override
+ void Run(bool success) const override
{
- if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
- return;
- m_device->onConfigurationSelected(false /* failure */, m_configurationIndex);
- m_resolver->reject(USBError::take(m_resolver, e));
+ if (active()) {
+ m_device->onConfigurationSelected(success, m_configurationIndex);
+ if (success)
+ resolve();
+ else
+ reject(DOMException::create(NetworkError, "Unable to set device configuration."));
+ }
}
private:
Persistent<USBDevice> m_device;
- Persistent<ScriptPromiseResolver> m_resolver;
size_t m_configurationIndex;
};
-class ClaimInterfacePromiseAdapter : public WebCallbacks<void, const WebUSBError&> {
+class ClaimInterfacePromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::ClaimInterfaceCallback> {
+ WTF_MAKE_NONCOPYABLE(ClaimInterfacePromiseAdapter);
+
public:
- ClaimInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t interfaceIndex, bool desiredState)
- : m_device(device)
- , m_resolver(resolver)
+ ClaimInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t interfaceIndex)
+ : PromiseAdapterBase(resolver)
+ , m_device(device)
, m_interfaceIndex(interfaceIndex)
- , m_desiredState(desiredState)
{
}
- void onSuccess() override
+ void Run(bool success) const override
+ {
+ if (active()) {
+ m_device->onInterfaceClaimedOrUnclaimed(success, m_interfaceIndex);
+ if (success)
+ resolve();
+ else
+ reject(DOMException::create(NetworkError, "Unable to claim interface."));
+ }
+ }
+
+private:
+ Persistent<USBDevice> m_device;
+ size_t m_interfaceIndex;
+};
+
+class ReleaseInterfacePromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::ReleaseInterfaceCallback> {
+ WTF_MAKE_NONCOPYABLE(ReleaseInterfacePromiseAdapter);
+
+public:
+ ReleaseInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t interfaceIndex)
+ : PromiseAdapterBase(resolver)
+ , m_device(device)
+ , m_interfaceIndex(interfaceIndex)
{
- if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
- return;
- m_device->onInterfaceClaimedOrUnclaimed(m_desiredState, m_interfaceIndex);
- m_resolver->resolve();
}
- void onError(const WebUSBError& e) override
+ void Run(bool success) const override
{
- if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
- return;
- m_device->onInterfaceClaimedOrUnclaimed(!m_desiredState, m_interfaceIndex);
- m_resolver->reject(USBError::take(m_resolver, e));
+ if (active()) {
+ m_device->onInterfaceClaimedOrUnclaimed(!success, m_interfaceIndex);
+ if (success)
+ resolve();
+ else
+ reject(DOMException::create(NetworkError, "Unable to release interface."));
+ }
}
private:
Persistent<USBDevice> m_device;
- Persistent<ScriptPromiseResolver> m_resolver;
size_t m_interfaceIndex;
- bool m_desiredState; // true: claimed, false: unclaimed
};
-class SelectAlternateInterfacePromiseAdapter : public WebCallbacks<void, const WebUSBError&> {
+class SetInterfacePromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::SetInterfaceAlternateSettingCallback> {
+ WTF_MAKE_NONCOPYABLE(SetInterfacePromiseAdapter);
+
public:
- SelectAlternateInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t interfaceIndex, size_t alternateIndex)
- : m_device(device)
- , m_resolver(resolver)
+ SetInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t interfaceIndex, size_t alternateIndex)
+ : PromiseAdapterBase(resolver)
+ , m_device(device)
, m_interfaceIndex(interfaceIndex)
, m_alternateIndex(alternateIndex)
{
}
- void onSuccess() override
- {
- if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
- return;
- m_device->onAlternateInterfaceSelected(true /* success */, m_interfaceIndex, m_alternateIndex);
- m_resolver->resolve();
- }
-
- void onError(const WebUSBError& e) override
+ void Run(bool success) const override
{
- if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
- return;
- m_device->onAlternateInterfaceSelected(false /* failure */, m_interfaceIndex, m_alternateIndex);
- m_resolver->reject(USBError::take(m_resolver, e));
+ if (active()) {
+ m_device->onAlternateInterfaceSelected(success, m_interfaceIndex, m_alternateIndex);
+ if (success)
+ resolve();
+ else
+ reject(DOMException::create(NetworkError, "Unable to set device interface."));
+ }
}
private:
Persistent<USBDevice> m_device;
- Persistent<ScriptPromiseResolver> m_resolver;
size_t m_interfaceIndex;
size_t m_alternateIndex;
};
-class InputTransferResult {
- WTF_MAKE_NONCOPYABLE(InputTransferResult);
+class ControlTransferInPromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::ControlTransferInCallback> {
+ WTF_MAKE_NONCOPYABLE(ControlTransferInPromiseAdapter);
+
public:
- using WebType = OwnPtr<WebUSBTransferInfo>;
+ ControlTransferInPromiseAdapter(ScriptPromiseResolver* resolver)
+ : PromiseAdapterBase(resolver)
+ {
+ }
- static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTransferInfo> webTransferInfo)
+ void Run(device::usb::blink::TransferStatus status, mojo::WTFArray<uint8_t> data) const override
{
- ASSERT(webTransferInfo->status.size() == 1);
- return USBInTransferResult::create(convertTransferStatus(webTransferInfo->status[0]), webTransferInfo->data);
+ if (active()) {
+ DOMException* error = convertFatalTransferStatus(status);
+ if (error)
+ reject(error);
+ else
+ resolve(USBInTransferResult::create(convertTransferStatus(status), data.PassStorage()));
+ }
+ }
+};
+
+class ControlTransferOutPromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::ControlTransferOutCallback> {
+ WTF_MAKE_NONCOPYABLE(ControlTransferOutPromiseAdapter);
+
+public:
+ ControlTransferOutPromiseAdapter(ScriptPromiseResolver* resolver, unsigned transferLength)
+ : PromiseAdapterBase(resolver)
+ , m_transferLength(transferLength)
+ {
+ }
+
+ void Run(device::usb::blink::TransferStatus status) const override
+ {
+ if (active()) {
+ DOMException* error = convertFatalTransferStatus(status);
+ if (error)
+ reject(error);
+ else
+ resolve(USBOutTransferResult::create(convertTransferStatus(status), m_transferLength));
+ }
}
private:
- InputTransferResult() = delete;
+ unsigned m_transferLength;
};
-class OutputTransferResult {
- WTF_MAKE_NONCOPYABLE(OutputTransferResult);
+class ClearHaltPromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::ClearHaltCallback> {
+ WTF_MAKE_NONCOPYABLE(ClearHaltPromiseAdapter);
+
public:
- using WebType = OwnPtr<WebUSBTransferInfo>;
+ ClearHaltPromiseAdapter(ScriptPromiseResolver* resolver)
+ : PromiseAdapterBase(resolver)
+ {
+ }
- static USBOutTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTransferInfo> webTransferInfo)
+ void Run(bool success) const override
{
- ASSERT(webTransferInfo->status.size() == 1);
- ASSERT(webTransferInfo->bytesTransferred.size() == 1);
- return USBOutTransferResult::create(convertTransferStatus(webTransferInfo->status[0]), webTransferInfo->bytesTransferred[0]);
+ if (active()) {
+ if (success)
+ resolve();
+ else
+ reject(DOMException::create(NetworkError, "Unable to clear endpoint."));
+ }
}
+};
-private:
- OutputTransferResult() = delete;
+class GenericTransferInPromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::GenericTransferInCallback> {
+ WTF_MAKE_NONCOPYABLE(GenericTransferInPromiseAdapter);
+
+public:
+ GenericTransferInPromiseAdapter(ScriptPromiseResolver* resolver)
+ : PromiseAdapterBase(resolver)
+ {
+ }
+
+ void Run(device::usb::blink::TransferStatus status, mojo::WTFArray<uint8_t> data) const override
+ {
+ if (active()) {
+ DOMException* error = convertFatalTransferStatus(status);
+ if (error)
+ reject(error);
+ else
+ resolve(USBInTransferResult::create(convertTransferStatus(status), data.PassStorage()));
+ }
+ }
};
-class IsochronousInputTransferResult {
- WTF_MAKE_NONCOPYABLE(IsochronousInputTransferResult);
+class GenericTransferOutPromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::GenericTransferOutCallback> {
+ WTF_MAKE_NONCOPYABLE(GenericTransferOutPromiseAdapter);
public:
- using WebType = OwnPtr<WebUSBTransferInfo>;
+ GenericTransferOutPromiseAdapter(ScriptPromiseResolver* resolver, unsigned transferLength)
+ : PromiseAdapterBase(resolver)
+ , m_transferLength(transferLength)
+ {
+ }
- static USBIsochronousInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTransferInfo> webTransferInfo)
+ void Run(device::usb::blink::TransferStatus status) const override
{
- ASSERT(webTransferInfo->status.size() == webTransferInfo->packetLength.size() && webTransferInfo->packetLength.size() == webTransferInfo->bytesTransferred.size());
- RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(webTransferInfo->data.data(), webTransferInfo->data.size());
- HeapVector<Member<USBIsochronousInTransferPacket>> packets(webTransferInfo->status.size());
- size_t byteOffset = 0;
- for (size_t i = 0; i < webTransferInfo->status.size(); ++i) {
- packets[i] = USBIsochronousInTransferPacket::create(convertTransferStatus(webTransferInfo->status[i]), DOMDataView::create(buffer, byteOffset, webTransferInfo->bytesTransferred[i]));
- byteOffset += webTransferInfo->packetLength[i];
+ if (active()) {
+ DOMException* error = convertFatalTransferStatus(status);
+ if (error)
+ reject(error);
+ else
+ resolve(USBOutTransferResult::create(convertTransferStatus(status), m_transferLength));
}
- return USBIsochronousInTransferResult::create(buffer, packets);
}
+
+private:
+ unsigned m_transferLength;
};
-class IsochronousOutputTransferResult {
- WTF_MAKE_NONCOPYABLE(IsochronousOutputTransferResult);
+class IsochronousTransferInPromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::IsochronousTransferInCallback> {
+ WTF_MAKE_NONCOPYABLE(IsochronousTransferInPromiseAdapter);
public:
- using WebType = OwnPtr<WebUSBTransferInfo>;
+ IsochronousTransferInPromiseAdapter(ScriptPromiseResolver* resolver)
+ : PromiseAdapterBase(resolver)
+ {
+ }
- static USBIsochronousOutTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTransferInfo> webTransferInfo)
+ void Run(mojo::WTFArray<uint8_t> data, mojo::WTFArray<device::usb::blink::IsochronousPacketPtr> mojoPackets) const override
{
- ASSERT(webTransferInfo->status.size() == webTransferInfo->bytesTransferred.size());
- HeapVector<Member<USBIsochronousOutTransferPacket>> packets(webTransferInfo->status.size());
- for (size_t i = 0; i < webTransferInfo->status.size(); ++i)
- packets[i] = USBIsochronousOutTransferPacket::create(convertTransferStatus(webTransferInfo->status[i]), webTransferInfo->bytesTransferred[i]);
- return USBIsochronousOutTransferResult::create(packets);
+ RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(data.storage().data(), data.storage().size());
+ HeapVector<Member<USBIsochronousInTransferPacket>> packets(mojoPackets.size());
+ size_t byteOffset = 0;
+ for (size_t i = 0; i < mojoPackets.size(); ++i) {
+ DOMException* error = convertFatalTransferStatus(mojoPackets[i]->status);
+ if (error) {
+ reject(error);
+ return;
+ }
+ packets[i] = USBIsochronousInTransferPacket::create(convertTransferStatus(mojoPackets[i]->status), DOMDataView::create(buffer, byteOffset, mojoPackets[i]->transferred_length));
+ byteOffset += mojoPackets[i]->length;
+ }
+ resolve(USBIsochronousInTransferResult::create(buffer, packets));
}
};
-class BufferSource {
- WTF_MAKE_NONCOPYABLE(BufferSource);
+class IsochronousTransferOutPromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::IsochronousTransferOutCallback> {
+ WTF_MAKE_NONCOPYABLE(IsochronousTransferOutPromiseAdapter);
+
public:
- BufferSource(const ArrayBufferOrArrayBufferView& buffer) : m_buffer(buffer)
+ IsochronousTransferOutPromiseAdapter(ScriptPromiseResolver* resolver)
+ : PromiseAdapterBase(resolver)
{
- ASSERT(!m_buffer.isNull());
}
- uint8_t* data() const
+ void Run(mojo::WTFArray<device::usb::blink::IsochronousPacketPtr> mojoPackets) const override
{
- if (m_buffer.isArrayBuffer())
- return static_cast<uint8_t*>(m_buffer.getAsArrayBuffer()->data());
- return static_cast<uint8_t*>(m_buffer.getAsArrayBufferView()->baseAddress());
+ HeapVector<Member<USBIsochronousOutTransferPacket>> packets(mojoPackets.size());
+ for (size_t i = 0; i < mojoPackets.size(); ++i) {
esprehn 2016/04/06 20:10:45 range loop?
Reilly Grant (use Gerrit) 2016/04/06 22:30:07 Done.
+ DOMException* error = convertFatalTransferStatus(mojoPackets[i]->status);
+ if (error) {
+ reject(error);
+ return;
+ }
+ packets[i] = USBIsochronousOutTransferPacket::create(convertTransferStatus(mojoPackets[i]->status), mojoPackets[i]->transferred_length);
+ }
+ resolve(USBIsochronousOutTransferResult::create(packets));
}
+};
- unsigned size() const
+class ResetPromiseAdapter : public PromiseAdapterBase<device::usb::blink::Device::ResetCallback> {
+ WTF_MAKE_NONCOPYABLE(ResetPromiseAdapter);
+
+public:
+ ResetPromiseAdapter(ScriptPromiseResolver* resolver)
+ : PromiseAdapterBase(resolver)
{
- if (m_buffer.isArrayBuffer())
- return m_buffer.getAsArrayBuffer()->byteLength();
- return m_buffer.getAsArrayBufferView()->byteLength();
}
-private:
- const ArrayBufferOrArrayBufferView& m_buffer;
+ void Run(bool success) const override
+ {
+ if (active()) {
+ if (success)
+ resolve();
+ else
+ reject(DOMException::create(NetworkError, "Unable to reset the device."));
+ }
+ }
};
} // namespace
-// static
-USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDevice> device)
-{
- return USBDevice::create(device, resolver->getExecutionContext());
-}
-
-USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context)
+USBDevice::USBDevice(device::usb::blink::DeviceInfoPtr deviceInfo, device::usb::blink::DevicePtr device, ExecutionContext* context)
: ContextLifecycleObserver(context)
, PageLifecycleObserver(toDocument(context)->page())
- , m_device(device)
+ , m_deviceInfo(std::move(deviceInfo))
+ , m_device(std::move(device))
, m_opened(false)
, m_deviceStateChangeInProgress(false)
, m_configurationIndex(-1)
- , m_inEndpoints(15)
- , m_outEndpoints(15)
{
- int configurationIndex = findConfigurationIndex(info().activeConfiguration);
+ if (m_device) {
+ m_device.set_connection_error_handler([this]() {
+ m_device = nullptr;
+ m_opened = false;
+ });
+ }
+ int configurationIndex = findConfigurationIndex(info().active_configuration);
if (configurationIndex != -1)
onConfigurationSelected(true /* success */, configurationIndex);
}
+USBDevice::~USBDevice()
+{
+}
+
void USBDevice::onDeviceOpenedOrClosed(bool opened)
{
m_opened = opened;
@@ -311,7 +525,7 @@ void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex)
{
if (success) {
m_configurationIndex = configurationIndex;
- size_t numInterfaces = info().configurations[m_configurationIndex].interfaces.size();
+ size_t numInterfaces = info().configurations[m_configurationIndex]->interfaces.size();
m_claimedInterfaces.clearAll();
m_claimedInterfaces.resize(numInterfaces);
m_interfaceStateChangeInProgress.clearAll();
@@ -379,7 +593,8 @@ ScriptPromise USBDevice::open(ScriptState* scriptState)
resolver->resolve();
} else {
m_deviceStateChangeInProgress = true;
- m_device->open(new OpenClosePromiseAdapter(this, resolver, true /* open */));
+ auto adapter = new OpenPromiseAdapter(this, resolver);
+ m_device->Open(adapter->callback());
}
}
return promise;
@@ -394,7 +609,8 @@ ScriptPromise USBDevice::close(ScriptState* scriptState)
resolver->resolve();
} else {
m_deviceStateChangeInProgress = true;
- m_device->close(new OpenClosePromiseAdapter(this, resolver, false /* closed */));
+ auto adapter = new ClosePromiseAdapter(this, resolver);
+ m_device->Close(adapter->callback());
}
}
return promise;
@@ -415,7 +631,8 @@ ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c
resolver->resolve();
} else {
m_deviceStateChangeInProgress = true;
- m_device->setConfiguration(configurationValue, new SelectConfigurationPromiseAdapter(this, resolver, configurationIndex));
+ auto adapter = new SelectConfigurationPromiseAdapter(this, resolver, configurationIndex);
+ m_device->SetConfiguration(configurationValue, adapter->callback());
}
}
}
@@ -436,7 +653,8 @@ ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf
resolver->resolve();
} else {
m_interfaceStateChangeInProgress.set(interfaceIndex);
- m_device->claimInterface(interfaceNumber, new ClaimInterfacePromiseAdapter(this, resolver, interfaceIndex, true /* claim */));
+ auto adapter = new ClaimInterfacePromiseAdapter(this, resolver, interfaceIndex);
+ m_device->ClaimInterface(interfaceNumber, adapter->callback());
}
}
return promise;
@@ -459,7 +677,8 @@ ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte
// changing.
setEndpointsForInterface(interfaceIndex, false);
m_interfaceStateChangeInProgress.set(interfaceIndex);
- m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromiseAdapter(this, resolver, interfaceIndex, false /* release */));
+ auto adapter = new ReleaseInterfacePromiseAdapter(this, resolver, interfaceIndex);
+ m_device->ReleaseInterface(interfaceNumber, adapter->callback());
}
}
return promise;
@@ -481,7 +700,8 @@ ScriptPromise USBDevice::selectAlternateInterface(ScriptState* scriptState, uint
// the change is in progress.
setEndpointsForInterface(interfaceIndex, false);
m_interfaceStateChangeInProgress.set(interfaceIndex);
- m_device->setInterface(interfaceNumber, alternateSetting, new SelectAlternateInterfacePromiseAdapter(this, resolver, interfaceIndex, alternateIndex));
+ auto adapter = new SetInterfacePromiseAdapter(this, resolver, interfaceIndex, alternateIndex);
+ m_device->SetInterfaceAlternateSetting(interfaceNumber, alternateSetting, adapter->callback());
}
}
return promise;
@@ -492,9 +712,11 @@ ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = resolver->promise();
if (ensureDeviceConfigured(resolver)) {
- WebUSBDevice::ControlTransferParameters parameters;
- if (convertControlTransferParameters(WebUSBDevice::TransferDirection::In, setup, &parameters, resolver))
- m_device->controlTransfer(parameters, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(resolver));
+ auto parameters = convertControlTransferParameters(setup, resolver);
+ if (parameters) {
+ auto adapter = new ControlTransferInPromiseAdapter(resolver);
+ m_device->ControlTransferIn(std::move(parameters), length, 0, adapter->callback());
+ }
}
return promise;
}
@@ -504,9 +726,11 @@ ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = resolver->promise();
if (ensureDeviceConfigured(resolver)) {
- WebUSBDevice::ControlTransferParameters parameters;
- if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Out, setup, &parameters, resolver))
- m_device->controlTransfer(parameters, nullptr, 0, 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
+ auto parameters = convertControlTransferParameters(setup, resolver);
+ if (parameters) {
+ auto adapter = new ControlTransferOutPromiseAdapter(resolver, 0);
+ m_device->ControlTransferOut(std::move(parameters), mojo::WTFArray<uint8_t>(), 0, adapter->callback());
+ }
}
return promise;
}
@@ -516,10 +740,11 @@ ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = resolver->promise();
if (ensureDeviceConfigured(resolver)) {
- WebUSBDevice::ControlTransferParameters parameters;
- if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Out, setup, &parameters, resolver)) {
- BufferSource buffer(data);
- m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
+ auto parameters = convertControlTransferParameters(setup, resolver);
+ if (parameters) {
+ mojo::WTFArray<uint8_t> buffer = convertBufferSource(data);
+ auto adapter = new ControlTransferOutPromiseAdapter(resolver, buffer.size());
+ m_device->ControlTransferOut(std::move(parameters), std::move(buffer), 0, adapter->callback());
}
}
return promise;
@@ -529,8 +754,10 @@ ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u
{
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = resolver->promise();
- if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver))
- m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USBError>(resolver));
+ if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver)) {
+ auto adapter = new ClearHaltPromiseAdapter(resolver);
+ m_device->ClearHalt(endpointNumber, adapter->callback());
+ }
return promise;
}
@@ -538,8 +765,10 @@ ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu
{
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = resolver->promise();
- if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver))
- m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(resolver));
+ if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) {
+ auto adapter = new GenericTransferInPromiseAdapter(resolver);
+ m_device->GenericTransferIn(endpointNumber, length, 0, adapter->callback());
+ }
return promise;
}
@@ -548,8 +777,9 @@ ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = resolver->promise();
if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
- BufferSource buffer(data);
- m_device->transfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
+ mojo::WTFArray<uint8_t> buffer = convertBufferSource(data);
+ auto adapter = new GenericTransferOutPromiseAdapter(resolver, buffer.size());
+ m_device->GenericTransferOut(endpointNumber, std::move(buffer), 0, adapter->callback());
}
return promise;
}
@@ -558,8 +788,10 @@ ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t
{
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = resolver->promise();
- if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver))
- m_device->isochronousTransfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, 0, packetLengths, 0, new CallbackPromiseAdapter<IsochronousInputTransferResult, USBError>(resolver));
+ if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) {
+ auto adapter = new IsochronousTransferInPromiseAdapter(resolver);
+ m_device->IsochronousTransferIn(endpointNumber, mojo::WTFArray<uint32_t>(std::move(packetLengths)), 0, adapter->callback());
+ }
return promise;
}
@@ -568,8 +800,8 @@ ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = resolver->promise();
if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
- BufferSource buffer(data);
- m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseAdapter<IsochronousOutputTransferResult, USBError>(resolver));
+ auto adapter = new IsochronousTransferOutPromiseAdapter(resolver);
+ m_device->IsochronousTransferOut(endpointNumber, convertBufferSource(data), mojo::WTFArray<uint32_t>(std::move(packetLengths)), 0, adapter->callback());
}
return promise;
}
@@ -579,26 +811,25 @@ ScriptPromise USBDevice::reset(ScriptState* scriptState)
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = resolver->promise();
if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
- if (!m_opened)
+ if (!m_opened) {
resolver->reject(DOMException::create(InvalidStateError, kOpenRequired));
- else
- m_device->reset(new CallbackPromiseAdapter<void, USBError>(resolver));
+ } else {
+ auto adapter = new ResetPromiseAdapter(resolver);
+ m_device->Reset(adapter->callback());
+ }
}
return promise;
}
void USBDevice::contextDestroyed()
{
- if (m_opened) {
- m_device->close(new WebUSBDeviceCloseCallbacks());
- m_opened = false;
- }
+ m_device.reset();
}
void USBDevice::pageVisibilityChanged()
{
if (!page()->isPageVisible() && m_opened) {
- m_device->close(new WebUSBDeviceCloseCallbacks());
+ m_device->Close(device::usb::blink::Device::CloseCallback());
m_opened = false;
}
}
@@ -613,7 +844,7 @@ int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
{
const auto& configurations = info().configurations;
for (size_t i = 0; i < configurations.size(); ++i) {
- if (configurations[i].configurationValue == configurationValue)
+ if (configurations[i]->configuration_value == configurationValue)
return i;
}
return -1;
@@ -622,9 +853,9 @@ int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
{
ASSERT(m_configurationIndex != -1);
- const auto& interfaces = info().configurations[m_configurationIndex].interfaces;
+ const auto& interfaces = info().configurations[m_configurationIndex]->interfaces;
for (size_t i = 0; i < interfaces.size(); ++i) {
- if (interfaces[i].interfaceNumber == interfaceNumber)
+ if (interfaces[i]->interface_number == interfaceNumber)
return i;
}
return -1;
@@ -633,9 +864,9 @@ int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSetting) const
{
ASSERT(m_configurationIndex != -1);
- const auto& alternates = info().configurations[m_configurationIndex].interfaces[interfaceIndex].alternates;
+ const auto& alternates = info().configurations[m_configurationIndex]->interfaces[interfaceIndex]->alternates;
for (size_t i = 0; i < alternates.size(); ++i) {
- if (alternates[i].alternateSetting == alternateSetting)
+ if (alternates[i]->alternate_setting == alternateSetting)
return i;
}
return -1;
@@ -654,7 +885,9 @@ bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver*
{
if (!ensurePageVisible(resolver))
return false;
- if (m_deviceStateChangeInProgress)
+ if (!m_device)
+ resolver->reject(DOMException::create(NotFoundError, kDeviceUnavailable));
+ else if (m_deviceStateChangeInProgress)
resolver->reject(DOMException::create(InvalidStateError, kDeviceStateChangeInProgress));
else if (anyInterfaceChangeInProgress())
resolver->reject(DOMException::create(InvalidStateError, kInterfaceStateChangeInProgress));
@@ -667,7 +900,9 @@ bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const
{
if (!ensurePageVisible(resolver))
return false;
- if (m_deviceStateChangeInProgress)
+ if (!m_device)
+ resolver->reject(DOMException::create(NotFoundError, kDeviceUnavailable));
+ else if (m_deviceStateChangeInProgress)
resolver->reject(DOMException::create(InvalidStateError, kDeviceStateChangeInProgress));
else if (!m_opened)
resolver->reject(DOMException::create(InvalidStateError, kOpenRequired));
@@ -719,64 +954,63 @@ bool USBDevice::anyInterfaceChangeInProgress() const
return false;
}
-bool USBDevice::convertControlTransferParameters(
- WebUSBDevice::TransferDirection direction,
+device::usb::blink::ControlTransferParamsPtr USBDevice::convertControlTransferParameters(
const USBControlTransferParameters& parameters,
- WebUSBDevice::ControlTransferParameters* webParameters,
ScriptPromiseResolver* resolver) const
{
- webParameters->direction = direction;
+ auto mojoParameters = device::usb::blink::ControlTransferParams::New();
if (parameters.requestType() == "standard") {
- webParameters->type = WebUSBDevice::RequestType::Standard;
+ mojoParameters->type = device::usb::blink::ControlTransferType::STANDARD;
} else if (parameters.requestType() == "class") {
- webParameters->type = WebUSBDevice::RequestType::Class;
+ mojoParameters->type = device::usb::blink::ControlTransferType::CLASS;
} else if (parameters.requestType() == "vendor") {
- webParameters->type = WebUSBDevice::RequestType::Vendor;
+ mojoParameters->type = device::usb::blink::ControlTransferType::VENDOR;
} else {
resolver->reject(DOMException::create(TypeMismatchError, "The control transfer requestType parameter is invalid."));
- return false;
+ return nullptr;
}
if (parameters.recipient() == "device") {
- webParameters->recipient = WebUSBDevice::RequestRecipient::Device;
+ mojoParameters->recipient = device::usb::blink::ControlTransferRecipient::DEVICE;
} else if (parameters.recipient() == "interface") {
size_t interfaceNumber = parameters.index() & 0xff;
if (!ensureInterfaceClaimed(interfaceNumber, resolver))
- return false;
- webParameters->recipient = WebUSBDevice::RequestRecipient::Interface;
+ return nullptr;
+ mojoParameters->recipient = device::usb::blink::ControlTransferRecipient::INTERFACE;
} else if (parameters.recipient() == "endpoint") {
bool inTransfer = parameters.index() & 0x80;
size_t endpointNumber = parameters.index() & 0x0f;
if (!ensureEndpointAvailable(inTransfer, endpointNumber, resolver))
- return false;
- webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint;
+ return nullptr;
+ mojoParameters->recipient = device::usb::blink::ControlTransferRecipient::ENDPOINT;
} else if (parameters.recipient() == "other") {
- webParameters->recipient = WebUSBDevice::RequestRecipient::Other;
+ mojoParameters->recipient = device::usb::blink::ControlTransferRecipient::OTHER;
} else {
resolver->reject(DOMException::create(TypeMismatchError, "The control transfer recipient parameter is invalid."));
- return false;
+ return nullptr;
}
- webParameters->request = parameters.request();
- webParameters->value = parameters.value();
- webParameters->index = parameters.index();
- return true;
+ mojoParameters->request = parameters.request();
+ mojoParameters->value = parameters.value();
+ mojoParameters->index = parameters.index();
+ return mojoParameters;
}
void USBDevice::setEndpointsForInterface(size_t interfaceIndex, bool set)
{
- const auto& configuration = info().configurations[m_configurationIndex];
- const auto& interface = configuration.interfaces[interfaceIndex];
- const auto& alternate = interface.alternates[m_selectedAlternates[interfaceIndex]];
- for (const auto& endpoint : alternate.endpoints) {
- if (endpoint.endpointNumber == 0 || endpoint.endpointNumber >= 16)
+ const auto& configuration = *info().configurations[m_configurationIndex];
+ const auto& interface = *configuration.interfaces[interfaceIndex];
+ const auto& alternate = *interface.alternates[m_selectedAlternates[interfaceIndex]];
+ for (const auto& endpoint : alternate.endpoints.storage()) {
+ uint8_t endpointNumber = endpoint->endpoint_number;
+ if (endpointNumber == 0 || endpointNumber >= 16)
continue; // Ignore endpoints with invalid indices.
- auto& bitVector = endpoint.direction == WebUSBDevice::TransferDirection::In ? m_inEndpoints : m_outEndpoints;
+ auto& bitVector = endpoint->direction == device::usb::blink::TransferDirection::INBOUND ? m_inEndpoints : m_outEndpoints;
if (set)
- bitVector.set(endpoint.endpointNumber - 1);
+ bitVector.set(endpointNumber - 1);
else
- bitVector.clear(endpoint.endpointNumber - 1);
+ bitVector.clear(endpointNumber - 1);
}
}

Powered by Google App Engine
This is Rietveld 408576698