@yume-chan/adb 0.0.20 → 0.0.22
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 +45 -0
- package/CHANGELOG.md +22 -1
- package/README.md +46 -364
- package/esm/adb.d.ts +9 -5
- package/esm/adb.d.ts.map +1 -1
- package/esm/adb.js +21 -11
- package/esm/adb.js.map +1 -1
- package/esm/banner.d.ts.map +1 -1
- package/esm/banner.js +1 -1
- package/esm/banner.js.map +1 -1
- package/esm/commands/base.d.ts.map +1 -1
- package/esm/commands/base.js.map +1 -1
- package/esm/commands/framebuffer.d.ts +9 -0
- package/esm/commands/framebuffer.d.ts.map +1 -1
- package/esm/commands/framebuffer.js +27 -3
- package/esm/commands/framebuffer.js.map +1 -1
- package/esm/commands/power.d.ts.map +1 -1
- package/esm/commands/power.js.map +1 -1
- package/esm/commands/reverse.d.ts.map +1 -1
- package/esm/commands/reverse.js.map +1 -1
- package/esm/commands/subprocess/command.d.ts +1 -1
- package/esm/commands/subprocess/command.d.ts.map +1 -1
- package/esm/commands/subprocess/command.js +15 -13
- package/esm/commands/subprocess/command.js.map +1 -1
- package/esm/commands/subprocess/protocols/none.d.ts +2 -1
- package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/none.js +11 -14
- package/esm/commands/subprocess/protocols/none.js.map +1 -1
- package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/shell.js +21 -17
- package/esm/commands/subprocess/protocols/shell.js.map +1 -1
- package/esm/commands/subprocess/utils.js.map +1 -1
- package/esm/commands/sync/list.d.ts +2 -1
- package/esm/commands/sync/list.d.ts.map +1 -1
- package/esm/commands/sync/list.js +2 -2
- package/esm/commands/sync/list.js.map +1 -1
- package/esm/commands/sync/pull.d.ts.map +1 -1
- package/esm/commands/sync/pull.js +4 -0
- package/esm/commands/sync/pull.js.map +1 -1
- package/esm/commands/sync/push.js +1 -1
- package/esm/commands/sync/push.js.map +1 -1
- package/esm/commands/sync/request.js +1 -1
- package/esm/commands/sync/request.js.map +1 -1
- package/esm/commands/sync/response.d.ts +3 -1
- package/esm/commands/sync/response.d.ts.map +1 -1
- package/esm/commands/sync/response.js +5 -3
- package/esm/commands/sync/response.js.map +1 -1
- package/esm/commands/sync/socket.d.ts +1 -1
- package/esm/commands/sync/socket.d.ts.map +1 -1
- package/esm/commands/sync/socket.js +7 -3
- package/esm/commands/sync/socket.js.map +1 -1
- package/esm/commands/sync/stat.js +2 -2
- package/esm/commands/sync/stat.js.map +1 -1
- package/esm/commands/sync/sync.d.ts +15 -0
- package/esm/commands/sync/sync.d.ts.map +1 -1
- package/esm/commands/sync/sync.js +17 -2
- package/esm/commands/sync/sync.js.map +1 -1
- package/esm/commands/tcpip.d.ts +21 -0
- package/esm/commands/tcpip.d.ts.map +1 -1
- package/esm/commands/tcpip.js +18 -0
- package/esm/commands/tcpip.js.map +1 -1
- package/esm/daemon/auth.d.ts +11 -9
- package/esm/daemon/auth.d.ts.map +1 -1
- package/esm/daemon/auth.js +21 -12
- package/esm/daemon/auth.js.map +1 -1
- package/esm/daemon/crypto.js +2 -2
- package/esm/daemon/crypto.js.map +1 -1
- package/esm/daemon/dispatcher.d.ts +6 -5
- package/esm/daemon/dispatcher.d.ts.map +1 -1
- package/esm/daemon/dispatcher.js +69 -58
- package/esm/daemon/dispatcher.js.map +1 -1
- package/esm/daemon/packet.d.ts +5 -5
- package/esm/daemon/packet.d.ts.map +1 -1
- package/esm/daemon/packet.js +2 -2
- package/esm/daemon/packet.js.map +1 -1
- package/esm/daemon/socket.d.ts +7 -14
- package/esm/daemon/socket.d.ts.map +1 -1
- package/esm/daemon/socket.js +58 -46
- package/esm/daemon/socket.js.map +1 -1
- package/esm/daemon/transport.d.ts +16 -4
- package/esm/daemon/transport.d.ts.map +1 -1
- package/esm/daemon/transport.js +11 -7
- package/esm/daemon/transport.js.map +1 -1
- package/esm/features.js +1 -1
- package/esm/features.js.map +1 -1
- package/esm/server/client.d.ts +12 -8
- package/esm/server/client.d.ts.map +1 -1
- package/esm/server/client.js +41 -22
- package/esm/server/client.js.map +1 -1
- package/esm/server/transport.d.ts.map +1 -1
- package/esm/server/transport.js.map +1 -1
- package/esm/utils/auto-reset-event.d.ts.map +1 -1
- package/esm/utils/auto-reset-event.js.map +1 -1
- package/esm/utils/base64.js.map +1 -1
- package/esm/utils/conditional-variable.d.ts.map +1 -1
- package/esm/utils/conditional-variable.js.map +1 -1
- package/esm/utils/hex.js.map +1 -1
- package/package.json +13 -14
- package/src/adb.ts +49 -35
- package/src/banner.ts +7 -7
- package/src/commands/base.ts +1 -1
- package/src/commands/framebuffer.ts +31 -3
- package/src/commands/power.ts +9 -9
- package/src/commands/reverse.ts +13 -13
- package/src/commands/subprocess/command.ts +24 -25
- package/src/commands/subprocess/protocols/none.ts +23 -27
- package/src/commands/subprocess/protocols/shell.ts +42 -37
- package/src/commands/sync/list.ts +11 -7
- package/src/commands/sync/pull.ts +7 -4
- package/src/commands/sync/push.ts +6 -6
- package/src/commands/sync/request.ts +3 -3
- package/src/commands/sync/response.ts +8 -6
- package/src/commands/sync/socket.ts +19 -14
- package/src/commands/sync/stat.ts +5 -5
- package/src/commands/sync/sync.ts +32 -17
- package/src/commands/tcpip.ts +46 -2
- package/src/daemon/auth.ts +49 -30
- package/src/daemon/crypto.ts +9 -9
- package/src/daemon/dispatcher.ts +104 -88
- package/src/daemon/packet.ts +2 -2
- package/src/daemon/socket.ts +106 -115
- package/src/daemon/transport.ts +49 -29
- package/src/server/client.ts +88 -77
- package/src/server/transport.ts +13 -13
- package/src/utils/auto-reset-event.ts +4 -4
- package/src/utils/base64.ts +5 -5
- package/src/utils/conditional-variable.ts +4 -4
- package/tsconfig.build.tsbuildinfo +1 -1
- package/esm/daemon/connection.d.ts +0 -11
- package/esm/daemon/connection.d.ts.map +0 -1
- package/esm/daemon/connection.js +0 -2
- package/esm/daemon/connection.js.map +0 -1
|
@@ -61,38 +61,38 @@ class StdinSerializeStream extends ConsumableTransformStream<
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
class MultiplexStream<T> {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return this
|
|
64
|
+
#readable: PushReadableStream<T>;
|
|
65
|
+
#readableController!: PushReadableStreamController<T>;
|
|
66
|
+
get readable() {
|
|
67
|
+
return this.#readable;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
#activeCount = 0;
|
|
71
71
|
|
|
72
72
|
constructor() {
|
|
73
|
-
this
|
|
74
|
-
this
|
|
73
|
+
this.#readable = new PushReadableStream((controller) => {
|
|
74
|
+
this.#readableController = controller;
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
createWriteable() {
|
|
79
79
|
return new WritableStream<T>({
|
|
80
80
|
start: () => {
|
|
81
|
-
this
|
|
81
|
+
this.#activeCount += 1;
|
|
82
82
|
},
|
|
83
83
|
write: async (chunk) => {
|
|
84
|
-
await this.
|
|
84
|
+
await this.#readableController.enqueue(chunk);
|
|
85
85
|
},
|
|
86
86
|
abort: () => {
|
|
87
|
-
this
|
|
88
|
-
if (this
|
|
89
|
-
this.
|
|
87
|
+
this.#activeCount -= 1;
|
|
88
|
+
if (this.#activeCount === 0) {
|
|
89
|
+
this.#readableController.close();
|
|
90
90
|
}
|
|
91
91
|
},
|
|
92
92
|
close: () => {
|
|
93
|
-
this
|
|
94
|
-
if (this
|
|
95
|
-
this.
|
|
93
|
+
this.#activeCount -= 1;
|
|
94
|
+
if (this.#activeCount === 0) {
|
|
95
|
+
this.#readableController.close();
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
});
|
|
@@ -108,20 +108,20 @@ class MultiplexStream<T> {
|
|
|
108
108
|
* * `resize`: Yes
|
|
109
109
|
*/
|
|
110
110
|
export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
|
|
111
|
-
|
|
111
|
+
static isSupported(adb: Adb) {
|
|
112
112
|
return adb.supportsFeature(AdbFeature.ShellV2);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
static async pty(adb: Adb, command: string) {
|
|
116
116
|
// TODO: AdbShellSubprocessProtocol: Support setting `XTERM` environment variable
|
|
117
117
|
return new AdbSubprocessShellProtocol(
|
|
118
|
-
await adb.createSocket(`shell,v2,pty:${command}`)
|
|
118
|
+
await adb.createSocket(`shell,v2,pty:${command}`),
|
|
119
119
|
);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
static async raw(adb: Adb, command: string) {
|
|
123
123
|
return new AdbSubprocessShellProtocol(
|
|
124
|
-
await adb.createSocket(`shell,v2,raw:${command}`)
|
|
124
|
+
await adb.createSocket(`shell,v2,raw:${command}`),
|
|
125
125
|
);
|
|
126
126
|
}
|
|
127
127
|
|
|
@@ -131,26 +131,26 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
|
|
|
131
131
|
>;
|
|
132
132
|
|
|
133
133
|
#stdin: WritableStream<Consumable<Uint8Array>>;
|
|
134
|
-
|
|
134
|
+
get stdin() {
|
|
135
135
|
return this.#stdin;
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
#stdout: ReadableStream<Uint8Array>;
|
|
139
|
-
|
|
139
|
+
get stdout() {
|
|
140
140
|
return this.#stdout;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
#stderr: ReadableStream<Uint8Array>;
|
|
144
|
-
|
|
144
|
+
get stderr() {
|
|
145
145
|
return this.#stderr;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
readonly #exit = new PromiseResolver<number>();
|
|
149
|
-
|
|
149
|
+
get exit() {
|
|
150
150
|
return this.#exit.promise;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
constructor(socket: AdbSocket) {
|
|
154
154
|
this.#socket = socket;
|
|
155
155
|
|
|
156
156
|
// Check this image to help you understand the stream graph
|
|
@@ -159,6 +159,7 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
|
|
|
159
159
|
|
|
160
160
|
let stdoutController!: PushReadableStreamController<Uint8Array>;
|
|
161
161
|
let stderrController!: PushReadableStreamController<Uint8Array>;
|
|
162
|
+
|
|
162
163
|
this.#stdout = new PushReadableStream<Uint8Array>((controller) => {
|
|
163
164
|
stdoutController = controller;
|
|
164
165
|
});
|
|
@@ -176,14 +177,18 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
|
|
|
176
177
|
this.#exit.resolve(chunk.data[0]!);
|
|
177
178
|
break;
|
|
178
179
|
case AdbShellProtocolId.Stdout:
|
|
179
|
-
|
|
180
|
+
if (!stdoutController.abortSignal.aborted) {
|
|
181
|
+
await stdoutController.enqueue(chunk.data);
|
|
182
|
+
}
|
|
180
183
|
break;
|
|
181
184
|
case AdbShellProtocolId.Stderr:
|
|
182
|
-
|
|
185
|
+
if (!stderrController.abortSignal.aborted) {
|
|
186
|
+
await stderrController.enqueue(chunk.data);
|
|
187
|
+
}
|
|
183
188
|
break;
|
|
184
189
|
}
|
|
185
190
|
},
|
|
186
|
-
})
|
|
191
|
+
}),
|
|
187
192
|
)
|
|
188
193
|
.then(
|
|
189
194
|
() => {
|
|
@@ -191,7 +196,7 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
|
|
|
191
196
|
stderrController.close();
|
|
192
197
|
// If `#exit` has already resolved, this will be a no-op
|
|
193
198
|
this.#exit.reject(
|
|
194
|
-
new Error("Socket ended without exit message")
|
|
199
|
+
new Error("Socket ended without exit message"),
|
|
195
200
|
);
|
|
196
201
|
},
|
|
197
202
|
(e) => {
|
|
@@ -199,7 +204,7 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
|
|
|
199
204
|
stderrController.error(e);
|
|
200
205
|
// If `#exit` has already resolved, this will be a no-op
|
|
201
206
|
this.#exit.reject(e);
|
|
202
|
-
}
|
|
207
|
+
},
|
|
203
208
|
);
|
|
204
209
|
|
|
205
210
|
const multiplexer = new MultiplexStream<
|
|
@@ -210,34 +215,34 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
|
|
|
210
215
|
new ConsumableTransformStream({
|
|
211
216
|
async transform(chunk, controller) {
|
|
212
217
|
await controller.enqueue(
|
|
213
|
-
AdbShellProtocolPacket.serialize(chunk)
|
|
218
|
+
AdbShellProtocolPacket.serialize(chunk),
|
|
214
219
|
);
|
|
215
220
|
},
|
|
216
|
-
})
|
|
221
|
+
}),
|
|
217
222
|
)
|
|
218
223
|
.pipeTo(socket.writable);
|
|
219
224
|
|
|
220
225
|
this.#stdin = pipeFrom(
|
|
221
226
|
multiplexer.createWriteable(),
|
|
222
|
-
new StdinSerializeStream()
|
|
227
|
+
new StdinSerializeStream(),
|
|
223
228
|
);
|
|
224
229
|
|
|
225
230
|
this.#socketWriter = multiplexer.createWriteable().getWriter();
|
|
226
231
|
}
|
|
227
232
|
|
|
228
|
-
|
|
233
|
+
async resize(rows: number, cols: number) {
|
|
229
234
|
await ConsumableWritableStream.write(this.#socketWriter, {
|
|
230
235
|
id: AdbShellProtocolId.WindowSizeChange,
|
|
231
236
|
data: encodeUtf8(
|
|
232
237
|
// The "correct" format is `${rows}x${cols},${x_pixels}x${y_pixels}`
|
|
233
238
|
// However, according to https://linux.die.net/man/4/tty_ioctl
|
|
234
239
|
// `x_pixels` and `y_pixels` are unused, so always sending `0` should be fine.
|
|
235
|
-
`${rows}x${cols},0x0\0
|
|
240
|
+
`${rows}x${cols},0x0\0`,
|
|
236
241
|
),
|
|
237
242
|
});
|
|
238
243
|
}
|
|
239
244
|
|
|
240
|
-
|
|
245
|
+
kill() {
|
|
241
246
|
return this.#socket.close();
|
|
242
247
|
}
|
|
243
248
|
}
|
|
@@ -4,7 +4,11 @@ import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
|
|
4
4
|
import { AdbSyncResponseId, adbSyncReadResponses } from "./response.js";
|
|
5
5
|
import type { AdbSyncSocket } from "./socket.js";
|
|
6
6
|
import type { AdbSyncStat } from "./stat.js";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
AdbSyncLstatResponse,
|
|
9
|
+
AdbSyncStatErrorCode,
|
|
10
|
+
AdbSyncStatResponse,
|
|
11
|
+
} from "./stat.js";
|
|
8
12
|
|
|
9
13
|
export interface AdbSyncEntry extends AdbSyncStat {
|
|
10
14
|
name: string;
|
|
@@ -30,7 +34,7 @@ export type AdbSyncEntry2Response =
|
|
|
30
34
|
|
|
31
35
|
export async function* adbSyncOpenDirV2(
|
|
32
36
|
socket: AdbSyncSocket,
|
|
33
|
-
path: string
|
|
37
|
+
path: string,
|
|
34
38
|
): AsyncGenerator<AdbSyncEntry2Response, void, void> {
|
|
35
39
|
const locked = await socket.lock();
|
|
36
40
|
try {
|
|
@@ -38,12 +42,12 @@ export async function* adbSyncOpenDirV2(
|
|
|
38
42
|
for await (const item of adbSyncReadResponses(
|
|
39
43
|
locked,
|
|
40
44
|
AdbSyncResponseId.Entry2,
|
|
41
|
-
AdbSyncEntry2Response
|
|
45
|
+
AdbSyncEntry2Response,
|
|
42
46
|
)) {
|
|
43
47
|
// `LST2` can return error codes for failed `lstat` calls.
|
|
44
48
|
// `LIST` just ignores them.
|
|
45
49
|
// But they only contain `name` so still pretty useless.
|
|
46
|
-
if (item.error !==
|
|
50
|
+
if (item.error !== AdbSyncStatErrorCode.SUCCESS) {
|
|
47
51
|
continue;
|
|
48
52
|
}
|
|
49
53
|
yield item;
|
|
@@ -55,7 +59,7 @@ export async function* adbSyncOpenDirV2(
|
|
|
55
59
|
|
|
56
60
|
export async function* adbSyncOpenDirV1(
|
|
57
61
|
socket: AdbSyncSocket,
|
|
58
|
-
path: string
|
|
62
|
+
path: string,
|
|
59
63
|
): AsyncGenerator<AdbSyncEntryResponse, void, void> {
|
|
60
64
|
const locked = await socket.lock();
|
|
61
65
|
try {
|
|
@@ -63,7 +67,7 @@ export async function* adbSyncOpenDirV1(
|
|
|
63
67
|
for await (const item of adbSyncReadResponses(
|
|
64
68
|
locked,
|
|
65
69
|
AdbSyncResponseId.Entry,
|
|
66
|
-
AdbSyncEntryResponse
|
|
70
|
+
AdbSyncEntryResponse,
|
|
67
71
|
)) {
|
|
68
72
|
yield item;
|
|
69
73
|
}
|
|
@@ -75,7 +79,7 @@ export async function* adbSyncOpenDirV1(
|
|
|
75
79
|
export async function* adbSyncOpenDir(
|
|
76
80
|
socket: AdbSyncSocket,
|
|
77
81
|
path: string,
|
|
78
|
-
v2: boolean
|
|
82
|
+
v2: boolean,
|
|
79
83
|
): AsyncGenerator<AdbSyncEntry, void, void> {
|
|
80
84
|
if (v2) {
|
|
81
85
|
yield* adbSyncOpenDirV2(socket, path);
|
|
@@ -16,7 +16,7 @@ export type AdbSyncDataResponse =
|
|
|
16
16
|
|
|
17
17
|
export async function* adbSyncPullGenerator(
|
|
18
18
|
socket: AdbSyncSocket,
|
|
19
|
-
path: string
|
|
19
|
+
path: string,
|
|
20
20
|
): AsyncGenerator<Uint8Array, void, void> {
|
|
21
21
|
const locked = await socket.lock();
|
|
22
22
|
let done = false;
|
|
@@ -25,18 +25,21 @@ export async function* adbSyncPullGenerator(
|
|
|
25
25
|
for await (const packet of adbSyncReadResponses(
|
|
26
26
|
locked,
|
|
27
27
|
AdbSyncResponseId.Data,
|
|
28
|
-
AdbSyncDataResponse
|
|
28
|
+
AdbSyncDataResponse,
|
|
29
29
|
)) {
|
|
30
30
|
yield packet.data;
|
|
31
31
|
}
|
|
32
32
|
done = true;
|
|
33
|
+
} catch (e) {
|
|
34
|
+
done = true;
|
|
35
|
+
throw e;
|
|
33
36
|
} finally {
|
|
34
37
|
if (!done) {
|
|
35
38
|
// sync pull can't be cancelled, so we have to read all data
|
|
36
39
|
for await (const packet of adbSyncReadResponses(
|
|
37
40
|
locked,
|
|
38
41
|
AdbSyncResponseId.Data,
|
|
39
|
-
AdbSyncDataResponse
|
|
42
|
+
AdbSyncDataResponse,
|
|
40
43
|
)) {
|
|
41
44
|
void packet;
|
|
42
45
|
}
|
|
@@ -47,7 +50,7 @@ export async function* adbSyncPullGenerator(
|
|
|
47
50
|
|
|
48
51
|
export function adbSyncPull(
|
|
49
52
|
socket: AdbSyncSocket,
|
|
50
|
-
path: string
|
|
53
|
+
path: string,
|
|
51
54
|
): ReadableStream<Uint8Array> {
|
|
52
55
|
return new PushReadableStream(async (controller) => {
|
|
53
56
|
for await (const data of adbSyncPullGenerator(socket, path)) {
|
|
@@ -26,14 +26,14 @@ export interface AdbSyncPushV1Options {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export const AdbSyncOkResponse = new Struct({ littleEndian: true }).uint32(
|
|
29
|
-
"unused"
|
|
29
|
+
"unused",
|
|
30
30
|
);
|
|
31
31
|
|
|
32
32
|
async function pipeFileData(
|
|
33
33
|
locked: AdbSyncSocketLocked,
|
|
34
34
|
file: ReadableStream<Consumable<Uint8Array>>,
|
|
35
35
|
packetSize: number,
|
|
36
|
-
mtime: number
|
|
36
|
+
mtime: number,
|
|
37
37
|
) {
|
|
38
38
|
// Read and write in parallel,
|
|
39
39
|
// allow error response to abort the write.
|
|
@@ -45,11 +45,11 @@ async function pipeFileData(
|
|
|
45
45
|
await adbSyncWriteRequest(
|
|
46
46
|
locked,
|
|
47
47
|
AdbSyncRequestId.Data,
|
|
48
|
-
chunk
|
|
48
|
+
chunk,
|
|
49
49
|
);
|
|
50
50
|
},
|
|
51
51
|
}),
|
|
52
|
-
{ signal: abortController.signal }
|
|
52
|
+
{ signal: abortController.signal },
|
|
53
53
|
)
|
|
54
54
|
.then(async () => {
|
|
55
55
|
await adbSyncWriteRequest(locked, AdbSyncRequestId.Done, mtime);
|
|
@@ -59,7 +59,7 @@ async function pipeFileData(
|
|
|
59
59
|
await adbSyncReadResponse(
|
|
60
60
|
locked,
|
|
61
61
|
AdbSyncResponseId.Ok,
|
|
62
|
-
AdbSyncOkResponse
|
|
62
|
+
AdbSyncOkResponse,
|
|
63
63
|
).catch((e) => {
|
|
64
64
|
abortController.abort();
|
|
65
65
|
throw e;
|
|
@@ -142,7 +142,7 @@ export async function adbSyncPushV2({
|
|
|
142
142
|
id: AdbSyncRequestId.SendV2,
|
|
143
143
|
mode,
|
|
144
144
|
flags,
|
|
145
|
-
})
|
|
145
|
+
}),
|
|
146
146
|
);
|
|
147
147
|
|
|
148
148
|
await pipeFileData(locked, file, packetSize, mtime);
|
|
@@ -30,7 +30,7 @@ export interface AdbSyncWritable {
|
|
|
30
30
|
export async function adbSyncWriteRequest(
|
|
31
31
|
writable: AdbSyncWritable,
|
|
32
32
|
id: AdbSyncRequestId | string,
|
|
33
|
-
value: number | string | Uint8Array
|
|
33
|
+
value: number | string | Uint8Array,
|
|
34
34
|
): Promise<void> {
|
|
35
35
|
if (typeof value === "number") {
|
|
36
36
|
const buffer = AdbSyncNumberRequest.serialize({
|
|
@@ -42,12 +42,12 @@ export async function adbSyncWriteRequest(
|
|
|
42
42
|
// Let `writable` buffer writes
|
|
43
43
|
const buffer = encodeUtf8(value);
|
|
44
44
|
await writable.write(
|
|
45
|
-
AdbSyncNumberRequest.serialize({ id, arg: buffer.byteLength })
|
|
45
|
+
AdbSyncNumberRequest.serialize({ id, arg: buffer.byteLength }),
|
|
46
46
|
);
|
|
47
47
|
await writable.write(buffer);
|
|
48
48
|
} else {
|
|
49
49
|
await writable.write(
|
|
50
|
-
AdbSyncNumberRequest.serialize({ id, arg: value.byteLength })
|
|
50
|
+
AdbSyncNumberRequest.serialize({ id, arg: value.byteLength }),
|
|
51
51
|
);
|
|
52
52
|
await writable.write(value);
|
|
53
53
|
}
|
|
@@ -19,17 +19,19 @@ export enum AdbSyncResponseId {
|
|
|
19
19
|
Fail = "FAIL",
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
export class AdbSyncError extends Error {}
|
|
23
|
+
|
|
22
24
|
export const AdbSyncFailResponse = new Struct({ littleEndian: true })
|
|
23
25
|
.uint32("messageLength")
|
|
24
26
|
.string("message", { lengthField: "messageLength" })
|
|
25
27
|
.postDeserialize((object) => {
|
|
26
|
-
throw new
|
|
28
|
+
throw new AdbSyncError(object.message);
|
|
27
29
|
});
|
|
28
30
|
|
|
29
31
|
export async function adbSyncReadResponse<T>(
|
|
30
32
|
stream: AsyncExactReadable,
|
|
31
33
|
id: AdbSyncResponseId,
|
|
32
|
-
type: StructLike<T
|
|
34
|
+
type: StructLike<T>,
|
|
33
35
|
): Promise<T> {
|
|
34
36
|
const actualId = decodeUtf8(await stream.readExactly(4));
|
|
35
37
|
switch (actualId) {
|
|
@@ -44,11 +46,11 @@ export async function adbSyncReadResponse<T>(
|
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
export async function* adbSyncReadResponses<
|
|
47
|
-
T extends Struct<object, PropertyKey, object,
|
|
49
|
+
T extends Struct<object, PropertyKey, object, unknown>,
|
|
48
50
|
>(
|
|
49
51
|
stream: AsyncExactReadable,
|
|
50
52
|
id: AdbSyncResponseId,
|
|
51
|
-
type: T
|
|
53
|
+
type: T,
|
|
52
54
|
): AsyncGenerator<StructValueType<T>, void, void> {
|
|
53
55
|
while (true) {
|
|
54
56
|
const actualId = decodeUtf8(await stream.readExactly(4));
|
|
@@ -64,11 +66,11 @@ export async function* adbSyncReadResponses<
|
|
|
64
66
|
await stream.readExactly(type.size);
|
|
65
67
|
return;
|
|
66
68
|
case id:
|
|
67
|
-
yield await type.deserialize(stream)
|
|
69
|
+
yield (await type.deserialize(stream)) as StructValueType<T>;
|
|
68
70
|
break;
|
|
69
71
|
default:
|
|
70
72
|
throw new Error(
|
|
71
|
-
`Expected '${id}' or '${AdbSyncResponseId.Done}', but got '${actualId}'
|
|
73
|
+
`Expected '${id}' or '${AdbSyncResponseId.Done}', but got '${actualId}'`,
|
|
72
74
|
);
|
|
73
75
|
}
|
|
74
76
|
}
|
|
@@ -19,15 +19,15 @@ export class AdbSyncSocketLocked implements AsyncExactReadable {
|
|
|
19
19
|
readonly #writeLock = new AutoResetEvent();
|
|
20
20
|
readonly #combiner: BufferCombiner;
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
get position() {
|
|
23
23
|
return this.#readable.position;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
constructor(
|
|
27
27
|
writer: WritableStreamDefaultWriter<Consumable<Uint8Array>>,
|
|
28
28
|
readable: BufferedReadableStream,
|
|
29
29
|
bufferSize: number,
|
|
30
|
-
lock: AutoResetEvent
|
|
30
|
+
lock: AutoResetEvent,
|
|
31
31
|
) {
|
|
32
32
|
this.#writer = writer;
|
|
33
33
|
this.#readable = readable;
|
|
@@ -35,42 +35,46 @@ export class AdbSyncSocketLocked implements AsyncExactReadable {
|
|
|
35
35
|
this.#combiner = new BufferCombiner(bufferSize);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
async #writeInnerStream(buffer: Uint8Array) {
|
|
39
39
|
await ConsumableWritableStream.write(this.#writer, buffer);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
async flush() {
|
|
43
43
|
try {
|
|
44
44
|
await this.#writeLock.wait();
|
|
45
45
|
const buffer = this.#combiner.flush();
|
|
46
46
|
if (buffer) {
|
|
47
|
-
await this
|
|
47
|
+
await this.#writeInnerStream(buffer);
|
|
48
48
|
}
|
|
49
49
|
} finally {
|
|
50
50
|
this.#writeLock.notifyOne();
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
async write(data: Uint8Array) {
|
|
55
55
|
try {
|
|
56
56
|
await this.#writeLock.wait();
|
|
57
57
|
for (const buffer of this.#combiner.push(data)) {
|
|
58
|
-
await this
|
|
58
|
+
await this.#writeInnerStream(buffer);
|
|
59
59
|
}
|
|
60
60
|
} finally {
|
|
61
61
|
this.#writeLock.notifyOne();
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
async readExactly(length: number) {
|
|
66
66
|
await this.flush();
|
|
67
67
|
return await this.#readable.readExactly(length);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
release(): void {
|
|
71
71
|
this.#combiner.flush();
|
|
72
72
|
this.#socketLock.notifyOne();
|
|
73
73
|
}
|
|
74
|
+
|
|
75
|
+
async close() {
|
|
76
|
+
await this.#readable.cancel();
|
|
77
|
+
}
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
export class AdbSyncSocket {
|
|
@@ -78,22 +82,23 @@ export class AdbSyncSocket {
|
|
|
78
82
|
readonly #socket: AdbSocket;
|
|
79
83
|
readonly #locked: AdbSyncSocketLocked;
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
constructor(socket: AdbSocket, bufferSize: number) {
|
|
82
86
|
this.#socket = socket;
|
|
83
87
|
this.#locked = new AdbSyncSocketLocked(
|
|
84
88
|
socket.writable.getWriter(),
|
|
85
89
|
new BufferedReadableStream(socket.readable),
|
|
86
90
|
bufferSize,
|
|
87
|
-
this.#lock
|
|
91
|
+
this.#lock,
|
|
88
92
|
);
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
|
|
95
|
+
async lock() {
|
|
92
96
|
await this.#lock.wait();
|
|
93
97
|
return this.#locked;
|
|
94
98
|
}
|
|
95
99
|
|
|
96
|
-
|
|
100
|
+
async close() {
|
|
101
|
+
await this.#locked.close();
|
|
97
102
|
await this.#socket.close();
|
|
98
103
|
}
|
|
99
104
|
}
|
|
@@ -103,7 +103,7 @@ export type AdbSyncStatResponse =
|
|
|
103
103
|
export async function adbSyncLstat(
|
|
104
104
|
socket: AdbSyncSocket,
|
|
105
105
|
path: string,
|
|
106
|
-
v2: boolean
|
|
106
|
+
v2: boolean,
|
|
107
107
|
): Promise<AdbSyncStat> {
|
|
108
108
|
const locked = await socket.lock();
|
|
109
109
|
try {
|
|
@@ -112,14 +112,14 @@ export async function adbSyncLstat(
|
|
|
112
112
|
return await adbSyncReadResponse(
|
|
113
113
|
locked,
|
|
114
114
|
AdbSyncResponseId.Lstat2,
|
|
115
|
-
AdbSyncStatResponse
|
|
115
|
+
AdbSyncStatResponse,
|
|
116
116
|
);
|
|
117
117
|
} else {
|
|
118
118
|
await adbSyncWriteRequest(locked, AdbSyncRequestId.Lstat, path);
|
|
119
119
|
const response = await adbSyncReadResponse(
|
|
120
120
|
locked,
|
|
121
121
|
AdbSyncResponseId.Lstat,
|
|
122
|
-
AdbSyncLstatResponse
|
|
122
|
+
AdbSyncLstatResponse,
|
|
123
123
|
);
|
|
124
124
|
return {
|
|
125
125
|
mode: response.mode,
|
|
@@ -141,7 +141,7 @@ export async function adbSyncLstat(
|
|
|
141
141
|
|
|
142
142
|
export async function adbSyncStat(
|
|
143
143
|
socket: AdbSyncSocket,
|
|
144
|
-
path: string
|
|
144
|
+
path: string,
|
|
145
145
|
): Promise<AdbSyncStatResponse> {
|
|
146
146
|
const locked = await socket.lock();
|
|
147
147
|
try {
|
|
@@ -149,7 +149,7 @@ export async function adbSyncStat(
|
|
|
149
149
|
return await adbSyncReadResponse(
|
|
150
150
|
locked,
|
|
151
151
|
AdbSyncResponseId.Stat,
|
|
152
|
-
AdbSyncStatResponse
|
|
152
|
+
AdbSyncStatResponse,
|
|
153
153
|
);
|
|
154
154
|
} finally {
|
|
155
155
|
locked.release();
|