UNPKG

@yume-chan/adb-daemon-webusb

Version:

Adb daemon transport connection for `@yume-chan/adb` using WebUSB API.

113 lines (99 loc) 3.55 kB
import { AdbDaemonWebUsbDevice, mergeDefaultAdbInterfaceFilter, } from "./device.js"; import { AdbDaemonWebUsbDeviceObserver } from "./observer.js"; import { isErrorName, matchFilters } from "./utils.js"; export namespace AdbDaemonWebUsbDeviceManager { export interface RequestDeviceOptions { filters?: USBDeviceFilter[] | undefined; exclusionFilters?: USBDeviceFilter[] | undefined; } } export class AdbDaemonWebUsbDeviceManager { /** * Gets the instance of {@link AdbDaemonWebUsbDeviceManager} using browser WebUSB implementation. * * May be `undefined` if current runtime does not support WebUSB. */ static readonly BROWSER = /* #__PURE__ */ (() => typeof globalThis.navigator !== "undefined" && globalThis.navigator.usb ? new AdbDaemonWebUsbDeviceManager(globalThis.navigator.usb) : undefined)(); readonly #usbManager: USB; /** * Create a new instance of {@link AdbDaemonWebUsbDeviceManager} using the specified WebUSB implementation. * @param usbManager A WebUSB compatible interface. */ constructor(usbManager: USB) { this.#usbManager = usbManager; } /** * Call `USB#requestDevice()` to prompt the user to select a device. */ async requestDevice( options: AdbDaemonWebUsbDeviceManager.RequestDeviceOptions = {}, ): Promise<AdbDaemonWebUsbDevice | undefined> { const filters = mergeDefaultAdbInterfaceFilter(options.filters); try { const device = await this.#usbManager.requestDevice({ filters, exclusionFilters: options.exclusionFilters, }); const interface_ = matchFilters( device, filters, options.exclusionFilters, ); if (!interface_) { // `#usbManager` doesn't support `exclusionFilters`, // selected device is invalid return undefined; } return new AdbDaemonWebUsbDevice( device, interface_, this.#usbManager, ); } catch (e) { // No device selected if (isErrorName(e, "NotFoundError")) { return undefined; } throw e; } } /** * Get all connected and requested devices that match the specified filters. */ async getDevices( options: AdbDaemonWebUsbDeviceManager.RequestDeviceOptions = {}, ): Promise<AdbDaemonWebUsbDevice[]> { const filters = mergeDefaultAdbInterfaceFilter(options.filters); const devices = await this.#usbManager.getDevices(); // filter map const result: AdbDaemonWebUsbDevice[] = []; for (const device of devices) { const interface_ = matchFilters( device, filters, options.exclusionFilters, ); if (interface_) { result.push( new AdbDaemonWebUsbDevice( device, interface_, this.#usbManager, ), ); } } return result; } trackDevices( options: AdbDaemonWebUsbDeviceManager.RequestDeviceOptions = {}, ): Promise<AdbDaemonWebUsbDeviceObserver> { return AdbDaemonWebUsbDeviceObserver.create(this.#usbManager, options); } }