#include "third_party/blink/renderer/modules/webusb/usb_device.h"
#include <limits>
#include <optional>
#include <utility>
#include "base/containers/span.h"
#include "base/not_fatal_until.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_usb_control_transfer_parameters.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/modules/webusb/usb.h"
#include "third_party/blink/renderer/modules/webusb/usb_configuration.h"
#include "third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h"
#include "third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h"
#include "third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h"
#include "third_party/blink/renderer/modules/webusb/usb_out_transfer_result.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
UsbClaimInterfaceResult;
UsbControlTransferParamsPtr;
UsbControlTransferRecipient;
UsbControlTransferType;
UsbDevice;
UsbDeviceInfoPtr;
UsbIsochronousPacketPtr;
UsbOpenDeviceError;
UsbTransferDirection;
UsbTransferStatus;
namespace blink {
namespace {
const char kAccessDeniedError[] = …;
const char kPacketLengthsTooBig[] = …;
const char kBufferSizeMismatch[] = …;
const char kDetachedBuffer[] = …;
const char kDeviceStateChangeInProgress[] = …;
const char kDeviceDisconnected[] = …;
const char kInterfaceNotFound[] = …;
const char kInterfaceStateChangeInProgress[] = …;
const char kOpenRequired[] = …;
const char kProtectedInterfaceClassError[] = …;
const char kTransferPermissionDeniedError[] = …;
const int kUsbTransferLengthLimit = …;
bool CheckFatalTransferStatus(ScriptPromiseResolverBase* resolver,
const UsbTransferStatus& status) { … }
String ConvertTransferStatus(const UsbTransferStatus& status) { … }
std::optional<uint32_t> TotalPacketLength(
const Vector<unsigned>& packet_lengths) { … }
bool ShouldRejectUsbTransferLength(size_t length,
ExceptionState& exception_state) { … }
}
USBDevice::USBDevice(USB* parent,
UsbDeviceInfoPtr device_info,
mojo::PendingRemote<UsbDevice> device,
ExecutionContext* context)
: … { … }
USBDevice::~USBDevice() { … }
bool USBDevice::IsInterfaceClaimed(wtf_size_t configuration_index,
wtf_size_t interface_index) const { … }
wtf_size_t USBDevice::SelectedAlternateInterfaceIndex(
wtf_size_t interface_index) const { … }
USBConfiguration* USBDevice::configuration() const { … }
HeapVector<Member<USBConfiguration>> USBDevice::configurations() const { … }
ScriptPromise<IDLUndefined> USBDevice::open(ScriptState* script_state,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> USBDevice::close(ScriptState* script_state,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> USBDevice::forget(ScriptState* script_state,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> USBDevice::selectConfiguration(
ScriptState* script_state,
uint8_t configuration_value,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> USBDevice::claimInterface(
ScriptState* script_state,
uint8_t interface_number,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> USBDevice::releaseInterface(
ScriptState* script_state,
uint8_t interface_number,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> USBDevice::selectAlternateInterface(
ScriptState* script_state,
uint8_t interface_number,
uint8_t alternate_setting,
ExceptionState& exception_state) { … }
ScriptPromise<USBInTransferResult> USBDevice::controlTransferIn(
ScriptState* script_state,
const USBControlTransferParameters* setup,
uint16_t length,
ExceptionState& exception_state) { … }
ScriptPromise<USBOutTransferResult> USBDevice::controlTransferOut(
ScriptState* script_state,
const USBControlTransferParameters* setup,
ExceptionState& exception_state) { … }
ScriptPromise<USBOutTransferResult> USBDevice::controlTransferOut(
ScriptState* script_state,
const USBControlTransferParameters* setup,
const DOMArrayPiece& optional_data,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> USBDevice::clearHalt(
ScriptState* script_state,
String direction,
uint8_t endpoint_number,
ExceptionState& exception_state) { … }
ScriptPromise<USBInTransferResult> USBDevice::transferIn(
ScriptState* script_state,
uint8_t endpoint_number,
unsigned length,
ExceptionState& exception_state) { … }
ScriptPromise<USBOutTransferResult> USBDevice::transferOut(
ScriptState* script_state,
uint8_t endpoint_number,
const DOMArrayPiece& data,
ExceptionState& exception_state) { … }
ScriptPromise<USBIsochronousInTransferResult> USBDevice::isochronousTransferIn(
ScriptState* script_state,
uint8_t endpoint_number,
Vector<unsigned> packet_lengths,
ExceptionState& exception_state) { … }
ScriptPromise<USBIsochronousOutTransferResult>
USBDevice::isochronousTransferOut(ScriptState* script_state,
uint8_t endpoint_number,
const DOMArrayPiece& data,
Vector<unsigned> packet_lengths,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> USBDevice::reset(ScriptState* script_state,
ExceptionState& exception_state) { … }
void USBDevice::ContextDestroyed() { … }
void USBDevice::Trace(Visitor* visitor) const { … }
wtf_size_t USBDevice::FindConfigurationIndex(
uint8_t configuration_value) const { … }
wtf_size_t USBDevice::FindInterfaceIndex(uint8_t interface_number) const { … }
wtf_size_t USBDevice::FindAlternateIndex(uint32_t interface_index,
uint8_t alternate_setting) const { … }
void USBDevice::EnsureNoDeviceChangeInProgress(
ExceptionState& exception_state) const { … }
void USBDevice::EnsureNoDeviceOrInterfaceChangeInProgress(
ExceptionState& exception_state) const { … }
void USBDevice::EnsureDeviceConfigured(ExceptionState& exception_state) const { … }
void USBDevice::EnsureInterfaceClaimed(uint8_t interface_number,
ExceptionState& exception_state) const { … }
void USBDevice::EnsureEndpointAvailable(bool in_transfer,
uint8_t endpoint_number,
ExceptionState& exception_state) const { … }
bool USBDevice::AnyInterfaceChangeInProgress() const { … }
UsbControlTransferParamsPtr USBDevice::ConvertControlTransferParameters(
const USBControlTransferParameters* parameters,
ExceptionState& exception_state) const { … }
void USBDevice::SetEndpointsForInterface(wtf_size_t interface_index, bool set) { … }
void USBDevice::AsyncOpen(ScriptPromiseResolver<IDLUndefined>* resolver,
device::mojom::blink::UsbOpenDeviceResultPtr result) { … }
void USBDevice::AsyncClose(ScriptPromiseResolver<IDLUndefined>* resolver) { … }
void USBDevice::AsyncForget(ScriptPromiseResolver<IDLUndefined>* resolver) { … }
void USBDevice::OnDeviceOpenedOrClosed(bool opened) { … }
void USBDevice::AsyncSelectConfiguration(
wtf_size_t configuration_index,
ScriptPromiseResolver<IDLUndefined>* resolver,
bool success) { … }
void USBDevice::OnConfigurationSelected(bool success,
wtf_size_t configuration_index) { … }
void USBDevice::AsyncClaimInterface(
wtf_size_t interface_index,
ScriptPromiseResolver<IDLUndefined>* resolver,
device::mojom::blink::UsbClaimInterfaceResult result) { … }
void USBDevice::AsyncReleaseInterface(
wtf_size_t interface_index,
ScriptPromiseResolver<IDLUndefined>* resolver,
bool success) { … }
void USBDevice::OnInterfaceClaimedOrUnclaimed(bool claimed,
wtf_size_t interface_index) { … }
void USBDevice::AsyncSelectAlternateInterface(
wtf_size_t interface_index,
wtf_size_t alternate_index,
ScriptPromiseResolver<IDLUndefined>* resolver,
bool success) { … }
void USBDevice::AsyncControlTransferIn(
ScriptPromiseResolver<USBInTransferResult>* resolver,
UsbTransferStatus status,
base::span<const uint8_t> data) { … }
void USBDevice::AsyncControlTransferOut(
uint32_t transfer_length,
ScriptPromiseResolver<USBOutTransferResult>* resolver,
UsbTransferStatus status) { … }
void USBDevice::AsyncClearHalt(ScriptPromiseResolver<IDLUndefined>* resolver,
bool success) { … }
void USBDevice::AsyncTransferIn(
ScriptPromiseResolver<USBInTransferResult>* resolver,
UsbTransferStatus status,
base::span<const uint8_t> data) { … }
void USBDevice::AsyncTransferOut(
uint32_t transfer_length,
ScriptPromiseResolver<USBOutTransferResult>* resolver,
UsbTransferStatus status) { … }
void USBDevice::AsyncIsochronousTransferIn(
ScriptPromiseResolver<USBIsochronousInTransferResult>* resolver,
base::span<const uint8_t> data,
Vector<UsbIsochronousPacketPtr> mojo_packets) { … }
void USBDevice::AsyncIsochronousTransferOut(
ScriptPromiseResolver<USBIsochronousOutTransferResult>* resolver,
Vector<UsbIsochronousPacketPtr> mojo_packets) { … }
void USBDevice::AsyncReset(ScriptPromiseResolver<IDLUndefined>* resolver,
bool success) { … }
void USBDevice::OnConnectionError() { … }
void USBDevice::MarkRequestComplete(ScriptPromiseResolverBase* resolver) { … }
}