Skip to content

Commit

Permalink
Add web command to request device access (microsoft#152310)
Browse files Browse the repository at this point in the history
* Add web command to request serial access

Signed-off-by: thegecko <[email protected]>

* Add support for requesting HID devices

Signed-off-by: thegecko <[email protected]>
  • Loading branch information
thegecko authored Jun 21, 2022
1 parent 9ec50c6 commit dd2ca4c
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface UsbDeviceData {
readonly vendorId: number;
}

export async function requestUsb(options?: { filters?: unknown[] }): Promise<UsbDeviceData | undefined> {
export async function requestUsbDevice(options?: { filters?: unknown[] }): Promise<UsbDeviceData | undefined> {
const usb = (navigator as any).usb;
if (!usb) {
return undefined;
Expand Down Expand Up @@ -50,3 +50,59 @@ export async function requestUsb(options?: { filters?: unknown[] }): Promise<Usb
vendorId: device.vendorId,
};
}

// https://wicg.github.io/serial/

export interface SerialPortData {
readonly usbVendorId?: number | undefined;
readonly usbProductId?: number | undefined;
}

export async function requestSerialPort(options?: { filters?: unknown[] }): Promise<SerialPortData | undefined> {
const serial = (navigator as any).serial;
if (!serial) {
return undefined;
}

const port = await serial.requestPort({ filters: options?.filters ?? [] });
if (!port) {
return undefined;
}

const info = port.getInfo();
return {
usbVendorId: info.usbVendorId,
usbProductId: info.usbProductId
};
}

// https://wicg.github.io/webhid/

export interface HidDeviceData {
readonly opened: boolean;
readonly vendorId: number;
readonly productId: number;
readonly productName: string;
readonly collections: [];
}

export async function requestHidDevice(options?: { filters?: unknown[] }): Promise<HidDeviceData | undefined> {
const hid = (navigator as any).hid;
if (!hid) {
return undefined;
}

const devices = await hid.requestDevice({ filters: options?.filters ?? [] });
if (!devices.length) {
return undefined;
}

const device = devices[0];
return {
opened: device.opened,
vendorId: device.vendorId,
productId: device.productId,
productName: device.productName,
collections: device.collections
};
}
1 change: 0 additions & 1 deletion src/vs/workbench/browser/actions/workspaceCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,3 @@ CommandsRegistry.registerCommand('_workbench.getRecentlyOpened', async function

return workspacesService.getRecentlyOpened();
});

14 changes: 12 additions & 2 deletions src/vs/workbench/browser/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { isSafari, setFullscreen } from 'vs/base/browser/browser';
import { addDisposableListener, addDisposableThrottledListener, detectFullscreen, EventHelper, EventType, windowOpenNoOpener, windowOpenPopup, windowOpenWithSuccess } from 'vs/base/browser/dom';
import { DomEmitter } from 'vs/base/browser/event';
import { requestUsb, UsbDeviceData } from 'vs/base/browser/usb';
import { HidDeviceData, requestHidDevice, requestSerialPort, requestUsbDevice, SerialPortData, UsbDeviceData } from 'vs/base/browser/deviceAccess';
import { timeout } from 'vs/base/common/async';
import { Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
Expand Down Expand Up @@ -248,7 +248,17 @@ export class BrowserWindow extends Disposable {

// Allow extensions to request USB devices in Web
CommandsRegistry.registerCommand('workbench.experimental.requestUsbDevice', async (_accessor: ServicesAccessor, options?: { filters?: unknown[] }): Promise<UsbDeviceData | undefined> => {
return requestUsb(options);
return requestUsbDevice(options);
});

// Allow extensions to request Serial devices in Web
CommandsRegistry.registerCommand('workbench.experimental.requestSerialPort', async (_accessor: ServicesAccessor, options?: { filters?: unknown[] }): Promise<SerialPortData | undefined> => {
return requestSerialPort(options);
});

// Allow extensions to request HID devices in Web
CommandsRegistry.registerCommand('workbench.experimental.requestHidDevice', async (_accessor: ServicesAccessor, options?: { filters?: unknown[] }): Promise<HidDeviceData | undefined> => {
return requestHidDevice(options);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
const iframe = document.createElement('iframe');
iframe.setAttribute('class', 'web-worker-ext-host-iframe');
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
iframe.setAttribute('allow', 'usb; cross-origin-isolated;');
iframe.setAttribute('allow', 'usb; serial; hid; cross-origin-isolated;');
iframe.setAttribute('aria-hidden', 'true');
iframe.style.display = 'none';

Expand Down

0 comments on commit dd2ca4c

Please sign in to comment.