|  | // 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_ |