chore: update docs

This commit is contained in:
Simon Chan 2022-04-03 13:14:05 +08:00
parent 8a521c8d93
commit 82f5a90838
No known key found for this signature in database
GPG key ID: A8B69F750B9BCEDD
6 changed files with 62 additions and 52 deletions

View file

@ -5,7 +5,7 @@ Backend for `@yume-chan/adb` using WebUSB ([MDN](https://developer.mozilla.org/e
- [Note](#note) - [Note](#note)
- [`pickDevice`](#pickdevice) - [`pickDevice`](#pickdevice)
- [`fromDevice`](#fromdevice) - [`fromDevice`](#fromdevice)
- [`read`/`write`](#readwrite) - [`connect`](#connect)
## Note ## Note
@ -36,6 +36,10 @@ static async fromDevice(device: USBDevice): Promise<AdbWebBackend>
Create an `AdbWebBackend` instance from an exist `USBDevice` instance. Create an `AdbWebBackend` instance from an exist `USBDevice` instance.
## `read`/`write` ## `connect`
Read/write data from/to the underlying `USBDevice` instance. ```ts
async connect(): Promise<ReadableWritablePair<AdbPacketCore, AdbPacketInit>>
```
Connect to a device and create a pair of `AdbPacket` streams.

View file

@ -4,6 +4,6 @@ Backend for `@yume-chan/adb` using WebSocket API.
Requires WebSockify softwares to bridge the connection between TCP (ADB over Wi-Fi) and WebSocket. Requires WebSockify softwares to bridge the connection between TCP (ADB over Wi-Fi) and WebSocket.
**WARNING:** WebSocket is an unreliable protocol! When send buffer is full, it will throw away any new-coming data, or even close the connection. **WARNING:** WebSocket is an unreliable protocol! When send buffer is full, it will throw away any new-coming data, or even cut the connection.
Note: This package only demonstrate the possibility. It's not intended to be used in production, thus not published to NPM registry. Note: This package only demonstrate the possibility. It's not intended to be used in production, thus not published to NPM registry.

View file

@ -1,18 +1,26 @@
# `@yume-chan/adb-credential-web` # `@yume-chan/adb-credential-web`
Store ADB credentials in LocalStorage. Generate RSA keys using Web Crypto API ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API)) and store them in LocalStorage ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)).
- [`generateKey`](#generatekey) - [`generateKey`](#generatekey)
- [`iterateKeys`](#iteratekeys) - [`iterateKeys`](#iteratekeys)
## `generateKey` ## `generateKey`
**Web Crypto API** ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API)) ```ts
async generateKey(): Promise<Uint8Array>
**Web Storage API** ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)) ```
Generate a RSA private key and store it into LocalStorage. Generate a RSA private key and store it into LocalStorage.
Calling this method multiple times will overwrite the previous key.
The returned `Uint8Array` is the private key in PKCS #8 format.
## `iterateKeys` ## `iterateKeys`
Return the stored RSA private key. (This backend only supports a single key) ```ts
*iterateKeys(): Generator<Uint8Array, void, void>
```
Return the stored RSA private key. (This implementation doesn't support storing multiple keys)

View file

@ -10,14 +10,13 @@ TypeScript implementation of Android Debug Bridge (ADB) protocol.
- [Connection](#connection) - [Connection](#connection)
- [Backend](#backend) - [Backend](#backend)
- [`connect`](#connect) - [`connect`](#connect)
- [`read`](#read)
- [`write`](#write)
- [Authentication](#authentication) - [Authentication](#authentication)
- [AdbCredentialStore](#adbcredentialstore) - [AdbCredentialStore](#adbcredentialstore)
- [`generateKey`](#generatekey) - [`generateKey`](#generatekey)
- [`iterateKeys`](#iteratekeys) - [`iterateKeys`](#iteratekeys)
- [Implementations](#implementations) - [Implementations](#implementations)
- [AdbAuthenticator](#adbauthenticator) - [AdbAuthenticator](#adbauthenticator)
- [`authenticate`](#authenticate)
- [Stream multiplex](#stream-multiplex) - [Stream multiplex](#stream-multiplex)
- [Backend](#backend-1) - [Backend](#backend-1)
- [Commands](#commands) - [Commands](#commands)
@ -38,7 +37,7 @@ TypeScript implementation of Android Debug Bridge (ADB) protocol.
## Compatibility ## Compatibility
Here is a list of features, their used APIs, and their compatibilities. If you don't use an optional feature, you can ignore its requirement. Here is a list of features, their used APIs, and their compatibilities. If an optional feature is not actually used, its requirements can be ignored.
Some features can be polyfilled to support older runtimes, but this library doesn't ship with any polyfills. Some features can be polyfilled to support older runtimes, but this library doesn't ship with any polyfills.
@ -58,9 +57,9 @@ Each backend may have different requirements.
### Use without bundlers ### Use without bundlers
| | Chrome | Edge | Firefox | Internet Explorer | Safari | Node.js | | | Chrome | Edge | Firefox | Internet Explorer | Safari | Node.js |
| --------------------------- | ------ | ---- | ------- | ----------------- | ------ | ------- | | --------------- | ------ | ---- | ------- | ----------------- | ------ | ------- |
| Top-level await<sup>1</sup> | 89 | 89 | 89 | No | 15 | 14.8 | | Top-level await | 89 | 89 | 89 | No | 15 | 14.8 |
[MDN_Streams]: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API [MDN_Streams]: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API
@ -68,33 +67,19 @@ Each backend may have different requirements.
This library doesn't tie to a specific transportation method. This library doesn't tie to a specific transportation method.
Instead, a `Backend` is responsible for transferring data in its own way (USB, WebSocket, etc). Instead, a `Backend` is responsible for transferring data in its own way (USB, WebSocket, TCP, etc).
### Backend ### Backend
#### `connect` #### `connect`
Establishes a connection with the device.
If a backend doesn't have extra steps to establish the connection, it can omit the `connect` method implementation.
#### `read`
```ts ```ts
read(length: number): ArrayBuffer | Promise<ArrayBuffer> connect(): ValueOrPromise<ReadableWritablePair<AdbPacketCore, AdbPacketInit>>
``` ```
Reads the specified amount of data from the underlying connection. Connect to a device and create a pair of `AdbPacket` streams.
The returned `ArrayBuffer` may have more or less data than the `length` parameter specified, if there is some residual data in the connection buffer. The client will automatically call `read` again with the same `length`. The backend is responsible for serializing and deserializing the packets, because it's extreme slow for WebUSB backend (`@yume-chan/adb-backend-webusb`) to read packets with unknown size.
#### `write`
```ts
write(buffer: ArrayBuffer): void | Promise<void>
```
Writes data to the underlying connection.
## Authentication ## Authentication
@ -102,22 +87,19 @@ For how does ADB authentication work, see https://chensi.moe/blog/2020/09/30/web
In this library, authentication comes in two parts: In this library, authentication comes in two parts:
* `AdbCredentialStore`: because JavaScript has no unified method to generate, store and iterate crypto keys, an implementation of `AdbCredentialStore` is required for the two built-in authenticators.
* `AdbAuthenticator`: can be used to implement custom authentication modes.
Custom `AdbCredentialStore`s and `AdbAuthenticator`s can be specified in the `Adb#connect` method.
#### AdbCredentialStore #### AdbCredentialStore
An interface to generate, store and iterate ADB private keys on each runtime. (Because Node.js and Browsers have different APIs to do this)
##### `generateKey` ##### `generateKey`
```ts ```ts
generateKey(): ArrayBuffer | Promise<ArrayBuffer> generateKey(): ValueOrPromise<Uint8Array>
``` ```
Generate and store a RSA private key with modulus length `2048` and public exponent `65537`. Generate and store a RSA private key with modulus length `2048` and public exponent `65537`.
The returned `ArrayBuffer` is the private key in PKCS #8 format. The returned `Uint8Array` is the private key in PKCS #8 format.
##### `iterateKeys` ##### `iterateKeys`
@ -131,7 +113,7 @@ Each call to `iterateKeys` must return a different iterator that iterate through
##### Implementations ##### Implementations
The `@yume-chan/adb-backend-webusb` package contains a `AdbWebCredentialStore` implementation using Web Crypto API to generating keys and Web Storage API to storing keys. The `@yume-chan/adb-credential-web` package contains a `AdbWebCredentialStore` implementation using Web Crypto API for generating keys and Web Storage API for storing keys.
#### AdbAuthenticator #### AdbAuthenticator
@ -139,6 +121,20 @@ An `AdbAuthenticator` generates `AUTH` responses for each `AUTH` request from se
This package contains `AdbSignatureAuthenticator` and `AdbPublicKeyAuthenticator`, the two basic modes. This package contains `AdbSignatureAuthenticator` and `AdbPublicKeyAuthenticator`, the two basic modes.
#### `authenticate`
```ts
static async authenticate(
connection: ReadableWritablePair<AdbPacketCore, AdbPacketCore>,
credentialStore: AdbCredentialStore,
authenticators = AdbDefaultAuthenticators,
): Promise<Adb>
```
Call this method to authenticate the connection and create an `Adb` instance.
It's possible to call `authenticate` multiple times on a single connection, every time the device receives a `CNXN` packet, it resets its internal state, and starts a new authentication process.
## Stream multiplex ## Stream multiplex
ADB commands are all based on streams. Multiple streams can send and receive at the same time in one connection. ADB commands are all based on streams. Multiple streams can send and receive at the same time in one connection.
@ -158,16 +154,18 @@ The `Backend` is responsible for reading and writing data from underlying source
Spawns child process on server. ADB has two shell modes: Spawns child process on server. ADB has two shell modes:
| | Legacy mode | Shell Protocol | | | Legacy mode | Shell Protocol |
| --------------------------- | ---------------- | ------------------ | | --------------------------- | --------------------------- | ---------------------------- |
| Feature flag | - | `shell_v2` | | Feature flag | - | `shell_v2` |
| Implementation | `AdbLegacyShell` | `AdbShellProtocol` | | Implementation | `AdbNoneSubprocessProtocol` | `AdbShellSubprocessProtocol` |
| Splitting stdout and stderr | No | Yes | | Splitting stdout and stderr | No | Yes |
| Returning exit code | No | Yes | | Returning exit code | No | Yes |
| Resizing window | No | Yes | | Resizing window | No | Yes |
The `Adb#childProcess#shell` and `Adb#childProcess#spawn` methods accepts a list of implementations, and will use the first supported one. The `Adb#childProcess#shell` and `Adb#childProcess#spawn` methods accepts a list of implementations, and will use the first supported one.
For simple command invocation, usually the `AdbNoneSubprocessProtocol` is enough.
### usb ### usb
Disable ADB over WiFi. Disable ADB over WiFi.

View file

@ -19,14 +19,14 @@ export const VERSION_OMIT_CHECKSUM = 0x01000001;
export class Adb { export class Adb {
/** /**
* It's possible to call `authenticate` multiple times on a single connection, * It's possible to call `authenticate` multiple times on a single connection,
* every time the device receives a `CNXN` packet it will reset its internal state, * every time the device receives a `CNXN` packet, it resets its internal state,
* and begin authentication again. * and starts a new authentication process.
*/ */
public static async authenticate( public static async authenticate(
connection: ReadableWritablePair<AdbPacketCore, AdbPacketCore>, connection: ReadableWritablePair<AdbPacketCore, AdbPacketCore>,
credentialStore: AdbCredentialStore, credentialStore: AdbCredentialStore,
authenticators = AdbDefaultAuthenticators, authenticators = AdbDefaultAuthenticators,
) { ): Promise<Adb> {
let version = 0x01000001; let version = 0x01000001;
let maxPayloadSize = 0x100000; let maxPayloadSize = 0x100000;

View file

@ -83,7 +83,7 @@ const buffer = MyStruct.serialize({
## Compatibility ## Compatibility
Here is a list of features, their used APIs, and their compatibilities. If you don't use an optional feature, you can ignore its requirement. Here is a list of features, their used APIs, and their compatibilities. If an optional feature is not actually used, its requirements can be ignored.
Some features can be polyfilled to support older runtimes, but this library doesn't ship with any polyfills. Some features can be polyfilled to support older runtimes, but this library doesn't ship with any polyfills.