@yume-chan/adb 0.0.22 → 0.0.24
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 +51 -0
- package/CHANGELOG.md +24 -1
- package/LICENSE +1 -1
- package/esm/adb.d.ts +6 -3
- package/esm/adb.d.ts.map +1 -1
- package/esm/adb.js +11 -4
- package/esm/adb.js.map +1 -1
- package/esm/banner.d.ts.map +1 -1
- package/esm/banner.js +1 -0
- package/esm/banner.js.map +1 -1
- package/esm/commands/power.d.ts.map +1 -1
- package/esm/commands/power.js +6 -5
- package/esm/commands/power.js.map +1 -1
- package/esm/commands/reverse.d.ts.map +1 -1
- package/esm/commands/reverse.js +23 -11
- package/esm/commands/reverse.js.map +1 -1
- package/esm/commands/subprocess/command.js +3 -3
- package/esm/commands/subprocess/command.js.map +1 -1
- package/esm/commands/subprocess/protocols/none.d.ts +2 -2
- package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/shell.d.ts +3 -3
- package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/shell.js +14 -69
- package/esm/commands/subprocess/protocols/shell.js.map +1 -1
- package/esm/commands/subprocess/protocols/types.d.ts +2 -2
- package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
- package/esm/commands/subprocess/utils.js +1 -1
- package/esm/commands/subprocess/utils.js.map +1 -1
- package/esm/commands/sync/list.d.ts +2 -5
- package/esm/commands/sync/list.d.ts.map +1 -1
- package/esm/commands/sync/list.js +2 -4
- package/esm/commands/sync/list.js.map +1 -1
- package/esm/commands/sync/pull.d.ts +1 -4
- package/esm/commands/sync/pull.d.ts.map +1 -1
- package/esm/commands/sync/pull.js +2 -2
- package/esm/commands/sync/pull.js.map +1 -1
- package/esm/commands/sync/push.d.ts +4 -7
- package/esm/commands/sync/push.d.ts.map +1 -1
- package/esm/commands/sync/push.js +3 -6
- package/esm/commands/sync/push.js.map +1 -1
- package/esm/commands/sync/request.d.ts +13 -18
- package/esm/commands/sync/request.d.ts.map +1 -1
- package/esm/commands/sync/request.js +23 -28
- package/esm/commands/sync/request.js.map +1 -1
- package/esm/commands/sync/response.d.ts +18 -12
- package/esm/commands/sync/response.d.ts.map +1 -1
- package/esm/commands/sync/response.js +39 -17
- package/esm/commands/sync/response.js.map +1 -1
- package/esm/commands/sync/socket.d.ts +2 -2
- package/esm/commands/sync/socket.d.ts.map +1 -1
- package/esm/commands/sync/socket.js +10 -5
- package/esm/commands/sync/socket.js.map +1 -1
- package/esm/commands/sync/stat.d.ts +0 -3
- package/esm/commands/sync/stat.d.ts.map +1 -1
- package/esm/commands/sync/stat.js +0 -2
- package/esm/commands/sync/stat.js.map +1 -1
- package/esm/commands/sync/sync.d.ts +4 -3
- package/esm/commands/sync/sync.d.ts.map +1 -1
- package/esm/commands/sync/sync.js +9 -7
- package/esm/commands/sync/sync.js.map +1 -1
- package/esm/commands/tcpip.js +1 -1
- package/esm/commands/tcpip.js.map +1 -1
- package/esm/daemon/auth.js +1 -1
- package/esm/daemon/auth.js.map +1 -1
- package/esm/daemon/crypto.d.ts +3 -2
- package/esm/daemon/crypto.d.ts.map +1 -1
- package/esm/daemon/crypto.js +56 -49
- package/esm/daemon/crypto.js.map +1 -1
- package/esm/daemon/dispatcher.d.ts +38 -6
- package/esm/daemon/dispatcher.d.ts.map +1 -1
- package/esm/daemon/dispatcher.js +86 -28
- package/esm/daemon/dispatcher.js.map +1 -1
- package/esm/daemon/packet.d.ts +2 -2
- package/esm/daemon/packet.d.ts.map +1 -1
- package/esm/daemon/packet.js +13 -12
- package/esm/daemon/packet.js.map +1 -1
- package/esm/daemon/socket.d.ts +11 -6
- package/esm/daemon/socket.d.ts.map +1 -1
- package/esm/daemon/socket.js +42 -12
- package/esm/daemon/socket.js.map +1 -1
- package/esm/daemon/transport.d.ts +75 -11
- package/esm/daemon/transport.d.ts.map +1 -1
- package/esm/daemon/transport.js +60 -33
- package/esm/daemon/transport.js.map +1 -1
- package/esm/features.d.ts +2 -1
- package/esm/features.d.ts.map +1 -1
- package/esm/features.js +2 -1
- package/esm/features.js.map +1 -1
- package/esm/server/client.d.ts +128 -48
- package/esm/server/client.d.ts.map +1 -1
- package/esm/server/client.js +378 -145
- package/esm/server/client.js.map +1 -1
- package/esm/server/transport.d.ts +3 -0
- package/esm/server/transport.d.ts.map +1 -1
- package/esm/server/transport.js +30 -4
- package/esm/server/transport.js.map +1 -1
- package/esm/utils/base64.d.ts.map +1 -1
- package/esm/utils/base64.js +33 -22
- package/esm/utils/base64.js.map +1 -1
- package/esm/utils/hex.d.ts +1 -1
- package/esm/utils/hex.d.ts.map +1 -1
- package/esm/utils/hex.js +12 -14
- package/esm/utils/hex.js.map +1 -1
- package/esm/utils/index.d.ts +1 -1
- package/esm/utils/index.d.ts.map +1 -1
- package/esm/utils/index.js +1 -1
- package/esm/utils/index.js.map +1 -1
- package/esm/utils/sequence-equal.d.ts +2 -0
- package/esm/utils/sequence-equal.d.ts.map +1 -0
- package/esm/utils/sequence-equal.js +12 -0
- package/esm/utils/sequence-equal.js.map +1 -0
- package/package.json +13 -15
- package/src/adb.ts +22 -6
- package/src/banner.ts +1 -0
- package/src/commands/power.ts +7 -5
- package/src/commands/reverse.ts +31 -18
- package/src/commands/subprocess/command.ts +3 -3
- package/src/commands/subprocess/protocols/none.ts +2 -2
- package/src/commands/subprocess/protocols/shell.ts +21 -100
- package/src/commands/subprocess/protocols/types.ts +2 -2
- package/src/commands/subprocess/utils.ts +1 -1
- package/src/commands/sync/list.ts +2 -4
- package/src/commands/sync/pull.ts +2 -2
- package/src/commands/sync/push.ts +7 -10
- package/src/commands/sync/request.ts +32 -32
- package/src/commands/sync/response.ts +47 -20
- package/src/commands/sync/socket.ts +13 -8
- package/src/commands/sync/stat.ts +0 -2
- package/src/commands/sync/sync.ts +13 -9
- package/src/commands/tcpip.ts +1 -1
- package/src/daemon/auth.ts +1 -1
- package/src/daemon/crypto.ts +64 -55
- package/src/daemon/dispatcher.ts +175 -37
- package/src/daemon/packet.ts +21 -14
- package/src/daemon/socket.ts +62 -28
- package/src/daemon/transport.ts +145 -40
- package/src/features.ts +2 -1
- package/src/server/client.ts +472 -224
- package/src/server/transport.ts +32 -4
- package/src/utils/base64.ts +33 -22
- package/src/utils/hex.ts +16 -14
- package/src/utils/index.ts +1 -1
- package/src/utils/sequence-equal.ts +13 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/esm/utils/conditional-variable.d.ts +0 -8
- package/esm/utils/conditional-variable.d.ts.map +0 -1
- package/esm/utils/conditional-variable.js +0 -34
- package/esm/utils/conditional-variable.js.map +0 -1
- package/src/utils/conditional-variable.ts +0 -45
package/src/daemon/transport.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PromiseResolver } from "@yume-chan/async";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ReadableWritablePair } from "@yume-chan/stream-extra";
|
|
3
3
|
import {
|
|
4
4
|
AbortController,
|
|
5
|
-
|
|
5
|
+
Consumable,
|
|
6
6
|
WritableStream,
|
|
7
7
|
} from "@yume-chan/stream-extra";
|
|
8
8
|
import type { ValueOrPromise } from "@yume-chan/struct";
|
|
@@ -26,22 +26,82 @@ import type { AdbPacketData, AdbPacketInit } from "./packet.js";
|
|
|
26
26
|
import { AdbCommand, calculateChecksum } from "./packet.js";
|
|
27
27
|
|
|
28
28
|
export const ADB_DAEMON_VERSION_OMIT_CHECKSUM = 0x01000001;
|
|
29
|
+
// https://android.googlesource.com/platform/packages/modules/adb/+/79010dc6d5ca7490c493df800d4421730f5466ca/transport.cpp#1252
|
|
30
|
+
// There are some other feature constants, but some of them are only used by ADB server, not devices (daemons).
|
|
31
|
+
export const ADB_DAEMON_DEFAULT_FEATURES = [
|
|
32
|
+
AdbFeature.ShellV2,
|
|
33
|
+
AdbFeature.Cmd,
|
|
34
|
+
AdbFeature.StatV2,
|
|
35
|
+
AdbFeature.ListV2,
|
|
36
|
+
AdbFeature.FixedPushMkdir,
|
|
37
|
+
"apex",
|
|
38
|
+
AdbFeature.Abb,
|
|
39
|
+
// only tells the client the symlink timestamp issue in `adb push --sync` has been fixed.
|
|
40
|
+
// No special handling required.
|
|
41
|
+
"fixed_push_symlink_timestamp",
|
|
42
|
+
AdbFeature.AbbExec,
|
|
43
|
+
"remount_shell",
|
|
44
|
+
"track_app",
|
|
45
|
+
AdbFeature.SendReceiveV2,
|
|
46
|
+
"sendrecv_v2_brotli",
|
|
47
|
+
"sendrecv_v2_lz4",
|
|
48
|
+
"sendrecv_v2_zstd",
|
|
49
|
+
"sendrecv_v2_dry_run_send",
|
|
50
|
+
AdbFeature.DelayedAck,
|
|
51
|
+
] as AdbFeature[];
|
|
52
|
+
export const ADB_DAEMON_DEFAULT_INITIAL_PAYLOAD_SIZE = 32 * 1024 * 1024;
|
|
29
53
|
|
|
30
54
|
export type AdbDaemonConnection = ReadableWritablePair<
|
|
31
55
|
AdbPacketData,
|
|
32
56
|
Consumable<AdbPacketInit>
|
|
33
57
|
>;
|
|
34
58
|
|
|
35
|
-
interface AdbDaemonAuthenticationOptions {
|
|
59
|
+
export interface AdbDaemonAuthenticationOptions {
|
|
36
60
|
serial: string;
|
|
37
61
|
connection: AdbDaemonConnection;
|
|
38
62
|
credentialStore: AdbCredentialStore;
|
|
39
63
|
authenticators?: AdbAuthenticator[];
|
|
64
|
+
features?: readonly AdbFeature[];
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The number of bytes the device can send before receiving an ack packet.
|
|
68
|
+
* Using delayed ack can improve the throughput,
|
|
69
|
+
* especially when the device is connected over Wi-Fi (so the latency is higher).
|
|
70
|
+
*
|
|
71
|
+
* Set to 0 or any negative value to disable delayed ack in handshake.
|
|
72
|
+
* Otherwise the value must be in the range of unsigned 32-bit integer.
|
|
73
|
+
*
|
|
74
|
+
* Delayed ack was added in Android 14,
|
|
75
|
+
* this option will be ignored when the device doesn't support it.
|
|
76
|
+
*
|
|
77
|
+
* @default ADB_DAEMON_DEFAULT_INITIAL_PAYLOAD_SIZE
|
|
78
|
+
*/
|
|
79
|
+
initialDelayedAckBytes?: number;
|
|
80
|
+
|
|
40
81
|
/**
|
|
41
|
-
* Whether to
|
|
82
|
+
* Whether to keep the `connection` open (don't call `writable.close` and `readable.cancel`)
|
|
83
|
+
* when `AdbDaemonTransport.close` is called.
|
|
84
|
+
*
|
|
85
|
+
* Note that when `authenticate` fails,
|
|
86
|
+
* no matter which value this option has,
|
|
87
|
+
* the `connection` is always kept open, so it can be used in another `authenticate` call.
|
|
88
|
+
*
|
|
89
|
+
* @default false
|
|
42
90
|
*/
|
|
43
91
|
preserveConnection?: boolean | undefined;
|
|
44
|
-
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* When set, the transport will throw an error when
|
|
95
|
+
* one of the socket readable stalls for this amount of milliseconds.
|
|
96
|
+
*
|
|
97
|
+
* Because ADB is a multiplexed protocol, blocking one socket will also block all other sockets.
|
|
98
|
+
* It's important to always read from all sockets to prevent stalling.
|
|
99
|
+
*
|
|
100
|
+
* This option is helpful to detect bugs in the client code.
|
|
101
|
+
*
|
|
102
|
+
* @default undefined
|
|
103
|
+
*/
|
|
104
|
+
readTimeLimit?: number | undefined;
|
|
45
105
|
}
|
|
46
106
|
|
|
47
107
|
interface AdbDaemonSocketConnectorConstructionOptions {
|
|
@@ -50,11 +110,40 @@ interface AdbDaemonSocketConnectorConstructionOptions {
|
|
|
50
110
|
version: number;
|
|
51
111
|
maxPayloadSize: number;
|
|
52
112
|
banner: string;
|
|
113
|
+
features?: readonly AdbFeature[];
|
|
114
|
+
|
|
53
115
|
/**
|
|
54
|
-
*
|
|
116
|
+
* The number of bytes the device can send before receiving an ack packet.
|
|
117
|
+
* Using delayed ack can improve the throughput,
|
|
118
|
+
* especially when the device is connected over Wi-Fi (so the latency is higher).
|
|
119
|
+
*
|
|
120
|
+
* When `features` doesn't include `AdbFeature.DelayedAck`, it must be set to 0. Otherwise,
|
|
121
|
+
* the value must be in the range of unsigned 32-bit integer. If the device enabled
|
|
122
|
+
* delayed ack but the client didn't, the device will throw an error when the client sends
|
|
123
|
+
* the first data packet. And vice versa.
|
|
124
|
+
*/
|
|
125
|
+
initialDelayedAckBytes: number;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Whether to keep the `connection` open (don't call `writable.close` and `readable.cancel`)
|
|
129
|
+
* when `AdbDaemonTransport.close` is called.
|
|
130
|
+
*
|
|
131
|
+
* @default false
|
|
55
132
|
*/
|
|
56
133
|
preserveConnection?: boolean | undefined;
|
|
57
|
-
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* When set, the transport will throw an error when
|
|
137
|
+
* one of the socket readable stalls for this amount of milliseconds.
|
|
138
|
+
*
|
|
139
|
+
* Because ADB is a multiplexed protocol, blocking one socket will also block all other sockets.
|
|
140
|
+
* It's important to always read from all sockets to prevent stalling.
|
|
141
|
+
*
|
|
142
|
+
* This option is helpful to detect bugs in the client code.
|
|
143
|
+
*
|
|
144
|
+
* @default undefined
|
|
145
|
+
*/
|
|
146
|
+
readTimeLimit?: number | undefined;
|
|
58
147
|
}
|
|
59
148
|
|
|
60
149
|
export class AdbDaemonTransport implements AdbTransport {
|
|
@@ -62,15 +151,17 @@ export class AdbDaemonTransport implements AdbTransport {
|
|
|
62
151
|
* Authenticates the connection and creates an `AdbDaemonTransport` instance
|
|
63
152
|
* that can be used by `Adb` class.
|
|
64
153
|
*
|
|
65
|
-
* If an authentication process failed,
|
|
66
|
-
*
|
|
67
|
-
*
|
|
154
|
+
* If an authentication process failed,
|
|
155
|
+
* no matter which value the `preserveConnection` option has,
|
|
156
|
+
* the `connection` is always kept open, so it can be used in another `authenticate` call.
|
|
68
157
|
*/
|
|
69
158
|
static async authenticate({
|
|
70
159
|
serial,
|
|
71
160
|
connection,
|
|
72
161
|
credentialStore,
|
|
73
162
|
authenticators = ADB_DEFAULT_AUTHENTICATORS,
|
|
163
|
+
features = ADB_DAEMON_DEFAULT_FEATURES,
|
|
164
|
+
initialDelayedAckBytes = ADB_DAEMON_DEFAULT_INITIAL_PAYLOAD_SIZE,
|
|
74
165
|
...options
|
|
75
166
|
}: AdbDaemonAuthenticationOptions): Promise<AdbDaemonTransport> {
|
|
76
167
|
// Initially, set to highest-supported version and payload size.
|
|
@@ -124,11 +215,10 @@ export class AdbDaemonTransport implements AdbTransport {
|
|
|
124
215
|
)
|
|
125
216
|
.then(
|
|
126
217
|
() => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
218
|
+
// If `resolver` is already settled, call `reject` won't do anything.
|
|
219
|
+
resolver.reject(
|
|
220
|
+
new Error("Connection closed unexpectedly"),
|
|
221
|
+
);
|
|
132
222
|
},
|
|
133
223
|
(e) => {
|
|
134
224
|
resolver.reject(e);
|
|
@@ -141,41 +231,31 @@ export class AdbDaemonTransport implements AdbTransport {
|
|
|
141
231
|
// Because we don't know if the device needs it or not.
|
|
142
232
|
(init as AdbPacketInit).checksum = calculateChecksum(init.payload);
|
|
143
233
|
(init as AdbPacketInit).magic = init.command ^ 0xffffffff;
|
|
144
|
-
await
|
|
234
|
+
await Consumable.WritableStream.write(
|
|
235
|
+
writer,
|
|
236
|
+
init as AdbPacketInit,
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const actualFeatures = features.slice();
|
|
241
|
+
if (initialDelayedAckBytes <= 0) {
|
|
242
|
+
const index = features.indexOf(AdbFeature.DelayedAck);
|
|
243
|
+
if (index !== -1) {
|
|
244
|
+
actualFeatures.splice(index, 1);
|
|
245
|
+
}
|
|
145
246
|
}
|
|
146
247
|
|
|
147
248
|
let banner: string;
|
|
148
249
|
try {
|
|
149
|
-
// https://android.googlesource.com/platform/packages/modules/adb/+/79010dc6d5ca7490c493df800d4421730f5466ca/transport.cpp#1252
|
|
150
|
-
// There are some other feature constants, but some of them are only used by ADB server, not devices (daemons).
|
|
151
|
-
const features = [
|
|
152
|
-
AdbFeature.ShellV2,
|
|
153
|
-
AdbFeature.Cmd,
|
|
154
|
-
AdbFeature.StatV2,
|
|
155
|
-
AdbFeature.ListV2,
|
|
156
|
-
AdbFeature.FixedPushMkdir,
|
|
157
|
-
"apex",
|
|
158
|
-
AdbFeature.Abb,
|
|
159
|
-
// only tells the client the symlink timestamp issue in `adb push --sync` has been fixed.
|
|
160
|
-
// No special handling required.
|
|
161
|
-
"fixed_push_symlink_timestamp",
|
|
162
|
-
AdbFeature.AbbExec,
|
|
163
|
-
"remount_shell",
|
|
164
|
-
"track_app",
|
|
165
|
-
AdbFeature.SendReceiveV2,
|
|
166
|
-
"sendrecv_v2_brotli",
|
|
167
|
-
"sendrecv_v2_lz4",
|
|
168
|
-
"sendrecv_v2_zstd",
|
|
169
|
-
"sendrecv_v2_dry_run_send",
|
|
170
|
-
].join(",");
|
|
171
|
-
|
|
172
250
|
await sendPacket({
|
|
173
251
|
command: AdbCommand.Connect,
|
|
174
252
|
arg0: version,
|
|
175
253
|
arg1: maxPayloadSize,
|
|
176
254
|
// The terminating `;` is required in formal definition
|
|
177
255
|
// But ADB daemon (all versions) can still work without it
|
|
178
|
-
payload: encodeUtf8(
|
|
256
|
+
payload: encodeUtf8(
|
|
257
|
+
`host::features=${actualFeatures.join(",")}`,
|
|
258
|
+
),
|
|
179
259
|
});
|
|
180
260
|
|
|
181
261
|
banner = await resolver.promise;
|
|
@@ -195,6 +275,8 @@ export class AdbDaemonTransport implements AdbTransport {
|
|
|
195
275
|
version,
|
|
196
276
|
maxPayloadSize,
|
|
197
277
|
banner,
|
|
278
|
+
features: actualFeatures,
|
|
279
|
+
initialDelayedAckBytes,
|
|
198
280
|
...options,
|
|
199
281
|
});
|
|
200
282
|
}
|
|
@@ -229,16 +311,38 @@ export class AdbDaemonTransport implements AdbTransport {
|
|
|
229
311
|
return this.#dispatcher.disconnected;
|
|
230
312
|
}
|
|
231
313
|
|
|
314
|
+
#clientFeatures: readonly AdbFeature[];
|
|
315
|
+
get clientFeatures() {
|
|
316
|
+
return this.#clientFeatures;
|
|
317
|
+
}
|
|
318
|
+
|
|
232
319
|
constructor({
|
|
233
320
|
serial,
|
|
234
321
|
connection,
|
|
235
322
|
version,
|
|
236
323
|
banner,
|
|
324
|
+
features = ADB_DAEMON_DEFAULT_FEATURES,
|
|
325
|
+
initialDelayedAckBytes,
|
|
237
326
|
...options
|
|
238
327
|
}: AdbDaemonSocketConnectorConstructionOptions) {
|
|
239
328
|
this.#serial = serial;
|
|
240
329
|
this.#connection = connection;
|
|
241
330
|
this.#banner = AdbBanner.parse(banner);
|
|
331
|
+
this.#clientFeatures = features;
|
|
332
|
+
|
|
333
|
+
if (features.includes(AdbFeature.DelayedAck)) {
|
|
334
|
+
if (initialDelayedAckBytes <= 0) {
|
|
335
|
+
throw new TypeError(
|
|
336
|
+
"`initialDelayedAckBytes` must be greater than 0 when DelayedAck feature is enabled.",
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (!this.#banner.features.includes(AdbFeature.DelayedAck)) {
|
|
341
|
+
initialDelayedAckBytes = 0;
|
|
342
|
+
}
|
|
343
|
+
} else {
|
|
344
|
+
initialDelayedAckBytes = 0;
|
|
345
|
+
}
|
|
242
346
|
|
|
243
347
|
let calculateChecksum: boolean;
|
|
244
348
|
let appendNullToServiceString: boolean;
|
|
@@ -253,6 +357,7 @@ export class AdbDaemonTransport implements AdbTransport {
|
|
|
253
357
|
this.#dispatcher = new AdbPacketDispatcher(connection, {
|
|
254
358
|
calculateChecksum,
|
|
255
359
|
appendNullToServiceString,
|
|
360
|
+
initialDelayedAckBytes,
|
|
256
361
|
...options,
|
|
257
362
|
});
|
|
258
363
|
|
package/src/features.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// The order follows
|
|
2
|
-
// https://android.
|
|
2
|
+
// https://cs.android.com/android/platform/superproject/+/master:packages/modules/adb/transport.cpp;l=77;drc=6d14d35d0241f6fee145f8e54ffd77252e8d29fd
|
|
3
3
|
export enum AdbFeature {
|
|
4
4
|
ShellV2 = "shell_v2",
|
|
5
5
|
Cmd = "cmd",
|
|
@@ -9,4 +9,5 @@ export enum AdbFeature {
|
|
|
9
9
|
Abb = "abb",
|
|
10
10
|
AbbExec = "abb_exec",
|
|
11
11
|
SendReceiveV2 = "sendrecv_v2",
|
|
12
|
+
DelayedAck = "delayed_ack",
|
|
12
13
|
}
|