@yume-chan/adb 0.0.16 → 0.0.18

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 (177) hide show
  1. package/CHANGELOG.json +18 -0
  2. package/CHANGELOG.md +13 -1
  3. package/LICENSE +1 -1
  4. package/esm/adb.d.ts +13 -8
  5. package/esm/adb.d.ts.map +1 -1
  6. package/esm/adb.js +63 -38
  7. package/esm/adb.js.map +1 -1
  8. package/esm/auth.d.ts +4 -4
  9. package/esm/auth.d.ts.map +1 -1
  10. package/esm/auth.js +6 -6
  11. package/esm/auth.js.map +1 -1
  12. package/esm/backend.d.ts +3 -3
  13. package/esm/backend.d.ts.map +1 -1
  14. package/esm/commands/base.d.ts +2 -2
  15. package/esm/commands/base.d.ts.map +1 -1
  16. package/esm/commands/base.js +1 -1
  17. package/esm/commands/base.js.map +1 -1
  18. package/esm/commands/framebuffer.d.ts +22 -6
  19. package/esm/commands/framebuffer.d.ts.map +1 -1
  20. package/esm/commands/framebuffer.js +33 -45
  21. package/esm/commands/framebuffer.js.map +1 -1
  22. package/esm/commands/install.d.ts +2 -2
  23. package/esm/commands/install.d.ts.map +1 -1
  24. package/esm/commands/install.js +12 -5
  25. package/esm/commands/install.js.map +1 -1
  26. package/esm/commands/power.d.ts.map +1 -1
  27. package/esm/commands/power.js +13 -9
  28. package/esm/commands/power.js.map +1 -1
  29. package/esm/commands/reverse.d.ts +5 -5
  30. package/esm/commands/reverse.d.ts.map +1 -1
  31. package/esm/commands/reverse.js +20 -18
  32. package/esm/commands/reverse.js.map +1 -1
  33. package/esm/commands/subprocess/command.d.ts +52 -0
  34. package/esm/commands/subprocess/command.d.ts.map +1 -0
  35. package/esm/commands/subprocess/command.js +81 -0
  36. package/esm/commands/subprocess/command.js.map +1 -0
  37. package/esm/commands/subprocess/index.d.ts +1 -53
  38. package/esm/commands/subprocess/index.d.ts.map +1 -1
  39. package/esm/commands/subprocess/index.js +1 -85
  40. package/esm/commands/subprocess/index.js.map +1 -1
  41. package/esm/commands/subprocess/protocols/none.d.ts +5 -5
  42. package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
  43. package/esm/commands/subprocess/protocols/none.js +5 -3
  44. package/esm/commands/subprocess/protocols/none.js.map +1 -1
  45. package/esm/commands/subprocess/protocols/shell.d.ts +4 -4
  46. package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
  47. package/esm/commands/subprocess/protocols/shell.js +28 -20
  48. package/esm/commands/subprocess/protocols/shell.js.map +1 -1
  49. package/esm/commands/subprocess/protocols/types.d.ts +7 -7
  50. package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
  51. package/esm/commands/sync/index.d.ts +1 -1
  52. package/esm/commands/sync/index.d.ts.map +1 -1
  53. package/esm/commands/sync/index.js +1 -1
  54. package/esm/commands/sync/index.js.map +1 -1
  55. package/esm/commands/sync/list.d.ts +7 -7
  56. package/esm/commands/sync/list.d.ts.map +1 -1
  57. package/esm/commands/sync/list.js +34 -50
  58. package/esm/commands/sync/list.js.map +1 -1
  59. package/esm/commands/sync/pull.d.ts +5 -4
  60. package/esm/commands/sync/pull.d.ts.map +1 -1
  61. package/esm/commands/sync/pull.js +21 -22
  62. package/esm/commands/sync/pull.js.map +1 -1
  63. package/esm/commands/sync/push.d.ts +4 -4
  64. package/esm/commands/sync/push.d.ts.map +1 -1
  65. package/esm/commands/sync/push.js +7 -11
  66. package/esm/commands/sync/push.js.map +1 -1
  67. package/esm/commands/sync/request.d.ts +4 -4
  68. package/esm/commands/sync/request.d.ts.map +1 -1
  69. package/esm/commands/sync/request.js +6 -6
  70. package/esm/commands/sync/request.js.map +1 -1
  71. package/esm/commands/sync/response.d.ts +5 -10
  72. package/esm/commands/sync/response.d.ts.map +1 -1
  73. package/esm/commands/sync/response.js +35 -26
  74. package/esm/commands/sync/response.js.map +1 -1
  75. package/esm/commands/sync/stat.d.ts +7 -7
  76. package/esm/commands/sync/stat.d.ts.map +1 -1
  77. package/esm/commands/sync/stat.js +48 -55
  78. package/esm/commands/sync/stat.js.map +1 -1
  79. package/esm/commands/sync/sync.d.ts +7 -7
  80. package/esm/commands/sync/sync.d.ts.map +1 -1
  81. package/esm/commands/sync/sync.js +25 -22
  82. package/esm/commands/sync/sync.js.map +1 -1
  83. package/esm/crypto.d.ts.map +1 -1
  84. package/esm/crypto.js +26 -16
  85. package/esm/crypto.js.map +1 -1
  86. package/esm/index.d.ts +9 -10
  87. package/esm/index.d.ts.map +1 -1
  88. package/esm/index.js +9 -10
  89. package/esm/index.js.map +1 -1
  90. package/esm/packet.d.ts +8 -8
  91. package/esm/packet.d.ts.map +1 -1
  92. package/esm/packet.js +14 -12
  93. package/esm/packet.js.map +1 -1
  94. package/esm/socket/dispatcher.d.ts +11 -6
  95. package/esm/socket/dispatcher.d.ts.map +1 -1
  96. package/esm/socket/dispatcher.js +28 -20
  97. package/esm/socket/dispatcher.js.map +1 -1
  98. package/esm/socket/index.d.ts +1 -1
  99. package/esm/socket/index.d.ts.map +1 -1
  100. package/esm/socket/index.js +1 -1
  101. package/esm/socket/index.js.map +1 -1
  102. package/esm/socket/socket.d.ts +5 -5
  103. package/esm/socket/socket.d.ts.map +1 -1
  104. package/esm/socket/socket.js +37 -17
  105. package/esm/socket/socket.js.map +1 -1
  106. package/esm/utils/auto-reset-event.d.ts +1 -1
  107. package/esm/utils/auto-reset-event.d.ts.map +1 -1
  108. package/esm/utils/auto-reset-event.js +2 -2
  109. package/esm/utils/base64.d.ts +23 -0
  110. package/esm/utils/base64.d.ts.map +1 -1
  111. package/esm/utils/base64.js +36 -29
  112. package/esm/utils/base64.js.map +1 -1
  113. package/package.json +19 -17
  114. package/src/adb.ts +140 -86
  115. package/src/auth.ts +27 -18
  116. package/src/backend.ts +7 -4
  117. package/src/commands/base.ts +3 -2
  118. package/src/commands/framebuffer.ts +48 -47
  119. package/src/commands/install.ts +20 -10
  120. package/src/commands/power.ts +14 -10
  121. package/src/commands/reverse.ts +53 -33
  122. package/src/commands/subprocess/command.ts +134 -0
  123. package/src/commands/subprocess/index.ts +1 -137
  124. package/src/commands/subprocess/protocols/none.ts +10 -6
  125. package/src/commands/subprocess/protocols/shell.ts +72 -39
  126. package/src/commands/subprocess/protocols/types.ts +12 -8
  127. package/src/commands/sync/index.ts +1 -1
  128. package/src/commands/sync/list.ts +63 -68
  129. package/src/commands/sync/pull.ts +53 -37
  130. package/src/commands/sync/push.ts +26 -15
  131. package/src/commands/sync/request.ts +20 -21
  132. package/src/commands/sync/response.ts +63 -53
  133. package/src/commands/sync/stat.ts +91 -90
  134. package/src/commands/sync/sync.ts +56 -34
  135. package/src/crypto.ts +61 -33
  136. package/src/features.ts +1 -1
  137. package/src/index.ts +9 -11
  138. package/src/packet.ts +40 -30
  139. package/src/socket/dispatcher.ts +119 -77
  140. package/src/socket/index.ts +1 -1
  141. package/src/socket/socket.ts +68 -26
  142. package/src/utils/auto-reset-event.ts +3 -3
  143. package/src/utils/base64.ts +75 -42
  144. package/tsconfig.build.json +1 -1
  145. package/tsconfig.build.tsbuildinfo +1 -1
  146. package/esm/stream/buffered.d.ts +0 -39
  147. package/esm/stream/buffered.d.ts.map +0 -1
  148. package/esm/stream/buffered.js +0 -143
  149. package/esm/stream/buffered.js.map +0 -1
  150. package/esm/stream/detect.d.ts +0 -2
  151. package/esm/stream/detect.d.ts.map +0 -1
  152. package/esm/stream/detect.js +0 -6
  153. package/esm/stream/detect.js.map +0 -1
  154. package/esm/stream/detect.native.d.ts +0 -240
  155. package/esm/stream/detect.native.d.ts.map +0 -1
  156. package/esm/stream/detect.native.js +0 -60
  157. package/esm/stream/detect.native.js.map +0 -1
  158. package/esm/stream/detect.polyfill.d.ts +0 -18
  159. package/esm/stream/detect.polyfill.d.ts.map +0 -1
  160. package/esm/stream/detect.polyfill.js +0 -4
  161. package/esm/stream/detect.polyfill.js.map +0 -1
  162. package/esm/stream/index.d.ts +0 -4
  163. package/esm/stream/index.d.ts.map +0 -1
  164. package/esm/stream/index.js +0 -4
  165. package/esm/stream/index.js.map +0 -1
  166. package/esm/stream/transform.d.ts +0 -124
  167. package/esm/stream/transform.d.ts.map +0 -1
  168. package/esm/stream/transform.js +0 -379
  169. package/esm/stream/transform.js.map +0 -1
  170. package/src/stream/buffered.ts +0 -168
  171. package/src/stream/detect.native.ts +0 -362
  172. package/src/stream/detect.polyfill.ts +0 -22
  173. package/src/stream/detect.ts +0 -7
  174. package/src/stream/index.ts +0 -3
  175. package/src/stream/transform.ts +0 -474
  176. package/tsconfig.test.json +0 -9
  177. package/web-streams-polyfill-4.0.0-beta.2.tgz +0 -0
package/src/adb.ts CHANGED
@@ -1,19 +1,50 @@
1
1
  // cspell: ignore libusb
2
2
 
3
- import { PromiseResolver } from '@yume-chan/async';
4
- import { AdbAuthenticationProcessor, ADB_DEFAULT_AUTHENTICATORS, type AdbCredentialStore } from './auth.js';
5
- import { AdbPower, AdbReverseCommand, AdbSubprocess, AdbSync, AdbTcpIpCommand, escapeArg, framebuffer, install, type AdbFrameBuffer } from './commands/index.js';
6
- import { AdbFeatures } from './features.js';
7
- import { AdbCommand, calculateChecksum, type AdbPacketData, type AdbPacketInit } from './packet.js';
8
- import { AdbIncomingSocketHandler, AdbPacketDispatcher, type AdbSocket, type Closeable } from './socket/index.js';
9
- import { AbortController, DecodeUtf8Stream, GatherStringStream, WritableStream, type ReadableWritablePair } from "./stream/index.js";
3
+ import { PromiseResolver } from "@yume-chan/async";
4
+ import {
5
+ AbortController,
6
+ DecodeUtf8Stream,
7
+ GatherStringStream,
8
+ WritableStream,
9
+ type ReadableWritablePair,
10
+ } from "@yume-chan/stream-extra";
11
+
12
+ import {
13
+ ADB_DEFAULT_AUTHENTICATORS,
14
+ AdbAuthenticationProcessor,
15
+ type AdbCredentialStore,
16
+ } from "./auth.js";
17
+ import {
18
+ AdbPower,
19
+ AdbReverseCommand,
20
+ AdbSubprocess,
21
+ AdbSync,
22
+ AdbTcpIpCommand,
23
+ escapeArg,
24
+ framebuffer,
25
+ install,
26
+ type AdbFrameBuffer,
27
+ } from "./commands/index.js";
28
+ import { AdbFeatures } from "./features.js";
29
+ import {
30
+ AdbCommand,
31
+ calculateChecksum,
32
+ type AdbPacketData,
33
+ type AdbPacketInit,
34
+ } from "./packet.js";
35
+ import {
36
+ AdbPacketDispatcher,
37
+ type AdbIncomingSocketHandler,
38
+ type AdbSocket,
39
+ type Closeable,
40
+ } from "./socket/index.js";
10
41
  import { decodeUtf8, encodeUtf8 } from "./utils/index.js";
11
42
 
12
43
  export enum AdbPropKey {
13
- Product = 'ro.product.name',
14
- Model = 'ro.product.model',
15
- Device = 'ro.product.device',
16
- Features = 'features',
44
+ Product = "ro.product.name",
45
+ Model = "ro.product.model",
46
+ Device = "ro.product.device",
47
+ Features = "features",
17
48
  }
18
49
 
19
50
  export const VERSION_OMIT_CHECKSUM = 0x01000001;
@@ -27,44 +58,57 @@ export class Adb implements Closeable {
27
58
  public static async authenticate(
28
59
  connection: ReadableWritablePair<AdbPacketData, AdbPacketInit>,
29
60
  credentialStore: AdbCredentialStore,
30
- authenticators = ADB_DEFAULT_AUTHENTICATORS,
61
+ authenticators = ADB_DEFAULT_AUTHENTICATORS
31
62
  ): Promise<Adb> {
32
63
  // Initially, set to highest-supported version and payload size.
33
64
  let version = 0x01000001;
34
65
  let maxPayloadSize = 0x100000;
35
66
 
36
67
  const resolver = new PromiseResolver<string>();
37
- const authProcessor = new AdbAuthenticationProcessor(authenticators, credentialStore);
68
+ const authProcessor = new AdbAuthenticationProcessor(
69
+ authenticators,
70
+ credentialStore
71
+ );
38
72
 
39
73
  // Here is similar to `AdbPacketDispatcher`,
40
74
  // But the received packet types and send packet processing are different.
41
75
  const abortController = new AbortController();
42
76
  const pipe = connection.readable
43
- .pipeTo(new WritableStream({
44
- async write(packet) {
45
- switch (packet.command) {
46
- case AdbCommand.Connect:
47
- version = Math.min(version, packet.arg0);
48
- maxPayloadSize = Math.min(maxPayloadSize, packet.arg1);
49
- resolver.resolve(decodeUtf8(packet.payload));
50
- break;
51
- case AdbCommand.Auth:
52
- const response = await authProcessor.process(packet);
53
- await sendPacket(response);
54
- break;
55
- default:
56
- // Maybe the previous ADB client exited without reading all packets,
57
- // so they are still waiting in OS internal buffer.
58
- // Just ignore them.
59
- // Because a `Connect` packet will reset the device,
60
- // Eventually there will be `Connect` and `Auth` response packets.
61
- break;
62
- }
77
+ .pipeTo(
78
+ new WritableStream({
79
+ async write(packet) {
80
+ switch (packet.command) {
81
+ case AdbCommand.Connect:
82
+ version = Math.min(version, packet.arg0);
83
+ maxPayloadSize = Math.min(
84
+ maxPayloadSize,
85
+ packet.arg1
86
+ );
87
+ resolver.resolve(decodeUtf8(packet.payload));
88
+ break;
89
+ case AdbCommand.Auth: {
90
+ const response = await authProcessor.process(
91
+ packet
92
+ );
93
+ await sendPacket(response);
94
+ break;
95
+ }
96
+ default:
97
+ // Maybe the previous ADB client exited without reading all packets,
98
+ // so they are still waiting in OS internal buffer.
99
+ // Just ignore them.
100
+ // Because a `Connect` packet will reset the device,
101
+ // Eventually there will be `Connect` and `Auth` response packets.
102
+ break;
103
+ }
104
+ },
105
+ }),
106
+ {
107
+ // Don't cancel the source ReadableStream on AbortSignal abort.
108
+ preventCancel: true,
109
+ signal: abortController.signal,
63
110
  }
64
- }), {
65
- preventCancel: true,
66
- signal: abortController.signal,
67
- })
111
+ )
68
112
  .catch((e) => {
69
113
  resolver.reject(e);
70
114
  });
@@ -86,20 +130,20 @@ export class Adb implements Closeable {
86
130
  AdbFeatures.StatV2,
87
131
  AdbFeatures.ListV2,
88
132
  AdbFeatures.FixedPushMkdir,
89
- 'apex',
90
- 'abb',
133
+ "apex",
134
+ "abb",
91
135
  // only tells the client the symlink timestamp issue in `adb push --sync` has been fixed.
92
136
  // No special handling required.
93
- 'fixed_push_symlink_timestamp',
94
- 'abb_exec',
95
- 'remount_shell',
96
- 'track_app',
97
- 'sendrecv_v2',
98
- 'sendrecv_v2_brotli',
99
- 'sendrecv_v2_lz4',
100
- 'sendrecv_v2_zstd',
101
- 'sendrecv_v2_dry_run_send',
102
- ].join(',');
137
+ "fixed_push_symlink_timestamp",
138
+ "abb_exec",
139
+ "remount_shell",
140
+ "track_app",
141
+ "sendrecv_v2",
142
+ "sendrecv_v2_brotli",
143
+ "sendrecv_v2_lz4",
144
+ "sendrecv_v2_zstd",
145
+ "sendrecv_v2_dry_run_send",
146
+ ].join(",");
103
147
 
104
148
  await sendPacket({
105
149
  command: AdbCommand.Connect,
@@ -121,32 +165,39 @@ export class Adb implements Closeable {
121
165
  await pipe;
122
166
  }
123
167
 
124
- return new Adb(
125
- connection,
126
- version,
127
- maxPayloadSize,
128
- banner,
129
- );
168
+ return new Adb(connection, version, maxPayloadSize, banner);
130
169
  }
131
170
 
132
171
  private readonly dispatcher: AdbPacketDispatcher;
133
172
 
134
- public get disconnected() { return this.dispatcher.disconnected; }
173
+ public get disconnected() {
174
+ return this.dispatcher.disconnected;
175
+ }
135
176
 
136
177
  private _protocolVersion: number | undefined;
137
- public get protocolVersion() { return this._protocolVersion; }
178
+ public get protocolVersion() {
179
+ return this._protocolVersion;
180
+ }
138
181
 
139
182
  private _product: string | undefined;
140
- public get product() { return this._product; }
183
+ public get product() {
184
+ return this._product;
185
+ }
141
186
 
142
187
  private _model: string | undefined;
143
- public get model() { return this._model; }
188
+ public get model() {
189
+ return this._model;
190
+ }
144
191
 
145
192
  private _device: string | undefined;
146
- public get device() { return this._device; }
193
+ public get device() {
194
+ return this._device;
195
+ }
147
196
 
148
- private _features: AdbFeatures[] | undefined;
149
- public get features() { return this._features; }
197
+ private _features: AdbFeatures[] = [];
198
+ public get features() {
199
+ return this._features;
200
+ }
150
201
 
151
202
  public readonly subprocess: AdbSubprocess;
152
203
  public readonly power: AdbPower;
@@ -157,7 +208,7 @@ export class Adb implements Closeable {
157
208
  connection: ReadableWritablePair<AdbPacketData, AdbPacketInit>,
158
209
  version: number,
159
210
  maxPayloadSize: number,
160
- banner: string,
211
+ banner: string
161
212
  ) {
162
213
  this.parseBanner(banner);
163
214
 
@@ -171,14 +222,11 @@ export class Adb implements Closeable {
171
222
  appendNullToServiceString = true;
172
223
  }
173
224
 
174
- this.dispatcher = new AdbPacketDispatcher(
175
- connection,
176
- {
177
- calculateChecksum,
178
- appendNullToServiceString,
179
- maxPayloadSize,
180
- }
181
- );
225
+ this.dispatcher = new AdbPacketDispatcher(connection, {
226
+ calculateChecksum,
227
+ appendNullToServiceString,
228
+ maxPayloadSize,
229
+ });
182
230
 
183
231
  this._protocolVersion = version;
184
232
 
@@ -189,17 +237,15 @@ export class Adb implements Closeable {
189
237
  }
190
238
 
191
239
  private parseBanner(banner: string): void {
192
- this._features = [];
193
-
194
- const pieces = banner.split('::');
240
+ const pieces = banner.split("::");
195
241
  if (pieces.length > 1) {
196
242
  const props = pieces[1]!;
197
- for (const prop of props.split(';')) {
243
+ for (const prop of props.split(";")) {
198
244
  if (!prop) {
199
245
  continue;
200
246
  }
201
247
 
202
- const keyValue = prop.split('=');
248
+ const keyValue = prop.split("=");
203
249
  if (keyValue.length !== 2) {
204
250
  continue;
205
251
  }
@@ -216,15 +262,20 @@ export class Adb implements Closeable {
216
262
  this._device = value;
217
263
  break;
218
264
  case AdbPropKey.Features:
219
- this._features = value!.split(',') as AdbFeatures[];
265
+ this._features = value!.split(",") as AdbFeatures[];
220
266
  break;
221
267
  }
222
268
  }
223
269
  }
224
270
  }
225
271
 
226
- public addIncomingSocketHandler(handler: AdbIncomingSocketHandler) {
227
- return this.dispatcher.addIncomingSocketHandler(handler);
272
+ /**
273
+ * Add a handler for incoming socket.
274
+ * @param handler A function to call with new incoming sockets. It must return `true` if it accepts the socket.
275
+ * @returns A function to remove the handler.
276
+ */
277
+ public onIncomingSocket(handler: AdbIncomingSocketHandler) {
278
+ return this.dispatcher.onIncomingSocket(handler);
228
279
  }
229
280
 
230
281
  public async createSocket(service: string): Promise<AdbSocket> {
@@ -241,16 +292,19 @@ export class Adb implements Closeable {
241
292
  }
242
293
 
243
294
  public async getProp(key: string): Promise<string> {
244
- const stdout = await this.subprocess.spawnAndWaitLegacy(
245
- ['getprop', key]
246
- );
295
+ const stdout = await this.subprocess.spawnAndWaitLegacy([
296
+ "getprop",
297
+ key,
298
+ ]);
247
299
  return stdout.trim();
248
300
  }
249
301
 
250
302
  public async rm(...filenames: string[]): Promise<string> {
251
- const stdout = await this.subprocess.spawnAndWaitLegacy(
252
- ['rm', '-rf', ...filenames.map(arg => escapeArg(arg))],
253
- );
303
+ const stdout = await this.subprocess.spawnAndWaitLegacy([
304
+ "rm",
305
+ "-rf",
306
+ ...filenames.map((arg) => escapeArg(arg)),
307
+ ]);
254
308
  return stdout;
255
309
  }
256
310
 
@@ -259,7 +313,7 @@ export class Adb implements Closeable {
259
313
  }
260
314
 
261
315
  public async sync(): Promise<AdbSync> {
262
- const socket = await this.createSocket('sync:');
316
+ const socket = await this.createSocket("sync:");
263
317
  return new AdbSync(this, socket);
264
318
  }
265
319
 
package/src/auth.ts CHANGED
@@ -1,9 +1,14 @@
1
- import { PromiseResolver } from '@yume-chan/async';
2
- import type { Disposable } from '@yume-chan/event';
3
- import type { ValueOrPromise } from '@yume-chan/struct';
4
- import { calculatePublicKey, calculatePublicKeyLength, sign } from './crypto.js';
5
- import { AdbCommand, type AdbPacketData } from './packet.js';
6
- import { calculateBase64EncodedLength, encodeBase64 } from './utils/index.js';
1
+ import { PromiseResolver } from "@yume-chan/async";
2
+ import { type Disposable } from "@yume-chan/event";
3
+ import { type ValueOrPromise } from "@yume-chan/struct";
4
+
5
+ import {
6
+ calculatePublicKey,
7
+ calculatePublicKeyLength,
8
+ sign,
9
+ } from "./crypto.js";
10
+ import { AdbCommand, type AdbPacketData } from "./packet.js";
11
+ import { calculateBase64EncodedLength, encodeBase64 } from "./utils/index.js";
7
12
 
8
13
  export type AdbKeyIterable = Iterable<Uint8Array> | AsyncIterable<Uint8Array>;
9
14
 
@@ -49,7 +54,7 @@ export interface AdbAuthenticator {
49
54
 
50
55
  export const AdbSignatureAuthenticator: AdbAuthenticator = async function* (
51
56
  credentialStore: AdbCredentialStore,
52
- getNextRequest: () => Promise<AdbPacketData>,
57
+ getNextRequest: () => Promise<AdbPacketData>
53
58
  ): AsyncIterable<AdbPacketData> {
54
59
  for await (const key of credentialStore.iterateKeys()) {
55
60
  const packet = await getNextRequest();
@@ -70,7 +75,7 @@ export const AdbSignatureAuthenticator: AdbAuthenticator = async function* (
70
75
 
71
76
  export const AdbPublicKeyAuthenticator: AdbAuthenticator = async function* (
72
77
  credentialStore: AdbCredentialStore,
73
- getNextRequest: () => Promise<AdbPacketData>,
78
+ getNextRequest: () => Promise<AdbPacketData>
74
79
  ): AsyncIterable<AdbPacketData> {
75
80
  const packet = await getNextRequest();
76
81
 
@@ -84,23 +89,20 @@ export const AdbPublicKeyAuthenticator: AdbAuthenticator = async function* (
84
89
  break;
85
90
  }
86
91
 
87
-
88
92
  if (!privateKey) {
89
93
  privateKey = await credentialStore.generateKey();
90
94
  }
91
95
 
92
96
  const publicKeyLength = calculatePublicKeyLength();
93
- const [publicKeyBase64Length] = calculateBase64EncodedLength(publicKeyLength);
97
+ const [publicKeyBase64Length] =
98
+ calculateBase64EncodedLength(publicKeyLength);
94
99
 
95
100
  // The public key is null terminated,
96
101
  // So we allocate the buffer with one extra byte.
97
102
  const publicKeyBuffer = new Uint8Array(publicKeyBase64Length + 1);
98
103
 
99
104
  calculatePublicKey(privateKey, publicKeyBuffer);
100
- encodeBase64(
101
- publicKeyBuffer.subarray(0, publicKeyLength),
102
- publicKeyBuffer
103
- );
105
+ encodeBase64(publicKeyBuffer.subarray(0, publicKeyLength), publicKeyBuffer);
104
106
 
105
107
  yield {
106
108
  command: AdbCommand.Auth,
@@ -136,9 +138,16 @@ export class AdbAuthenticationProcessor implements Disposable {
136
138
  return this.pendingRequest.promise;
137
139
  };
138
140
 
139
- private async* invokeAuthenticator(): AsyncGenerator<AdbPacketData, void, void> {
141
+ private async *invokeAuthenticator(): AsyncGenerator<
142
+ AdbPacketData,
143
+ void,
144
+ void
145
+ > {
140
146
  for (const authenticator of this.authenticators) {
141
- for await (const packet of authenticator(this.credentialStore, this.getNextRequest)) {
147
+ for await (const packet of authenticator(
148
+ this.credentialStore,
149
+ this.getNextRequest
150
+ )) {
142
151
  // If the authenticator yielded a response
143
152
  // Prepare `nextRequest` for next authentication request
144
153
  this.pendingRequest = new PromiseResolver();
@@ -161,13 +170,13 @@ export class AdbAuthenticationProcessor implements Disposable {
161
170
 
162
171
  const result = await this.iterator.next();
163
172
  if (result.done) {
164
- throw new Error('No authenticator can handle the request');
173
+ throw new Error("No authenticator can handle the request");
165
174
  }
166
175
 
167
176
  return result.value;
168
177
  }
169
178
 
170
179
  public dispose() {
171
- this.iterator?.return?.();
180
+ void this.iterator?.return?.();
172
181
  }
173
182
  }
package/src/backend.ts CHANGED
@@ -1,11 +1,14 @@
1
- import type { ValueOrPromise } from '@yume-chan/struct';
2
- import type { AdbPacketData, AdbPacketInit } from "./packet.js";
3
- import type { ReadableWritablePair } from "./stream/index.js";
1
+ import { type ReadableWritablePair } from "@yume-chan/stream-extra";
2
+ import { type ValueOrPromise } from "@yume-chan/struct";
3
+
4
+ import { type AdbPacketData, type AdbPacketInit } from "./packet.js";
4
5
 
5
6
  export interface AdbBackend {
6
7
  readonly serial: string;
7
8
 
8
9
  readonly name: string | undefined;
9
10
 
10
- connect(): ValueOrPromise<ReadableWritablePair<AdbPacketData, AdbPacketInit>>;
11
+ connect(): ValueOrPromise<
12
+ ReadableWritablePair<AdbPacketData, AdbPacketInit>
13
+ >;
11
14
  }
@@ -1,5 +1,6 @@
1
- import { AutoDisposable } from '@yume-chan/event';
2
- import type { Adb } from '../adb.js';
1
+ import { AutoDisposable } from "@yume-chan/event";
2
+
3
+ import { type Adb } from "../adb.js";
3
4
 
4
5
  export class AdbCommandBase extends AutoDisposable {
5
6
  protected adb: Adb;
@@ -1,14 +1,50 @@
1
+ import { BufferedReadableStream } from "@yume-chan/stream-extra";
1
2
  import Struct from "@yume-chan/struct";
2
- import type { Adb } from '../adb.js';
3
- import { AdbBufferedStream } from '../stream/index.js';
4
3
 
5
- const Version =
6
- new Struct({ littleEndian: true })
7
- .uint32('version');
4
+ import { type Adb } from "../adb.js";
8
5
 
9
- /*
6
+ const Version = new Struct({ littleEndian: true }).uint32("version");
7
+
8
+ export const AdbFrameBufferV1 = new Struct({ littleEndian: true })
9
+ .uint32("bpp")
10
+ .uint32("size")
11
+ .uint32("width")
12
+ .uint32("height")
13
+ .uint32("red_offset")
14
+ .uint32("red_length")
15
+ .uint32("blue_offset")
16
+ .uint32("blue_length")
17
+ .uint32("green_offset")
18
+ .uint32("green_length")
19
+ .uint32("alpha_offset")
20
+ .uint32("alpha_length")
21
+ .uint8Array("data", { lengthField: "size" });
22
+
23
+ export type AdbFrameBufferV1 = typeof AdbFrameBufferV1["TDeserializeResult"];
24
+
25
+ export const AdbFrameBufferV2 = new Struct({ littleEndian: true })
26
+ .uint32("bpp")
27
+ .uint32("colorSpace")
28
+ .uint32("size")
29
+ .uint32("width")
30
+ .uint32("height")
31
+ .uint32("red_offset")
32
+ .uint32("red_length")
33
+ .uint32("blue_offset")
34
+ .uint32("blue_length")
35
+ .uint32("green_offset")
36
+ .uint32("green_length")
37
+ .uint32("alpha_offset")
38
+ .uint32("alpha_length")
39
+ .uint8Array("data", { lengthField: "size" });
40
+
41
+ export type AdbFrameBufferV2 = typeof AdbFrameBufferV2["TDeserializeResult"];
42
+
43
+ /**
10
44
  * ADB uses 8 int32 fields to describe bit depths
45
+ *
11
46
  * The only combination I have seen is RGBA8888, which is
47
+ *
12
48
  * red_offset: 0
13
49
  * red_length: 8
14
50
  * blue_offset: 16
@@ -17,57 +53,22 @@ const Version =
17
53
  * green_length: 8
18
54
  * alpha_offset: 24
19
55
  * alpha_length: 8
56
+ *
57
+ * But it doesn't mean that other combinations are not possible.
20
58
  */
21
-
22
- export const AdbFrameBufferV1 =
23
- new Struct({ littleEndian: true })
24
- .uint32('bpp')
25
- .uint32('size')
26
- .uint32('width')
27
- .uint32('height')
28
- .uint32('red_offset')
29
- .uint32('red_length')
30
- .uint32('blue_offset')
31
- .uint32('blue_length')
32
- .uint32('green_offset')
33
- .uint32('green_length')
34
- .uint32('alpha_offset')
35
- .uint32('alpha_length')
36
- .uint8Array('data', { lengthField: 'size' });
37
-
38
- export type AdbFrameBufferV1 = typeof AdbFrameBufferV1['TDeserializeResult'];
39
-
40
- export const AdbFrameBufferV2 =
41
- new Struct({ littleEndian: true })
42
- .uint32('bpp')
43
- .uint32('colorSpace')
44
- .uint32('size')
45
- .uint32('width')
46
- .uint32('height')
47
- .uint32('red_offset')
48
- .uint32('red_length')
49
- .uint32('blue_offset')
50
- .uint32('blue_length')
51
- .uint32('green_offset')
52
- .uint32('green_length')
53
- .uint32('alpha_offset')
54
- .uint32('alpha_length')
55
- .uint8Array('data', { lengthField: 'size' });
56
-
57
- export type AdbFrameBufferV2 = typeof AdbFrameBufferV2['TDeserializeResult'];
58
-
59
59
  export type AdbFrameBuffer = AdbFrameBufferV1 | AdbFrameBufferV2;
60
60
 
61
61
  export async function framebuffer(adb: Adb): Promise<AdbFrameBuffer> {
62
- const socket = await adb.createSocket('framebuffer:');
63
- const stream = new AdbBufferedStream(socket);
62
+ const socket = await adb.createSocket("framebuffer:");
63
+ const stream = new BufferedReadableStream(socket.readable);
64
64
  const { version } = await Version.deserialize(stream);
65
65
  switch (version) {
66
66
  case 1:
67
+ // TODO: AdbFrameBuffer: does all v1 responses uses the same color space? Add it so the command returns same format for all versions.
67
68
  return AdbFrameBufferV1.deserialize(stream);
68
69
  case 2:
69
70
  return AdbFrameBufferV2.deserialize(stream);
70
71
  default:
71
- throw new Error('Unknown FrameBuffer version');
72
+ throw new Error("Unknown FrameBuffer version");
72
73
  }
73
74
  }
@@ -1,30 +1,40 @@
1
- import type { Adb } from "../adb.js";
2
- import { WrapWritableStream, WritableStream } from "../stream/index.js";
1
+ import {
2
+ WrapWritableStream,
3
+ type WritableStream,
4
+ } from "@yume-chan/stream-extra";
5
+
6
+ import { type Adb } from "../adb.js";
7
+
3
8
  import { escapeArg } from "./subprocess/index.js";
4
- import type { AdbSync } from "./sync/index.js";
9
+ import { type AdbSync } from "./sync/index.js";
5
10
 
6
- export function install(
7
- adb: Adb,
8
- ): WritableStream<Uint8Array> {
9
- const filename = `/data/local/tmp/${Math.random().toString().substring(2)}.apk`;
11
+ export function install(adb: Adb): WritableStream<Uint8Array> {
12
+ const filename = `/data/local/tmp/${Math.random()
13
+ .toString()
14
+ .substring(2)}.apk`;
10
15
 
11
16
  let sync!: AdbSync;
12
17
  return new WrapWritableStream<Uint8Array>({
13
18
  async start() {
14
19
  // TODO: install: support other install apk methods (streaming, etc.)
20
+ // TODO: install: support split apk formats (`adb install-multiple`)
15
21
 
16
22
  // Upload apk file to tmp folder
17
23
  sync = await adb.sync();
18
24
  return sync.write(filename, undefined, undefined);
19
25
  },
20
26
  async close() {
21
- sync.dispose();
27
+ await sync.dispose();
22
28
 
23
29
  // Invoke `pm install` to install it
24
- await adb.subprocess.spawnAndWaitLegacy(['pm', 'install', escapeArg(filename)]);
30
+ await adb.subprocess.spawnAndWaitLegacy([
31
+ "pm",
32
+ "install",
33
+ escapeArg(filename),
34
+ ]);
25
35
 
26
36
  // Remove the temp file
27
37
  await adb.rm(filename);
28
- }
38
+ },
29
39
  });
30
40
  }