@yume-chan/adb 0.0.21 → 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.
Files changed (85) hide show
  1. package/CHANGELOG.json +21 -0
  2. package/CHANGELOG.md +11 -1
  3. package/README.md +46 -366
  4. package/esm/adb.d.ts +5 -4
  5. package/esm/adb.d.ts.map +1 -1
  6. package/esm/adb.js.map +1 -1
  7. package/esm/banner.js.map +1 -1
  8. package/esm/commands/framebuffer.d.ts +1 -1
  9. package/esm/commands/framebuffer.d.ts.map +1 -1
  10. package/esm/commands/framebuffer.js.map +1 -1
  11. package/esm/commands/reverse.js.map +1 -1
  12. package/esm/commands/subprocess/command.js.map +1 -1
  13. package/esm/commands/subprocess/protocols/none.d.ts +2 -1
  14. package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
  15. package/esm/commands/subprocess/protocols/none.js +11 -14
  16. package/esm/commands/subprocess/protocols/none.js.map +1 -1
  17. package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
  18. package/esm/commands/subprocess/protocols/shell.js +6 -2
  19. package/esm/commands/subprocess/protocols/shell.js.map +1 -1
  20. package/esm/commands/subprocess/utils.js.map +1 -1
  21. package/esm/commands/sync/list.d.ts +2 -1
  22. package/esm/commands/sync/list.d.ts.map +1 -1
  23. package/esm/commands/sync/list.js +2 -2
  24. package/esm/commands/sync/list.js.map +1 -1
  25. package/esm/commands/sync/pull.d.ts.map +1 -1
  26. package/esm/commands/sync/pull.js +4 -0
  27. package/esm/commands/sync/pull.js.map +1 -1
  28. package/esm/commands/sync/push.js.map +1 -1
  29. package/esm/commands/sync/request.js.map +1 -1
  30. package/esm/commands/sync/response.d.ts +1 -1
  31. package/esm/commands/sync/response.d.ts.map +1 -1
  32. package/esm/commands/sync/response.js +1 -1
  33. package/esm/commands/sync/response.js.map +1 -1
  34. package/esm/commands/sync/socket.d.ts +1 -0
  35. package/esm/commands/sync/socket.d.ts.map +1 -1
  36. package/esm/commands/sync/socket.js +4 -0
  37. package/esm/commands/sync/socket.js.map +1 -1
  38. package/esm/commands/sync/stat.js.map +1 -1
  39. package/esm/commands/sync/sync.js.map +1 -1
  40. package/esm/commands/tcpip.d.ts +21 -0
  41. package/esm/commands/tcpip.d.ts.map +1 -1
  42. package/esm/commands/tcpip.js +18 -0
  43. package/esm/commands/tcpip.js.map +1 -1
  44. package/esm/daemon/auth.js.map +1 -1
  45. package/esm/daemon/crypto.js.map +1 -1
  46. package/esm/daemon/dispatcher.d.ts +2 -1
  47. package/esm/daemon/dispatcher.d.ts.map +1 -1
  48. package/esm/daemon/dispatcher.js +56 -45
  49. package/esm/daemon/dispatcher.js.map +1 -1
  50. package/esm/daemon/packet.d.ts +5 -5
  51. package/esm/daemon/packet.d.ts.map +1 -1
  52. package/esm/daemon/packet.js +1 -1
  53. package/esm/daemon/packet.js.map +1 -1
  54. package/esm/daemon/socket.d.ts +7 -12
  55. package/esm/daemon/socket.d.ts.map +1 -1
  56. package/esm/daemon/socket.js +49 -41
  57. package/esm/daemon/socket.js.map +1 -1
  58. package/esm/daemon/transport.d.ts +8 -4
  59. package/esm/daemon/transport.d.ts.map +1 -1
  60. package/esm/daemon/transport.js +10 -8
  61. package/esm/daemon/transport.js.map +1 -1
  62. package/esm/server/client.d.ts +12 -8
  63. package/esm/server/client.d.ts.map +1 -1
  64. package/esm/server/client.js +40 -20
  65. package/esm/server/client.js.map +1 -1
  66. package/esm/utils/auto-reset-event.js.map +1 -1
  67. package/esm/utils/base64.js.map +1 -1
  68. package/esm/utils/conditional-variable.js.map +1 -1
  69. package/esm/utils/hex.js.map +1 -1
  70. package/package.json +12 -12
  71. package/src/adb.ts +7 -5
  72. package/src/commands/framebuffer.ts +1 -1
  73. package/src/commands/subprocess/protocols/none.ts +15 -19
  74. package/src/commands/subprocess/protocols/shell.ts +7 -2
  75. package/src/commands/sync/list.ts +6 -2
  76. package/src/commands/sync/pull.ts +3 -0
  77. package/src/commands/sync/response.ts +2 -2
  78. package/src/commands/sync/socket.ts +5 -0
  79. package/src/commands/tcpip.ts +44 -0
  80. package/src/daemon/dispatcher.ts +73 -58
  81. package/src/daemon/packet.ts +1 -1
  82. package/src/daemon/socket.ts +71 -84
  83. package/src/daemon/transport.ts +22 -14
  84. package/src/server/client.ts +54 -40
  85. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,4 +1,8 @@
1
- import { AsyncOperationManager, PromiseResolver } from "@yume-chan/async";
1
+ import {
2
+ AsyncOperationManager,
3
+ PromiseResolver,
4
+ delay,
5
+ } from "@yume-chan/async";
2
6
  import type {
3
7
  Consumable,
4
8
  ReadableWritablePair,
@@ -12,7 +16,7 @@ import {
12
16
  import { EMPTY_UINT8_ARRAY } from "@yume-chan/struct";
13
17
 
14
18
  import type { AdbIncomingSocketHandler, AdbSocket, Closeable } from "../adb.js";
15
- import { decodeUtf8, encodeUtf8, unreachable } from "../utils/index.js";
19
+ import { decodeUtf8, encodeUtf8 } from "../utils/index.js";
16
20
 
17
21
  import type { AdbPacketData, AdbPacketInit } from "./packet.js";
18
22
  import { AdbCommand, calculateChecksum } from "./packet.js";
@@ -32,6 +36,7 @@ export interface AdbPacketDispatcherOptions {
32
36
  * Whether to preserve the connection open after the `AdbPacketDispatcher` is closed.
33
37
  */
34
38
  preserveConnection?: boolean | undefined;
39
+ debugSlowRead?: boolean | undefined;
35
40
  }
36
41
 
37
42
  /**
@@ -80,30 +85,18 @@ export class AdbPacketDispatcher implements Closeable {
80
85
  new WritableStream({
81
86
  write: async (packet) => {
82
87
  switch (packet.command) {
83
- case AdbCommand.OK:
84
- this.#handleOk(packet);
85
- break;
86
88
  case AdbCommand.Close:
87
89
  await this.#handleClose(packet);
88
90
  break;
89
- case AdbCommand.Write:
90
- if (this.#sockets.has(packet.arg1)) {
91
- await this.#sockets
92
- .get(packet.arg1)!
93
- .enqueue(packet.payload);
94
- await this.sendPacket(
95
- AdbCommand.OK,
96
- packet.arg1,
97
- packet.arg0,
98
- );
99
- break;
100
- }
101
- throw new Error(
102
- `Unknown local socket id: ${packet.arg1}`,
103
- );
91
+ case AdbCommand.Okay:
92
+ this.#handleOkay(packet);
93
+ break;
104
94
  case AdbCommand.Open:
105
95
  await this.#handleOpen(packet);
106
96
  break;
97
+ case AdbCommand.Write:
98
+ await this.#handleWrite(packet);
99
+ break;
107
100
  default:
108
101
  // Junk data may only appear in the authentication phase,
109
102
  // since the dispatcher only works after authentication,
@@ -137,24 +130,6 @@ export class AdbPacketDispatcher implements Closeable {
137
130
  this.#writer = connection.writable.getWriter();
138
131
  }
139
132
 
140
- #handleOk(packet: AdbPacketData) {
141
- if (this.#initializers.resolve(packet.arg1, packet.arg0)) {
142
- // Device successfully created the socket
143
- return;
144
- }
145
-
146
- const socket = this.#sockets.get(packet.arg1);
147
- if (socket) {
148
- // Device has received last `WRTE` to the socket
149
- socket.ack();
150
- return;
151
- }
152
-
153
- // Maybe the device is responding to a packet of last connection
154
- // Tell the device to close the socket
155
- void this.sendPacket(AdbCommand.Close, packet.arg1, packet.arg0);
156
- }
157
-
158
133
  async #handleClose(packet: AdbPacketData) {
159
134
  // If the socket is still pending
160
135
  if (
@@ -182,15 +157,8 @@ export class AdbPacketDispatcher implements Closeable {
182
157
  // Ignore `arg0` and search for the socket
183
158
  const socket = this.#sockets.get(packet.arg1);
184
159
  if (socket) {
185
- // The device want to close the socket
186
- if (!socket.closed) {
187
- await this.sendPacket(
188
- AdbCommand.Close,
189
- packet.arg1,
190
- packet.arg0,
191
- );
192
- }
193
- await socket.dispose();
160
+ await socket.close();
161
+ socket.dispose();
194
162
  this.#sockets.delete(packet.arg1);
195
163
  return;
196
164
  }
@@ -200,16 +168,22 @@ export class AdbPacketDispatcher implements Closeable {
200
168
  // the device may also respond with two `CLSE` packets.
201
169
  }
202
170
 
203
- addReverseTunnel(service: string, handler: AdbIncomingSocketHandler) {
204
- this.#incomingSocketHandlers.set(service, handler);
205
- }
171
+ #handleOkay(packet: AdbPacketData) {
172
+ if (this.#initializers.resolve(packet.arg1, packet.arg0)) {
173
+ // Device successfully created the socket
174
+ return;
175
+ }
206
176
 
207
- removeReverseTunnel(address: string) {
208
- this.#incomingSocketHandlers.delete(address);
209
- }
177
+ const socket = this.#sockets.get(packet.arg1);
178
+ if (socket) {
179
+ // Device has received last `WRTE` to the socket
180
+ socket.ack();
181
+ return;
182
+ }
210
183
 
211
- clearReverseTunnels() {
212
- this.#incomingSocketHandlers.clear();
184
+ // Maybe the device is responding to a packet of last connection
185
+ // Tell the device to close the socket
186
+ void this.sendPacket(AdbCommand.Close, packet.arg1, packet.arg0);
213
187
  }
214
188
 
215
189
  async #handleOpen(packet: AdbPacketData) {
@@ -241,12 +215,41 @@ export class AdbPacketDispatcher implements Closeable {
241
215
  try {
242
216
  await handler(controller.socket);
243
217
  this.#sockets.set(localId, controller);
244
- await this.sendPacket(AdbCommand.OK, localId, remoteId);
218
+ await this.sendPacket(AdbCommand.Okay, localId, remoteId);
245
219
  } catch (e) {
246
220
  await this.sendPacket(AdbCommand.Close, 0, remoteId);
247
221
  }
248
222
  }
249
223
 
224
+ async #handleWrite(packet: AdbPacketData) {
225
+ const socket = this.#sockets.get(packet.arg1);
226
+ if (!socket) {
227
+ throw new Error(`Unknown local socket id: ${packet.arg1}`);
228
+ }
229
+
230
+ let handled = false;
231
+ await Promise.race([
232
+ delay(5000).then(() => {
233
+ if (this.options.debugSlowRead && !handled) {
234
+ throw new Error(
235
+ `packet for \`${socket.service}\` not handled in 5 seconds`,
236
+ );
237
+ }
238
+ }),
239
+ (async () => {
240
+ await socket.enqueue(packet.payload);
241
+ await this.sendPacket(
242
+ AdbCommand.Okay,
243
+ packet.arg1,
244
+ packet.arg0,
245
+ );
246
+ handled = true;
247
+ })(),
248
+ ]);
249
+
250
+ return;
251
+ }
252
+
250
253
  async createSocket(service: string): Promise<AdbSocket> {
251
254
  if (this.options.appendNullToServiceString) {
252
255
  service += "\0";
@@ -269,6 +272,18 @@ export class AdbPacketDispatcher implements Closeable {
269
272
  return controller.socket;
270
273
  }
271
274
 
275
+ addReverseTunnel(service: string, handler: AdbIncomingSocketHandler) {
276
+ this.#incomingSocketHandlers.set(service, handler);
277
+ }
278
+
279
+ removeReverseTunnel(address: string) {
280
+ this.#incomingSocketHandlers.delete(address);
281
+ }
282
+
283
+ clearReverseTunnels() {
284
+ this.#incomingSocketHandlers.clear();
285
+ }
286
+
272
287
  async sendPacket(
273
288
  command: AdbCommand,
274
289
  arg0: number,
@@ -307,7 +322,7 @@ export class AdbPacketDispatcher implements Closeable {
307
322
  this.#closed = true;
308
323
 
309
324
  this.#readAbortController.abort();
310
- if (this.options.preserveConnection ?? false) {
325
+ if (this.options.preserveConnection) {
311
326
  this.#writer.releaseLock();
312
327
  } else {
313
328
  await this.#writer.close();
@@ -318,7 +333,7 @@ export class AdbPacketDispatcher implements Closeable {
318
333
 
319
334
  #dispose() {
320
335
  for (const socket of this.#sockets.values()) {
321
- socket.dispose().catch(unreachable);
336
+ socket.dispose();
322
337
  }
323
338
 
324
339
  this.#disconnected.resolve();
@@ -5,7 +5,7 @@ export enum AdbCommand {
5
5
  Auth = 0x48545541, // 'AUTH'
6
6
  Close = 0x45534c43, // 'CLSE'
7
7
  Connect = 0x4e584e43, // 'CNXN'
8
- OK = 0x59414b4f, // 'OKAY'
8
+ Okay = 0x59414b4f, // 'OKAY'
9
9
  Open = 0x4e45504f, // 'OPEN'
10
10
  Write = 0x45545257, // 'WRTE'
11
11
  }
@@ -4,18 +4,16 @@ import type {
4
4
  Consumable,
5
5
  PushReadableStreamController,
6
6
  ReadableStream,
7
- ReadableWritablePair,
8
7
  WritableStream,
8
+ WritableStreamDefaultController,
9
9
  } from "@yume-chan/stream-extra";
10
10
  import {
11
11
  ConsumableWritableStream,
12
- DistributionStream,
13
- DuplexStreamFactory,
14
12
  PushReadableStream,
15
- pipeFrom,
16
13
  } from "@yume-chan/stream-extra";
17
14
 
18
- import type { Closeable } from "../adb.js";
15
+ import type { AdbSocket } from "../adb.js";
16
+ import { raceSignal } from "../server/index.js";
19
17
 
20
18
  import type { AdbPacketDispatcher } from "./dispatcher.js";
21
19
  import { AdbCommand } from "./packet.js";
@@ -36,11 +34,7 @@ export interface AdbDaemonSocketConstructionOptions
36
34
  }
37
35
 
38
36
  export class AdbDaemonSocketController
39
- implements
40
- AdbDaemonSocketInfo,
41
- ReadableWritablePair<Uint8Array, Consumable<Uint8Array>>,
42
- Closeable,
43
- Disposable
37
+ implements AdbDaemonSocketInfo, AdbSocket, Disposable
44
38
  {
45
39
  readonly #dispatcher!: AdbPacketDispatcher;
46
40
 
@@ -49,8 +43,6 @@ export class AdbDaemonSocketController
49
43
  readonly localCreated!: boolean;
50
44
  readonly service!: string;
51
45
 
52
- #duplex: DuplexStreamFactory<Uint8Array, Consumable<Uint8Array>>;
53
-
54
46
  #readable: ReadableStream<Uint8Array>;
55
47
  #readableController!: PushReadableStreamController<Uint8Array>;
56
48
  get readable() {
@@ -58,16 +50,14 @@ export class AdbDaemonSocketController
58
50
  }
59
51
 
60
52
  #writePromise: PromiseResolver<void> | undefined;
53
+ #writableController!: WritableStreamDefaultController;
61
54
  readonly writable: WritableStream<Consumable<Uint8Array>>;
62
55
 
63
56
  #closed = false;
64
- /**
65
- * Whether the socket is half-closed (i.e. the local side initiated the close).
66
- *
67
- * It's only used by dispatcher to avoid sending another `CLSE` packet to remote.
68
- */
57
+
58
+ #closedPromise = new PromiseResolver<void>();
69
59
  get closed() {
70
- return this.#closed;
60
+ return this.#closedPromise.promise;
71
61
  }
72
62
 
73
63
  #socket: AdbDaemonSocket;
@@ -82,76 +72,56 @@ export class AdbDaemonSocketController
82
72
  this.localCreated = options.localCreated;
83
73
  this.service = options.service;
84
74
 
85
- // Check this image to help you understand the stream graph
86
- // cspell: disable-next-line
87
- // https://www.plantuml.com/plantuml/png/TL0zoeGm4ErpYc3l5JxyS0yWM6mX5j4C6p4cxcJ25ejttuGX88ZftizxUKmJI275pGhXl0PP_UkfK_CAz5Z2hcWsW9Ny2fdU4C1f5aSchFVxA8vJjlTPRhqZzDQMRB7AklwJ0xXtX0ZSKH1h24ghoKAdGY23FhxC4nS2pDvxzIvxb-8THU0XlEQJ-ZB7SnXTAvc_LhOckhMdLBnbtndpb-SB7a8q2SRD_W00
88
-
89
- this.#duplex = new DuplexStreamFactory<
90
- Uint8Array,
91
- Consumable<Uint8Array>
92
- >({
93
- close: async () => {
94
- this.#closed = true;
95
-
96
- await this.#dispatcher.sendPacket(
97
- AdbCommand.Close,
98
- this.localId,
99
- this.remoteId
100
- );
101
-
102
- // Don't `dispose` here, we need to wait for `CLSE` response packet.
103
- return false;
104
- },
105
- dispose: () => {
106
- // Error out the pending writes
107
- this.#writePromise?.reject(new Error("Socket closed"));
108
- },
75
+ this.#readable = new PushReadableStream((controller) => {
76
+ this.#readableController = controller;
109
77
  });
110
78
 
111
- this.#readable = this.#duplex.wrapReadable(
112
- new PushReadableStream(
113
- (controller) => {
114
- this.#readableController = controller;
115
- },
116
- {
117
- highWaterMark: options.highWaterMark ?? 16 * 1024,
118
- size(chunk) {
119
- return chunk.byteLength;
120
- },
79
+ this.writable = new ConsumableWritableStream<Uint8Array>({
80
+ start: (controller) => {
81
+ this.#writableController = controller;
82
+ },
83
+ write: async (data, controller) => {
84
+ const size = data.length;
85
+ const chunkSize = this.#dispatcher.options.maxPayloadSize;
86
+ for (
87
+ let start = 0, end = chunkSize;
88
+ start < size;
89
+ start = end, end += chunkSize
90
+ ) {
91
+ this.#writePromise = new PromiseResolver();
92
+ await this.#dispatcher.sendPacket(
93
+ AdbCommand.Write,
94
+ this.localId,
95
+ this.remoteId,
96
+ data.subarray(start, end),
97
+ );
98
+ // Wait for ack packet
99
+ await raceSignal(
100
+ () => this.#writePromise!.promise,
101
+ controller.signal,
102
+ );
121
103
  }
122
- )
123
- );
124
-
125
- this.writable = pipeFrom(
126
- this.#duplex.createWritable(
127
- new ConsumableWritableStream<Uint8Array>({
128
- write: async (chunk) => {
129
- // Wait for an ack packet
130
- this.#writePromise = new PromiseResolver();
131
- await this.#dispatcher.sendPacket(
132
- AdbCommand.Write,
133
- this.localId,
134
- this.remoteId,
135
- chunk
136
- );
137
- await this.#writePromise.promise;
138
- },
139
- })
140
- ),
141
- new DistributionStream(this.#dispatcher.options.maxPayloadSize)
142
- );
104
+ },
105
+ });
143
106
 
144
107
  this.#socket = new AdbDaemonSocket(this);
145
108
  }
146
109
 
147
110
  async enqueue(data: Uint8Array) {
148
- // Consumer may abort the `ReadableStream` to close the socket,
149
- // it's OK to throw away further packets in this case.
111
+ // Consumers can `cancel` the `readable` if they are not interested in future data.
112
+ // Throw away the data if that happens.
150
113
  if (this.#readableController.abortSignal.aborted) {
151
114
  return;
152
115
  }
153
116
 
154
- await this.#readableController.enqueue(data);
117
+ try {
118
+ await this.#readableController.enqueue(data);
119
+ } catch (e) {
120
+ if (this.#readableController.abortSignal.aborted) {
121
+ return;
122
+ }
123
+ throw e;
124
+ }
155
125
  }
156
126
 
157
127
  ack() {
@@ -159,11 +129,32 @@ export class AdbDaemonSocketController
159
129
  }
160
130
 
161
131
  async close(): Promise<void> {
162
- await this.#duplex.close();
132
+ if (this.#closed) {
133
+ return;
134
+ }
135
+ this.#closed = true;
136
+
137
+ try {
138
+ this.#writableController.error(new Error("Socket closed"));
139
+ } catch {
140
+ // ignore
141
+ }
142
+
143
+ await this.#dispatcher.sendPacket(
144
+ AdbCommand.Close,
145
+ this.localId,
146
+ this.remoteId,
147
+ );
163
148
  }
164
149
 
165
150
  dispose() {
166
- return this.#duplex.dispose();
151
+ try {
152
+ this.#readableController.close();
153
+ } catch {
154
+ // ignore
155
+ }
156
+
157
+ this.#closedPromise.resolve();
167
158
  }
168
159
  }
169
160
 
@@ -175,11 +166,7 @@ export class AdbDaemonSocketController
175
166
  * `socket.writable.abort()`, `socket.writable.getWriter().abort()`,
176
167
  * `socket.writable.close()` or `socket.writable.getWriter().close()`.
177
168
  */
178
- export class AdbDaemonSocket
179
- implements
180
- AdbDaemonSocketInfo,
181
- ReadableWritablePair<Uint8Array, Consumable<Uint8Array>>
182
- {
169
+ export class AdbDaemonSocket implements AdbDaemonSocketInfo, AdbSocket {
183
170
  #controller: AdbDaemonSocketController;
184
171
 
185
172
  get localId(): number {
@@ -202,7 +189,7 @@ export class AdbDaemonSocket
202
189
  return this.#controller.writable;
203
190
  }
204
191
 
205
- get closed(): boolean {
192
+ get closed(): Promise<void> {
206
193
  return this.#controller.closed;
207
194
  }
208
195
 
@@ -27,20 +27,26 @@ import { AdbCommand, calculateChecksum } from "./packet.js";
27
27
 
28
28
  export const ADB_DAEMON_VERSION_OMIT_CHECKSUM = 0x01000001;
29
29
 
30
+ export type AdbDaemonConnection = ReadableWritablePair<
31
+ AdbPacketData,
32
+ Consumable<AdbPacketInit>
33
+ >;
34
+
30
35
  interface AdbDaemonAuthenticationOptions {
31
36
  serial: string;
32
- connection: ReadableWritablePair<AdbPacketData, Consumable<AdbPacketInit>>;
37
+ connection: AdbDaemonConnection;
33
38
  credentialStore: AdbCredentialStore;
34
39
  authenticators?: AdbAuthenticator[];
35
40
  /**
36
41
  * Whether to preserve the connection open after the `AdbDaemonTransport` is closed.
37
42
  */
38
43
  preserveConnection?: boolean | undefined;
44
+ debugSlowRead?: boolean | undefined;
39
45
  }
40
46
 
41
47
  interface AdbDaemonSocketConnectorConstructionOptions {
42
48
  serial: string;
43
- connection: ReadableWritablePair<AdbPacketData, Consumable<AdbPacketInit>>;
49
+ connection: AdbDaemonConnection;
44
50
  version: number;
45
51
  maxPayloadSize: number;
46
52
  banner: string;
@@ -48,6 +54,7 @@ interface AdbDaemonSocketConnectorConstructionOptions {
48
54
  * Whether to preserve the connection open after the `AdbDaemonTransport` is closed.
49
55
  */
50
56
  preserveConnection?: boolean | undefined;
57
+ debugSlowRead?: boolean | undefined;
51
58
  }
52
59
 
53
60
  export class AdbDaemonTransport implements AdbTransport {
@@ -64,7 +71,7 @@ export class AdbDaemonTransport implements AdbTransport {
64
71
  connection,
65
72
  credentialStore,
66
73
  authenticators = ADB_DEFAULT_AUTHENTICATORS,
67
- preserveConnection,
74
+ ...options
68
75
  }: AdbDaemonAuthenticationOptions): Promise<AdbDaemonTransport> {
69
76
  // Initially, set to highest-supported version and payload size.
70
77
  let version = 0x01000001;
@@ -94,9 +101,8 @@ export class AdbDaemonTransport implements AdbTransport {
94
101
  resolver.resolve(decodeUtf8(packet.payload));
95
102
  break;
96
103
  case AdbCommand.Auth: {
97
- const response = await authProcessor.process(
98
- packet,
99
- );
104
+ const response =
105
+ await authProcessor.process(packet);
100
106
  await sendPacket(response);
101
107
  break;
102
108
  }
@@ -189,10 +195,15 @@ export class AdbDaemonTransport implements AdbTransport {
189
195
  version,
190
196
  maxPayloadSize,
191
197
  banner,
192
- preserveConnection,
198
+ ...options,
193
199
  });
194
200
  }
195
201
 
202
+ #connection: AdbDaemonConnection;
203
+ get connection() {
204
+ return this.#connection;
205
+ }
206
+
196
207
  readonly #dispatcher: AdbPacketDispatcher;
197
208
 
198
209
  #serial: string;
@@ -205,9 +216,8 @@ export class AdbDaemonTransport implements AdbTransport {
205
216
  return this.#protocolVersion;
206
217
  }
207
218
 
208
- #maxPayloadSize: number;
209
219
  get maxPayloadSize() {
210
- return this.#maxPayloadSize;
220
+ return this.#dispatcher.options.maxPayloadSize;
211
221
  }
212
222
 
213
223
  #banner: AdbBanner;
@@ -223,11 +233,11 @@ export class AdbDaemonTransport implements AdbTransport {
223
233
  serial,
224
234
  connection,
225
235
  version,
226
- maxPayloadSize,
227
236
  banner,
228
- preserveConnection,
237
+ ...options
229
238
  }: AdbDaemonSocketConnectorConstructionOptions) {
230
239
  this.#serial = serial;
240
+ this.#connection = connection;
231
241
  this.#banner = AdbBanner.parse(banner);
232
242
 
233
243
  let calculateChecksum: boolean;
@@ -243,12 +253,10 @@ export class AdbDaemonTransport implements AdbTransport {
243
253
  this.#dispatcher = new AdbPacketDispatcher(connection, {
244
254
  calculateChecksum,
245
255
  appendNullToServiceString,
246
- maxPayloadSize,
247
- preserveConnection,
256
+ ...options,
248
257
  });
249
258
 
250
259
  this.#protocolVersion = version;
251
- this.#maxPayloadSize = maxPayloadSize;
252
260
  }
253
261
 
254
262
  connect(service: string): ValueOrPromise<AdbSocket> {