@yume-chan/adb 0.0.18 → 0.0.19
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 +21 -0
- package/CHANGELOG.md +11 -1
- package/esm/adb.d.ts +63 -60
- package/esm/adb.d.ts.map +1 -1
- package/esm/adb.js +257 -249
- package/esm/adb.js.map +1 -1
- package/esm/auth.d.ts +51 -51
- package/esm/auth.d.ts.map +1 -1
- package/esm/auth.js +95 -96
- package/esm/auth.js.map +1 -1
- package/esm/backend.d.ts +8 -8
- package/esm/backend.d.ts.map +1 -1
- package/esm/backend.js +1 -1
- package/esm/commands/base.d.ts +6 -6
- package/esm/commands/base.d.ts.map +1 -1
- package/esm/commands/base.js +8 -8
- package/esm/commands/framebuffer.d.ts +53 -53
- package/esm/commands/framebuffer.d.ts.map +1 -1
- package/esm/commands/framebuffer.js +46 -46
- package/esm/commands/framebuffer.js.map +1 -1
- package/esm/commands/index.d.ts +7 -8
- package/esm/commands/index.d.ts.map +1 -1
- package/esm/commands/index.js +7 -8
- package/esm/commands/index.js.map +1 -1
- package/esm/commands/install.d.ts +9 -3
- package/esm/commands/install.d.ts.map +1 -1
- package/esm/commands/install.js +26 -26
- package/esm/commands/install.js.map +1 -1
- package/esm/commands/power.d.ts +22 -22
- package/esm/commands/power.js +48 -48
- package/esm/commands/reverse.d.ts +41 -28
- package/esm/commands/reverse.d.ts.map +1 -1
- package/esm/commands/reverse.js +125 -100
- package/esm/commands/reverse.js.map +1 -1
- package/esm/commands/subprocess/command.d.ts +57 -51
- package/esm/commands/subprocess/command.d.ts.map +1 -1
- package/esm/commands/subprocess/command.js +86 -80
- package/esm/commands/subprocess/command.js.map +1 -1
- package/esm/commands/subprocess/index.d.ts +3 -3
- package/esm/commands/subprocess/index.js +3 -3
- package/esm/commands/subprocess/protocols/index.d.ts +3 -3
- package/esm/commands/subprocess/protocols/index.js +3 -3
- package/esm/commands/subprocess/protocols/none.d.ts +35 -35
- package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/none.js +65 -55
- package/esm/commands/subprocess/protocols/none.js.map +1 -1
- package/esm/commands/subprocess/protocols/shell.d.ts +39 -38
- package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/shell.js +166 -162
- package/esm/commands/subprocess/protocols/shell.js.map +1 -1
- package/esm/commands/subprocess/protocols/types.d.ts +49 -49
- package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/types.js +1 -1
- package/esm/commands/subprocess/utils.d.ts +1 -1
- package/esm/commands/subprocess/utils.js +18 -18
- package/esm/commands/sync/index.d.ts +8 -7
- package/esm/commands/sync/index.d.ts.map +1 -1
- package/esm/commands/sync/index.js +8 -7
- package/esm/commands/sync/index.js.map +1 -1
- package/esm/commands/sync/list.d.ts +42 -40
- package/esm/commands/sync/list.d.ts.map +1 -1
- package/esm/commands/sync/list.js +67 -47
- package/esm/commands/sync/list.js.map +1 -1
- package/esm/commands/sync/pull.d.ts +13 -11
- package/esm/commands/sync/pull.d.ts.map +1 -1
- package/esm/commands/sync/pull.js +35 -37
- package/esm/commands/sync/pull.js.map +1 -1
- package/esm/commands/sync/push.d.ts +46 -7
- package/esm/commands/sync/push.d.ts.map +1 -1
- package/esm/commands/sync/push.js +89 -22
- package/esm/commands/sync/push.js.map +1 -1
- package/esm/commands/sync/request.d.ts +26 -23
- package/esm/commands/sync/request.d.ts.map +1 -1
- package/esm/commands/sync/request.js +40 -42
- package/esm/commands/sync/request.js.map +1 -1
- package/esm/commands/sync/response.d.ts +19 -19
- package/esm/commands/sync/response.d.ts.map +1 -1
- package/esm/commands/sync/response.js +54 -54
- package/esm/commands/sync/response.js.map +1 -1
- package/esm/commands/sync/socket.d.ts +27 -0
- package/esm/commands/sync/socket.d.ts.map +1 -0
- package/esm/commands/sync/socket.js +66 -0
- package/esm/commands/sync/socket.js.map +1 -0
- package/esm/commands/sync/stat.d.ts +72 -72
- package/esm/commands/sync/stat.d.ts.map +1 -1
- package/esm/commands/sync/stat.js +116 -104
- package/esm/commands/sync/stat.js.map +1 -1
- package/esm/commands/sync/sync.d.ts +72 -60
- package/esm/commands/sync/sync.d.ts.map +1 -1
- package/esm/commands/sync/sync.js +127 -149
- package/esm/commands/sync/sync.js.map +1 -1
- package/esm/commands/tcpip.d.ts +5 -5
- package/esm/commands/tcpip.js +18 -18
- package/esm/crypto.d.ts +36 -36
- package/esm/crypto.js +248 -248
- package/esm/features.d.ts +10 -7
- package/esm/features.d.ts.map +1 -1
- package/esm/features.js +13 -10
- package/esm/features.js.map +1 -1
- package/esm/index.d.ts +9 -9
- package/esm/index.js +9 -9
- package/esm/packet.d.ts +45 -46
- package/esm/packet.d.ts.map +1 -1
- package/esm/packet.js +43 -48
- package/esm/packet.js.map +1 -1
- package/esm/socket/dispatcher.d.ts +59 -59
- package/esm/socket/dispatcher.d.ts.map +1 -1
- package/esm/socket/dispatcher.js +223 -234
- package/esm/socket/dispatcher.js.map +1 -1
- package/esm/socket/index.d.ts +2 -2
- package/esm/socket/index.js +2 -2
- package/esm/socket/socket.d.ts +59 -59
- package/esm/socket/socket.d.ts.map +1 -1
- package/esm/socket/socket.js +118 -118
- package/esm/socket/socket.js.map +1 -1
- package/esm/utils/auto-reset-event.d.ts +9 -9
- package/esm/utils/auto-reset-event.d.ts.map +1 -1
- package/esm/utils/auto-reset-event.js +33 -33
- package/esm/utils/auto-reset-event.js.map +1 -1
- package/esm/utils/base64.d.ts +27 -27
- package/esm/utils/base64.js +246 -246
- package/esm/utils/conditional-variable.d.ts +9 -0
- package/esm/utils/conditional-variable.d.ts.map +1 -0
- package/esm/utils/conditional-variable.js +34 -0
- package/esm/utils/conditional-variable.js.map +1 -0
- package/esm/utils/index.d.ts +4 -3
- package/esm/utils/index.d.ts.map +1 -1
- package/esm/utils/index.js +4 -3
- package/esm/utils/index.js.map +1 -1
- package/package.json +11 -10
- package/src/adb.ts +47 -37
- package/src/auth.ts +7 -6
- package/src/backend.ts +4 -4
- package/src/commands/base.ts +1 -1
- package/src/commands/framebuffer.ts +4 -4
- package/src/commands/index.ts +7 -8
- package/src/commands/reverse.ts +35 -10
- package/src/commands/subprocess/command.ts +12 -4
- package/src/commands/subprocess/index.ts +3 -3
- package/src/commands/subprocess/protocols/index.ts +3 -3
- package/src/commands/subprocess/protocols/none.ts +25 -11
- package/src/commands/subprocess/protocols/shell.ts +50 -28
- package/src/commands/subprocess/protocols/types.ts +8 -7
- package/src/commands/subprocess/utils.ts +1 -1
- package/src/commands/sync/index.ts +8 -7
- package/src/commands/sync/list.ts +42 -23
- package/src/commands/sync/pull.ts +40 -45
- package/src/commands/sync/push.ts +146 -39
- package/src/commands/sync/request.ts +20 -15
- package/src/commands/sync/response.ts +7 -6
- package/src/commands/sync/socket.ts +97 -0
- package/src/commands/sync/stat.ts +47 -42
- package/src/commands/sync/sync.ts +68 -108
- package/src/commands/tcpip.ts +5 -5
- package/src/features.ts +9 -6
- package/src/packet.ts +19 -34
- package/src/socket/dispatcher.ts +32 -47
- package/src/socket/index.ts +2 -2
- package/src/socket/socket.ts +26 -17
- package/src/utils/auto-reset-event.ts +14 -15
- package/src/utils/conditional-variable.ts +45 -0
- package/src/utils/index.ts +4 -3
- package/tsconfig.build.tsbuildinfo +1 -1
- package/src/commands/install.ts +0 -40
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type BufferedReadableStream,
|
|
3
|
-
type WritableStreamDefaultWriter,
|
|
4
|
-
} from "@yume-chan/stream-extra";
|
|
5
1
|
import Struct, { placeholder } from "@yume-chan/struct";
|
|
6
2
|
|
|
7
3
|
import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
|
8
4
|
import { AdbSyncResponseId, adbSyncReadResponse } from "./response.js";
|
|
5
|
+
import type { AdbSyncSocket } from "./socket.js";
|
|
9
6
|
|
|
10
7
|
// https://github.com/python/cpython/blob/4e581d64b8aff3e2eda99b12f080c877bb78dfca/Lib/stat.py#L36
|
|
11
8
|
export enum LinuxFileType {
|
|
@@ -47,7 +44,7 @@ export const AdbSyncLstatResponse = new Struct({ littleEndian: true })
|
|
|
47
44
|
});
|
|
48
45
|
|
|
49
46
|
export type AdbSyncLstatResponse =
|
|
50
|
-
typeof AdbSyncLstatResponse["TDeserializeResult"];
|
|
47
|
+
(typeof AdbSyncLstatResponse)["TDeserializeResult"];
|
|
51
48
|
|
|
52
49
|
export enum AdbSyncStatErrorCode {
|
|
53
50
|
SUCCESS = 0,
|
|
@@ -101,52 +98,60 @@ export const AdbSyncStatResponse = new Struct({ littleEndian: true })
|
|
|
101
98
|
});
|
|
102
99
|
|
|
103
100
|
export type AdbSyncStatResponse =
|
|
104
|
-
typeof AdbSyncStatResponse["TDeserializeResult"];
|
|
101
|
+
(typeof AdbSyncStatResponse)["TDeserializeResult"];
|
|
105
102
|
|
|
106
103
|
export async function adbSyncLstat(
|
|
107
|
-
|
|
108
|
-
writer: WritableStreamDefaultWriter<Uint8Array>,
|
|
104
|
+
socket: AdbSyncSocket,
|
|
109
105
|
path: string,
|
|
110
106
|
v2: boolean
|
|
111
107
|
): Promise<AdbSyncStat> {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
108
|
+
const locked = await socket.lock();
|
|
109
|
+
try {
|
|
110
|
+
if (v2) {
|
|
111
|
+
await adbSyncWriteRequest(locked, AdbSyncRequestId.LstatV2, path);
|
|
112
|
+
return await adbSyncReadResponse(
|
|
113
|
+
locked,
|
|
114
|
+
AdbSyncResponseId.Lstat2,
|
|
115
|
+
AdbSyncStatResponse
|
|
116
|
+
);
|
|
117
|
+
} else {
|
|
118
|
+
await adbSyncWriteRequest(locked, AdbSyncRequestId.Lstat, path);
|
|
119
|
+
const response = await adbSyncReadResponse(
|
|
120
|
+
locked,
|
|
121
|
+
AdbSyncResponseId.Lstat,
|
|
122
|
+
AdbSyncLstatResponse
|
|
123
|
+
);
|
|
124
|
+
return {
|
|
125
|
+
mode: response.mode,
|
|
126
|
+
// Convert to `BigInt` to make it compatible with `AdbSyncStatResponse`
|
|
127
|
+
size: BigInt(response.size),
|
|
128
|
+
mtime: BigInt(response.mtime),
|
|
129
|
+
get type() {
|
|
130
|
+
return response.type;
|
|
131
|
+
},
|
|
132
|
+
get permission() {
|
|
133
|
+
return response.permission;
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
} finally {
|
|
138
|
+
locked.release();
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
export async function adbSyncStat(
|
|
142
|
-
|
|
143
|
-
writer: WritableStreamDefaultWriter<Uint8Array>,
|
|
143
|
+
socket: AdbSyncSocket,
|
|
144
144
|
path: string
|
|
145
145
|
): Promise<AdbSyncStatResponse> {
|
|
146
|
-
await
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
const locked = await socket.lock();
|
|
147
|
+
try {
|
|
148
|
+
await adbSyncWriteRequest(locked, AdbSyncRequestId.Stat, path);
|
|
149
|
+
return await adbSyncReadResponse(
|
|
150
|
+
locked,
|
|
151
|
+
AdbSyncResponseId.Stat,
|
|
152
|
+
AdbSyncStatResponse
|
|
153
|
+
);
|
|
154
|
+
} finally {
|
|
155
|
+
locked.release();
|
|
156
|
+
}
|
|
152
157
|
}
|
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
import { AutoDisposable } from "@yume-chan/event";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
type WritableStream,
|
|
8
|
-
type WritableStreamDefaultWriter,
|
|
9
|
-
} from "@yume-chan/stream-extra";
|
|
10
|
-
|
|
11
|
-
import { type Adb } from "../../adb.js";
|
|
12
|
-
import { AdbFeatures } from "../../features.js";
|
|
13
|
-
import { type AdbSocket } from "../../socket/index.js";
|
|
14
|
-
import { AutoResetEvent } from "../../utils/index.js";
|
|
2
|
+
import type { Consumable, ReadableStream } from "@yume-chan/stream-extra";
|
|
3
|
+
|
|
4
|
+
import type { Adb } from "../../adb.js";
|
|
5
|
+
import { AdbFeature } from "../../features.js";
|
|
6
|
+
import type { AdbSocket } from "../../socket/index.js";
|
|
15
7
|
import { escapeArg } from "../subprocess/index.js";
|
|
16
8
|
|
|
17
|
-
import {
|
|
9
|
+
import type { AdbSyncEntry } from "./list.js";
|
|
10
|
+
import { adbSyncOpenDir } from "./list.js";
|
|
18
11
|
import { adbSyncPull } from "./pull.js";
|
|
19
12
|
import { adbSyncPush } from "./push.js";
|
|
13
|
+
import { AdbSyncSocket } from "./socket.js";
|
|
20
14
|
import { adbSyncLstat, adbSyncStat } from "./stat.js";
|
|
21
15
|
|
|
22
16
|
/**
|
|
@@ -35,57 +29,64 @@ export function dirname(path: string): string {
|
|
|
35
29
|
return path.substring(0, end);
|
|
36
30
|
}
|
|
37
31
|
|
|
32
|
+
export interface AdbSyncWriteOptions {
|
|
33
|
+
filename: string;
|
|
34
|
+
file: ReadableStream<Consumable<Uint8Array>>;
|
|
35
|
+
mode?: number;
|
|
36
|
+
mtime?: number;
|
|
37
|
+
dryRun?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
38
40
|
export class AdbSync extends AutoDisposable {
|
|
39
|
-
protected
|
|
41
|
+
protected _adb: Adb;
|
|
42
|
+
protected _socket: AdbSyncSocket;
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
protected sendLock = this.addDisposable(new AutoResetEvent());
|
|
44
|
+
private _supportsStat: boolean;
|
|
45
|
+
private _supportsListV2: boolean;
|
|
46
|
+
private _fixedPushMkdir: boolean;
|
|
47
|
+
private _supportsSendReceiveV2: boolean;
|
|
48
|
+
private _needPushMkdirWorkaround: boolean;
|
|
47
49
|
|
|
48
50
|
public get supportsStat(): boolean {
|
|
49
|
-
return this.
|
|
51
|
+
return this._supportsStat;
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
public get
|
|
53
|
-
return this.
|
|
54
|
+
public get supportsListV2(): boolean {
|
|
55
|
+
return this._supportsListV2;
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
public get fixedPushMkdir(): boolean {
|
|
57
|
-
return this.
|
|
59
|
+
return this._fixedPushMkdir;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public get supportsSendReceiveV2(): boolean {
|
|
63
|
+
return this._supportsSendReceiveV2;
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
public get needPushMkdirWorkaround(): boolean {
|
|
61
|
-
|
|
62
|
-
return (
|
|
63
|
-
this.adb.features.includes(AdbFeatures.ShellV2) &&
|
|
64
|
-
!this.fixedPushMkdir
|
|
65
|
-
);
|
|
67
|
+
return this._needPushMkdirWorkaround;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
public constructor(adb: Adb, socket: AdbSocket) {
|
|
69
71
|
super();
|
|
70
72
|
|
|
71
|
-
this.
|
|
72
|
-
this.
|
|
73
|
-
|
|
73
|
+
this._adb = adb;
|
|
74
|
+
this._socket = new AdbSyncSocket(socket, adb.maxPayloadSize);
|
|
75
|
+
|
|
76
|
+
this._supportsStat = adb.supportsFeature(AdbFeature.StatV2);
|
|
77
|
+
this._supportsListV2 = adb.supportsFeature(AdbFeature.ListV2);
|
|
78
|
+
this._fixedPushMkdir = adb.supportsFeature(AdbFeature.FixedPushMkdir);
|
|
79
|
+
this._supportsSendReceiveV2 = adb.supportsFeature(
|
|
80
|
+
AdbFeature.SendReceiveV2
|
|
81
|
+
);
|
|
82
|
+
// https://android.googlesource.com/platform/packages/modules/adb/+/91768a57b7138166e0a3d11f79cd55909dda7014/client/file_sync_client.cpp#1361
|
|
83
|
+
this._needPushMkdirWorkaround =
|
|
84
|
+
this._adb.supportsFeature(AdbFeature.ShellV2) &&
|
|
85
|
+
!this.fixedPushMkdir;
|
|
74
86
|
}
|
|
75
87
|
|
|
76
88
|
public async lstat(path: string) {
|
|
77
|
-
await this.
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
return adbSyncLstat(
|
|
81
|
-
this.stream,
|
|
82
|
-
this.writer,
|
|
83
|
-
path,
|
|
84
|
-
this.supportsStat
|
|
85
|
-
);
|
|
86
|
-
} finally {
|
|
87
|
-
this.sendLock.notify();
|
|
88
|
-
}
|
|
89
|
+
return await adbSyncLstat(this._socket, path, this.supportsStat);
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
public async stat(path: string) {
|
|
@@ -93,13 +94,7 @@ export class AdbSync extends AutoDisposable {
|
|
|
93
94
|
throw new Error("Not supported");
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
await this.
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
return adbSyncStat(this.stream, this.writer, path);
|
|
100
|
-
} finally {
|
|
101
|
-
this.sendLock.notify();
|
|
102
|
-
}
|
|
97
|
+
return await adbSyncStat(this._socket, path);
|
|
103
98
|
}
|
|
104
99
|
|
|
105
100
|
public async isDirectory(path: string): Promise<boolean> {
|
|
@@ -111,21 +106,8 @@ export class AdbSync extends AutoDisposable {
|
|
|
111
106
|
}
|
|
112
107
|
}
|
|
113
108
|
|
|
114
|
-
public
|
|
115
|
-
path
|
|
116
|
-
): AsyncGenerator<AdbSyncEntry, void, void> {
|
|
117
|
-
await this.sendLock.wait();
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
yield* adbSyncOpenDir(
|
|
121
|
-
this.stream,
|
|
122
|
-
this.writer,
|
|
123
|
-
path,
|
|
124
|
-
this.supportsList2
|
|
125
|
-
);
|
|
126
|
-
} finally {
|
|
127
|
-
this.sendLock.notify();
|
|
128
|
-
}
|
|
109
|
+
public opendir(path: string): AsyncGenerator<AdbSyncEntry, void, void> {
|
|
110
|
+
return adbSyncOpenDir(this._socket, path, this.supportsListV2);
|
|
129
111
|
}
|
|
130
112
|
|
|
131
113
|
public async readdir(path: string) {
|
|
@@ -143,61 +125,39 @@ export class AdbSync extends AutoDisposable {
|
|
|
143
125
|
* @returns A `ReadableStream` that reads from the file.
|
|
144
126
|
*/
|
|
145
127
|
public read(filename: string): ReadableStream<Uint8Array> {
|
|
146
|
-
return
|
|
147
|
-
start: async () => {
|
|
148
|
-
await this.sendLock.wait();
|
|
149
|
-
return adbSyncPull(this.stream, this.writer, filename);
|
|
150
|
-
},
|
|
151
|
-
close: () => {
|
|
152
|
-
this.sendLock.notify();
|
|
153
|
-
},
|
|
154
|
-
});
|
|
128
|
+
return adbSyncPull(this._socket, filename);
|
|
155
129
|
}
|
|
156
130
|
|
|
157
131
|
/**
|
|
158
132
|
* Write (or overwrite) a file on device.
|
|
159
133
|
*
|
|
160
134
|
* @param filename The full path of the file on device to write.
|
|
135
|
+
* @param file The content to write.
|
|
161
136
|
* @param mode The unix permissions of the file.
|
|
162
137
|
* @param mtime The modified time of the file.
|
|
163
138
|
* @returns A `WritableStream` that writes to the file.
|
|
164
139
|
*/
|
|
165
|
-
public write(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
escapeArg(dirname(filename)),
|
|
182
|
-
]);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return adbSyncPush(
|
|
186
|
-
this.stream,
|
|
187
|
-
this.writer,
|
|
188
|
-
filename,
|
|
189
|
-
mode,
|
|
190
|
-
mtime
|
|
191
|
-
);
|
|
192
|
-
},
|
|
193
|
-
close: () => {
|
|
194
|
-
this.sendLock.notify();
|
|
195
|
-
},
|
|
140
|
+
public async write(options: AdbSyncWriteOptions) {
|
|
141
|
+
if (this.needPushMkdirWorkaround) {
|
|
142
|
+
// It may fail if the path is already existed.
|
|
143
|
+
// Ignore the result.
|
|
144
|
+
// TODO: sync: test push mkdir workaround (need an Android 8 device)
|
|
145
|
+
await this._adb.subprocess.spawnAndWait([
|
|
146
|
+
"mkdir",
|
|
147
|
+
"-p",
|
|
148
|
+
escapeArg(dirname(options.filename)),
|
|
149
|
+
]);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
await adbSyncPush({
|
|
153
|
+
v2: this.supportsSendReceiveV2,
|
|
154
|
+
socket: this._socket,
|
|
155
|
+
...options,
|
|
196
156
|
});
|
|
197
157
|
}
|
|
198
158
|
|
|
199
159
|
public override async dispose() {
|
|
200
160
|
super.dispose();
|
|
201
|
-
await this.
|
|
161
|
+
await this._socket.close();
|
|
202
162
|
}
|
|
203
163
|
}
|
package/src/commands/tcpip.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AdbCommandBase } from
|
|
1
|
+
import { AdbCommandBase } from "./base.js";
|
|
2
2
|
|
|
3
3
|
export class AdbTcpIpCommand extends AdbCommandBase {
|
|
4
4
|
public async setPort(port: number): Promise<void> {
|
|
@@ -8,14 +8,14 @@ export class AdbTcpIpCommand extends AdbCommandBase {
|
|
|
8
8
|
|
|
9
9
|
const output = await this.adb.createSocketAndWait(`tcpip:${port}`);
|
|
10
10
|
if (output !== `restarting in TCP mode port: ${port}\n`) {
|
|
11
|
-
throw new Error(
|
|
11
|
+
throw new Error("Invalid response");
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
public async disable(): Promise<void> {
|
|
16
|
-
const output = await this.adb.createSocketAndWait(
|
|
17
|
-
if (output !==
|
|
18
|
-
throw new Error(
|
|
16
|
+
const output = await this.adb.createSocketAndWait("usb:");
|
|
17
|
+
if (output !== "restarting in USB mode\n") {
|
|
18
|
+
throw new Error("Invalid response");
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
}
|
package/src/features.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// The order follows
|
|
2
2
|
// https://android.googlesource.com/platform/packages/modules/adb/+/79010dc6d5ca7490c493df800d4421730f5466ca/transport.cpp#1252
|
|
3
|
-
export enum
|
|
4
|
-
ShellV2 =
|
|
5
|
-
Cmd =
|
|
6
|
-
StatV2 =
|
|
7
|
-
ListV2 =
|
|
8
|
-
FixedPushMkdir =
|
|
3
|
+
export enum AdbFeature {
|
|
4
|
+
ShellV2 = "shell_v2",
|
|
5
|
+
Cmd = "cmd",
|
|
6
|
+
StatV2 = "stat_v2",
|
|
7
|
+
ListV2 = "ls_v2",
|
|
8
|
+
FixedPushMkdir = "fixed_push_mkdir",
|
|
9
|
+
Abb = "abb",
|
|
10
|
+
AbbExec = "abb_exec",
|
|
11
|
+
SendReceiveV2 = "sendrecv_v2",
|
|
9
12
|
}
|
package/src/packet.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConsumableTransformStream } from "@yume-chan/stream-extra";
|
|
2
2
|
import Struct from "@yume-chan/struct";
|
|
3
3
|
|
|
4
4
|
export enum AdbCommand {
|
|
@@ -18,15 +18,15 @@ export const AdbPacketHeader = new Struct({ littleEndian: true })
|
|
|
18
18
|
.uint32("checksum")
|
|
19
19
|
.int32("magic");
|
|
20
20
|
|
|
21
|
-
export type AdbPacketHeader = typeof AdbPacketHeader["TDeserializeResult"];
|
|
21
|
+
export type AdbPacketHeader = (typeof AdbPacketHeader)["TDeserializeResult"];
|
|
22
22
|
|
|
23
|
-
type AdbPacketHeaderInit = typeof AdbPacketHeader["TInit"];
|
|
23
|
+
type AdbPacketHeaderInit = (typeof AdbPacketHeader)["TInit"];
|
|
24
24
|
|
|
25
25
|
export const AdbPacket = new Struct({ littleEndian: true })
|
|
26
26
|
.fields(AdbPacketHeader)
|
|
27
27
|
.uint8Array("payload", { lengthField: "payloadLength" });
|
|
28
28
|
|
|
29
|
-
export type AdbPacket = typeof AdbPacket["TDeserializeResult"];
|
|
29
|
+
export type AdbPacket = (typeof AdbPacket)["TDeserializeResult"];
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* `AdbPacketData` contains all the useful fields of `AdbPacket`.
|
|
@@ -39,50 +39,35 @@ export type AdbPacket = typeof AdbPacket["TDeserializeResult"];
|
|
|
39
39
|
* so `AdbSocket#writable#write` only needs `AdbPacketData`.
|
|
40
40
|
*/
|
|
41
41
|
export type AdbPacketData = Omit<
|
|
42
|
-
typeof AdbPacket["TInit"],
|
|
42
|
+
(typeof AdbPacket)["TInit"],
|
|
43
43
|
"checksum" | "magic"
|
|
44
44
|
>;
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
export type AdbPacketInit = Omit<typeof AdbPacket["TInit"], "magic">;
|
|
46
|
+
export type AdbPacketInit = (typeof AdbPacket)["TInit"];
|
|
48
47
|
|
|
49
|
-
export function calculateChecksum(payload: Uint8Array): number
|
|
50
|
-
|
|
51
|
-
export function calculateChecksum(
|
|
52
|
-
payload: Uint8Array | AdbPacketData
|
|
53
|
-
): number | AdbPacketInit {
|
|
54
|
-
if (payload instanceof Uint8Array) {
|
|
55
|
-
return payload.reduce((result, item) => result + item, 0);
|
|
56
|
-
} else {
|
|
57
|
-
(payload as AdbPacketInit).checksum = calculateChecksum(
|
|
58
|
-
payload.payload
|
|
59
|
-
);
|
|
60
|
-
return payload as AdbPacketInit;
|
|
61
|
-
}
|
|
48
|
+
export function calculateChecksum(payload: Uint8Array): number {
|
|
49
|
+
return payload.reduce((result, item) => result + item, 0);
|
|
62
50
|
}
|
|
63
51
|
|
|
64
|
-
export class AdbPacketSerializeStream extends
|
|
52
|
+
export class AdbPacketSerializeStream extends ConsumableTransformStream<
|
|
65
53
|
AdbPacketInit,
|
|
66
54
|
Uint8Array
|
|
67
55
|
> {
|
|
68
56
|
public constructor() {
|
|
57
|
+
const headerBuffer = new Uint8Array(AdbPacketHeader.size);
|
|
69
58
|
super({
|
|
70
|
-
transform: (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
init.command ^ 0xffffffff;
|
|
74
|
-
(init as unknown as AdbPacketHeaderInit).payloadLength =
|
|
75
|
-
init.payload.byteLength;
|
|
59
|
+
transform: async (chunk, controller) => {
|
|
60
|
+
const init = chunk as AdbPacketInit & AdbPacketHeaderInit;
|
|
61
|
+
init.payloadLength = init.payload.byteLength;
|
|
76
62
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
init as unknown as AdbPacketHeaderInit
|
|
80
|
-
)
|
|
81
|
-
);
|
|
63
|
+
AdbPacketHeader.serialize(init, headerBuffer);
|
|
64
|
+
await controller.enqueue(headerBuffer);
|
|
82
65
|
|
|
83
66
|
if (init.payload.byteLength) {
|
|
84
|
-
//
|
|
85
|
-
|
|
67
|
+
// USB protocol preserves packet boundaries,
|
|
68
|
+
// so we must write payload separately as native ADB does,
|
|
69
|
+
// otherwise the read operation on device will fail.
|
|
70
|
+
await controller.enqueue(init.payload);
|
|
86
71
|
}
|
|
87
72
|
},
|
|
88
73
|
});
|
package/src/socket/dispatcher.ts
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import { AsyncOperationManager, PromiseResolver } from "@yume-chan/async";
|
|
2
|
-
import {
|
|
2
|
+
import type { RemoveEventListener } from "@yume-chan/event";
|
|
3
|
+
import type {
|
|
4
|
+
Consumable,
|
|
5
|
+
ReadableWritablePair,
|
|
6
|
+
WritableStreamDefaultWriter,
|
|
7
|
+
} from "@yume-chan/stream-extra";
|
|
3
8
|
import {
|
|
4
9
|
AbortController,
|
|
10
|
+
ConsumableWritableStream,
|
|
5
11
|
WritableStream,
|
|
6
|
-
type ReadableWritablePair,
|
|
7
|
-
type WritableStreamDefaultWriter,
|
|
8
12
|
} from "@yume-chan/stream-extra";
|
|
9
|
-
import {
|
|
13
|
+
import type { ValueOrPromise } from "@yume-chan/struct";
|
|
14
|
+
import { EMPTY_UINT8_ARRAY } from "@yume-chan/struct";
|
|
10
15
|
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
calculateChecksum,
|
|
14
|
-
type AdbPacketData,
|
|
15
|
-
type AdbPacketInit,
|
|
16
|
-
} from "../packet.js";
|
|
16
|
+
import type { AdbPacketData, AdbPacketInit } from "../packet.js";
|
|
17
|
+
import { AdbCommand, calculateChecksum } from "../packet.js";
|
|
17
18
|
import { decodeUtf8, encodeUtf8 } from "../utils/index.js";
|
|
18
19
|
|
|
19
|
-
import {
|
|
20
|
+
import type { AdbSocket } from "./socket.js";
|
|
21
|
+
import { AdbSocketController } from "./socket.js";
|
|
20
22
|
|
|
21
23
|
export interface AdbPacketDispatcherOptions {
|
|
22
24
|
calculateChecksum: boolean;
|
|
@@ -57,7 +59,7 @@ export class AdbPacketDispatcher implements Closeable {
|
|
|
57
59
|
*/
|
|
58
60
|
private readonly sockets = new Map<number, AdbSocketController>();
|
|
59
61
|
|
|
60
|
-
private _writer
|
|
62
|
+
private _writer: WritableStreamDefaultWriter<Consumable<AdbPacketInit>>;
|
|
61
63
|
|
|
62
64
|
public readonly options: AdbPacketDispatcherOptions;
|
|
63
65
|
|
|
@@ -72,7 +74,10 @@ export class AdbPacketDispatcher implements Closeable {
|
|
|
72
74
|
private _abortController = new AbortController();
|
|
73
75
|
|
|
74
76
|
public constructor(
|
|
75
|
-
connection: ReadableWritablePair<
|
|
77
|
+
connection: ReadableWritablePair<
|
|
78
|
+
AdbPacketData,
|
|
79
|
+
Consumable<AdbPacketInit>
|
|
80
|
+
>,
|
|
76
81
|
options: AdbPacketDispatcherOptions
|
|
77
82
|
) {
|
|
78
83
|
this.options = options;
|
|
@@ -273,50 +278,30 @@ export class AdbPacketDispatcher implements Closeable {
|
|
|
273
278
|
return controller.socket;
|
|
274
279
|
}
|
|
275
280
|
|
|
276
|
-
public sendPacket(
|
|
277
|
-
public sendPacket(
|
|
281
|
+
public async sendPacket(
|
|
278
282
|
command: AdbCommand,
|
|
279
283
|
arg0: number,
|
|
280
284
|
arg1: number,
|
|
281
|
-
payload?: string | Uint8Array
|
|
282
|
-
): Promise<void>;
|
|
283
|
-
public async sendPacket(
|
|
284
|
-
packetOrCommand: AdbPacketInit | AdbCommand,
|
|
285
|
-
arg0?: number,
|
|
286
|
-
arg1?: number,
|
|
287
285
|
payload: string | Uint8Array = EMPTY_UINT8_ARRAY
|
|
288
286
|
): Promise<void> {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
init = packetOrCommand as AdbPacketInit;
|
|
292
|
-
} else {
|
|
293
|
-
if (typeof payload === "string") {
|
|
294
|
-
payload = encodeUtf8(payload);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
init = {
|
|
298
|
-
command: packetOrCommand as AdbCommand,
|
|
299
|
-
arg0: arg0,
|
|
300
|
-
arg1: arg1 as number,
|
|
301
|
-
payload,
|
|
302
|
-
};
|
|
287
|
+
if (typeof payload === "string") {
|
|
288
|
+
payload = encodeUtf8(payload);
|
|
303
289
|
}
|
|
304
290
|
|
|
305
|
-
if (
|
|
306
|
-
init.payload &&
|
|
307
|
-
init.payload.byteLength > this.options.maxPayloadSize
|
|
308
|
-
) {
|
|
291
|
+
if (payload.byteLength > this.options.maxPayloadSize) {
|
|
309
292
|
throw new Error("payload too large");
|
|
310
293
|
}
|
|
311
294
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
295
|
+
await ConsumableWritableStream.write(this._writer, {
|
|
296
|
+
command,
|
|
297
|
+
arg0,
|
|
298
|
+
arg1,
|
|
299
|
+
payload,
|
|
300
|
+
checksum: this.options.calculateChecksum
|
|
301
|
+
? calculateChecksum(payload)
|
|
302
|
+
: 0,
|
|
303
|
+
magic: command ^ 0xffffffff,
|
|
304
|
+
});
|
|
320
305
|
}
|
|
321
306
|
|
|
322
307
|
public async close() {
|
package/src/socket/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
1
|
+
export * from "./dispatcher.js";
|
|
2
|
+
export * from "./socket.js";
|