@yume-chan/adb 0.0.13 → 0.0.16

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 (116) hide show
  1. package/CHANGELOG.json +57 -0
  2. package/CHANGELOG.md +29 -1
  3. package/LICENSE +21 -21
  4. package/README.md +247 -247
  5. package/esm/adb.d.ts +12 -4
  6. package/esm/adb.d.ts.map +1 -1
  7. package/esm/adb.js +29 -19
  8. package/esm/adb.js.map +1 -1
  9. package/esm/commands/reverse.d.ts +9 -12
  10. package/esm/commands/reverse.d.ts.map +1 -1
  11. package/esm/commands/reverse.js +44 -36
  12. package/esm/commands/reverse.js.map +1 -1
  13. package/esm/commands/subprocess/protocols/none.d.ts +2 -1
  14. package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
  15. package/esm/commands/subprocess/protocols/none.js +10 -9
  16. package/esm/commands/subprocess/protocols/none.js.map +1 -1
  17. package/esm/commands/sync/pull.d.ts.map +1 -1
  18. package/esm/commands/sync/pull.js +6 -3
  19. package/esm/commands/sync/pull.js.map +1 -1
  20. package/esm/commands/sync/stat.d.ts.map +1 -1
  21. package/esm/commands/sync/stat.js +2 -2
  22. package/esm/commands/sync/stat.js.map +1 -1
  23. package/esm/commands/sync/sync.js +1 -1
  24. package/esm/commands/sync/sync.js.map +1 -1
  25. package/esm/socket/dispatcher.d.ts +25 -14
  26. package/esm/socket/dispatcher.d.ts.map +1 -1
  27. package/esm/socket/dispatcher.js +94 -63
  28. package/esm/socket/dispatcher.js.map +1 -1
  29. package/esm/socket/socket.d.ts +18 -4
  30. package/esm/socket/socket.d.ts.map +1 -1
  31. package/esm/socket/socket.js +36 -21
  32. package/esm/socket/socket.js.map +1 -1
  33. package/esm/stream/buffered.d.ts +7 -3
  34. package/esm/stream/buffered.d.ts.map +1 -1
  35. package/esm/stream/buffered.js +69 -49
  36. package/esm/stream/buffered.js.map +1 -1
  37. package/esm/stream/detect.js +1 -0
  38. package/esm/stream/detect.js.map +1 -1
  39. package/esm/stream/detect.polyfill.d.ts +1 -1
  40. package/esm/stream/detect.polyfill.d.ts.map +1 -1
  41. package/esm/stream/detect.polyfill.js +0 -5
  42. package/esm/stream/detect.polyfill.js.map +1 -1
  43. package/esm/stream/transform.d.ts +39 -13
  44. package/esm/stream/transform.d.ts.map +1 -1
  45. package/esm/stream/transform.js +67 -90
  46. package/esm/stream/transform.js.map +1 -1
  47. package/esm/utils/base64.js +5 -5
  48. package/esm/utils/base64.js.map +1 -1
  49. package/package.json +10 -10
  50. package/src/adb.ts +280 -270
  51. package/src/auth.ts +173 -173
  52. package/src/backend.ts +11 -11
  53. package/src/commands/base.ts +11 -11
  54. package/src/commands/framebuffer.ts +73 -73
  55. package/src/commands/index.ts +8 -8
  56. package/src/commands/install.ts +30 -30
  57. package/src/commands/power.ts +54 -54
  58. package/src/commands/reverse.ts +140 -136
  59. package/src/commands/subprocess/index.ts +139 -139
  60. package/src/commands/subprocess/protocols/none.ts +70 -68
  61. package/src/commands/subprocess/protocols/shell.ts +190 -190
  62. package/src/commands/subprocess/protocols/types.ts +59 -59
  63. package/src/commands/subprocess/utils.ts +20 -20
  64. package/src/commands/sync/index.ts +7 -7
  65. package/src/commands/sync/list.ts +86 -86
  66. package/src/commands/sync/pull.ts +46 -43
  67. package/src/commands/sync/push.ts +41 -41
  68. package/src/commands/sync/request.ts +50 -50
  69. package/src/commands/sync/response.ts +64 -64
  70. package/src/commands/sync/stat.ts +151 -150
  71. package/src/commands/sync/sync.ts +181 -181
  72. package/src/commands/tcpip.ts +21 -21
  73. package/src/crypto.ts +296 -296
  74. package/src/features.ts +9 -9
  75. package/src/index.ts +11 -11
  76. package/src/packet.ts +80 -80
  77. package/src/socket/dispatcher.ts +305 -270
  78. package/src/socket/index.ts +2 -2
  79. package/src/socket/socket.ts +155 -136
  80. package/src/stream/buffered.ts +168 -147
  81. package/src/stream/detect.native.ts +362 -362
  82. package/src/stream/detect.polyfill.ts +22 -28
  83. package/src/stream/detect.ts +7 -5
  84. package/src/stream/index.ts +3 -3
  85. package/src/stream/transform.ts +474 -483
  86. package/src/utils/auto-reset-event.ts +41 -41
  87. package/src/utils/base64.ts +306 -306
  88. package/src/utils/index.ts +3 -3
  89. package/tsconfig.build.json +3 -3
  90. package/tsconfig.build.tsbuildinfo +1 -1
  91. package/tsconfig.test.json +9 -10
  92. package/web-streams-polyfill-4.0.0-beta.2.tgz +0 -0
  93. package/esm/commands/subprocess/legacy.d.ts +0 -35
  94. package/esm/commands/subprocess/legacy.d.ts.map +0 -1
  95. package/esm/commands/subprocess/legacy.js +0 -53
  96. package/esm/commands/subprocess/legacy.js.map +0 -1
  97. package/esm/commands/subprocess/protocol.d.ts +0 -39
  98. package/esm/commands/subprocess/protocol.d.ts.map +0 -1
  99. package/esm/commands/subprocess/protocol.js +0 -157
  100. package/esm/commands/subprocess/protocol.js.map +0 -1
  101. package/esm/commands/subprocess/types.d.ts +0 -50
  102. package/esm/commands/subprocess/types.d.ts.map +0 -1
  103. package/esm/commands/subprocess/types.js +0 -2
  104. package/esm/commands/subprocess/types.js.map +0 -1
  105. package/esm/socket/controller.d.ts +0 -37
  106. package/esm/socket/controller.d.ts.map +0 -1
  107. package/esm/socket/controller.js +0 -66
  108. package/esm/socket/controller.js.map +0 -1
  109. package/esm/stream/detect.bak.d.ts +0 -240
  110. package/esm/stream/detect.bak.d.ts.map +0 -1
  111. package/esm/stream/detect.bak.js +0 -60
  112. package/esm/stream/detect.bak.js.map +0 -1
  113. package/esm/utils/encoding.d.ts +0 -3
  114. package/esm/utils/encoding.d.ts.map +0 -1
  115. package/esm/utils/encoding.js +0 -11
  116. package/esm/utils/encoding.js.map +0 -1
@@ -1,54 +1,54 @@
1
- // cspell: ignore bootloader
2
- // cspell: ignore fastboot
3
- // cspell: ignore keyevent
4
- // cspell: ignore longpress
5
-
6
- import { AdbCommandBase } from "./base.js";
7
-
8
- export class AdbPower extends AdbCommandBase {
9
- public reboot(name: string = '') {
10
- return this.adb.createSocketAndWait(`reboot:${name}`);
11
- }
12
-
13
- public bootloader() {
14
- return this.reboot('bootloader');
15
- }
16
-
17
- public fastboot() {
18
- return this.reboot('fastboot');
19
- }
20
-
21
- public recovery() {
22
- return this.reboot('recovery');
23
- }
24
-
25
- public sideload() {
26
- return this.reboot('sideload');
27
- }
28
-
29
- /**
30
- * Reboot to Qualcomm Emergency Download (EDL) Mode.
31
- *
32
- * Only works on some Qualcomm devices.
33
- */
34
- public qualcommEdlMode() {
35
- return this.reboot('edl');
36
- }
37
-
38
- public powerOff() {
39
- return this.adb.subprocess.spawnAndWaitLegacy(['reboot', '-p']);
40
- }
41
-
42
- public powerButton(longPress: boolean = false) {
43
- return this.adb.subprocess.spawnAndWaitLegacy(['input', 'keyevent', longPress ? '--longpress POWER' : 'POWER']);
44
- }
45
-
46
- /**
47
- * Reboot to Samsung Odin download mode.
48
- *
49
- * Only works on Samsung devices.
50
- */
51
- public samsungOdin() {
52
- return this.reboot('download');
53
- }
54
- }
1
+ // cspell: ignore bootloader
2
+ // cspell: ignore fastboot
3
+ // cspell: ignore keyevent
4
+ // cspell: ignore longpress
5
+
6
+ import { AdbCommandBase } from "./base.js";
7
+
8
+ export class AdbPower extends AdbCommandBase {
9
+ public reboot(name: string = '') {
10
+ return this.adb.createSocketAndWait(`reboot:${name}`);
11
+ }
12
+
13
+ public bootloader() {
14
+ return this.reboot('bootloader');
15
+ }
16
+
17
+ public fastboot() {
18
+ return this.reboot('fastboot');
19
+ }
20
+
21
+ public recovery() {
22
+ return this.reboot('recovery');
23
+ }
24
+
25
+ public sideload() {
26
+ return this.reboot('sideload');
27
+ }
28
+
29
+ /**
30
+ * Reboot to Qualcomm Emergency Download (EDL) Mode.
31
+ *
32
+ * Only works on some Qualcomm devices.
33
+ */
34
+ public qualcommEdlMode() {
35
+ return this.reboot('edl');
36
+ }
37
+
38
+ public powerOff() {
39
+ return this.adb.subprocess.spawnAndWaitLegacy(['reboot', '-p']);
40
+ }
41
+
42
+ public powerButton(longPress: boolean = false) {
43
+ return this.adb.subprocess.spawnAndWaitLegacy(['input', 'keyevent', longPress ? '--longpress POWER' : 'POWER']);
44
+ }
45
+
46
+ /**
47
+ * Reboot to Samsung Odin download mode.
48
+ *
49
+ * Only works on Samsung devices.
50
+ */
51
+ public samsungOdin() {
52
+ return this.reboot('download');
53
+ }
54
+ }
@@ -1,136 +1,140 @@
1
- // cspell: ignore killforward
2
-
3
- import { AutoDisposable } from '@yume-chan/event';
4
- import Struct from '@yume-chan/struct';
5
- import type { AdbPacketData } from '../packet.js';
6
- import type { AdbIncomingSocketEventArgs, AdbPacketDispatcher, AdbSocket } from '../socket/index.js';
7
- import { AdbBufferedStream } from '../stream/index.js';
8
- import { decodeUtf8 } from "../utils/index.js";
9
-
10
- export interface AdbReverseHandler {
11
- onSocket(packet: AdbPacketData, socket: AdbSocket): void;
12
- }
13
-
14
- export interface AdbForwardListener {
15
- deviceSerial: string;
16
-
17
- localName: string;
18
-
19
- remoteName: string;
20
- }
21
-
22
- const AdbReverseStringResponse =
23
- new Struct({ littleEndian: true })
24
- .string('length', { length: 4 })
25
- .string('content', { lengthField: 'length', lengthFieldBase: 16 });
26
-
27
- const AdbReverseErrorResponse =
28
- new Struct({ littleEndian: true })
29
- .fields(AdbReverseStringResponse)
30
- .postDeserialize((value) => {
31
- throw new Error(value.content);
32
- });
33
-
34
- export class AdbReverseCommand extends AutoDisposable {
35
- protected localPortToHandler = new Map<number, AdbReverseHandler>();
36
-
37
- protected deviceAddressToLocalPort = new Map<string, number>();
38
-
39
- protected dispatcher: AdbPacketDispatcher;
40
-
41
- protected listening = false;
42
-
43
- public constructor(dispatcher: AdbPacketDispatcher) {
44
- super();
45
-
46
- this.dispatcher = dispatcher;
47
- this.addDisposable(this.dispatcher.onIncomingSocket(this.handleIncomingSocket, this));
48
- }
49
-
50
- protected handleIncomingSocket(e: AdbIncomingSocketEventArgs): void {
51
- if (e.handled) {
52
- return;
53
- }
54
-
55
- const address = decodeUtf8(e.packet.payload);
56
- // Address format: `tcp:12345\0`
57
- const port = Number.parseInt(address.substring(4));
58
- if (this.localPortToHandler.has(port)) {
59
- this.localPortToHandler.get(port)!.onSocket(e.packet, e.socket);
60
- e.handled = true;
61
- }
62
- }
63
-
64
- private async createBufferedStream(service: string) {
65
- const socket = await this.dispatcher.createSocket(service);
66
- return new AdbBufferedStream(socket);
67
- }
68
-
69
- private async sendRequest(service: string) {
70
- const stream = await this.createBufferedStream(service);
71
- const success = decodeUtf8(await stream.read(4)) === 'OKAY';
72
- if (!success) {
73
- await AdbReverseErrorResponse.deserialize(stream);
74
- }
75
- return stream;
76
- }
77
-
78
- public async list(): Promise<AdbForwardListener[]> {
79
- const stream = await this.createBufferedStream('reverse:list-forward');
80
-
81
- const response = await AdbReverseStringResponse.deserialize(stream);
82
- return response.content!.split('\n').map(line => {
83
- const [deviceSerial, localName, remoteName] = line.split(' ') as [string, string, string];
84
- return { deviceSerial, localName, remoteName };
85
- });
86
-
87
- // No need to close the stream, device will close it
88
- }
89
-
90
- /**
91
- * @param deviceAddress The address adbd on device is listening on. Can be `tcp:0` to let adbd choose an available TCP port by itself.
92
- * @param localPort Native ADB will open a connection to localPort when reverse connection starts. In webadb, it's only used to uniquely identify a reverse registry, `handler` will be called on connection.
93
- * @param handler A callback to handle incoming connections
94
- * @returns If `deviceAddress` is `tcp:0`, return `tcp:{ACTUAL_LISTENING_PORT}`; otherwise, return `deviceAddress`.
95
- */
96
- public async add(
97
- deviceAddress: string,
98
- localPort: number,
99
- handler: AdbReverseHandler,
100
- ): Promise<string> {
101
- const stream = await this.sendRequest(`reverse:forward:${deviceAddress};tcp:${localPort}`);
102
-
103
- // `tcp:0` tells the device to pick an available port.
104
- // However, device will response with the selected port for all `tcp:` requests.
105
- if (deviceAddress.startsWith('tcp:')) {
106
- const response = await AdbReverseStringResponse.deserialize(stream);
107
- deviceAddress = `tcp:${Number.parseInt(response.content!, 10)}`;
108
- }
109
-
110
- this.localPortToHandler.set(localPort, handler);
111
- this.deviceAddressToLocalPort.set(deviceAddress, localPort);
112
- return deviceAddress;
113
-
114
- // No need to close the stream, device will close it
115
- }
116
-
117
- public async remove(deviceAddress: string): Promise<void> {
118
- await this.sendRequest(`reverse:killforward:${deviceAddress}`);
119
-
120
- if (this.deviceAddressToLocalPort.has(deviceAddress)) {
121
- this.localPortToHandler.delete(this.deviceAddressToLocalPort.get(deviceAddress)!);
122
- this.deviceAddressToLocalPort.delete(deviceAddress);
123
- }
124
-
125
- // No need to close the stream, device will close it
126
- }
127
-
128
- public async removeAll(): Promise<void> {
129
- await this.sendRequest(`reverse:killforward-all`);
130
-
131
- this.deviceAddressToLocalPort.clear();
132
- this.localPortToHandler.clear();
133
-
134
- // No need to close the stream, device will close it
135
- }
136
- }
1
+ // cspell: ignore killforward
2
+
3
+ import { AutoDisposable } from '@yume-chan/event';
4
+ import Struct from '@yume-chan/struct';
5
+ import type { Adb } from "../adb.js";
6
+ import type { AdbIncomingSocketHandler, AdbSocket } from '../socket/index.js';
7
+ import { AdbBufferedStream, BufferedStreamEndedError } from '../stream/index.js';
8
+ import { decodeUtf8 } from "../utils/index.js";
9
+
10
+ export interface AdbForwardListener {
11
+ deviceSerial: string;
12
+
13
+ localName: string;
14
+
15
+ remoteName: string;
16
+ }
17
+
18
+ const AdbReverseStringResponse =
19
+ new Struct()
20
+ .string('length', { length: 4 })
21
+ .string('content', { lengthField: 'length', lengthFieldRadix: 16 });
22
+
23
+ const AdbReverseErrorResponse =
24
+ new Struct()
25
+ .fields(AdbReverseStringResponse)
26
+ .postDeserialize((value) => {
27
+ throw new Error(value.content);
28
+ });
29
+
30
+ export class AdbReverseCommand extends AutoDisposable {
31
+ protected localAddressToHandler = new Map<string, AdbIncomingSocketHandler>();
32
+
33
+ protected deviceAddressToLocalAddress = new Map<string, string>();
34
+
35
+ protected adb: Adb;
36
+
37
+ protected listening = false;
38
+
39
+ public constructor(adb: Adb) {
40
+ super();
41
+
42
+ this.adb = adb;
43
+ this.addDisposable(this.adb.addIncomingSocketHandler(this.handleIncomingSocket));
44
+ }
45
+
46
+ protected handleIncomingSocket = async (socket: AdbSocket) => {
47
+ let address = socket.serviceString;
48
+ // ADB daemon appends `\0` to the service string
49
+ address = address.replace(/\0/g, '');
50
+ return !!(await this.localAddressToHandler.get(address)?.(socket));
51
+ };
52
+
53
+ private async createBufferedStream(service: string) {
54
+ const socket = await this.adb.createSocket(service);
55
+ return new AdbBufferedStream(socket);
56
+ }
57
+
58
+ private async sendRequest(service: string) {
59
+ const stream = await this.createBufferedStream(service);
60
+ const success = decodeUtf8(await stream.read(4)) === 'OKAY';
61
+ if (!success) {
62
+ await AdbReverseErrorResponse.deserialize(stream);
63
+ }
64
+ return stream;
65
+ }
66
+
67
+ public async list(): Promise<AdbForwardListener[]> {
68
+ const stream = await this.createBufferedStream('reverse:list-forward');
69
+
70
+ const response = await AdbReverseStringResponse.deserialize(stream);
71
+ return response.content!.split('\n').map(line => {
72
+ const [deviceSerial, localName, remoteName] = line.split(' ') as [string, string, string];
73
+ return { deviceSerial, localName, remoteName };
74
+ });
75
+
76
+ // No need to close the stream, device will close it
77
+ }
78
+
79
+ /**
80
+ * @param deviceAddress The address adbd on device is listening on. Can be `tcp:0` to let adbd choose an available TCP port by itself.
81
+ * @param localAddress Native ADB client will open a connection to this address when reverse connection received. In WebADB, it's only used to uniquely identify a reverse tunnel registry, `handler` will be called to handle the connection.
82
+ * @param handler A callback to handle incoming connections
83
+ * @returns If `deviceAddress` is `tcp:0`, return `tcp:{ACTUAL_LISTENING_PORT}`; otherwise, return `deviceAddress`.
84
+ */
85
+ public async add(
86
+ deviceAddress: string,
87
+ localAddress: string,
88
+ handler: AdbIncomingSocketHandler,
89
+ ): Promise<string> {
90
+ const stream = await this.sendRequest(`reverse:forward:${deviceAddress};${localAddress}`);
91
+
92
+ // `tcp:0` tells the device to pick an available port.
93
+ // Begin with Android 8, device will respond with the selected port for all `tcp:` requests.
94
+ if (deviceAddress.startsWith('tcp:')) {
95
+ let length: number | undefined;
96
+ try {
97
+ length = Number.parseInt(decodeUtf8(await stream.read(4)), 16);
98
+ } catch (e) {
99
+ if (!(e instanceof BufferedStreamEndedError)) {
100
+ throw e;
101
+ }
102
+
103
+ // Device before Android 8 doesn't have this response.
104
+ // (the stream is closed now)
105
+ // Can be safely ignored.
106
+ }
107
+
108
+ if (length !== undefined) {
109
+ const port = decodeUtf8(await stream.read(length!));
110
+ deviceAddress = `tcp:${Number.parseInt(port, 10)}`;
111
+ }
112
+ }
113
+
114
+ this.localAddressToHandler.set(localAddress, handler);
115
+ this.deviceAddressToLocalAddress.set(deviceAddress, localAddress);
116
+ return deviceAddress;
117
+
118
+ // No need to close the stream, device will close it
119
+ }
120
+
121
+ public async remove(deviceAddress: string): Promise<void> {
122
+ await this.sendRequest(`reverse:killforward:${deviceAddress}`);
123
+
124
+ if (this.deviceAddressToLocalAddress.has(deviceAddress)) {
125
+ this.localAddressToHandler.delete(this.deviceAddressToLocalAddress.get(deviceAddress)!);
126
+ this.deviceAddressToLocalAddress.delete(deviceAddress);
127
+ }
128
+
129
+ // No need to close the stream, device will close it
130
+ }
131
+
132
+ public async removeAll(): Promise<void> {
133
+ await this.sendRequest(`reverse:killforward-all`);
134
+
135
+ this.deviceAddressToLocalAddress.clear();
136
+ this.localAddressToHandler.clear();
137
+
138
+ // No need to close the stream, device will close it
139
+ }
140
+ }