@yume-chan/adb 0.0.10 → 0.0.13
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.json +50 -0
- package/CHANGELOG.md +29 -1
- package/LICENSE +1 -1
- package/README.md +71 -51
- package/esm/adb.d.ts +48 -0
- package/esm/adb.d.ts.map +1 -0
- package/esm/adb.js +149 -136
- package/esm/adb.js.map +1 -1
- package/{dts → esm}/auth.d.ts +11 -11
- package/esm/auth.d.ts.map +1 -0
- package/esm/auth.js +72 -110
- package/esm/auth.js.map +1 -1
- package/esm/backend.d.ts +9 -0
- package/esm/backend.d.ts.map +1 -0
- package/{dts → esm}/commands/base.d.ts +1 -1
- package/esm/commands/base.d.ts.map +1 -0
- package/esm/commands/base.js +1 -0
- package/esm/commands/base.js.map +1 -1
- package/{dts → esm}/commands/framebuffer.d.ts +3 -3
- package/esm/commands/framebuffer.d.ts.map +1 -0
- package/esm/commands/framebuffer.js +15 -18
- package/esm/commands/framebuffer.js.map +1 -1
- package/esm/commands/index.d.ts +9 -0
- package/esm/commands/index.d.ts.map +1 -0
- package/esm/commands/index.js +8 -8
- package/esm/commands/index.js.map +1 -1
- package/esm/commands/install.d.ts +4 -0
- package/esm/commands/install.d.ts.map +1 -0
- package/esm/commands/install.js +19 -13
- package/esm/commands/install.js.map +1 -1
- package/esm/commands/power.d.ts +23 -0
- package/esm/commands/power.d.ts.map +1 -0
- package/esm/commands/power.js +45 -0
- package/esm/commands/power.js.map +1 -0
- package/{dts → esm}/commands/reverse.d.ts +3 -3
- package/esm/commands/reverse.d.ts.map +1 -0
- package/esm/commands/reverse.js +49 -60
- package/esm/commands/reverse.js.map +1 -1
- package/esm/commands/subprocess/index.d.ts +56 -0
- package/esm/commands/subprocess/index.d.ts.map +1 -0
- package/esm/commands/subprocess/index.js +88 -0
- package/esm/commands/subprocess/index.js.map +1 -0
- package/esm/commands/subprocess/legacy.d.ts +35 -0
- package/esm/commands/subprocess/legacy.d.ts.map +1 -0
- package/esm/commands/subprocess/legacy.js +53 -0
- package/esm/commands/subprocess/legacy.js.map +1 -0
- package/esm/commands/subprocess/protocol.d.ts +39 -0
- package/esm/commands/subprocess/protocol.d.ts.map +1 -0
- package/esm/commands/subprocess/protocol.js +157 -0
- package/esm/commands/subprocess/protocol.js.map +1 -0
- package/esm/commands/subprocess/protocols/index.d.ts +4 -0
- package/esm/commands/subprocess/protocols/index.d.ts.map +1 -0
- package/esm/commands/subprocess/protocols/index.js +4 -0
- package/esm/commands/subprocess/protocols/index.js.map +1 -0
- package/esm/commands/subprocess/protocols/none.d.ts +35 -0
- package/esm/commands/subprocess/protocols/none.d.ts.map +1 -0
- package/esm/commands/subprocess/protocols/none.js +53 -0
- package/esm/commands/subprocess/protocols/none.js.map +1 -0
- package/esm/commands/subprocess/protocols/shell.d.ts +39 -0
- package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -0
- package/esm/commands/subprocess/protocols/shell.js +155 -0
- package/esm/commands/subprocess/protocols/shell.js.map +1 -0
- package/esm/commands/subprocess/protocols/types.d.ts +50 -0
- package/esm/commands/subprocess/protocols/types.d.ts.map +1 -0
- package/esm/commands/{shell → subprocess/protocols}/types.js +0 -0
- package/esm/commands/subprocess/protocols/types.js.map +1 -0
- package/esm/commands/subprocess/types.d.ts +50 -0
- package/esm/commands/subprocess/types.d.ts.map +1 -0
- package/esm/commands/subprocess/types.js +2 -0
- package/esm/commands/{shell → subprocess}/types.js.map +1 -1
- package/{dts/commands/shell → esm/commands/subprocess}/utils.d.ts +0 -0
- package/esm/commands/subprocess/utils.d.ts.map +1 -0
- package/esm/commands/{shell → subprocess}/utils.js +0 -0
- package/esm/commands/subprocess/utils.js.map +1 -0
- package/esm/commands/sync/index.d.ts +8 -0
- package/esm/commands/sync/index.d.ts.map +1 -0
- package/esm/commands/sync/index.js +7 -7
- package/esm/commands/sync/index.js.map +1 -1
- package/esm/commands/sync/list.d.ts +41 -0
- package/esm/commands/sync/list.d.ts.map +1 -0
- package/esm/commands/sync/list.js +52 -20
- package/esm/commands/sync/list.js.map +1 -1
- package/esm/commands/sync/pull.d.ts +11 -0
- package/esm/commands/sync/pull.d.ts.map +1 -0
- package/esm/commands/sync/pull.js +17 -11
- package/esm/commands/sync/pull.js.map +1 -1
- package/esm/commands/sync/push.d.ts +8 -0
- package/esm/commands/sync/push.d.ts.map +1 -0
- package/esm/commands/sync/push.js +19 -37
- package/esm/commands/sync/push.js.map +1 -1
- package/{dts → esm}/commands/sync/request.d.ts +4 -3
- package/esm/commands/sync/request.d.ts.map +1 -0
- package/esm/commands/sync/request.js +25 -27
- package/esm/commands/sync/request.js.map +1 -1
- package/{dts → esm}/commands/sync/response.d.ts +4 -3
- package/esm/commands/sync/response.d.ts.map +1 -0
- package/esm/commands/sync/response.js +17 -20
- package/esm/commands/sync/response.js.map +1 -1
- package/{dts → esm}/commands/sync/stat.d.ts +16 -4
- package/esm/commands/sync/stat.d.ts.map +1 -0
- package/esm/commands/sync/stat.js +38 -30
- package/esm/commands/sync/stat.js.map +1 -1
- package/esm/commands/sync/sync.d.ts +61 -0
- package/esm/commands/sync/sync.d.ts.map +1 -0
- package/esm/commands/sync/sync.js +122 -89
- package/esm/commands/sync/sync.js.map +1 -1
- package/{dts → esm}/commands/tcpip.d.ts +1 -1
- package/{dts → esm}/commands/tcpip.d.ts.map +1 -1
- package/esm/commands/tcpip.js +14 -19
- package/esm/commands/tcpip.js.map +1 -1
- package/esm/crypto.d.ts +37 -0
- package/esm/crypto.d.ts.map +1 -0
- package/esm/crypto.js +77 -62
- package/esm/crypto.js.map +1 -1
- package/esm/features.d.ts +8 -0
- package/esm/features.d.ts.map +1 -0
- package/esm/features.js +7 -3
- package/esm/features.js.map +1 -1
- package/esm/index.d.ts +11 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +10 -10
- package/esm/index.js.map +1 -1
- package/esm/packet.d.ts +47 -0
- package/esm/packet.d.ts.map +1 -0
- package/esm/packet.js +27 -52
- package/esm/packet.js.map +1 -1
- package/esm/socket/controller.d.ts +37 -0
- package/esm/socket/controller.d.ts.map +1 -0
- package/esm/socket/controller.js +52 -66
- package/esm/socket/controller.js.map +1 -1
- package/esm/socket/dispatcher.d.ts +44 -0
- package/esm/socket/dispatcher.d.ts.map +1 -0
- package/esm/socket/dispatcher.js +146 -165
- package/esm/socket/dispatcher.js.map +1 -1
- package/esm/socket/index.d.ts +3 -0
- package/esm/socket/index.d.ts.map +1 -0
- package/esm/socket/index.js +2 -6
- package/esm/socket/index.js.map +1 -1
- package/esm/socket/socket.d.ts +46 -0
- package/esm/socket/socket.d.ts.map +1 -0
- package/esm/socket/socket.js +77 -13
- package/esm/socket/socket.js.map +1 -1
- package/esm/stream/buffered.d.ts +35 -0
- package/esm/stream/buffered.d.ts.map +1 -0
- package/esm/stream/buffered.js +123 -0
- package/esm/stream/buffered.js.map +1 -0
- package/esm/stream/detect.bak.d.ts +240 -0
- package/esm/stream/detect.bak.d.ts.map +1 -0
- package/esm/stream/detect.bak.js +60 -0
- package/esm/stream/detect.bak.js.map +1 -0
- package/esm/stream/detect.d.ts +2 -0
- package/esm/stream/detect.d.ts.map +1 -0
- package/esm/stream/detect.js +5 -0
- package/esm/stream/detect.js.map +1 -0
- package/esm/stream/detect.native.d.ts +240 -0
- package/esm/stream/detect.native.d.ts.map +1 -0
- package/esm/stream/detect.native.js +60 -0
- package/esm/stream/detect.native.js.map +1 -0
- package/esm/stream/detect.polyfill.d.ts +18 -0
- package/esm/stream/detect.polyfill.d.ts.map +1 -0
- package/esm/stream/detect.polyfill.js +9 -0
- package/esm/stream/detect.polyfill.js.map +1 -0
- package/esm/stream/index.d.ts +4 -0
- package/esm/stream/index.d.ts.map +1 -0
- package/esm/stream/index.js +3 -2
- package/esm/stream/index.js.map +1 -1
- package/esm/stream/transform.d.ts +98 -0
- package/esm/stream/transform.d.ts.map +1 -0
- package/esm/stream/transform.js +402 -0
- package/esm/stream/transform.js.map +1 -0
- package/{dts → esm}/utils/auto-reset-event.d.ts +1 -1
- package/esm/utils/auto-reset-event.d.ts.map +1 -0
- package/esm/utils/auto-reset-event.js +2 -1
- package/esm/utils/auto-reset-event.js.map +1 -1
- package/esm/utils/base64.d.ts +5 -0
- package/esm/utils/base64.d.ts.map +1 -0
- package/esm/utils/base64.js +116 -80
- package/esm/utils/base64.js.map +1 -1
- package/esm/utils/encoding.d.ts +3 -0
- package/esm/utils/encoding.d.ts.map +1 -0
- package/esm/utils/encoding.js +1 -1
- package/esm/utils/encoding.js.map +1 -1
- package/esm/utils/index.d.ts +4 -0
- package/esm/utils/index.d.ts.map +1 -0
- package/esm/utils/index.js +3 -5
- package/esm/utils/index.js.map +1 -1
- package/package.json +50 -44
- package/src/adb.ts +177 -150
- package/src/auth.ts +37 -30
- package/src/backend.ts +3 -12
- package/src/commands/base.ts +1 -1
- package/src/commands/framebuffer.ts +4 -4
- package/src/commands/index.ts +8 -8
- package/src/commands/install.ts +24 -15
- package/src/commands/power.ts +54 -0
- package/src/commands/reverse.ts +10 -8
- package/src/commands/subprocess/index.ts +139 -0
- package/src/commands/subprocess/protocols/index.ts +3 -0
- package/src/commands/subprocess/protocols/none.ts +68 -0
- package/src/commands/subprocess/protocols/shell.ts +190 -0
- package/src/commands/subprocess/protocols/types.ts +59 -0
- package/src/commands/{shell → subprocess}/utils.ts +0 -0
- package/src/commands/sync/index.ts +7 -7
- package/src/commands/sync/list.ts +56 -9
- package/src/commands/sync/pull.ts +27 -18
- package/src/commands/sync/push.ts +25 -30
- package/src/commands/sync/request.ts +8 -7
- package/src/commands/sync/response.ts +12 -6
- package/src/commands/sync/stat.ts +43 -14
- package/src/commands/sync/sync.ts +102 -34
- package/src/commands/tcpip.ts +3 -3
- package/src/crypto.ts +95 -84
- package/src/features.ts +6 -2
- package/src/index.ts +11 -10
- package/src/packet.ts +49 -53
- package/src/socket/dispatcher.ts +110 -109
- package/src/socket/index.ts +2 -6
- package/src/socket/socket.ts +125 -17
- package/src/stream/buffered.ts +147 -0
- package/src/stream/detect.native.ts +362 -0
- package/src/stream/detect.polyfill.ts +28 -0
- package/src/stream/detect.ts +5 -0
- package/src/stream/index.ts +3 -2
- package/src/stream/transform.ts +483 -0
- package/src/utils/auto-reset-event.ts +1 -1
- package/src/utils/base64.ts +161 -129
- package/src/utils/index.ts +3 -5
- package/tsconfig.build.json +3 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.test.json +10 -0
- package/dts/adb.d.ts +0 -46
- package/dts/adb.d.ts.map +0 -1
- package/dts/auth.d.ts.map +0 -1
- package/dts/backend.d.ts +0 -13
- package/dts/backend.d.ts.map +0 -1
- package/dts/commands/base.d.ts.map +0 -1
- package/dts/commands/demo-mode.d.ts +0 -41
- package/dts/commands/demo-mode.d.ts.map +0 -1
- package/dts/commands/framebuffer.d.ts.map +0 -1
- package/dts/commands/index.d.ts +0 -9
- package/dts/commands/index.d.ts.map +0 -1
- package/dts/commands/install.d.ts +0 -3
- package/dts/commands/install.d.ts.map +0 -1
- package/dts/commands/reverse.d.ts.map +0 -1
- package/dts/commands/shell/index.d.ts +0 -46
- package/dts/commands/shell/index.d.ts.map +0 -1
- package/dts/commands/shell/legacy.d.ts +0 -38
- package/dts/commands/shell/legacy.d.ts.map +0 -1
- package/dts/commands/shell/protocol.d.ts +0 -45
- package/dts/commands/shell/protocol.d.ts.map +0 -1
- package/dts/commands/shell/types.d.ts +0 -47
- package/dts/commands/shell/types.d.ts.map +0 -1
- package/dts/commands/shell/utils.d.ts.map +0 -1
- package/dts/commands/sync/index.d.ts +0 -8
- package/dts/commands/sync/index.d.ts.map +0 -1
- package/dts/commands/sync/list.d.ts +0 -17
- package/dts/commands/sync/list.d.ts.map +0 -1
- package/dts/commands/sync/pull.d.ts +0 -11
- package/dts/commands/sync/pull.d.ts.map +0 -1
- package/dts/commands/sync/push.d.ts +0 -8
- package/dts/commands/sync/push.d.ts.map +0 -1
- package/dts/commands/sync/request.d.ts.map +0 -1
- package/dts/commands/sync/response.d.ts.map +0 -1
- package/dts/commands/sync/stat.d.ts.map +0 -1
- package/dts/commands/sync/sync.d.ts +0 -68
- package/dts/commands/sync/sync.d.ts.map +0 -1
- package/dts/crypto.d.ts +0 -24
- package/dts/crypto.d.ts.map +0 -1
- package/dts/features.d.ts +0 -6
- package/dts/features.d.ts.map +0 -1
- package/dts/index.d.ts +0 -11
- package/dts/index.d.ts.map +0 -1
- package/dts/packet.d.ts +0 -27
- package/dts/packet.d.ts.map +0 -1
- package/dts/socket/close-event-emitter.d.ts +0 -8
- package/dts/socket/close-event-emitter.d.ts.map +0 -1
- package/dts/socket/controller.d.ts +0 -43
- package/dts/socket/controller.d.ts.map +0 -1
- package/dts/socket/data-event-emitter.d.ts +0 -10
- package/dts/socket/data-event-emitter.d.ts.map +0 -1
- package/dts/socket/dispatcher.d.ts +0 -53
- package/dts/socket/dispatcher.d.ts.map +0 -1
- package/dts/socket/index.d.ts +0 -7
- package/dts/socket/index.d.ts.map +0 -1
- package/dts/socket/logger.d.ts +0 -9
- package/dts/socket/logger.d.ts.map +0 -1
- package/dts/socket/socket.d.ts +0 -22
- package/dts/socket/socket.d.ts.map +0 -1
- package/dts/stream/buffered-stream.d.ts +0 -28
- package/dts/stream/buffered-stream.d.ts.map +0 -1
- package/dts/stream/index.d.ts +0 -3
- package/dts/stream/index.d.ts.map +0 -1
- package/dts/stream/stream.d.ts +0 -15
- package/dts/stream/stream.d.ts.map +0 -1
- package/dts/utils/auto-reset-event.d.ts.map +0 -1
- package/dts/utils/base64.d.ts +0 -7
- package/dts/utils/base64.d.ts.map +0 -1
- package/dts/utils/chunk.d.ts +0 -3
- package/dts/utils/chunk.d.ts.map +0 -1
- package/dts/utils/encoding.d.ts +0 -3
- package/dts/utils/encoding.d.ts.map +0 -1
- package/dts/utils/event-queue.d.ts +0 -35
- package/dts/utils/event-queue.d.ts.map +0 -1
- package/dts/utils/index.d.ts +0 -6
- package/dts/utils/index.d.ts.map +0 -1
- package/esm/commands/demo-mode.js +0 -170
- package/esm/commands/demo-mode.js.map +0 -1
- package/esm/commands/shell/index.js +0 -62
- package/esm/commands/shell/index.js.map +0 -1
- package/esm/commands/shell/legacy.js +0 -49
- package/esm/commands/shell/legacy.js.map +0 -1
- package/esm/commands/shell/protocol.js +0 -106
- package/esm/commands/shell/protocol.js.map +0 -1
- package/esm/commands/shell/utils.js.map +0 -1
- package/esm/socket/close-event-emitter.js +0 -28
- package/esm/socket/close-event-emitter.js.map +0 -1
- package/esm/socket/data-event-emitter.js +0 -25
- package/esm/socket/data-event-emitter.js.map +0 -1
- package/esm/socket/logger.js +0 -2
- package/esm/socket/logger.js.map +0 -1
- package/esm/stream/buffered-stream.js +0 -67
- package/esm/stream/buffered-stream.js.map +0 -1
- package/esm/stream/stream.js +0 -41
- package/esm/stream/stream.js.map +0 -1
- package/esm/utils/chunk.js +0 -70
- package/esm/utils/chunk.js.map +0 -1
- package/esm/utils/event-queue.js +0 -104
- package/esm/utils/event-queue.js.map +0 -1
- package/src/commands/demo-mode.ts +0 -160
- package/src/commands/shell/index.ts +0 -87
- package/src/commands/shell/legacy.ts +0 -59
- package/src/commands/shell/protocol.ts +0 -121
- package/src/commands/shell/types.ts +0 -55
- package/src/socket/close-event-emitter.ts +0 -28
- package/src/socket/controller.ts +0 -105
- package/src/socket/data-event-emitter.ts +0 -27
- package/src/socket/logger.ts +0 -12
- package/src/stream/buffered-stream.ts +0 -92
- package/src/stream/stream.ts +0 -50
- package/src/utils/chunk.ts +0 -70
- package/src/utils/encoding.ts +0 -13
- package/src/utils/event-queue.ts +0 -145
package/src/socket/dispatcher.ts
CHANGED
|
@@ -1,111 +1,105 @@
|
|
|
1
|
-
import { AsyncOperationManager } from '@yume-chan/async';
|
|
1
|
+
import { AsyncOperationManager, PromiseResolver } from '@yume-chan/async';
|
|
2
2
|
import { AutoDisposable, EventEmitter } from '@yume-chan/event';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { AdbSocketController } from './
|
|
7
|
-
import { AdbLogger } from './logger';
|
|
8
|
-
import { AdbSocket } from './socket';
|
|
9
|
-
|
|
10
|
-
export interface AdbPacketReceivedEventArgs {
|
|
11
|
-
handled: boolean;
|
|
12
|
-
|
|
13
|
-
packet: AdbPacket;
|
|
14
|
-
}
|
|
3
|
+
import { AdbCommand, calculateChecksum, type AdbPacketData, type AdbPacketInit } from '../packet.js';
|
|
4
|
+
import { AbortController, WritableStream, WritableStreamDefaultWriter, type ReadableWritablePair } from '../stream/index.js';
|
|
5
|
+
import { decodeUtf8, encodeUtf8 } from '../utils/index.js';
|
|
6
|
+
import { AdbSocket, AdbSocketController } from './socket.js';
|
|
15
7
|
|
|
16
8
|
export interface AdbIncomingSocketEventArgs {
|
|
17
9
|
handled: boolean;
|
|
18
10
|
|
|
19
|
-
packet:
|
|
11
|
+
packet: AdbPacketData;
|
|
20
12
|
|
|
21
13
|
serviceString: string;
|
|
22
14
|
|
|
23
15
|
socket: AdbSocket;
|
|
24
16
|
}
|
|
25
17
|
|
|
26
|
-
const
|
|
18
|
+
const EmptyUint8Array = new Uint8Array(0);
|
|
19
|
+
|
|
20
|
+
export interface AdbPacketDispatcherOptions {
|
|
21
|
+
calculateChecksum: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Before Android 9.0, ADB uses `char*` to parse service string,
|
|
24
|
+
* thus requires a null character to terminate.
|
|
25
|
+
*
|
|
26
|
+
* Usually it should have the same value as `calculateChecksum`.
|
|
27
|
+
*/
|
|
28
|
+
appendNullToServiceString: boolean;
|
|
29
|
+
maxPayloadSize: number;
|
|
30
|
+
}
|
|
27
31
|
|
|
28
32
|
export class AdbPacketDispatcher extends AutoDisposable {
|
|
29
33
|
// ADB socket id starts from 1
|
|
30
34
|
// (0 means open failed)
|
|
31
35
|
private readonly initializers = new AsyncOperationManager(1);
|
|
32
36
|
private readonly sockets = new Map<number, AdbSocketController>();
|
|
33
|
-
private readonly sendLock = new AutoResetEvent();
|
|
34
|
-
private readonly logger: AdbLogger | undefined;
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
private _writer!: WritableStreamDefaultWriter<AdbPacketInit>;
|
|
37
39
|
|
|
38
|
-
public
|
|
39
|
-
public calculateChecksum = true;
|
|
40
|
-
public appendNullToServiceString = true;
|
|
40
|
+
public readonly options: AdbPacketDispatcherOptions;
|
|
41
41
|
|
|
42
|
-
private
|
|
43
|
-
public get
|
|
42
|
+
private _disconnected = new PromiseResolver<void>();
|
|
43
|
+
public get disconnected() { return this._disconnected.promise; }
|
|
44
44
|
|
|
45
45
|
private readonly incomingSocketEvent = this.addDisposable(new EventEmitter<AdbIncomingSocketEventArgs>());
|
|
46
46
|
public get onIncomingSocket() { return this.incomingSocketEvent.event; }
|
|
47
47
|
|
|
48
|
-
private
|
|
49
|
-
public get onError() { return this.errorEvent.event; }
|
|
48
|
+
private _abortController = new AbortController();
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
public constructor(
|
|
51
|
+
connection: ReadableWritablePair<AdbPacketData, AdbPacketInit>,
|
|
52
|
+
options: AdbPacketDispatcherOptions
|
|
53
|
+
) {
|
|
55
54
|
super();
|
|
56
55
|
|
|
57
|
-
this.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
56
|
+
this.options = options;
|
|
57
|
+
|
|
58
|
+
connection.readable
|
|
59
|
+
.pipeTo(new WritableStream({
|
|
60
|
+
write: async (packet) => {
|
|
61
|
+
try {
|
|
62
|
+
switch (packet.command) {
|
|
63
|
+
case AdbCommand.OK:
|
|
64
|
+
this.handleOk(packet);
|
|
65
|
+
return;
|
|
66
|
+
case AdbCommand.Close:
|
|
67
|
+
await this.handleClose(packet);
|
|
68
|
+
return;
|
|
69
|
+
case AdbCommand.Write:
|
|
70
|
+
if (this.sockets.has(packet.arg1)) {
|
|
71
|
+
await this.sockets.get(packet.arg1)!.enqueue(packet.payload);
|
|
72
|
+
await this.sendPacket(AdbCommand.OK, packet.arg1, packet.arg0);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Maybe the device is responding to a packet of last connection
|
|
76
|
+
// Just ignore it
|
|
77
|
+
return;
|
|
78
|
+
case AdbCommand.Open:
|
|
79
|
+
await this.handleOpen(packet);
|
|
80
|
+
return;
|
|
78
81
|
}
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
this.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
} catch (e) {
|
|
99
|
-
if (!this._running) {
|
|
100
|
-
// ignore error
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
this.errorEvent.fire(e as Error);
|
|
105
|
-
}
|
|
82
|
+
} catch (e) {
|
|
83
|
+
// Throw error here will stop the pipe
|
|
84
|
+
// But won't close `readable` because of `preventCancel: true`
|
|
85
|
+
throw e;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
}), {
|
|
89
|
+
preventCancel: false,
|
|
90
|
+
signal: this._abortController.signal,
|
|
91
|
+
})
|
|
92
|
+
.then(() => {
|
|
93
|
+
this.dispose();
|
|
94
|
+
}, (e) => {
|
|
95
|
+
this._disconnected.reject(e);
|
|
96
|
+
this.dispose();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
this._writer = connection.writable.getWriter();
|
|
106
100
|
}
|
|
107
101
|
|
|
108
|
-
private handleOk(packet:
|
|
102
|
+
private handleOk(packet: AdbPacketData) {
|
|
109
103
|
if (this.initializers.resolve(packet.arg1, packet.arg0)) {
|
|
110
104
|
// Device successfully created the socket
|
|
111
105
|
return;
|
|
@@ -123,7 +117,7 @@ export class AdbPacketDispatcher extends AutoDisposable {
|
|
|
123
117
|
this.sendPacket(AdbCommand.Close, packet.arg1, packet.arg0);
|
|
124
118
|
}
|
|
125
119
|
|
|
126
|
-
private async handleClose(packet:
|
|
120
|
+
private async handleClose(packet: AdbPacketData) {
|
|
127
121
|
// From https://android.googlesource.com/platform/packages/modules/adb/+/65d18e2c1cc48b585811954892311b28a4c3d188/adb.cpp#459
|
|
128
122
|
/* According to protocol.txt, p->msg.arg0 might be 0 to indicate
|
|
129
123
|
* a failed OPEN only. However, due to a bug in previous ADB
|
|
@@ -153,14 +147,14 @@ export class AdbPacketDispatcher extends AutoDisposable {
|
|
|
153
147
|
// Just ignore it
|
|
154
148
|
}
|
|
155
149
|
|
|
156
|
-
private async handleOpen(packet:
|
|
150
|
+
private async handleOpen(packet: AdbPacketData) {
|
|
157
151
|
// AsyncOperationManager doesn't support get and skip an ID
|
|
158
152
|
// Use `add` + `resolve` to simulate this behavior
|
|
159
153
|
const [localId] = this.initializers.add<number>();
|
|
160
154
|
this.initializers.resolve(localId, undefined);
|
|
161
155
|
|
|
162
156
|
const remoteId = packet.arg0;
|
|
163
|
-
const serviceString = decodeUtf8(packet.payload
|
|
157
|
+
const serviceString = decodeUtf8(packet.payload);
|
|
164
158
|
|
|
165
159
|
const controller = new AdbSocketController({
|
|
166
160
|
dispatcher: this,
|
|
@@ -169,13 +163,12 @@ export class AdbPacketDispatcher extends AutoDisposable {
|
|
|
169
163
|
localCreated: false,
|
|
170
164
|
serviceString,
|
|
171
165
|
});
|
|
172
|
-
const socket = new AdbSocket(controller);
|
|
173
166
|
|
|
174
167
|
const args: AdbIncomingSocketEventArgs = {
|
|
175
168
|
handled: false,
|
|
176
169
|
packet,
|
|
177
170
|
serviceString,
|
|
178
|
-
socket,
|
|
171
|
+
socket: controller.socket,
|
|
179
172
|
};
|
|
180
173
|
this.incomingSocketEvent.fire(args);
|
|
181
174
|
|
|
@@ -187,19 +180,20 @@ export class AdbPacketDispatcher extends AutoDisposable {
|
|
|
187
180
|
}
|
|
188
181
|
}
|
|
189
182
|
|
|
190
|
-
public start() {
|
|
191
|
-
this._running = true;
|
|
192
|
-
this.receiveLoop();
|
|
193
|
-
}
|
|
194
|
-
|
|
195
183
|
public async createSocket(serviceString: string): Promise<AdbSocket> {
|
|
196
|
-
if (this.appendNullToServiceString) {
|
|
184
|
+
if (this.options.appendNullToServiceString) {
|
|
197
185
|
serviceString += '\0';
|
|
198
186
|
}
|
|
199
187
|
|
|
200
188
|
const [localId, initializer] = this.initializers.add<number>();
|
|
201
|
-
await this.sendPacket(
|
|
189
|
+
await this.sendPacket(
|
|
190
|
+
AdbCommand.Open,
|
|
191
|
+
localId,
|
|
192
|
+
0,
|
|
193
|
+
serviceString
|
|
194
|
+
);
|
|
202
195
|
|
|
196
|
+
// Fulfilled by `handleOk`
|
|
203
197
|
const remoteId = await initializer;
|
|
204
198
|
const controller = new AdbSocketController({
|
|
205
199
|
dispatcher: this,
|
|
@@ -208,9 +202,9 @@ export class AdbPacketDispatcher extends AutoDisposable {
|
|
|
208
202
|
localCreated: true,
|
|
209
203
|
serviceString,
|
|
210
204
|
});
|
|
211
|
-
this.sockets.set(
|
|
205
|
+
this.sockets.set(localId, controller);
|
|
212
206
|
|
|
213
|
-
return
|
|
207
|
+
return controller.socket;
|
|
214
208
|
}
|
|
215
209
|
|
|
216
210
|
public sendPacket(packet: AdbPacketInit): Promise<void>;
|
|
@@ -218,52 +212,59 @@ export class AdbPacketDispatcher extends AutoDisposable {
|
|
|
218
212
|
command: AdbCommand,
|
|
219
213
|
arg0: number,
|
|
220
214
|
arg1: number,
|
|
221
|
-
payload?: string |
|
|
215
|
+
payload?: string | Uint8Array
|
|
222
216
|
): Promise<void>;
|
|
223
217
|
public async sendPacket(
|
|
224
218
|
packetOrCommand: AdbPacketInit | AdbCommand,
|
|
225
219
|
arg0?: number,
|
|
226
220
|
arg1?: number,
|
|
227
|
-
payload: string |
|
|
221
|
+
payload: string | Uint8Array = EmptyUint8Array,
|
|
228
222
|
): Promise<void> {
|
|
229
|
-
let init:
|
|
223
|
+
let init: AdbPacketData;
|
|
230
224
|
if (arg0 === undefined) {
|
|
231
225
|
init = packetOrCommand as AdbPacketInit;
|
|
232
226
|
} else {
|
|
227
|
+
if (typeof payload === 'string') {
|
|
228
|
+
payload = encodeUtf8(payload);
|
|
229
|
+
}
|
|
230
|
+
|
|
233
231
|
init = {
|
|
234
232
|
command: packetOrCommand as AdbCommand,
|
|
235
233
|
arg0: arg0 as number,
|
|
236
234
|
arg1: arg1 as number,
|
|
237
|
-
payload
|
|
235
|
+
payload,
|
|
238
236
|
};
|
|
239
237
|
}
|
|
240
238
|
|
|
241
239
|
if (init.payload &&
|
|
242
|
-
init.payload.byteLength > this.maxPayloadSize) {
|
|
240
|
+
init.payload.byteLength > this.options.maxPayloadSize) {
|
|
243
241
|
throw new Error('payload too large');
|
|
244
242
|
}
|
|
245
243
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
this.logger?.onOutgoingPacket?.(init);
|
|
252
|
-
|
|
253
|
-
await AdbPacket.write(init, this.calculateChecksum, this.backend);
|
|
254
|
-
} finally {
|
|
255
|
-
this.sendLock.notify();
|
|
244
|
+
if (this.options.calculateChecksum) {
|
|
245
|
+
calculateChecksum(init);
|
|
246
|
+
} else {
|
|
247
|
+
(init as AdbPacketInit).checksum = 0;
|
|
256
248
|
}
|
|
249
|
+
|
|
250
|
+
await this._writer.write(init as AdbPacketInit);
|
|
257
251
|
}
|
|
258
252
|
|
|
259
253
|
public override dispose() {
|
|
260
|
-
this._running = false;
|
|
261
|
-
|
|
262
254
|
for (const socket of this.sockets.values()) {
|
|
263
255
|
socket.dispose();
|
|
264
256
|
}
|
|
265
257
|
this.sockets.clear();
|
|
266
258
|
|
|
259
|
+
try {
|
|
260
|
+
// Stop pipes
|
|
261
|
+
this._abortController.abort();
|
|
262
|
+
} catch { }
|
|
263
|
+
|
|
264
|
+
this._writer.releaseLock();
|
|
265
|
+
|
|
266
|
+
this._disconnected.resolve();
|
|
267
|
+
|
|
267
268
|
super.dispose();
|
|
268
269
|
}
|
|
269
270
|
}
|
package/src/socket/index.ts
CHANGED
package/src/socket/socket.ts
CHANGED
|
@@ -1,28 +1,136 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PromiseResolver } from "@yume-chan/async";
|
|
2
|
+
import { AdbCommand } from '../packet.js';
|
|
3
|
+
import { ChunkStream, DuplexStreamFactory, pipeFrom, type PushReadableStreamController, type ReadableStream, type ReadableWritablePair, type WritableStream } from '../stream/index.js';
|
|
4
|
+
import type { AdbPacketDispatcher } from './dispatcher.js';
|
|
2
5
|
|
|
3
|
-
export
|
|
4
|
-
|
|
6
|
+
export interface AdbSocketInfo {
|
|
7
|
+
localId: number;
|
|
8
|
+
remoteId: number;
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
localCreated: boolean;
|
|
11
|
+
serviceString: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface AdbSocketConstructionOptions extends AdbSocketInfo {
|
|
15
|
+
dispatcher: AdbPacketDispatcher;
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
highWaterMark?: number | undefined;
|
|
18
|
+
}
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
export class AdbSocketController implements AdbSocketInfo, ReadableWritablePair<Uint8Array, Uint8Array> {
|
|
21
|
+
private readonly dispatcher!: AdbPacketDispatcher;
|
|
16
22
|
|
|
17
|
-
public
|
|
18
|
-
|
|
23
|
+
public readonly localId!: number;
|
|
24
|
+
public readonly remoteId!: number;
|
|
25
|
+
public readonly localCreated!: boolean;
|
|
26
|
+
public readonly serviceString!: string;
|
|
27
|
+
|
|
28
|
+
private _factory: DuplexStreamFactory<Uint8Array, Uint8Array>;
|
|
29
|
+
|
|
30
|
+
private _readable: ReadableStream<Uint8Array>;
|
|
31
|
+
private _readableController!: PushReadableStreamController<Uint8Array>;
|
|
32
|
+
public get readable() { return this._readable; }
|
|
33
|
+
|
|
34
|
+
private _writePromise: PromiseResolver<void> | undefined;
|
|
35
|
+
public readonly writable: WritableStream<Uint8Array>;
|
|
36
|
+
|
|
37
|
+
private _closed = false;
|
|
38
|
+
public get closed() { return this._closed; }
|
|
39
|
+
|
|
40
|
+
private _socket: AdbSocket;
|
|
41
|
+
public get socket() { return this._socket; }
|
|
42
|
+
|
|
43
|
+
public constructor(options: AdbSocketConstructionOptions) {
|
|
44
|
+
Object.assign(this, options);
|
|
45
|
+
|
|
46
|
+
// Check this image to help you understand the stream graph
|
|
47
|
+
// cspell: disable-next-line
|
|
48
|
+
// https://www.plantuml.com/plantuml/png/TL0zoeGm4ErpYc3l5JxyS0yWM6mX5j4C6p4cxcJ25ejttuGX88ZftizxUKmJI275pGhXl0PP_UkfK_CAz5Z2hcWsW9Ny2fdU4C1f5aSchFVxA8vJjlTPRhqZzDQMRB7AklwJ0xXtX0ZSKH1h24ghoKAdGY23FhxC4nS2pDvxzIvxb-8THU0XlEQJ-ZB7SnXTAvc_LhOckhMdLBnbtndpb-SB7a8q2SRD_W00
|
|
49
|
+
|
|
50
|
+
this._factory = new DuplexStreamFactory<Uint8Array, Uint8Array>({
|
|
51
|
+
close: async () => {
|
|
52
|
+
await this.close();
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
this._readable = this._factory.createPushReadable(controller => {
|
|
57
|
+
this._readableController = controller;
|
|
58
|
+
}, {
|
|
59
|
+
highWaterMark: options.highWaterMark ?? 16 * 1024,
|
|
60
|
+
size(chunk) { return chunk.byteLength; }
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
this.writable = pipeFrom(
|
|
64
|
+
this._factory.createWritable({
|
|
65
|
+
write: async (chunk) => {
|
|
66
|
+
// Wait for an ack packet
|
|
67
|
+
this._writePromise = new PromiseResolver();
|
|
68
|
+
await this.dispatcher.sendPacket(
|
|
69
|
+
AdbCommand.Write,
|
|
70
|
+
this.localId,
|
|
71
|
+
this.remoteId,
|
|
72
|
+
chunk
|
|
73
|
+
);
|
|
74
|
+
await this._writePromise.promise;
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
new ChunkStream(this.dispatcher.options.maxPayloadSize)
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
this._socket = new AdbSocket(this);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public async enqueue(packet: Uint8Array) {
|
|
84
|
+
await this._readableController.enqueue(packet);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public ack() {
|
|
88
|
+
this._writePromise?.resolve();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public async close(): Promise<void> {
|
|
92
|
+
// Error out the pending writes
|
|
93
|
+
this._writePromise?.reject(new Error('Socket closed'));
|
|
94
|
+
|
|
95
|
+
if (!this._closed) {
|
|
96
|
+
this._closed = true;
|
|
97
|
+
|
|
98
|
+
// Only send close packet when `close` is called before `dispose`
|
|
99
|
+
// (the client initiated the close)
|
|
100
|
+
await this.dispatcher.sendPacket(
|
|
101
|
+
AdbCommand.Close,
|
|
102
|
+
this.localId,
|
|
103
|
+
this.remoteId
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public dispose() {
|
|
109
|
+
this._closed = true;
|
|
110
|
+
|
|
111
|
+
this._factory.close();
|
|
112
|
+
|
|
113
|
+
// Close `writable` side
|
|
114
|
+
this.close();
|
|
19
115
|
}
|
|
116
|
+
}
|
|
20
117
|
|
|
21
|
-
|
|
22
|
-
|
|
118
|
+
export class AdbSocket implements AdbSocketInfo, ReadableWritablePair<Uint8Array, Uint8Array>{
|
|
119
|
+
private _controller: AdbSocketController;
|
|
120
|
+
|
|
121
|
+
public get localId(): number { return this._controller.localId; }
|
|
122
|
+
public get remoteId(): number { return this._controller.remoteId; }
|
|
123
|
+
public get localCreated(): boolean { return this._controller.localCreated; }
|
|
124
|
+
public get serviceString(): string { return this._controller.serviceString; }
|
|
125
|
+
|
|
126
|
+
public get readable(): ReadableStream<Uint8Array> { return this._controller.readable; }
|
|
127
|
+
public get writable(): WritableStream<Uint8Array> { return this._controller.writable; }
|
|
128
|
+
|
|
129
|
+
public constructor(controller: AdbSocketController) {
|
|
130
|
+
this._controller = controller;
|
|
23
131
|
}
|
|
24
132
|
|
|
25
|
-
public close()
|
|
26
|
-
return this.
|
|
133
|
+
public close() {
|
|
134
|
+
return this._controller.close();
|
|
27
135
|
}
|
|
28
136
|
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { StructAsyncDeserializeStream } from '@yume-chan/struct';
|
|
2
|
+
import type { AdbSocket, AdbSocketInfo } from '../socket/index.js';
|
|
3
|
+
import type { ReadableStream, ReadableStreamDefaultReader } from './detect.js';
|
|
4
|
+
import { PushReadableStream } from "./transform.js";
|
|
5
|
+
|
|
6
|
+
export class BufferedStreamEndedError extends Error {
|
|
7
|
+
public constructor() {
|
|
8
|
+
super('Stream ended');
|
|
9
|
+
|
|
10
|
+
// Fix Error's prototype chain when compiling to ES5
|
|
11
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class BufferedStream {
|
|
16
|
+
private buffer: Uint8Array | undefined;
|
|
17
|
+
|
|
18
|
+
protected readonly stream: ReadableStream<Uint8Array>;
|
|
19
|
+
|
|
20
|
+
protected readonly reader: ReadableStreamDefaultReader<Uint8Array>;
|
|
21
|
+
|
|
22
|
+
public constructor(stream: ReadableStream<Uint8Array>) {
|
|
23
|
+
this.stream = stream;
|
|
24
|
+
this.reader = stream.getReader();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* @param length
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
32
|
+
public async read(length: number): Promise<Uint8Array> {
|
|
33
|
+
let array: Uint8Array;
|
|
34
|
+
let index: number;
|
|
35
|
+
if (this.buffer) {
|
|
36
|
+
const buffer = this.buffer;
|
|
37
|
+
if (buffer.byteLength > length) {
|
|
38
|
+
this.buffer = buffer.subarray(length);
|
|
39
|
+
return buffer.subarray(0, length);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
array = new Uint8Array(length);
|
|
43
|
+
array.set(buffer);
|
|
44
|
+
index = buffer.byteLength;
|
|
45
|
+
this.buffer = undefined;
|
|
46
|
+
} else {
|
|
47
|
+
const { done, value } = await this.reader.read();
|
|
48
|
+
if (done) {
|
|
49
|
+
throw new BufferedStreamEndedError();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (value.byteLength === length) {
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (value.byteLength > length) {
|
|
57
|
+
this.buffer = value.subarray(length);
|
|
58
|
+
return value.subarray(0, length);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
array = new Uint8Array(length);
|
|
62
|
+
array.set(value);
|
|
63
|
+
index = value.byteLength;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
while (index < length) {
|
|
67
|
+
const left = length - index;
|
|
68
|
+
|
|
69
|
+
const { done, value } = await this.reader.read();
|
|
70
|
+
if (done) {
|
|
71
|
+
throw new BufferedStreamEndedError();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (value.byteLength === left) {
|
|
75
|
+
array.set(value, index);
|
|
76
|
+
return array;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (value.byteLength > left) {
|
|
80
|
+
array.set(value.subarray(0, left), index);
|
|
81
|
+
this.buffer = value.subarray(left);
|
|
82
|
+
return array;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
array.set(value, index);
|
|
86
|
+
index += value.byteLength;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return array;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Return a readable stream with unconsumed data (if any) and
|
|
94
|
+
* all data from the wrapped stream.
|
|
95
|
+
* @returns A `ReadableStream`
|
|
96
|
+
*/
|
|
97
|
+
public release(): ReadableStream<Uint8Array> {
|
|
98
|
+
if (this.buffer) {
|
|
99
|
+
return new PushReadableStream<Uint8Array>(async controller => {
|
|
100
|
+
// Put the remaining data back to the stream
|
|
101
|
+
await controller.enqueue(this.buffer!);
|
|
102
|
+
|
|
103
|
+
// Manually pipe the stream
|
|
104
|
+
while (true) {
|
|
105
|
+
try {
|
|
106
|
+
const { done, value } = await this.reader.read();
|
|
107
|
+
if (done) {
|
|
108
|
+
controller.close();
|
|
109
|
+
break;
|
|
110
|
+
} else {
|
|
111
|
+
await controller.enqueue(value);
|
|
112
|
+
}
|
|
113
|
+
} catch (e) {
|
|
114
|
+
controller.error(e);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
} else {
|
|
120
|
+
// Simply release the reader and return the stream
|
|
121
|
+
this.reader.releaseLock();
|
|
122
|
+
return this.stream;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public close() {
|
|
127
|
+
this.reader.cancel();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export class AdbBufferedStream
|
|
132
|
+
extends BufferedStream
|
|
133
|
+
implements AdbSocketInfo, StructAsyncDeserializeStream {
|
|
134
|
+
protected readonly socket: AdbSocket;
|
|
135
|
+
|
|
136
|
+
public get localId() { return this.socket.localId; }
|
|
137
|
+
public get remoteId() { return this.socket.remoteId; }
|
|
138
|
+
public get localCreated() { return this.socket.localCreated; }
|
|
139
|
+
public get serviceString() { return this.socket.serviceString; }
|
|
140
|
+
|
|
141
|
+
public get writable() { return this.socket.writable; }
|
|
142
|
+
|
|
143
|
+
public constructor(socket: AdbSocket) {
|
|
144
|
+
super(socket.readable);
|
|
145
|
+
this.socket = socket;
|
|
146
|
+
}
|
|
147
|
+
}
|