@yume-chan/android-bin 0.0.17 → 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.
package/src/demo-mode.ts CHANGED
@@ -4,28 +4,51 @@
4
4
  // cspell: ignore systemui
5
5
  // cspell: ignore sysui
6
6
 
7
- import { Adb, AdbCommandBase } from '@yume-chan/adb';
7
+ import { type Adb, AdbCommandBase } from "@yume-chan/adb";
8
+
8
9
  import { Settings } from "./settings.js";
9
10
 
10
11
  export enum DemoModeSignalStrength {
11
- Hidden = 'null',
12
- Level0 = '0',
13
- Level1 = '1',
14
- Level2 = '2',
15
- Level3 = '3',
16
- Level4 = '4',
12
+ Hidden = "null",
13
+ Level0 = "0",
14
+ Level1 = "1",
15
+ Level2 = "2",
16
+ Level3 = "3",
17
+ Level4 = "4",
17
18
  }
18
19
 
19
20
  // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java;l=1362;drc=3b775bf7ad89902f94e03d191b0d8fbdebf2bdbf
20
- export const DemoModeMobileDataTypes = ['1x', '3g', '4g', '4g+', '5g', '5ge', '5g+',
21
- 'e', 'g', 'h', 'h+', 'lte', 'lte+', 'dis', 'not', 'null'] as const;
22
-
23
- export type DemoModeMobileDataType = (typeof DemoModeMobileDataTypes)[number];
21
+ export const DemoModeMobileDataTypes = [
22
+ "1x",
23
+ "3g",
24
+ "4g",
25
+ "4g+",
26
+ "5g",
27
+ "5ge",
28
+ "5g+",
29
+ "e",
30
+ "g",
31
+ "h",
32
+ "h+",
33
+ "lte",
34
+ "lte+",
35
+ "dis",
36
+ "not",
37
+ "null",
38
+ ] as const;
39
+
40
+ export type DemoModeMobileDataType = typeof DemoModeMobileDataTypes[number];
24
41
 
25
42
  // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java;l=3136
26
- export const DemoModeStatusBarModes = ['opaque', 'translucent', 'semi-transparent', 'transparent', 'warning'] as const;
43
+ export const DemoModeStatusBarModes = [
44
+ "opaque",
45
+ "translucent",
46
+ "semi-transparent",
47
+ "transparent",
48
+ "warning",
49
+ ] as const;
27
50
 
28
- export type DemoModeStatusBarMode = (typeof DemoModeStatusBarModes)[number];
51
+ export type DemoModeStatusBarMode = typeof DemoModeStatusBarModes[number];
29
52
 
30
53
  export class DemoMode extends AdbCommandBase {
31
54
  private settings: Settings;
@@ -35,145 +58,170 @@ export class DemoMode extends AdbCommandBase {
35
58
  this.settings = new Settings(adb);
36
59
  }
37
60
 
38
- public static readonly AllowedSettingKey = 'sysui_demo_allowed';
61
+ public static readonly AllowedSettingKey = "sysui_demo_allowed";
39
62
 
40
63
  // Demo Mode actually doesn't have a setting indicates its enablement
41
64
  // However Developer Mode menu uses this key
42
65
  // So we can only try our best to guess if it's enabled
43
- public static readonly EnabledSettingKey = 'sysui_tuner_demo_on';
66
+ public static readonly EnabledSettingKey = "sysui_tuner_demo_on";
44
67
 
45
68
  public async getAllowed(): Promise<boolean> {
46
- const output = await this.settings.get('global', DemoMode.AllowedSettingKey);
47
- return output.trim() === '1';
69
+ const output = await this.settings.get(
70
+ "global",
71
+ DemoMode.AllowedSettingKey
72
+ );
73
+ return output.trim() === "1";
48
74
  }
49
75
 
50
76
  public async setAllowed(value: boolean): Promise<void> {
51
77
  if (value) {
52
- await this.settings.put('global', DemoMode.AllowedSettingKey, '1');
78
+ await this.settings.put("global", DemoMode.AllowedSettingKey, "1");
53
79
  } else {
54
80
  await this.setEnabled(false);
55
- await this.settings.delete('global', DemoMode.AllowedSettingKey);
81
+ await this.settings.delete("global", DemoMode.AllowedSettingKey);
56
82
  }
57
83
  }
58
84
 
59
85
  public async getEnabled(): Promise<boolean> {
60
- const result = await this.settings.get('global', DemoMode.EnabledSettingKey);
61
- return result.trim() === '1';
86
+ const result = await this.settings.get(
87
+ "global",
88
+ DemoMode.EnabledSettingKey
89
+ );
90
+ return result.trim() === "1";
62
91
  }
63
92
 
64
93
  public async setEnabled(value: boolean): Promise<void> {
65
94
  if (value) {
66
- await this.settings.put('global', DemoMode.EnabledSettingKey, '1');
95
+ await this.settings.put("global", DemoMode.EnabledSettingKey, "1");
67
96
  } else {
68
- await this.settings.delete('global', DemoMode.EnabledSettingKey);
69
- await this.broadcast('exit');
97
+ await this.settings.delete("global", DemoMode.EnabledSettingKey);
98
+ await this.broadcast("exit");
70
99
  }
71
100
  }
72
101
 
73
- public async broadcast(command: string, extra?: Record<string, string>): Promise<void> {
102
+ public async broadcast(
103
+ command: string,
104
+ extra?: Record<string, string>
105
+ ): Promise<void> {
74
106
  await this.adb.subprocess.spawnAndWaitLegacy([
75
- 'am',
76
- 'broadcast',
77
- '-a',
78
- 'com.android.systemui.demo',
79
- '-e',
80
- 'command',
107
+ "am",
108
+ "broadcast",
109
+ "-a",
110
+ "com.android.systemui.demo",
111
+ "-e",
112
+ "command",
81
113
  command,
82
- ...(extra ? Object.entries(extra).flatMap(([key, value]) => ['-e', key, value]) : []),
114
+ ...(extra
115
+ ? Object.entries(extra).flatMap(([key, value]) => [
116
+ "-e",
117
+ key,
118
+ value,
119
+ ])
120
+ : []),
83
121
  ]);
84
122
  }
85
123
 
86
124
  public async setBatteryLevel(level: number): Promise<void> {
87
- await this.broadcast('battery', { level: level.toString() });
125
+ await this.broadcast("battery", { level: level.toString() });
88
126
  }
89
127
 
90
128
  public async setBatteryCharging(value: boolean): Promise<void> {
91
- await this.broadcast('battery', { plugged: value.toString() });
129
+ await this.broadcast("battery", { plugged: value.toString() });
92
130
  }
93
131
 
94
132
  public async setPowerSaveMode(value: boolean): Promise<void> {
95
- await this.broadcast('battery', { powersave: value.toString() });
133
+ await this.broadcast("battery", { powersave: value.toString() });
96
134
  }
97
135
 
98
136
  public async setAirplaneMode(show: boolean): Promise<void> {
99
- await this.broadcast('network', { airplane: show ? 'show' : 'hide' });
137
+ await this.broadcast("network", { airplane: show ? "show" : "hide" });
100
138
  }
101
139
 
102
- public async setWifiSignalStrength(value: DemoModeSignalStrength): Promise<void> {
103
- await this.broadcast('network', { wifi: 'show', level: value });
140
+ public async setWifiSignalStrength(
141
+ value: DemoModeSignalStrength
142
+ ): Promise<void> {
143
+ await this.broadcast("network", { wifi: "show", level: value });
104
144
  }
105
145
 
106
- public async setMobileDataType(value: DemoModeMobileDataType): Promise<void> {
146
+ public async setMobileDataType(
147
+ value: DemoModeMobileDataType
148
+ ): Promise<void> {
107
149
  for (let i = 0; i < 2; i += 1) {
108
- await this.broadcast('network', {
109
- mobile: 'show',
110
- sims: '1',
111
- nosim: 'hide',
112
- slot: '0',
150
+ await this.broadcast("network", {
151
+ mobile: "show",
152
+ sims: "1",
153
+ nosim: "hide",
154
+ slot: "0",
113
155
  datatype: value,
114
- fully: 'true',
115
- roam: 'false',
116
- level: '4',
117
- inflate: 'false',
118
- activity: 'in',
119
- carriernetworkchange: 'hide',
156
+ fully: "true",
157
+ roam: "false",
158
+ level: "4",
159
+ inflate: "false",
160
+ activity: "in",
161
+ carriernetworkchange: "hide",
120
162
  });
121
163
  }
122
164
  }
123
165
 
124
- public async setMobileSignalStrength(value: DemoModeSignalStrength): Promise<void> {
125
- await this.broadcast('network', { mobile: 'show', level: value });
166
+ public async setMobileSignalStrength(
167
+ value: DemoModeSignalStrength
168
+ ): Promise<void> {
169
+ await this.broadcast("network", { mobile: "show", level: value });
126
170
  }
127
171
 
128
172
  public async setNoSimCardIcon(show: boolean): Promise<void> {
129
- await this.broadcast('network', { nosim: show ? 'show' : 'hide' });
173
+ await this.broadcast("network", { nosim: show ? "show" : "hide" });
130
174
  }
131
175
 
132
176
  public async setStatusBarMode(mode: DemoModeStatusBarMode): Promise<void> {
133
- await this.broadcast('bars', { mode });
177
+ await this.broadcast("bars", { mode });
134
178
  }
135
179
 
136
180
  public async setVibrateModeEnabled(value: boolean): Promise<void> {
137
181
  // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java;l=103
138
- await this.broadcast('status', { volume: value ? 'vibrate' : 'hide' });
182
+ await this.broadcast("status", { volume: value ? "vibrate" : "hide" });
139
183
  }
140
184
 
141
185
  public async setBluetoothConnected(value: boolean): Promise<void> {
142
186
  // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java;l=114
143
- await this.broadcast('status', { bluetooth: value ? 'connected' : 'hide' });
187
+ await this.broadcast("status", {
188
+ bluetooth: value ? "connected" : "hide",
189
+ });
144
190
  }
145
191
 
146
192
  public async setLocatingIcon(show: boolean): Promise<void> {
147
- await this.broadcast('status', { location: show ? 'show' : 'hide' });
193
+ await this.broadcast("status", { location: show ? "show" : "hide" });
148
194
  }
149
195
 
150
196
  public async setAlarmIcon(show: boolean): Promise<void> {
151
- await this.broadcast('status', { alarm: show ? 'show' : 'hide' });
197
+ await this.broadcast("status", { alarm: show ? "show" : "hide" });
152
198
  }
153
199
 
154
200
  public async setSyncingIcon(show: boolean): Promise<void> {
155
- await this.broadcast('status', { sync: show ? 'show' : 'hide' });
201
+ await this.broadcast("status", { sync: show ? "show" : "hide" });
156
202
  }
157
203
 
158
204
  public async setMuteIcon(show: boolean): Promise<void> {
159
- await this.broadcast('status', { mute: show ? 'show' : 'hide' });
205
+ await this.broadcast("status", { mute: show ? "show" : "hide" });
160
206
  }
161
207
 
162
208
  public async setSpeakerPhoneIcon(show: boolean): Promise<void> {
163
- await this.broadcast('status', { speakerphone: show ? 'show' : 'hide' });
209
+ await this.broadcast("status", {
210
+ speakerphone: show ? "show" : "hide",
211
+ });
164
212
  }
165
213
 
166
214
  public async setNotificationsVisibility(show: boolean): Promise<void> {
167
215
  // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java;l=3131
168
- await this.broadcast('notifications', { visible: show.toString() });
216
+ await this.broadcast("notifications", { visible: show.toString() });
169
217
  }
170
218
 
171
219
  public async setTime(hour: number, minute: number): Promise<void> {
172
- await this.broadcast('clock', {
220
+ await this.broadcast("clock", {
173
221
  // cspell: disable-next-line
174
222
  hhmm:
175
- hour.toString().padStart(2, '0') +
176
- minute.toString().padStart(2, '0'),
223
+ hour.toString().padStart(2, "0") +
224
+ minute.toString().padStart(2, "0"),
177
225
  });
178
226
  }
179
227
  }
package/src/logcat.ts CHANGED
@@ -1,8 +1,18 @@
1
1
  // cspell: ignore logcat
2
2
 
3
- import { AdbCommandBase, AdbSubprocessNoneProtocol } from '@yume-chan/adb';
4
- import { BufferedTransformStream, DecodeUtf8Stream, SplitStringStream, WrapReadableStream, WritableStream, type ReadableStream } from '@yume-chan/stream-extra';
5
- import Struct, { decodeUtf8, StructAsyncDeserializeStream } from '@yume-chan/struct';
3
+ import { AdbCommandBase, AdbSubprocessNoneProtocol } from "@yume-chan/adb";
4
+ import {
5
+ BufferedTransformStream,
6
+ DecodeUtf8Stream,
7
+ SplitStringStream,
8
+ WrapReadableStream,
9
+ WritableStream,
10
+ type ReadableStream,
11
+ } from "@yume-chan/stream-extra";
12
+ import Struct, {
13
+ decodeUtf8,
14
+ type StructAsyncDeserializeStream,
15
+ } from "@yume-chan/struct";
6
16
 
7
17
  // `adb logcat` is an alias to `adb shell logcat`
8
18
  // so instead of adding to core library, it's implemented here
@@ -34,17 +44,18 @@ export enum AndroidLogPriority {
34
44
  }
35
45
 
36
46
  // https://cs.android.com/android/platform/superproject/+/master:system/logging/liblog/logprint.cpp;l=140;drc=8dbf3b2bb6b6d1652d9797e477b9abd03278bb79
37
- export const AndroidLogPriorityToCharacter: Record<AndroidLogPriority, string> = {
38
- [AndroidLogPriority.Unknown]: '?',
39
- [AndroidLogPriority.Default]: '?',
40
- [AndroidLogPriority.Verbose]: 'V',
41
- [AndroidLogPriority.Debug]: 'D',
42
- [AndroidLogPriority.Info]: 'I',
43
- [AndroidLogPriority.Warn]: 'W',
44
- [AndroidLogPriority.Error]: 'E',
45
- [AndroidLogPriority.Fatal]: 'F',
46
- [AndroidLogPriority.Silent]: 'S',
47
- };
47
+ export const AndroidLogPriorityToCharacter: Record<AndroidLogPriority, string> =
48
+ {
49
+ [AndroidLogPriority.Unknown]: "?",
50
+ [AndroidLogPriority.Default]: "?",
51
+ [AndroidLogPriority.Verbose]: "V",
52
+ [AndroidLogPriority.Debug]: "D",
53
+ [AndroidLogPriority.Info]: "I",
54
+ [AndroidLogPriority.Warn]: "W",
55
+ [AndroidLogPriority.Error]: "E",
56
+ [AndroidLogPriority.Fatal]: "F",
57
+ [AndroidLogPriority.Silent]: "S",
58
+ };
48
59
 
49
60
  export enum LogcatFormat {
50
61
  Brief,
@@ -54,7 +65,7 @@ export enum LogcatFormat {
54
65
  Raw,
55
66
  Time,
56
67
  ThreadTime,
57
- Long
68
+ Long,
58
69
  }
59
70
 
60
71
  export interface LogcatFormatModifiers {
@@ -76,23 +87,25 @@ export interface LogcatOptions {
76
87
  const NANOSECONDS_PER_SECOND = BigInt(1e9);
77
88
 
78
89
  // https://cs.android.com/android/platform/superproject/+/master:system/logging/liblog/include/log/log_read.h;l=39;drc=82b5738732161dbaafb2e2f25cce19cd26b9157d
79
- export const LoggerEntry =
80
- new Struct({ littleEndian: true })
81
- .uint16('payloadSize')
82
- .uint16('headerSize')
83
- .int32('pid')
84
- .uint32('tid')
85
- .uint32('second')
86
- .uint32('nanoseconds')
87
- .uint32('logId')
88
- .uint32('uid')
89
- .extra({
90
- get timestamp() {
91
- return BigInt(this.second) * NANOSECONDS_PER_SECOND + BigInt(this.nanoseconds);
92
- },
93
- });
94
-
95
- export type LoggerEntry = typeof LoggerEntry['TDeserializeResult'];
90
+ export const LoggerEntry = new Struct({ littleEndian: true })
91
+ .uint16("payloadSize")
92
+ .uint16("headerSize")
93
+ .int32("pid")
94
+ .uint32("tid")
95
+ .uint32("second")
96
+ .uint32("nanoseconds")
97
+ .uint32("logId")
98
+ .uint32("uid")
99
+ .extra({
100
+ get timestamp() {
101
+ return (
102
+ BigInt(this.second) * NANOSECONDS_PER_SECOND +
103
+ BigInt(this.nanoseconds)
104
+ );
105
+ },
106
+ });
107
+
108
+ export type LoggerEntry = typeof LoggerEntry["TDeserializeResult"];
96
109
 
97
110
  // https://cs.android.com/android/platform/superproject/+/master:system/logging/liblog/logprint.cpp;drc=bbe77d66e7bee8bd1f0bc7e5492b5376b0207ef6;bpv=0
98
111
  export interface AndroidLogEntry extends LoggerEntry {
@@ -107,24 +120,28 @@ export function formatAndroidLogEntry(
107
120
  format: LogcatFormat = LogcatFormat.Brief,
108
121
  modifier?: LogcatFormatModifiers
109
122
  ) {
110
- const uid = modifier?.uid ? `${entry.uid.toString().padStart(5)}:` : '';
123
+ const uid = modifier?.uid ? `${entry.uid.toString().padStart(5)}:` : "";
111
124
 
112
125
  switch (format) {
113
126
  // TODO: implement other formats
114
127
  default:
115
- return `${AndroidLogPriorityToCharacter[entry.priority]}/${entry.tag.padEnd(8)}(${uid}${entry.pid.toString().padStart(5)}): ${entry.message}`;
128
+ return `${
129
+ AndroidLogPriorityToCharacter[entry.priority]
130
+ }/${entry.tag.padEnd(8)}(${uid}${entry.pid
131
+ .toString()
132
+ .padStart(5)}): ${entry.message}`;
116
133
  }
117
134
  }
118
135
 
119
136
  function findTagEnd(payload: Uint8Array) {
120
- for (const separator of [0, ' '.charCodeAt(0), ':'.charCodeAt(0)]) {
137
+ for (const separator of [0, " ".charCodeAt(0), ":".charCodeAt(0)]) {
121
138
  const index = payload.indexOf(separator);
122
139
  if (index !== -1) {
123
140
  return index;
124
141
  }
125
142
  }
126
143
 
127
- const index = payload.findIndex(x => x >= 0x7f);
144
+ const index = payload.findIndex((x) => x >= 0x7f);
128
145
  if (index !== -1) {
129
146
  return index;
130
147
  }
@@ -132,8 +149,12 @@ function findTagEnd(payload: Uint8Array) {
132
149
  return payload.length;
133
150
  }
134
151
 
135
- export async function deserializeAndroidLogEntry(stream: StructAsyncDeserializeStream): Promise<AndroidLogEntry> {
136
- const entry = await LoggerEntry.deserialize(stream) as unknown as AndroidLogEntry;
152
+ export async function deserializeAndroidLogEntry(
153
+ stream: StructAsyncDeserializeStream
154
+ ): Promise<AndroidLogEntry> {
155
+ const entry = (await LoggerEntry.deserialize(
156
+ stream
157
+ )) as unknown as AndroidLogEntry;
137
158
  if (entry.headerSize !== LoggerEntry.size) {
138
159
  await stream.read(entry.headerSize - LoggerEntry.size);
139
160
  }
@@ -146,7 +167,10 @@ export async function deserializeAndroidLogEntry(stream: StructAsyncDeserializeS
146
167
  payload = payload.subarray(1);
147
168
  const tagEnd = findTagEnd(payload);
148
169
  entry.tag = decodeUtf8(payload.subarray(0, tagEnd));
149
- entry.message = tagEnd < payload.length - 1 ? decodeUtf8(payload.subarray(tagEnd + 1)) : '';
170
+ entry.message =
171
+ tagEnd < payload.length - 1
172
+ ? decodeUtf8(payload.subarray(tagEnd + 1))
173
+ : "";
150
174
  return entry;
151
175
  }
152
176
 
@@ -166,72 +190,91 @@ export class Logcat extends AdbCommandBase {
166
190
 
167
191
  public static logNameToId(name: string): LogId {
168
192
  const key = name[0]!.toUpperCase() + name.substring(1);
169
- return (LogId as any)[key];
193
+ return LogId[key as keyof typeof LogId];
170
194
  }
171
195
 
172
196
  public static joinLogId(ids: LogId[]): string {
173
- return ids.map(id => Logcat.logIdToName(id)).join(',');
197
+ return ids.map((id) => Logcat.logIdToName(id)).join(",");
174
198
  }
175
199
 
176
200
  public static parseSize(value: number, multiplier: string): number {
177
- const MULTIPLIERS = ['', 'Ki', 'Mi', 'Gi'];
201
+ const MULTIPLIERS = ["", "Ki", "Mi", "Gi"];
178
202
  return value * 1024 ** (MULTIPLIERS.indexOf(multiplier) || 0);
179
203
  }
180
204
 
181
205
  // TODO: logcat: Support output format before Android 10
182
206
  // ref https://android-review.googlesource.com/c/platform/system/core/+/748128
183
- public static readonly LOG_SIZE_REGEX_10 = /(.*): ring buffer is (.*) (.*)B \((.*) (.*)B consumed\), max entry is (.*) B, max payload is (.*) B/;
207
+ public static readonly LOG_SIZE_REGEX_10 =
208
+ /(.*): ring buffer is (.*) (.*)B \((.*) (.*)B consumed\), max entry is (.*) B, max payload is (.*) B/;
184
209
 
185
210
  // Android 11 added `readable` part
186
211
  // ref https://android-review.googlesource.com/c/platform/system/core/+/1390940
187
- public static readonly LOG_SIZE_REGEX_11 = /(.*): ring buffer is (.*) (.*)B \((.*) (.*)B consumed, (.*) (.*)B readable\), max entry is (.*) B, max payload is (.*) B/;
212
+ public static readonly LOG_SIZE_REGEX_11 =
213
+ /(.*): ring buffer is (.*) (.*)B \((.*) (.*)B consumed, (.*) (.*)B readable\), max entry is (.*) B, max payload is (.*) B/;
188
214
 
189
215
  public async getLogSize(ids?: LogId[]): Promise<LogSize[]> {
190
216
  const { stdout } = await this.adb.subprocess.spawn([
191
- 'logcat',
192
- '-g',
193
- ...(ids ? ['-b', Logcat.joinLogId(ids)] : [])
217
+ "logcat",
218
+ "-g",
219
+ ...(ids ? ["-b", Logcat.joinLogId(ids)] : []),
194
220
  ]);
195
221
 
196
222
  const result: LogSize[] = [];
197
223
  await stdout
198
224
  .pipeThrough(new DecodeUtf8Stream())
199
- .pipeThrough(new SplitStringStream('\n'))
200
- .pipeTo(new WritableStream({
201
- write(chunk) {
202
- let match = chunk.match(Logcat.LOG_SIZE_REGEX_11);
203
- if (match) {
204
- result.push({
205
- id: Logcat.logNameToId(match[1]!),
206
- size: Logcat.parseSize(Number.parseInt(match[2]!, 10), match[3]!),
207
- readable: Logcat.parseSize(Number.parseInt(match[6]!, 10), match[7]!),
208
- consumed: Logcat.parseSize(Number.parseInt(match[4]!, 10), match[5]!),
209
- maxEntrySize: parseInt(match[8]!, 10),
210
- maxPayloadSize: parseInt(match[9]!, 10),
211
- });
212
- }
213
-
214
- match = chunk.match(Logcat.LOG_SIZE_REGEX_10);
215
- if (match) {
216
- result.push({
217
- id: Logcat.logNameToId(match[1]!),
218
- size: Logcat.parseSize(Number.parseInt(match[2]!, 10), match[3]!),
219
- consumed: Logcat.parseSize(Number.parseInt(match[4]!, 10), match[5]!),
220
- maxEntrySize: parseInt(match[6]!, 10),
221
- maxPayloadSize: parseInt(match[7]!, 10),
222
- });
223
- }
224
- },
225
- }));
225
+ .pipeThrough(new SplitStringStream("\n"))
226
+ .pipeTo(
227
+ new WritableStream({
228
+ write(chunk) {
229
+ let match = chunk.match(Logcat.LOG_SIZE_REGEX_11);
230
+ if (match) {
231
+ result.push({
232
+ id: Logcat.logNameToId(match[1]!),
233
+ size: Logcat.parseSize(
234
+ Number.parseInt(match[2]!, 10),
235
+ match[3]!
236
+ ),
237
+ readable: Logcat.parseSize(
238
+ Number.parseInt(match[6]!, 10),
239
+ match[7]!
240
+ ),
241
+ consumed: Logcat.parseSize(
242
+ Number.parseInt(match[4]!, 10),
243
+ match[5]!
244
+ ),
245
+ maxEntrySize: parseInt(match[8]!, 10),
246
+ maxPayloadSize: parseInt(match[9]!, 10),
247
+ });
248
+ }
249
+
250
+ match = chunk.match(Logcat.LOG_SIZE_REGEX_10);
251
+ if (match) {
252
+ result.push({
253
+ id: Logcat.logNameToId(match[1]!),
254
+ size: Logcat.parseSize(
255
+ Number.parseInt(match[2]!, 10),
256
+ match[3]!
257
+ ),
258
+ consumed: Logcat.parseSize(
259
+ Number.parseInt(match[4]!, 10),
260
+ match[5]!
261
+ ),
262
+ maxEntrySize: parseInt(match[6]!, 10),
263
+ maxPayloadSize: parseInt(match[7]!, 10),
264
+ });
265
+ }
266
+ },
267
+ })
268
+ );
226
269
 
227
270
  return result;
228
271
  }
229
272
 
230
273
  public async clear(ids?: LogId[]) {
231
274
  await this.adb.subprocess.spawnAndWait([
232
- 'logcat',
233
- '-c',
234
- ...(ids ? ['-b', Logcat.joinLogId(ids)] : []),
275
+ "logcat",
276
+ "-c",
277
+ ...(ids ? ["-b", Logcat.joinLogId(ids)] : []),
235
278
  ]);
236
279
  }
237
280
 
@@ -239,18 +282,25 @@ export class Logcat extends AdbCommandBase {
239
282
  return new WrapReadableStream(async () => {
240
283
  // TODO: make `spawn` return synchronously with streams pending
241
284
  // so it's easier to chain them.
242
- const { stdout } = await this.adb.subprocess.spawn([
243
- 'logcat',
244
- '-B',
245
- ...(options?.pid ? ['--pid', options.pid.toString()] : []),
246
- ...(options?.ids ? ['-b', Logcat.joinLogId(options.ids)] : [])
247
- ], {
248
- // PERF: None protocol is 150% faster then Shell protocol
249
- protocols: [AdbSubprocessNoneProtocol],
250
- });
285
+ const { stdout } = await this.adb.subprocess.spawn(
286
+ [
287
+ "logcat",
288
+ "-B",
289
+ ...(options?.pid ? ["--pid", options.pid.toString()] : []),
290
+ ...(options?.ids
291
+ ? ["-b", Logcat.joinLogId(options.ids)]
292
+ : []),
293
+ ],
294
+ {
295
+ // PERF: None protocol is 150% faster then Shell protocol
296
+ protocols: [AdbSubprocessNoneProtocol],
297
+ }
298
+ );
251
299
  return stdout;
252
- }).pipeThrough(new BufferedTransformStream(stream => {
253
- return deserializeAndroidLogEntry(stream);
254
- }));
300
+ }).pipeThrough(
301
+ new BufferedTransformStream((stream) => {
302
+ return deserializeAndroidLogEntry(stream);
303
+ })
304
+ );
255
305
  }
256
306
  }
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "./node_modules/@yume-chan/tsconfig/tsconfig.base.json",
3
+ }