Consume Mojo services directly in Blink's WebUSB implementation.
This patch takes advantage of the ability to consume a Mojo service directly in //third_party/WebKit/Source/modules to remove the //third_party/WebKit/public/platform/modules/webusb, //content/renderer/usb and the rest of that intermediate layer. BUG=None Review URL: https://codereview.chromium.org/1850023002 Cr-Commit-Position: refs/heads/master@{#388571}
This commit is contained in:
content
content_renderer.gypi
renderer
device/usb
third_party/WebKit
@ -13,7 +13,6 @@
|
|||||||
'../components/url_formatter/url_formatter.gyp:url_formatter',
|
'../components/url_formatter/url_formatter.gyp:url_formatter',
|
||||||
'../device/battery/battery.gyp:device_battery',
|
'../device/battery/battery.gyp:device_battery',
|
||||||
'../device/battery/battery.gyp:device_battery_mojo_bindings',
|
'../device/battery/battery.gyp:device_battery_mojo_bindings',
|
||||||
'../device/usb/usb.gyp:device_usb_mojo_bindings',
|
|
||||||
'../device/vibration/vibration.gyp:device_vibration',
|
'../device/vibration/vibration.gyp:device_vibration',
|
||||||
'../device/vibration/vibration.gyp:device_vibration_mojo_bindings',
|
'../device/vibration/vibration.gyp:device_vibration_mojo_bindings',
|
||||||
'../gin/gin.gyp:gin',
|
'../gin/gin.gyp:gin',
|
||||||
@ -465,12 +464,6 @@
|
|||||||
'renderer/theme_helper_mac.mm',
|
'renderer/theme_helper_mac.mm',
|
||||||
'renderer/top_level_blame_context.cc',
|
'renderer/top_level_blame_context.cc',
|
||||||
'renderer/top_level_blame_context.h',
|
'renderer/top_level_blame_context.h',
|
||||||
'renderer/usb/type_converters.cc',
|
|
||||||
'renderer/usb/type_converters.h',
|
|
||||||
'renderer/usb/web_usb_client_impl.cc',
|
|
||||||
'renderer/usb/web_usb_client_impl.h',
|
|
||||||
'renderer/usb/web_usb_device_impl.cc',
|
|
||||||
'renderer/usb/web_usb_device_impl.h',
|
|
||||||
'renderer/web_frame_utils.cc',
|
'renderer/web_frame_utils.cc',
|
||||||
'renderer/web_frame_utils.h',
|
'renderer/web_frame_utils.h',
|
||||||
'renderer/web_ui_extension.cc',
|
'renderer/web_ui_extension.cc',
|
||||||
|
@ -125,7 +125,6 @@
|
|||||||
#include "content/renderer/shared_worker_repository.h"
|
#include "content/renderer/shared_worker_repository.h"
|
||||||
#include "content/renderer/skia_benchmarking_extension.h"
|
#include "content/renderer/skia_benchmarking_extension.h"
|
||||||
#include "content/renderer/stats_collection_controller.h"
|
#include "content/renderer/stats_collection_controller.h"
|
||||||
#include "content/renderer/usb/web_usb_client_impl.h"
|
|
||||||
#include "content/renderer/web_frame_utils.h"
|
#include "content/renderer/web_frame_utils.h"
|
||||||
#include "content/renderer/web_ui_extension.h"
|
#include "content/renderer/web_ui_extension.h"
|
||||||
#include "content/renderer/websharedworker_proxy.h"
|
#include "content/renderer/websharedworker_proxy.h"
|
||||||
@ -161,7 +160,6 @@
|
|||||||
#include "third_party/WebKit/public/platform/WebURLError.h"
|
#include "third_party/WebKit/public/platform/WebURLError.h"
|
||||||
#include "third_party/WebKit/public/platform/WebURLResponse.h"
|
#include "third_party/WebKit/public/platform/WebURLResponse.h"
|
||||||
#include "third_party/WebKit/public/platform/WebVector.h"
|
#include "third_party/WebKit/public/platform/WebVector.h"
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBClient.h"
|
|
||||||
#include "third_party/WebKit/public/web/WebColorSuggestion.h"
|
#include "third_party/WebKit/public/web/WebColorSuggestion.h"
|
||||||
#include "third_party/WebKit/public/web/WebDocument.h"
|
#include "third_party/WebKit/public/web/WebDocument.h"
|
||||||
#include "third_party/WebKit/public/web/WebFindOptions.h"
|
#include "third_party/WebKit/public/web/WebFindOptions.h"
|
||||||
@ -4285,16 +4283,6 @@ blink::WebBluetooth* RenderFrameImpl::bluetooth() {
|
|||||||
return bluetooth_.get();
|
return bluetooth_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
blink::WebUSBClient* RenderFrameImpl::usbClient() {
|
|
||||||
if (!base::FeatureList::IsEnabled(features::kWebUsb))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (!usb_client_)
|
|
||||||
usb_client_.reset(new WebUSBClientImpl(GetServiceRegistry()));
|
|
||||||
|
|
||||||
return usb_client_.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(ENABLE_WEBVR)
|
#if defined(ENABLE_WEBVR)
|
||||||
blink::WebVRClient* RenderFrameImpl::webVRClient() {
|
blink::WebVRClient* RenderFrameImpl::webVRClient() {
|
||||||
if (!vr_dispatcher_)
|
if (!vr_dispatcher_)
|
||||||
|
@ -616,7 +616,6 @@ class CONTENT_EXPORT RenderFrameImpl
|
|||||||
void unregisterProtocolHandler(const blink::WebString& scheme,
|
void unregisterProtocolHandler(const blink::WebString& scheme,
|
||||||
const blink::WebURL& url) override;
|
const blink::WebURL& url) override;
|
||||||
blink::WebBluetooth* bluetooth() override;
|
blink::WebBluetooth* bluetooth() override;
|
||||||
blink::WebUSBClient* usbClient() override;
|
|
||||||
void checkIfAudioSinkExistsAndIsAuthorized(
|
void checkIfAudioSinkExistsAndIsAuthorized(
|
||||||
const blink::WebString& sink_id,
|
const blink::WebString& sink_id,
|
||||||
const blink::WebSecurityOrigin& security_origin,
|
const blink::WebSecurityOrigin& security_origin,
|
||||||
@ -1193,8 +1192,6 @@ class CONTENT_EXPORT RenderFrameImpl
|
|||||||
|
|
||||||
std::unique_ptr<blink::WebBluetooth> bluetooth_;
|
std::unique_ptr<blink::WebBluetooth> bluetooth_;
|
||||||
|
|
||||||
std::unique_ptr<blink::WebUSBClient> usb_client_;
|
|
||||||
|
|
||||||
// Manages play, pause notifications for WebMediaPlayer implementations; its
|
// Manages play, pause notifications for WebMediaPlayer implementations; its
|
||||||
// lifetime is tied to the RenderFrame via the RenderFrameObserver interface.
|
// lifetime is tied to the RenderFrame via the RenderFrameObserver interface.
|
||||||
media::RendererWebMediaPlayerDelegate* media_player_delegate_;
|
media::RendererWebMediaPlayerDelegate* media_player_delegate_;
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
include_rules = [
|
|
||||||
"+device/usb/public",
|
|
||||||
]
|
|
@ -1,2 +0,0 @@
|
|||||||
reillyg@chromium.org
|
|
||||||
rockot@chromium.org
|
|
@ -1,262 +0,0 @@
|
|||||||
// 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 "content/renderer/usb/type_converters.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "base/logging.h"
|
|
||||||
|
|
||||||
namespace mojo {
|
|
||||||
|
|
||||||
// static
|
|
||||||
blink::WebUSBDevice::TransferDirection
|
|
||||||
TypeConverter<blink::WebUSBDevice::TransferDirection,
|
|
||||||
device::usb::TransferDirection>::
|
|
||||||
Convert(const device::usb::TransferDirection& direction) {
|
|
||||||
switch (direction) {
|
|
||||||
case device::usb::TransferDirection::INBOUND:
|
|
||||||
return blink::WebUSBDevice::TransferDirection::In;
|
|
||||||
case device::usb::TransferDirection::OUTBOUND:
|
|
||||||
return blink::WebUSBDevice::TransferDirection::Out;
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
return blink::WebUSBDevice::TransferDirection::In;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
device::usb::TransferDirection
|
|
||||||
TypeConverter<device::usb::TransferDirection,
|
|
||||||
blink::WebUSBDevice::TransferDirection>::
|
|
||||||
Convert(const blink::WebUSBDevice::TransferDirection& direction) {
|
|
||||||
switch (direction) {
|
|
||||||
case blink::WebUSBDevice::TransferDirection::In:
|
|
||||||
return device::usb::TransferDirection::INBOUND;
|
|
||||||
case blink::WebUSBDevice::TransferDirection::Out:
|
|
||||||
return device::usb::TransferDirection::OUTBOUND;
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
return device::usb::TransferDirection::INBOUND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
device::usb::ControlTransferType
|
|
||||||
TypeConverter<device::usb::ControlTransferType,
|
|
||||||
blink::WebUSBDevice::RequestType>::
|
|
||||||
Convert(const blink::WebUSBDevice::RequestType& direction) {
|
|
||||||
switch (direction) {
|
|
||||||
case blink::WebUSBDevice::RequestType::Standard:
|
|
||||||
return device::usb::ControlTransferType::STANDARD;
|
|
||||||
case blink::WebUSBDevice::RequestType::Class:
|
|
||||||
return device::usb::ControlTransferType::CLASS;
|
|
||||||
case blink::WebUSBDevice::RequestType::Vendor:
|
|
||||||
return device::usb::ControlTransferType::VENDOR;
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
return device::usb::ControlTransferType::STANDARD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
device::usb::ControlTransferRecipient
|
|
||||||
TypeConverter<device::usb::ControlTransferRecipient,
|
|
||||||
blink::WebUSBDevice::RequestRecipient>::
|
|
||||||
Convert(const blink::WebUSBDevice::RequestRecipient& direction) {
|
|
||||||
switch (direction) {
|
|
||||||
case blink::WebUSBDevice::RequestRecipient::Device:
|
|
||||||
return device::usb::ControlTransferRecipient::DEVICE;
|
|
||||||
case blink::WebUSBDevice::RequestRecipient::Interface:
|
|
||||||
return device::usb::ControlTransferRecipient::INTERFACE;
|
|
||||||
case blink::WebUSBDevice::RequestRecipient::Endpoint:
|
|
||||||
return device::usb::ControlTransferRecipient::ENDPOINT;
|
|
||||||
case blink::WebUSBDevice::RequestRecipient::Other:
|
|
||||||
return device::usb::ControlTransferRecipient::OTHER;
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
return device::usb::ControlTransferRecipient::DEVICE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
device::usb::ControlTransferParamsPtr
|
|
||||||
TypeConverter<device::usb::ControlTransferParamsPtr,
|
|
||||||
blink::WebUSBDevice::ControlTransferParameters>::
|
|
||||||
Convert(const blink::WebUSBDevice::ControlTransferParameters& parameters) {
|
|
||||||
device::usb::ControlTransferParamsPtr params =
|
|
||||||
device::usb::ControlTransferParams::New();
|
|
||||||
params->type =
|
|
||||||
mojo::ConvertTo<device::usb::ControlTransferType>(parameters.type);
|
|
||||||
params->recipient = mojo::ConvertTo<device::usb::ControlTransferRecipient>(
|
|
||||||
parameters.recipient);
|
|
||||||
params->request = parameters.request;
|
|
||||||
params->value = parameters.value;
|
|
||||||
params->index = parameters.index;
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
blink::WebUSBDeviceInfo::Endpoint::Type TypeConverter<
|
|
||||||
blink::WebUSBDeviceInfo::Endpoint::Type,
|
|
||||||
device::usb::EndpointType>::Convert(const device::usb::EndpointType&
|
|
||||||
endpoint_type) {
|
|
||||||
switch (endpoint_type) {
|
|
||||||
case device::usb::EndpointType::BULK:
|
|
||||||
return blink::WebUSBDeviceInfo::Endpoint::Type::Bulk;
|
|
||||||
case device::usb::EndpointType::INTERRUPT:
|
|
||||||
return blink::WebUSBDeviceInfo::Endpoint::Type::Interrupt;
|
|
||||||
case device::usb::EndpointType::ISOCHRONOUS:
|
|
||||||
return blink::WebUSBDeviceInfo::Endpoint::Type::Isochronous;
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
return blink::WebUSBDeviceInfo::Endpoint::Type::Bulk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
blink::WebUSBDeviceInfo::Endpoint
|
|
||||||
TypeConverter<blink::WebUSBDeviceInfo::Endpoint, device::usb::EndpointInfoPtr>::
|
|
||||||
Convert(const device::usb::EndpointInfoPtr& info) {
|
|
||||||
blink::WebUSBDeviceInfo::Endpoint endpoint;
|
|
||||||
endpoint.endpointNumber = info->endpoint_number;
|
|
||||||
endpoint.direction =
|
|
||||||
mojo::ConvertTo<blink::WebUSBDevice::TransferDirection>(info->direction);
|
|
||||||
endpoint.type =
|
|
||||||
mojo::ConvertTo<blink::WebUSBDeviceInfo::Endpoint::Type>(info->type);
|
|
||||||
endpoint.packetSize = info->packet_size;
|
|
||||||
return endpoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
blink::WebUSBDeviceInfo::AlternateInterface
|
|
||||||
TypeConverter<blink::WebUSBDeviceInfo::AlternateInterface,
|
|
||||||
device::usb::AlternateInterfaceInfoPtr>::
|
|
||||||
Convert(const device::usb::AlternateInterfaceInfoPtr& info) {
|
|
||||||
blink::WebUSBDeviceInfo::AlternateInterface alternate;
|
|
||||||
alternate.alternateSetting = info->alternate_setting;
|
|
||||||
alternate.classCode = info->class_code;
|
|
||||||
alternate.subclassCode = info->subclass_code;
|
|
||||||
alternate.protocolCode = info->protocol_code;
|
|
||||||
if (!info->interface_name.is_null())
|
|
||||||
alternate.interfaceName = blink::WebString::fromUTF8(info->interface_name);
|
|
||||||
alternate.endpoints = blink::WebVector<blink::WebUSBDeviceInfo::Endpoint>(
|
|
||||||
info->endpoints.size());
|
|
||||||
for (size_t i = 0; i < info->endpoints.size(); ++i) {
|
|
||||||
alternate.endpoints[i] =
|
|
||||||
mojo::ConvertTo<blink::WebUSBDeviceInfo::Endpoint>(info->endpoints[i]);
|
|
||||||
}
|
|
||||||
return alternate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
blink::WebUSBDeviceInfo::Interface TypeConverter<
|
|
||||||
blink::WebUSBDeviceInfo::Interface,
|
|
||||||
device::usb::InterfaceInfoPtr>::Convert(const device::usb::InterfaceInfoPtr&
|
|
||||||
info) {
|
|
||||||
blink::WebUSBDeviceInfo::Interface interface;
|
|
||||||
interface.interfaceNumber = info->interface_number;
|
|
||||||
interface.alternates =
|
|
||||||
blink::WebVector<blink::WebUSBDeviceInfo::AlternateInterface>(
|
|
||||||
info->alternates.size());
|
|
||||||
for (size_t i = 0; i < info->alternates.size(); ++i) {
|
|
||||||
interface.alternates[i] =
|
|
||||||
mojo::ConvertTo<blink::WebUSBDeviceInfo::AlternateInterface>(
|
|
||||||
info->alternates[i]);
|
|
||||||
}
|
|
||||||
return interface;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
blink::WebUSBDeviceInfo::Configuration
|
|
||||||
TypeConverter<blink::WebUSBDeviceInfo::Configuration,
|
|
||||||
device::usb::ConfigurationInfoPtr>::
|
|
||||||
Convert(const device::usb::ConfigurationInfoPtr& info) {
|
|
||||||
blink::WebUSBDeviceInfo::Configuration config;
|
|
||||||
config.configurationValue = info->configuration_value;
|
|
||||||
if (!info->configuration_name.is_null()) {
|
|
||||||
config.configurationName =
|
|
||||||
blink::WebString::fromUTF8(info->configuration_name);
|
|
||||||
}
|
|
||||||
config.interfaces = blink::WebVector<blink::WebUSBDeviceInfo::Interface>(
|
|
||||||
info->interfaces.size());
|
|
||||||
for (size_t i = 0; i < info->interfaces.size(); ++i) {
|
|
||||||
config.interfaces[i] = mojo::ConvertTo<blink::WebUSBDeviceInfo::Interface>(
|
|
||||||
info->interfaces[i]);
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
blink::WebUSBDeviceInfo
|
|
||||||
TypeConverter<blink::WebUSBDeviceInfo, device::usb::DeviceInfoPtr>::Convert(
|
|
||||||
const device::usb::DeviceInfoPtr& info) {
|
|
||||||
blink::WebUSBDeviceInfo device;
|
|
||||||
device.guid = blink::WebString::fromUTF8(info->guid);
|
|
||||||
device.usbVersionMajor = info->usb_version_major;
|
|
||||||
device.usbVersionMinor = info->usb_version_minor;
|
|
||||||
device.usbVersionSubminor = info->usb_version_subminor;
|
|
||||||
device.deviceClass = info->class_code;
|
|
||||||
device.deviceSubclass = info->subclass_code;
|
|
||||||
device.deviceProtocol = info->protocol_code;
|
|
||||||
device.vendorID = info->vendor_id;
|
|
||||||
device.productID = info->product_id;
|
|
||||||
device.deviceVersionMajor = info->device_version_major;
|
|
||||||
device.deviceVersionMinor = info->device_version_minor;
|
|
||||||
device.deviceVersionSubminor = info->device_version_subminor;
|
|
||||||
if (!info->manufacturer_name.is_null()) {
|
|
||||||
device.manufacturerName =
|
|
||||||
blink::WebString::fromUTF8(info->manufacturer_name);
|
|
||||||
}
|
|
||||||
if (!info->product_name.is_null())
|
|
||||||
device.productName = blink::WebString::fromUTF8(info->product_name);
|
|
||||||
if (!info->serial_number.is_null())
|
|
||||||
device.serialNumber = blink::WebString::fromUTF8(info->serial_number);
|
|
||||||
device.activeConfiguration = info->active_configuration;
|
|
||||||
device.configurations =
|
|
||||||
blink::WebVector<blink::WebUSBDeviceInfo::Configuration>(
|
|
||||||
info->configurations.size());
|
|
||||||
for (size_t i = 0; i < info->configurations.size(); ++i) {
|
|
||||||
device.configurations[i] =
|
|
||||||
mojo::ConvertTo<blink::WebUSBDeviceInfo::Configuration>(
|
|
||||||
info->configurations[i]);
|
|
||||||
}
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
device::usb::DeviceFilterPtr
|
|
||||||
TypeConverter<device::usb::DeviceFilterPtr, blink::WebUSBDeviceFilter>::Convert(
|
|
||||||
const blink::WebUSBDeviceFilter& web_filter) {
|
|
||||||
device::usb::DeviceFilterPtr filter = device::usb::DeviceFilter::New();
|
|
||||||
filter->has_vendor_id = web_filter.hasVendorID;
|
|
||||||
filter->vendor_id = web_filter.vendorID;
|
|
||||||
filter->has_product_id = web_filter.hasProductID;
|
|
||||||
filter->product_id = web_filter.productID;
|
|
||||||
filter->has_class_code = web_filter.hasClassCode;
|
|
||||||
filter->class_code = web_filter.classCode;
|
|
||||||
filter->has_subclass_code = web_filter.hasSubclassCode;
|
|
||||||
filter->subclass_code = web_filter.subclassCode;
|
|
||||||
filter->has_protocol_code = web_filter.hasProtocolCode;
|
|
||||||
filter->protocol_code = web_filter.protocolCode;
|
|
||||||
return filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
device::usb::EnumerationOptionsPtr
|
|
||||||
TypeConverter<device::usb::EnumerationOptionsPtr,
|
|
||||||
blink::WebUSBDeviceRequestOptions>::
|
|
||||||
Convert(const blink::WebUSBDeviceRequestOptions& web_options) {
|
|
||||||
device::usb::EnumerationOptionsPtr options =
|
|
||||||
device::usb::EnumerationOptions::New();
|
|
||||||
options->filters = mojo::Array<device::usb::DeviceFilterPtr>::New(
|
|
||||||
web_options.filters.size());
|
|
||||||
for (size_t i = 0; i < web_options.filters.size(); ++i) {
|
|
||||||
options->filters[i] =
|
|
||||||
device::usb::DeviceFilter::From(web_options.filters[i]);
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace mojo
|
|
@ -1,105 +0,0 @@
|
|||||||
// 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 "mojo/public/cpp/bindings/type_converter.h"
|
|
||||||
|
|
||||||
#include "device/usb/public/interfaces/device.mojom.h"
|
|
||||||
#include "device/usb/public/interfaces/device_manager.mojom.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBDevice.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceFilter.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceRequestOptions.h"
|
|
||||||
|
|
||||||
namespace mojo {
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<blink::WebUSBDevice::TransferDirection,
|
|
||||||
device::usb::TransferDirection> {
|
|
||||||
static blink::WebUSBDevice::TransferDirection Convert(
|
|
||||||
const device::usb::TransferDirection& direction);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<device::usb::TransferDirection,
|
|
||||||
blink::WebUSBDevice::TransferDirection> {
|
|
||||||
static device::usb::TransferDirection Convert(
|
|
||||||
const blink::WebUSBDevice::TransferDirection& direction);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<device::usb::ControlTransferType,
|
|
||||||
blink::WebUSBDevice::RequestType> {
|
|
||||||
static device::usb::ControlTransferType Convert(
|
|
||||||
const blink::WebUSBDevice::RequestType& direction);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<device::usb::ControlTransferRecipient,
|
|
||||||
blink::WebUSBDevice::RequestRecipient> {
|
|
||||||
static device::usb::ControlTransferRecipient Convert(
|
|
||||||
const blink::WebUSBDevice::RequestRecipient& direction);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<device::usb::ControlTransferParamsPtr,
|
|
||||||
blink::WebUSBDevice::ControlTransferParameters> {
|
|
||||||
static device::usb::ControlTransferParamsPtr Convert(
|
|
||||||
const blink::WebUSBDevice::ControlTransferParameters& parameters);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<blink::WebUSBDeviceInfo::Endpoint::Type,
|
|
||||||
device::usb::EndpointType> {
|
|
||||||
static blink::WebUSBDeviceInfo::Endpoint::Type Convert(
|
|
||||||
const device::usb::EndpointType& endpoint_type);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<blink::WebUSBDeviceInfo::Endpoint,
|
|
||||||
device::usb::EndpointInfoPtr> {
|
|
||||||
static blink::WebUSBDeviceInfo::Endpoint Convert(
|
|
||||||
const device::usb::EndpointInfoPtr& info);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<blink::WebUSBDeviceInfo::AlternateInterface,
|
|
||||||
device::usb::AlternateInterfaceInfoPtr> {
|
|
||||||
static blink::WebUSBDeviceInfo::AlternateInterface Convert(
|
|
||||||
const device::usb::AlternateInterfaceInfoPtr& info);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<blink::WebUSBDeviceInfo::Interface,
|
|
||||||
device::usb::InterfaceInfoPtr> {
|
|
||||||
static blink::WebUSBDeviceInfo::Interface Convert(
|
|
||||||
const device::usb::InterfaceInfoPtr& info);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<blink::WebUSBDeviceInfo::Configuration,
|
|
||||||
device::usb::ConfigurationInfoPtr> {
|
|
||||||
static blink::WebUSBDeviceInfo::Configuration Convert(
|
|
||||||
const device::usb::ConfigurationInfoPtr& info);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<blink::WebUSBDeviceInfo, device::usb::DeviceInfoPtr> {
|
|
||||||
static blink::WebUSBDeviceInfo Convert(
|
|
||||||
const device::usb::DeviceInfoPtr& info);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<device::usb::DeviceFilterPtr, blink::WebUSBDeviceFilter> {
|
|
||||||
static device::usb::DeviceFilterPtr Convert(
|
|
||||||
const blink::WebUSBDeviceFilter& web_filter);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TypeConverter<device::usb::EnumerationOptionsPtr,
|
|
||||||
blink::WebUSBDeviceRequestOptions> {
|
|
||||||
static device::usb::EnumerationOptionsPtr Convert(
|
|
||||||
const blink::WebUSBDeviceRequestOptions& web_options);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace mojo
|
|
@ -1,180 +0,0 @@
|
|||||||
// 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 "content/renderer/usb/web_usb_client_impl.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "base/bind.h"
|
|
||||||
#include "base/callback.h"
|
|
||||||
#include "base/memory/ptr_util.h"
|
|
||||||
#include "base/move.h"
|
|
||||||
#include "base/stl_util.h"
|
|
||||||
#include "base/strings/utf_string_conversions.h"
|
|
||||||
#include "content/child/mojo/type_converters.h"
|
|
||||||
#include "content/child/scoped_web_callbacks.h"
|
|
||||||
#include "content/public/common/service_registry.h"
|
|
||||||
#include "content/renderer/usb/type_converters.h"
|
|
||||||
#include "content/renderer/usb/web_usb_device_impl.h"
|
|
||||||
#include "mojo/public/cpp/bindings/array.h"
|
|
||||||
#include "mojo/public/cpp/bindings/interface_request.h"
|
|
||||||
#include "third_party/WebKit/public/platform/WebCallbacks.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceFilter.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceRequestOptions.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBError.h"
|
|
||||||
|
|
||||||
namespace content {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
const char kNoServiceError[] = "USB service unavailable.";
|
|
||||||
|
|
||||||
// Generic default rejection handler for any WebUSB callbacks type. Assumes
|
|
||||||
// |CallbacksType| is a blink::WebCallbacks<T, const blink::WebUSBError&>
|
|
||||||
// for any type |T|.
|
|
||||||
template <typename CallbacksType>
|
|
||||||
void RejectCallbacksWithError(const blink::WebUSBError& error,
|
|
||||||
std::unique_ptr<CallbacksType> callbacks) {
|
|
||||||
callbacks->onError(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new ScopedWebCallbacks for WebUSB client callbacks, defaulting to
|
|
||||||
// a "no service" rejection.
|
|
||||||
template <typename CallbacksType>
|
|
||||||
ScopedWebCallbacks<CallbacksType> MakeScopedUSBCallbacks(
|
|
||||||
CallbacksType* callbacks) {
|
|
||||||
return make_scoped_web_callbacks(
|
|
||||||
callbacks,
|
|
||||||
base::Bind(&RejectCallbacksWithError<CallbacksType>,
|
|
||||||
blink::WebUSBError(blink::WebUSBError::Error::NotFound,
|
|
||||||
base::ASCIIToUTF16(kNoServiceError))));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnGetDevicesComplete(
|
|
||||||
ScopedWebCallbacks<blink::WebUSBClientGetDevicesCallbacks> scoped_callbacks,
|
|
||||||
device::usb::DeviceManager* device_manager,
|
|
||||||
mojo::Array<device::usb::DeviceInfoPtr> results) {
|
|
||||||
// TODO(dcheng): This WebVector should hold smart pointers.
|
|
||||||
std::unique_ptr<blink::WebVector<blink::WebUSBDevice*>> devices(
|
|
||||||
new blink::WebVector<blink::WebUSBDevice*>(results.size()));
|
|
||||||
for (size_t i = 0; i < results.size(); ++i) {
|
|
||||||
device::usb::DevicePtr device;
|
|
||||||
device_manager->GetDevice(results[i]->guid, mojo::GetProxy(&device));
|
|
||||||
(*devices)[i] = new WebUSBDeviceImpl(
|
|
||||||
std::move(device),
|
|
||||||
mojo::ConvertTo<blink::WebUSBDeviceInfo>(results[i]));
|
|
||||||
}
|
|
||||||
scoped_callbacks.PassCallbacks()->onSuccess(std::move(devices));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnRequestDevicesComplete(
|
|
||||||
ScopedWebCallbacks<blink::WebUSBClientRequestDeviceCallbacks> callbacks,
|
|
||||||
device::usb::DeviceManager* device_manager,
|
|
||||||
device::usb::DeviceInfoPtr result) {
|
|
||||||
auto scoped_callbacks = callbacks.PassCallbacks();
|
|
||||||
if (result) {
|
|
||||||
device::usb::DevicePtr device;
|
|
||||||
device_manager->GetDevice(result->guid, mojo::GetProxy(&device));
|
|
||||||
std::unique_ptr<blink::WebUSBDevice> web_usb_device(new WebUSBDeviceImpl(
|
|
||||||
std::move(device), mojo::ConvertTo<blink::WebUSBDeviceInfo>(result)));
|
|
||||||
|
|
||||||
scoped_callbacks->onSuccess(std::move(web_usb_device));
|
|
||||||
} else {
|
|
||||||
scoped_callbacks->onError(
|
|
||||||
blink::WebUSBError(blink::WebUSBError::Error::NotFound,
|
|
||||||
base::ASCIIToUTF16("No device selected.")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
WebUSBClientImpl::WebUSBClientImpl(content::ServiceRegistry* service_registry)
|
|
||||||
: service_registry_(service_registry) {}
|
|
||||||
|
|
||||||
WebUSBClientImpl::~WebUSBClientImpl() {}
|
|
||||||
|
|
||||||
void WebUSBClientImpl::getDevices(
|
|
||||||
blink::WebUSBClientGetDevicesCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
GetDeviceManager()->GetDevices(
|
|
||||||
nullptr,
|
|
||||||
base::Bind(&OnGetDevicesComplete, base::Passed(&scoped_callbacks),
|
|
||||||
base::Unretained(device_manager_.get())));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBClientImpl::requestDevice(
|
|
||||||
const blink::WebUSBDeviceRequestOptions& options,
|
|
||||||
blink::WebUSBClientRequestDeviceCallbacks* callbacks) {
|
|
||||||
if (!chooser_service_) {
|
|
||||||
service_registry_->ConnectToRemoteService(
|
|
||||||
mojo::GetProxy(&chooser_service_));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
|
|
||||||
mojo::Array<device::usb::DeviceFilterPtr> device_filters =
|
|
||||||
mojo::Array<device::usb::DeviceFilterPtr>::From(options.filters);
|
|
||||||
|
|
||||||
chooser_service_->GetPermission(
|
|
||||||
std::move(device_filters),
|
|
||||||
base::Bind(&OnRequestDevicesComplete, base::Passed(&scoped_callbacks),
|
|
||||||
base::Unretained(device_manager_.get())));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBClientImpl::addObserver(Observer* observer) {
|
|
||||||
if (observers_.empty()) {
|
|
||||||
// Set up two sequential calls to GetDeviceChanges to avoid latency.
|
|
||||||
device::usb::DeviceManager* device_manager = GetDeviceManager();
|
|
||||||
device_manager->GetDeviceChanges(base::Bind(
|
|
||||||
&WebUSBClientImpl::OnDeviceChangeNotification, base::Unretained(this)));
|
|
||||||
device_manager->GetDeviceChanges(base::Bind(
|
|
||||||
&WebUSBClientImpl::OnDeviceChangeNotification, base::Unretained(this)));
|
|
||||||
}
|
|
||||||
|
|
||||||
observers_.insert(observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBClientImpl::removeObserver(Observer* observer) {
|
|
||||||
DCHECK(ContainsKey(observers_, observer));
|
|
||||||
observers_.erase(observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
device::usb::DeviceManager* WebUSBClientImpl::GetDeviceManager() {
|
|
||||||
if (!device_manager_)
|
|
||||||
service_registry_->ConnectToRemoteService(mojo::GetProxy(&device_manager_));
|
|
||||||
return device_manager_.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBClientImpl::OnDeviceChangeNotification(
|
|
||||||
device::usb::DeviceChangeNotificationPtr notification) {
|
|
||||||
if (observers_.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
device_manager_->GetDeviceChanges(base::Bind(
|
|
||||||
&WebUSBClientImpl::OnDeviceChangeNotification, base::Unretained(this)));
|
|
||||||
for (size_t i = 0; i < notification->devices_added.size(); ++i) {
|
|
||||||
const device::usb::DeviceInfoPtr& device_info =
|
|
||||||
notification->devices_added[i];
|
|
||||||
for (auto observer : observers_) {
|
|
||||||
device::usb::DevicePtr device;
|
|
||||||
device_manager_->GetDevice(device_info->guid, mojo::GetProxy(&device));
|
|
||||||
observer->onDeviceConnected(base::WrapUnique(new WebUSBDeviceImpl(
|
|
||||||
std::move(device),
|
|
||||||
mojo::ConvertTo<blink::WebUSBDeviceInfo>(device_info))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < notification->devices_removed.size(); ++i) {
|
|
||||||
const device::usb::DeviceInfoPtr& device_info =
|
|
||||||
notification->devices_removed[i];
|
|
||||||
for (auto observer : observers_)
|
|
||||||
observer->onDeviceDisconnected(base::WrapUnique(new WebUSBDeviceImpl(
|
|
||||||
nullptr, mojo::ConvertTo<blink::WebUSBDeviceInfo>(device_info))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace content
|
|
@ -1,45 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef CONTENT_RENDERER_USB_WEB_USB_CLIENT_IMPL_H_
|
|
||||||
#define CONTENT_RENDERER_USB_WEB_USB_CLIENT_IMPL_H_
|
|
||||||
|
|
||||||
#include "base/macros.h"
|
|
||||||
#include "device/usb/public/interfaces/chooser_service.mojom.h"
|
|
||||||
#include "device/usb/public/interfaces/device_manager.mojom.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBClient.h"
|
|
||||||
|
|
||||||
namespace content {
|
|
||||||
|
|
||||||
class ServiceRegistry;
|
|
||||||
|
|
||||||
class WebUSBClientImpl : public blink::WebUSBClient {
|
|
||||||
public:
|
|
||||||
explicit WebUSBClientImpl(ServiceRegistry* service_registry);
|
|
||||||
~WebUSBClientImpl() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// blink::WebUSBClient implementation:
|
|
||||||
void getDevices(blink::WebUSBClientGetDevicesCallbacks* callbacks) override;
|
|
||||||
void requestDevice(
|
|
||||||
const blink::WebUSBDeviceRequestOptions& options,
|
|
||||||
blink::WebUSBClientRequestDeviceCallbacks* callbacks) override;
|
|
||||||
void addObserver(Observer* observer) override;
|
|
||||||
void removeObserver(Observer* observer) override;
|
|
||||||
|
|
||||||
device::usb::DeviceManager* GetDeviceManager();
|
|
||||||
void OnDeviceChangeNotification(
|
|
||||||
device::usb::DeviceChangeNotificationPtr notification);
|
|
||||||
|
|
||||||
ServiceRegistry* const service_registry_;
|
|
||||||
device::usb::DeviceManagerPtr device_manager_;
|
|
||||||
device::usb::ChooserServicePtr chooser_service_;
|
|
||||||
std::set<Observer*> observers_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(WebUSBClientImpl);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace content
|
|
||||||
|
|
||||||
#endif // CONTENT_RENDERER_USB_WEB_USB_CLIENT_IMPL_H_
|
|
@ -1,421 +0,0 @@
|
|||||||
// 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 "content/renderer/usb/web_usb_device_impl.h"
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "base/bind.h"
|
|
||||||
#include "base/callback.h"
|
|
||||||
#include "base/strings/utf_string_conversions.h"
|
|
||||||
#include "content/child/mojo/type_converters.h"
|
|
||||||
#include "content/child/scoped_web_callbacks.h"
|
|
||||||
#include "content/renderer/usb/type_converters.h"
|
|
||||||
#include "services/shell/public/cpp/connect.h"
|
|
||||||
#include "services/shell/public/interfaces/connector.mojom.h"
|
|
||||||
#include "third_party/WebKit/public/platform/WebVector.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBTransferInfo.h"
|
|
||||||
|
|
||||||
namespace content {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
const char kClaimInterfaceFailed[] = "Unable to claim interface.";
|
|
||||||
const char kClearHaltFailed[] = "Unable to clear endpoint.";
|
|
||||||
const char kDeviceAlreadyOpen[] = "Device has already been opened.";
|
|
||||||
const char kDeviceNoAccess[] = "Access denied.";
|
|
||||||
const char kDeviceUnavailable[] = "Device unavailable.";
|
|
||||||
const char kDeviceResetFailed[] = "Unable to reset the device.";
|
|
||||||
const char kReleaseInterfaceFailed[] = "Unable to release interface.";
|
|
||||||
const char kSetConfigurationFailed[] = "Unable to set device configuration.";
|
|
||||||
const char kSetInterfaceFailed[] = "Unable to set device interface.";
|
|
||||||
const char kTransferFailed[] = "Transfer failed.";
|
|
||||||
|
|
||||||
// Generic default rejection handler for any WebUSB callbacks type. Assumes
|
|
||||||
// |CallbacksType| is a blink::WebCallbacks<T, const blink::WebUSBError&>
|
|
||||||
// for any type |T|.
|
|
||||||
template <typename CallbacksType>
|
|
||||||
void RejectWithError(const blink::WebUSBError& error,
|
|
||||||
std::unique_ptr<CallbacksType> callbacks) {
|
|
||||||
callbacks->onError(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CallbacksType>
|
|
||||||
void RejectWithTransferError(std::unique_ptr<CallbacksType> callbacks) {
|
|
||||||
RejectWithError(blink::WebUSBError(blink::WebUSBError::Error::Network,
|
|
||||||
base::ASCIIToUTF16(kTransferFailed)),
|
|
||||||
std::move(callbacks));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new ScopedWebCallbacks for WebUSB device callbacks, defaulting to
|
|
||||||
// a "device unavailable" rejection.
|
|
||||||
template <typename CallbacksType>
|
|
||||||
ScopedWebCallbacks<CallbacksType> MakeScopedUSBCallbacks(
|
|
||||||
CallbacksType* callbacks) {
|
|
||||||
return make_scoped_web_callbacks(
|
|
||||||
callbacks,
|
|
||||||
base::Bind(&RejectWithError<CallbacksType>,
|
|
||||||
blink::WebUSBError(blink::WebUSBError::Error::NotFound,
|
|
||||||
base::ASCIIToUTF16(kDeviceUnavailable))));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnOpenDevice(
|
|
||||||
ScopedWebCallbacks<blink::WebUSBDeviceOpenCallbacks> callbacks,
|
|
||||||
device::usb::OpenDeviceError error) {
|
|
||||||
auto scoped_callbacks = callbacks.PassCallbacks();
|
|
||||||
switch(error) {
|
|
||||||
case device::usb::OpenDeviceError::OK:
|
|
||||||
scoped_callbacks->onSuccess();
|
|
||||||
break;
|
|
||||||
case device::usb::OpenDeviceError::ACCESS_DENIED:
|
|
||||||
scoped_callbacks->onError(blink::WebUSBError(
|
|
||||||
blink::WebUSBError::Error::Security,
|
|
||||||
base::ASCIIToUTF16(kDeviceNoAccess)));
|
|
||||||
break;
|
|
||||||
case device::usb::OpenDeviceError::ALREADY_OPEN:
|
|
||||||
scoped_callbacks->onError(blink::WebUSBError(
|
|
||||||
blink::WebUSBError::Error::InvalidState,
|
|
||||||
base::ASCIIToUTF16(kDeviceAlreadyOpen)));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnDeviceClosed(
|
|
||||||
ScopedWebCallbacks<blink::WebUSBDeviceCloseCallbacks> callbacks) {
|
|
||||||
callbacks.PassCallbacks()->onSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandlePassFailDeviceOperation(
|
|
||||||
ScopedWebCallbacks<blink::WebCallbacks<void, const blink::WebUSBError&>>
|
|
||||||
callbacks,
|
|
||||||
const std::string& failure_message,
|
|
||||||
bool success) {
|
|
||||||
auto scoped_callbacks = callbacks.PassCallbacks();
|
|
||||||
if (success) {
|
|
||||||
scoped_callbacks->onSuccess();
|
|
||||||
} else {
|
|
||||||
RejectWithError(blink::WebUSBError(blink::WebUSBError::Error::Network,
|
|
||||||
base::ASCIIToUTF16(failure_message)),
|
|
||||||
std::move(scoped_callbacks));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnTransferIn(
|
|
||||||
ScopedWebCallbacks<blink::WebUSBDeviceTransferCallbacks> callbacks,
|
|
||||||
device::usb::TransferStatus status,
|
|
||||||
mojo::Array<uint8_t> data) {
|
|
||||||
auto scoped_callbacks = callbacks.PassCallbacks();
|
|
||||||
blink::WebUSBTransferInfo::Status web_status;
|
|
||||||
switch (status) {
|
|
||||||
case device::usb::TransferStatus::COMPLETED:
|
|
||||||
web_status = blink::WebUSBTransferInfo::Status::Ok;
|
|
||||||
break;
|
|
||||||
case device::usb::TransferStatus::STALLED:
|
|
||||||
web_status = blink::WebUSBTransferInfo::Status::Stall;
|
|
||||||
break;
|
|
||||||
case device::usb::TransferStatus::BABBLE:
|
|
||||||
web_status = blink::WebUSBTransferInfo::Status::Babble;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
RejectWithTransferError(std::move(scoped_callbacks));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::unique_ptr<blink::WebUSBTransferInfo> info(
|
|
||||||
new blink::WebUSBTransferInfo());
|
|
||||||
info->status.assign(
|
|
||||||
std::vector<blink::WebUSBTransferInfo::Status>(1, web_status));
|
|
||||||
info->data.assign(data);
|
|
||||||
scoped_callbacks->onSuccess(std::move(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnTransferOut(
|
|
||||||
ScopedWebCallbacks<blink::WebUSBDeviceTransferCallbacks> callbacks,
|
|
||||||
size_t bytes_written,
|
|
||||||
device::usb::TransferStatus status) {
|
|
||||||
auto scoped_callbacks = callbacks.PassCallbacks();
|
|
||||||
blink::WebUSBTransferInfo::Status web_status;
|
|
||||||
switch (status) {
|
|
||||||
case device::usb::TransferStatus::COMPLETED:
|
|
||||||
web_status = blink::WebUSBTransferInfo::Status::Ok;
|
|
||||||
break;
|
|
||||||
case device::usb::TransferStatus::STALLED:
|
|
||||||
web_status = blink::WebUSBTransferInfo::Status::Stall;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
RejectWithTransferError(std::move(scoped_callbacks));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// TODO(rockot): Device::ControlTransferOut should expose the number of bytes
|
|
||||||
// actually transferred so we can send it from here.
|
|
||||||
std::unique_ptr<blink::WebUSBTransferInfo> info(
|
|
||||||
new blink::WebUSBTransferInfo());
|
|
||||||
info->status.assign(
|
|
||||||
std::vector<blink::WebUSBTransferInfo::Status>(1, web_status));
|
|
||||||
info->bytesTransferred.assign(std::vector<uint32_t>(1, bytes_written));
|
|
||||||
scoped_callbacks->onSuccess(std::move(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnIsochronousTransferIn(
|
|
||||||
ScopedWebCallbacks<blink::WebUSBDeviceTransferCallbacks> callbacks,
|
|
||||||
mojo::Array<uint8_t> data,
|
|
||||||
mojo::Array<device::usb::IsochronousPacketPtr> packets) {
|
|
||||||
auto scoped_callbacks = callbacks.PassCallbacks();
|
|
||||||
std::unique_ptr<blink::WebUSBTransferInfo> info(
|
|
||||||
new blink::WebUSBTransferInfo());
|
|
||||||
info->data.assign(data);
|
|
||||||
info->status =
|
|
||||||
blink::WebVector<blink::WebUSBTransferInfo::Status>(packets.size());
|
|
||||||
info->packetLength = blink::WebVector<uint32_t>(packets.size());
|
|
||||||
info->bytesTransferred = blink::WebVector<uint32_t>(packets.size());
|
|
||||||
for (size_t i = 0; i < packets.size(); ++i) {
|
|
||||||
switch (packets[i]->status) {
|
|
||||||
case device::usb::TransferStatus::COMPLETED:
|
|
||||||
info->status[i] = blink::WebUSBTransferInfo::Status::Ok;
|
|
||||||
break;
|
|
||||||
case device::usb::TransferStatus::STALLED:
|
|
||||||
info->status[i] = blink::WebUSBTransferInfo::Status::Stall;
|
|
||||||
break;
|
|
||||||
case device::usb::TransferStatus::BABBLE:
|
|
||||||
info->status[i] = blink::WebUSBTransferInfo::Status::Babble;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
RejectWithTransferError(std::move(scoped_callbacks));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
info->packetLength[i] = packets[i]->length;
|
|
||||||
info->bytesTransferred[i] = packets[i]->transferred_length;
|
|
||||||
}
|
|
||||||
scoped_callbacks->onSuccess(std::move(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnIsochronousTransferOut(
|
|
||||||
ScopedWebCallbacks<blink::WebUSBDeviceTransferCallbacks> callbacks,
|
|
||||||
mojo::Array<device::usb::IsochronousPacketPtr> packets) {
|
|
||||||
auto scoped_callbacks = callbacks.PassCallbacks();
|
|
||||||
std::unique_ptr<blink::WebUSBTransferInfo> info(
|
|
||||||
new blink::WebUSBTransferInfo());
|
|
||||||
info->status =
|
|
||||||
blink::WebVector<blink::WebUSBTransferInfo::Status>(packets.size());
|
|
||||||
info->bytesTransferred = blink::WebVector<uint32_t>(packets.size());
|
|
||||||
for (size_t i = 0; i < packets.size(); ++i) {
|
|
||||||
switch (packets[i]->status) {
|
|
||||||
case device::usb::TransferStatus::COMPLETED:
|
|
||||||
info->status[i] = blink::WebUSBTransferInfo::Status::Ok;
|
|
||||||
break;
|
|
||||||
case device::usb::TransferStatus::STALLED:
|
|
||||||
info->status[i] = blink::WebUSBTransferInfo::Status::Stall;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
RejectWithTransferError(std::move(scoped_callbacks));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
info->bytesTransferred[i] = packets[i]->transferred_length;
|
|
||||||
}
|
|
||||||
scoped_callbacks->onSuccess(std::move(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
WebUSBDeviceImpl::WebUSBDeviceImpl(device::usb::DevicePtr device,
|
|
||||||
const blink::WebUSBDeviceInfo& device_info)
|
|
||||||
: device_(std::move(device)),
|
|
||||||
device_info_(device_info),
|
|
||||||
weak_factory_(this) {
|
|
||||||
if (device_)
|
|
||||||
device_.set_connection_error_handler([this]() { device_.reset(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
WebUSBDeviceImpl::~WebUSBDeviceImpl() {}
|
|
||||||
|
|
||||||
const blink::WebUSBDeviceInfo& WebUSBDeviceImpl::info() const {
|
|
||||||
return device_info_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::open(blink::WebUSBDeviceOpenCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (device_)
|
|
||||||
device_->Open(base::Bind(&OnOpenDevice, base::Passed(&scoped_callbacks)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::close(blink::WebUSBDeviceCloseCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (device_)
|
|
||||||
device_->Close(
|
|
||||||
base::Bind(&OnDeviceClosed, base::Passed(&scoped_callbacks)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::setConfiguration(
|
|
||||||
uint8_t configuration_value,
|
|
||||||
blink::WebUSBDeviceSetConfigurationCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (device_)
|
|
||||||
device_->SetConfiguration(
|
|
||||||
configuration_value,
|
|
||||||
base::Bind(&HandlePassFailDeviceOperation,
|
|
||||||
base::Passed(&scoped_callbacks), kSetConfigurationFailed));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::claimInterface(
|
|
||||||
uint8_t interface_number,
|
|
||||||
blink::WebUSBDeviceClaimInterfaceCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (device_)
|
|
||||||
device_->ClaimInterface(
|
|
||||||
interface_number,
|
|
||||||
base::Bind(&HandlePassFailDeviceOperation,
|
|
||||||
base::Passed(&scoped_callbacks), kClaimInterfaceFailed));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::releaseInterface(
|
|
||||||
uint8_t interface_number,
|
|
||||||
blink::WebUSBDeviceReleaseInterfaceCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (device_)
|
|
||||||
device_->ReleaseInterface(
|
|
||||||
interface_number,
|
|
||||||
base::Bind(&HandlePassFailDeviceOperation,
|
|
||||||
base::Passed(&scoped_callbacks), kReleaseInterfaceFailed));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::setInterface(
|
|
||||||
uint8_t interface_number,
|
|
||||||
uint8_t alternate_setting,
|
|
||||||
blink::WebUSBDeviceSetInterfaceAlternateSettingCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (device_)
|
|
||||||
device_->SetInterfaceAlternateSetting(
|
|
||||||
interface_number, alternate_setting,
|
|
||||||
base::Bind(&HandlePassFailDeviceOperation,
|
|
||||||
base::Passed(&scoped_callbacks), kSetInterfaceFailed));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::clearHalt(
|
|
||||||
uint8_t endpoint_number,
|
|
||||||
blink::WebUSBDeviceClearHaltCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (device_)
|
|
||||||
device_->ClearHalt(
|
|
||||||
endpoint_number,
|
|
||||||
base::Bind(&HandlePassFailDeviceOperation,
|
|
||||||
base::Passed(&scoped_callbacks), kClearHaltFailed));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::controlTransfer(
|
|
||||||
const blink::WebUSBDevice::ControlTransferParameters& parameters,
|
|
||||||
uint8_t* data,
|
|
||||||
size_t data_size,
|
|
||||||
unsigned int timeout,
|
|
||||||
blink::WebUSBDeviceTransferCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (!device_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
device::usb::ControlTransferParamsPtr params =
|
|
||||||
device::usb::ControlTransferParams::From(parameters);
|
|
||||||
switch (parameters.direction) {
|
|
||||||
case WebUSBDevice::TransferDirection::In:
|
|
||||||
device_->ControlTransferIn(
|
|
||||||
std::move(params), data_size, timeout,
|
|
||||||
base::Bind(&OnTransferIn, base::Passed(&scoped_callbacks)));
|
|
||||||
break;
|
|
||||||
case WebUSBDevice::TransferDirection::Out: {
|
|
||||||
std::vector<uint8_t> bytes;
|
|
||||||
if (data)
|
|
||||||
bytes.assign(data, data + data_size);
|
|
||||||
mojo::Array<uint8_t> mojo_bytes;
|
|
||||||
mojo_bytes.Swap(&bytes);
|
|
||||||
device_->ControlTransferOut(
|
|
||||||
std::move(params), std::move(mojo_bytes), timeout,
|
|
||||||
base::Bind(&OnTransferOut, base::Passed(&scoped_callbacks),
|
|
||||||
data_size));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::transfer(
|
|
||||||
blink::WebUSBDevice::TransferDirection direction,
|
|
||||||
uint8_t endpoint_number,
|
|
||||||
uint8_t* data,
|
|
||||||
size_t data_size,
|
|
||||||
unsigned int timeout,
|
|
||||||
blink::WebUSBDeviceTransferCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (!device_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (direction) {
|
|
||||||
case WebUSBDevice::TransferDirection::In:
|
|
||||||
device_->GenericTransferIn(
|
|
||||||
endpoint_number, data_size, timeout,
|
|
||||||
base::Bind(&OnTransferIn, base::Passed(&scoped_callbacks)));
|
|
||||||
break;
|
|
||||||
case WebUSBDevice::TransferDirection::Out: {
|
|
||||||
std::vector<uint8_t> bytes;
|
|
||||||
if (data)
|
|
||||||
bytes.assign(data, data + data_size);
|
|
||||||
mojo::Array<uint8_t> mojo_bytes;
|
|
||||||
mojo_bytes.Swap(&bytes);
|
|
||||||
device_->GenericTransferOut(
|
|
||||||
endpoint_number, std::move(mojo_bytes), timeout,
|
|
||||||
base::Bind(&OnTransferOut, base::Passed(&scoped_callbacks),
|
|
||||||
data_size));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::isochronousTransfer(
|
|
||||||
blink::WebUSBDevice::TransferDirection direction,
|
|
||||||
uint8_t endpoint_number,
|
|
||||||
uint8_t* data,
|
|
||||||
size_t data_size,
|
|
||||||
blink::WebVector<uint32_t> packet_lengths,
|
|
||||||
unsigned int timeout,
|
|
||||||
blink::WebUSBDeviceTransferCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (!device_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (direction) {
|
|
||||||
case WebUSBDevice::TransferDirection::In:
|
|
||||||
device_->IsochronousTransferIn(
|
|
||||||
endpoint_number, mojo::Array<uint32_t>::From(packet_lengths), timeout,
|
|
||||||
base::Bind(&OnIsochronousTransferIn,
|
|
||||||
base::Passed(&scoped_callbacks)));
|
|
||||||
break;
|
|
||||||
case WebUSBDevice::TransferDirection::Out: {
|
|
||||||
std::vector<uint8_t> bytes;
|
|
||||||
if (data)
|
|
||||||
bytes.assign(data, data + data_size);
|
|
||||||
mojo::Array<uint8_t> mojo_bytes;
|
|
||||||
mojo_bytes.Swap(&bytes);
|
|
||||||
device_->IsochronousTransferOut(
|
|
||||||
endpoint_number, std::move(mojo_bytes),
|
|
||||||
mojo::Array<uint32_t>::From(packet_lengths), timeout,
|
|
||||||
base::Bind(&OnIsochronousTransferOut,
|
|
||||||
base::Passed(&scoped_callbacks)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebUSBDeviceImpl::reset(blink::WebUSBDeviceResetCallbacks* callbacks) {
|
|
||||||
auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
|
|
||||||
if (device_)
|
|
||||||
device_->Reset(base::Bind(&HandlePassFailDeviceOperation,
|
|
||||||
base::Passed(&scoped_callbacks),
|
|
||||||
kDeviceResetFailed));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace content
|
|
@ -1,86 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef CONTENT_RENDERER_USB_WEB_USB_DEVICE_IMPL_H_
|
|
||||||
#define CONTENT_RENDERER_USB_WEB_USB_DEVICE_IMPL_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "base/macros.h"
|
|
||||||
#include "base/memory/weak_ptr.h"
|
|
||||||
#include "device/usb/public/interfaces/device.mojom.h"
|
|
||||||
#include "device/usb/public/interfaces/device_manager.mojom.h"
|
|
||||||
#include "services/shell/public/interfaces/interface_provider.mojom.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBDevice.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
|
||||||
#include "third_party/WebKit/public/platform/modules/webusb/WebUSBError.h"
|
|
||||||
|
|
||||||
namespace mojo {
|
|
||||||
class Shell;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace content {
|
|
||||||
|
|
||||||
class WebUSBDeviceImpl : public blink::WebUSBDevice {
|
|
||||||
public:
|
|
||||||
WebUSBDeviceImpl(device::usb::DevicePtr device,
|
|
||||||
const blink::WebUSBDeviceInfo& device_info);
|
|
||||||
~WebUSBDeviceImpl() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// blink::WebUSBDevice implementation:
|
|
||||||
const blink::WebUSBDeviceInfo& info() const override;
|
|
||||||
void open(blink::WebUSBDeviceOpenCallbacks* callbacks) override;
|
|
||||||
void close(blink::WebUSBDeviceCloseCallbacks* callbacks) override;
|
|
||||||
void setConfiguration(
|
|
||||||
uint8_t configuration_value,
|
|
||||||
blink::WebUSBDeviceSetConfigurationCallbacks* callbacks) override;
|
|
||||||
void claimInterface(
|
|
||||||
uint8_t interface_number,
|
|
||||||
blink::WebUSBDeviceClaimInterfaceCallbacks* callbacks) override;
|
|
||||||
void releaseInterface(
|
|
||||||
uint8_t interface_number,
|
|
||||||
blink::WebUSBDeviceReleaseInterfaceCallbacks* callbacks) override;
|
|
||||||
void setInterface(uint8_t interface_number,
|
|
||||||
uint8_t alternate_setting,
|
|
||||||
blink::WebUSBDeviceSetInterfaceAlternateSettingCallbacks*
|
|
||||||
callbacks) override;
|
|
||||||
void clearHalt(uint8_t endpoint_number,
|
|
||||||
blink::WebUSBDeviceClearHaltCallbacks* callbacks) override;
|
|
||||||
void controlTransfer(
|
|
||||||
const blink::WebUSBDevice::ControlTransferParameters& parameters,
|
|
||||||
uint8_t* data,
|
|
||||||
size_t data_size,
|
|
||||||
unsigned int timeout,
|
|
||||||
blink::WebUSBDeviceTransferCallbacks* callbacks) override;
|
|
||||||
void transfer(blink::WebUSBDevice::TransferDirection direction,
|
|
||||||
uint8_t endpoint_number,
|
|
||||||
uint8_t* data,
|
|
||||||
size_t data_size,
|
|
||||||
unsigned int timeout,
|
|
||||||
blink::WebUSBDeviceTransferCallbacks* callbacks) override;
|
|
||||||
void isochronousTransfer(
|
|
||||||
blink::WebUSBDevice::TransferDirection direction,
|
|
||||||
uint8_t endpoint_number,
|
|
||||||
uint8_t* data,
|
|
||||||
size_t data_size,
|
|
||||||
blink::WebVector<uint32_t> packet_lengths,
|
|
||||||
unsigned int timeout,
|
|
||||||
blink::WebUSBDeviceTransferCallbacks* callbacks) override;
|
|
||||||
void reset(blink::WebUSBDeviceResetCallbacks* callbacks) override;
|
|
||||||
|
|
||||||
device::usb::DevicePtr device_;
|
|
||||||
blink::WebUSBDeviceInfo device_info_;
|
|
||||||
|
|
||||||
base::WeakPtrFactory<WebUSBDeviceImpl> weak_factory_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(WebUSBDeviceImpl);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace content
|
|
||||||
|
|
||||||
#endif // CONTENT_RENDERER_USB_WEB_USB_DEVICE_IMPL_H_
|
|
@ -4,10 +4,12 @@
|
|||||||
|
|
||||||
import("//mojo/public/tools/bindings/mojom.gni")
|
import("//mojo/public/tools/bindings/mojom.gni")
|
||||||
|
|
||||||
|
mojom_files = [
|
||||||
|
"chooser_service.mojom",
|
||||||
|
"device.mojom",
|
||||||
|
"device_manager.mojom",
|
||||||
|
]
|
||||||
|
|
||||||
mojom("interfaces") {
|
mojom("interfaces") {
|
||||||
sources = [
|
sources = mojom_files
|
||||||
"chooser_service.mojom",
|
|
||||||
"device.mojom",
|
|
||||||
"device_manager.mojom",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,11 @@
|
|||||||
{
|
{
|
||||||
'variables': {
|
'variables': {
|
||||||
'chromium_code': 1,
|
'chromium_code': 1,
|
||||||
|
'mojom_files': [
|
||||||
|
'public/interfaces/chooser_service.mojom',
|
||||||
|
'public/interfaces/device.mojom',
|
||||||
|
'public/interfaces/device_manager.mojom',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
'targets': [
|
'targets': [
|
||||||
{
|
{
|
||||||
@ -141,11 +146,19 @@
|
|||||||
{
|
{
|
||||||
'target_name': 'device_usb_mojo_bindings',
|
'target_name': 'device_usb_mojo_bindings',
|
||||||
'type': 'static_library',
|
'type': 'static_library',
|
||||||
'sources': [
|
'sources': [ '<@(mojom_files)' ],
|
||||||
'public/interfaces/chooser_service.mojom',
|
'includes': [
|
||||||
'public/interfaces/device.mojom',
|
'../../mojo/mojom_bindings_generator.gypi',
|
||||||
'public/interfaces/device_manager.mojom',
|
|
||||||
],
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'target_name': 'device_usb_mojo_bindings_for_blink',
|
||||||
|
'type': 'static_library',
|
||||||
|
'sources': [ '<@(mojom_files)' ],
|
||||||
|
'variables': {
|
||||||
|
'mojom_variant': 'wtf',
|
||||||
|
'for_blink': 'true',
|
||||||
|
},
|
||||||
'includes': [
|
'includes': [
|
||||||
'../../mojo/mojom_bindings_generator.gypi',
|
'../../mojo/mojom_bindings_generator.gypi',
|
||||||
],
|
],
|
||||||
|
@ -244,7 +244,6 @@ usb_test(usb => {
|
|||||||
});
|
});
|
||||||
}, 'a non-existent interface cannot be claimed or released');
|
}, 'a non-existent interface cannot be claimed or released');
|
||||||
|
|
||||||
|
|
||||||
usb_test(usb => {
|
usb_test(usb => {
|
||||||
usb.mockDeviceManager.addMockDevice(usb.fakeDevices[0]);
|
usb.mockDeviceManager.addMockDevice(usb.fakeDevices[0]);
|
||||||
return navigator.usb.getDevices().then(devices => {
|
return navigator.usb.getDevices().then(devices => {
|
||||||
|
1
third_party/WebKit/Source/modules/BUILD.gn
vendored
1
third_party/WebKit/Source/modules/BUILD.gn
vendored
@ -47,6 +47,7 @@ component("modules") {
|
|||||||
deps = [
|
deps = [
|
||||||
":make_modules_generated",
|
":make_modules_generated",
|
||||||
"//device/battery:mojo_bindings",
|
"//device/battery:mojo_bindings",
|
||||||
|
"//device/usb/public/interfaces:interfaces_wtf",
|
||||||
"//mojo/public/c/system:for_component",
|
"//mojo/public/c/system:for_component",
|
||||||
"//third_party/WebKit/Source/core",
|
"//third_party/WebKit/Source/core",
|
||||||
"//third_party/WebKit/public:mojo_bindings_wtf",
|
"//third_party/WebKit/public:mojo_bindings_wtf",
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
'target_name': 'modules',
|
'target_name': 'modules',
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'<(DEPTH)/device/battery/battery.gyp:device_battery_mojo_bindings',
|
'<(DEPTH)/device/battery/battery.gyp:device_battery_mojo_bindings',
|
||||||
|
'<(DEPTH)/device/usb/usb.gyp:device_usb_mojo_bindings_for_blink',
|
||||||
'<(DEPTH)/mojo/mojo_edk.gyp:mojo_system_impl',
|
'<(DEPTH)/mojo/mojo_edk.gyp:mojo_system_impl',
|
||||||
'<(DEPTH)/mojo/mojo_public.gyp:mojo_cpp_bindings',
|
'<(DEPTH)/mojo/mojo_public.gyp:mojo_cpp_bindings',
|
||||||
'<(DEPTH)/third_party/icu/icu.gyp:icui18n',
|
'<(DEPTH)/third_party/icu/icu.gyp:icui18n',
|
||||||
|
@ -1907,14 +1907,10 @@
|
|||||||
'webusb/USBConfiguration.h',
|
'webusb/USBConfiguration.h',
|
||||||
'webusb/USBConnectionEvent.cpp',
|
'webusb/USBConnectionEvent.cpp',
|
||||||
'webusb/USBConnectionEvent.h',
|
'webusb/USBConnectionEvent.h',
|
||||||
'webusb/USBController.cpp',
|
|
||||||
'webusb/USBController.h',
|
|
||||||
'webusb/USBDevice.cpp',
|
'webusb/USBDevice.cpp',
|
||||||
'webusb/USBDevice.h',
|
'webusb/USBDevice.h',
|
||||||
'webusb/USBEndpoint.cpp',
|
'webusb/USBEndpoint.cpp',
|
||||||
'webusb/USBEndpoint.h',
|
'webusb/USBEndpoint.h',
|
||||||
'webusb/USBError.cpp',
|
|
||||||
'webusb/USBError.h',
|
|
||||||
'webusb/USBInTransferResult.h',
|
'webusb/USBInTransferResult.h',
|
||||||
'webusb/USBInterface.cpp',
|
'webusb/USBInterface.cpp',
|
||||||
'webusb/USBInterface.h',
|
'webusb/USBInterface.h',
|
||||||
|
4
third_party/WebKit/Source/modules/webusb/DEPS
vendored
Normal file
4
third_party/WebKit/Source/modules/webusb/DEPS
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
include_rules = [
|
||||||
|
"+device/usb/public/interfaces",
|
||||||
|
"+mojo/public/cpp/bindings",
|
||||||
|
]
|
217
third_party/WebKit/Source/modules/webusb/USB.cpp
vendored
217
third_party/WebKit/Source/modules/webusb/USB.cpp
vendored
@ -4,133 +4,138 @@
|
|||||||
|
|
||||||
#include "modules/webusb/USB.h"
|
#include "modules/webusb/USB.h"
|
||||||
|
|
||||||
#include "bindings/core/v8/CallbackPromiseAdapter.h"
|
|
||||||
#include "bindings/core/v8/ScriptPromise.h"
|
#include "bindings/core/v8/ScriptPromise.h"
|
||||||
#include "bindings/core/v8/ScriptPromiseResolver.h"
|
#include "bindings/core/v8/ScriptPromiseResolver.h"
|
||||||
#include "core/dom/DOMException.h"
|
#include "core/dom/DOMException.h"
|
||||||
#include "core/dom/Document.h"
|
#include "core/dom/Document.h"
|
||||||
#include "core/dom/ExceptionCode.h"
|
#include "core/dom/ExceptionCode.h"
|
||||||
|
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||||
#include "modules/EventTargetModules.h"
|
#include "modules/EventTargetModules.h"
|
||||||
#include "modules/webusb/USBConnectionEvent.h"
|
#include "modules/webusb/USBConnectionEvent.h"
|
||||||
#include "modules/webusb/USBController.h"
|
|
||||||
#include "modules/webusb/USBDevice.h"
|
#include "modules/webusb/USBDevice.h"
|
||||||
#include "modules/webusb/USBDeviceFilter.h"
|
#include "modules/webusb/USBDeviceFilter.h"
|
||||||
#include "modules/webusb/USBDeviceRequestOptions.h"
|
#include "modules/webusb/USBDeviceRequestOptions.h"
|
||||||
#include "modules/webusb/USBError.h"
|
#include "platform/MojoHelper.h"
|
||||||
#include "platform/UserGestureIndicator.h"
|
#include "platform/UserGestureIndicator.h"
|
||||||
#include "public/platform/Platform.h"
|
#include "public/platform/ServiceRegistry.h"
|
||||||
#include "public/platform/WebVector.h"
|
#include "wtf/Functional.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBClient.h"
|
|
||||||
#include "public/platform/modules/webusb/WebUSBDeviceFilter.h"
|
namespace usb = device::usb::wtf;
|
||||||
#include "public/platform/modules/webusb/WebUSBDeviceRequestOptions.h"
|
|
||||||
#include "public/platform/modules/webusb/WebUSBError.h"
|
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void convertDeviceFilter(const USBDeviceFilter& filter, WebUSBDeviceFilter* webFilter)
|
const char kNoServiceError[] = "USB service unavailable.";
|
||||||
|
|
||||||
|
usb::DeviceFilterPtr convertDeviceFilter(const USBDeviceFilter& filter)
|
||||||
{
|
{
|
||||||
webFilter->hasVendorID = filter.hasVendorId();
|
auto mojoFilter = usb::DeviceFilter::New();
|
||||||
if (filter.hasVendorId())
|
mojoFilter->has_vendor_id = filter.hasVendorId();
|
||||||
webFilter->vendorID = filter.vendorId();
|
if (mojoFilter->has_vendor_id)
|
||||||
webFilter->hasProductID = filter.hasProductId();
|
mojoFilter->vendor_id = filter.vendorId();
|
||||||
if (filter.hasProductId())
|
mojoFilter->has_product_id = filter.hasProductId();
|
||||||
webFilter->productID = filter.productId();
|
if (mojoFilter->has_product_id)
|
||||||
webFilter->hasClassCode = filter.hasClassCode();
|
mojoFilter->product_id = filter.productId();
|
||||||
if (filter.hasClassCode())
|
mojoFilter->has_class_code = filter.hasClassCode();
|
||||||
webFilter->classCode = filter.classCode();
|
if (mojoFilter->has_class_code)
|
||||||
webFilter->hasSubclassCode = filter.hasSubclassCode();
|
mojoFilter->class_code = filter.classCode();
|
||||||
if (filter.hasSubclassCode())
|
mojoFilter->has_subclass_code = filter.hasSubclassCode();
|
||||||
webFilter->subclassCode = filter.subclassCode();
|
if (mojoFilter->has_subclass_code)
|
||||||
webFilter->hasProtocolCode = filter.hasProtocolCode();
|
mojoFilter->subclass_code = filter.subclassCode();
|
||||||
if (filter.hasProtocolCode())
|
mojoFilter->has_protocol_code = filter.hasProtocolCode();
|
||||||
webFilter->protocolCode = filter.protocolCode();
|
if (mojoFilter->has_protocol_code)
|
||||||
|
mojoFilter->protocol_code = filter.protocolCode();
|
||||||
|
return mojoFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void convertDeviceRequestOptions(const USBDeviceRequestOptions& options, WebUSBDeviceRequestOptions* webOptions)
|
bool isActive(ScriptPromiseResolver* resolver)
|
||||||
{
|
{
|
||||||
DCHECK(options.hasFilters());
|
ExecutionContext* context = resolver->getExecutionContext();
|
||||||
webOptions->filters = WebVector<WebUSBDeviceFilter>(options.filters().size());
|
return context && !context->activeDOMObjectsAreStopped();
|
||||||
for (size_t i = 0; i < options.filters().size(); ++i) {
|
|
||||||
convertDeviceFilter(options.filters()[i], &webOptions->filters[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allows using a CallbackPromiseAdapter with a WebVector to resolve the
|
|
||||||
// getDevices() promise with a HeapVector owning USBDevices.
|
|
||||||
class DeviceArray {
|
|
||||||
STATIC_ONLY(DeviceArray);
|
|
||||||
public:
|
|
||||||
using WebType = OwnPtr<WebVector<WebUSBDevice*>>;
|
|
||||||
|
|
||||||
static HeapVector<Member<USBDevice>> take(ScriptPromiseResolver* resolver, PassOwnPtr<WebVector<WebUSBDevice*>> webDevices)
|
|
||||||
{
|
|
||||||
HeapVector<Member<USBDevice>> devices;
|
|
||||||
for (const auto webDevice : *webDevices)
|
|
||||||
devices.append(USBDevice::create(adoptPtr(webDevice), resolver->getExecutionContext()));
|
|
||||||
return devices;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
USB::USB(LocalFrame& frame)
|
USB::USB(LocalFrame& frame)
|
||||||
: ContextLifecycleObserver(frame.document())
|
: ContextLifecycleObserver(frame.document())
|
||||||
, m_client(USBController::from(frame).client())
|
|
||||||
{
|
{
|
||||||
ThreadState::current()->registerPreFinalizer(this);
|
frame.serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_deviceManager));
|
||||||
if (m_client)
|
m_deviceManager.set_connection_error_handler([this]() {
|
||||||
m_client->addObserver(this);
|
m_deviceManager.reset();
|
||||||
|
for (ScriptPromiseResolver* resolver : m_deviceManagerRequests) {
|
||||||
|
if (isActive(resolver))
|
||||||
|
resolver->reject(DOMException::create(NotFoundError, kNoServiceError));
|
||||||
|
}
|
||||||
|
m_deviceManagerRequests.clear();
|
||||||
|
});
|
||||||
|
// Set up two sequential calls to GetDeviceChanges to avoid latency.
|
||||||
|
m_deviceManager->GetDeviceChanges(createBaseCallback(bind<usb::DeviceChangeNotificationPtr>(&USB::onDeviceChanges, this)));
|
||||||
|
m_deviceManager->GetDeviceChanges(createBaseCallback(bind<usb::DeviceChangeNotificationPtr>(&USB::onDeviceChanges, this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
USB::~USB()
|
USB::~USB()
|
||||||
{
|
{
|
||||||
}
|
DCHECK(!m_deviceManager);
|
||||||
|
DCHECK(m_deviceManagerRequests.isEmpty());
|
||||||
void USB::dispose()
|
DCHECK(!m_chooserService);
|
||||||
{
|
DCHECK(m_chooserServiceRequests.isEmpty());
|
||||||
// Promptly clears a raw reference from content/ to an on-heap object
|
|
||||||
// so that content/ doesn't access it in a lazy sweeping phase.
|
|
||||||
if (m_client)
|
|
||||||
m_client->removeObserver(this);
|
|
||||||
m_client = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptPromise USB::getDevices(ScriptState* scriptState)
|
ScriptPromise USB::getDevices(ScriptState* scriptState)
|
||||||
{
|
{
|
||||||
if (!m_client)
|
|
||||||
return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError));
|
|
||||||
|
|
||||||
String errorMessage;
|
|
||||||
if (!scriptState->getExecutionContext()->isSecureContext(errorMessage))
|
|
||||||
return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(SecurityError, errorMessage));
|
|
||||||
|
|
||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
m_client->getDevices(new CallbackPromiseAdapter<DeviceArray, USBError>(resolver));
|
if (!m_deviceManager) {
|
||||||
|
resolver->reject(DOMException::create(NotSupportedError));
|
||||||
|
} else {
|
||||||
|
String errorMessage;
|
||||||
|
if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) {
|
||||||
|
resolver->reject(DOMException::create(SecurityError, errorMessage));
|
||||||
|
} else {
|
||||||
|
m_deviceManagerRequests.add(resolver);
|
||||||
|
m_deviceManager->GetDevices(nullptr, createBaseCallback(bind<mojo::WTFArray<usb::DeviceInfoPtr>>(&USB::onGetDevices, this, resolver)));
|
||||||
|
}
|
||||||
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptPromise USB::requestDevice(ScriptState* scriptState, const USBDeviceRequestOptions& options)
|
ScriptPromise USB::requestDevice(ScriptState* scriptState, const USBDeviceRequestOptions& options)
|
||||||
{
|
{
|
||||||
if (!m_client)
|
|
||||||
return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError));
|
|
||||||
|
|
||||||
String errorMessage;
|
|
||||||
if (!scriptState->getExecutionContext()->isSecureContext(errorMessage))
|
|
||||||
return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(SecurityError, errorMessage));
|
|
||||||
|
|
||||||
if (!UserGestureIndicator::consumeUserGesture())
|
|
||||||
return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(SecurityError, "Must be handling a user gesture to show a permission request."));
|
|
||||||
|
|
||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
|
|
||||||
WebUSBDeviceRequestOptions webOptions;
|
if (!m_chooserService) {
|
||||||
convertDeviceRequestOptions(options, &webOptions);
|
LocalFrame* frame = getExecutionContext() ? toDocument(getExecutionContext())->frame() : nullptr;
|
||||||
m_client->requestDevice(webOptions, new CallbackPromiseAdapter<USBDevice, USBError>(resolver));
|
if (!frame) {
|
||||||
|
resolver->reject(DOMException::create(NotSupportedError));
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
frame->serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_chooserService));
|
||||||
|
m_chooserService.set_connection_error_handler([this]() {
|
||||||
|
m_chooserService.reset();
|
||||||
|
for (ScriptPromiseResolver* resolver : m_chooserServiceRequests) {
|
||||||
|
if (isActive(resolver))
|
||||||
|
resolver->reject(DOMException::create(NotFoundError, kNoServiceError));
|
||||||
|
}
|
||||||
|
m_chooserServiceRequests.clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
String errorMessage;
|
||||||
|
if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) {
|
||||||
|
resolver->reject(DOMException::create(SecurityError, errorMessage));
|
||||||
|
} else if (!UserGestureIndicator::consumeUserGesture()) {
|
||||||
|
resolver->reject(DOMException::create(SecurityError, "Must be handling a user gesture to show a permission request."));
|
||||||
|
} else {
|
||||||
|
Vector<usb::DeviceFilterPtr> filters;
|
||||||
|
if (options.hasFilters()) {
|
||||||
|
filters.reserveCapacity(options.filters().size());
|
||||||
|
for (const auto& filter : options.filters())
|
||||||
|
filters.append(convertDeviceFilter(filter));
|
||||||
|
}
|
||||||
|
m_chooserServiceRequests.add(resolver);
|
||||||
|
m_chooserService->GetPermission(std::move(filters), createBaseCallback(bind<usb::DeviceInfoPtr>(&USB::onGetPermission, this, resolver)));
|
||||||
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,25 +151,59 @@ const AtomicString& USB::interfaceName() const
|
|||||||
|
|
||||||
void USB::contextDestroyed()
|
void USB::contextDestroyed()
|
||||||
{
|
{
|
||||||
if (m_client)
|
m_deviceManager.reset();
|
||||||
m_client->removeObserver(this);
|
m_deviceManagerRequests.clear();
|
||||||
m_client = nullptr;
|
m_chooserService.reset();
|
||||||
|
m_chooserServiceRequests.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void USB::onDeviceConnected(std::unique_ptr<WebUSBDevice> device)
|
void USB::onGetDevices(ScriptPromiseResolver* resolver, mojo::WTFArray<usb::DeviceInfoPtr> deviceInfos)
|
||||||
{
|
{
|
||||||
dispatchEvent(USBConnectionEvent::create(EventTypeNames::connect, USBDevice::create(adoptPtr(device.release()), getExecutionContext())));
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
HeapVector<Member<USBDevice>> devices;
|
||||||
|
for (auto& deviceInfo : deviceInfos.PassStorage()) {
|
||||||
|
usb::DevicePtr device;
|
||||||
|
m_deviceManager->GetDevice(deviceInfo->guid, mojo::GetProxy(&device));
|
||||||
|
devices.append(USBDevice::create(std::move(deviceInfo), std::move(device), resolver->getExecutionContext()));
|
||||||
|
}
|
||||||
|
resolver->resolve(devices);
|
||||||
|
m_deviceManagerRequests.remove(resolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USB::onDeviceDisconnected(std::unique_ptr<WebUSBDevice> device)
|
void USB::onGetPermission(ScriptPromiseResolver* resolver, usb::DeviceInfoPtr deviceInfo)
|
||||||
{
|
{
|
||||||
dispatchEvent(USBConnectionEvent::create(EventTypeNames::disconnect, USBDevice::create(adoptPtr(device.release()), getExecutionContext())));
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (deviceInfo) {
|
||||||
|
usb::DevicePtr device;
|
||||||
|
m_deviceManager->GetDevice(deviceInfo->guid, mojo::GetProxy(&device));
|
||||||
|
resolver->resolve(USBDevice::create(std::move(deviceInfo), std::move(device), resolver->getExecutionContext()));
|
||||||
|
} else {
|
||||||
|
resolver->reject(DOMException::create(NotFoundError, "No device selected."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void USB::onDeviceChanges(usb::DeviceChangeNotificationPtr notification)
|
||||||
|
{
|
||||||
|
m_deviceManager->GetDeviceChanges(createBaseCallback(bind<usb::DeviceChangeNotificationPtr>(&USB::onDeviceChanges, this)));
|
||||||
|
for (auto& deviceInfo : notification->devices_added.PassStorage()) {
|
||||||
|
usb::DevicePtr device;
|
||||||
|
m_deviceManager->GetDevice(deviceInfo->guid, mojo::GetProxy(&device));
|
||||||
|
dispatchEvent(USBConnectionEvent::create(EventTypeNames::connect, USBDevice::create(std::move(deviceInfo), std::move(device), getExecutionContext())));
|
||||||
|
}
|
||||||
|
for (auto& deviceInfo : notification->devices_removed.PassStorage())
|
||||||
|
dispatchEvent(USBConnectionEvent::create(EventTypeNames::disconnect, USBDevice::create(std::move(deviceInfo), nullptr, getExecutionContext())));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_TRACE(USB)
|
DEFINE_TRACE(USB)
|
||||||
{
|
{
|
||||||
EventTargetWithInlineData::trace(visitor);
|
EventTargetWithInlineData::trace(visitor);
|
||||||
ContextLifecycleObserver::trace(visitor);
|
ContextLifecycleObserver::trace(visitor);
|
||||||
|
visitor->trace(m_deviceManagerRequests);
|
||||||
|
visitor->trace(m_chooserServiceRequests);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blink
|
} // namespace blink
|
||||||
|
25
third_party/WebKit/Source/modules/webusb/USB.h
vendored
25
third_party/WebKit/Source/modules/webusb/USB.h
vendored
@ -9,30 +9,29 @@
|
|||||||
#include "bindings/core/v8/ScriptWrappable.h"
|
#include "bindings/core/v8/ScriptWrappable.h"
|
||||||
#include "core/dom/ContextLifecycleObserver.h"
|
#include "core/dom/ContextLifecycleObserver.h"
|
||||||
#include "core/events/EventTarget.h"
|
#include "core/events/EventTarget.h"
|
||||||
|
#include "device/usb/public/interfaces/chooser_service.mojom-wtf.h"
|
||||||
|
#include "device/usb/public/interfaces/device_manager.mojom-wtf.h"
|
||||||
#include "platform/heap/Handle.h"
|
#include "platform/heap/Handle.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBClient.h"
|
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
|
||||||
class LocalFrame;
|
class LocalFrame;
|
||||||
|
class ScopedScriptPromiseResolver;
|
||||||
class ScriptState;
|
class ScriptState;
|
||||||
class USBDeviceRequestOptions;
|
class USBDeviceRequestOptions;
|
||||||
class WebUSBDevice;
|
|
||||||
|
|
||||||
class USB final
|
class USB final
|
||||||
: public EventTargetWithInlineData
|
: public EventTargetWithInlineData
|
||||||
, public ContextLifecycleObserver
|
, public ContextLifecycleObserver {
|
||||||
, public WebUSBClient::Observer {
|
|
||||||
DEFINE_WRAPPERTYPEINFO();
|
DEFINE_WRAPPERTYPEINFO();
|
||||||
USING_GARBAGE_COLLECTED_MIXIN(USB);
|
USING_GARBAGE_COLLECTED_MIXIN(USB);
|
||||||
USING_PRE_FINALIZER(USB, dispose);
|
|
||||||
public:
|
public:
|
||||||
static USB* create(LocalFrame& frame)
|
static USB* create(LocalFrame& frame)
|
||||||
{
|
{
|
||||||
return new USB(frame);
|
return new USB(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
~USB() override;
|
virtual ~USB();
|
||||||
|
|
||||||
// USB.idl
|
// USB.idl
|
||||||
ScriptPromise getDevices(ScriptState*);
|
ScriptPromise getDevices(ScriptState*);
|
||||||
@ -47,17 +46,21 @@ public:
|
|||||||
// ContextLifecycleObserver overrides.
|
// ContextLifecycleObserver overrides.
|
||||||
void contextDestroyed() override;
|
void contextDestroyed() override;
|
||||||
|
|
||||||
// WebUSBClient::Observer overrides.
|
device::usb::wtf::DeviceManager* deviceManager() const { return m_deviceManager.get(); }
|
||||||
void onDeviceConnected(std::unique_ptr<WebUSBDevice>) override;
|
|
||||||
void onDeviceDisconnected(std::unique_ptr<WebUSBDevice>) override;
|
void onGetDevices(ScriptPromiseResolver*, mojo::WTFArray<device::usb::wtf::DeviceInfoPtr>);
|
||||||
|
void onGetPermission(ScriptPromiseResolver*, device::usb::wtf::DeviceInfoPtr);
|
||||||
|
void onDeviceChanges(device::usb::wtf::DeviceChangeNotificationPtr);
|
||||||
|
|
||||||
DECLARE_VIRTUAL_TRACE();
|
DECLARE_VIRTUAL_TRACE();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit USB(LocalFrame& frame);
|
explicit USB(LocalFrame& frame);
|
||||||
void dispose();
|
|
||||||
|
|
||||||
WebUSBClient* m_client;
|
device::usb::wtf::DeviceManagerPtr m_deviceManager;
|
||||||
|
HeapHashSet<Member<ScriptPromiseResolver>> m_deviceManagerRequests;
|
||||||
|
device::usb::wtf::ChooserServicePtr m_chooserService;
|
||||||
|
HeapHashSet<Member<ScriptPromiseResolver>> m_chooserServiceRequests;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blink
|
} // namespace blink
|
||||||
|
@ -17,8 +17,9 @@ USBAlternateInterface* USBAlternateInterface::create(const USBInterface* interfa
|
|||||||
|
|
||||||
USBAlternateInterface* USBAlternateInterface::create(const USBInterface* interface, size_t alternateSetting, ExceptionState& exceptionState)
|
USBAlternateInterface* USBAlternateInterface::create(const USBInterface* interface, size_t alternateSetting, ExceptionState& exceptionState)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < interface->info().alternates.size(); ++i) {
|
const auto& alternates = interface->info().alternates;
|
||||||
if (interface->info().alternates[i].alternateSetting == alternateSetting)
|
for (size_t i = 0; i < alternates.size(); ++i) {
|
||||||
|
if (alternates[i]->alternate_setting == alternateSetting)
|
||||||
return USBAlternateInterface::create(interface, i);
|
return USBAlternateInterface::create(interface, i);
|
||||||
}
|
}
|
||||||
exceptionState.throwRangeError("Invalid alternate setting.");
|
exceptionState.throwRangeError("Invalid alternate setting.");
|
||||||
@ -33,36 +34,11 @@ USBAlternateInterface::USBAlternateInterface(const USBInterface* interface, size
|
|||||||
ASSERT(m_alternateIndex < m_interface->info().alternates.size());
|
ASSERT(m_alternateIndex < m_interface->info().alternates.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
const WebUSBDeviceInfo::AlternateInterface& USBAlternateInterface::info() const
|
const device::usb::wtf::AlternateInterfaceInfo& USBAlternateInterface::info() const
|
||||||
{
|
{
|
||||||
const WebUSBDeviceInfo::Interface& interfaceInfo = m_interface->info();
|
const device::usb::wtf::InterfaceInfo& interfaceInfo = m_interface->info();
|
||||||
ASSERT(m_alternateIndex < interfaceInfo.alternates.size());
|
ASSERT(m_alternateIndex < interfaceInfo.alternates.size());
|
||||||
return interfaceInfo.alternates[m_alternateIndex];
|
return *interfaceInfo.alternates[m_alternateIndex];
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBAlternateInterface::alternateSetting() const
|
|
||||||
{
|
|
||||||
return info().alternateSetting;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBAlternateInterface::interfaceClass() const
|
|
||||||
{
|
|
||||||
return info().classCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBAlternateInterface::interfaceSubclass() const
|
|
||||||
{
|
|
||||||
return info().subclassCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBAlternateInterface::interfaceProtocol() const
|
|
||||||
{
|
|
||||||
return info().protocolCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
String USBAlternateInterface::interfaceName() const
|
|
||||||
{
|
|
||||||
return info().interfaceName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapVector<Member<USBEndpoint>> USBAlternateInterface::endpoints() const
|
HeapVector<Member<USBEndpoint>> USBAlternateInterface::endpoints() const
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#define USBAlternateInterface_h
|
#define USBAlternateInterface_h
|
||||||
|
|
||||||
#include "bindings/core/v8/ScriptWrappable.h"
|
#include "bindings/core/v8/ScriptWrappable.h"
|
||||||
|
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||||
#include "platform/heap/Heap.h"
|
#include "platform/heap/Heap.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
|
||||||
@ -25,13 +25,13 @@ public:
|
|||||||
|
|
||||||
USBAlternateInterface(const USBInterface*, size_t alternateIndex);
|
USBAlternateInterface(const USBInterface*, size_t alternateIndex);
|
||||||
|
|
||||||
const WebUSBDeviceInfo::AlternateInterface& info() const;
|
const device::usb::wtf::AlternateInterfaceInfo& info() const;
|
||||||
|
|
||||||
uint8_t alternateSetting() const;
|
uint8_t alternateSetting() const { return info().alternate_setting; }
|
||||||
uint8_t interfaceClass() const;
|
uint8_t interfaceClass() const { return info().class_code; }
|
||||||
uint8_t interfaceSubclass() const;
|
uint8_t interfaceSubclass() const { return info().subclass_code; }
|
||||||
uint8_t interfaceProtocol() const;
|
uint8_t interfaceProtocol() const { return info().protocol_code; }
|
||||||
String interfaceName() const;
|
String interfaceName() const { return info().interface_name; }
|
||||||
HeapVector<Member<USBEndpoint>> endpoints() const;
|
HeapVector<Member<USBEndpoint>> endpoints() const;
|
||||||
|
|
||||||
DECLARE_TRACE();
|
DECLARE_TRACE();
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "modules/webusb/USBConfiguration.h"
|
#include "modules/webusb/USBConfiguration.h"
|
||||||
|
|
||||||
#include "bindings/core/v8/ExceptionState.h"
|
#include "bindings/core/v8/ExceptionState.h"
|
||||||
|
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||||
#include "modules/webusb/USBDevice.h"
|
#include "modules/webusb/USBDevice.h"
|
||||||
#include "modules/webusb/USBInterface.h"
|
#include "modules/webusb/USBInterface.h"
|
||||||
|
|
||||||
@ -17,23 +18,15 @@ USBConfiguration* USBConfiguration::create(const USBDevice* device, size_t confi
|
|||||||
|
|
||||||
USBConfiguration* USBConfiguration::create(const USBDevice* device, size_t configurationValue, ExceptionState& exceptionState)
|
USBConfiguration* USBConfiguration::create(const USBDevice* device, size_t configurationValue, ExceptionState& exceptionState)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < device->info().configurations.size(); ++i) {
|
const auto& configurations = device->info().configurations;
|
||||||
if (device->info().configurations[i].configurationValue == configurationValue)
|
for (size_t i = 0; i < configurations.size(); ++i) {
|
||||||
|
if (configurations[i]->configuration_value == configurationValue)
|
||||||
return new USBConfiguration(device, i);
|
return new USBConfiguration(device, i);
|
||||||
}
|
}
|
||||||
exceptionState.throwRangeError("Invalid configuration value.");
|
exceptionState.throwRangeError("Invalid configuration value.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
USBConfiguration* USBConfiguration::createFromValue(const USBDevice* device, uint8_t configurationValue)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < device->info().configurations.size(); ++i) {
|
|
||||||
if (device->info().configurations[i].configurationValue == configurationValue)
|
|
||||||
return new USBConfiguration(device, i);
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
USBConfiguration::USBConfiguration(const USBDevice* device, size_t configurationIndex)
|
USBConfiguration::USBConfiguration(const USBDevice* device, size_t configurationIndex)
|
||||||
: m_device(device)
|
: m_device(device)
|
||||||
, m_configurationIndex(configurationIndex)
|
, m_configurationIndex(configurationIndex)
|
||||||
@ -52,19 +45,9 @@ size_t USBConfiguration::index() const
|
|||||||
return m_configurationIndex;
|
return m_configurationIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
const WebUSBDeviceInfo::Configuration& USBConfiguration::info() const
|
const device::usb::wtf::ConfigurationInfo& USBConfiguration::info() const
|
||||||
{
|
{
|
||||||
return m_device->info().configurations[m_configurationIndex];
|
return *m_device->info().configurations[m_configurationIndex];
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBConfiguration::configurationValue() const
|
|
||||||
{
|
|
||||||
return info().configurationValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String USBConfiguration::configurationName() const
|
|
||||||
{
|
|
||||||
return info().configurationName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapVector<Member<USBInterface>> USBConfiguration::interfaces() const
|
HeapVector<Member<USBInterface>> USBConfiguration::interfaces() const
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#define USBConfiguration_h
|
#define USBConfiguration_h
|
||||||
|
|
||||||
#include "bindings/core/v8/ScriptWrappable.h"
|
#include "bindings/core/v8/ScriptWrappable.h"
|
||||||
|
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||||
#include "platform/heap/Handle.h"
|
#include "platform/heap/Handle.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
|
||||||
@ -22,16 +22,15 @@ class USBConfiguration
|
|||||||
public:
|
public:
|
||||||
static USBConfiguration* create(const USBDevice*, size_t configurationIndex);
|
static USBConfiguration* create(const USBDevice*, size_t configurationIndex);
|
||||||
static USBConfiguration* create(const USBDevice*, size_t configurationValue, ExceptionState&);
|
static USBConfiguration* create(const USBDevice*, size_t configurationValue, ExceptionState&);
|
||||||
static USBConfiguration* createFromValue(const USBDevice*, uint8_t configurationValue);
|
|
||||||
|
|
||||||
USBConfiguration(const USBDevice*, size_t configurationIndex);
|
USBConfiguration(const USBDevice*, size_t configurationIndex);
|
||||||
|
|
||||||
const USBDevice* device() const;
|
const USBDevice* device() const;
|
||||||
size_t index() const;
|
size_t index() const;
|
||||||
const WebUSBDeviceInfo::Configuration& info() const;
|
const device::usb::wtf::ConfigurationInfo& info() const;
|
||||||
|
|
||||||
uint8_t configurationValue() const;
|
uint8_t configurationValue() const { return info().configuration_value; }
|
||||||
String configurationName() const;
|
String configurationName() const { return info().configuration_name; }
|
||||||
HeapVector<Member<USBInterface>> interfaces() const;
|
HeapVector<Member<USBInterface>> interfaces() const;
|
||||||
|
|
||||||
DECLARE_TRACE();
|
DECLARE_TRACE();
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
// 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 "modules/webusb/USBController.h"
|
|
||||||
|
|
||||||
#include "platform/RuntimeEnabledFeatures.h"
|
|
||||||
#include "public/platform/modules/webusb/WebUSBClient.h"
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
USBController::~USBController()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void USBController::provideTo(LocalFrame& frame, WebUSBClient* client)
|
|
||||||
{
|
|
||||||
USBController* controller = new USBController(frame, client);
|
|
||||||
Supplement<LocalFrame>::provideTo(frame, supplementName(), controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
USBController& USBController::from(LocalFrame& frame)
|
|
||||||
{
|
|
||||||
USBController* controller = static_cast<USBController*>(Supplement<LocalFrame>::from(frame, supplementName()));
|
|
||||||
ASSERT(controller);
|
|
||||||
return *controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* USBController::supplementName()
|
|
||||||
{
|
|
||||||
return "USBController";
|
|
||||||
}
|
|
||||||
|
|
||||||
USBController::USBController(LocalFrame& frame, WebUSBClient* client)
|
|
||||||
: LocalFrameLifecycleObserver(&frame)
|
|
||||||
, m_client(client)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void USBController::willDetachFrameHost()
|
|
||||||
{
|
|
||||||
m_client = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_TRACE(USBController)
|
|
||||||
{
|
|
||||||
Supplement<LocalFrame>::trace(visitor);
|
|
||||||
LocalFrameLifecycleObserver::trace(visitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace blink
|
|
@ -1,45 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef USBController_h
|
|
||||||
#define USBController_h
|
|
||||||
|
|
||||||
#include "core/frame/LocalFrame.h"
|
|
||||||
#include "core/frame/LocalFrameLifecycleObserver.h"
|
|
||||||
#include "modules/ModulesExport.h"
|
|
||||||
#include "platform/heap/Handle.h"
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
class WebUSBClient;
|
|
||||||
|
|
||||||
class MODULES_EXPORT USBController final
|
|
||||||
: public GarbageCollectedFinalized<USBController>
|
|
||||||
, public Supplement<LocalFrame>
|
|
||||||
, public LocalFrameLifecycleObserver {
|
|
||||||
WTF_MAKE_NONCOPYABLE(USBController);
|
|
||||||
USING_GARBAGE_COLLECTED_MIXIN(USBController);
|
|
||||||
public:
|
|
||||||
virtual ~USBController();
|
|
||||||
|
|
||||||
WebUSBClient* client() { return m_client; }
|
|
||||||
|
|
||||||
static void provideTo(LocalFrame&, WebUSBClient*);
|
|
||||||
static USBController& from(LocalFrame&);
|
|
||||||
static const char* supplementName();
|
|
||||||
|
|
||||||
DECLARE_VIRTUAL_TRACE();
|
|
||||||
|
|
||||||
private:
|
|
||||||
USBController(LocalFrame&, WebUSBClient*);
|
|
||||||
|
|
||||||
// Inherited from LocalFrameLifecycleObserver.
|
|
||||||
void willDetachFrameHost() override;
|
|
||||||
|
|
||||||
WebUSBClient* m_client;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blink
|
|
||||||
|
|
||||||
#endif // USBController_h
|
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include "modules/webusb/USBDevice.h"
|
#include "modules/webusb/USBDevice.h"
|
||||||
|
|
||||||
#include "bindings/core/v8/CallbackPromiseAdapter.h"
|
|
||||||
#include "bindings/core/v8/ScriptPromise.h"
|
#include "bindings/core/v8/ScriptPromise.h"
|
||||||
#include "bindings/core/v8/ScriptPromiseResolver.h"
|
#include "bindings/core/v8/ScriptPromiseResolver.h"
|
||||||
#include "bindings/core/v8/ToV8.h"
|
#include "bindings/core/v8/ToV8.h"
|
||||||
@ -14,31 +13,58 @@
|
|||||||
#include "core/dom/ExceptionCode.h"
|
#include "core/dom/ExceptionCode.h"
|
||||||
#include "modules/webusb/USBConfiguration.h"
|
#include "modules/webusb/USBConfiguration.h"
|
||||||
#include "modules/webusb/USBControlTransferParameters.h"
|
#include "modules/webusb/USBControlTransferParameters.h"
|
||||||
#include "modules/webusb/USBError.h"
|
|
||||||
#include "modules/webusb/USBInTransferResult.h"
|
#include "modules/webusb/USBInTransferResult.h"
|
||||||
#include "modules/webusb/USBIsochronousInTransferResult.h"
|
#include "modules/webusb/USBIsochronousInTransferResult.h"
|
||||||
#include "modules/webusb/USBIsochronousOutTransferResult.h"
|
#include "modules/webusb/USBIsochronousOutTransferResult.h"
|
||||||
#include "modules/webusb/USBOutTransferResult.h"
|
#include "modules/webusb/USBOutTransferResult.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBTransferInfo.h"
|
#include "platform/MojoHelper.h"
|
||||||
#include "wtf/Assertions.h"
|
#include "wtf/Assertions.h"
|
||||||
|
|
||||||
|
namespace usb = device::usb::wtf;
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const char kDeviceStateChangeInProgress[] = "An operation that changes the device state is in progress.";
|
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 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 kInterfaceStateChangeInProgress[] = "An operation that changes interface state is in progress.";
|
||||||
const char kOpenRequired[] = "The device must be opened first.";
|
const char kOpenRequired[] = "The device must be opened first.";
|
||||||
|
|
||||||
String convertTransferStatus(const WebUSBTransferInfo::Status& status)
|
DOMException* convertFatalTransferStatus(const usb::TransferStatus& status)
|
||||||
{
|
{
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case WebUSBTransferInfo::Status::Ok:
|
case usb::TransferStatus::TRANSFER_ERROR:
|
||||||
|
return DOMException::create(NetworkError, "A transfer error has occured.");
|
||||||
|
case usb::TransferStatus::PERMISSION_DENIED:
|
||||||
|
return DOMException::create(SecurityError, "The transfer was not allowed.");
|
||||||
|
case usb::TransferStatus::TIMEOUT:
|
||||||
|
return DOMException::create(TimeoutError, "The transfer timed out.");
|
||||||
|
case usb::TransferStatus::CANCELLED:
|
||||||
|
return DOMException::create(AbortError, "The transfer was cancelled.");
|
||||||
|
case usb::TransferStatus::DISCONNECT:
|
||||||
|
return DOMException::create(NotFoundError, kDeviceUnavailable);
|
||||||
|
case usb::TransferStatus::COMPLETED:
|
||||||
|
case usb::TransferStatus::STALLED:
|
||||||
|
case usb::TransferStatus::BABBLE:
|
||||||
|
case usb::TransferStatus::SHORT_PACKET:
|
||||||
|
return nullptr;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String convertTransferStatus(const usb::TransferStatus& status)
|
||||||
|
{
|
||||||
|
switch (status) {
|
||||||
|
case usb::TransferStatus::COMPLETED:
|
||||||
|
case usb::TransferStatus::SHORT_PACKET:
|
||||||
return "ok";
|
return "ok";
|
||||||
case WebUSBTransferInfo::Status::Stall:
|
case usb::TransferStatus::STALLED:
|
||||||
return "stall";
|
return "stall";
|
||||||
case WebUSBTransferInfo::Status::Babble:
|
case usb::TransferStatus::BABBLE:
|
||||||
return "babble";
|
return "babble";
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
@ -46,291 +72,52 @@ String convertTransferStatus(const WebUSBTransferInfo::Status& status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpenClosePromiseAdapter : public WebCallbacks<void, const WebUSBError&> {
|
mojo::WTFArray<uint8_t> convertBufferSource(const ArrayBufferOrArrayBufferView& buffer)
|
||||||
public:
|
{
|
||||||
OpenClosePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, bool desiredState)
|
ASSERT(!buffer.isNull());
|
||||||
: m_device(device)
|
Vector<uint8_t> vector;
|
||||||
, m_resolver(resolver)
|
if (buffer.isArrayBuffer())
|
||||||
, m_desiredState(desiredState)
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
void onSuccess() override
|
bool isActive(ScriptPromiseResolver* resolver)
|
||||||
{
|
{
|
||||||
if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
|
ExecutionContext* context = resolver->getExecutionContext();
|
||||||
return;
|
return context && !context->activeDOMObjectsAreStopped();
|
||||||
|
}
|
||||||
m_device->onDeviceOpenedOrClosed(m_desiredState);
|
|
||||||
m_resolver->resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
void onError(const WebUSBError& e) override
|
|
||||||
{
|
|
||||||
if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
|
|
||||||
return;
|
|
||||||
m_device->onDeviceOpenedOrClosed(!m_desiredState);
|
|
||||||
m_resolver->reject(USBError::take(m_resolver, e));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Persistent<USBDevice> m_device;
|
|
||||||
Persistent<ScriptPromiseResolver> m_resolver;
|
|
||||||
bool m_desiredState; // true: open, false: closed
|
|
||||||
};
|
|
||||||
|
|
||||||
class SelectConfigurationPromiseAdapter : public WebCallbacks<void, const WebUSBError&> {
|
|
||||||
public:
|
|
||||||
SelectConfigurationPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t configurationIndex)
|
|
||||||
: m_device(device)
|
|
||||||
, m_resolver(resolver)
|
|
||||||
, m_configurationIndex(configurationIndex)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void onSuccess() override
|
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
|
||||||
if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
|
|
||||||
return;
|
|
||||||
m_device->onConfigurationSelected(false /* failure */, m_configurationIndex);
|
|
||||||
m_resolver->reject(USBError::take(m_resolver, e));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Persistent<USBDevice> m_device;
|
|
||||||
Persistent<ScriptPromiseResolver> m_resolver;
|
|
||||||
size_t m_configurationIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ClaimInterfacePromiseAdapter : public WebCallbacks<void, const WebUSBError&> {
|
|
||||||
public:
|
|
||||||
ClaimInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t interfaceIndex, bool desiredState)
|
|
||||||
: m_device(device)
|
|
||||||
, m_resolver(resolver)
|
|
||||||
, m_interfaceIndex(interfaceIndex)
|
|
||||||
, m_desiredState(desiredState)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void onSuccess() override
|
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
|
||||||
if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
|
|
||||||
return;
|
|
||||||
m_device->onInterfaceClaimedOrUnclaimed(!m_desiredState, m_interfaceIndex);
|
|
||||||
m_resolver->reject(USBError::take(m_resolver, e));
|
|
||||||
}
|
|
||||||
|
|
||||||
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&> {
|
|
||||||
public:
|
|
||||||
SelectAlternateInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t interfaceIndex, size_t alternateIndex)
|
|
||||||
: m_device(device)
|
|
||||||
, m_resolver(resolver)
|
|
||||||
, 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
|
|
||||||
{
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Persistent<USBDevice> m_device;
|
|
||||||
Persistent<ScriptPromiseResolver> m_resolver;
|
|
||||||
size_t m_interfaceIndex;
|
|
||||||
size_t m_alternateIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
class InputTransferResult {
|
|
||||||
WTF_MAKE_NONCOPYABLE(InputTransferResult);
|
|
||||||
public:
|
|
||||||
using WebType = OwnPtr<WebUSBTransferInfo>;
|
|
||||||
|
|
||||||
static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTransferInfo> webTransferInfo)
|
|
||||||
{
|
|
||||||
ASSERT(webTransferInfo->status.size() == 1);
|
|
||||||
return USBInTransferResult::create(convertTransferStatus(webTransferInfo->status[0]), webTransferInfo->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
InputTransferResult() = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
class OutputTransferResult {
|
|
||||||
WTF_MAKE_NONCOPYABLE(OutputTransferResult);
|
|
||||||
public:
|
|
||||||
using WebType = OwnPtr<WebUSBTransferInfo>;
|
|
||||||
|
|
||||||
static USBOutTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTransferInfo> webTransferInfo)
|
|
||||||
{
|
|
||||||
ASSERT(webTransferInfo->status.size() == 1);
|
|
||||||
ASSERT(webTransferInfo->bytesTransferred.size() == 1);
|
|
||||||
return USBOutTransferResult::create(convertTransferStatus(webTransferInfo->status[0]), webTransferInfo->bytesTransferred[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
OutputTransferResult() = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IsochronousInputTransferResult {
|
|
||||||
WTF_MAKE_NONCOPYABLE(IsochronousInputTransferResult);
|
|
||||||
|
|
||||||
public:
|
|
||||||
using WebType = OwnPtr<WebUSBTransferInfo>;
|
|
||||||
|
|
||||||
static USBIsochronousInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTransferInfo> webTransferInfo)
|
|
||||||
{
|
|
||||||
ASSERT(webTransferInfo->status.size() == webTransferInfo->packetLength.size() && webTransferInfo->packetLength.size() == webTransferInfo->bytesTransferred.size());
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
return USBIsochronousInTransferResult::create(buffer, packets);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class IsochronousOutputTransferResult {
|
|
||||||
WTF_MAKE_NONCOPYABLE(IsochronousOutputTransferResult);
|
|
||||||
|
|
||||||
public:
|
|
||||||
using WebType = OwnPtr<WebUSBTransferInfo>;
|
|
||||||
|
|
||||||
static USBIsochronousOutTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTransferInfo> webTransferInfo)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class BufferSource {
|
|
||||||
WTF_MAKE_NONCOPYABLE(BufferSource);
|
|
||||||
public:
|
|
||||||
BufferSource(const ArrayBufferOrArrayBufferView& buffer) : m_buffer(buffer)
|
|
||||||
{
|
|
||||||
ASSERT(!m_buffer.isNull());
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
} // namespace
|
||||||
|
|
||||||
// static
|
USBDevice::USBDevice(usb::DeviceInfoPtr deviceInfo, usb::DevicePtr device, ExecutionContext* context)
|
||||||
USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDevice> device)
|
|
||||||
{
|
|
||||||
return USBDevice::create(device, resolver->getExecutionContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context)
|
|
||||||
: ContextLifecycleObserver(context)
|
: ContextLifecycleObserver(context)
|
||||||
, m_device(device)
|
, m_deviceInfo(std::move(deviceInfo))
|
||||||
|
, m_device(std::move(device))
|
||||||
, m_opened(false)
|
, m_opened(false)
|
||||||
, m_deviceStateChangeInProgress(false)
|
, m_deviceStateChangeInProgress(false)
|
||||||
, m_configurationIndex(-1)
|
, 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.reset();
|
||||||
|
m_opened = false;
|
||||||
|
for (ScriptPromiseResolver* resolver : m_deviceRequests) {
|
||||||
|
if (isActive(resolver))
|
||||||
|
resolver->reject(DOMException::create(NotFoundError, kDeviceUnavailable));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
int configurationIndex = findConfigurationIndex(info().active_configuration);
|
||||||
if (configurationIndex != -1)
|
if (configurationIndex != -1)
|
||||||
onConfigurationSelected(true /* success */, configurationIndex);
|
onConfigurationSelected(true /* success */, configurationIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBDevice::onDeviceOpenedOrClosed(bool opened)
|
USBDevice::~USBDevice()
|
||||||
{
|
{
|
||||||
m_opened = opened;
|
DCHECK(!m_device);
|
||||||
m_deviceStateChangeInProgress = false;
|
DCHECK(m_deviceRequests.isEmpty());
|
||||||
}
|
|
||||||
|
|
||||||
void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex)
|
|
||||||
{
|
|
||||||
if (success) {
|
|
||||||
m_configurationIndex = configurationIndex;
|
|
||||||
size_t numInterfaces = info().configurations[m_configurationIndex].interfaces.size();
|
|
||||||
m_claimedInterfaces.clearAll();
|
|
||||||
m_claimedInterfaces.resize(numInterfaces);
|
|
||||||
m_interfaceStateChangeInProgress.clearAll();
|
|
||||||
m_interfaceStateChangeInProgress.resize(numInterfaces);
|
|
||||||
m_selectedAlternates.resize(numInterfaces);
|
|
||||||
m_selectedAlternates.fill(0);
|
|
||||||
m_inEndpoints.clearAll();
|
|
||||||
m_outEndpoints.clearAll();
|
|
||||||
}
|
|
||||||
m_deviceStateChangeInProgress = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USBDevice::onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceIndex)
|
|
||||||
{
|
|
||||||
if (claimed) {
|
|
||||||
m_claimedInterfaces.set(interfaceIndex);
|
|
||||||
} else {
|
|
||||||
m_claimedInterfaces.clear(interfaceIndex);
|
|
||||||
m_selectedAlternates[interfaceIndex] = 0;
|
|
||||||
}
|
|
||||||
setEndpointsForInterface(interfaceIndex, claimed);
|
|
||||||
m_interfaceStateChangeInProgress.clear(interfaceIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void USBDevice::onAlternateInterfaceSelected(bool success, size_t interfaceIndex, size_t alternateIndex)
|
|
||||||
{
|
|
||||||
if (success)
|
|
||||||
m_selectedAlternates[interfaceIndex] = alternateIndex;
|
|
||||||
setEndpointsForInterface(interfaceIndex, success);
|
|
||||||
m_interfaceStateChangeInProgress.clear(interfaceIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBDevice::isInterfaceClaimed(size_t configurationIndex, size_t interfaceIndex) const
|
bool USBDevice::isInterfaceClaimed(size_t configurationIndex, size_t interfaceIndex) const
|
||||||
@ -352,10 +139,10 @@ USBConfiguration* USBDevice::configuration() const
|
|||||||
|
|
||||||
HeapVector<Member<USBConfiguration>> USBDevice::configurations() const
|
HeapVector<Member<USBConfiguration>> USBDevice::configurations() const
|
||||||
{
|
{
|
||||||
HeapVector<Member<USBConfiguration>> configurations;
|
|
||||||
size_t numConfigurations = info().configurations.size();
|
size_t numConfigurations = info().configurations.size();
|
||||||
|
HeapVector<Member<USBConfiguration>> configurations(numConfigurations);
|
||||||
for (size_t i = 0; i < numConfigurations; ++i)
|
for (size_t i = 0; i < numConfigurations; ++i)
|
||||||
configurations.append(USBConfiguration::create(this, i));
|
configurations[i] = USBConfiguration::create(this, i);
|
||||||
return configurations;
|
return configurations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +155,8 @@ ScriptPromise USBDevice::open(ScriptState* scriptState)
|
|||||||
resolver->resolve();
|
resolver->resolve();
|
||||||
} else {
|
} else {
|
||||||
m_deviceStateChangeInProgress = true;
|
m_deviceStateChangeInProgress = true;
|
||||||
m_device->open(new OpenClosePromiseAdapter(this, resolver, true /* open */));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->Open(createBaseCallback(bind<usb::OpenDeviceError>(&USBDevice::asyncOpen, this, resolver)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
@ -383,7 +171,8 @@ ScriptPromise USBDevice::close(ScriptState* scriptState)
|
|||||||
resolver->resolve();
|
resolver->resolve();
|
||||||
} else {
|
} else {
|
||||||
m_deviceStateChangeInProgress = true;
|
m_deviceStateChangeInProgress = true;
|
||||||
m_device->close(new OpenClosePromiseAdapter(this, resolver, false /* closed */));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->Close(createBaseCallback(bind(&USBDevice::asyncClose, this, resolver)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
@ -404,7 +193,8 @@ ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c
|
|||||||
resolver->resolve();
|
resolver->resolve();
|
||||||
} else {
|
} else {
|
||||||
m_deviceStateChangeInProgress = true;
|
m_deviceStateChangeInProgress = true;
|
||||||
m_device->setConfiguration(configurationValue, new SelectConfigurationPromiseAdapter(this, resolver, configurationIndex));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->SetConfiguration(configurationValue, createBaseCallback(bind<bool>(&USBDevice::asyncSelectConfiguration, this, configurationIndex, resolver)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -425,7 +215,8 @@ ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf
|
|||||||
resolver->resolve();
|
resolver->resolve();
|
||||||
} else {
|
} else {
|
||||||
m_interfaceStateChangeInProgress.set(interfaceIndex);
|
m_interfaceStateChangeInProgress.set(interfaceIndex);
|
||||||
m_device->claimInterface(interfaceNumber, new ClaimInterfacePromiseAdapter(this, resolver, interfaceIndex, true /* claim */));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->ClaimInterface(interfaceNumber, createBaseCallback(bind<bool>(&USBDevice::asyncClaimInterface, this, interfaceIndex, resolver)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
@ -448,7 +239,8 @@ ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte
|
|||||||
// changing.
|
// changing.
|
||||||
setEndpointsForInterface(interfaceIndex, false);
|
setEndpointsForInterface(interfaceIndex, false);
|
||||||
m_interfaceStateChangeInProgress.set(interfaceIndex);
|
m_interfaceStateChangeInProgress.set(interfaceIndex);
|
||||||
m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromiseAdapter(this, resolver, interfaceIndex, false /* release */));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->ReleaseInterface(interfaceNumber, createBaseCallback(bind<bool>(&USBDevice::asyncReleaseInterface, this, interfaceIndex, resolver)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
@ -470,7 +262,8 @@ ScriptPromise USBDevice::selectAlternateInterface(ScriptState* scriptState, uint
|
|||||||
// the change is in progress.
|
// the change is in progress.
|
||||||
setEndpointsForInterface(interfaceIndex, false);
|
setEndpointsForInterface(interfaceIndex, false);
|
||||||
m_interfaceStateChangeInProgress.set(interfaceIndex);
|
m_interfaceStateChangeInProgress.set(interfaceIndex);
|
||||||
m_device->setInterface(interfaceNumber, alternateSetting, new SelectAlternateInterfacePromiseAdapter(this, resolver, interfaceIndex, alternateIndex));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->SetInterfaceAlternateSetting(interfaceNumber, alternateSetting, createBaseCallback(bind<bool>(&USBDevice::asyncSelectAlternateInterface, this, interfaceNumber, alternateSetting, resolver)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
@ -481,9 +274,11 @@ ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo
|
|||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
if (ensureDeviceConfigured(resolver)) {
|
if (ensureDeviceConfigured(resolver)) {
|
||||||
WebUSBDevice::ControlTransferParameters parameters;
|
auto parameters = convertControlTransferParameters(setup, resolver);
|
||||||
if (convertControlTransferParameters(WebUSBDevice::TransferDirection::In, setup, ¶meters, resolver))
|
if (parameters) {
|
||||||
m_device->controlTransfer(parameters, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(resolver));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->ControlTransferIn(std::move(parameters), length, 0, createBaseCallback(bind<usb::TransferStatus, mojo::WTFArray<uint8_t>>(&USBDevice::asyncControlTransferIn, this, resolver)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
@ -493,9 +288,11 @@ ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC
|
|||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
if (ensureDeviceConfigured(resolver)) {
|
if (ensureDeviceConfigured(resolver)) {
|
||||||
WebUSBDevice::ControlTransferParameters parameters;
|
auto parameters = convertControlTransferParameters(setup, resolver);
|
||||||
if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Out, setup, ¶meters, resolver))
|
if (parameters) {
|
||||||
m_device->controlTransfer(parameters, nullptr, 0, 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->ControlTransferOut(std::move(parameters), mojo::WTFArray<uint8_t>(), 0, createBaseCallback(bind<usb::TransferStatus>(&USBDevice::asyncControlTransferOut, this, 0, resolver)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
@ -505,10 +302,12 @@ ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC
|
|||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
if (ensureDeviceConfigured(resolver)) {
|
if (ensureDeviceConfigured(resolver)) {
|
||||||
WebUSBDevice::ControlTransferParameters parameters;
|
auto parameters = convertControlTransferParameters(setup, resolver);
|
||||||
if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Out, setup, ¶meters, resolver)) {
|
if (parameters) {
|
||||||
BufferSource buffer(data);
|
mojo::WTFArray<uint8_t> buffer = convertBufferSource(data);
|
||||||
m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
|
unsigned transferLength = buffer.size();
|
||||||
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->ControlTransferOut(std::move(parameters), std::move(buffer), 0, createBaseCallback(bind<usb::TransferStatus>(&USBDevice::asyncControlTransferOut, this, transferLength, resolver)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
@ -518,8 +317,10 @@ ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u
|
|||||||
{
|
{
|
||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver))
|
if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver)) {
|
||||||
m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USBError>(resolver));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->ClearHalt(endpointNumber, createBaseCallback(bind<bool>(&USBDevice::asyncClearHalt, this, resolver)));
|
||||||
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,8 +328,10 @@ ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu
|
|||||||
{
|
{
|
||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver))
|
if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) {
|
||||||
m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(resolver));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->GenericTransferIn(endpointNumber, length, 0, createBaseCallback(bind<usb::TransferStatus, mojo::WTFArray<uint8_t>>(&USBDevice::asyncTransferIn, this, resolver)));
|
||||||
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,8 +340,10 @@ ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN
|
|||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
|
if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
|
||||||
BufferSource buffer(data);
|
mojo::WTFArray<uint8_t> buffer = convertBufferSource(data);
|
||||||
m_device->transfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
|
unsigned transferLength = buffer.size();
|
||||||
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->GenericTransferOut(endpointNumber, std::move(buffer), 0, createBaseCallback(bind<usb::TransferStatus>(&USBDevice::asyncTransferOut, this, transferLength, resolver)));
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
@ -547,8 +352,10 @@ ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t
|
|||||||
{
|
{
|
||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver))
|
if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) {
|
||||||
m_device->isochronousTransfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, 0, packetLengths, 0, new CallbackPromiseAdapter<IsochronousInputTransferResult, USBError>(resolver));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->IsochronousTransferIn(endpointNumber, mojo::WTFArray<uint32_t>(std::move(packetLengths)), 0, createBaseCallback(bind<mojo::WTFArray<uint8_t>, mojo::WTFArray<usb::IsochronousPacketPtr>>(&USBDevice::asyncIsochronousTransferIn, this, resolver)));
|
||||||
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,8 +364,8 @@ ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_
|
|||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
|
if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
|
||||||
BufferSource buffer(data);
|
m_deviceRequests.add(resolver);
|
||||||
m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseAdapter<IsochronousOutputTransferResult, USBError>(resolver));
|
m_device->IsochronousTransferOut(endpointNumber, convertBufferSource(data), mojo::WTFArray<uint32_t>(std::move(packetLengths)), 0, createBaseCallback(bind<mojo::WTFArray<usb::IsochronousPacketPtr>>(&USBDevice::asyncIsochronousTransferOut, this, resolver)));
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
@ -568,32 +375,33 @@ ScriptPromise USBDevice::reset(ScriptState* scriptState)
|
|||||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||||
ScriptPromise promise = resolver->promise();
|
ScriptPromise promise = resolver->promise();
|
||||||
if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
|
if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
|
||||||
if (!m_opened)
|
if (!m_opened) {
|
||||||
resolver->reject(DOMException::create(InvalidStateError, kOpenRequired));
|
resolver->reject(DOMException::create(InvalidStateError, kOpenRequired));
|
||||||
else
|
} else {
|
||||||
m_device->reset(new CallbackPromiseAdapter<void, USBError>(resolver));
|
m_deviceRequests.add(resolver);
|
||||||
|
m_device->Reset(createBaseCallback(bind<bool>(&USBDevice::asyncReset, this, resolver)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBDevice::contextDestroyed()
|
void USBDevice::contextDestroyed()
|
||||||
{
|
{
|
||||||
if (m_opened) {
|
m_device.reset();
|
||||||
m_device->close(new WebUSBDeviceCloseCallbacks());
|
m_deviceRequests.clear();
|
||||||
m_opened = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_TRACE(USBDevice)
|
DEFINE_TRACE(USBDevice)
|
||||||
{
|
{
|
||||||
ContextLifecycleObserver::trace(visitor);
|
ContextLifecycleObserver::trace(visitor);
|
||||||
|
visitor->trace(m_deviceRequests);
|
||||||
}
|
}
|
||||||
|
|
||||||
int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
|
int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
|
||||||
{
|
{
|
||||||
const auto& configurations = info().configurations;
|
const auto& configurations = info().configurations;
|
||||||
for (size_t i = 0; i < configurations.size(); ++i) {
|
for (size_t i = 0; i < configurations.size(); ++i) {
|
||||||
if (configurations[i].configurationValue == configurationValue)
|
if (configurations[i]->configuration_value == configurationValue)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -602,9 +410,9 @@ int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
|
|||||||
int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
|
int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
|
||||||
{
|
{
|
||||||
ASSERT(m_configurationIndex != -1);
|
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) {
|
for (size_t i = 0; i < interfaces.size(); ++i) {
|
||||||
if (interfaces[i].interfaceNumber == interfaceNumber)
|
if (interfaces[i]->interface_number == interfaceNumber)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -613,9 +421,9 @@ int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
|
|||||||
int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSetting) const
|
int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSetting) const
|
||||||
{
|
{
|
||||||
ASSERT(m_configurationIndex != -1);
|
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) {
|
for (size_t i = 0; i < alternates.size(); ++i) {
|
||||||
if (alternates[i].alternateSetting == alternateSetting)
|
if (alternates[i]->alternate_setting == alternateSetting)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -623,7 +431,9 @@ int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSettin
|
|||||||
|
|
||||||
bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver* resolver) const
|
bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver* resolver) const
|
||||||
{
|
{
|
||||||
if (m_deviceStateChangeInProgress)
|
if (!m_device)
|
||||||
|
resolver->reject(DOMException::create(NotFoundError, kDeviceUnavailable));
|
||||||
|
else if (m_deviceStateChangeInProgress)
|
||||||
resolver->reject(DOMException::create(InvalidStateError, kDeviceStateChangeInProgress));
|
resolver->reject(DOMException::create(InvalidStateError, kDeviceStateChangeInProgress));
|
||||||
else if (anyInterfaceChangeInProgress())
|
else if (anyInterfaceChangeInProgress())
|
||||||
resolver->reject(DOMException::create(InvalidStateError, kInterfaceStateChangeInProgress));
|
resolver->reject(DOMException::create(InvalidStateError, kInterfaceStateChangeInProgress));
|
||||||
@ -634,7 +444,9 @@ bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver*
|
|||||||
|
|
||||||
bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const
|
bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const
|
||||||
{
|
{
|
||||||
if (m_deviceStateChangeInProgress)
|
if (!m_device)
|
||||||
|
resolver->reject(DOMException::create(NotFoundError, kDeviceUnavailable));
|
||||||
|
else if (m_deviceStateChangeInProgress)
|
||||||
resolver->reject(DOMException::create(InvalidStateError, kDeviceStateChangeInProgress));
|
resolver->reject(DOMException::create(InvalidStateError, kDeviceStateChangeInProgress));
|
||||||
else if (!m_opened)
|
else if (!m_opened)
|
||||||
resolver->reject(DOMException::create(InvalidStateError, kOpenRequired));
|
resolver->reject(DOMException::create(InvalidStateError, kOpenRequired));
|
||||||
@ -686,65 +498,303 @@ bool USBDevice::anyInterfaceChangeInProgress() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBDevice::convertControlTransferParameters(
|
usb::ControlTransferParamsPtr USBDevice::convertControlTransferParameters(
|
||||||
WebUSBDevice::TransferDirection direction,
|
|
||||||
const USBControlTransferParameters& parameters,
|
const USBControlTransferParameters& parameters,
|
||||||
WebUSBDevice::ControlTransferParameters* webParameters,
|
|
||||||
ScriptPromiseResolver* resolver) const
|
ScriptPromiseResolver* resolver) const
|
||||||
{
|
{
|
||||||
webParameters->direction = direction;
|
auto mojoParameters = usb::ControlTransferParams::New();
|
||||||
|
|
||||||
if (parameters.requestType() == "standard") {
|
if (parameters.requestType() == "standard") {
|
||||||
webParameters->type = WebUSBDevice::RequestType::Standard;
|
mojoParameters->type = usb::ControlTransferType::STANDARD;
|
||||||
} else if (parameters.requestType() == "class") {
|
} else if (parameters.requestType() == "class") {
|
||||||
webParameters->type = WebUSBDevice::RequestType::Class;
|
mojoParameters->type = usb::ControlTransferType::CLASS;
|
||||||
} else if (parameters.requestType() == "vendor") {
|
} else if (parameters.requestType() == "vendor") {
|
||||||
webParameters->type = WebUSBDevice::RequestType::Vendor;
|
mojoParameters->type = usb::ControlTransferType::VENDOR;
|
||||||
} else {
|
} else {
|
||||||
resolver->reject(DOMException::create(TypeMismatchError, "The control transfer requestType parameter is invalid."));
|
resolver->reject(DOMException::create(TypeMismatchError, "The control transfer requestType parameter is invalid."));
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.recipient() == "device") {
|
if (parameters.recipient() == "device") {
|
||||||
webParameters->recipient = WebUSBDevice::RequestRecipient::Device;
|
mojoParameters->recipient = usb::ControlTransferRecipient::DEVICE;
|
||||||
} else if (parameters.recipient() == "interface") {
|
} else if (parameters.recipient() == "interface") {
|
||||||
size_t interfaceNumber = parameters.index() & 0xff;
|
size_t interfaceNumber = parameters.index() & 0xff;
|
||||||
if (!ensureInterfaceClaimed(interfaceNumber, resolver))
|
if (!ensureInterfaceClaimed(interfaceNumber, resolver))
|
||||||
return false;
|
return nullptr;
|
||||||
webParameters->recipient = WebUSBDevice::RequestRecipient::Interface;
|
mojoParameters->recipient = usb::ControlTransferRecipient::INTERFACE;
|
||||||
} else if (parameters.recipient() == "endpoint") {
|
} else if (parameters.recipient() == "endpoint") {
|
||||||
bool inTransfer = parameters.index() & 0x80;
|
bool inTransfer = parameters.index() & 0x80;
|
||||||
size_t endpointNumber = parameters.index() & 0x0f;
|
size_t endpointNumber = parameters.index() & 0x0f;
|
||||||
if (!ensureEndpointAvailable(inTransfer, endpointNumber, resolver))
|
if (!ensureEndpointAvailable(inTransfer, endpointNumber, resolver))
|
||||||
return false;
|
return nullptr;
|
||||||
webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint;
|
mojoParameters->recipient = usb::ControlTransferRecipient::ENDPOINT;
|
||||||
} else if (parameters.recipient() == "other") {
|
} else if (parameters.recipient() == "other") {
|
||||||
webParameters->recipient = WebUSBDevice::RequestRecipient::Other;
|
mojoParameters->recipient = usb::ControlTransferRecipient::OTHER;
|
||||||
} else {
|
} else {
|
||||||
resolver->reject(DOMException::create(TypeMismatchError, "The control transfer recipient parameter is invalid."));
|
resolver->reject(DOMException::create(TypeMismatchError, "The control transfer recipient parameter is invalid."));
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
webParameters->request = parameters.request();
|
mojoParameters->request = parameters.request();
|
||||||
webParameters->value = parameters.value();
|
mojoParameters->value = parameters.value();
|
||||||
webParameters->index = parameters.index();
|
mojoParameters->index = parameters.index();
|
||||||
return true;
|
return mojoParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBDevice::setEndpointsForInterface(size_t interfaceIndex, bool set)
|
void USBDevice::setEndpointsForInterface(size_t interfaceIndex, bool set)
|
||||||
{
|
{
|
||||||
const auto& configuration = info().configurations[m_configurationIndex];
|
const auto& configuration = *info().configurations[m_configurationIndex];
|
||||||
const auto& interface = configuration.interfaces[interfaceIndex];
|
const auto& interface = *configuration.interfaces[interfaceIndex];
|
||||||
const auto& alternate = interface.alternates[m_selectedAlternates[interfaceIndex]];
|
const auto& alternate = *interface.alternates[m_selectedAlternates[interfaceIndex]];
|
||||||
for (const auto& endpoint : alternate.endpoints) {
|
for (const auto& endpoint : alternate.endpoints.storage()) {
|
||||||
if (endpoint.endpointNumber == 0 || endpoint.endpointNumber >= 16)
|
uint8_t endpointNumber = endpoint->endpoint_number;
|
||||||
|
if (endpointNumber == 0 || endpointNumber >= 16)
|
||||||
continue; // Ignore endpoints with invalid indices.
|
continue; // Ignore endpoints with invalid indices.
|
||||||
auto& bitVector = endpoint.direction == WebUSBDevice::TransferDirection::In ? m_inEndpoints : m_outEndpoints;
|
auto& bitVector = endpoint->direction == usb::TransferDirection::INBOUND ? m_inEndpoints : m_outEndpoints;
|
||||||
if (set)
|
if (set)
|
||||||
bitVector.set(endpoint.endpointNumber - 1);
|
bitVector.set(endpointNumber - 1);
|
||||||
else
|
else
|
||||||
bitVector.clear(endpoint.endpointNumber - 1);
|
bitVector.clear(endpointNumber - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncOpen(ScriptPromiseResolver* resolver, usb::OpenDeviceError error)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (error) {
|
||||||
|
case usb::OpenDeviceError::ALREADY_OPEN:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
// fall through
|
||||||
|
case usb::OpenDeviceError::OK:
|
||||||
|
onDeviceOpenedOrClosed(true /* opened */);
|
||||||
|
resolver->resolve();
|
||||||
|
return;
|
||||||
|
case usb::OpenDeviceError::ACCESS_DENIED:
|
||||||
|
onDeviceOpenedOrClosed(false /* not opened */);
|
||||||
|
resolver->reject(DOMException::create(SecurityError, "Access denied."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncClose(ScriptPromiseResolver* resolver)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
onDeviceOpenedOrClosed(false /* closed */);
|
||||||
|
resolver->resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::onDeviceOpenedOrClosed(bool opened)
|
||||||
|
{
|
||||||
|
m_opened = opened;
|
||||||
|
m_deviceStateChangeInProgress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncSelectConfiguration(size_t configurationIndex, ScriptPromiseResolver* resolver, bool success)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
onConfigurationSelected(success, configurationIndex);
|
||||||
|
if (success)
|
||||||
|
resolver->resolve();
|
||||||
|
else
|
||||||
|
resolver->reject(DOMException::create(NetworkError, "Unable to set device configuration."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex)
|
||||||
|
{
|
||||||
|
if (success) {
|
||||||
|
m_configurationIndex = configurationIndex;
|
||||||
|
size_t numInterfaces = info().configurations[m_configurationIndex]->interfaces.size();
|
||||||
|
m_claimedInterfaces.clearAll();
|
||||||
|
m_claimedInterfaces.resize(numInterfaces);
|
||||||
|
m_interfaceStateChangeInProgress.clearAll();
|
||||||
|
m_interfaceStateChangeInProgress.resize(numInterfaces);
|
||||||
|
m_selectedAlternates.resize(numInterfaces);
|
||||||
|
m_selectedAlternates.fill(0);
|
||||||
|
m_inEndpoints.clearAll();
|
||||||
|
m_outEndpoints.clearAll();
|
||||||
|
}
|
||||||
|
m_deviceStateChangeInProgress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncClaimInterface(size_t interfaceIndex, ScriptPromiseResolver* resolver, bool success)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
onInterfaceClaimedOrUnclaimed(success, interfaceIndex);
|
||||||
|
if (success)
|
||||||
|
resolver->resolve();
|
||||||
|
else
|
||||||
|
resolver->reject(DOMException::create(NetworkError, "Unable to claim interface."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncReleaseInterface(size_t interfaceIndex, ScriptPromiseResolver* resolver, bool success)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
onInterfaceClaimedOrUnclaimed(!success, interfaceIndex);
|
||||||
|
if (success)
|
||||||
|
resolver->resolve();
|
||||||
|
else
|
||||||
|
resolver->reject(DOMException::create(NetworkError, "Unable to release interface."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceIndex)
|
||||||
|
{
|
||||||
|
if (claimed) {
|
||||||
|
m_claimedInterfaces.set(interfaceIndex);
|
||||||
|
} else {
|
||||||
|
m_claimedInterfaces.clear(interfaceIndex);
|
||||||
|
m_selectedAlternates[interfaceIndex] = 0;
|
||||||
|
}
|
||||||
|
setEndpointsForInterface(interfaceIndex, claimed);
|
||||||
|
m_interfaceStateChangeInProgress.clear(interfaceIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncSelectAlternateInterface(size_t interfaceIndex, size_t alternateIndex, ScriptPromiseResolver* resolver, bool success)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
m_selectedAlternates[interfaceIndex] = alternateIndex;
|
||||||
|
setEndpointsForInterface(interfaceIndex, success);
|
||||||
|
m_interfaceStateChangeInProgress.clear(interfaceIndex);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
resolver->resolve();
|
||||||
|
else
|
||||||
|
resolver->reject(DOMException::create(NetworkError, "Unable to set device interface."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncControlTransferIn(ScriptPromiseResolver* resolver, usb::TransferStatus status, mojo::WTFArray<uint8_t> data)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DOMException* error = convertFatalTransferStatus(status);
|
||||||
|
if (error)
|
||||||
|
resolver->reject(error);
|
||||||
|
else
|
||||||
|
resolver->resolve(USBInTransferResult::create(convertTransferStatus(status), data.PassStorage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncControlTransferOut(unsigned transferLength, ScriptPromiseResolver* resolver, usb::TransferStatus status)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DOMException* error = convertFatalTransferStatus(status);
|
||||||
|
if (error)
|
||||||
|
resolver->reject(error);
|
||||||
|
else
|
||||||
|
resolver->resolve(USBOutTransferResult::create(convertTransferStatus(status), transferLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncClearHalt(ScriptPromiseResolver* resolver, bool success)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
resolver->resolve();
|
||||||
|
else
|
||||||
|
resolver->reject(DOMException::create(NetworkError, "Unable to clear endpoint."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncTransferIn(ScriptPromiseResolver* resolver, usb::TransferStatus status, mojo::WTFArray<uint8_t> data)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DOMException* error = convertFatalTransferStatus(status);
|
||||||
|
if (error)
|
||||||
|
resolver->reject(error);
|
||||||
|
else
|
||||||
|
resolver->resolve(USBInTransferResult::create(convertTransferStatus(status), data.PassStorage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncTransferOut(unsigned transferLength, ScriptPromiseResolver* resolver, usb::TransferStatus status)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DOMException* error = convertFatalTransferStatus(status);
|
||||||
|
if (error)
|
||||||
|
resolver->reject(error);
|
||||||
|
else
|
||||||
|
resolver->resolve(USBOutTransferResult::create(convertTransferStatus(status), transferLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncIsochronousTransferIn(ScriptPromiseResolver* resolver, mojo::WTFArray<uint8_t> data, mojo::WTFArray<usb::IsochronousPacketPtr> mojoPackets)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DOMArrayBuffer* buffer = DOMArrayBuffer::create(data.storage().data(), data.storage().size());
|
||||||
|
HeapVector<Member<USBIsochronousInTransferPacket>> packets;
|
||||||
|
packets.reserveCapacity(mojoPackets.size());
|
||||||
|
size_t byteOffset = 0;
|
||||||
|
for (const auto& packet : mojoPackets.storage()) {
|
||||||
|
DOMException* error = convertFatalTransferStatus(packet->status);
|
||||||
|
if (error) {
|
||||||
|
resolver->reject(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
packets.append(USBIsochronousInTransferPacket::create(convertTransferStatus(packet->status), DOMDataView::create(buffer, byteOffset, packet->transferred_length)));
|
||||||
|
byteOffset += packet->length;
|
||||||
|
}
|
||||||
|
resolver->resolve(USBIsochronousInTransferResult::create(buffer, packets));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncIsochronousTransferOut(ScriptPromiseResolver* resolver, mojo::WTFArray<usb::IsochronousPacketPtr> mojoPackets)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
HeapVector<Member<USBIsochronousOutTransferPacket>> packets;
|
||||||
|
packets.reserveCapacity(mojoPackets.size());
|
||||||
|
for (const auto& packet : mojoPackets.storage()) {
|
||||||
|
DOMException* error = convertFatalTransferStatus(packet->status);
|
||||||
|
if (error) {
|
||||||
|
resolver->reject(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
packets.append(USBIsochronousOutTransferPacket::create(convertTransferStatus(packet->status), packet->transferred_length));
|
||||||
|
}
|
||||||
|
resolver->resolve(USBIsochronousOutTransferResult::create(packets));
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDevice::asyncReset(ScriptPromiseResolver* resolver, bool success)
|
||||||
|
{
|
||||||
|
m_deviceRequests.remove(resolver);
|
||||||
|
if (!isActive(resolver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
resolver->resolve();
|
||||||
|
else
|
||||||
|
resolver->reject(DOMException::create(NetworkError, "Unable to reset the device."));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blink
|
} // namespace blink
|
||||||
|
@ -9,9 +9,8 @@
|
|||||||
#include "bindings/core/v8/ScriptWrappable.h"
|
#include "bindings/core/v8/ScriptWrappable.h"
|
||||||
#include "bindings/modules/v8/UnionTypesModules.h"
|
#include "bindings/modules/v8/UnionTypesModules.h"
|
||||||
#include "core/dom/ContextLifecycleObserver.h"
|
#include "core/dom/ContextLifecycleObserver.h"
|
||||||
|
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||||
#include "platform/heap/Handle.h"
|
#include "platform/heap/Handle.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBDevice.h"
|
|
||||||
#include "public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
|
||||||
#include "wtf/BitVector.h"
|
#include "wtf/BitVector.h"
|
||||||
#include "wtf/Vector.h"
|
#include "wtf/Vector.h"
|
||||||
|
|
||||||
@ -29,42 +28,34 @@ class USBDevice
|
|||||||
USING_GARBAGE_COLLECTED_MIXIN(USBDevice);
|
USING_GARBAGE_COLLECTED_MIXIN(USBDevice);
|
||||||
DEFINE_WRAPPERTYPEINFO();
|
DEFINE_WRAPPERTYPEINFO();
|
||||||
public:
|
public:
|
||||||
using WebType = OwnPtr<WebUSBDevice>;
|
static USBDevice* create(device::usb::wtf::DeviceInfoPtr deviceInfo, device::usb::wtf::DevicePtr device, ExecutionContext* context)
|
||||||
|
|
||||||
static USBDevice* create(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context)
|
|
||||||
{
|
{
|
||||||
return new USBDevice(device, context);
|
return new USBDevice(std::move(deviceInfo), std::move(device), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static USBDevice* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBDevice>);
|
explicit USBDevice(device::usb::wtf::DeviceInfoPtr, device::usb::wtf::DevicePtr, ExecutionContext*);
|
||||||
|
virtual ~USBDevice();
|
||||||
|
|
||||||
explicit USBDevice(PassOwnPtr<WebUSBDevice>, ExecutionContext*);
|
const device::usb::wtf::DeviceInfo& info() const { return *m_deviceInfo; }
|
||||||
virtual ~USBDevice() { }
|
|
||||||
|
|
||||||
const WebUSBDeviceInfo& info() const { return m_device->info(); }
|
|
||||||
void onDeviceOpenedOrClosed(bool);
|
|
||||||
void onConfigurationSelected(bool success, size_t configurationIndex);
|
|
||||||
void onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceIndex);
|
|
||||||
void onAlternateInterfaceSelected(bool success, size_t interfaceIndex, size_t alternateIndex);
|
|
||||||
bool isInterfaceClaimed(size_t configurationIndex, size_t interfaceIndex) const;
|
bool isInterfaceClaimed(size_t configurationIndex, size_t interfaceIndex) const;
|
||||||
size_t selectedAlternateInterface(size_t interfaceIndex) const;
|
size_t selectedAlternateInterface(size_t interfaceIndex) const;
|
||||||
|
|
||||||
// IDL exposed interface:
|
// USBDevice.idl
|
||||||
String guid() const { return info().guid; }
|
String guid() const { return info().guid; }
|
||||||
uint8_t usbVersionMajor() { return info().usbVersionMajor; }
|
uint8_t usbVersionMajor() const { return info().usb_version_major; }
|
||||||
uint8_t usbVersionMinor() { return info().usbVersionMinor; }
|
uint8_t usbVersionMinor() const { return info().usb_version_minor; }
|
||||||
uint8_t usbVersionSubminor() { return info().usbVersionSubminor; }
|
uint8_t usbVersionSubminor() const { return info().usb_version_subminor; }
|
||||||
uint8_t deviceClass() { return info().deviceClass; }
|
uint8_t deviceClass() const { return info().class_code; }
|
||||||
uint8_t deviceSubclass() const { return info().deviceSubclass; }
|
uint8_t deviceSubclass() const { return info().subclass_code; }
|
||||||
uint8_t deviceProtocol() const { return info().deviceProtocol; }
|
uint8_t deviceProtocol() const { return info().protocol_code; }
|
||||||
uint16_t vendorId() const { return info().vendorID; }
|
uint16_t vendorId() const { return info().vendor_id; }
|
||||||
uint16_t productId() const { return info().productID; }
|
uint16_t productId() const { return info().product_id; }
|
||||||
uint8_t deviceVersionMajor() const { return info().deviceVersionMajor; }
|
uint8_t deviceVersionMajor() const { return info().device_version_major; }
|
||||||
uint8_t deviceVersionMinor() const { return info().deviceVersionMinor; }
|
uint8_t deviceVersionMinor() const { return info().device_version_minor; }
|
||||||
uint8_t deviceVersionSubminor() const { return info().deviceVersionSubminor; }
|
uint8_t deviceVersionSubminor() const { return info().device_version_subminor; }
|
||||||
String manufacturerName() const { return info().manufacturerName; }
|
String manufacturerName() const { return info().manufacturer_name; }
|
||||||
String productName() const { return info().productName; }
|
String productName() const { return info().product_name; }
|
||||||
String serialNumber() const { return info().serialNumber; }
|
String serialNumber() const { return info().serial_number; }
|
||||||
USBConfiguration* configuration() const;
|
USBConfiguration* configuration() const;
|
||||||
HeapVector<Member<USBConfiguration>> configurations() const;
|
HeapVector<Member<USBConfiguration>> configurations() const;
|
||||||
bool opened() const { return m_opened; }
|
bool opened() const { return m_opened; }
|
||||||
@ -99,10 +90,30 @@ private:
|
|||||||
bool ensureInterfaceClaimed(uint8_t interfaceNumber, ScriptPromiseResolver*) const;
|
bool ensureInterfaceClaimed(uint8_t interfaceNumber, ScriptPromiseResolver*) const;
|
||||||
bool ensureEndpointAvailable(bool inTransfer, uint8_t endpointNumber, ScriptPromiseResolver*) const;
|
bool ensureEndpointAvailable(bool inTransfer, uint8_t endpointNumber, ScriptPromiseResolver*) const;
|
||||||
bool anyInterfaceChangeInProgress() const;
|
bool anyInterfaceChangeInProgress() const;
|
||||||
bool convertControlTransferParameters(WebUSBDevice::TransferDirection, const USBControlTransferParameters&, WebUSBDevice::ControlTransferParameters*, ScriptPromiseResolver*) const;
|
device::usb::wtf::ControlTransferParamsPtr convertControlTransferParameters(const USBControlTransferParameters&, ScriptPromiseResolver*) const;
|
||||||
void setEndpointsForInterface(size_t interfaceIndex, bool set);
|
void setEndpointsForInterface(size_t interfaceIndex, bool set);
|
||||||
|
|
||||||
OwnPtr<WebUSBDevice> m_device;
|
void asyncOpen(ScriptPromiseResolver*, device::usb::wtf::OpenDeviceError);
|
||||||
|
void asyncClose(ScriptPromiseResolver*);
|
||||||
|
void onDeviceOpenedOrClosed(bool);
|
||||||
|
void asyncSelectConfiguration(size_t configurationIndex, ScriptPromiseResolver*, bool success);
|
||||||
|
void onConfigurationSelected(bool success, size_t configurationIndex);
|
||||||
|
void asyncClaimInterface(size_t interfaceIndex, ScriptPromiseResolver*, bool success);
|
||||||
|
void asyncReleaseInterface(size_t interfaceIndex, ScriptPromiseResolver*, bool success);
|
||||||
|
void onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceIndex);
|
||||||
|
void asyncSelectAlternateInterface(size_t interfaceIndex, size_t alternateIndex, ScriptPromiseResolver*, bool success);
|
||||||
|
void asyncControlTransferIn(ScriptPromiseResolver*, device::usb::wtf::TransferStatus, mojo::WTFArray<uint8_t>);
|
||||||
|
void asyncControlTransferOut(unsigned, ScriptPromiseResolver*, device::usb::wtf::TransferStatus);
|
||||||
|
void asyncClearHalt(ScriptPromiseResolver*, bool success);
|
||||||
|
void asyncTransferIn(ScriptPromiseResolver*, device::usb::wtf::TransferStatus, mojo::WTFArray<uint8_t>);
|
||||||
|
void asyncTransferOut(unsigned, ScriptPromiseResolver*, device::usb::wtf::TransferStatus);
|
||||||
|
void asyncIsochronousTransferIn(ScriptPromiseResolver*, mojo::WTFArray<uint8_t>, mojo::WTFArray<device::usb::wtf::IsochronousPacketPtr>);
|
||||||
|
void asyncIsochronousTransferOut(ScriptPromiseResolver*, mojo::WTFArray<device::usb::wtf::IsochronousPacketPtr>);
|
||||||
|
void asyncReset(ScriptPromiseResolver*, bool success);
|
||||||
|
|
||||||
|
device::usb::wtf::DeviceInfoPtr m_deviceInfo;
|
||||||
|
device::usb::wtf::DevicePtr m_device;
|
||||||
|
HeapHashSet<Member<ScriptPromiseResolver>> m_deviceRequests;
|
||||||
bool m_opened;
|
bool m_opened;
|
||||||
bool m_deviceStateChangeInProgress;
|
bool m_deviceStateChangeInProgress;
|
||||||
int m_configurationIndex;
|
int m_configurationIndex;
|
||||||
|
@ -7,30 +7,22 @@
|
|||||||
#include "bindings/core/v8/ExceptionState.h"
|
#include "bindings/core/v8/ExceptionState.h"
|
||||||
#include "core/dom/DOMException.h"
|
#include "core/dom/DOMException.h"
|
||||||
#include "core/dom/ExceptionCode.h"
|
#include "core/dom/ExceptionCode.h"
|
||||||
|
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||||
#include "modules/webusb/USBAlternateInterface.h"
|
#include "modules/webusb/USBAlternateInterface.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBDevice.h"
|
|
||||||
|
using device::usb::wtf::EndpointType;
|
||||||
|
using device::usb::wtf::TransferDirection;
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool convertDirectionFromEnum(const String& direction, WebUSBDevice::TransferDirection* webDirection)
|
String convertDirectionToEnum(const TransferDirection& direction)
|
||||||
{
|
|
||||||
if (direction == "in")
|
|
||||||
*webDirection = WebUSBDevice::TransferDirection::In;
|
|
||||||
else if (direction == "out")
|
|
||||||
*webDirection = WebUSBDevice::TransferDirection::Out;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String convertDirectionToEnum(const WebUSBDevice::TransferDirection& direction)
|
|
||||||
{
|
{
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case WebUSBDevice::TransferDirection::In:
|
case TransferDirection::INBOUND:
|
||||||
return "in";
|
return "in";
|
||||||
case WebUSBDevice::TransferDirection::Out:
|
case TransferDirection::OUTBOUND:
|
||||||
return "out";
|
return "out";
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
@ -38,14 +30,14 @@ String convertDirectionToEnum(const WebUSBDevice::TransferDirection& direction)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String convertTypeToEnum(const WebUSBDeviceInfo::Endpoint::Type& type)
|
String convertTypeToEnum(const EndpointType& type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case WebUSBDeviceInfo::Endpoint::Type::Bulk:
|
case EndpointType::BULK:
|
||||||
return "bulk";
|
return "bulk";
|
||||||
case WebUSBDeviceInfo::Endpoint::Type::Interrupt:
|
case EndpointType::INTERRUPT:
|
||||||
return "interrupt";
|
return "interrupt";
|
||||||
case WebUSBDeviceInfo::Endpoint::Type::Isochronous:
|
case EndpointType::ISOCHRONOUS:
|
||||||
return "isochronous";
|
return "isochronous";
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
@ -62,17 +54,14 @@ USBEndpoint* USBEndpoint::create(const USBAlternateInterface* alternate, size_t
|
|||||||
|
|
||||||
USBEndpoint* USBEndpoint::create(const USBAlternateInterface* alternate, size_t endpointNumber, const String& direction, ExceptionState& exceptionState)
|
USBEndpoint* USBEndpoint::create(const USBAlternateInterface* alternate, size_t endpointNumber, const String& direction, ExceptionState& exceptionState)
|
||||||
{
|
{
|
||||||
WebUSBDevice::TransferDirection webDirection;
|
TransferDirection mojoDirection = direction == "in" ? TransferDirection::INBOUND : TransferDirection::OUTBOUND;
|
||||||
if (!convertDirectionFromEnum(direction, &webDirection)) {
|
const auto& endpoints = alternate->info().endpoints;
|
||||||
exceptionState.throwRangeError("Invalid endpoint direction.");
|
for (size_t i = 0; i < endpoints.size(); ++i) {
|
||||||
return nullptr;
|
const auto& endpoint = endpoints[i];
|
||||||
}
|
if (endpoint->endpoint_number == endpointNumber && endpoint->direction == mojoDirection)
|
||||||
for (size_t i = 0; i < alternate->info().endpoints.size(); ++i) {
|
|
||||||
const WebUSBDeviceInfo::Endpoint& endpoint = alternate->info().endpoints[i];
|
|
||||||
if (endpoint.endpointNumber == endpointNumber && endpoint.direction == webDirection)
|
|
||||||
return USBEndpoint::create(alternate, i);
|
return USBEndpoint::create(alternate, i);
|
||||||
}
|
}
|
||||||
exceptionState.throwRangeError("Invalid endpoint number.");
|
exceptionState.throwRangeError("No such endpoint exists in the given alternate interface.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,16 +73,11 @@ USBEndpoint::USBEndpoint(const USBAlternateInterface* alternate, size_t endpoint
|
|||||||
ASSERT(m_endpointIndex < m_alternate->info().endpoints.size());
|
ASSERT(m_endpointIndex < m_alternate->info().endpoints.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
const WebUSBDeviceInfo::Endpoint& USBEndpoint::info() const
|
const device::usb::wtf::EndpointInfo& USBEndpoint::info() const
|
||||||
{
|
{
|
||||||
const WebUSBDeviceInfo::AlternateInterface& alternateInfo = m_alternate->info();
|
const device::usb::wtf::AlternateInterfaceInfo& alternateInfo = m_alternate->info();
|
||||||
ASSERT(m_endpointIndex < alternateInfo.endpoints.size());
|
ASSERT(m_endpointIndex < alternateInfo.endpoints.size());
|
||||||
return alternateInfo.endpoints[m_endpointIndex];
|
return *alternateInfo.endpoints[m_endpointIndex];
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBEndpoint::endpointNumber() const
|
|
||||||
{
|
|
||||||
return info().endpointNumber;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String USBEndpoint::direction() const
|
String USBEndpoint::direction() const
|
||||||
@ -106,11 +90,6 @@ String USBEndpoint::type() const
|
|||||||
return convertTypeToEnum(info().type);
|
return convertTypeToEnum(info().type);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned USBEndpoint::packetSize() const
|
|
||||||
{
|
|
||||||
return info().packetSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_TRACE(USBEndpoint)
|
DEFINE_TRACE(USBEndpoint)
|
||||||
{
|
{
|
||||||
visitor->trace(m_alternate);
|
visitor->trace(m_alternate);
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#define USBEndpoint_h
|
#define USBEndpoint_h
|
||||||
|
|
||||||
#include "bindings/core/v8/ScriptWrappable.h"
|
#include "bindings/core/v8/ScriptWrappable.h"
|
||||||
|
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||||
#include "platform/heap/Heap.h"
|
#include "platform/heap/Heap.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
|
||||||
@ -24,12 +24,12 @@ public:
|
|||||||
|
|
||||||
USBEndpoint(const USBAlternateInterface*, size_t endpointIndex);
|
USBEndpoint(const USBAlternateInterface*, size_t endpointIndex);
|
||||||
|
|
||||||
const WebUSBDeviceInfo::Endpoint& info() const;
|
const device::usb::wtf::EndpointInfo& info() const;
|
||||||
|
|
||||||
uint8_t endpointNumber() const;
|
uint8_t endpointNumber() const { return info().endpoint_number; }
|
||||||
String direction() const;
|
String direction() const;
|
||||||
String type() const;
|
String type() const;
|
||||||
unsigned packetSize() const;
|
unsigned packetSize() const { return info().packet_size; }
|
||||||
|
|
||||||
DECLARE_TRACE();
|
DECLARE_TRACE();
|
||||||
|
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
// 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 "modules/webusb/USBError.h"
|
|
||||||
|
|
||||||
#include "core/dom/DOMException.h"
|
|
||||||
#include "core/dom/ExceptionCode.h"
|
|
||||||
#include "public/platform/modules/webusb/WebUSBError.h"
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
DOMException* USBError::take(ScriptPromiseResolver*, const WebUSBError& webError)
|
|
||||||
{
|
|
||||||
switch (webError.error) {
|
|
||||||
case WebUSBError::Error::InvalidState:
|
|
||||||
return DOMException::create(InvalidStateError, webError.message);
|
|
||||||
case WebUSBError::Error::Network:
|
|
||||||
return DOMException::create(NetworkError, webError.message);
|
|
||||||
case WebUSBError::Error::NotFound:
|
|
||||||
return DOMException::create(NotFoundError, webError.message);
|
|
||||||
case WebUSBError::Error::Security:
|
|
||||||
return DOMException::create(SecurityError, webError.message);
|
|
||||||
}
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
return DOMException::create(UnknownError);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace blink
|
|
@ -1,32 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef USBError_h
|
|
||||||
#define USBError_h
|
|
||||||
|
|
||||||
#include "platform/heap/Handle.h"
|
|
||||||
#include "public/platform/modules/webusb/WebUSBError.h"
|
|
||||||
#include "wtf/PassOwnPtr.h"
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
class DOMException;
|
|
||||||
class ScriptPromiseResolver;
|
|
||||||
|
|
||||||
// USBError is used with CallbackPromiseAdapter to receive WebUSBError
|
|
||||||
// responses. See CallbackPromiseAdapter class comments.
|
|
||||||
class USBError {
|
|
||||||
WTF_MAKE_NONCOPYABLE(USBError);
|
|
||||||
public:
|
|
||||||
// Interface required by CallbackPromiseAdapter:
|
|
||||||
using WebType = const WebUSBError&;
|
|
||||||
static DOMException* take(ScriptPromiseResolver*, const WebUSBError&);
|
|
||||||
|
|
||||||
private:
|
|
||||||
USBError() = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blink
|
|
||||||
|
|
||||||
#endif // USBError_h
|
|
@ -9,7 +9,7 @@
|
|||||||
#include "core/dom/DOMArrayBuffer.h"
|
#include "core/dom/DOMArrayBuffer.h"
|
||||||
#include "core/dom/DOMDataView.h"
|
#include "core/dom/DOMDataView.h"
|
||||||
#include "platform/heap/Handle.h"
|
#include "platform/heap/Handle.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBTransferInfo.h"
|
#include "wtf/Vector.h"
|
||||||
#include "wtf/text/WTFString.h"
|
#include "wtf/text/WTFString.h"
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
@ -19,12 +19,12 @@ class USBInTransferResult final
|
|||||||
, public ScriptWrappable {
|
, public ScriptWrappable {
|
||||||
DEFINE_WRAPPERTYPEINFO();
|
DEFINE_WRAPPERTYPEINFO();
|
||||||
public:
|
public:
|
||||||
static USBInTransferResult* create(const String& status, const WebVector<uint8_t> data)
|
static USBInTransferResult* create(const String& status, const Vector<uint8_t>& data)
|
||||||
{
|
{
|
||||||
return new USBInTransferResult(status, data);
|
return new USBInTransferResult(status, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
USBInTransferResult(const String& status, const WebVector<uint8_t> data)
|
USBInTransferResult(const String& status, const Vector<uint8_t>& data)
|
||||||
: m_status(status)
|
: m_status(status)
|
||||||
, m_data(DOMDataView::create(DOMArrayBuffer::create(data.data(), data.size()), 0, data.size()))
|
, m_data(DOMDataView::create(DOMArrayBuffer::create(data.data(), data.size()), 0, data.size()))
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "modules/webusb/USBInterface.h"
|
#include "modules/webusb/USBInterface.h"
|
||||||
|
|
||||||
#include "bindings/core/v8/ExceptionState.h"
|
#include "bindings/core/v8/ExceptionState.h"
|
||||||
|
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||||
#include "modules/webusb/USBAlternateInterface.h"
|
#include "modules/webusb/USBAlternateInterface.h"
|
||||||
#include "modules/webusb/USBConfiguration.h"
|
#include "modules/webusb/USBConfiguration.h"
|
||||||
#include "modules/webusb/USBDevice.h"
|
#include "modules/webusb/USBDevice.h"
|
||||||
@ -20,7 +21,7 @@ USBInterface* USBInterface::create(const USBConfiguration* configuration, size_t
|
|||||||
{
|
{
|
||||||
const auto& interfaces = configuration->info().interfaces;
|
const auto& interfaces = configuration->info().interfaces;
|
||||||
for (size_t i = 0; i < interfaces.size(); ++i) {
|
for (size_t i = 0; i < interfaces.size(); ++i) {
|
||||||
if (interfaces[i].interfaceNumber == interfaceNumber)
|
if (interfaces[i]->interface_number == interfaceNumber)
|
||||||
return new USBInterface(configuration->device(), configuration->index(), i);
|
return new USBInterface(configuration->device(), configuration->index(), i);
|
||||||
}
|
}
|
||||||
exceptionState.throwRangeError("Invalid interface index.");
|
exceptionState.throwRangeError("Invalid interface index.");
|
||||||
@ -33,12 +34,12 @@ USBInterface::USBInterface(const USBDevice* device, size_t configurationIndex, s
|
|||||||
, m_interfaceIndex(interfaceIndex)
|
, m_interfaceIndex(interfaceIndex)
|
||||||
{
|
{
|
||||||
ASSERT(m_configurationIndex < m_device->info().configurations.size());
|
ASSERT(m_configurationIndex < m_device->info().configurations.size());
|
||||||
ASSERT(m_interfaceIndex < m_device->info().configurations[m_configurationIndex].interfaces.size());
|
ASSERT(m_interfaceIndex < m_device->info().configurations[m_configurationIndex]->interfaces.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
const WebUSBDeviceInfo::Interface& USBInterface::info() const
|
const device::usb::wtf::InterfaceInfo& USBInterface::info() const
|
||||||
{
|
{
|
||||||
return m_device->info().configurations[m_configurationIndex].interfaces[m_interfaceIndex];
|
return *m_device->info().configurations[m_configurationIndex]->interfaces[m_interfaceIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
USBAlternateInterface* USBInterface::alternate() const
|
USBAlternateInterface* USBInterface::alternate() const
|
||||||
@ -56,11 +57,6 @@ HeapVector<Member<USBAlternateInterface>> USBInterface::alternates() const
|
|||||||
return alternates;
|
return alternates;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t USBInterface::interfaceNumber() const
|
|
||||||
{
|
|
||||||
return info().interfaceNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USBInterface::claimed() const
|
bool USBInterface::claimed() const
|
||||||
{
|
{
|
||||||
return m_device->isInterfaceClaimed(m_configurationIndex, m_interfaceIndex);
|
return m_device->isInterfaceClaimed(m_configurationIndex, m_interfaceIndex);
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#define USBInterface_h
|
#define USBInterface_h
|
||||||
|
|
||||||
#include "bindings/core/v8/ScriptWrappable.h"
|
#include "bindings/core/v8/ScriptWrappable.h"
|
||||||
|
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||||
#include "platform/heap/Heap.h"
|
#include "platform/heap/Heap.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
|
||||||
@ -26,9 +26,9 @@ public:
|
|||||||
|
|
||||||
USBInterface(const USBDevice*, size_t configurationIndex, size_t interfaceIndex);
|
USBInterface(const USBDevice*, size_t configurationIndex, size_t interfaceIndex);
|
||||||
|
|
||||||
const WebUSBDeviceInfo::Interface& info() const;
|
const device::usb::wtf::InterfaceInfo& info() const;
|
||||||
|
|
||||||
uint8_t interfaceNumber() const;
|
uint8_t interfaceNumber() const { return info().interface_number; }
|
||||||
USBAlternateInterface* alternate() const;
|
USBAlternateInterface* alternate() const;
|
||||||
HeapVector<Member<USBAlternateInterface>> alternates() const;
|
HeapVector<Member<USBAlternateInterface>> alternates() const;
|
||||||
bool claimed() const;
|
bool claimed() const;
|
||||||
|
@ -6,9 +6,7 @@
|
|||||||
#define USBOutTransferResult_h
|
#define USBOutTransferResult_h
|
||||||
|
|
||||||
#include "bindings/core/v8/ScriptWrappable.h"
|
#include "bindings/core/v8/ScriptWrappable.h"
|
||||||
#include "core/dom/DOMArrayBuffer.h"
|
|
||||||
#include "platform/heap/Handle.h"
|
#include "platform/heap/Handle.h"
|
||||||
#include "public/platform/modules/webusb/WebUSBTransferInfo.h"
|
|
||||||
#include "wtf/text/WTFString.h"
|
#include "wtf/text/WTFString.h"
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
16
third_party/WebKit/Source/platform/MojoHelper.h
vendored
16
third_party/WebKit/Source/platform/MojoHelper.h
vendored
@ -13,6 +13,16 @@
|
|||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename R, typename... Args>
|
||||||
|
R CallWTFFunction(Function<R(Args...)>* functor, Args... args)
|
||||||
|
{
|
||||||
|
return (*functor)(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Binds an instance of a class to its member function. Does not bind anything
|
// Binds an instance of a class to its member function. Does not bind anything
|
||||||
// else. Provides limited access to base::Bind() function. base::Bind() could
|
// else. Provides limited access to base::Bind() function. base::Bind() could
|
||||||
// be dangerous if it's used across threads, so we don't want to allow general
|
// be dangerous if it's used across threads, so we don't want to allow general
|
||||||
@ -24,6 +34,12 @@ sameThreadBindForMojo(ReturnType (Class::*method)(Args...), Class* instance)
|
|||||||
return base::Bind(method, base::Unretained(instance));
|
return base::Bind(method, base::Unretained(instance));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename R, typename... Args>
|
||||||
|
base::Callback<R(Args...)> createBaseCallback(PassOwnPtr<Function<R(Args...)>> functor)
|
||||||
|
{
|
||||||
|
return base::Bind(&internal::CallWTFFunction<R, Args...>, base::Owned(functor.leakPtr()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blink
|
} // namespace blink
|
||||||
|
|
||||||
namespace mojo {
|
namespace mojo {
|
||||||
|
@ -166,7 +166,6 @@
|
|||||||
#include "modules/screen_orientation/ScreenOrientationController.h"
|
#include "modules/screen_orientation/ScreenOrientationController.h"
|
||||||
#include "modules/vr/VRController.h"
|
#include "modules/vr/VRController.h"
|
||||||
#include "modules/wake_lock/ScreenWakeLock.h"
|
#include "modules/wake_lock/ScreenWakeLock.h"
|
||||||
#include "modules/webusb/USBController.h"
|
|
||||||
#include "platform/ScriptForbiddenScope.h"
|
#include "platform/ScriptForbiddenScope.h"
|
||||||
#include "platform/TraceEvent.h"
|
#include "platform/TraceEvent.h"
|
||||||
#include "platform/UserGestureIndicator.h"
|
#include "platform/UserGestureIndicator.h"
|
||||||
@ -1478,10 +1477,6 @@ void WebLocalFrameImpl::setCoreFrame(LocalFrame* frame)
|
|||||||
provideLocalFileSystemTo(*m_frame, LocalFileSystemClient::create());
|
provideLocalFileSystemTo(*m_frame, LocalFileSystemClient::create());
|
||||||
provideNavigatorContentUtilsTo(*m_frame, NavigatorContentUtilsClientImpl::create(this));
|
provideNavigatorContentUtilsTo(*m_frame, NavigatorContentUtilsClientImpl::create(this));
|
||||||
|
|
||||||
// Always provided so that availability of the API can be controlled by
|
|
||||||
// OriginTrials::webUSBEnabled().
|
|
||||||
USBController::provideTo(*m_frame, m_client ? m_client->usbClient() : nullptr);
|
|
||||||
|
|
||||||
bool enableWebBluetooth = RuntimeEnabledFeatures::webBluetoothEnabled();
|
bool enableWebBluetooth = RuntimeEnabledFeatures::webBluetoothEnabled();
|
||||||
#if OS(CHROMEOS) || OS(ANDROID)
|
#if OS(CHROMEOS) || OS(ANDROID)
|
||||||
enableWebBluetooth = true;
|
enableWebBluetooth = true;
|
||||||
|
7
third_party/WebKit/public/blink_headers.gypi
vendored
7
third_party/WebKit/public/blink_headers.gypi
vendored
@ -319,13 +319,6 @@
|
|||||||
"platform/modules/websockets/WebSocketHandleClient.h",
|
"platform/modules/websockets/WebSocketHandleClient.h",
|
||||||
"platform/modules/websockets/WebSocketHandshakeRequestInfo.h",
|
"platform/modules/websockets/WebSocketHandshakeRequestInfo.h",
|
||||||
"platform/modules/websockets/WebSocketHandshakeResponseInfo.h",
|
"platform/modules/websockets/WebSocketHandshakeResponseInfo.h",
|
||||||
"platform/modules/webusb/WebUSBClient.h",
|
|
||||||
"platform/modules/webusb/WebUSBDeviceFilter.h",
|
|
||||||
"platform/modules/webusb/WebUSBDevice.h",
|
|
||||||
"platform/modules/webusb/WebUSBDeviceInfo.h",
|
|
||||||
"platform/modules/webusb/WebUSBDeviceRequestOptions.h",
|
|
||||||
"platform/modules/webusb/WebUSBError.h",
|
|
||||||
"platform/modules/webusb/WebUSBTransferInfo.h",
|
|
||||||
"web/WebAXEnums.h",
|
"web/WebAXEnums.h",
|
||||||
"web/WebAXObject.h",
|
"web/WebAXObject.h",
|
||||||
"web/WebActiveWheelFlingParameters.h",
|
"web/WebActiveWheelFlingParameters.h",
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
reillyg@chromium.org
|
|
||||||
rockot@chromium.org
|
|
@ -1,52 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef WebUSBClient_h
|
|
||||||
#define WebUSBClient_h
|
|
||||||
|
|
||||||
#include "public/platform/WebCallbacks.h"
|
|
||||||
#include "public/platform/WebVector.h"
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
class WebUSBDevice;
|
|
||||||
struct WebUSBDeviceRequestOptions;
|
|
||||||
struct WebUSBError;
|
|
||||||
|
|
||||||
using WebUSBClientGetDevicesCallbacks = WebCallbacks<std::unique_ptr<WebVector<WebUSBDevice*>>, const WebUSBError&>;
|
|
||||||
using WebUSBClientRequestDeviceCallbacks = WebCallbacks<std::unique_ptr<WebUSBDevice>, const WebUSBError&>;
|
|
||||||
|
|
||||||
class WebUSBClient {
|
|
||||||
public:
|
|
||||||
class Observer {
|
|
||||||
public:
|
|
||||||
virtual ~Observer() { }
|
|
||||||
|
|
||||||
// Called when a device is connected to the system.
|
|
||||||
virtual void onDeviceConnected(std::unique_ptr<WebUSBDevice>) = 0;
|
|
||||||
|
|
||||||
// Called when a device is disconnected from the system.
|
|
||||||
virtual void onDeviceDisconnected(std::unique_ptr<WebUSBDevice>) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~WebUSBClient() { }
|
|
||||||
|
|
||||||
// Enumerates available devices.
|
|
||||||
// Ownership of the WebUSBClientGetDevicesCallbacks is transferred to the client.
|
|
||||||
virtual void getDevices(WebUSBClientGetDevicesCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Requests access to a device.
|
|
||||||
// Ownership of the WebUSBClientRequestDeviceCallbacks is transferred to the client.
|
|
||||||
virtual void requestDevice(const WebUSBDeviceRequestOptions&, WebUSBClientRequestDeviceCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Adds an observer of device changes to the WebUSBClient.
|
|
||||||
virtual void addObserver(Observer*) = 0;
|
|
||||||
|
|
||||||
// Removes an observer of device changes from the WebUSBClient.
|
|
||||||
virtual void removeObserver(Observer*) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blink
|
|
||||||
|
|
||||||
#endif // WebUSBClient_h
|
|
@ -1,109 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef WebUSBDevice_h
|
|
||||||
#define WebUSBDevice_h
|
|
||||||
|
|
||||||
#include "public/platform/WebCallbacks.h"
|
|
||||||
#include "public/platform/WebVector.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
struct WebUSBDeviceInfo;
|
|
||||||
struct WebUSBError;
|
|
||||||
struct WebUSBTransferInfo;
|
|
||||||
|
|
||||||
using WebUSBDeviceOpenCallbacks = WebCallbacks<void, const WebUSBError&>;
|
|
||||||
using WebUSBDeviceCloseCallbacks = WebCallbacks<void, const WebUSBError&>;
|
|
||||||
using WebUSBDeviceSetConfigurationCallbacks = WebCallbacks<void, const WebUSBError&>;
|
|
||||||
using WebUSBDeviceClaimInterfaceCallbacks = WebCallbacks<void, const WebUSBError&>;
|
|
||||||
using WebUSBDeviceReleaseInterfaceCallbacks = WebCallbacks<void, const WebUSBError&>;
|
|
||||||
using WebUSBDeviceResetCallbacks = WebCallbacks<void, const WebUSBError&>;
|
|
||||||
using WebUSBDeviceSetInterfaceAlternateSettingCallbacks = WebCallbacks<void, const WebUSBError&>;
|
|
||||||
using WebUSBDeviceClearHaltCallbacks = WebCallbacks<void, const WebUSBError&>;
|
|
||||||
using WebUSBDeviceTransferCallbacks = WebCallbacks<std::unique_ptr<WebUSBTransferInfo>, const WebUSBError&>;
|
|
||||||
|
|
||||||
class WebUSBDevice {
|
|
||||||
public:
|
|
||||||
enum class TransferDirection {
|
|
||||||
In,
|
|
||||||
Out,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class RequestType {
|
|
||||||
Standard,
|
|
||||||
Class,
|
|
||||||
Vendor,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class RequestRecipient {
|
|
||||||
Device,
|
|
||||||
Interface,
|
|
||||||
Endpoint,
|
|
||||||
Other,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ControlTransferParameters {
|
|
||||||
TransferDirection direction;
|
|
||||||
RequestType type;
|
|
||||||
RequestRecipient recipient;
|
|
||||||
uint8_t request;
|
|
||||||
uint16_t value;
|
|
||||||
uint16_t index;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~WebUSBDevice() { }
|
|
||||||
|
|
||||||
virtual const WebUSBDeviceInfo& info() const = 0;
|
|
||||||
|
|
||||||
// Opens the device.
|
|
||||||
// Ownership of the WebUSBDeviceOpenCallbacks is transferred to the client.
|
|
||||||
virtual void open(WebUSBDeviceOpenCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Closes the device.
|
|
||||||
// Ownership of the WebUSBDeviceCloseCallbacks is transferred to the client.
|
|
||||||
virtual void close(WebUSBDeviceCloseCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Sets the active configuration for the device.
|
|
||||||
// Ownership of the WebUSBDeviceSetConfigurationCallbacks is transferred to the client.
|
|
||||||
virtual void setConfiguration(uint8_t configurationValue, WebUSBDeviceSetConfigurationCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Claims an interface in the active configuration.
|
|
||||||
// Ownership of the WebUSBDeviceClaimInterfaceCallbacks is transferred to the client.
|
|
||||||
virtual void claimInterface(uint8_t interfaceNumber, WebUSBDeviceClaimInterfaceCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Releases a claimed interface.
|
|
||||||
// Ownership of the WebUSBDeviceReleaseInterfaceCallbacks is transferred to the client.
|
|
||||||
virtual void releaseInterface(uint8_t interfaceNumber, WebUSBDeviceReleaseInterfaceCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Sets the alternate setting of an interface.
|
|
||||||
// Ownership of the WebUSBDeviceSetInterfaceAlternateSettingCallbacks is transferred to the client.
|
|
||||||
virtual void setInterface(uint8_t interfaceNumber, uint8_t alternateSetting, WebUSBDeviceSetInterfaceAlternateSettingCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Clears the halt condition on a specific endpoint.
|
|
||||||
// Ownership of the WebUSBDeviceClearHaltCallbacks is transferred to the client.
|
|
||||||
virtual void clearHalt(uint8_t endpointNumber, WebUSBDeviceClearHaltCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Initiates a control transfer.
|
|
||||||
// Ownership of the WebUSBDeviceTransferCallbacks is transferred to the client.
|
|
||||||
virtual void controlTransfer(const ControlTransferParameters&, uint8_t* data, size_t dataSize, unsigned timeout, WebUSBDeviceTransferCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Initiates a bulk or interrupt transfer.
|
|
||||||
// Ownership of the WebUSBDeviceTransferCallbacks is transferred to the client.
|
|
||||||
virtual void transfer(TransferDirection, uint8_t endpointNumber, uint8_t* data, size_t dataSize, unsigned timeout, WebUSBDeviceTransferCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Initiates an isochronous transfer.
|
|
||||||
// Ownership of the WebUSBDeviceTransferCallbacks is transferred to the client.
|
|
||||||
virtual void isochronousTransfer(TransferDirection, uint8_t endpointNumber, uint8_t* data, size_t dataSize, WebVector<unsigned> packetLengths, unsigned timeout, WebUSBDeviceTransferCallbacks*) = 0;
|
|
||||||
|
|
||||||
// Resets the device.
|
|
||||||
// Ownership of the WebUSBDeviceResetCallbacks is transferred to the client.
|
|
||||||
virtual void reset(WebUSBDeviceResetCallbacks*) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blink
|
|
||||||
|
|
||||||
#endif // WebUSBDevice_h
|
|
@ -1,34 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef WebUSBDeviceFilter_h
|
|
||||||
#define WebUSBDeviceFilter_h
|
|
||||||
|
|
||||||
#include "public/platform/WebCommon.h"
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
// Filter which specifies what devices the API consumer wants to enumerate.
|
|
||||||
// Properties which are not present in a filter should be treated as wildcards.
|
|
||||||
struct WebUSBDeviceFilter {
|
|
||||||
WebUSBDeviceFilter() {}
|
|
||||||
|
|
||||||
// Members corresponding to USBDeviceFilter properties specified in the IDL.
|
|
||||||
uint16_t vendorID;
|
|
||||||
uint16_t productID;
|
|
||||||
uint8_t classCode;
|
|
||||||
uint8_t subclassCode;
|
|
||||||
uint8_t protocolCode;
|
|
||||||
|
|
||||||
// Presence flags for each of the above properties.
|
|
||||||
bool hasVendorID : 1;
|
|
||||||
bool hasProductID : 1;
|
|
||||||
bool hasClassCode : 1;
|
|
||||||
bool hasSubclassCode : 1;
|
|
||||||
bool hasProtocolCode : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blink
|
|
||||||
|
|
||||||
#endif // WebUSBDeviceFilter_h
|
|
@ -1,110 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef WebUSBDeviceInfo_h
|
|
||||||
#define WebUSBDeviceInfo_h
|
|
||||||
|
|
||||||
#include "public/platform/WebString.h"
|
|
||||||
#include "public/platform/WebVector.h"
|
|
||||||
#include "public/platform/modules/webusb/WebUSBDevice.h"
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
struct WebUSBDeviceInfo {
|
|
||||||
struct Endpoint {
|
|
||||||
enum class Type {
|
|
||||||
Bulk,
|
|
||||||
Interrupt,
|
|
||||||
Isochronous
|
|
||||||
};
|
|
||||||
|
|
||||||
Endpoint()
|
|
||||||
: endpointNumber(0)
|
|
||||||
, direction(WebUSBDevice::TransferDirection::In)
|
|
||||||
, type(Type::Bulk)
|
|
||||||
, packetSize(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t endpointNumber;
|
|
||||||
WebUSBDevice::TransferDirection direction;
|
|
||||||
Type type;
|
|
||||||
uint32_t packetSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AlternateInterface {
|
|
||||||
AlternateInterface()
|
|
||||||
: alternateSetting(0)
|
|
||||||
, classCode(0)
|
|
||||||
, subclassCode(0)
|
|
||||||
, protocolCode(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t alternateSetting;
|
|
||||||
uint8_t classCode;
|
|
||||||
uint8_t subclassCode;
|
|
||||||
uint8_t protocolCode;
|
|
||||||
WebString interfaceName;
|
|
||||||
WebVector<Endpoint> endpoints;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Interface {
|
|
||||||
Interface()
|
|
||||||
: interfaceNumber(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t interfaceNumber;
|
|
||||||
WebVector<AlternateInterface> alternates;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Configuration {
|
|
||||||
Configuration()
|
|
||||||
: configurationValue(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t configurationValue;
|
|
||||||
WebString configurationName;
|
|
||||||
WebVector<Interface> interfaces;
|
|
||||||
};
|
|
||||||
|
|
||||||
WebUSBDeviceInfo()
|
|
||||||
: usbVersionMajor(0)
|
|
||||||
, usbVersionMinor(0)
|
|
||||||
, usbVersionSubminor(0)
|
|
||||||
, deviceClass(0)
|
|
||||||
, deviceSubclass(0)
|
|
||||||
, deviceProtocol(0)
|
|
||||||
, vendorID(0)
|
|
||||||
, productID(0)
|
|
||||||
, deviceVersionMajor(0)
|
|
||||||
, deviceVersionMinor(0)
|
|
||||||
, deviceVersionSubminor(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
WebString guid;
|
|
||||||
uint8_t usbVersionMajor;
|
|
||||||
uint8_t usbVersionMinor;
|
|
||||||
uint8_t usbVersionSubminor;
|
|
||||||
uint8_t deviceClass;
|
|
||||||
uint8_t deviceSubclass;
|
|
||||||
uint8_t deviceProtocol;
|
|
||||||
uint16_t vendorID;
|
|
||||||
uint16_t productID;
|
|
||||||
uint8_t deviceVersionMajor;
|
|
||||||
uint8_t deviceVersionMinor;
|
|
||||||
uint8_t deviceVersionSubminor;
|
|
||||||
WebString manufacturerName;
|
|
||||||
WebString productName;
|
|
||||||
WebString serialNumber;
|
|
||||||
uint8_t activeConfiguration;
|
|
||||||
WebVector<Configuration> configurations;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blink
|
|
||||||
|
|
||||||
#endif // WebUSBDeviceInfo_h
|
|
@ -1,20 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef WebUSBDeviceRequestOptions_h
|
|
||||||
#define WebUSBDeviceRequestOptions_h
|
|
||||||
|
|
||||||
#include "public/platform/WebVector.h"
|
|
||||||
#include "public/platform/modules/webusb/WebUSBDeviceFilter.h"
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
// Options which constrain the kind of devices the user is prompted to select.
|
|
||||||
struct WebUSBDeviceRequestOptions {
|
|
||||||
WebVector<WebUSBDeviceFilter> filters;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blink
|
|
||||||
|
|
||||||
#endif // WebUSBDeviceRequestOptions_h
|
|
@ -1,34 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef WebUSBError_h
|
|
||||||
#define WebUSBError_h
|
|
||||||
|
|
||||||
#include "public/platform/WebString.h"
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
// Error object used to create DOMExceptions when a Web USB request cannot be
|
|
||||||
// satisfied.
|
|
||||||
struct WebUSBError {
|
|
||||||
enum class Error {
|
|
||||||
InvalidState,
|
|
||||||
Network,
|
|
||||||
NotFound,
|
|
||||||
Security,
|
|
||||||
};
|
|
||||||
|
|
||||||
WebUSBError(Error error, const WebString& message)
|
|
||||||
: error(error)
|
|
||||||
, message(message)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Error error;
|
|
||||||
WebString message;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blink
|
|
||||||
|
|
||||||
#endif // WebUSBError_h
|
|
@ -1,43 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef WebUSBTransferInfo_h
|
|
||||||
#define WebUSBTransferInfo_h
|
|
||||||
|
|
||||||
#include "public/platform/WebVector.h"
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
|
|
||||||
struct WebUSBTransferInfo {
|
|
||||||
enum class Status {
|
|
||||||
Ok,
|
|
||||||
Stall,
|
|
||||||
Babble,
|
|
||||||
};
|
|
||||||
|
|
||||||
WebUSBTransferInfo()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Individual packet statuses. This vector has only one element if this is
|
|
||||||
// not an isochronous transfer.
|
|
||||||
WebVector<Status> status;
|
|
||||||
|
|
||||||
// Data received, if this is an inbound transfer.
|
|
||||||
WebVector<uint8_t> data;
|
|
||||||
|
|
||||||
// Requested length of each packet if this is an inbound isochronous
|
|
||||||
// transfer.
|
|
||||||
WebVector<uint32_t> packetLength;
|
|
||||||
|
|
||||||
// Number of bytes written if this is an outbound transfer. This vector has
|
|
||||||
// only one element if this is not an isochronous transfer otherwise it is
|
|
||||||
// the number of bytes transferred in each isochronous packet (inbound or
|
|
||||||
// outbound).
|
|
||||||
WebVector<uint32_t> bytesTransferred;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blink
|
|
||||||
|
|
||||||
#endif // WebUSBTransferInfo_h
|
|
@ -97,7 +97,6 @@ class WebScreenOrientationClient;
|
|||||||
class WebString;
|
class WebString;
|
||||||
class WebURL;
|
class WebURL;
|
||||||
class WebURLResponse;
|
class WebURLResponse;
|
||||||
class WebUSBClient;
|
|
||||||
class WebUserMediaClient;
|
class WebUserMediaClient;
|
||||||
class WebVRClient;
|
class WebVRClient;
|
||||||
class WebWorkerContentSettingsClientProxy;
|
class WebWorkerContentSettingsClientProxy;
|
||||||
@ -710,9 +709,6 @@ public:
|
|||||||
// Bluetooth -----------------------------------------------------------
|
// Bluetooth -----------------------------------------------------------
|
||||||
virtual WebBluetooth* bluetooth() { return 0; }
|
virtual WebBluetooth* bluetooth() { return 0; }
|
||||||
|
|
||||||
// WebUSB --------------------------------------------------------------
|
|
||||||
virtual WebUSBClient* usbClient() { return nullptr; }
|
|
||||||
|
|
||||||
|
|
||||||
// Audio Output Devices API --------------------------------------------
|
// Audio Output Devices API --------------------------------------------
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user