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',
|
||||
'../device/battery/battery.gyp:device_battery',
|
||||
'../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_mojo_bindings',
|
||||
'../gin/gin.gyp:gin',
|
||||
@ -465,12 +464,6 @@
|
||||
'renderer/theme_helper_mac.mm',
|
||||
'renderer/top_level_blame_context.cc',
|
||||
'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.h',
|
||||
'renderer/web_ui_extension.cc',
|
||||
|
@ -125,7 +125,6 @@
|
||||
#include "content/renderer/shared_worker_repository.h"
|
||||
#include "content/renderer/skia_benchmarking_extension.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_ui_extension.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/WebURLResponse.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/WebDocument.h"
|
||||
#include "third_party/WebKit/public/web/WebFindOptions.h"
|
||||
@ -4285,16 +4283,6 @@ blink::WebBluetooth* RenderFrameImpl::bluetooth() {
|
||||
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)
|
||||
blink::WebVRClient* RenderFrameImpl::webVRClient() {
|
||||
if (!vr_dispatcher_)
|
||||
|
@ -616,7 +616,6 @@ class CONTENT_EXPORT RenderFrameImpl
|
||||
void unregisterProtocolHandler(const blink::WebString& scheme,
|
||||
const blink::WebURL& url) override;
|
||||
blink::WebBluetooth* bluetooth() override;
|
||||
blink::WebUSBClient* usbClient() override;
|
||||
void checkIfAudioSinkExistsAndIsAuthorized(
|
||||
const blink::WebString& sink_id,
|
||||
const blink::WebSecurityOrigin& security_origin,
|
||||
@ -1193,8 +1192,6 @@ class CONTENT_EXPORT RenderFrameImpl
|
||||
|
||||
std::unique_ptr<blink::WebBluetooth> bluetooth_;
|
||||
|
||||
std::unique_ptr<blink::WebUSBClient> usb_client_;
|
||||
|
||||
// Manages play, pause notifications for WebMediaPlayer implementations; its
|
||||
// lifetime is tied to the RenderFrame via the RenderFrameObserver interface.
|
||||
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")
|
||||
|
||||
mojom_files = [
|
||||
"chooser_service.mojom",
|
||||
"device.mojom",
|
||||
"device_manager.mojom",
|
||||
]
|
||||
|
||||
mojom("interfaces") {
|
||||
sources = [
|
||||
"chooser_service.mojom",
|
||||
"device.mojom",
|
||||
"device_manager.mojom",
|
||||
]
|
||||
sources = mojom_files
|
||||
}
|
||||
|
@ -5,6 +5,11 @@
|
||||
{
|
||||
'variables': {
|
||||
'chromium_code': 1,
|
||||
'mojom_files': [
|
||||
'public/interfaces/chooser_service.mojom',
|
||||
'public/interfaces/device.mojom',
|
||||
'public/interfaces/device_manager.mojom',
|
||||
],
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
@ -141,11 +146,19 @@
|
||||
{
|
||||
'target_name': 'device_usb_mojo_bindings',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'public/interfaces/chooser_service.mojom',
|
||||
'public/interfaces/device.mojom',
|
||||
'public/interfaces/device_manager.mojom',
|
||||
'sources': [ '<@(mojom_files)' ],
|
||||
'includes': [
|
||||
'../../mojo/mojom_bindings_generator.gypi',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'device_usb_mojo_bindings_for_blink',
|
||||
'type': 'static_library',
|
||||
'sources': [ '<@(mojom_files)' ],
|
||||
'variables': {
|
||||
'mojom_variant': 'wtf',
|
||||
'for_blink': 'true',
|
||||
},
|
||||
'includes': [
|
||||
'../../mojo/mojom_bindings_generator.gypi',
|
||||
],
|
||||
|
@ -244,7 +244,6 @@ usb_test(usb => {
|
||||
});
|
||||
}, 'a non-existent interface cannot be claimed or released');
|
||||
|
||||
|
||||
usb_test(usb => {
|
||||
usb.mockDeviceManager.addMockDevice(usb.fakeDevices[0]);
|
||||
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 = [
|
||||
":make_modules_generated",
|
||||
"//device/battery:mojo_bindings",
|
||||
"//device/usb/public/interfaces:interfaces_wtf",
|
||||
"//mojo/public/c/system:for_component",
|
||||
"//third_party/WebKit/Source/core",
|
||||
"//third_party/WebKit/public:mojo_bindings_wtf",
|
||||
|
@ -40,6 +40,7 @@
|
||||
'target_name': 'modules',
|
||||
'dependencies': [
|
||||
'<(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_public.gyp:mojo_cpp_bindings',
|
||||
'<(DEPTH)/third_party/icu/icu.gyp:icui18n',
|
||||
|
@ -1907,14 +1907,10 @@
|
||||
'webusb/USBConfiguration.h',
|
||||
'webusb/USBConnectionEvent.cpp',
|
||||
'webusb/USBConnectionEvent.h',
|
||||
'webusb/USBController.cpp',
|
||||
'webusb/USBController.h',
|
||||
'webusb/USBDevice.cpp',
|
||||
'webusb/USBDevice.h',
|
||||
'webusb/USBEndpoint.cpp',
|
||||
'webusb/USBEndpoint.h',
|
||||
'webusb/USBError.cpp',
|
||||
'webusb/USBError.h',
|
||||
'webusb/USBInTransferResult.h',
|
||||
'webusb/USBInterface.cpp',
|
||||
'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 "bindings/core/v8/CallbackPromiseAdapter.h"
|
||||
#include "bindings/core/v8/ScriptPromise.h"
|
||||
#include "bindings/core/v8/ScriptPromiseResolver.h"
|
||||
#include "core/dom/DOMException.h"
|
||||
#include "core/dom/Document.h"
|
||||
#include "core/dom/ExceptionCode.h"
|
||||
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||
#include "modules/EventTargetModules.h"
|
||||
#include "modules/webusb/USBConnectionEvent.h"
|
||||
#include "modules/webusb/USBController.h"
|
||||
#include "modules/webusb/USBDevice.h"
|
||||
#include "modules/webusb/USBDeviceFilter.h"
|
||||
#include "modules/webusb/USBDeviceRequestOptions.h"
|
||||
#include "modules/webusb/USBError.h"
|
||||
#include "platform/MojoHelper.h"
|
||||
#include "platform/UserGestureIndicator.h"
|
||||
#include "public/platform/Platform.h"
|
||||
#include "public/platform/WebVector.h"
|
||||
#include "public/platform/modules/webusb/WebUSBClient.h"
|
||||
#include "public/platform/modules/webusb/WebUSBDeviceFilter.h"
|
||||
#include "public/platform/modules/webusb/WebUSBDeviceRequestOptions.h"
|
||||
#include "public/platform/modules/webusb/WebUSBError.h"
|
||||
#include "public/platform/ServiceRegistry.h"
|
||||
#include "wtf/Functional.h"
|
||||
|
||||
namespace usb = device::usb::wtf;
|
||||
|
||||
namespace blink {
|
||||
namespace {
|
||||
|
||||
void convertDeviceFilter(const USBDeviceFilter& filter, WebUSBDeviceFilter* webFilter)
|
||||
const char kNoServiceError[] = "USB service unavailable.";
|
||||
|
||||
usb::DeviceFilterPtr convertDeviceFilter(const USBDeviceFilter& filter)
|
||||
{
|
||||
webFilter->hasVendorID = filter.hasVendorId();
|
||||
if (filter.hasVendorId())
|
||||
webFilter->vendorID = filter.vendorId();
|
||||
webFilter->hasProductID = filter.hasProductId();
|
||||
if (filter.hasProductId())
|
||||
webFilter->productID = filter.productId();
|
||||
webFilter->hasClassCode = filter.hasClassCode();
|
||||
if (filter.hasClassCode())
|
||||
webFilter->classCode = filter.classCode();
|
||||
webFilter->hasSubclassCode = filter.hasSubclassCode();
|
||||
if (filter.hasSubclassCode())
|
||||
webFilter->subclassCode = filter.subclassCode();
|
||||
webFilter->hasProtocolCode = filter.hasProtocolCode();
|
||||
if (filter.hasProtocolCode())
|
||||
webFilter->protocolCode = filter.protocolCode();
|
||||
auto mojoFilter = usb::DeviceFilter::New();
|
||||
mojoFilter->has_vendor_id = filter.hasVendorId();
|
||||
if (mojoFilter->has_vendor_id)
|
||||
mojoFilter->vendor_id = filter.vendorId();
|
||||
mojoFilter->has_product_id = filter.hasProductId();
|
||||
if (mojoFilter->has_product_id)
|
||||
mojoFilter->product_id = filter.productId();
|
||||
mojoFilter->has_class_code = filter.hasClassCode();
|
||||
if (mojoFilter->has_class_code)
|
||||
mojoFilter->class_code = filter.classCode();
|
||||
mojoFilter->has_subclass_code = filter.hasSubclassCode();
|
||||
if (mojoFilter->has_subclass_code)
|
||||
mojoFilter->subclass_code = filter.subclassCode();
|
||||
mojoFilter->has_protocol_code = filter.hasProtocolCode();
|
||||
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());
|
||||
webOptions->filters = WebVector<WebUSBDeviceFilter>(options.filters().size());
|
||||
for (size_t i = 0; i < options.filters().size(); ++i) {
|
||||
convertDeviceFilter(options.filters()[i], &webOptions->filters[i]);
|
||||
}
|
||||
ExecutionContext* context = resolver->getExecutionContext();
|
||||
return context && !context->activeDOMObjectsAreStopped();
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
USB::USB(LocalFrame& frame)
|
||||
: ContextLifecycleObserver(frame.document())
|
||||
, m_client(USBController::from(frame).client())
|
||||
{
|
||||
ThreadState::current()->registerPreFinalizer(this);
|
||||
if (m_client)
|
||||
m_client->addObserver(this);
|
||||
frame.serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_deviceManager));
|
||||
m_deviceManager.set_connection_error_handler([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()
|
||||
{
|
||||
}
|
||||
|
||||
void USB::dispose()
|
||||
{
|
||||
// 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;
|
||||
DCHECK(!m_deviceManager);
|
||||
DCHECK(m_deviceManagerRequests.isEmpty());
|
||||
DCHECK(!m_chooserService);
|
||||
DCHECK(m_chooserServiceRequests.isEmpty());
|
||||
}
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
ScriptPromise promise = resolver->promise();
|
||||
|
||||
WebUSBDeviceRequestOptions webOptions;
|
||||
convertDeviceRequestOptions(options, &webOptions);
|
||||
m_client->requestDevice(webOptions, new CallbackPromiseAdapter<USBDevice, USBError>(resolver));
|
||||
if (!m_chooserService) {
|
||||
LocalFrame* frame = getExecutionContext() ? toDocument(getExecutionContext())->frame() : nullptr;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -146,25 +151,59 @@ const AtomicString& USB::interfaceName() const
|
||||
|
||||
void USB::contextDestroyed()
|
||||
{
|
||||
if (m_client)
|
||||
m_client->removeObserver(this);
|
||||
m_client = nullptr;
|
||||
m_deviceManager.reset();
|
||||
m_deviceManagerRequests.clear();
|
||||
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)
|
||||
{
|
||||
EventTargetWithInlineData::trace(visitor);
|
||||
ContextLifecycleObserver::trace(visitor);
|
||||
visitor->trace(m_deviceManagerRequests);
|
||||
visitor->trace(m_chooserServiceRequests);
|
||||
}
|
||||
|
||||
} // 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 "core/dom/ContextLifecycleObserver.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 "public/platform/modules/webusb/WebUSBClient.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class LocalFrame;
|
||||
class ScopedScriptPromiseResolver;
|
||||
class ScriptState;
|
||||
class USBDeviceRequestOptions;
|
||||
class WebUSBDevice;
|
||||
|
||||
class USB final
|
||||
: public EventTargetWithInlineData
|
||||
, public ContextLifecycleObserver
|
||||
, public WebUSBClient::Observer {
|
||||
, public ContextLifecycleObserver {
|
||||
DEFINE_WRAPPERTYPEINFO();
|
||||
USING_GARBAGE_COLLECTED_MIXIN(USB);
|
||||
USING_PRE_FINALIZER(USB, dispose);
|
||||
public:
|
||||
static USB* create(LocalFrame& frame)
|
||||
{
|
||||
return new USB(frame);
|
||||
}
|
||||
|
||||
~USB() override;
|
||||
virtual ~USB();
|
||||
|
||||
// USB.idl
|
||||
ScriptPromise getDevices(ScriptState*);
|
||||
@ -47,17 +46,21 @@ public:
|
||||
// ContextLifecycleObserver overrides.
|
||||
void contextDestroyed() override;
|
||||
|
||||
// WebUSBClient::Observer overrides.
|
||||
void onDeviceConnected(std::unique_ptr<WebUSBDevice>) override;
|
||||
void onDeviceDisconnected(std::unique_ptr<WebUSBDevice>) override;
|
||||
device::usb::wtf::DeviceManager* deviceManager() const { return m_deviceManager.get(); }
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
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
|
||||
|
@ -17,8 +17,9 @@ USBAlternateInterface* USBAlternateInterface::create(const USBInterface* interfa
|
||||
|
||||
USBAlternateInterface* USBAlternateInterface::create(const USBInterface* interface, size_t alternateSetting, ExceptionState& exceptionState)
|
||||
{
|
||||
for (size_t i = 0; i < interface->info().alternates.size(); ++i) {
|
||||
if (interface->info().alternates[i].alternateSetting == alternateSetting)
|
||||
const auto& alternates = interface->info().alternates;
|
||||
for (size_t i = 0; i < alternates.size(); ++i) {
|
||||
if (alternates[i]->alternate_setting == alternateSetting)
|
||||
return USBAlternateInterface::create(interface, i);
|
||||
}
|
||||
exceptionState.throwRangeError("Invalid alternate setting.");
|
||||
@ -33,36 +34,11 @@ USBAlternateInterface::USBAlternateInterface(const USBInterface* interface, 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());
|
||||
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;
|
||||
return *interfaceInfo.alternates[m_alternateIndex];
|
||||
}
|
||||
|
||||
HeapVector<Member<USBEndpoint>> USBAlternateInterface::endpoints() const
|
||||
|
@ -6,8 +6,8 @@
|
||||
#define USBAlternateInterface_h
|
||||
|
||||
#include "bindings/core/v8/ScriptWrappable.h"
|
||||
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||
#include "platform/heap/Heap.h"
|
||||
#include "public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@ -25,13 +25,13 @@ public:
|
||||
|
||||
USBAlternateInterface(const USBInterface*, size_t alternateIndex);
|
||||
|
||||
const WebUSBDeviceInfo::AlternateInterface& info() const;
|
||||
const device::usb::wtf::AlternateInterfaceInfo& info() const;
|
||||
|
||||
uint8_t alternateSetting() const;
|
||||
uint8_t interfaceClass() const;
|
||||
uint8_t interfaceSubclass() const;
|
||||
uint8_t interfaceProtocol() const;
|
||||
String interfaceName() const;
|
||||
uint8_t alternateSetting() const { return info().alternate_setting; }
|
||||
uint8_t interfaceClass() const { return info().class_code; }
|
||||
uint8_t interfaceSubclass() const { return info().subclass_code; }
|
||||
uint8_t interfaceProtocol() const { return info().protocol_code; }
|
||||
String interfaceName() const { return info().interface_name; }
|
||||
HeapVector<Member<USBEndpoint>> endpoints() const;
|
||||
|
||||
DECLARE_TRACE();
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "modules/webusb/USBConfiguration.h"
|
||||
|
||||
#include "bindings/core/v8/ExceptionState.h"
|
||||
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||
#include "modules/webusb/USBDevice.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)
|
||||
{
|
||||
for (size_t i = 0; i < device->info().configurations.size(); ++i) {
|
||||
if (device->info().configurations[i].configurationValue == configurationValue)
|
||||
const auto& configurations = device->info().configurations;
|
||||
for (size_t i = 0; i < configurations.size(); ++i) {
|
||||
if (configurations[i]->configuration_value == configurationValue)
|
||||
return new USBConfiguration(device, i);
|
||||
}
|
||||
exceptionState.throwRangeError("Invalid configuration value.");
|
||||
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)
|
||||
: m_device(device)
|
||||
, m_configurationIndex(configurationIndex)
|
||||
@ -52,19 +45,9 @@ size_t USBConfiguration::index() const
|
||||
return m_configurationIndex;
|
||||
}
|
||||
|
||||
const WebUSBDeviceInfo::Configuration& USBConfiguration::info() const
|
||||
const device::usb::wtf::ConfigurationInfo& USBConfiguration::info() const
|
||||
{
|
||||
return m_device->info().configurations[m_configurationIndex];
|
||||
}
|
||||
|
||||
uint8_t USBConfiguration::configurationValue() const
|
||||
{
|
||||
return info().configurationValue;
|
||||
}
|
||||
|
||||
String USBConfiguration::configurationName() const
|
||||
{
|
||||
return info().configurationName;
|
||||
return *m_device->info().configurations[m_configurationIndex];
|
||||
}
|
||||
|
||||
HeapVector<Member<USBInterface>> USBConfiguration::interfaces() const
|
||||
|
@ -6,8 +6,8 @@
|
||||
#define USBConfiguration_h
|
||||
|
||||
#include "bindings/core/v8/ScriptWrappable.h"
|
||||
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||
#include "platform/heap/Handle.h"
|
||||
#include "public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@ -22,16 +22,15 @@ class USBConfiguration
|
||||
public:
|
||||
static USBConfiguration* create(const USBDevice*, size_t configurationIndex);
|
||||
static USBConfiguration* create(const USBDevice*, size_t configurationValue, ExceptionState&);
|
||||
static USBConfiguration* createFromValue(const USBDevice*, uint8_t configurationValue);
|
||||
|
||||
USBConfiguration(const USBDevice*, size_t configurationIndex);
|
||||
|
||||
const USBDevice* device() const;
|
||||
size_t index() const;
|
||||
const WebUSBDeviceInfo::Configuration& info() const;
|
||||
const device::usb::wtf::ConfigurationInfo& info() const;
|
||||
|
||||
uint8_t configurationValue() const;
|
||||
String configurationName() const;
|
||||
uint8_t configurationValue() const { return info().configuration_value; }
|
||||
String configurationName() const { return info().configuration_name; }
|
||||
HeapVector<Member<USBInterface>> interfaces() const;
|
||||
|
||||
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 "bindings/core/v8/CallbackPromiseAdapter.h"
|
||||
#include "bindings/core/v8/ScriptPromise.h"
|
||||
#include "bindings/core/v8/ScriptPromiseResolver.h"
|
||||
#include "bindings/core/v8/ToV8.h"
|
||||
@ -14,31 +13,58 @@
|
||||
#include "core/dom/ExceptionCode.h"
|
||||
#include "modules/webusb/USBConfiguration.h"
|
||||
#include "modules/webusb/USBControlTransferParameters.h"
|
||||
#include "modules/webusb/USBError.h"
|
||||
#include "modules/webusb/USBInTransferResult.h"
|
||||
#include "modules/webusb/USBIsochronousInTransferResult.h"
|
||||
#include "modules/webusb/USBIsochronousOutTransferResult.h"
|
||||
#include "modules/webusb/USBOutTransferResult.h"
|
||||
#include "public/platform/modules/webusb/WebUSBTransferInfo.h"
|
||||
#include "platform/MojoHelper.h"
|
||||
#include "wtf/Assertions.h"
|
||||
|
||||
namespace usb = device::usb::wtf;
|
||||
|
||||
namespace blink {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kDeviceStateChangeInProgress[] = "An operation that changes the device state is in progress.";
|
||||
const char kDeviceUnavailable[] = "Device unavailable.";
|
||||
const char kInterfaceNotFound[] = "The interface number provided is not supported by the device in its current configuration.";
|
||||
const char kInterfaceStateChangeInProgress[] = "An operation that changes interface state is in progress.";
|
||||
const char kOpenRequired[] = "The device must be opened first.";
|
||||
|
||||
String convertTransferStatus(const WebUSBTransferInfo::Status& status)
|
||||
DOMException* convertFatalTransferStatus(const usb::TransferStatus& 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";
|
||||
case WebUSBTransferInfo::Status::Stall:
|
||||
case usb::TransferStatus::STALLED:
|
||||
return "stall";
|
||||
case WebUSBTransferInfo::Status::Babble:
|
||||
case usb::TransferStatus::BABBLE:
|
||||
return "babble";
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
@ -46,291 +72,52 @@ String convertTransferStatus(const WebUSBTransferInfo::Status& status)
|
||||
}
|
||||
}
|
||||
|
||||
class OpenClosePromiseAdapter : public WebCallbacks<void, const WebUSBError&> {
|
||||
public:
|
||||
OpenClosePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, bool desiredState)
|
||||
: m_device(device)
|
||||
, m_resolver(resolver)
|
||||
, m_desiredState(desiredState)
|
||||
{
|
||||
}
|
||||
mojo::WTFArray<uint8_t> convertBufferSource(const ArrayBufferOrArrayBufferView& buffer)
|
||||
{
|
||||
ASSERT(!buffer.isNull());
|
||||
Vector<uint8_t> vector;
|
||||
if (buffer.isArrayBuffer())
|
||||
vector.append(static_cast<uint8_t*>(buffer.getAsArrayBuffer()->data()), buffer.getAsArrayBuffer()->byteLength());
|
||||
else
|
||||
vector.append(static_cast<uint8_t*>(buffer.getAsArrayBufferView()->baseAddress()), buffer.getAsArrayBufferView()->byteLength());
|
||||
return mojo::WTFArray<uint8_t>(std::move(vector));
|
||||
}
|
||||
|
||||
void onSuccess() override
|
||||
{
|
||||
if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
|
||||
return;
|
||||
|
||||
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;
|
||||
};
|
||||
bool isActive(ScriptPromiseResolver* resolver)
|
||||
{
|
||||
ExecutionContext* context = resolver->getExecutionContext();
|
||||
return context && !context->activeDOMObjectsAreStopped();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDevice> device)
|
||||
{
|
||||
return USBDevice::create(device, resolver->getExecutionContext());
|
||||
}
|
||||
|
||||
USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context)
|
||||
USBDevice::USBDevice(usb::DeviceInfoPtr deviceInfo, usb::DevicePtr device, ExecutionContext* context)
|
||||
: ContextLifecycleObserver(context)
|
||||
, m_device(device)
|
||||
, m_deviceInfo(std::move(deviceInfo))
|
||||
, m_device(std::move(device))
|
||||
, m_opened(false)
|
||||
, m_deviceStateChangeInProgress(false)
|
||||
, m_configurationIndex(-1)
|
||||
, m_inEndpoints(15)
|
||||
, m_outEndpoints(15)
|
||||
{
|
||||
int configurationIndex = findConfigurationIndex(info().activeConfiguration);
|
||||
if (m_device) {
|
||||
m_device.set_connection_error_handler([this]() {
|
||||
m_device.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)
|
||||
onConfigurationSelected(true /* success */, configurationIndex);
|
||||
}
|
||||
|
||||
void USBDevice::onDeviceOpenedOrClosed(bool opened)
|
||||
USBDevice::~USBDevice()
|
||||
{
|
||||
m_opened = opened;
|
||||
m_deviceStateChangeInProgress = false;
|
||||
}
|
||||
|
||||
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);
|
||||
DCHECK(!m_device);
|
||||
DCHECK(m_deviceRequests.isEmpty());
|
||||
}
|
||||
|
||||
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>> configurations;
|
||||
size_t numConfigurations = info().configurations.size();
|
||||
HeapVector<Member<USBConfiguration>> configurations(numConfigurations);
|
||||
for (size_t i = 0; i < numConfigurations; ++i)
|
||||
configurations.append(USBConfiguration::create(this, i));
|
||||
configurations[i] = USBConfiguration::create(this, i);
|
||||
return configurations;
|
||||
}
|
||||
|
||||
@ -368,7 +155,8 @@ ScriptPromise USBDevice::open(ScriptState* scriptState)
|
||||
resolver->resolve();
|
||||
} else {
|
||||
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;
|
||||
@ -383,7 +171,8 @@ ScriptPromise USBDevice::close(ScriptState* scriptState)
|
||||
resolver->resolve();
|
||||
} else {
|
||||
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;
|
||||
@ -404,7 +193,8 @@ ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c
|
||||
resolver->resolve();
|
||||
} else {
|
||||
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();
|
||||
} else {
|
||||
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;
|
||||
@ -448,7 +239,8 @@ ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte
|
||||
// changing.
|
||||
setEndpointsForInterface(interfaceIndex, false);
|
||||
m_interfaceStateChangeInProgress.set(interfaceIndex);
|
||||
m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromiseAdapter(this, resolver, interfaceIndex, false /* release */));
|
||||
m_deviceRequests.add(resolver);
|
||||
m_device->ReleaseInterface(interfaceNumber, createBaseCallback(bind<bool>(&USBDevice::asyncReleaseInterface, this, interfaceIndex, resolver)));
|
||||
}
|
||||
}
|
||||
return promise;
|
||||
@ -470,7 +262,8 @@ ScriptPromise USBDevice::selectAlternateInterface(ScriptState* scriptState, uint
|
||||
// the change is in progress.
|
||||
setEndpointsForInterface(interfaceIndex, false);
|
||||
m_interfaceStateChangeInProgress.set(interfaceIndex);
|
||||
m_device->setInterface(interfaceNumber, alternateSetting, new SelectAlternateInterfacePromiseAdapter(this, resolver, interfaceIndex, alternateIndex));
|
||||
m_deviceRequests.add(resolver);
|
||||
m_device->SetInterfaceAlternateSetting(interfaceNumber, alternateSetting, createBaseCallback(bind<bool>(&USBDevice::asyncSelectAlternateInterface, this, interfaceNumber, alternateSetting, resolver)));
|
||||
}
|
||||
}
|
||||
return promise;
|
||||
@ -481,9 +274,11 @@ ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo
|
||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||
ScriptPromise promise = resolver->promise();
|
||||
if (ensureDeviceConfigured(resolver)) {
|
||||
WebUSBDevice::ControlTransferParameters parameters;
|
||||
if (convertControlTransferParameters(WebUSBDevice::TransferDirection::In, setup, ¶meters, resolver))
|
||||
m_device->controlTransfer(parameters, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(resolver));
|
||||
auto parameters = convertControlTransferParameters(setup, resolver);
|
||||
if (parameters) {
|
||||
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;
|
||||
}
|
||||
@ -493,9 +288,11 @@ ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC
|
||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||
ScriptPromise promise = resolver->promise();
|
||||
if (ensureDeviceConfigured(resolver)) {
|
||||
WebUSBDevice::ControlTransferParameters parameters;
|
||||
if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Out, setup, ¶meters, resolver))
|
||||
m_device->controlTransfer(parameters, nullptr, 0, 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
|
||||
auto parameters = convertControlTransferParameters(setup, resolver);
|
||||
if (parameters) {
|
||||
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;
|
||||
}
|
||||
@ -505,10 +302,12 @@ ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC
|
||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||
ScriptPromise promise = resolver->promise();
|
||||
if (ensureDeviceConfigured(resolver)) {
|
||||
WebUSBDevice::ControlTransferParameters parameters;
|
||||
if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Out, setup, ¶meters, resolver)) {
|
||||
BufferSource buffer(data);
|
||||
m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
|
||||
auto parameters = convertControlTransferParameters(setup, resolver);
|
||||
if (parameters) {
|
||||
mojo::WTFArray<uint8_t> buffer = convertBufferSource(data);
|
||||
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;
|
||||
@ -518,8 +317,10 @@ ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u
|
||||
{
|
||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||
ScriptPromise promise = resolver->promise();
|
||||
if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver))
|
||||
m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USBError>(resolver));
|
||||
if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver)) {
|
||||
m_deviceRequests.add(resolver);
|
||||
m_device->ClearHalt(endpointNumber, createBaseCallback(bind<bool>(&USBDevice::asyncClearHalt, this, resolver)));
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
@ -527,8 +328,10 @@ ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu
|
||||
{
|
||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||
ScriptPromise promise = resolver->promise();
|
||||
if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver))
|
||||
m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(resolver));
|
||||
if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) {
|
||||
m_deviceRequests.add(resolver);
|
||||
m_device->GenericTransferIn(endpointNumber, length, 0, createBaseCallback(bind<usb::TransferStatus, mojo::WTFArray<uint8_t>>(&USBDevice::asyncTransferIn, this, resolver)));
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
@ -537,8 +340,10 @@ ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN
|
||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||
ScriptPromise promise = resolver->promise();
|
||||
if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
|
||||
BufferSource buffer(data);
|
||||
m_device->transfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
|
||||
mojo::WTFArray<uint8_t> buffer = convertBufferSource(data);
|
||||
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;
|
||||
}
|
||||
@ -547,8 +352,10 @@ ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t
|
||||
{
|
||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||
ScriptPromise promise = resolver->promise();
|
||||
if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver))
|
||||
m_device->isochronousTransfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, 0, packetLengths, 0, new CallbackPromiseAdapter<IsochronousInputTransferResult, USBError>(resolver));
|
||||
if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -557,8 +364,8 @@ ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_
|
||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||
ScriptPromise promise = resolver->promise();
|
||||
if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
|
||||
BufferSource buffer(data);
|
||||
m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseAdapter<IsochronousOutputTransferResult, USBError>(resolver));
|
||||
m_deviceRequests.add(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;
|
||||
}
|
||||
@ -568,32 +375,33 @@ ScriptPromise USBDevice::reset(ScriptState* scriptState)
|
||||
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
||||
ScriptPromise promise = resolver->promise();
|
||||
if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
|
||||
if (!m_opened)
|
||||
if (!m_opened) {
|
||||
resolver->reject(DOMException::create(InvalidStateError, kOpenRequired));
|
||||
else
|
||||
m_device->reset(new CallbackPromiseAdapter<void, USBError>(resolver));
|
||||
} else {
|
||||
m_deviceRequests.add(resolver);
|
||||
m_device->Reset(createBaseCallback(bind<bool>(&USBDevice::asyncReset, this, resolver)));
|
||||
}
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
void USBDevice::contextDestroyed()
|
||||
{
|
||||
if (m_opened) {
|
||||
m_device->close(new WebUSBDeviceCloseCallbacks());
|
||||
m_opened = false;
|
||||
}
|
||||
m_device.reset();
|
||||
m_deviceRequests.clear();
|
||||
}
|
||||
|
||||
DEFINE_TRACE(USBDevice)
|
||||
{
|
||||
ContextLifecycleObserver::trace(visitor);
|
||||
visitor->trace(m_deviceRequests);
|
||||
}
|
||||
|
||||
int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
|
||||
{
|
||||
const auto& configurations = info().configurations;
|
||||
for (size_t i = 0; i < configurations.size(); ++i) {
|
||||
if (configurations[i].configurationValue == configurationValue)
|
||||
if (configurations[i]->configuration_value == configurationValue)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@ -602,9 +410,9 @@ int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
|
||||
int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
|
||||
{
|
||||
ASSERT(m_configurationIndex != -1);
|
||||
const auto& interfaces = info().configurations[m_configurationIndex].interfaces;
|
||||
const auto& interfaces = info().configurations[m_configurationIndex]->interfaces;
|
||||
for (size_t i = 0; i < interfaces.size(); ++i) {
|
||||
if (interfaces[i].interfaceNumber == interfaceNumber)
|
||||
if (interfaces[i]->interface_number == interfaceNumber)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@ -613,9 +421,9 @@ int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
|
||||
int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSetting) const
|
||||
{
|
||||
ASSERT(m_configurationIndex != -1);
|
||||
const auto& alternates = info().configurations[m_configurationIndex].interfaces[interfaceIndex].alternates;
|
||||
const auto& alternates = info().configurations[m_configurationIndex]->interfaces[interfaceIndex]->alternates;
|
||||
for (size_t i = 0; i < alternates.size(); ++i) {
|
||||
if (alternates[i].alternateSetting == alternateSetting)
|
||||
if (alternates[i]->alternate_setting == alternateSetting)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@ -623,7 +431,9 @@ int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSettin
|
||||
|
||||
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));
|
||||
else if (anyInterfaceChangeInProgress())
|
||||
resolver->reject(DOMException::create(InvalidStateError, kInterfaceStateChangeInProgress));
|
||||
@ -634,7 +444,9 @@ bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver*
|
||||
|
||||
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));
|
||||
else if (!m_opened)
|
||||
resolver->reject(DOMException::create(InvalidStateError, kOpenRequired));
|
||||
@ -686,65 +498,303 @@ bool USBDevice::anyInterfaceChangeInProgress() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool USBDevice::convertControlTransferParameters(
|
||||
WebUSBDevice::TransferDirection direction,
|
||||
usb::ControlTransferParamsPtr USBDevice::convertControlTransferParameters(
|
||||
const USBControlTransferParameters& parameters,
|
||||
WebUSBDevice::ControlTransferParameters* webParameters,
|
||||
ScriptPromiseResolver* resolver) const
|
||||
{
|
||||
webParameters->direction = direction;
|
||||
auto mojoParameters = usb::ControlTransferParams::New();
|
||||
|
||||
if (parameters.requestType() == "standard") {
|
||||
webParameters->type = WebUSBDevice::RequestType::Standard;
|
||||
mojoParameters->type = usb::ControlTransferType::STANDARD;
|
||||
} else if (parameters.requestType() == "class") {
|
||||
webParameters->type = WebUSBDevice::RequestType::Class;
|
||||
mojoParameters->type = usb::ControlTransferType::CLASS;
|
||||
} else if (parameters.requestType() == "vendor") {
|
||||
webParameters->type = WebUSBDevice::RequestType::Vendor;
|
||||
mojoParameters->type = usb::ControlTransferType::VENDOR;
|
||||
} else {
|
||||
resolver->reject(DOMException::create(TypeMismatchError, "The control transfer requestType parameter is invalid."));
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (parameters.recipient() == "device") {
|
||||
webParameters->recipient = WebUSBDevice::RequestRecipient::Device;
|
||||
mojoParameters->recipient = usb::ControlTransferRecipient::DEVICE;
|
||||
} else if (parameters.recipient() == "interface") {
|
||||
size_t interfaceNumber = parameters.index() & 0xff;
|
||||
if (!ensureInterfaceClaimed(interfaceNumber, resolver))
|
||||
return false;
|
||||
webParameters->recipient = WebUSBDevice::RequestRecipient::Interface;
|
||||
return nullptr;
|
||||
mojoParameters->recipient = usb::ControlTransferRecipient::INTERFACE;
|
||||
} else if (parameters.recipient() == "endpoint") {
|
||||
bool inTransfer = parameters.index() & 0x80;
|
||||
size_t endpointNumber = parameters.index() & 0x0f;
|
||||
if (!ensureEndpointAvailable(inTransfer, endpointNumber, resolver))
|
||||
return false;
|
||||
webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint;
|
||||
return nullptr;
|
||||
mojoParameters->recipient = usb::ControlTransferRecipient::ENDPOINT;
|
||||
} else if (parameters.recipient() == "other") {
|
||||
webParameters->recipient = WebUSBDevice::RequestRecipient::Other;
|
||||
mojoParameters->recipient = usb::ControlTransferRecipient::OTHER;
|
||||
} else {
|
||||
resolver->reject(DOMException::create(TypeMismatchError, "The control transfer recipient parameter is invalid."));
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
webParameters->request = parameters.request();
|
||||
webParameters->value = parameters.value();
|
||||
webParameters->index = parameters.index();
|
||||
return true;
|
||||
mojoParameters->request = parameters.request();
|
||||
mojoParameters->value = parameters.value();
|
||||
mojoParameters->index = parameters.index();
|
||||
return mojoParameters;
|
||||
}
|
||||
|
||||
void USBDevice::setEndpointsForInterface(size_t interfaceIndex, bool set)
|
||||
{
|
||||
const auto& configuration = info().configurations[m_configurationIndex];
|
||||
const auto& interface = configuration.interfaces[interfaceIndex];
|
||||
const auto& alternate = interface.alternates[m_selectedAlternates[interfaceIndex]];
|
||||
for (const auto& endpoint : alternate.endpoints) {
|
||||
if (endpoint.endpointNumber == 0 || endpoint.endpointNumber >= 16)
|
||||
const auto& configuration = *info().configurations[m_configurationIndex];
|
||||
const auto& interface = *configuration.interfaces[interfaceIndex];
|
||||
const auto& alternate = *interface.alternates[m_selectedAlternates[interfaceIndex]];
|
||||
for (const auto& endpoint : alternate.endpoints.storage()) {
|
||||
uint8_t endpointNumber = endpoint->endpoint_number;
|
||||
if (endpointNumber == 0 || endpointNumber >= 16)
|
||||
continue; // Ignore endpoints with invalid indices.
|
||||
auto& bitVector = endpoint.direction == WebUSBDevice::TransferDirection::In ? m_inEndpoints : m_outEndpoints;
|
||||
auto& bitVector = endpoint->direction == usb::TransferDirection::INBOUND ? m_inEndpoints : m_outEndpoints;
|
||||
if (set)
|
||||
bitVector.set(endpoint.endpointNumber - 1);
|
||||
bitVector.set(endpointNumber - 1);
|
||||
else
|
||||
bitVector.clear(endpoint.endpointNumber - 1);
|
||||
bitVector.clear(endpointNumber - 1);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -9,9 +9,8 @@
|
||||
#include "bindings/core/v8/ScriptWrappable.h"
|
||||
#include "bindings/modules/v8/UnionTypesModules.h"
|
||||
#include "core/dom/ContextLifecycleObserver.h"
|
||||
#include "device/usb/public/interfaces/device.mojom-wtf.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/Vector.h"
|
||||
|
||||
@ -29,42 +28,34 @@ class USBDevice
|
||||
USING_GARBAGE_COLLECTED_MIXIN(USBDevice);
|
||||
DEFINE_WRAPPERTYPEINFO();
|
||||
public:
|
||||
using WebType = OwnPtr<WebUSBDevice>;
|
||||
|
||||
static USBDevice* create(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context)
|
||||
static USBDevice* create(device::usb::wtf::DeviceInfoPtr deviceInfo, device::usb::wtf::DevicePtr 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*);
|
||||
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);
|
||||
const device::usb::wtf::DeviceInfo& info() const { return *m_deviceInfo; }
|
||||
bool isInterfaceClaimed(size_t configurationIndex, size_t interfaceIndex) const;
|
||||
size_t selectedAlternateInterface(size_t interfaceIndex) const;
|
||||
|
||||
// IDL exposed interface:
|
||||
// USBDevice.idl
|
||||
String guid() const { return info().guid; }
|
||||
uint8_t usbVersionMajor() { return info().usbVersionMajor; }
|
||||
uint8_t usbVersionMinor() { return info().usbVersionMinor; }
|
||||
uint8_t usbVersionSubminor() { return info().usbVersionSubminor; }
|
||||
uint8_t deviceClass() { return info().deviceClass; }
|
||||
uint8_t deviceSubclass() const { return info().deviceSubclass; }
|
||||
uint8_t deviceProtocol() const { return info().deviceProtocol; }
|
||||
uint16_t vendorId() const { return info().vendorID; }
|
||||
uint16_t productId() const { return info().productID; }
|
||||
uint8_t deviceVersionMajor() const { return info().deviceVersionMajor; }
|
||||
uint8_t deviceVersionMinor() const { return info().deviceVersionMinor; }
|
||||
uint8_t deviceVersionSubminor() const { return info().deviceVersionSubminor; }
|
||||
String manufacturerName() const { return info().manufacturerName; }
|
||||
String productName() const { return info().productName; }
|
||||
String serialNumber() const { return info().serialNumber; }
|
||||
uint8_t usbVersionMajor() const { return info().usb_version_major; }
|
||||
uint8_t usbVersionMinor() const { return info().usb_version_minor; }
|
||||
uint8_t usbVersionSubminor() const { return info().usb_version_subminor; }
|
||||
uint8_t deviceClass() const { return info().class_code; }
|
||||
uint8_t deviceSubclass() const { return info().subclass_code; }
|
||||
uint8_t deviceProtocol() const { return info().protocol_code; }
|
||||
uint16_t vendorId() const { return info().vendor_id; }
|
||||
uint16_t productId() const { return info().product_id; }
|
||||
uint8_t deviceVersionMajor() const { return info().device_version_major; }
|
||||
uint8_t deviceVersionMinor() const { return info().device_version_minor; }
|
||||
uint8_t deviceVersionSubminor() const { return info().device_version_subminor; }
|
||||
String manufacturerName() const { return info().manufacturer_name; }
|
||||
String productName() const { return info().product_name; }
|
||||
String serialNumber() const { return info().serial_number; }
|
||||
USBConfiguration* configuration() const;
|
||||
HeapVector<Member<USBConfiguration>> configurations() const;
|
||||
bool opened() const { return m_opened; }
|
||||
@ -99,10 +90,30 @@ private:
|
||||
bool ensureInterfaceClaimed(uint8_t interfaceNumber, ScriptPromiseResolver*) const;
|
||||
bool ensureEndpointAvailable(bool inTransfer, uint8_t endpointNumber, ScriptPromiseResolver*) 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);
|
||||
|
||||
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_deviceStateChangeInProgress;
|
||||
int m_configurationIndex;
|
||||
|
@ -7,30 +7,22 @@
|
||||
#include "bindings/core/v8/ExceptionState.h"
|
||||
#include "core/dom/DOMException.h"
|
||||
#include "core/dom/ExceptionCode.h"
|
||||
#include "device/usb/public/interfaces/device.mojom-wtf.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 {
|
||||
|
||||
bool convertDirectionFromEnum(const String& direction, WebUSBDevice::TransferDirection* webDirection)
|
||||
{
|
||||
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)
|
||||
String convertDirectionToEnum(const TransferDirection& direction)
|
||||
{
|
||||
switch (direction) {
|
||||
case WebUSBDevice::TransferDirection::In:
|
||||
case TransferDirection::INBOUND:
|
||||
return "in";
|
||||
case WebUSBDevice::TransferDirection::Out:
|
||||
case TransferDirection::OUTBOUND:
|
||||
return "out";
|
||||
default:
|
||||
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) {
|
||||
case WebUSBDeviceInfo::Endpoint::Type::Bulk:
|
||||
case EndpointType::BULK:
|
||||
return "bulk";
|
||||
case WebUSBDeviceInfo::Endpoint::Type::Interrupt:
|
||||
case EndpointType::INTERRUPT:
|
||||
return "interrupt";
|
||||
case WebUSBDeviceInfo::Endpoint::Type::Isochronous:
|
||||
case EndpointType::ISOCHRONOUS:
|
||||
return "isochronous";
|
||||
default:
|
||||
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)
|
||||
{
|
||||
WebUSBDevice::TransferDirection webDirection;
|
||||
if (!convertDirectionFromEnum(direction, &webDirection)) {
|
||||
exceptionState.throwRangeError("Invalid endpoint direction.");
|
||||
return nullptr;
|
||||
}
|
||||
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)
|
||||
TransferDirection mojoDirection = direction == "in" ? TransferDirection::INBOUND : TransferDirection::OUTBOUND;
|
||||
const auto& endpoints = alternate->info().endpoints;
|
||||
for (size_t i = 0; i < endpoints.size(); ++i) {
|
||||
const auto& endpoint = endpoints[i];
|
||||
if (endpoint->endpoint_number == endpointNumber && endpoint->direction == mojoDirection)
|
||||
return USBEndpoint::create(alternate, i);
|
||||
}
|
||||
exceptionState.throwRangeError("Invalid endpoint number.");
|
||||
exceptionState.throwRangeError("No such endpoint exists in the given alternate interface.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -84,16 +73,11 @@ USBEndpoint::USBEndpoint(const USBAlternateInterface* alternate, size_t endpoint
|
||||
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());
|
||||
return alternateInfo.endpoints[m_endpointIndex];
|
||||
}
|
||||
|
||||
uint8_t USBEndpoint::endpointNumber() const
|
||||
{
|
||||
return info().endpointNumber;
|
||||
return *alternateInfo.endpoints[m_endpointIndex];
|
||||
}
|
||||
|
||||
String USBEndpoint::direction() const
|
||||
@ -106,11 +90,6 @@ String USBEndpoint::type() const
|
||||
return convertTypeToEnum(info().type);
|
||||
}
|
||||
|
||||
unsigned USBEndpoint::packetSize() const
|
||||
{
|
||||
return info().packetSize;
|
||||
}
|
||||
|
||||
DEFINE_TRACE(USBEndpoint)
|
||||
{
|
||||
visitor->trace(m_alternate);
|
||||
|
@ -6,8 +6,8 @@
|
||||
#define USBEndpoint_h
|
||||
|
||||
#include "bindings/core/v8/ScriptWrappable.h"
|
||||
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||
#include "platform/heap/Heap.h"
|
||||
#include "public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@ -24,12 +24,12 @@ public:
|
||||
|
||||
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 type() const;
|
||||
unsigned packetSize() const;
|
||||
unsigned packetSize() const { return info().packet_size; }
|
||||
|
||||
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/DOMDataView.h"
|
||||
#include "platform/heap/Handle.h"
|
||||
#include "public/platform/modules/webusb/WebUSBTransferInfo.h"
|
||||
#include "wtf/Vector.h"
|
||||
#include "wtf/text/WTFString.h"
|
||||
|
||||
namespace blink {
|
||||
@ -19,12 +19,12 @@ class USBInTransferResult final
|
||||
, public ScriptWrappable {
|
||||
DEFINE_WRAPPERTYPEINFO();
|
||||
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);
|
||||
}
|
||||
|
||||
USBInTransferResult(const String& status, const WebVector<uint8_t> data)
|
||||
USBInTransferResult(const String& status, const Vector<uint8_t>& data)
|
||||
: m_status(status)
|
||||
, m_data(DOMDataView::create(DOMArrayBuffer::create(data.data(), data.size()), 0, data.size()))
|
||||
{
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "modules/webusb/USBInterface.h"
|
||||
|
||||
#include "bindings/core/v8/ExceptionState.h"
|
||||
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||
#include "modules/webusb/USBAlternateInterface.h"
|
||||
#include "modules/webusb/USBConfiguration.h"
|
||||
#include "modules/webusb/USBDevice.h"
|
||||
@ -20,7 +21,7 @@ USBInterface* USBInterface::create(const USBConfiguration* configuration, size_t
|
||||
{
|
||||
const auto& interfaces = configuration->info().interfaces;
|
||||
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);
|
||||
}
|
||||
exceptionState.throwRangeError("Invalid interface index.");
|
||||
@ -33,12 +34,12 @@ USBInterface::USBInterface(const USBDevice* device, size_t configurationIndex, s
|
||||
, m_interfaceIndex(interfaceIndex)
|
||||
{
|
||||
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
|
||||
@ -56,11 +57,6 @@ HeapVector<Member<USBAlternateInterface>> USBInterface::alternates() const
|
||||
return alternates;
|
||||
}
|
||||
|
||||
uint8_t USBInterface::interfaceNumber() const
|
||||
{
|
||||
return info().interfaceNumber;
|
||||
}
|
||||
|
||||
bool USBInterface::claimed() const
|
||||
{
|
||||
return m_device->isInterfaceClaimed(m_configurationIndex, m_interfaceIndex);
|
||||
|
@ -6,8 +6,8 @@
|
||||
#define USBInterface_h
|
||||
|
||||
#include "bindings/core/v8/ScriptWrappable.h"
|
||||
#include "device/usb/public/interfaces/device.mojom-wtf.h"
|
||||
#include "platform/heap/Heap.h"
|
||||
#include "public/platform/modules/webusb/WebUSBDeviceInfo.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@ -26,9 +26,9 @@ public:
|
||||
|
||||
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;
|
||||
HeapVector<Member<USBAlternateInterface>> alternates() const;
|
||||
bool claimed() const;
|
||||
|
@ -6,9 +6,7 @@
|
||||
#define USBOutTransferResult_h
|
||||
|
||||
#include "bindings/core/v8/ScriptWrappable.h"
|
||||
#include "core/dom/DOMArrayBuffer.h"
|
||||
#include "platform/heap/Handle.h"
|
||||
#include "public/platform/modules/webusb/WebUSBTransferInfo.h"
|
||||
#include "wtf/text/WTFString.h"
|
||||
|
||||
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 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
|
||||
// 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
|
||||
@ -24,6 +34,12 @@ sameThreadBindForMojo(ReturnType (Class::*method)(Args...), Class* 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 mojo {
|
||||
|
@ -166,7 +166,6 @@
|
||||
#include "modules/screen_orientation/ScreenOrientationController.h"
|
||||
#include "modules/vr/VRController.h"
|
||||
#include "modules/wake_lock/ScreenWakeLock.h"
|
||||
#include "modules/webusb/USBController.h"
|
||||
#include "platform/ScriptForbiddenScope.h"
|
||||
#include "platform/TraceEvent.h"
|
||||
#include "platform/UserGestureIndicator.h"
|
||||
@ -1478,10 +1477,6 @@ void WebLocalFrameImpl::setCoreFrame(LocalFrame* frame)
|
||||
provideLocalFileSystemTo(*m_frame, LocalFileSystemClient::create());
|
||||
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();
|
||||
#if OS(CHROMEOS) || OS(ANDROID)
|
||||
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/WebSocketHandshakeRequestInfo.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/WebAXObject.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 WebURL;
|
||||
class WebURLResponse;
|
||||
class WebUSBClient;
|
||||
class WebUserMediaClient;
|
||||
class WebVRClient;
|
||||
class WebWorkerContentSettingsClientProxy;
|
||||
@ -710,9 +709,6 @@ public:
|
||||
// Bluetooth -----------------------------------------------------------
|
||||
virtual WebBluetooth* bluetooth() { return 0; }
|
||||
|
||||
// WebUSB --------------------------------------------------------------
|
||||
virtual WebUSBClient* usbClient() { return nullptr; }
|
||||
|
||||
|
||||
// Audio Output Devices API --------------------------------------------
|
||||
|
||||
|
Reference in New Issue
Block a user