@yume-chan/android-bin 2.1.0 → 3.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +4 -1
  3. package/esm/am.d.ts +20 -15
  4. package/esm/am.d.ts.map +1 -1
  5. package/esm/am.js +60 -13
  6. package/esm/am.js.map +1 -1
  7. package/esm/bu.d.ts +22 -18
  8. package/esm/bu.d.ts.map +1 -1
  9. package/esm/bu.js +10 -4
  10. package/esm/bu.js.map +1 -1
  11. package/esm/bug-report.d.ts +21 -20
  12. package/esm/bug-report.d.ts.map +1 -1
  13. package/esm/bug-report.js +15 -21
  14. package/esm/bug-report.js.map +1 -1
  15. package/esm/cmd/index.d.ts +2 -0
  16. package/esm/cmd/index.d.ts.map +1 -0
  17. package/esm/cmd/index.js +2 -0
  18. package/esm/cmd/index.js.map +1 -0
  19. package/esm/cmd/none.d.ts +5 -0
  20. package/esm/cmd/none.d.ts.map +1 -0
  21. package/esm/cmd/none.js +39 -0
  22. package/esm/cmd/none.js.map +1 -0
  23. package/esm/cmd/service.d.ts +29 -0
  24. package/esm/cmd/service.d.ts.map +1 -0
  25. package/esm/cmd/service.js +24 -0
  26. package/esm/cmd/service.js.map +1 -0
  27. package/esm/cmd/shell.d.ts +5 -0
  28. package/esm/cmd/shell.d.ts.map +1 -0
  29. package/esm/cmd/shell.js +43 -0
  30. package/esm/cmd/shell.js.map +1 -0
  31. package/esm/cmd/utils.d.ts +5 -0
  32. package/esm/cmd/utils.d.ts.map +1 -0
  33. package/esm/cmd/utils.js +24 -0
  34. package/esm/cmd/utils.js.map +1 -0
  35. package/esm/demo-mode.d.ts +3 -4
  36. package/esm/demo-mode.d.ts.map +1 -1
  37. package/esm/demo-mode.js +13 -21
  38. package/esm/demo-mode.js.map +1 -1
  39. package/esm/dumpsys.d.ts +4 -2
  40. package/esm/dumpsys.d.ts.map +1 -1
  41. package/esm/dumpsys.js +13 -10
  42. package/esm/dumpsys.js.map +1 -1
  43. package/esm/index.d.ts +1 -1
  44. package/esm/index.d.ts.map +1 -1
  45. package/esm/index.js +1 -1
  46. package/esm/index.js.map +1 -1
  47. package/esm/intent.d.ts +37 -9
  48. package/esm/intent.d.ts.map +1 -1
  49. package/esm/intent.js +116 -53
  50. package/esm/intent.js.map +1 -1
  51. package/esm/logcat.d.ts +4 -2
  52. package/esm/logcat.d.ts.map +1 -1
  53. package/esm/logcat.js +9 -6
  54. package/esm/logcat.js.map +1 -1
  55. package/esm/overlay-display.d.ts +17 -14
  56. package/esm/overlay-display.d.ts.map +1 -1
  57. package/esm/overlay-display.js +2 -4
  58. package/esm/overlay-display.js.map +1 -1
  59. package/esm/pm.d.ts +131 -168
  60. package/esm/pm.d.ts.map +1 -1
  61. package/esm/pm.js +229 -112
  62. package/esm/pm.js.map +1 -1
  63. package/esm/settings.d.ts +1 -2
  64. package/esm/settings.d.ts.map +1 -1
  65. package/esm/settings.js +9 -9
  66. package/esm/settings.js.map +1 -1
  67. package/esm/utils.d.ts +4 -1
  68. package/esm/utils.d.ts.map +1 -1
  69. package/esm/utils.js +24 -13
  70. package/esm/utils.js.map +1 -1
  71. package/package.json +9 -9
  72. package/src/am.ts +94 -34
  73. package/src/bu.ts +31 -20
  74. package/src/bug-report.ts +42 -42
  75. package/src/cmd/index.ts +1 -0
  76. package/src/cmd/none.ts +62 -0
  77. package/src/cmd/service.ts +54 -0
  78. package/src/cmd/shell.ts +67 -0
  79. package/src/cmd/utils.ts +35 -0
  80. package/src/demo-mode.ts +13 -24
  81. package/src/dumpsys.ts +16 -10
  82. package/src/index.ts +1 -1
  83. package/src/intent.ts +187 -49
  84. package/src/logcat.ts +12 -6
  85. package/src/overlay-display.ts +21 -19
  86. package/src/pm.ts +374 -301
  87. package/src/settings.ts +11 -10
  88. package/src/utils.ts +30 -13
  89. package/tsconfig.build.json +0 -11
  90. package/CHANGELOG.md +0 -181
  91. package/esm/cmd.d.ts +0 -23
  92. package/esm/cmd.d.ts.map +0 -1
  93. package/esm/cmd.js +0 -104
  94. package/esm/cmd.js.map +0 -1
  95. package/src/cmd.ts +0 -166
  96. package/tsconfig.build.tsbuildinfo +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
package/esm/utils.d.ts CHANGED
@@ -1,4 +1,7 @@
1
- export declare function buildArguments<T>(commands: readonly string[], options: Partial<T> | undefined, map: Partial<Record<keyof T, string>>): string[];
1
+ export declare function buildCommand<T>(commands: readonly string[], options: Partial<T> | undefined, map: Partial<Record<keyof T, string>>): string[];
2
2
  export type SingleUser = number | "current";
3
3
  export type SingleUserOrAll = SingleUser | "all";
4
+ export type Optional<T extends object> = {
5
+ [K in keyof T]?: T[K] | undefined;
6
+ };
4
7
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,CAAC,EAC5B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,EAC/B,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GACtC,MAAM,EAAE,CAqBV;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;AAC5C,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,KAAK,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,CAAC,EAC1B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,EAC/B,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GACtC,MAAM,EAAE,CAoCV;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;AAC5C,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,KAAK,CAAC;AAEjD,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;CAAE,CAAC"}
package/esm/utils.js CHANGED
@@ -1,20 +1,31 @@
1
- export function buildArguments(commands, options, map) {
1
+ export function buildCommand(commands, options, map) {
2
2
  const args = commands.slice();
3
3
  if (options) {
4
4
  for (const [key, value] of Object.entries(options)) {
5
- if (value) {
6
- const option = map[key];
7
- if (option) {
8
- args.push(option);
9
- switch (typeof value) {
10
- case "number":
11
- args.push(value.toString());
12
- break;
13
- case "string":
14
- args.push(value);
15
- break;
5
+ if (value === undefined || value === null) {
6
+ continue;
7
+ }
8
+ const option = map[key];
9
+ // Empty string means positional argument,
10
+ // they must be added at the end,
11
+ // so let the caller handle it.
12
+ if (option === undefined || option === "") {
13
+ continue;
14
+ }
15
+ switch (typeof value) {
16
+ case "boolean":
17
+ if (value) {
18
+ args.push(option);
16
19
  }
17
- }
20
+ break;
21
+ case "number":
22
+ args.push(option, value.toString());
23
+ break;
24
+ case "string":
25
+ args.push(option, value);
26
+ break;
27
+ default:
28
+ throw new Error(`Unsupported type for option ${key}: ${typeof value}`);
18
29
  }
19
30
  }
20
31
  }
package/esm/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAC1B,QAA2B,EAC3B,OAA+B,EAC/B,GAAqC;IAErC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC9B,IAAI,OAAO,EAAE,CAAC;QACV,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,IAAI,KAAK,EAAE,CAAC;gBACR,MAAM,MAAM,GAAG,GAAG,CAAC,GAAc,CAAC,CAAC;gBACnC,IAAI,MAAM,EAAE,CAAC;oBACT,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAClB,QAAQ,OAAO,KAAK,EAAE,CAAC;wBACnB,KAAK,QAAQ;4BACT,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;4BAC5B,MAAM;wBACV,KAAK,QAAQ;4BACT,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;4BACjB,MAAM;oBACd,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CACxB,QAA2B,EAC3B,OAA+B,EAC/B,GAAqC;IAErC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC9B,IAAI,OAAO,EAAE,CAAC;QACV,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACxC,SAAS;YACb,CAAC;YAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAc,CAAC,CAAC;YACnC,0CAA0C;YAC1C,iCAAiC;YACjC,+BAA+B;YAC/B,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;gBACxC,SAAS;YACb,CAAC;YAED,QAAQ,OAAO,KAAK,EAAE,CAAC;gBACnB,KAAK,SAAS;oBACV,IAAI,KAAK,EAAE,CAAC;wBACR,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBACtB,CAAC;oBACD,MAAM;gBACV,KAAK,QAAQ;oBACT,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;oBACpC,MAAM;gBACV,KAAK,QAAQ;oBACT,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;oBACzB,MAAM;gBACV;oBACI,MAAM,IAAI,KAAK,CACX,+BAA+B,GAAG,KAAK,OAAO,KAAK,EAAE,CACxD,CAAC;YACV,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yume-chan/android-bin",
3
- "version": "2.1.0",
3
+ "version": "3.0.0-beta.1",
4
4
  "description": "Wrappers for Android built-in executables.",
5
5
  "keywords": [
6
6
  "adb",
@@ -26,20 +26,20 @@
26
26
  "types": "esm/index.d.ts",
27
27
  "sideEffects": false,
28
28
  "dependencies": {
29
- "@yume-chan/stream-extra": "^2.1.0",
30
- "@yume-chan/struct": "^2.0.1",
31
- "@yume-chan/adb": "^2.1.0"
29
+ "@yume-chan/stream-extra": "3.0.0-beta.1",
30
+ "@yume-chan/adb": "3.0.0-beta.1",
31
+ "@yume-chan/struct": "3.0.0-beta.1"
32
32
  },
33
33
  "devDependencies": {
34
- "@types/node": "^24.0.1",
35
- "prettier": "^3.5.3",
36
- "typescript": "^5.8.3",
37
- "@yume-chan/test-runner": "^1.0.0",
34
+ "@types/node": "^26.1.1",
35
+ "prettier": "^3.9.6",
36
+ "typescript": "^6.0.3",
38
37
  "@yume-chan/eslint-config": "^1.0.0",
38
+ "@yume-chan/test-runner": "^1.0.0",
39
39
  "@yume-chan/tsconfig": "^1.0.0"
40
40
  },
41
41
  "scripts": {
42
- "build": "tsc -b tsconfig.build.json",
42
+ "build": "tsc -p tsconfig.build.json",
43
43
  "lint": "run-eslint && prettier src/**/*.ts --write --tab-width 4",
44
44
  "test": "run-test"
45
45
  }
package/src/am.ts CHANGED
@@ -1,21 +1,15 @@
1
- import type { Adb } from "@yume-chan/adb";
2
- import { AdbServiceBase } from "@yume-chan/adb";
3
-
4
- import { CmdNoneProtocolService } from "./cmd.js";
5
- import type { IntentBuilder } from "./intent.js";
6
- import type { SingleUser } from "./utils.js";
7
- import { buildArguments } from "./utils.js";
8
-
9
- export interface ActivityManagerStartActivityOptions {
10
- displayId?: number;
11
- windowingMode?: number;
12
- forceStop?: boolean;
13
- user?: SingleUser;
14
- intent: IntentBuilder;
15
- }
1
+ import type { Adb, AdbNoneProtocolProcess } from "@yume-chan/adb";
2
+ import { escapeArg } from "@yume-chan/adb";
3
+ import { SplitStringStream, TextDecoderStream } from "@yume-chan/stream-extra";
4
+
5
+ import { Cmd } from "./cmd/index.js";
6
+ import type { Intent } from "./intent.js";
7
+ import { serializeIntent } from "./intent.js";
8
+ import type { SingleUser, SingleUserOrAll } from "./utils.js";
9
+ import { buildCommand } from "./utils.js";
16
10
 
17
11
  const START_ACTIVITY_OPTIONS_MAP: Partial<
18
- Record<keyof ActivityManagerStartActivityOptions, string>
12
+ Record<keyof ActivityManager.StartActivityOptions, string>
19
13
  > = {
20
14
  displayId: "--display",
21
15
  windowingMode: "--windowingMode",
@@ -23,42 +17,108 @@ const START_ACTIVITY_OPTIONS_MAP: Partial<
23
17
  user: "--user",
24
18
  };
25
19
 
26
- export class ActivityManager extends AdbServiceBase {
27
- static ServiceName = "activity";
28
- static CommandName = "am";
20
+ export class ActivityManager {
21
+ static readonly ServiceName = "activity";
22
+ static readonly CommandName = "am";
29
23
 
30
- #cmd: CmdNoneProtocolService;
24
+ readonly #adb: Adb;
31
25
 
32
- constructor(adb: Adb) {
33
- super(adb);
34
- this.#cmd = new CmdNoneProtocolService(
35
- adb,
36
- ActivityManager.CommandName,
37
- );
26
+ #apiLevel: number | undefined;
27
+ #cmd: Cmd.NoneProtocolService;
28
+
29
+ constructor(adb: Adb, apiLevel?: number) {
30
+ this.#adb = adb;
31
+ this.#apiLevel = apiLevel;
32
+ this.#cmd = Cmd.createNoneProtocol(adb, ActivityManager.CommandName);
38
33
  }
39
34
 
40
35
  async startActivity(
41
- options: ActivityManagerStartActivityOptions,
36
+ options: ActivityManager.StartActivityOptions,
42
37
  ): Promise<void> {
43
- let args = buildArguments(
44
- [ActivityManager.ServiceName, "start-activity", "-W"],
38
+ // Android 8 added "start-activity" alias to "start"
39
+ // but we want to use the most compatible one.
40
+ const command = buildCommand(
41
+ [ActivityManager.ServiceName, "start", "-W"],
45
42
  options,
46
43
  START_ACTIVITY_OPTIONS_MAP,
47
44
  );
48
45
 
49
- args = args.concat(options.intent.build());
46
+ for (const arg of serializeIntent(options.intent)) {
47
+ command.push(arg);
48
+ }
50
49
 
51
- const output = await this.#cmd
52
- .spawnWaitText(args)
53
- .then((output) => output.trim());
50
+ // Android 7 supports `cmd activity` but not `cmd activity start` command
51
+ let process: AdbNoneProtocolProcess;
52
+ if (this.#apiLevel !== undefined && this.#apiLevel <= 25) {
53
+ command[0] = ActivityManager.CommandName;
54
+ process = await this.#adb.subprocess.noneProtocol.spawn(
55
+ command.map(escapeArg),
56
+ );
57
+ } else {
58
+ process = await this.#cmd.spawn(command);
59
+ }
54
60
 
55
- for (const line of output) {
61
+ const lines = process.output
62
+ .pipeThrough(new TextDecoderStream())
63
+ .pipeThrough(new SplitStringStream("\n", { trim: true }));
64
+
65
+ for await (const line of lines) {
56
66
  if (line.startsWith("Error:")) {
67
+ // Exit from the `for await` loop will cancel `lines`,
68
+ // and subsequently, `process`, which is fine, as the work is already done
57
69
  throw new Error(line.substring("Error:".length).trim());
58
70
  }
71
+
59
72
  if (line === "Complete") {
73
+ // Same as above
60
74
  return;
61
75
  }
62
76
  }
77
+
78
+ // Ensure the subprocess exits before returning
79
+ await process.exited;
80
+ }
81
+
82
+ async broadcast(
83
+ intent: Intent,
84
+ options?: { user?: SingleUserOrAll; receiverPermission?: string },
85
+ ) {
86
+ const command = [ActivityManager.ServiceName, "broadcast"];
87
+
88
+ if (options) {
89
+ if (options.user !== undefined) {
90
+ command.push("--user", options.user.toString());
91
+ }
92
+ if (options.receiverPermission) {
93
+ command.push(
94
+ "--receiver-permission",
95
+ options.receiverPermission,
96
+ );
97
+ }
98
+ }
99
+
100
+ for (const arg of serializeIntent(intent)) {
101
+ command.push(arg);
102
+ }
103
+
104
+ // Android 7 supports `cmd activity` but not `cmd activity broadcast` command
105
+ if (this.#apiLevel !== undefined && this.#apiLevel <= 25) {
106
+ command[0] = ActivityManager.CommandName;
107
+ await this.#adb.subprocess.noneProtocol
108
+ .spawn(command.map(escapeArg))
109
+ .wait();
110
+ } else {
111
+ await this.#cmd.spawn(command).wait();
112
+ }
113
+ }
114
+ }
115
+
116
+ export namespace ActivityManager {
117
+ export interface StartActivityOptions {
118
+ displayId?: number;
119
+ windowingMode?: number;
120
+ forceStop?: boolean;
121
+ user?: SingleUser;
122
+ intent: Intent;
63
123
  }
64
124
  }
package/src/bu.ts CHANGED
@@ -1,28 +1,18 @@
1
- import { AdbServiceBase } from "@yume-chan/adb";
1
+ import type { Adb } from "@yume-chan/adb";
2
2
  import type { MaybeConsumable, ReadableStream } from "@yume-chan/stream-extra";
3
3
 
4
- export interface AdbBackupOptions {
5
- user: number;
6
- saveSharedStorage?: boolean;
7
- saveWidgets?: boolean;
8
- packages: readonly string[] | "user" | "all";
9
- savePackageApk: boolean;
10
- savePackageObb: boolean;
11
- savePackageKeyValue: boolean;
12
- compress: boolean;
13
- }
4
+ export class AdbBackup {
5
+ readonly #adb: Adb;
14
6
 
15
- export interface AdbRestoreOptions {
16
- user: number;
17
- file: ReadableStream<MaybeConsumable<Uint8Array>>;
18
- }
7
+ constructor(adb: Adb) {
8
+ this.#adb = adb;
9
+ }
19
10
 
20
- export class AdbBackup extends AdbServiceBase {
21
11
  /**
22
12
  * User must confirm backup on device within 60 seconds.
23
13
  */
24
14
  async backup(
25
- options: AdbBackupOptions,
15
+ options: AdbBackup.BackupOptions,
26
16
  ): Promise<ReadableStream<Uint8Array>> {
27
17
  const args = ["bu", "backup"];
28
18
 
@@ -54,7 +44,7 @@ export class AdbBackup extends AdbServiceBase {
54
44
  args.push(...options.packages);
55
45
  }
56
46
 
57
- const process = await this.adb.subprocess.noneProtocol.spawn(args);
47
+ const process = await this.#adb.subprocess.noneProtocol.spawn(args);
58
48
  return process.output;
59
49
  }
60
50
 
@@ -62,11 +52,32 @@ export class AdbBackup extends AdbServiceBase {
62
52
  * User must enter the password (if any) and
63
53
  * confirm restore on device within 60 seconds.
64
54
  */
65
- restore(options: AdbRestoreOptions): Promise<string> {
55
+ restore(options: AdbBackup.RestoreOptions): Promise<string> {
66
56
  const args = ["bu", "restore"];
67
57
  if (options.user !== undefined) {
68
58
  args.push("--user", options.user.toString());
69
59
  }
70
- return this.adb.subprocess.noneProtocol.spawnWaitText(args);
60
+ return this.#adb.subprocess.noneProtocol
61
+ .spawn(args)
62
+ .wait({ stdin: options.file })
63
+ .toString();
64
+ }
65
+ }
66
+
67
+ export namespace AdbBackup {
68
+ export interface BackupOptions {
69
+ user?: number | undefined;
70
+ saveSharedStorage?: boolean | undefined;
71
+ saveWidgets?: boolean | undefined;
72
+ packages: readonly string[] | "user" | "all";
73
+ savePackageApk: boolean;
74
+ savePackageObb: boolean;
75
+ savePackageKeyValue: boolean;
76
+ compress: boolean;
77
+ }
78
+
79
+ export interface RestoreOptions {
80
+ user?: number | undefined;
81
+ file: ReadableStream<MaybeConsumable<Uint8Array>>;
71
82
  }
72
83
  }
package/src/bug-report.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  // cspell: ignore bugreport
2
2
  // cspell: ignore bugreportz
3
3
 
4
- import type { Adb, AdbSync } from "@yume-chan/adb";
5
- import { AdbServiceBase } from "@yume-chan/adb";
4
+ import type { Adb } from "@yume-chan/adb";
6
5
  import type { AbortSignal, ReadableStream } from "@yume-chan/stream-extra";
7
6
  import {
8
7
  AbortController,
@@ -13,25 +12,7 @@ import {
13
12
  WritableStream,
14
13
  } from "@yume-chan/stream-extra";
15
14
 
16
- export interface BugReportCapabilities {
17
- supportsBugReport: boolean;
18
- bugReportZVersion?: string | undefined;
19
- supportsBugReportZ: boolean;
20
- supportsBugReportZProgress: boolean;
21
- supportsBugReportZStream: boolean;
22
- }
23
-
24
- export interface BugReportZOptions {
25
- signal?: AbortSignal;
26
- /**
27
- * A callback that will be called when progress is updated.
28
- *
29
- * Specify `onProgress` when `supportsBugReportZProgress` is `false` will throw an error.
30
- */
31
- onProgress?: ((completed: string, total: string) => void) | undefined;
32
- }
33
-
34
- export class BugReport extends AdbServiceBase {
15
+ export class BugReport {
35
16
  static VERSION_REGEX: RegExp = /(\d+)\.(\d+)/;
36
17
 
37
18
  static BEGIN_REGEX: RegExp = /BEGIN:(.*)/;
@@ -57,10 +38,10 @@ export class BugReport extends AdbServiceBase {
57
38
  });
58
39
  }
59
40
 
60
- const result = await adb.subprocess.shellProtocol.spawnWaitText([
61
- "bugreportz",
62
- "-v",
63
- ]);
41
+ const result = await adb.subprocess.shellProtocol
42
+ .spawn(["bugreportz", "-v"])
43
+ .wait()
44
+ .toString();
64
45
  if (result.exitCode !== 0 || result.stderr === "") {
65
46
  return new BugReport(adb, {
66
47
  supportsBugReport: true,
@@ -95,6 +76,8 @@ export class BugReport extends AdbServiceBase {
95
76
  });
96
77
  }
97
78
 
79
+ readonly #adb: Adb;
80
+
98
81
  #supportsBugReport: boolean;
99
82
  /**
100
83
  * Gets whether the device supports flat (text file, non-zipped) bugreport.
@@ -145,8 +128,8 @@ export class BugReport extends AdbServiceBase {
145
128
  return this.#supportsBugReportZStream;
146
129
  }
147
130
 
148
- constructor(adb: Adb, capabilities: BugReportCapabilities) {
149
- super(adb);
131
+ constructor(adb: Adb, capabilities: BugReport.Capabilities) {
132
+ this.#adb = adb;
150
133
 
151
134
  this.#supportsBugReport = capabilities.supportsBugReport;
152
135
  this.#bugReportZVersion = capabilities.bugReportZVersion;
@@ -171,7 +154,7 @@ export class BugReport extends AdbServiceBase {
171
154
  return new WrapReadableStream(async () => {
172
155
  // https://cs.android.com/android/platform/superproject/+/master:frameworks/native/cmds/bugreport/bugreport.cpp;drc=9b73bf07d73dbab5b792632e1e233edbad77f5fd;bpv=0;bpt=0
173
156
  const process =
174
- await this.adb.subprocess.noneProtocol.spawn("bugreport");
157
+ await this.#adb.subprocess.noneProtocol.spawn("bugreport");
175
158
  return process.output;
176
159
  });
177
160
  }
@@ -184,7 +167,7 @@ export class BugReport extends AdbServiceBase {
184
167
  *
185
168
  * @returns The path to the generated bugreport file on device filesystem.
186
169
  */
187
- async bugReportZ(options?: BugReportZOptions): Promise<string> {
170
+ async bugReportZ(options?: BugReport.BugReportZOptions): Promise<string> {
188
171
  if (options?.signal?.aborted) {
189
172
  throw options?.signal.reason as Error;
190
173
  }
@@ -202,7 +185,7 @@ export class BugReport extends AdbServiceBase {
202
185
  }
203
186
 
204
187
  // `subprocess.shellProtocol` must be defined when `this.#supportsBugReportZ` is `true`
205
- const process = await this.adb.subprocess.shellProtocol!.spawn(args);
188
+ const process = await this.#adb.subprocess.shellProtocol!.spawn(args);
206
189
 
207
190
  options?.signal?.addEventListener("abort", () => {
208
191
  void process.kill();
@@ -211,10 +194,10 @@ export class BugReport extends AdbServiceBase {
211
194
  let filename: string | undefined;
212
195
  let error: string | undefined;
213
196
 
214
- for await (const line of process.stdout
197
+ const lines = process.stdout
215
198
  .pipeThrough(new TextDecoderStream())
216
- // Each chunk should contain one or several full lines
217
- .pipeThrough(new SplitStringStream("\n"))) {
199
+ .pipeThrough(new SplitStringStream("\n", { trim: true }));
200
+ for await (const line of lines) {
218
201
  // `BEGIN:` and `PROGRESS:` only appear when `-p` is specified.
219
202
  let match = line.match(BugReport.PROGRESS_REGEX);
220
203
  if (match) {
@@ -258,10 +241,10 @@ export class BugReport extends AdbServiceBase {
258
241
  */
259
242
  bugReportZStream(): ReadableStream<Uint8Array> {
260
243
  return new PushReadableStream(async (controller) => {
261
- const process = await this.adb.subprocess.shellProtocol!.spawn([
262
- "bugreportz",
263
- "-s",
264
- ]);
244
+ const process = await this.#adb.subprocess.shellProtocol!.spawn(
245
+ ["bugreportz", "-s"],
246
+ controller.abortSignal,
247
+ );
265
248
  process.stdout
266
249
  .pipeTo(
267
250
  new WritableStream({
@@ -310,13 +293,11 @@ export class BugReport extends AdbServiceBase {
310
293
 
311
294
  if (this.#supportsBugReportZ) {
312
295
  let path: string | undefined;
313
- let sync: AdbSync | undefined;
314
296
  const controller = new AbortController();
315
297
  const cleanup = async () => {
316
298
  controller.abort();
317
- await sync?.dispose();
318
299
  if (path) {
319
- await this.adb.rm(path);
300
+ await this.#adb.rm(path);
320
301
  }
321
302
  };
322
303
 
@@ -330,8 +311,7 @@ export class BugReport extends AdbServiceBase {
330
311
  ? onProgress
331
312
  : undefined,
332
313
  });
333
- sync = await this.adb.sync();
334
- return sync.read(path);
314
+ return this.#adb.sync.read(path);
335
315
  },
336
316
  cancel: cleanup,
337
317
  close: cleanup,
@@ -342,3 +322,23 @@ export class BugReport extends AdbServiceBase {
342
322
  return { type: "bugreport", stream: this.bugReport() };
343
323
  }
344
324
  }
325
+
326
+ export namespace BugReport {
327
+ export interface Capabilities {
328
+ supportsBugReport: boolean;
329
+ bugReportZVersion?: string | undefined;
330
+ supportsBugReportZ: boolean;
331
+ supportsBugReportZProgress: boolean;
332
+ supportsBugReportZStream: boolean;
333
+ }
334
+
335
+ export interface BugReportZOptions {
336
+ signal?: AbortSignal;
337
+ /**
338
+ * A callback that will be called when progress is updated.
339
+ *
340
+ * Specify `onProgress` when `supportsBugReportZProgress` is `false` will throw an error.
341
+ */
342
+ onProgress?: ((completed: string, total: string) => void) | undefined;
343
+ }
344
+ }
@@ -0,0 +1 @@
1
+ export * from "./service.js";
@@ -0,0 +1,62 @@
1
+ import type { Adb } from "@yume-chan/adb";
2
+ import {
3
+ AdbFeature,
4
+ AdbNoneProtocolProcessImpl,
5
+ adbNoneProtocolSpawner,
6
+ escapeArg,
7
+ } from "@yume-chan/adb";
8
+
9
+ import { Cmd } from "./service.js";
10
+ import { checkCommand, resolveFallback, serializeAbbService } from "./utils.js";
11
+
12
+ export function createNoneProtocol(
13
+ adb: Adb,
14
+ fallback: NonNullable<Cmd.Fallback>,
15
+ ): Cmd.NoneProtocolService;
16
+ export function createNoneProtocol(
17
+ adb: Adb,
18
+ fallback?: Cmd.Fallback,
19
+ ): Cmd.NoneProtocolService | undefined;
20
+ export function createNoneProtocol(
21
+ adb: Adb,
22
+ fallback?: Cmd.Fallback,
23
+ ): Cmd.NoneProtocolService | undefined {
24
+ if (adb.canUseFeature(AdbFeature.AbbExec)) {
25
+ return {
26
+ mode: Cmd.Mode.Abb,
27
+ spawn: adbNoneProtocolSpawner(async (command, signal) => {
28
+ const service = serializeAbbService("abb_exec", command);
29
+ const socket = await adb.createSocket(service);
30
+ return new AdbNoneProtocolProcessImpl(socket, signal);
31
+ }),
32
+ };
33
+ }
34
+
35
+ if (adb.canUseFeature(AdbFeature.Cmd)) {
36
+ return {
37
+ mode: Cmd.Mode.Cmd,
38
+ spawn: adbNoneProtocolSpawner(async (command, signal) => {
39
+ checkCommand(command);
40
+
41
+ const newCommand = command.map(escapeArg);
42
+ newCommand.unshift("cmd");
43
+ return adb.subprocess.noneProtocol.spawn(newCommand, signal);
44
+ }),
45
+ };
46
+ }
47
+
48
+ if (fallback) {
49
+ return {
50
+ mode: Cmd.Mode.Fallback,
51
+ spawn: adbNoneProtocolSpawner(async (command, signal) => {
52
+ checkCommand(command);
53
+
54
+ const newCommand = command.map(escapeArg);
55
+ newCommand[0] = resolveFallback(fallback, command[0]!);
56
+ return adb.subprocess.noneProtocol.spawn(newCommand, signal);
57
+ }),
58
+ };
59
+ }
60
+
61
+ return undefined;
62
+ }
@@ -0,0 +1,54 @@
1
+ import type {
2
+ Adb,
3
+ AdbNoneProtocolSpawner,
4
+ AdbShellProtocolSpawner,
5
+ } from "@yume-chan/adb";
6
+
7
+ import { createNoneProtocol } from "./none.js";
8
+ import { createShellProtocol } from "./shell.js";
9
+
10
+ export class Cmd {
11
+ static readonly Mode = {
12
+ Abb: 0,
13
+ Cmd: 1,
14
+ Fallback: 2,
15
+ } as const;
16
+
17
+ static readonly createNoneProtocol = createNoneProtocol;
18
+ static readonly createShellProtocol = createShellProtocol;
19
+
20
+ #noneProtocol: Cmd.NoneProtocolService | undefined;
21
+ get noneProtocol() {
22
+ return this.#noneProtocol;
23
+ }
24
+
25
+ #shellProtocol: Cmd.ShellProtocolService | undefined;
26
+ get shellProtocol() {
27
+ return this.#shellProtocol;
28
+ }
29
+
30
+ constructor(adb: Adb, fallback?: Cmd.Fallback) {
31
+ this.#noneProtocol = createNoneProtocol(adb, fallback);
32
+ this.#shellProtocol = createShellProtocol(adb, fallback);
33
+ }
34
+ }
35
+
36
+ export namespace Cmd {
37
+ export type Fallback =
38
+ | string
39
+ | Record<string, string>
40
+ | ((service: string) => string)
41
+ | undefined;
42
+
43
+ export type Mode = (typeof Cmd.Mode)[keyof typeof Cmd.Mode];
44
+
45
+ export interface NoneProtocolService {
46
+ mode: Mode;
47
+ spawn: AdbNoneProtocolSpawner;
48
+ }
49
+
50
+ export interface ShellProtocolService {
51
+ mode: Mode;
52
+ spawn: AdbShellProtocolSpawner;
53
+ }
54
+ }