Skip to main content
Version: next

Create device manager

WebUSB provides APIs for discovering and communicating with USB devices. The AdbDaemonWebUsbDeviceManager class wraps the WebUSB API to better work with ADB devices.

The usage of AdbDaemonWebUsbDeviceManager is different in Node.js and Web browsers:

Web

Chromium-based browsers support WebUSB natively. Chrome for Android is supported, but Chrome for iOS is based on Safari and not supported.

Secure Context Required

WebUSB API requires a Secure Context. Basically it means the page must be served over HTTPS or localhost.

  • If you have a domain name, you can easily get a free SSL certificate from Let's Encrypt.
  • If you only have an IP address, you can create a self-signed certificate and trust it in every device that will access your server (or ignore the warning every time).
  • For Chromium-based browser, you can also add your origin to chrome://flags/#unsafely-treat-insecure-origin-as-secure.

Create a device manager for browsers:

import { AdbDaemonWebUsbDeviceManager } from "@yume-chan/adb-daemon-webusb";

const Manager: AdbDaemonWebUsbDeviceManager | undefined = AdbDaemonWebUsbDeviceManager.BROWSER;
info

AdbDaemonWebUsbDeviceManager.BROWSER is a shorthand of:

navigator.usb ? new AdbDaemonWebUsbDeviceManager(navigator.usb) : undefined;

In two cases, Manager may be undefined:

  1. Current page isn't in a Secure Context
  2. Current browser does not support WebUSB API

It's your responsibility to make sure the first case doesn't happen. So there is only one reason left:

if (!Manager) {
alert("WebUSB is not supported in this browser");
return;
}

Node.js

Node.js doesn't support WebUSB natively, but the usb package provides a WebUSB implementation for it.

It uses libusb library to access USB devices, which should work perfectly on Linux and macOS, but may have some issues on Windows.

npm i usb

Create a device manager using WebUSB from usb package:

import { AdbDaemonWebUsbDeviceManager } from "@yume-chan/adb-daemon-webusb";
import { WebUSB } from "usb";

const WebUsb: WebUSB = new WebUSB({ allowAllDevices: true });
const Manager: AdbDaemonWebUsbDeviceManager = new AdbDaemonWebUsbDeviceManager(WebUsb);
info

By default, WebUSB from usb package has the same permission system as browsers:

  • Each device must be authorized separately using requestDevice method and a custom devicesFound callback
  • getDevices method only returns devices that have been authorized

Passing allowAllDevices: true option disables the permission system and returns all connected devices from getDevices methods.

Electron

AdbDaemonWebUsbDeviceManager can be used in either Electron renderer processes or Electron main processes. However, because of the exclusivity of USB API, you can't access a device from both renderer and main processors, or from multiple renderer processes, at the same time.

Renderer Process

To use Tango in Electron renderer processes:

  1. Enable WebUSB API in Electron following https://www.electronjs.org/docs/latest/tutorial/devices#webusb-api
  2. Follow the instructions for Web.

This allows a USB-enabled Web app to run in Electron with minimal changes.

Main Process

To use Tango in Electron main processes, follow the instructions for Node.js.

It's recommended to use Tango in main process, then expose your own API to renderer processes using Electron IPC. For example, you can modify the server-client custom transport example to share an AdbTransport with multiple renderer processes.