@yume-chan/android-bin 0.0.19 → 0.0.21

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 (61) hide show
  1. package/CHANGELOG.json +36 -0
  2. package/CHANGELOG.md +19 -1
  3. package/LICENSE +21 -0
  4. package/esm/bu.d.ts +20 -7
  5. package/esm/bu.d.ts.map +1 -1
  6. package/esm/bu.js +47 -8
  7. package/esm/bu.js.map +1 -1
  8. package/esm/bug-report.d.ts +82 -21
  9. package/esm/bug-report.d.ts.map +1 -1
  10. package/esm/bug-report.js +189 -55
  11. package/esm/bug-report.js.map +1 -1
  12. package/esm/cmd.d.ts +4 -6
  13. package/esm/cmd.d.ts.map +1 -1
  14. package/esm/cmd.js +39 -24
  15. package/esm/cmd.js.map +1 -1
  16. package/esm/demo-mode.d.ts +3 -3
  17. package/esm/demo-mode.d.ts.map +1 -1
  18. package/esm/demo-mode.js +14 -15
  19. package/esm/demo-mode.js.map +1 -1
  20. package/esm/dumpsys.d.ts +21 -0
  21. package/esm/dumpsys.d.ts.map +1 -0
  22. package/esm/dumpsys.js +82 -0
  23. package/esm/dumpsys.js.map +1 -0
  24. package/esm/index.d.ts +3 -0
  25. package/esm/index.d.ts.map +1 -1
  26. package/esm/index.js +3 -0
  27. package/esm/index.js.map +1 -1
  28. package/esm/logcat.d.ts +3 -2
  29. package/esm/logcat.d.ts.map +1 -1
  30. package/esm/logcat.js +34 -24
  31. package/esm/logcat.js.map +1 -1
  32. package/esm/overlay-display.d.ts +20 -3
  33. package/esm/overlay-display.d.ts.map +1 -1
  34. package/esm/overlay-display.js +34 -61
  35. package/esm/overlay-display.js.map +1 -1
  36. package/esm/pm.d.ts +25 -2
  37. package/esm/pm.d.ts.map +1 -1
  38. package/esm/pm.js +88 -17
  39. package/esm/pm.js.map +1 -1
  40. package/esm/settings.d.ts +21 -8
  41. package/esm/settings.d.ts.map +1 -1
  42. package/esm/settings.js +55 -19
  43. package/esm/settings.js.map +1 -1
  44. package/esm/string-format.d.ts +40 -0
  45. package/esm/string-format.d.ts.map +1 -0
  46. package/esm/string-format.js +153 -0
  47. package/esm/string-format.js.map +1 -0
  48. package/package.json +13 -8
  49. package/src/bu.ts +68 -14
  50. package/src/bug-report.ts +236 -70
  51. package/src/cmd.ts +67 -33
  52. package/src/demo-mode.ts +47 -43
  53. package/src/dumpsys.ts +91 -0
  54. package/src/index.ts +3 -0
  55. package/src/logcat.ts +63 -74
  56. package/src/overlay-display.ts +82 -85
  57. package/src/pm.ts +149 -27
  58. package/src/settings.ts +99 -50
  59. package/src/string-format.ts +199 -0
  60. package/tsconfig.build.json +11 -0
  61. package/tsconfig.build.tsbuildinfo +1 -1
package/CHANGELOG.json CHANGED
@@ -1,6 +1,42 @@
1
1
  {
2
2
  "name": "@yume-chan/android-bin",
3
3
  "entries": [
4
+ {
5
+ "version": "0.0.21",
6
+ "tag": "@yume-chan/android-bin_v0.0.21",
7
+ "date": "Fri, 25 Aug 2023 14:05:18 GMT",
8
+ "comments": {
9
+ "none": [
10
+ {
11
+ "comment": "Add wrapper for `bu`"
12
+ },
13
+ {
14
+ "comment": "Remove the last `\\n` from `Settings#get`"
15
+ },
16
+ {
17
+ "comment": "Add wrappers for `dumpsys diskstats` and `dumpsys battery`"
18
+ },
19
+ {
20
+ "comment": "Add wrapper for `pm list packages`"
21
+ },
22
+ {
23
+ "comment": "Rewrite `Settings` to use `Cmd` if available"
24
+ },
25
+ {
26
+ "comment": "Add support to stop `bugreport`"
27
+ },
28
+ {
29
+ "comment": "Merge `bugreport` and `bugreportz` wrappers, providing an `automatic` method to choose the best available bugreport method"
30
+ }
31
+ ]
32
+ }
33
+ },
34
+ {
35
+ "version": "0.0.20",
36
+ "tag": "@yume-chan/android-bin_v0.0.20",
37
+ "date": "Mon, 05 Jun 2023 02:51:41 GMT",
38
+ "comments": {}
39
+ },
4
40
  {
5
41
  "version": "0.0.19",
6
42
  "tag": "@yume-chan/android-bin_v0.0.19",
package/CHANGELOG.md CHANGED
@@ -1,6 +1,24 @@
1
1
  # Change Log - @yume-chan/android-bin
2
2
 
3
- This log was last generated on Sun, 09 Apr 2023 05:55:33 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 25 Aug 2023 14:05:18 GMT and should not be manually modified.
4
+
5
+ ## 0.0.21
6
+ Fri, 25 Aug 2023 14:05:18 GMT
7
+
8
+ ### Updates
9
+
10
+ - Add wrapper for `bu`
11
+ - Remove the last `\n` from `Settings#get`
12
+ - Add wrappers for `dumpsys diskstats` and `dumpsys battery`
13
+ - Add wrapper for `pm list packages`
14
+ - Rewrite `Settings` to use `Cmd` if available
15
+ - Add support to stop `bugreport`
16
+ - Merge `bugreport` and `bugreportz` wrappers, providing an `automatic` method to choose the best available bugreport method
17
+
18
+ ## 0.0.20
19
+ Mon, 05 Jun 2023 02:51:41 GMT
20
+
21
+ _Version update only_
4
22
 
5
23
  ## 0.0.19
6
24
  Sun, 09 Apr 2023 05:55:33 GMT
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020-2023 Simon Chan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/esm/bu.d.ts CHANGED
@@ -1,15 +1,28 @@
1
1
  import { AdbCommandBase } from "@yume-chan/adb";
2
+ import type { Consumable, ReadableStream } from "@yume-chan/stream-extra";
2
3
  export interface AdbBackupOptions {
3
- apps: string[] | "all" | "all-including-system";
4
- apks: boolean;
5
- obbs: boolean;
6
- shared: boolean;
7
- widgets: boolean;
4
+ user: number;
5
+ saveSharedStorage?: boolean;
6
+ saveWidgets?: boolean;
7
+ packages: string[] | "user" | "all";
8
+ savePackageApk: boolean;
9
+ savePackageObb: boolean;
10
+ savePackageKeyValue: boolean;
8
11
  compress: boolean;
12
+ }
13
+ export interface AdbRestoreOptions {
9
14
  user: number;
15
+ file: ReadableStream<Consumable<Uint8Array>>;
10
16
  }
11
17
  export declare class AdbBackup extends AdbCommandBase {
12
- backup(options: AdbBackupOptions): Promise<void>;
13
- restore(options: AdbBackupOptions): Promise<void>;
18
+ /**
19
+ * User must confirm backup on device within 60 seconds.
20
+ */
21
+ backup(options: AdbBackupOptions): Promise<ReadableStream<Uint8Array>>;
22
+ /**
23
+ * User must enter the password (if any) and
24
+ * confirm restore on device within 60 seconds.
25
+ */
26
+ restore(options: AdbRestoreOptions): Promise<string>;
14
27
  }
15
28
  //# sourceMappingURL=bu.d.ts.map
package/esm/bu.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bu.d.ts","sourceRoot":"","sources":["../src/bu.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,GAAG,sBAAsB,CAAC;IAChD,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,SAAU,SAAQ,cAAc;IACzC,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhD,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;CAIpD"}
1
+ {"version":3,"file":"bu.d.ts","sourceRoot":"","sources":["../src/bu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG1E,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,KAAK,CAAC;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;CAChD;AAED,qBAAa,SAAU,SAAQ,cAAc;IACzC;;OAEG;IACG,MAAM,CACR,OAAO,EAAE,gBAAgB,GAC1B,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAmCtC;;;OAGG;IACG,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;CAc7D"}
package/esm/bu.js CHANGED
@@ -1,14 +1,53 @@
1
- // cspell: ignore apks
2
- // cspell: ignore obbs
3
1
  import { AdbCommandBase } from "@yume-chan/adb";
2
+ import { ConcatStringStream, DecodeUtf8Stream } from "@yume-chan/stream-extra";
4
3
  export class AdbBackup extends AdbCommandBase {
5
- backup(options) {
6
- void options;
7
- throw new Error("Not implemented");
4
+ /**
5
+ * User must confirm backup on device within 60 seconds.
6
+ */
7
+ async backup(options) {
8
+ const args = ["bu", "backup"];
9
+ if (options.user !== undefined) {
10
+ args.push("--user", options.user.toString());
11
+ }
12
+ args.push(options.saveSharedStorage ? "--shared" : "--no-shared");
13
+ args.push(options.saveWidgets ? "--widgets" : "--no-widgets");
14
+ args.push(options.savePackageApk ? "--apk" : "--no-apk");
15
+ args.push(options.savePackageObb ? "--obb" : "--no-obb");
16
+ args.push(options.savePackageKeyValue ? "--key-value" : "--no-key-value");
17
+ args.push(options.compress ? "--compress" : "--no-compress");
18
+ if (typeof options.packages === "string") {
19
+ switch (options.packages) {
20
+ case "user":
21
+ args.push("--all", "--no-system");
22
+ break;
23
+ case "all":
24
+ args.push("--all", "--system");
25
+ break;
26
+ }
27
+ }
28
+ else {
29
+ args.push(...options.packages);
30
+ }
31
+ const process = await this.adb.subprocess.spawn(args);
32
+ return process.stdout;
8
33
  }
9
- restore(options) {
10
- void options;
11
- throw new Error("Not implemented");
34
+ /**
35
+ * User must enter the password (if any) and
36
+ * confirm restore on device within 60 seconds.
37
+ */
38
+ async restore(options) {
39
+ const args = ["bu", "restore"];
40
+ if (options.user !== undefined) {
41
+ args.push("--user", options.user.toString());
42
+ }
43
+ const process = await this.adb.subprocess.spawn(args);
44
+ const [output] = await Promise.all([
45
+ process.stdout
46
+ .pipeThrough(new DecodeUtf8Stream())
47
+ .pipeThrough(new ConcatStringStream()),
48
+ options.file.pipeTo(process.stdin),
49
+ ]);
50
+ return output;
12
51
  }
13
52
  }
14
53
  //# sourceMappingURL=bu.js.map
package/esm/bu.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bu.js","sourceRoot":"","sources":["../src/bu.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,sBAAsB;AAEtB,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAYhD,MAAM,OAAO,SAAU,SAAQ,cAAc;IACzC,MAAM,CAAC,OAAyB;QAC5B,KAAK,OAAO,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAAyB;QAC7B,KAAK,OAAO,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACvC,CAAC;CACJ"}
1
+ {"version":3,"file":"bu.js","sourceRoot":"","sources":["../src/bu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAkB/E,MAAM,OAAO,SAAU,SAAQ,cAAc;IACzC;;OAEG;IACH,KAAK,CAAC,MAAM,CACR,OAAyB;QAEzB,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAE9B,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;SAChD;QAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QAClE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QAE9D,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,CACL,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CACjE,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAE7D,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE;YACtC,QAAQ,OAAO,CAAC,QAAQ,EAAE;gBACtB,KAAK,MAAM;oBACP,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;oBAClC,MAAM;gBACV,KAAK,KAAK;oBACN,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;oBAC/B,MAAM;aACb;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;SAClC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtD,OAAO,OAAO,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO,CAAC,OAA0B;QACpC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;SAChD;QACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC/B,OAAO,CAAC,MAAM;iBACT,WAAW,CAAC,IAAI,gBAAgB,EAAE,CAAC;iBACnC,WAAW,CAAC,IAAI,kBAAkB,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SACrC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ"}
@@ -1,38 +1,99 @@
1
+ import type { Adb } from "@yume-chan/adb";
1
2
  import { AdbCommandBase } from "@yume-chan/adb";
2
- import type { ReadableStream } from "@yume-chan/stream-extra";
3
- export interface BugReportZVersion {
4
- major: number;
5
- minor: number;
6
- supportProgress: boolean;
7
- supportStream: boolean;
3
+ import type { AbortSignal, ReadableStream } from "@yume-chan/stream-extra";
4
+ export interface BugReportCapabilities {
5
+ supportsBugReport: boolean;
6
+ bugReportZVersion?: string | undefined;
7
+ supportsBugReportZ: boolean;
8
+ supportsBugReportZProgress: boolean;
9
+ supportsBugReportZStream: boolean;
8
10
  }
9
- export declare class BugReportZ extends AdbCommandBase {
11
+ export interface BugReportZOptions {
12
+ signal?: AbortSignal;
13
+ /**
14
+ * A callback that will be called when progress is updated.
15
+ *
16
+ * Specify `onProgress` when `supportsBugReportZProgress` is `false` will throw an error.
17
+ */
18
+ onProgress?: ((completed: string, total: string) => void) | undefined;
19
+ }
20
+ export declare class BugReport extends AdbCommandBase {
21
+ #private;
10
22
  static VERSION_REGEX: RegExp;
11
23
  static BEGIN_REGEX: RegExp;
12
24
  static PROGRESS_REGEX: RegExp;
13
25
  static OK_REGEX: RegExp;
14
26
  static FAIL_REGEX: RegExp;
15
27
  /**
16
- * Retrieve the version of bugreportz.
28
+ * Queries the device's bugreport capabilities.
29
+ */
30
+ static queryCapabilities(adb: Adb): Promise<BugReport>;
31
+ /**
32
+ * Gets whether the device supports flat (text file, non-zipped) bugreport.
33
+ *
34
+ * Should be `true` for Android version <= 11.
35
+ */
36
+ get supportsBugReport(): boolean;
37
+ /**
38
+ * Gets the version of BugReportZ.
39
+ *
40
+ * Will be `undefined` if BugReportZ is not supported.
41
+ */
42
+ get bugReportZVersion(): string | undefined;
43
+ /**
44
+ * Gets whether the device supports zipped bugreport.
45
+ *
46
+ * Should be `true` for Android version >= 7.
47
+ */
48
+ get supportsBugReportZ(): boolean;
49
+ /**
50
+ * Gets whether the device supports progress report for zipped bugreport.
17
51
  *
18
- * @returns a `BugReportVersion` object, or `undefined` if `bugreportz` is not available.
52
+ * Should be `true` for Android version >= 8.
19
53
  */
20
- version(): Promise<BugReportZVersion | undefined>;
21
- supportProgress(major: number, minor: number): boolean;
54
+ get supportsBugReportZProgress(): boolean;
22
55
  /**
23
- * Create a zipped bugreport file.
56
+ * Gets whether the device supports streaming zipped bugreport.
24
57
  *
25
- * Compare to `stream`, this method will write the output to a file on device.
58
+ * Should be `true` for Android version >= 12.
59
+ */
60
+ get supportsBugReportZStream(): boolean;
61
+ constructor(adb: Adb, capabilities: BugReportCapabilities);
62
+ /**
63
+ * Creates a legacy, non-zipped bugreport file, or throws an error if `supportsBugReport` is `false`.
64
+ *
65
+ * @returns A flat (text file, non-zipped) bugreport.
66
+ */
67
+ bugReport(): ReadableStream<Uint8Array>;
68
+ /**
69
+ * Creates a zipped bugreport file, or throws an error if `supportsBugReportZ` is `false`.
70
+ *
71
+ * Compare to `bugReportZStream`, this method will write the output to a file on device.
26
72
  * You can pull it later using sync protocol.
27
73
  *
28
- * @param onProgress Progress callback. Only specify this if `supportsProgress` is `true`.
29
- * @returns The path of the bugreport file.
74
+ * @returns The path to the generated bugreport file on device filesystem.
30
75
  */
31
- generate(onProgress?: (progress: string, total: string) => void): Promise<string>;
32
- supportStream(major: number, minor: number): boolean;
33
- stream(): ReadableStream<Uint8Array>;
34
- }
35
- export declare class BugReport extends AdbCommandBase {
36
- generate(): ReadableStream<Uint8Array>;
76
+ bugReportZ(options?: BugReportZOptions): Promise<string>;
77
+ /**
78
+ * Creates a zipped bugreport file, or throws an error if `supportsBugReportZStream` is `false`.
79
+ *
80
+ * @returns The content of the generated bugreport file.
81
+ */
82
+ bugReportZStream(): ReadableStream<Uint8Array>;
83
+ /**
84
+ * Automatically choose the best bugreport method.
85
+ *
86
+ * * If `supportsBugReportZStream` is `true`, this method will return a stream of zipped bugreport.
87
+ * * If `supportsBugReportZ` is `true`, this method will return a stream of zipped bugreport, and will delete the file on device after the stream is closed.
88
+ * * If `supportsBugReport` is `true`, this method will return a stream of flat bugreport.
89
+ *
90
+ * @param onProgress
91
+ * If `supportsBugReportZStream` is `false` and `supportsBugReportZProgress` is `true`,
92
+ * this callback will be called when progress is updated.
93
+ */
94
+ automatic(onProgress?: (completed: string, total: string) => void): {
95
+ type: "bugreport" | "bugreportz";
96
+ stream: ReadableStream<Uint8Array>;
97
+ };
37
98
  }
38
99
  //# sourceMappingURL=bug-report.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bug-report.d.ts","sourceRoot":"","sources":["../src/bug-report.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAA8B,MAAM,gBAAgB,CAAC;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAS9D,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IAEd,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;CAC1B;AAED,qBAAa,UAAW,SAAQ,cAAc;IAC1C,OAAc,aAAa,SAAkB;IAE7C,OAAc,WAAW,SAAgB;IAEzC,OAAc,cAAc,SAAyB;IAErD,OAAc,QAAQ,SAAa;IAEnC,OAAc,UAAU,SAAe;IAEvC;;;;OAIG;IACU,OAAO,IAAI,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IA8BvD,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAI7D;;;;;;;;OAQG;IACU,QAAQ,CACjB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACvD,OAAO,CAAC,MAAM,CAAC;IAqDX,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAIpD,MAAM,IAAI,cAAc,CAAC,UAAU,CAAC;CAgC9C;AAGD,qBAAa,SAAU,SAAQ,cAAc;IAClC,QAAQ,IAAI,cAAc,CAAC,UAAU,CAAC;CAMhD"}
1
+ {"version":3,"file":"bug-report.d.ts","sourceRoot":"","sources":["../src/bug-report.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAW,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAA8B,MAAM,gBAAgB,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAU3E,MAAM,WAAW,qBAAqB;IAClC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,0BAA0B,EAAE,OAAO,CAAC;IACpC,wBAAwB,EAAE,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAC9B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACzE;AAED,qBAAa,SAAU,SAAQ,cAAc;;IACzC,MAAM,CAAC,aAAa,SAAkB;IAEtC,MAAM,CAAC,WAAW,SAAgB;IAElC,MAAM,CAAC,cAAc,SAAyB;IAE9C,MAAM,CAAC,QAAQ,SAAa;IAE5B,MAAM,CAAC,UAAU,SAAe;IAEhC;;OAEG;WACU,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC;IAmD5D;;;;OAIG;IACH,IAAI,iBAAiB,YAEpB;IAGD;;;;OAIG;IACH,IAAI,iBAAiB,uBAEpB;IAGD;;;;OAIG;IACH,IAAI,kBAAkB,YAErB;IAGD;;;;OAIG;IACH,IAAI,0BAA0B,YAE7B;IAGD;;;;OAIG;IACH,IAAI,wBAAwB,YAE3B;gBAEW,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,qBAAqB;IAWzD;;;;OAIG;IACH,SAAS,IAAI,cAAc,CAAC,UAAU,CAAC;IAcvC;;;;;;;OAOG;IACG,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAwE9D;;;;OAIG;IACH,gBAAgB,IAAI,cAAc,CAAC,UAAU,CAAC;IAiC9C;;;;;;;;;;OAUG;IACH,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG;QAChE,IAAI,EAAE,WAAW,GAAG,YAAY,CAAC;QACjC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;KACtC;CAsCJ"}
package/esm/bug-report.js CHANGED
@@ -1,60 +1,159 @@
1
1
  // cspell: ignore bugreport
2
2
  // cspell: ignore bugreportz
3
3
  import { AdbCommandBase, AdbSubprocessShellProtocol } from "@yume-chan/adb";
4
- import { DecodeUtf8Stream, PushReadableStream, SplitStringStream, WrapReadableStream, WritableStream, } from "@yume-chan/stream-extra";
5
- class BugReportZ extends AdbCommandBase {
4
+ import { AbortController, DecodeUtf8Stream, PushReadableStream, SplitStringStream, WrapReadableStream, WritableStream, } from "@yume-chan/stream-extra";
5
+ export class BugReport extends AdbCommandBase {
6
6
  static VERSION_REGEX = /(\d+)\.(\d+)/;
7
7
  static BEGIN_REGEX = /BEGIN:(.*)/;
8
8
  static PROGRESS_REGEX = /PROGRESS:(.*)\/(.*)/;
9
9
  static OK_REGEX = /OK:(.*)/;
10
10
  static FAIL_REGEX = /FAIL:(.*)/;
11
11
  /**
12
- * Retrieve the version of bugreportz.
13
- *
14
- * @returns a `BugReportVersion` object, or `undefined` if `bugreportz` is not available.
12
+ * Queries the device's bugreport capabilities.
15
13
  */
16
- async version() {
14
+ static async queryCapabilities(adb) {
17
15
  // bugreportz requires shell protocol
18
- if (!AdbSubprocessShellProtocol.isSupported(this.adb)) {
19
- return undefined;
16
+ if (!AdbSubprocessShellProtocol.isSupported(adb)) {
17
+ return new BugReport(adb, {
18
+ supportsBugReport: true,
19
+ bugReportZVersion: undefined,
20
+ supportsBugReportZ: false,
21
+ supportsBugReportZProgress: false,
22
+ supportsBugReportZStream: false,
23
+ });
20
24
  }
21
- const { stderr, exitCode } = await this.adb.subprocess.spawnAndWait([
25
+ const { stderr, exitCode } = await adb.subprocess.spawnAndWait([
22
26
  "bugreportz",
23
27
  "-v",
24
28
  ]);
25
29
  if (exitCode !== 0 || stderr === "") {
26
- return undefined;
30
+ return new BugReport(adb, {
31
+ supportsBugReport: true,
32
+ bugReportZVersion: undefined,
33
+ supportsBugReportZ: false,
34
+ supportsBugReportZProgress: false,
35
+ supportsBugReportZStream: false,
36
+ });
27
37
  }
28
- const match = stderr.match(BugReportZ.VERSION_REGEX);
38
+ const match = stderr.match(BugReport.VERSION_REGEX);
29
39
  if (!match) {
30
- return undefined;
40
+ return new BugReport(adb, {
41
+ supportsBugReport: true,
42
+ bugReportZVersion: undefined,
43
+ supportsBugReportZ: false,
44
+ supportsBugReportZProgress: false,
45
+ supportsBugReportZStream: false,
46
+ });
31
47
  }
32
- const major = parseInt(match[1], 10);
33
- const minor = parseInt(match[2], 10);
34
- return {
35
- major,
36
- minor,
37
- supportProgress: this.supportProgress(major, minor),
38
- supportStream: this.supportStream(major, minor),
39
- };
48
+ const [major, minor] = match[0]
49
+ .split(".")
50
+ .map((x) => parseInt(x, 10));
51
+ return new BugReport(adb, {
52
+ // Before BugReportZ version 1.2 (Android 12), BugReport was deprecated but still works.
53
+ supportsBugReport: major === 1 && minor <= 1,
54
+ bugReportZVersion: match[0],
55
+ supportsBugReportZ: true,
56
+ supportsBugReportZProgress: major > 1 || minor >= 1,
57
+ supportsBugReportZStream: major > 1 || minor >= 2,
58
+ });
59
+ }
60
+ #supportsBugReport;
61
+ /**
62
+ * Gets whether the device supports flat (text file, non-zipped) bugreport.
63
+ *
64
+ * Should be `true` for Android version <= 11.
65
+ */
66
+ get supportsBugReport() {
67
+ return this.#supportsBugReport;
68
+ }
69
+ #bugReportZVersion;
70
+ /**
71
+ * Gets the version of BugReportZ.
72
+ *
73
+ * Will be `undefined` if BugReportZ is not supported.
74
+ */
75
+ get bugReportZVersion() {
76
+ return this.#bugReportZVersion;
77
+ }
78
+ #supportsBugReportZ;
79
+ /**
80
+ * Gets whether the device supports zipped bugreport.
81
+ *
82
+ * Should be `true` for Android version >= 7.
83
+ */
84
+ get supportsBugReportZ() {
85
+ return this.#supportsBugReportZ;
40
86
  }
41
- supportProgress(major, minor) {
42
- return major > 1 || minor >= 1;
87
+ #supportsBugReportZProgress;
88
+ /**
89
+ * Gets whether the device supports progress report for zipped bugreport.
90
+ *
91
+ * Should be `true` for Android version >= 8.
92
+ */
93
+ get supportsBugReportZProgress() {
94
+ return this.#supportsBugReportZProgress;
43
95
  }
96
+ #supportsBugReportZStream;
44
97
  /**
45
- * Create a zipped bugreport file.
98
+ * Gets whether the device supports streaming zipped bugreport.
46
99
  *
47
- * Compare to `stream`, this method will write the output to a file on device.
100
+ * Should be `true` for Android version >= 12.
101
+ */
102
+ get supportsBugReportZStream() {
103
+ return this.#supportsBugReportZStream;
104
+ }
105
+ constructor(adb, capabilities) {
106
+ super(adb);
107
+ this.#supportsBugReport = capabilities.supportsBugReport;
108
+ this.#bugReportZVersion = capabilities.bugReportZVersion;
109
+ this.#supportsBugReportZ = capabilities.supportsBugReportZ;
110
+ this.#supportsBugReportZProgress =
111
+ capabilities.supportsBugReportZProgress;
112
+ this.#supportsBugReportZStream = capabilities.supportsBugReportZStream;
113
+ }
114
+ /**
115
+ * Creates a legacy, non-zipped bugreport file, or throws an error if `supportsBugReport` is `false`.
116
+ *
117
+ * @returns A flat (text file, non-zipped) bugreport.
118
+ */
119
+ bugReport() {
120
+ if (!this.#supportsBugReport) {
121
+ throw new Error("Flat (text file, non-zipped) bugreport is not supported.");
122
+ }
123
+ return new WrapReadableStream(async () => {
124
+ // https://cs.android.com/android/platform/superproject/+/master:frameworks/native/cmds/bugreport/bugreport.cpp;drc=9b73bf07d73dbab5b792632e1e233edbad77f5fd;bpv=0;bpt=0
125
+ const process = await this.adb.subprocess.spawn(["bugreport"]);
126
+ return process.stdout;
127
+ });
128
+ }
129
+ /**
130
+ * Creates a zipped bugreport file, or throws an error if `supportsBugReportZ` is `false`.
131
+ *
132
+ * Compare to `bugReportZStream`, this method will write the output to a file on device.
48
133
  * You can pull it later using sync protocol.
49
134
  *
50
- * @param onProgress Progress callback. Only specify this if `supportsProgress` is `true`.
51
- * @returns The path of the bugreport file.
135
+ * @returns The path to the generated bugreport file on device filesystem.
52
136
  */
53
- async generate(onProgress) {
54
- const process = await this.adb.subprocess.spawn([
55
- "bugreportz",
56
- ...(onProgress ? ["-p"] : []),
57
- ]);
137
+ async bugReportZ(options) {
138
+ if (options?.signal?.aborted) {
139
+ throw options?.signal.reason ?? new Error("Aborted");
140
+ }
141
+ if (!this.#supportsBugReportZ) {
142
+ throw new Error("bugreportz is not supported");
143
+ }
144
+ const args = ["bugreportz"];
145
+ if (options?.onProgress) {
146
+ if (!this.#supportsBugReportZProgress) {
147
+ throw new Error("bugreportz progress is not supported");
148
+ }
149
+ args.push("-p");
150
+ }
151
+ const process = await this.adb.subprocess.spawn(args, {
152
+ protocols: [AdbSubprocessShellProtocol],
153
+ });
154
+ options?.signal?.addEventListener("abort", () => {
155
+ void process.kill();
156
+ });
58
157
  let filename;
59
158
  let error;
60
159
  await process.stdout
@@ -63,19 +162,19 @@ class BugReportZ extends AdbCommandBase {
63
162
  .pipeTo(new WritableStream({
64
163
  write(line) {
65
164
  // `BEGIN:` and `PROGRESS:` only appear when `-p` is specified.
66
- let match = line.match(BugReportZ.PROGRESS_REGEX);
165
+ let match = line.match(BugReport.PROGRESS_REGEX);
67
166
  if (match) {
68
- onProgress?.(match[1], match[2]);
167
+ options?.onProgress?.(match[1], match[2]);
69
168
  }
70
- match = line.match(BugReportZ.BEGIN_REGEX);
169
+ match = line.match(BugReport.BEGIN_REGEX);
71
170
  if (match) {
72
171
  filename = match[1];
73
172
  }
74
- match = line.match(BugReportZ.OK_REGEX);
173
+ match = line.match(BugReport.OK_REGEX);
75
174
  if (match) {
76
175
  filename = match[1];
77
176
  }
78
- match = line.match(BugReportZ.FAIL_REGEX);
177
+ match = line.match(BugReport.FAIL_REGEX);
79
178
  if (match) {
80
179
  // Don't report error now
81
180
  // We want to gather all output.
@@ -92,15 +191,14 @@ class BugReportZ extends AdbCommandBase {
92
191
  // Design choice: we don't automatically pull the file to avoid more dependency on `@yume-chan/adb`
93
192
  return filename;
94
193
  }
95
- supportStream(major, minor) {
96
- return major > 1 || minor >= 2;
97
- }
98
- stream() {
194
+ /**
195
+ * Creates a zipped bugreport file, or throws an error if `supportsBugReportZStream` is `false`.
196
+ *
197
+ * @returns The content of the generated bugreport file.
198
+ */
199
+ bugReportZStream() {
99
200
  return new PushReadableStream(async (controller) => {
100
- const process = await this.adb.subprocess.spawn([
101
- "bugreportz",
102
- "-s",
103
- ]);
201
+ const process = await this.adb.subprocess.spawn(["bugreportz", "-s"], { protocols: [AdbSubprocessShellProtocol] });
104
202
  process.stdout
105
203
  .pipeTo(new WritableStream({
106
204
  async write(chunk) {
@@ -108,7 +206,7 @@ class BugReportZ extends AdbCommandBase {
108
206
  },
109
207
  }))
110
208
  .catch((e) => {
111
- void e;
209
+ controller.error(e);
112
210
  });
113
211
  process.stderr
114
212
  .pipeThrough(new DecodeUtf8Stream())
@@ -118,20 +216,56 @@ class BugReportZ extends AdbCommandBase {
118
216
  },
119
217
  }))
120
218
  .catch((e) => {
121
- void e;
219
+ controller.error(e);
122
220
  });
123
221
  await process.exit;
124
222
  });
125
223
  }
126
- }
127
- export { BugReportZ };
128
- // https://cs.android.com/android/platform/superproject/+/master:frameworks/native/cmds/bugreport/bugreport.cpp;drc=9b73bf07d73dbab5b792632e1e233edbad77f5fd;bpv=0;bpt=0
129
- export class BugReport extends AdbCommandBase {
130
- generate() {
131
- return new WrapReadableStream(async () => {
132
- const process = await this.adb.subprocess.spawn(["bugreport"]);
133
- return process.stdout;
134
- });
224
+ /**
225
+ * Automatically choose the best bugreport method.
226
+ *
227
+ * * If `supportsBugReportZStream` is `true`, this method will return a stream of zipped bugreport.
228
+ * * If `supportsBugReportZ` is `true`, this method will return a stream of zipped bugreport, and will delete the file on device after the stream is closed.
229
+ * * If `supportsBugReport` is `true`, this method will return a stream of flat bugreport.
230
+ *
231
+ * @param onProgress
232
+ * If `supportsBugReportZStream` is `false` and `supportsBugReportZProgress` is `true`,
233
+ * this callback will be called when progress is updated.
234
+ */
235
+ automatic(onProgress) {
236
+ if (this.#supportsBugReportZStream) {
237
+ return { type: "bugreportz", stream: this.bugReportZStream() };
238
+ }
239
+ if (this.#supportsBugReportZ) {
240
+ let path;
241
+ let sync;
242
+ const controller = new AbortController();
243
+ const cleanup = async () => {
244
+ controller.abort();
245
+ await sync?.dispose();
246
+ if (path) {
247
+ await this.adb.rm(path);
248
+ }
249
+ };
250
+ return {
251
+ type: "bugreportz",
252
+ stream: new WrapReadableStream({
253
+ start: async () => {
254
+ path = await this.bugReportZ({
255
+ signal: controller.signal,
256
+ onProgress: this.#supportsBugReportZProgress
257
+ ? onProgress
258
+ : undefined,
259
+ });
260
+ sync = await this.adb.sync();
261
+ return sync.read(path);
262
+ },
263
+ cancel: cleanup,
264
+ close: cleanup,
265
+ }),
266
+ };
267
+ }
268
+ return { type: "bugreport", stream: this.bugReport() };
135
269
  }
136
270
  }
137
271
  //# sourceMappingURL=bug-report.js.map