@yume-chan/android-bin 1.0.0 → 2.0.0
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.md +26 -0
- package/LICENSE +1 -1
- package/esm/am.d.ts +4 -2
- package/esm/am.d.ts.map +1 -1
- package/esm/am.js +9 -17
- package/esm/am.js.map +1 -1
- package/esm/bu.d.ts +2 -2
- package/esm/bu.d.ts.map +1 -1
- package/esm/bu.js +6 -14
- package/esm/bu.js.map +1 -1
- package/esm/bug-report.d.ts +2 -2
- package/esm/bug-report.d.ts.map +1 -1
- package/esm/bug-report.js +15 -13
- package/esm/bug-report.js.map +1 -1
- package/esm/cmd.d.ts +18 -20
- package/esm/cmd.d.ts.map +1 -1
- package/esm/cmd.js +84 -63
- package/esm/cmd.js.map +1 -1
- package/esm/demo-mode.d.ts +2 -2
- package/esm/demo-mode.js +3 -3
- package/esm/demo-mode.js.map +1 -1
- package/esm/dumpsys.d.ts +2 -2
- package/esm/dumpsys.js +6 -6
- package/esm/dumpsys.js.map +1 -1
- package/esm/logcat.d.ts +7 -8
- package/esm/logcat.d.ts.map +1 -1
- package/esm/logcat.js +18 -10
- package/esm/logcat.js.map +1 -1
- package/esm/overlay-display.d.ts +2 -2
- package/esm/overlay-display.js +2 -2
- package/esm/pm.d.ts +7 -3
- package/esm/pm.d.ts.map +1 -1
- package/esm/pm.js +81 -88
- package/esm/pm.js.map +1 -1
- package/esm/settings.d.ts +10 -7
- package/esm/settings.d.ts.map +1 -1
- package/esm/settings.js +14 -23
- package/esm/settings.js.map +1 -1
- package/package.json +9 -9
- package/src/am.ts +14 -21
- package/src/bu.ts +6 -14
- package/src/bug-report.ts +16 -16
- package/src/cmd.ts +136 -85
- package/src/demo-mode.ts +3 -3
- package/src/dumpsys.ts +6 -6
- package/src/logcat.ts +26 -15
- package/src/overlay-display.ts +2 -2
- package/src/pm.ts +92 -96
- package/src/settings.ts +20 -28
- package/tsconfig.build.tsbuildinfo +1 -1
package/src/bug-report.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// cspell: ignore bugreportz
|
|
3
3
|
|
|
4
4
|
import type { Adb, AdbSync } from "@yume-chan/adb";
|
|
5
|
-
import {
|
|
5
|
+
import { AdbServiceBase } from "@yume-chan/adb";
|
|
6
6
|
import type { AbortSignal, ReadableStream } from "@yume-chan/stream-extra";
|
|
7
7
|
import {
|
|
8
8
|
AbortController,
|
|
@@ -31,7 +31,7 @@ export interface BugReportZOptions {
|
|
|
31
31
|
onProgress?: ((completed: string, total: string) => void) | undefined;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
export class BugReport extends
|
|
34
|
+
export class BugReport extends AdbServiceBase {
|
|
35
35
|
static VERSION_REGEX: RegExp = /(\d+)\.(\d+)/;
|
|
36
36
|
|
|
37
37
|
static BEGIN_REGEX: RegExp = /BEGIN:(.*)/;
|
|
@@ -47,7 +47,7 @@ export class BugReport extends AdbCommandBase {
|
|
|
47
47
|
*/
|
|
48
48
|
static async queryCapabilities(adb: Adb): Promise<BugReport> {
|
|
49
49
|
// bugreportz requires shell protocol
|
|
50
|
-
if (!
|
|
50
|
+
if (!adb.subprocess.shellProtocol) {
|
|
51
51
|
return new BugReport(adb, {
|
|
52
52
|
supportsBugReport: true,
|
|
53
53
|
bugReportZVersion: undefined,
|
|
@@ -57,11 +57,11 @@ export class BugReport extends AdbCommandBase {
|
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
const
|
|
60
|
+
const result = await adb.subprocess.shellProtocol.spawnWaitText([
|
|
61
61
|
"bugreportz",
|
|
62
62
|
"-v",
|
|
63
63
|
]);
|
|
64
|
-
if (exitCode !== 0 || stderr === "") {
|
|
64
|
+
if (result.exitCode !== 0 || result.stderr === "") {
|
|
65
65
|
return new BugReport(adb, {
|
|
66
66
|
supportsBugReport: true,
|
|
67
67
|
bugReportZVersion: undefined,
|
|
@@ -71,7 +71,7 @@ export class BugReport extends AdbCommandBase {
|
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
const match = stderr.match(BugReport.VERSION_REGEX);
|
|
74
|
+
const match = result.stderr.match(BugReport.VERSION_REGEX);
|
|
75
75
|
if (!match) {
|
|
76
76
|
return new BugReport(adb, {
|
|
77
77
|
supportsBugReport: true,
|
|
@@ -170,8 +170,9 @@ export class BugReport extends AdbCommandBase {
|
|
|
170
170
|
|
|
171
171
|
return new WrapReadableStream(async () => {
|
|
172
172
|
// https://cs.android.com/android/platform/superproject/+/master:frameworks/native/cmds/bugreport/bugreport.cpp;drc=9b73bf07d73dbab5b792632e1e233edbad77f5fd;bpv=0;bpt=0
|
|
173
|
-
const process =
|
|
174
|
-
|
|
173
|
+
const process =
|
|
174
|
+
await this.adb.subprocess.noneProtocol.spawn("bugreport");
|
|
175
|
+
return process.output;
|
|
175
176
|
});
|
|
176
177
|
}
|
|
177
178
|
|
|
@@ -200,9 +201,8 @@ export class BugReport extends AdbCommandBase {
|
|
|
200
201
|
args.push("-p");
|
|
201
202
|
}
|
|
202
203
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
});
|
|
204
|
+
// `subprocess.shellProtocol` must be defined when `this.#supportsBugReportZ` is `true`
|
|
205
|
+
const process = await this.adb.subprocess.shellProtocol!.spawn(args);
|
|
206
206
|
|
|
207
207
|
options?.signal?.addEventListener("abort", () => {
|
|
208
208
|
void process.kill();
|
|
@@ -258,10 +258,10 @@ export class BugReport extends AdbCommandBase {
|
|
|
258
258
|
*/
|
|
259
259
|
bugReportZStream(): ReadableStream<Uint8Array> {
|
|
260
260
|
return new PushReadableStream(async (controller) => {
|
|
261
|
-
const process = await this.adb.subprocess.spawn(
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
);
|
|
261
|
+
const process = await this.adb.subprocess.shellProtocol!.spawn([
|
|
262
|
+
"bugreportz",
|
|
263
|
+
"-s",
|
|
264
|
+
]);
|
|
265
265
|
process.stdout
|
|
266
266
|
.pipeTo(
|
|
267
267
|
new WritableStream({
|
|
@@ -285,7 +285,7 @@ export class BugReport extends AdbCommandBase {
|
|
|
285
285
|
.catch((e) => {
|
|
286
286
|
controller.error(e);
|
|
287
287
|
});
|
|
288
|
-
await process.
|
|
288
|
+
await process.exited;
|
|
289
289
|
});
|
|
290
290
|
}
|
|
291
291
|
|
package/src/cmd.ts
CHANGED
|
@@ -1,23 +1,70 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Adb,
|
|
3
|
-
AdbSubprocessProtocol,
|
|
4
|
-
AdbSubprocessProtocolConstructor,
|
|
5
|
-
AdbSubprocessWaitResult,
|
|
6
|
-
} from "@yume-chan/adb";
|
|
1
|
+
import type { Adb, AdbShellProtocolProcess } from "@yume-chan/adb";
|
|
7
2
|
import {
|
|
8
|
-
AdbCommandBase,
|
|
9
3
|
AdbFeature,
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
AdbNoneProtocolProcessImpl,
|
|
5
|
+
AdbNoneProtocolSpawner,
|
|
6
|
+
AdbServiceBase,
|
|
7
|
+
AdbShellProtocolProcessImpl,
|
|
8
|
+
AdbShellProtocolSpawner,
|
|
12
9
|
} from "@yume-chan/adb";
|
|
13
|
-
import { ConcatStringStream, TextDecoderStream } from "@yume-chan/stream-extra";
|
|
14
10
|
|
|
15
|
-
export class
|
|
16
|
-
#
|
|
17
|
-
get
|
|
18
|
-
return this.#
|
|
11
|
+
export class CmdNoneProtocolService extends AdbNoneProtocolSpawner {
|
|
12
|
+
#supportsAbbExec: boolean;
|
|
13
|
+
get supportsAbbExec(): boolean {
|
|
14
|
+
return this.#supportsAbbExec;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
#supportsCmd: boolean;
|
|
18
|
+
get supportsCmd(): boolean {
|
|
19
|
+
return this.#supportsCmd;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get isSupported() {
|
|
23
|
+
return this.#supportsAbbExec || this.#supportsCmd;
|
|
19
24
|
}
|
|
20
25
|
|
|
26
|
+
constructor(
|
|
27
|
+
adb: Adb,
|
|
28
|
+
fallback?:
|
|
29
|
+
| string
|
|
30
|
+
| Record<string, string>
|
|
31
|
+
| ((service: string) => string),
|
|
32
|
+
) {
|
|
33
|
+
super(async (command) => {
|
|
34
|
+
if (this.#supportsAbbExec) {
|
|
35
|
+
return new AdbNoneProtocolProcessImpl(
|
|
36
|
+
await adb.createSocket(`abb_exec:${command.join("\0")}\0`),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (this.#supportsCmd) {
|
|
41
|
+
return adb.subprocess.noneProtocol.spawn(
|
|
42
|
+
`cmd ${command.join(" ")}`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (typeof fallback === "function") {
|
|
47
|
+
fallback = fallback(command[0]!);
|
|
48
|
+
} else if (typeof fallback === "object") {
|
|
49
|
+
fallback = fallback[command[0]!];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!fallback) {
|
|
53
|
+
throw new Error("Unsupported");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
command[0] = fallback;
|
|
57
|
+
return adb.subprocess.noneProtocol.spawn(command);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
this.#supportsCmd = adb.canUseFeature(AdbFeature.Cmd);
|
|
61
|
+
this.#supportsAbbExec = adb.canUseFeature(AdbFeature.AbbExec);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export class CmdShellProtocolService extends AdbShellProtocolSpawner {
|
|
66
|
+
#adb: Adb;
|
|
67
|
+
|
|
21
68
|
#supportsCmd: boolean;
|
|
22
69
|
get supportsCmd(): boolean {
|
|
23
70
|
return this.#supportsCmd;
|
|
@@ -28,86 +75,90 @@ export class Cmd extends AdbCommandBase {
|
|
|
28
75
|
return this.#supportsAbb;
|
|
29
76
|
}
|
|
30
77
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
78
|
+
get isSupported() {
|
|
79
|
+
return (
|
|
80
|
+
this.#supportsAbb ||
|
|
81
|
+
(this.#supportsCmd && !!this.#adb.subprocess.shellProtocol)
|
|
82
|
+
);
|
|
34
83
|
}
|
|
35
84
|
|
|
36
|
-
constructor(
|
|
37
|
-
|
|
38
|
-
|
|
85
|
+
constructor(
|
|
86
|
+
adb: Adb,
|
|
87
|
+
fallback?:
|
|
88
|
+
| string
|
|
89
|
+
| Record<string, string>
|
|
90
|
+
| ((service: string) => string),
|
|
91
|
+
) {
|
|
92
|
+
super(async (command): Promise<AdbShellProtocolProcess> => {
|
|
93
|
+
if (this.#supportsAbb) {
|
|
94
|
+
return new AdbShellProtocolProcessImpl(
|
|
95
|
+
await this.#adb.createSocket(`abb:${command.join("\0")}\0`),
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!adb.subprocess.shellProtocol) {
|
|
100
|
+
throw new Error("Unsupported");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (this.#supportsCmd) {
|
|
104
|
+
return adb.subprocess.shellProtocol.spawn(
|
|
105
|
+
`cmd ${command.join(" ")}`,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (typeof fallback === "function") {
|
|
110
|
+
fallback = fallback(command[0]!);
|
|
111
|
+
} else if (typeof fallback === "object") {
|
|
112
|
+
fallback = fallback[command[0]!];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!fallback) {
|
|
116
|
+
throw new Error("Unsupported");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
command[0] = fallback;
|
|
120
|
+
return adb.subprocess.shellProtocol.spawn(command);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
this.#adb = adb;
|
|
39
124
|
this.#supportsCmd = adb.canUseFeature(AdbFeature.Cmd);
|
|
40
125
|
this.#supportsAbb = adb.canUseFeature(AdbFeature.Abb);
|
|
41
|
-
this.#supportsAbbExec = adb.canUseFeature(AdbFeature.AbbExec);
|
|
42
126
|
}
|
|
127
|
+
}
|
|
43
128
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
*
|
|
50
|
-
* `cmd` doesn't use PTY, so even when shell protocol is used,
|
|
51
|
-
* resizing terminal size and closing `stdin` are not supported.
|
|
52
|
-
* @param command The command to run.
|
|
53
|
-
* @param args The arguments to pass to the command.
|
|
54
|
-
* @returns An `AdbSubprocessProtocol` that provides output streams.
|
|
55
|
-
*/
|
|
56
|
-
async spawn(
|
|
57
|
-
shellProtocol: boolean,
|
|
58
|
-
command: string,
|
|
59
|
-
...args: string[]
|
|
60
|
-
): Promise<AdbSubprocessProtocol> {
|
|
61
|
-
let supportsAbb: boolean;
|
|
62
|
-
let supportsCmd: boolean = this.#supportsCmd;
|
|
63
|
-
let service: string;
|
|
64
|
-
let Protocol: AdbSubprocessProtocolConstructor;
|
|
65
|
-
if (shellProtocol) {
|
|
66
|
-
supportsAbb = this.#supportsAbb;
|
|
67
|
-
supportsCmd &&= this.supportsShellV2;
|
|
68
|
-
service = "abb";
|
|
69
|
-
Protocol = AdbSubprocessShellProtocol;
|
|
70
|
-
} else {
|
|
71
|
-
supportsAbb = this.#supportsAbbExec;
|
|
72
|
-
service = "abb_exec";
|
|
73
|
-
Protocol = AdbSubprocessNoneProtocol;
|
|
74
|
-
}
|
|
129
|
+
export class Cmd extends AdbServiceBase {
|
|
130
|
+
#noneProtocol: CmdNoneProtocolService | undefined;
|
|
131
|
+
get noneProtocol() {
|
|
132
|
+
return this.#noneProtocol;
|
|
133
|
+
}
|
|
75
134
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
),
|
|
81
|
-
);
|
|
82
|
-
}
|
|
135
|
+
#shellProtocol: CmdShellProtocolService | undefined;
|
|
136
|
+
get shellProtocol() {
|
|
137
|
+
return this.#shellProtocol;
|
|
138
|
+
}
|
|
83
139
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
140
|
+
constructor(
|
|
141
|
+
adb: Adb,
|
|
142
|
+
fallback?:
|
|
143
|
+
| string
|
|
144
|
+
| Record<string, string>
|
|
145
|
+
| ((service: string) => string),
|
|
146
|
+
) {
|
|
147
|
+
super(adb);
|
|
87
148
|
|
|
88
|
-
|
|
89
|
-
|
|
149
|
+
if (
|
|
150
|
+
adb.canUseFeature(AdbFeature.AbbExec) ||
|
|
151
|
+
adb.canUseFeature(AdbFeature.Cmd)
|
|
152
|
+
) {
|
|
153
|
+
this.#noneProtocol = new CmdNoneProtocolService(adb, fallback);
|
|
154
|
+
}
|
|
90
155
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
process.stdout
|
|
99
|
-
.pipeThrough(new TextDecoderStream())
|
|
100
|
-
.pipeThrough(new ConcatStringStream()),
|
|
101
|
-
process.stderr
|
|
102
|
-
.pipeThrough(new TextDecoderStream())
|
|
103
|
-
.pipeThrough(new ConcatStringStream()),
|
|
104
|
-
process.exit,
|
|
105
|
-
]);
|
|
106
|
-
|
|
107
|
-
return {
|
|
108
|
-
stdout,
|
|
109
|
-
stderr,
|
|
110
|
-
exitCode,
|
|
111
|
-
};
|
|
156
|
+
if (
|
|
157
|
+
adb.canUseFeature(AdbFeature.Abb) ||
|
|
158
|
+
(adb.canUseFeature(AdbFeature.Cmd) &&
|
|
159
|
+
adb.canUseFeature(AdbFeature.ShellV2))
|
|
160
|
+
) {
|
|
161
|
+
this.#shellProtocol = new CmdShellProtocolService(adb, fallback);
|
|
162
|
+
}
|
|
112
163
|
}
|
|
113
164
|
}
|
package/src/demo-mode.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// cspell: ignore sysui
|
|
6
6
|
|
|
7
7
|
import type { Adb } from "@yume-chan/adb";
|
|
8
|
-
import {
|
|
8
|
+
import { AdbServiceBase } from "@yume-chan/adb";
|
|
9
9
|
|
|
10
10
|
import { Settings } from "./settings.js";
|
|
11
11
|
|
|
@@ -51,7 +51,7 @@ export const DemoModeStatusBarModes = [
|
|
|
51
51
|
|
|
52
52
|
export type DemoModeStatusBarMode = (typeof DemoModeStatusBarModes)[number];
|
|
53
53
|
|
|
54
|
-
export class DemoMode extends
|
|
54
|
+
export class DemoMode extends AdbServiceBase {
|
|
55
55
|
#settings: Settings;
|
|
56
56
|
|
|
57
57
|
constructor(adb: Adb) {
|
|
@@ -112,7 +112,7 @@ export class DemoMode extends AdbCommandBase {
|
|
|
112
112
|
command: string,
|
|
113
113
|
extra?: Record<string, string>,
|
|
114
114
|
): Promise<void> {
|
|
115
|
-
await this.adb.subprocess.
|
|
115
|
+
await this.adb.subprocess.noneProtocol.spawnWaitText([
|
|
116
116
|
"am",
|
|
117
117
|
"broadcast",
|
|
118
118
|
"-a",
|
package/src/dumpsys.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AdbServiceBase } from "@yume-chan/adb";
|
|
2
2
|
|
|
3
3
|
const BatteryDumpFields: Record<
|
|
4
4
|
string,
|
|
@@ -54,17 +54,17 @@ const Battery = {
|
|
|
54
54
|
Health,
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
-
export class DumpSys extends
|
|
57
|
+
export class DumpSys extends AdbServiceBase {
|
|
58
58
|
static readonly Battery = Battery;
|
|
59
59
|
|
|
60
60
|
async diskStats() {
|
|
61
|
-
const
|
|
61
|
+
const result = await this.adb.subprocess.noneProtocol.spawnWaitText([
|
|
62
62
|
"dumpsys",
|
|
63
63
|
"diskstats",
|
|
64
64
|
]);
|
|
65
65
|
|
|
66
66
|
function getSize(name: string) {
|
|
67
|
-
const match =
|
|
67
|
+
const match = result.match(
|
|
68
68
|
new RegExp(`${name}-Free: (\\d+)K / (\\d+)K`),
|
|
69
69
|
);
|
|
70
70
|
if (!match) {
|
|
@@ -91,7 +91,7 @@ export class DumpSys extends AdbCommandBase {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
async battery(): Promise<DumpSys.Battery.Info> {
|
|
94
|
-
const
|
|
94
|
+
const result = await this.adb.subprocess.noneProtocol.spawnWaitText([
|
|
95
95
|
"dumpsys",
|
|
96
96
|
"battery",
|
|
97
97
|
]);
|
|
@@ -105,7 +105,7 @@ export class DumpSys extends AdbCommandBase {
|
|
|
105
105
|
health: DumpSys.Battery.Health.Unknown,
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
-
for (const line of
|
|
108
|
+
for (const line of result.split("\n")) {
|
|
109
109
|
const parts = line.split(":").map((part) => part.trim());
|
|
110
110
|
if (parts.length !== 2) {
|
|
111
111
|
continue;
|
package/src/logcat.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// cspell: ignore logcat
|
|
2
2
|
// cspell: ignore usec
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { AdbServiceBase } from "@yume-chan/adb";
|
|
5
5
|
import type { ReadableStream } from "@yume-chan/stream-extra";
|
|
6
6
|
import {
|
|
7
7
|
BufferedTransformStream,
|
|
@@ -80,19 +80,25 @@ export type LogcatFormat = (typeof LogcatFormat)[keyof typeof LogcatFormat];
|
|
|
80
80
|
export interface LogcatFormatModifiers {
|
|
81
81
|
microseconds?: boolean;
|
|
82
82
|
nanoseconds?: boolean;
|
|
83
|
-
printable?: boolean;
|
|
84
83
|
year?: boolean;
|
|
85
84
|
timezone?: boolean;
|
|
86
85
|
epoch?: boolean;
|
|
87
86
|
monotonic?: boolean;
|
|
88
87
|
uid?: boolean;
|
|
89
|
-
descriptive?: boolean;
|
|
90
88
|
}
|
|
91
89
|
|
|
92
90
|
export interface LogcatOptions {
|
|
93
|
-
dump?: boolean;
|
|
94
|
-
pid?: number;
|
|
95
|
-
ids?: LogId[];
|
|
91
|
+
dump?: boolean | undefined;
|
|
92
|
+
pid?: number | undefined;
|
|
93
|
+
ids?: LogId[] | undefined;
|
|
94
|
+
tail?: number | Date | undefined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function formatTailTime(date: Date) {
|
|
98
|
+
// Tail time supports multiple formats,
|
|
99
|
+
// `sssss.mmm` is simplest to implement
|
|
100
|
+
const timestamp = date.getTime();
|
|
101
|
+
return ((timestamp / 1000) | 0) + "." + (timestamp % 1000);
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
const NANOSECONDS_PER_SECOND = /* #__PURE__ */ BigInt(1e9);
|
|
@@ -399,7 +405,7 @@ export interface LogSize {
|
|
|
399
405
|
maxPayloadSize: number;
|
|
400
406
|
}
|
|
401
407
|
|
|
402
|
-
export class Logcat extends
|
|
408
|
+
export class Logcat extends AdbServiceBase {
|
|
403
409
|
static logIdToName(id: LogId): string {
|
|
404
410
|
return LogIdName[id]!;
|
|
405
411
|
}
|
|
@@ -429,14 +435,14 @@ export class Logcat extends AdbCommandBase {
|
|
|
429
435
|
/(.*): ring buffer is (.*) (.*)B \((.*) (.*)B consumed, (.*) (.*)B readable\), max entry is (.*) B, max payload is (.*) B/;
|
|
430
436
|
|
|
431
437
|
async getLogSize(ids?: LogId[]): Promise<LogSize[]> {
|
|
432
|
-
const
|
|
438
|
+
const process = await this.adb.subprocess.noneProtocol.spawn([
|
|
433
439
|
"logcat",
|
|
434
440
|
"-g",
|
|
435
441
|
...(ids ? ["-b", Logcat.joinLogId(ids)] : []),
|
|
436
442
|
]);
|
|
437
443
|
|
|
438
444
|
const result: LogSize[] = [];
|
|
439
|
-
for await (const line of
|
|
445
|
+
for await (const line of process.output
|
|
440
446
|
.pipeThrough(new TextDecoderStream())
|
|
441
447
|
.pipeThrough(new SplitStringStream("\n"))) {
|
|
442
448
|
let match = line.match(Logcat.LOG_SIZE_REGEX_11);
|
|
@@ -488,7 +494,7 @@ export class Logcat extends AdbCommandBase {
|
|
|
488
494
|
args.push("-b", Logcat.joinLogId(ids));
|
|
489
495
|
}
|
|
490
496
|
|
|
491
|
-
await this.adb.subprocess.
|
|
497
|
+
await this.adb.subprocess.noneProtocol.spawnWaitText(args);
|
|
492
498
|
}
|
|
493
499
|
|
|
494
500
|
binary(options?: LogcatOptions): ReadableStream<AndroidLogEntry> {
|
|
@@ -503,14 +509,19 @@ export class Logcat extends AdbCommandBase {
|
|
|
503
509
|
if (options?.ids) {
|
|
504
510
|
args.push("-b", Logcat.joinLogId(options.ids));
|
|
505
511
|
}
|
|
512
|
+
if (options?.tail) {
|
|
513
|
+
args.push(
|
|
514
|
+
"-t",
|
|
515
|
+
typeof options.tail === "number"
|
|
516
|
+
? options.tail.toString()
|
|
517
|
+
: formatTailTime(options.tail),
|
|
518
|
+
);
|
|
519
|
+
}
|
|
506
520
|
|
|
507
521
|
// TODO: make `spawn` return synchronously with streams pending
|
|
508
522
|
// so it's easier to chain them.
|
|
509
|
-
const
|
|
510
|
-
|
|
511
|
-
protocols: [AdbSubprocessNoneProtocol],
|
|
512
|
-
});
|
|
513
|
-
return stdout;
|
|
523
|
+
const process = await this.adb.subprocess.noneProtocol.spawn(args);
|
|
524
|
+
return process.output;
|
|
514
525
|
}).pipeThrough(
|
|
515
526
|
new BufferedTransformStream((stream) => {
|
|
516
527
|
return deserializeAndroidLogEntry(stream);
|
package/src/overlay-display.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Adb } from "@yume-chan/adb";
|
|
2
|
-
import {
|
|
2
|
+
import { AdbServiceBase } from "@yume-chan/adb";
|
|
3
3
|
|
|
4
4
|
import { Settings } from "./settings.js";
|
|
5
5
|
import { p } from "./string-format.js";
|
|
@@ -17,7 +17,7 @@ export interface OverlayDisplayDevice {
|
|
|
17
17
|
showSystemDecorations: boolean;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export class OverlayDisplay extends
|
|
20
|
+
export class OverlayDisplay extends AdbServiceBase {
|
|
21
21
|
#settings: Settings;
|
|
22
22
|
|
|
23
23
|
static readonly SETTING_KEY = "overlay_display_devices";
|