Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 6425e54c authored by Simon Chan's avatar Simon Chan
Browse files

chore: update README and comments

parent cceaa657
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
{
    "changes": [
        {
            "packageName": "@yume-chan/scrcpy",
            "comment": "Add support for Scrcpy server version 1.25",
            "type": "none"
        }
    ],
    "packageName": "@yume-chan/scrcpy"
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -2,7 +2,7 @@
    "changes": [
    "changes": [
        {
        {
            "packageName": "@yume-chan/stream-extra",
            "packageName": "@yume-chan/stream-extra",
            "comment": "Add the ability to load native Web Streams API implementation from `globalThis`",
            "comment": "Change to load native Web Streams API implementation from `globalThis` if available",
            "type": "none"
            "type": "none"
        }
        }
    ],
    ],
+1 −1
Original line number Original line Diff line number Diff line
@@ -2,4 +2,4 @@


Use [Direct Sockets API](https://wicg.github.io/direct-sockets/) for plugin-free ADB over WiFi connection.
Use [Direct Sockets API](https://wicg.github.io/direct-sockets/) for plugin-free ADB over WiFi connection.


Note: Direct Sockets API is still under development in Chrome and requires extra command line arguments to enable. This package is not intended to be used in production, thus not published to NPM registry.
Note: Direct Sockets API is still under development. Currently it's only available in Chrome and requires extra command line arguments to enable. This package is not ready to be used in production, thus not published to NPM registry.
+50 −16
Original line number Original line Diff line number Diff line
@@ -3,43 +3,77 @@
Backend for `@yume-chan/adb` using WebUSB ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/USB), [Spec](https://wicg.github.io/webusb)) API.
Backend for `@yume-chan/adb` using WebUSB ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/USB), [Spec](https://wicg.github.io/webusb)) API.


- [Note](#note)
- [Note](#note)
- [`pickDevice`](#pickdevice)
- [Use in Node.js](#use-in-nodejs)
- [`fromDevice`](#fromdevice)
- [API](#api)
  - [Constructor](#constructor)
  - [`isSupported()`](#issupported)
  - [`requestDevice`](#requestdevice)
  - [`connect`](#connect)
  - [`connect`](#connect)


## Note
## Note


WebUSB API requires [secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) (basically means HTTPS).
WebUSB API requires [secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) (HTTPS).


Chrome will treat `localhost` as secure, but if you want to access a dev server running on another machine, you need to add the domain to the allowlist:
Chrome will treat `localhost` as secure, but if you want to access a dev server running on another machine, follow the steps to add the domain name to allowlist:


1. Open `chrome://flags/#unsafely-treat-insecure-origin-as-secure`
1. Open `chrome://flags/#unsafely-treat-insecure-origin-as-secure`
2. Add the protocol and domain part of your url (e.g. `http://192.168.0.100:9000`) to the input box
2. Add the protocol and domain part of your url (e.g. `http://192.168.0.100:9000`) to the input box
3. Choose `Enable` from the dropdown menu
3. Choose `Enable` from the dropdown menu
4. Restart your browser
4. Restart browser


## `pickDevice`
## Use in Node.js

Node.js doesn't support WebUSB API, but you might be able to use this package with the [`usb`](https://www.npmjs.com/package/usb) package (I didn't test this. If you have any results, please open a discussion to share with us).

All static methods will not work, but the constructor only requires an object that's structurally compatible with `USBDevice` interface. The `WebUSBDevice` class in `usb` package should satisfy this requirement.

## API

### Constructor


```ts
```ts
static async pickDevice(): Promise<AdbWebBackend | undefined>
public constructor(
    device: USBDevice,
    filters: AdbDeviceFilter[] = [ADB_DEFAULT_DEVICE_FILTER]
);
```
```


Request browser to present a list of connected Android devices to let the user choose from.
Create a new instance of `AdbWebBackend` using a `USBDevice` instance you already have.


Returns `undefined` if the user canceled the picker.
`USBDevice` type is from WebUSB API.


## `fromDevice`
The `filters` parameter specifies the `classCode`, `subclassCode` and `protocolCode`  to use when searching for ADB interface. The default value is `[{ classCode: 0xff, subclassCode: 0x42, protocolCode: 0x1 }]`, defined by Google.

### `isSupported()`


```ts
```ts
static async fromDevice(device: USBDevice): Promise<AdbWebBackend>
public static isSupported(): boolean;
```
```


Create an `AdbWebBackend` instance from an exist `USBDevice` instance.
Check if WebUSB API is supported by the browser.

### `requestDevice`

```ts
public static async requestDevice(
    filters: AdbDeviceFilter[] = [ADB_DEFAULT_DEVICE_FILTER]
): Promise<AdbWebUsbBackend | undefined>
```

Request access to a connected device from browser. The browser will display a list of devices to the user and let them choose one.

Only available in browsers that support WebUSB API (When `isSupported()` returns `true`).

The `filters` parameter must have `classCode`, `subclassCode` and `protocolCode` fields for selecting the ADB interface. It can also have `vendorId`, `productId` or `serialNumber` fields to limit the displayed device list.

Returns an `AdbWebUsbBackend` instance, or `undefined` if the user cancelled the picker.


## `connect`
### `connect`


```ts
```ts
async connect(): Promise<ReadableWritablePair<AdbPacketCore, AdbPacketInit>>
public async connect(): Promise<
    ReadableWritablePair<AdbPacketData, AdbPacketInit>
>
```
```


Connect to a device and create a pair of `AdbPacket` streams.
Claim the device and create a pair of `AdbPacket` streams to the ADB interface.
+44 −11
Original line number Original line Diff line number Diff line
@@ -235,17 +235,28 @@ export class AdbWebUsbBackendStream
}
}


export class AdbWebUsbBackend implements AdbBackend {
export class AdbWebUsbBackend implements AdbBackend {
    /**
     * Check if WebUSB API is supported by the browser.
     *
     * @returns `true` if WebUSB is supported by the current browser.
     */
    public static isSupported(): boolean {
    public static isSupported(): boolean {
        return !!globalThis.navigator?.usb;
        return !!globalThis.navigator?.usb;
    }
    }


    public static async getDevices(
    /**
        filters: AdbDeviceFilter[] = [ADB_DEFAULT_DEVICE_FILTER]
     * Request access to a connected device from browser.
    ): Promise<AdbWebUsbBackend[]> {
     * The browser will display a list of devices to the user and let them choose one.
        const devices = await window.navigator.usb.getDevices();
     *
        return devices.map((device) => new AdbWebUsbBackend(filters, device));
     * Only available in browsers that support WebUSB API (When `isSupported()` returns `true`).
    }
     *

     * @param filters
     * The filters to apply to the device list.
     *
     * It must have `classCode`, `subclassCode` and `protocolCode` fields for selecting the ADB interface,
     * but can also have `vendorId`, `productId` or `serialNumber` fields to limit the displayed device list.
     * @returns The `AdbWebUsbBackend` instance if the user selected a device, or `undefined` if the user cancelled the device picker.
     */
    public static async requestDevice(
    public static async requestDevice(
        filters: AdbDeviceFilter[] = [ADB_DEFAULT_DEVICE_FILTER]
        filters: AdbDeviceFilter[] = [ADB_DEFAULT_DEVICE_FILTER]
    ): Promise<AdbWebUsbBackend | undefined> {
    ): Promise<AdbWebUsbBackend | undefined> {
@@ -253,7 +264,7 @@ export class AdbWebUsbBackend implements AdbBackend {
            const device = await navigator.usb.requestDevice({
            const device = await navigator.usb.requestDevice({
                filters,
                filters,
            });
            });
            return new AdbWebUsbBackend(filters, device);
            return new AdbWebUsbBackend(device, filters);
        } catch (e) {
        } catch (e) {
            // User cancelled the device picker
            // User cancelled the device picker
            if (e instanceof DOMException && e.name === "NotFoundError") {
            if (e instanceof DOMException && e.name === "NotFoundError") {
@@ -264,6 +275,13 @@ export class AdbWebUsbBackend implements AdbBackend {
        }
        }
    }
    }


    public static async getDevices(
        filters: AdbDeviceFilter[] = [ADB_DEFAULT_DEVICE_FILTER]
    ): Promise<AdbWebUsbBackend[]> {
        const devices = await window.navigator.usb.getDevices();
        return devices.map((device) => new AdbWebUsbBackend(device, filters));
    }

    private _filters: AdbDeviceFilter[];
    private _filters: AdbDeviceFilter[];
    private _device: USBDevice;
    private _device: USBDevice;
    public get device() {
    public get device() {
@@ -278,12 +296,27 @@ export class AdbWebUsbBackend implements AdbBackend {
        return this._device.productName!;
        return this._device.productName!;
    }
    }


    public constructor(filters: AdbDeviceFilter[], device: USBDevice) {
    /**
        this._filters = filters;
     * Create a new instance of `AdbWebBackend` using a `USBDevice` instance you already have.
     *
     * @param device The `USBDevice` instance you already have.
     * @param filters The filters to use when searching for ADB interface. The default value is `[{ classCode: 0xff, subclassCode: 0x42, protocolCode: 0x1 }]`, defined by Google.
     */
    public constructor(
        device: USBDevice,
        filters: AdbDeviceFilter[] = [ADB_DEFAULT_DEVICE_FILTER]
    ) {
        this._device = device;
        this._device = device;
        this._filters = filters;
    }
    }


    public async connect() {
    /**
     * Claim the device and create a pair of `AdbPacket` streams to the ADB interface.
     * @returns The pair of `AdbPacket` streams.
     */
    public async connect(): Promise<
        ReadableWritablePair<AdbPacketData, AdbPacketInit>
    > {
        if (!this._device.opened) {
        if (!this._device.opened) {
            await this._device.open();
            await this._device.open();
        }
        }
Loading