@yume-chan/adb-daemon-webusb 0.0.23 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -2
- package/LICENSE +1 -1
- package/README.md +6 -3
- package/esm/device.d.ts +11 -14
- package/esm/device.d.ts.map +1 -1
- package/esm/device.js +46 -56
- package/esm/device.js.map +1 -1
- package/esm/index.d.ts +1 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -1
- package/esm/index.js.map +1 -1
- package/esm/manager.d.ts +6 -25
- package/esm/manager.d.ts.map +1 -1
- package/esm/manager.js +30 -60
- package/esm/manager.js.map +1 -1
- package/esm/observer.d.ts +17 -0
- package/esm/observer.d.ts.map +1 -0
- package/esm/observer.js +54 -0
- package/esm/observer.js.map +1 -0
- package/esm/utils.d.ts +22 -5
- package/esm/utils.d.ts.map +1 -1
- package/esm/utils.js +76 -5
- package/esm/utils.js.map +1 -1
- package/package.json +13 -11
- package/src/device.ts +56 -71
- package/src/index.ts +1 -1
- package/src/manager.ts +49 -75
- package/src/observer.ts +90 -0
- package/src/utils.ts +142 -18
- package/tsconfig.build.json +2 -13
- package/tsconfig.build.tsbuildinfo +1 -1
- package/CHANGELOG.json +0 -193
- package/esm/watcher.d.ts +0 -7
- package/esm/watcher.d.ts.map +0 -1
- package/esm/watcher.js +0 -21
- package/esm/watcher.js.map +0 -1
- package/src/watcher.ts +0 -28
package/esm/manager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,qBAAqB,EACrB,8BAA8B,GACjC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AASvD,MAAM,OAAO,4BAA4B;IACrC;;;;OAIG;IACH,MAAM,CAAU,OAAO,GACnB,OAAO,UAAU,CAAC,SAAS,KAAK,WAAW;QAC3C,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG;QACtB,CAAC,CAAC,IAAI,4BAA4B,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC;QAC5D,CAAC,CAAC,SAAS,CAAC;IAEpB,WAAW,CAAM;IAEjB;;;OAGG;IACH,YAAY,UAAe;QACvB,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CACf,UAA6D,EAAE;QAE/D,MAAM,OAAO,GAAG,8BAA8B,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEhE,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC;gBAChD,OAAO;gBACP,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;aAC7C,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,YAAY,CAC3B,MAAM,EACN,OAAO,EACP,OAAO,CAAC,gBAAgB,CAC3B,CAAC;YACF,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,oDAAoD;gBACpD,6BAA6B;gBAC7B,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,OAAO,IAAI,qBAAqB,CAC5B,MAAM,EACN,UAAU,EACV,IAAI,CAAC,WAAW,CACnB,CAAC;QACN,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,qBAAqB;YACrB,IAAI,WAAW,CAAC,CAAC,EAAE,eAAe,CAAC,EAAE,CAAC;gBAClC,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,MAAM,CAAC,CAAC;QACZ,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CACZ,UAA6D,EAAE;QAE/D,MAAM,OAAO,GAAG,8BAA8B,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEhE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QACpD,aAAa;QACb,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC3B,MAAM,UAAU,GAAG,YAAY,CAC3B,MAAM,EACN,OAAO,EACP,OAAO,CAAC,gBAAgB,CAC3B,CAAC;YACF,IAAI,UAAU,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CACP,IAAI,qBAAqB,CACrB,MAAM,EACN,UAAU,EACV,IAAI,CAAC,WAAW,CACnB,CACJ,CAAC;YACN,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,YAAY,CACR,UAA6D,EAAE;QAE/D,OAAO,IAAI,6BAA6B,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DeviceObserver } from "@yume-chan/adb";
|
|
2
|
+
import { AdbDaemonWebUsbDevice } from "./device.js";
|
|
3
|
+
import type { AdbDaemonWebUsbDeviceManager } from "./manager.js";
|
|
4
|
+
/**
|
|
5
|
+
* A watcher that listens for new WebUSB devices and notifies the callback when
|
|
6
|
+
* a new device is connected or disconnected.
|
|
7
|
+
*/
|
|
8
|
+
export declare class AdbDaemonWebUsbDeviceObserver implements DeviceObserver<AdbDaemonWebUsbDevice> {
|
|
9
|
+
#private;
|
|
10
|
+
onDeviceAdd: import("@yume-chan/event").AddEventListener<AdbDaemonWebUsbDevice[], unknown>;
|
|
11
|
+
onDeviceRemove: import("@yume-chan/event").AddEventListener<AdbDaemonWebUsbDevice[], unknown>;
|
|
12
|
+
onListChange: import("@yume-chan/event").AddEventListener<AdbDaemonWebUsbDevice[], unknown>;
|
|
13
|
+
current: AdbDaemonWebUsbDevice[];
|
|
14
|
+
constructor(usb: USB, options?: AdbDaemonWebUsbDeviceManager.RequestDeviceOptions);
|
|
15
|
+
stop(): void;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.d.ts","sourceRoot":"","sources":["../src/observer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EACH,qBAAqB,EAExB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAIjE;;;GAGG;AACH,qBAAa,6BACT,YAAW,cAAc,CAAC,qBAAqB,CAAC;;IAOhD,WAAW,gFAA2B;IAGtC,cAAc,gFAA8B;IAG5C,YAAY,gFAA4B;IAExC,OAAO,EAAE,qBAAqB,EAAE,CAAM;gBAGlC,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,4BAA4B,CAAC,oBAAyB;IA2CnE,IAAI,IAAI,IAAI;CAWf"}
|
package/esm/observer.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { EventEmitter } from "@yume-chan/event";
|
|
2
|
+
import { AdbDaemonWebUsbDevice, mergeDefaultAdbInterfaceFilter, } from "./device.js";
|
|
3
|
+
import { matchFilters } from "./utils.js";
|
|
4
|
+
/**
|
|
5
|
+
* A watcher that listens for new WebUSB devices and notifies the callback when
|
|
6
|
+
* a new device is connected or disconnected.
|
|
7
|
+
*/
|
|
8
|
+
export class AdbDaemonWebUsbDeviceObserver {
|
|
9
|
+
#filters;
|
|
10
|
+
#exclusionFilters;
|
|
11
|
+
#usbManager;
|
|
12
|
+
#onDeviceAdd = new EventEmitter();
|
|
13
|
+
onDeviceAdd = this.#onDeviceAdd.event;
|
|
14
|
+
#onDeviceRemove = new EventEmitter();
|
|
15
|
+
onDeviceRemove = this.#onDeviceRemove.event;
|
|
16
|
+
#onListChange = new EventEmitter();
|
|
17
|
+
onListChange = this.#onListChange.event;
|
|
18
|
+
current = [];
|
|
19
|
+
constructor(usb, options = {}) {
|
|
20
|
+
this.#filters = mergeDefaultAdbInterfaceFilter(options.filters);
|
|
21
|
+
this.#exclusionFilters = options.exclusionFilters;
|
|
22
|
+
this.#usbManager = usb;
|
|
23
|
+
this.#usbManager.addEventListener("connect", this.#handleConnect);
|
|
24
|
+
this.#usbManager.addEventListener("disconnect", this.#handleDisconnect);
|
|
25
|
+
}
|
|
26
|
+
#handleConnect = (e) => {
|
|
27
|
+
const interface_ = matchFilters(e.device, this.#filters, this.#exclusionFilters);
|
|
28
|
+
if (!interface_) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const device = new AdbDaemonWebUsbDevice(e.device, interface_, this.#usbManager);
|
|
32
|
+
this.#onDeviceAdd.fire([device]);
|
|
33
|
+
this.current.push(device);
|
|
34
|
+
this.#onListChange.fire(this.current);
|
|
35
|
+
};
|
|
36
|
+
#handleDisconnect = (e) => {
|
|
37
|
+
const index = this.current.findIndex((device) => device.raw === e.device);
|
|
38
|
+
if (index !== -1) {
|
|
39
|
+
const device = this.current[index];
|
|
40
|
+
this.#onDeviceRemove.fire([device]);
|
|
41
|
+
this.current[index] = this.current[this.current.length - 1];
|
|
42
|
+
this.current.length -= 1;
|
|
43
|
+
this.#onListChange.fire(this.current);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
stop() {
|
|
47
|
+
this.#usbManager.removeEventListener("connect", this.#handleConnect);
|
|
48
|
+
this.#usbManager.removeEventListener("disconnect", this.#handleDisconnect);
|
|
49
|
+
this.#onDeviceAdd.dispose();
|
|
50
|
+
this.#onDeviceRemove.dispose();
|
|
51
|
+
this.#onListChange.dispose();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.js","sourceRoot":"","sources":["../src/observer.ts"],"names":[],"mappings":"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"}
|
package/esm/utils.d.ts
CHANGED
|
@@ -1,14 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
export declare function isErrorName(e: unknown, name: string): e is Error;
|
|
2
|
+
export type PickNonNullable<T, K extends keyof T> = {
|
|
3
|
+
[P in K]-?: NonNullable<T[P]>;
|
|
4
|
+
};
|
|
3
5
|
/**
|
|
4
6
|
* `classCode`, `subclassCode` and `protocolCode` are required
|
|
5
7
|
* for selecting correct USB configuration and interface.
|
|
6
8
|
*/
|
|
7
|
-
export type
|
|
8
|
-
export declare function
|
|
9
|
+
export type UsbInterfaceFilter = PickNonNullable<USBDeviceFilter, "classCode" | "subclassCode" | "protocolCode">;
|
|
10
|
+
export declare function isUsbInterfaceFilter(filter: USBDeviceFilter): filter is UsbInterfaceFilter;
|
|
11
|
+
export interface UsbInterfaceIdentifier {
|
|
9
12
|
configuration: USBConfiguration;
|
|
10
13
|
interface_: USBInterface;
|
|
11
14
|
alternate: USBAlternateInterface;
|
|
12
|
-
}
|
|
15
|
+
}
|
|
16
|
+
export declare function findUsbInterface(device: USBDevice, filter: UsbInterfaceFilter): UsbInterfaceIdentifier | undefined;
|
|
13
17
|
export declare function getSerialNumber(device: USBDevice): string;
|
|
18
|
+
/**
|
|
19
|
+
* Find the first pair of input and output endpoints from an alternate interface.
|
|
20
|
+
*
|
|
21
|
+
* ADB interface only has two endpoints, one for input and one for output.
|
|
22
|
+
*/
|
|
23
|
+
export declare function findUsbEndpoints(endpoints: USBEndpoint[]): {
|
|
24
|
+
inEndpoint: USBEndpoint;
|
|
25
|
+
outEndpoint: USBEndpoint;
|
|
26
|
+
};
|
|
27
|
+
export declare function matchFilter(device: USBDevice, filter: USBDeviceFilter & UsbInterfaceFilter): UsbInterfaceIdentifier | false;
|
|
28
|
+
export declare function matchFilter(device: USBDevice, filter: USBDeviceFilter): boolean;
|
|
29
|
+
export declare function matchFilters(device: USBDevice, filters: (USBDeviceFilter & UsbInterfaceFilter)[], exclusionFilters?: USBDeviceFilter[]): UsbInterfaceIdentifier | false;
|
|
30
|
+
export declare function matchFilters(device: USBDevice, filters: USBDeviceFilter[], exclusionFilters?: USBDeviceFilter[]): boolean;
|
|
14
31
|
//# sourceMappingURL=utils.d.ts.map
|
package/esm/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,KAAK,CAOhE;AAED,MAAM,MAAM,eAAe,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI;KAC/C,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,eAAe,CAC5C,eAAe,EACf,WAAW,GAAG,cAAc,GAAG,cAAc,CAChD,CAAC;AAEF,wBAAgB,oBAAoB,CAChC,MAAM,EAAE,eAAe,GACxB,MAAM,IAAI,kBAAkB,CAM9B;AAaD,MAAM,WAAW,sBAAsB;IACnC,aAAa,EAAE,gBAAgB,CAAC;IAChC,UAAU,EAAE,YAAY,CAAC;IACzB,SAAS,EAAE,qBAAqB,CAAC;CACpC;AAED,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,kBAAkB,GAC3B,sBAAsB,GAAG,SAAS,CAWpC;AAMD,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,UAMhD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,WAAW,EAAE;;;EAgCxD;AAED,wBAAgB,WAAW,CACvB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,eAAe,GAAG,kBAAkB,GAC7C,sBAAsB,GAAG,KAAK,CAAC;AAClC,wBAAgB,WAAW,CACvB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,eAAe,GACxB,OAAO,CAAC;AA8BX,wBAAgB,YAAY,CACxB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,CAAC,eAAe,GAAG,kBAAkB,CAAC,EAAE,EACjD,gBAAgB,CAAC,EAAE,eAAe,EAAE,GACrC,sBAAsB,GAAG,KAAK,CAAC;AAClC,wBAAgB,YAAY,CACxB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,eAAe,EAAE,EAC1B,gBAAgB,CAAC,EAAE,eAAe,EAAE,GACrC,OAAO,CAAC"}
|
package/esm/utils.js
CHANGED
|
@@ -4,22 +4,27 @@ export function isErrorName(e, name) {
|
|
|
4
4
|
// https://github.com/node-usb/node-usb/issues/573
|
|
5
5
|
return (typeof e === "object" && e !== null && "name" in e && e.name === name);
|
|
6
6
|
}
|
|
7
|
-
function
|
|
8
|
-
return
|
|
7
|
+
export function isUsbInterfaceFilter(filter) {
|
|
8
|
+
return (filter.classCode !== undefined &&
|
|
9
|
+
filter.subclassCode !== undefined &&
|
|
10
|
+
filter.protocolCode !== undefined);
|
|
11
|
+
}
|
|
12
|
+
function matchUsbInterfaceFilter(alternate, filter) {
|
|
13
|
+
return (alternate.interfaceClass === filter.classCode &&
|
|
9
14
|
alternate.interfaceSubclass === filter.subclassCode &&
|
|
10
15
|
alternate.interfaceProtocol === filter.protocolCode);
|
|
11
16
|
}
|
|
12
|
-
export function
|
|
17
|
+
export function findUsbInterface(device, filter) {
|
|
13
18
|
for (const configuration of device.configurations) {
|
|
14
19
|
for (const interface_ of configuration.interfaces) {
|
|
15
20
|
for (const alternate of interface_.alternates) {
|
|
16
|
-
if (
|
|
21
|
+
if (matchUsbInterfaceFilter(alternate, filter)) {
|
|
17
22
|
return { configuration, interface_, alternate };
|
|
18
23
|
}
|
|
19
24
|
}
|
|
20
25
|
}
|
|
21
26
|
}
|
|
22
|
-
|
|
27
|
+
return undefined;
|
|
23
28
|
}
|
|
24
29
|
function padNumber(value) {
|
|
25
30
|
return value.toString(16).padStart(4, "0");
|
|
@@ -30,4 +35,70 @@ export function getSerialNumber(device) {
|
|
|
30
35
|
}
|
|
31
36
|
return padNumber(device.vendorId) + "x" + padNumber(device.productId);
|
|
32
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Find the first pair of input and output endpoints from an alternate interface.
|
|
40
|
+
*
|
|
41
|
+
* ADB interface only has two endpoints, one for input and one for output.
|
|
42
|
+
*/
|
|
43
|
+
export function findUsbEndpoints(endpoints) {
|
|
44
|
+
if (endpoints.length === 0) {
|
|
45
|
+
throw new TypeError("No endpoints given");
|
|
46
|
+
}
|
|
47
|
+
let inEndpoint;
|
|
48
|
+
let outEndpoint;
|
|
49
|
+
for (const endpoint of endpoints) {
|
|
50
|
+
switch (endpoint.direction) {
|
|
51
|
+
case "in":
|
|
52
|
+
inEndpoint = endpoint;
|
|
53
|
+
if (outEndpoint) {
|
|
54
|
+
return { inEndpoint, outEndpoint };
|
|
55
|
+
}
|
|
56
|
+
break;
|
|
57
|
+
case "out":
|
|
58
|
+
outEndpoint = endpoint;
|
|
59
|
+
if (inEndpoint) {
|
|
60
|
+
return { inEndpoint, outEndpoint };
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!inEndpoint) {
|
|
66
|
+
throw new TypeError("No input endpoint found.");
|
|
67
|
+
}
|
|
68
|
+
if (!outEndpoint) {
|
|
69
|
+
throw new TypeError("No output endpoint found.");
|
|
70
|
+
}
|
|
71
|
+
throw new Error("unreachable");
|
|
72
|
+
}
|
|
73
|
+
export function matchFilter(device, filter) {
|
|
74
|
+
if (filter.vendorId !== undefined && device.vendorId !== filter.vendorId) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
if (filter.productId !== undefined &&
|
|
78
|
+
device.productId !== filter.productId) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
if (filter.serialNumber !== undefined &&
|
|
82
|
+
getSerialNumber(device) !== filter.serialNumber) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
if (isUsbInterfaceFilter(filter)) {
|
|
86
|
+
return findUsbInterface(device, filter) || false;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
export function matchFilters(device, filters, exclusionFilters) {
|
|
91
|
+
if (exclusionFilters && exclusionFilters.length > 0) {
|
|
92
|
+
if (matchFilters(device, exclusionFilters)) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
for (const filter of filters) {
|
|
97
|
+
const result = matchFilter(device, filter);
|
|
98
|
+
if (result) {
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
33
104
|
//# sourceMappingURL=utils.js.map
|
package/esm/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,CAAU,EAAE,IAAY;IAChD,+CAA+C;IAC/C,wBAAwB;IACxB,kDAAkD;IAClD,OAAO,CACH,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CACxE,CAAC;AACN,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,CAAU,EAAE,IAAY;IAChD,+CAA+C;IAC/C,wBAAwB;IACxB,kDAAkD;IAClD,OAAO,CACH,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CACxE,CAAC;AACN,CAAC;AAeD,MAAM,UAAU,oBAAoB,CAChC,MAAuB;IAEvB,OAAO,CACH,MAAM,CAAC,SAAS,KAAK,SAAS;QAC9B,MAAM,CAAC,YAAY,KAAK,SAAS;QACjC,MAAM,CAAC,YAAY,KAAK,SAAS,CACpC,CAAC;AACN,CAAC;AAED,SAAS,uBAAuB,CAC5B,SAAgC,EAChC,MAA0B;IAE1B,OAAO,CACH,SAAS,CAAC,cAAc,KAAK,MAAM,CAAC,SAAS;QAC7C,SAAS,CAAC,iBAAiB,KAAK,MAAM,CAAC,YAAY;QACnD,SAAS,CAAC,iBAAiB,KAAK,MAAM,CAAC,YAAY,CACtD,CAAC;AACN,CAAC;AAQD,MAAM,UAAU,gBAAgB,CAC5B,MAAiB,EACjB,MAA0B;IAE1B,KAAK,MAAM,aAAa,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAChD,KAAK,MAAM,UAAU,IAAI,aAAa,CAAC,UAAU,EAAE,CAAC;YAChD,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;gBAC5C,IAAI,uBAAuB,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;oBAC7C,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;gBACpD,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC5B,OAAO,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC7C,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACtB,OAAO,MAAM,CAAC,YAAY,CAAC;IAC/B,CAAC;IAED,OAAO,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAwB;IACrD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,UAAmC,CAAC;IACxC,IAAI,WAAoC,CAAC;IAEzC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QAC/B,QAAQ,QAAQ,CAAC,SAAS,EAAE,CAAC;YACzB,KAAK,IAAI;gBACL,UAAU,GAAG,QAAQ,CAAC;gBACtB,IAAI,WAAW,EAAE,CAAC;oBACd,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;gBACvC,CAAC;gBACD,MAAM;YACV,KAAK,KAAK;gBACN,WAAW,GAAG,QAAQ,CAAC;gBACvB,IAAI,UAAU,EAAE,CAAC;oBACb,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;gBACvC,CAAC;gBACD,MAAM;QACd,CAAC;IACL,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QACd,MAAM,IAAI,SAAS,CAAC,0BAA0B,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACf,MAAM,IAAI,SAAS,CAAC,2BAA2B,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC;AAUD,MAAM,UAAU,WAAW,CACvB,MAAiB,EACjB,MAAuB;IAEvB,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,EAAE,CAAC;QACvE,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IACI,MAAM,CAAC,SAAS,KAAK,SAAS;QAC9B,MAAM,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,EACvC,CAAC;QACC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IACI,MAAM,CAAC,YAAY,KAAK,SAAS;QACjC,eAAe,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,YAAY,EACjD,CAAC;QACC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC;IACrD,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAYD,MAAM,UAAU,YAAY,CACxB,MAAiB,EACjB,OAA0B,EAC1B,gBAAoC;IAEpC,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,IAAI,YAAY,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAAE,CAAC;YACzC,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,MAAM,EAAE,CAAC;YACT,OAAO,MAAM,CAAC;QAClB,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yume-chan/adb-daemon-webusb",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Adb daemon transport connection for `@yume-chan/adb` using WebUSB API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webusb",
|
|
@@ -24,23 +24,25 @@
|
|
|
24
24
|
"type": "module",
|
|
25
25
|
"main": "esm/index.js",
|
|
26
26
|
"types": "esm/index.d.ts",
|
|
27
|
+
"sideEffects": false,
|
|
27
28
|
"dependencies": {
|
|
28
29
|
"@types/w3c-web-usb": "^1.0.10",
|
|
29
|
-
"@yume-chan/adb": "^0.0
|
|
30
|
-
"@yume-chan/stream-extra": "^0.0
|
|
31
|
-
"@yume-chan/struct": "^0.0
|
|
32
|
-
"
|
|
30
|
+
"@yume-chan/adb": "^1.0.0",
|
|
31
|
+
"@yume-chan/stream-extra": "^1.0.0",
|
|
32
|
+
"@yume-chan/struct": "^1.0.0",
|
|
33
|
+
"@yume-chan/event": "^1.0.0"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
36
|
+
"@types/node": "^22.10.0",
|
|
37
|
+
"prettier": "^3.4.1",
|
|
38
|
+
"typescript": "^5.7.2",
|
|
39
|
+
"@yume-chan/test-runner": "^1.0.0",
|
|
35
40
|
"@yume-chan/eslint-config": "^1.0.0",
|
|
36
|
-
"@yume-chan/tsconfig": "^1.0.0"
|
|
37
|
-
"eslint": "^8.57.0",
|
|
38
|
-
"prettier": "^3.2.5",
|
|
39
|
-
"typescript": "^5.4.2"
|
|
41
|
+
"@yume-chan/tsconfig": "^1.0.0"
|
|
40
42
|
},
|
|
41
43
|
"scripts": {
|
|
42
44
|
"build": "tsc -b tsconfig.build.json",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
+
"lint": "run-eslint && prettier src/**/*.ts --write --tab-width 4",
|
|
46
|
+
"test": "run-test"
|
|
45
47
|
}
|
|
46
48
|
}
|
package/src/device.ts
CHANGED
|
@@ -14,67 +14,41 @@ import type {
|
|
|
14
14
|
WritableStream,
|
|
15
15
|
} from "@yume-chan/stream-extra";
|
|
16
16
|
import {
|
|
17
|
-
ConsumableWritableStream,
|
|
18
17
|
DuplexStreamFactory,
|
|
18
|
+
MaybeConsumable,
|
|
19
19
|
ReadableStream,
|
|
20
20
|
pipeFrom,
|
|
21
21
|
} from "@yume-chan/stream-extra";
|
|
22
22
|
import type { ExactReadable } from "@yume-chan/struct";
|
|
23
|
-
import {
|
|
23
|
+
import { EmptyUint8Array } from "@yume-chan/struct";
|
|
24
24
|
|
|
25
|
-
import type {
|
|
26
|
-
import {
|
|
27
|
-
findUsbAlternateInterface,
|
|
28
|
-
getSerialNumber,
|
|
29
|
-
isErrorName,
|
|
30
|
-
} from "./utils.js";
|
|
25
|
+
import type { UsbInterfaceFilter, UsbInterfaceIdentifier } from "./utils.js";
|
|
26
|
+
import { findUsbEndpoints, getSerialNumber, isErrorName } from "./utils.js";
|
|
31
27
|
|
|
32
28
|
/**
|
|
33
29
|
* The default filter for ADB devices, as defined by Google.
|
|
34
30
|
*/
|
|
35
|
-
export const
|
|
31
|
+
export const AdbDefaultInterfaceFilter = {
|
|
36
32
|
classCode: 0xff,
|
|
37
33
|
subclassCode: 0x42,
|
|
38
34
|
protocolCode: 1,
|
|
39
|
-
} as const satisfies
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
switch (endpoint.direction) {
|
|
56
|
-
case "in":
|
|
57
|
-
inEndpoint = endpoint;
|
|
58
|
-
if (outEndpoint) {
|
|
59
|
-
return { inEndpoint, outEndpoint };
|
|
60
|
-
}
|
|
61
|
-
break;
|
|
62
|
-
case "out":
|
|
63
|
-
outEndpoint = endpoint;
|
|
64
|
-
if (inEndpoint) {
|
|
65
|
-
return { inEndpoint, outEndpoint };
|
|
66
|
-
}
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!inEndpoint) {
|
|
72
|
-
throw new Error("No input endpoint found.");
|
|
73
|
-
}
|
|
74
|
-
if (!outEndpoint) {
|
|
75
|
-
throw new Error("No output endpoint found.");
|
|
35
|
+
} as const satisfies UsbInterfaceFilter;
|
|
36
|
+
|
|
37
|
+
export function mergeDefaultAdbInterfaceFilter(
|
|
38
|
+
filters: USBDeviceFilter[] | undefined,
|
|
39
|
+
): (USBDeviceFilter & UsbInterfaceFilter)[] {
|
|
40
|
+
if (!filters || filters.length === 0) {
|
|
41
|
+
return [AdbDefaultInterfaceFilter];
|
|
42
|
+
} else {
|
|
43
|
+
return filters.map((filter) => ({
|
|
44
|
+
...filter,
|
|
45
|
+
classCode: filter.classCode ?? AdbDefaultInterfaceFilter.classCode,
|
|
46
|
+
subclassCode:
|
|
47
|
+
filter.subclassCode ?? AdbDefaultInterfaceFilter.subclassCode,
|
|
48
|
+
protocolCode:
|
|
49
|
+
filter.protocolCode ?? AdbDefaultInterfaceFilter.protocolCode,
|
|
50
|
+
}));
|
|
76
51
|
}
|
|
77
|
-
throw new Error("unreachable");
|
|
78
52
|
}
|
|
79
53
|
|
|
80
54
|
class Uint8ArrayExactReadable implements ExactReadable {
|
|
@@ -188,7 +162,7 @@ export class AdbDaemonWebUsbConnection
|
|
|
188
162
|
const zeroMask = outEndpoint.packetSize - 1;
|
|
189
163
|
this.#writable = pipeFrom(
|
|
190
164
|
duplex.createWritable(
|
|
191
|
-
new
|
|
165
|
+
new MaybeConsumable.WritableStream({
|
|
192
166
|
write: async (chunk) => {
|
|
193
167
|
try {
|
|
194
168
|
await device.raw.transferOut(
|
|
@@ -200,13 +174,10 @@ export class AdbDaemonWebUsbConnection
|
|
|
200
174
|
// If the payload size is a multiple of the packet size,
|
|
201
175
|
// we need to send an empty packet to indicate the end,
|
|
202
176
|
// so the OS will send it to the device immediately.
|
|
203
|
-
if (
|
|
204
|
-
zeroMask &&
|
|
205
|
-
(chunk.byteLength & zeroMask) === 0
|
|
206
|
-
) {
|
|
177
|
+
if (zeroMask && (chunk.length & zeroMask) === 0) {
|
|
207
178
|
await device.raw.transferOut(
|
|
208
179
|
outEndpoint.endpointNumber,
|
|
209
|
-
|
|
180
|
+
EmptyUint8Array,
|
|
210
181
|
);
|
|
211
182
|
}
|
|
212
183
|
} catch (e) {
|
|
@@ -255,7 +226,7 @@ export class AdbDaemonWebUsbConnection
|
|
|
255
226
|
);
|
|
256
227
|
packet.payload = new Uint8Array(result.data!.buffer);
|
|
257
228
|
} else {
|
|
258
|
-
packet.payload =
|
|
229
|
+
packet.payload = EmptyUint8Array;
|
|
259
230
|
}
|
|
260
231
|
|
|
261
232
|
return packet;
|
|
@@ -263,7 +234,7 @@ export class AdbDaemonWebUsbConnection
|
|
|
263
234
|
} catch (e) {
|
|
264
235
|
// On Windows, disconnecting the device will cause `NetworkError` to be thrown,
|
|
265
236
|
// even before the `disconnect` event is fired.
|
|
266
|
-
//
|
|
237
|
+
// Wait a little while and check if the device is still connected.
|
|
267
238
|
// https://github.com/WICG/webusb/issues/219
|
|
268
239
|
if (isErrorName(e, "NetworkError")) {
|
|
269
240
|
await new Promise<void>((resolve) => {
|
|
@@ -274,8 +245,6 @@ export class AdbDaemonWebUsbConnection
|
|
|
274
245
|
|
|
275
246
|
if (closed) {
|
|
276
247
|
return undefined;
|
|
277
|
-
} else {
|
|
278
|
-
throw e;
|
|
279
248
|
}
|
|
280
249
|
}
|
|
281
250
|
|
|
@@ -285,7 +254,7 @@ export class AdbDaemonWebUsbConnection
|
|
|
285
254
|
}
|
|
286
255
|
|
|
287
256
|
export class AdbDaemonWebUsbDevice implements AdbDaemonDevice {
|
|
288
|
-
#
|
|
257
|
+
#interface: UsbInterfaceIdentifier;
|
|
289
258
|
#usbManager: USB;
|
|
290
259
|
|
|
291
260
|
#raw: USBDevice;
|
|
@@ -310,22 +279,24 @@ export class AdbDaemonWebUsbDevice implements AdbDaemonDevice {
|
|
|
310
279
|
*/
|
|
311
280
|
constructor(
|
|
312
281
|
device: USBDevice,
|
|
313
|
-
|
|
282
|
+
interface_: UsbInterfaceIdentifier,
|
|
314
283
|
usbManager: USB,
|
|
315
284
|
) {
|
|
316
285
|
this.#raw = device;
|
|
317
286
|
this.#serial = getSerialNumber(device);
|
|
318
|
-
this.#
|
|
287
|
+
this.#interface = interface_;
|
|
319
288
|
this.#usbManager = usbManager;
|
|
320
289
|
}
|
|
321
290
|
|
|
322
|
-
async #claimInterface(): Promise<
|
|
291
|
+
async #claimInterface(): Promise<{
|
|
292
|
+
inEndpoint: USBEndpoint;
|
|
293
|
+
outEndpoint: USBEndpoint;
|
|
294
|
+
}> {
|
|
323
295
|
if (!this.#raw.opened) {
|
|
324
296
|
await this.#raw.open();
|
|
325
297
|
}
|
|
326
298
|
|
|
327
|
-
const { configuration, interface_, alternate } =
|
|
328
|
-
findUsbAlternateInterface(this.#raw, this.#filters);
|
|
299
|
+
const { configuration, interface_, alternate } = this.#interface;
|
|
329
300
|
|
|
330
301
|
if (
|
|
331
302
|
this.#raw.configuration?.configurationValue !==
|
|
@@ -339,7 +310,15 @@ export class AdbDaemonWebUsbDevice implements AdbDaemonDevice {
|
|
|
339
310
|
}
|
|
340
311
|
|
|
341
312
|
if (!interface_.claimed) {
|
|
342
|
-
|
|
313
|
+
try {
|
|
314
|
+
await this.#raw.claimInterface(interface_.interfaceNumber);
|
|
315
|
+
} catch (e) {
|
|
316
|
+
if (isErrorName(e, "NetworkError")) {
|
|
317
|
+
throw new AdbDaemonWebUsbDevice.DeviceBusyError(e);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
throw e;
|
|
321
|
+
}
|
|
343
322
|
}
|
|
344
323
|
|
|
345
324
|
if (
|
|
@@ -351,18 +330,14 @@ export class AdbDaemonWebUsbDevice implements AdbDaemonDevice {
|
|
|
351
330
|
);
|
|
352
331
|
}
|
|
353
332
|
|
|
354
|
-
|
|
355
|
-
alternate.endpoints,
|
|
356
|
-
);
|
|
357
|
-
return [inEndpoint, outEndpoint];
|
|
333
|
+
return findUsbEndpoints(alternate.endpoints);
|
|
358
334
|
}
|
|
359
335
|
|
|
360
336
|
/**
|
|
361
|
-
*
|
|
362
|
-
* @returns The pair of `AdbPacket` streams.
|
|
337
|
+
* Open the device and create a new connection to the ADB Daemon.
|
|
363
338
|
*/
|
|
364
339
|
async connect(): Promise<AdbDaemonWebUsbConnection> {
|
|
365
|
-
const
|
|
340
|
+
const { inEndpoint, outEndpoint } = await this.#claimInterface();
|
|
366
341
|
return new AdbDaemonWebUsbConnection(
|
|
367
342
|
this,
|
|
368
343
|
inEndpoint,
|
|
@@ -371,3 +346,13 @@ export class AdbDaemonWebUsbDevice implements AdbDaemonDevice {
|
|
|
371
346
|
);
|
|
372
347
|
}
|
|
373
348
|
}
|
|
349
|
+
|
|
350
|
+
export namespace AdbDaemonWebUsbDevice {
|
|
351
|
+
export class DeviceBusyError extends Error {
|
|
352
|
+
constructor(cause?: Error) {
|
|
353
|
+
super("The device is already in used by another program", {
|
|
354
|
+
cause,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
package/src/index.ts
CHANGED