blob: 23b6cb485e8c61200504d3890ae0aeed7f1468d2 [file] [log] [blame]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_DEVICE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_DEVICE_H_
#include <bitset>
#include "base/containers/span.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/device/public/mojom/usb_device.mojom-blink.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/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class ScriptState;
class USB;
class USBConfiguration;
class USBControlTransferParameters;
class USBInTransferResult;
class USBIsochronousInTransferResult;
class USBIsochronousOutTransferResult;
class USBOutTransferResult;
class V8USBDirection;
class USBDevice : public ScriptWrappable,
public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
public:
explicit USBDevice(USB* parent,
device::mojom::blink::UsbDeviceInfoPtr,
mojo::PendingRemote<device::mojom::blink::UsbDevice>,
ExecutionContext*);
~USBDevice() override;
const device::mojom::blink::UsbDeviceInfo& Info() const {
return *device_info_;
}
bool IsInterfaceClaimed(wtf_size_t configuration_index,
wtf_size_t interface_index) const;
wtf_size_t SelectedAlternateInterfaceIndex(wtf_size_t interface_index) const;
// USBDevice.idl
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 opened_; }
ScriptPromise<IDLUndefined> open(ScriptState*, ExceptionState&);
ScriptPromise<IDLUndefined> close(ScriptState*, ExceptionState&);
ScriptPromise<IDLUndefined> forget(ScriptState*, ExceptionState&);
ScriptPromise<IDLUndefined> selectConfiguration(ScriptState*,
uint8_t configuration_value,
ExceptionState&);
ScriptPromise<IDLUndefined> claimInterface(ScriptState*,
uint8_t interface_number,
ExceptionState&);
ScriptPromise<IDLUndefined> releaseInterface(ScriptState*,
uint8_t interface_number,
ExceptionState&);
ScriptPromise<IDLUndefined> selectAlternateInterface(
ScriptState*,
uint8_t interface_number,
uint8_t alternate_setting,
ExceptionState&);
ScriptPromise<USBInTransferResult> controlTransferIn(
ScriptState*,
const USBControlTransferParameters* setup,
uint16_t length,
ExceptionState&);
ScriptPromise<USBOutTransferResult> controlTransferOut(
ScriptState*,
const USBControlTransferParameters* setup,
ExceptionState&);
ScriptPromise<USBOutTransferResult> controlTransferOut(
ScriptState*,
const USBControlTransferParameters* setup,
base::span<const uint8_t> data,
ExceptionState&);
ScriptPromise<IDLUndefined> clearHalt(ScriptState*,
const V8USBDirection& direction,
uint8_t endpoint_number,
ExceptionState&);
ScriptPromise<USBInTransferResult> transferIn(ScriptState*,
uint8_t endpoint_number,
unsigned length,
ExceptionState&);
ScriptPromise<USBOutTransferResult> transferOut(
ScriptState*,
uint8_t endpoint_number,
base::span<const uint8_t> data,
ExceptionState&);
ScriptPromise<USBIsochronousInTransferResult> isochronousTransferIn(
ScriptState*,
uint8_t endpoint_number,
Vector<unsigned> packet_lengths,
ExceptionState&);
ScriptPromise<USBIsochronousOutTransferResult> isochronousTransferOut(
ScriptState*,
uint8_t endpoint_number,
base::span<const uint8_t> data,
Vector<unsigned> packet_lengths,
ExceptionState&);
ScriptPromise<IDLUndefined> reset(ScriptState*, ExceptionState&);
// ExecutionContextLifecycleObserver interface.
void ContextDestroyed() override;
void Trace(Visitor*) const override;
private:
static const size_t kEndpointsBitsNumber = 16;
wtf_size_t FindConfigurationIndex(uint8_t configuration_value) const;
wtf_size_t FindInterfaceIndex(uint8_t interface_number) const;
wtf_size_t FindAlternateIndex(wtf_size_t interface_index,
uint8_t alternate_setting) const;
void EnsureNoDeviceChangeInProgress(ExceptionState&) const;
void EnsureNoDeviceOrInterfaceChangeInProgress(ExceptionState&) const;
void EnsureDeviceConfigured(ExceptionState&) const;
void EnsureInterfaceClaimed(uint8_t interface_number, ExceptionState&) const;
void EnsureEndpointAvailable(bool in_transfer,
uint8_t endpoint_number,
ExceptionState&) const;
bool AnyInterfaceChangeInProgress() const;
device::mojom::blink::UsbControlTransferParamsPtr
ConvertControlTransferParameters(const USBControlTransferParameters*,
ExceptionState&) const;
void SetEndpointsForInterface(wtf_size_t interface_index, bool set);
void AsyncOpen(ScriptPromiseResolver<IDLUndefined>*,
device::mojom::blink::UsbOpenDeviceResultPtr);
void AsyncClose(ScriptPromiseResolver<IDLUndefined>*);
static void AsyncForget(ScriptPromiseResolver<IDLUndefined>*);
void OnDeviceOpenedOrClosed(bool);
void AsyncSelectConfiguration(wtf_size_t configuration_index,
ScriptPromiseResolver<IDLUndefined>*,
bool success);
void OnConfigurationSelected(bool success, wtf_size_t configuration_index);
void AsyncClaimInterface(
wtf_size_t interface_index,
ScriptPromiseResolver<IDLUndefined>*,
device::mojom::blink::UsbClaimInterfaceResult result);
void AsyncReleaseInterface(wtf_size_t interface_index,
ScriptPromiseResolver<IDLUndefined>*,
bool success);
void OnInterfaceClaimedOrUnclaimed(bool claimed, wtf_size_t interface_index);
void AsyncSelectAlternateInterface(wtf_size_t interface_index,
wtf_size_t alternate_index,
ScriptPromiseResolver<IDLUndefined>*,
bool success);
void AsyncControlTransferIn(ScriptPromiseResolver<USBInTransferResult>*,
device::mojom::blink::UsbTransferStatus,
base::span<const uint8_t> data);
void AsyncControlTransferOut(uint32_t transfer_length,
ScriptPromiseResolver<USBOutTransferResult>*,
device::mojom::blink::UsbTransferStatus);
void AsyncClearHalt(ScriptPromiseResolver<IDLUndefined>*, bool success);
void AsyncTransferIn(ScriptPromiseResolver<USBInTransferResult>*,
device::mojom::blink::UsbTransferStatus,
base::span<const uint8_t> data);
void AsyncTransferOut(uint32_t transfer_length,
ScriptPromiseResolver<USBOutTransferResult>*,
device::mojom::blink::UsbTransferStatus);
void AsyncIsochronousTransferIn(
ScriptPromiseResolver<USBIsochronousInTransferResult>*,
base::span<const uint8_t> data,
Vector<device::mojom::blink::UsbIsochronousPacketPtr>);
void AsyncIsochronousTransferOut(
ScriptPromiseResolver<USBIsochronousOutTransferResult>*,
Vector<device::mojom::blink::UsbIsochronousPacketPtr>);
void AsyncReset(ScriptPromiseResolver<IDLUndefined>*, bool success);
void OnConnectionError();
void MarkRequestComplete(ScriptPromiseResolverBase*);
const Member<USB> parent_;
device::mojom::blink::UsbDeviceInfoPtr device_info_;
HeapMojoRemote<device::mojom::blink::UsbDevice> device_;
HeapHashSet<Member<ScriptPromiseResolverBase>> device_requests_;
HeapVector<Member<USBConfiguration>> configurations_;
bool opened_;
bool device_state_change_in_progress_;
wtf_size_t configuration_index_;
// These vectors have one entry for each interface in the currently selected
// configured. Use the index returned by FindInterfaceIndex().
Vector<bool> claimed_interfaces_;
Vector<bool> interface_state_change_in_progress_;
Vector<wtf_size_t> selected_alternate_indices_;
// These bit sets have one entry for each endpoint. Index using the endpoint
// number (lower 4 bits of the endpoint address).
std::bitset<kEndpointsBitsNumber> in_endpoints_;
std::bitset<kEndpointsBitsNumber> out_endpoints_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_DEVICE_H_