Request device permission
This page only applies to browsers. For Node.js, you can skip to the next step.
With WebUSB
In Web browsers, each website needs to request the permission to access each device separately using WebUSB's USB#requestDevice
method.
User activation
USB#requestDevice
method requires user activation, it must be called in response to a mouse click or keyboard press event.
Device picker
After calling USB#requestDevice
, the browser shows a list of connected devices to the user. The user can select one (and only one) device from the list, or cancel the picker without selecting any device.
You can filter the devices shown in the picker using the filters
and exclusionFilters
options, but otherwise you can't control the picker's appearance or behavior.
Return value
It will return an USBDevice
instance representing the selected device, or throws an DOMException
with name
set to NotFoundError
if the user cancelled the picker.
This code is for demonstration purposes only. You should use AdbDaemonWebUsbDeviceManager#requestDevice
described below in Tango.
- JavaScript
- TypeScript
document.getElementById("button").addEventListener("click", () => {
try {
const device = await navigator.usb.requestDevice({
filters: [
{
classCode: 0xff,
subclassCode: 0x42,
protocolCode: 1,
},
],
});
alert(`Selected device: ${device.serialNumber}`);
} catch (e) {
if (e instanceof DOMException && e.name === "NotFoundError") {
alert("No device selected");
return;
}
throw e;
}
});
document.getElementById("button").addEventListener("click", () => {
try {
const device: USBDevice = await navigator.usb.requestDevice({
filters: [
{
classCode: 0xff,
subclassCode: 0x42,
protocolCode: 1,
},
],
});
alert(`Selected device: ${device.serialNumber}`);
} catch (e) {
if (e instanceof DOMException && e.name === "NotFoundError") {
alert("No device selected");
return;
}
throw e;
}
});
Permission persistence
The permission will be persisted by the browser, so from next time, the website can access that device without calling requestDevice
again. The user can revoke the permission in "Settings -> Site Permissions -> USB devices" at any time.
USB mode affects permissions
When Android devices works in USB peripheral mode, they can have multiple USB interfaces, like MTP (file transfer), ADB, RNDIS (reverse tethering), MIDI, etc.
When any interface is turned on or off from system UI, the device will disconnect and reconnect to the USB host and report a different set of interfaces.
As a result, in Web browsers, the same Android device with different sets of interfaces will be treated as different devices, and have different permissions. The website might need to request permission again when Android device switches to another mode.
With Tango
AdbDaemonWebUsbDeviceManager#requestDevice
method provides a more convenient way to request permission for Android devices with ADB interface enabled.
namespace AdbDaemonWebUsbDeviceManager {
interface RequestDeviceOptions {
filters?: USBDeviceFilter[] | undefined;
exclusionFilters?: USBDeviceFilter[] | undefined;
}
}
declare class AdbDaemonWebUsbDeviceManager {
requestDevice(
options?: AdbDaemonWebUsbDeviceManager.RequestDeviceOptions
): Promise<AdbDaemonWebUsbDevice | undefined>;
}
It calls USB#requestDevice
internally, thus the user activation, device picker, and permission persistence behaviors are the same as USB#requestDevice
.
Options
The options
parameter allows filtering the devices shown in the picker. By default, it only includes devices with ADB interface enabled.
Return value
The only difference is the return value:
- When the user selects a device, it creates and returns an
AdbDaemonWebUsbDevice
instance, which includes the rawUSBDevice
handle and additional information required by later steps. - If the user cancels the picker, it returns
undefined
, instead of throwing an error.
- JavaScript
- TypeScript
document.getElementById("button").addEventListener("click", () => {
const device = await Manager.requestDevice();
if (!device) {
alert("No device selected");
return;
}
});
import { AdbDaemonWebUsbDevice, AdbDaemonWebUsbDeviceManager } from "@yume-chan/adb-daemon-webusb";
declare const Manager: AdbDaemonWebUsbDeviceManager;
document.getElementById("button").addEventListener("click", () => {
const device: AdbDaemonWebUsbDevice | undefined = await Manager.requestDevice();
if (!device) {
alert("No device selected");
return;
}
});
Drop permission
If a device is connected and the permission to access it was granted, but you don't want to access it anymore, you can drop the permission.
device.raw.forget();
Because there is no way to retrieve permission-granted but disconnected devices (unless you got the device
before it was disconnected), it's also not possible to drop permissions for them. (See https://github.com/WICG/webusb/issues/166)