@yume-chan/adb 0.0.15 → 0.0.17

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 (196) hide show
  1. package/CHANGELOG.json +33 -0
  2. package/CHANGELOG.md +18 -1
  3. package/LICENSE +21 -21
  4. package/README.md +247 -247
  5. package/esm/adb.d.ts +15 -3
  6. package/esm/adb.d.ts.map +1 -1
  7. package/esm/adb.js +18 -6
  8. package/esm/adb.js.map +1 -1
  9. package/esm/auth.d.ts.map +1 -1
  10. package/esm/auth.js.map +1 -1
  11. package/esm/backend.d.ts +2 -2
  12. package/esm/backend.d.ts.map +1 -1
  13. package/esm/commands/base.d.ts.map +1 -1
  14. package/esm/commands/base.js.map +1 -1
  15. package/esm/commands/framebuffer.d.ts +17 -1
  16. package/esm/commands/framebuffer.d.ts.map +1 -1
  17. package/esm/commands/framebuffer.js +4 -15
  18. package/esm/commands/framebuffer.js.map +1 -1
  19. package/esm/commands/install.d.ts +2 -2
  20. package/esm/commands/install.d.ts.map +1 -1
  21. package/esm/commands/install.js +3 -2
  22. package/esm/commands/install.js.map +1 -1
  23. package/esm/commands/power.d.ts +1 -1
  24. package/esm/commands/power.js +1 -1
  25. package/esm/commands/reverse.d.ts +3 -3
  26. package/esm/commands/reverse.d.ts.map +1 -1
  27. package/esm/commands/reverse.js +9 -9
  28. package/esm/commands/reverse.js.map +1 -1
  29. package/esm/commands/subprocess/command.d.ts +52 -0
  30. package/esm/commands/subprocess/command.d.ts.map +1 -0
  31. package/esm/commands/subprocess/command.js +83 -0
  32. package/esm/commands/subprocess/command.js.map +1 -0
  33. package/esm/commands/subprocess/index.d.ts +1 -53
  34. package/esm/commands/subprocess/index.d.ts.map +1 -1
  35. package/esm/commands/subprocess/index.js +1 -85
  36. package/esm/commands/subprocess/index.js.map +1 -1
  37. package/esm/commands/subprocess/protocols/none.d.ts +5 -4
  38. package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
  39. package/esm/commands/subprocess/protocols/none.js +11 -8
  40. package/esm/commands/subprocess/protocols/none.js.map +1 -1
  41. package/esm/commands/subprocess/protocols/shell.d.ts +4 -4
  42. package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
  43. package/esm/commands/subprocess/protocols/shell.js +6 -6
  44. package/esm/commands/subprocess/protocols/shell.js.map +1 -1
  45. package/esm/commands/subprocess/protocols/types.d.ts +7 -7
  46. package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
  47. package/esm/commands/sync/index.d.ts +1 -1
  48. package/esm/commands/sync/index.d.ts.map +1 -1
  49. package/esm/commands/sync/index.js +1 -1
  50. package/esm/commands/sync/index.js.map +1 -1
  51. package/esm/commands/sync/list.d.ts +2 -2
  52. package/esm/commands/sync/list.d.ts.map +1 -1
  53. package/esm/commands/sync/list.js +15 -43
  54. package/esm/commands/sync/list.js.map +1 -1
  55. package/esm/commands/sync/pull.d.ts +3 -2
  56. package/esm/commands/sync/pull.d.ts.map +1 -1
  57. package/esm/commands/sync/pull.js +15 -17
  58. package/esm/commands/sync/pull.js.map +1 -1
  59. package/esm/commands/sync/push.d.ts +2 -2
  60. package/esm/commands/sync/push.d.ts.map +1 -1
  61. package/esm/commands/sync/push.js +2 -5
  62. package/esm/commands/sync/push.js.map +1 -1
  63. package/esm/commands/sync/request.d.ts +1 -1
  64. package/esm/commands/sync/request.d.ts.map +1 -1
  65. package/esm/commands/sync/request.js +1 -1
  66. package/esm/commands/sync/request.js.map +1 -1
  67. package/esm/commands/sync/response.d.ts +4 -9
  68. package/esm/commands/sync/response.d.ts.map +1 -1
  69. package/esm/commands/sync/response.js +32 -23
  70. package/esm/commands/sync/response.js.map +1 -1
  71. package/esm/commands/sync/stat.d.ts +3 -3
  72. package/esm/commands/sync/stat.d.ts.map +1 -1
  73. package/esm/commands/sync/stat.js +13 -30
  74. package/esm/commands/sync/stat.js.map +1 -1
  75. package/esm/commands/sync/sync.d.ts +2 -2
  76. package/esm/commands/sync/sync.d.ts.map +1 -1
  77. package/esm/commands/sync/sync.js +7 -5
  78. package/esm/commands/sync/sync.js.map +1 -1
  79. package/esm/crypto.js +1 -1
  80. package/esm/crypto.js.map +1 -1
  81. package/esm/index.d.ts +0 -1
  82. package/esm/index.d.ts.map +1 -1
  83. package/esm/index.js +0 -1
  84. package/esm/index.js.map +1 -1
  85. package/esm/packet.d.ts +1 -1
  86. package/esm/packet.d.ts.map +1 -1
  87. package/esm/packet.js +1 -1
  88. package/esm/packet.js.map +1 -1
  89. package/esm/socket/dispatcher.d.ts +11 -3
  90. package/esm/socket/dispatcher.d.ts.map +1 -1
  91. package/esm/socket/dispatcher.js +19 -11
  92. package/esm/socket/dispatcher.js.map +1 -1
  93. package/esm/socket/index.d.ts +1 -1
  94. package/esm/socket/index.d.ts.map +1 -1
  95. package/esm/socket/index.js +1 -1
  96. package/esm/socket/index.js.map +1 -1
  97. package/esm/socket/socket.d.ts +9 -4
  98. package/esm/socket/socket.d.ts.map +1 -1
  99. package/esm/socket/socket.js +20 -10
  100. package/esm/socket/socket.js.map +1 -1
  101. package/esm/utils/base64.d.ts +23 -0
  102. package/esm/utils/base64.d.ts.map +1 -1
  103. package/esm/utils/base64.js +6 -0
  104. package/esm/utils/base64.js.map +1 -1
  105. package/package.json +13 -14
  106. package/src/adb.ts +285 -273
  107. package/src/auth.ts +174 -173
  108. package/src/backend.ts +12 -11
  109. package/src/commands/base.ts +12 -11
  110. package/src/commands/framebuffer.ts +78 -73
  111. package/src/commands/index.ts +8 -8
  112. package/src/commands/install.ts +32 -30
  113. package/src/commands/power.ts +54 -54
  114. package/src/commands/reverse.ts +141 -140
  115. package/src/commands/subprocess/command.ts +131 -0
  116. package/src/commands/subprocess/index.ts +3 -139
  117. package/src/commands/subprocess/protocols/none.ts +73 -68
  118. package/src/commands/subprocess/protocols/shell.ts +191 -190
  119. package/src/commands/subprocess/protocols/types.ts +60 -59
  120. package/src/commands/subprocess/utils.ts +20 -20
  121. package/src/commands/sync/index.ts +7 -7
  122. package/src/commands/sync/list.ts +54 -86
  123. package/src/commands/sync/pull.ts +45 -46
  124. package/src/commands/sync/push.ts +38 -41
  125. package/src/commands/sync/request.ts +51 -50
  126. package/src/commands/sync/response.ts +68 -64
  127. package/src/commands/sync/stat.ts +129 -150
  128. package/src/commands/sync/sync.ts +182 -181
  129. package/src/commands/tcpip.ts +21 -21
  130. package/src/crypto.ts +296 -296
  131. package/src/features.ts +9 -9
  132. package/src/index.ts +10 -11
  133. package/src/packet.ts +80 -80
  134. package/src/socket/dispatcher.ts +310 -304
  135. package/src/socket/index.ts +2 -2
  136. package/src/socket/socket.ts +156 -144
  137. package/src/utils/auto-reset-event.ts +41 -41
  138. package/src/utils/base64.ts +329 -306
  139. package/src/utils/index.ts +3 -3
  140. package/tsconfig.build.json +3 -3
  141. package/tsconfig.build.tsbuildinfo +1 -1
  142. package/esm/commands/subprocess/legacy.d.ts +0 -35
  143. package/esm/commands/subprocess/legacy.d.ts.map +0 -1
  144. package/esm/commands/subprocess/legacy.js +0 -53
  145. package/esm/commands/subprocess/legacy.js.map +0 -1
  146. package/esm/commands/subprocess/protocol.d.ts +0 -39
  147. package/esm/commands/subprocess/protocol.d.ts.map +0 -1
  148. package/esm/commands/subprocess/protocol.js +0 -157
  149. package/esm/commands/subprocess/protocol.js.map +0 -1
  150. package/esm/commands/subprocess/types.d.ts +0 -50
  151. package/esm/commands/subprocess/types.d.ts.map +0 -1
  152. package/esm/commands/subprocess/types.js +0 -2
  153. package/esm/commands/subprocess/types.js.map +0 -1
  154. package/esm/socket/controller.d.ts +0 -37
  155. package/esm/socket/controller.d.ts.map +0 -1
  156. package/esm/socket/controller.js +0 -66
  157. package/esm/socket/controller.js.map +0 -1
  158. package/esm/stream/buffered.d.ts +0 -35
  159. package/esm/stream/buffered.d.ts.map +0 -1
  160. package/esm/stream/buffered.js +0 -123
  161. package/esm/stream/buffered.js.map +0 -1
  162. package/esm/stream/detect.bak.d.ts +0 -240
  163. package/esm/stream/detect.bak.d.ts.map +0 -1
  164. package/esm/stream/detect.bak.js +0 -60
  165. package/esm/stream/detect.bak.js.map +0 -1
  166. package/esm/stream/detect.d.ts +0 -2
  167. package/esm/stream/detect.d.ts.map +0 -1
  168. package/esm/stream/detect.js +0 -5
  169. package/esm/stream/detect.js.map +0 -1
  170. package/esm/stream/detect.native.d.ts +0 -240
  171. package/esm/stream/detect.native.d.ts.map +0 -1
  172. package/esm/stream/detect.native.js +0 -60
  173. package/esm/stream/detect.native.js.map +0 -1
  174. package/esm/stream/detect.polyfill.d.ts +0 -18
  175. package/esm/stream/detect.polyfill.d.ts.map +0 -1
  176. package/esm/stream/detect.polyfill.js +0 -9
  177. package/esm/stream/detect.polyfill.js.map +0 -1
  178. package/esm/stream/index.d.ts +0 -4
  179. package/esm/stream/index.d.ts.map +0 -1
  180. package/esm/stream/index.js +0 -4
  181. package/esm/stream/index.js.map +0 -1
  182. package/esm/stream/transform.d.ts +0 -104
  183. package/esm/stream/transform.d.ts.map +0 -1
  184. package/esm/stream/transform.js +0 -373
  185. package/esm/stream/transform.js.map +0 -1
  186. package/esm/utils/encoding.d.ts +0 -3
  187. package/esm/utils/encoding.d.ts.map +0 -1
  188. package/esm/utils/encoding.js +0 -11
  189. package/esm/utils/encoding.js.map +0 -1
  190. package/src/stream/buffered.ts +0 -147
  191. package/src/stream/detect.native.ts +0 -362
  192. package/src/stream/detect.polyfill.ts +0 -28
  193. package/src/stream/detect.ts +0 -5
  194. package/src/stream/index.ts +0 -3
  195. package/src/stream/transform.ts +0 -447
  196. package/tsconfig.test.json +0 -10
package/src/auth.ts CHANGED
@@ -1,173 +1,174 @@
1
- import { PromiseResolver } from '@yume-chan/async';
2
- import type { Disposable } from '@yume-chan/event';
3
- import type { ValueOrPromise } from '@yume-chan/struct';
4
- import { calculatePublicKey, calculatePublicKeyLength, sign } from './crypto.js';
5
- import { AdbCommand, type AdbPacketData } from './packet.js';
6
- import { calculateBase64EncodedLength, encodeBase64 } from './utils/index.js';
7
-
8
- export type AdbKeyIterable = Iterable<Uint8Array> | AsyncIterable<Uint8Array>;
9
-
10
- export interface AdbCredentialStore {
11
- /**
12
- * Generate and store a RSA private key with modulus length `2048` and public exponent `65537`.
13
- *
14
- * The returned `Uint8Array` is the private key in PKCS #8 format.
15
- */
16
- generateKey(): ValueOrPromise<Uint8Array>;
17
-
18
- /**
19
- * Synchronously or asynchronously iterate through all stored RSA private keys.
20
- *
21
- * Each call to `iterateKeys` must return a different iterator that iterate through all stored keys.
22
- */
23
- iterateKeys(): AdbKeyIterable;
24
- }
25
-
26
- export enum AdbAuthType {
27
- Token = 1,
28
- Signature = 2,
29
- PublicKey = 3,
30
- }
31
-
32
- export interface AdbAuthenticator {
33
- /**
34
- * @param getNextRequest
35
- *
36
- * Call this function to get the next authentication request packet from device.
37
- *
38
- * After calling `getNextRequest`, authenticator can `yield` a packet as response, or `return` to indicate its incapability of handling the request.
39
- *
40
- * After `return`, the `AdbAuthenticatorHandler` will move on to next authenticator and never go back.
41
- *
42
- * Calling `getNextRequest` multiple times without `yield` or `return` will always return the same request.
43
- */
44
- (
45
- credentialStore: AdbCredentialStore,
46
- getNextRequest: () => Promise<AdbPacketData>
47
- ): AsyncIterable<AdbPacketData>;
48
- }
49
-
50
- export const AdbSignatureAuthenticator: AdbAuthenticator = async function* (
51
- credentialStore: AdbCredentialStore,
52
- getNextRequest: () => Promise<AdbPacketData>,
53
- ): AsyncIterable<AdbPacketData> {
54
- for await (const key of credentialStore.iterateKeys()) {
55
- const packet = await getNextRequest();
56
-
57
- if (packet.arg0 !== AdbAuthType.Token) {
58
- return;
59
- }
60
-
61
- const signature = sign(key, packet.payload);
62
- yield {
63
- command: AdbCommand.Auth,
64
- arg0: AdbAuthType.Signature,
65
- arg1: 0,
66
- payload: new Uint8Array(signature),
67
- };
68
- }
69
- };
70
-
71
- export const AdbPublicKeyAuthenticator: AdbAuthenticator = async function* (
72
- credentialStore: AdbCredentialStore,
73
- getNextRequest: () => Promise<AdbPacketData>,
74
- ): AsyncIterable<AdbPacketData> {
75
- const packet = await getNextRequest();
76
-
77
- if (packet.arg0 !== AdbAuthType.Token) {
78
- return;
79
- }
80
-
81
- let privateKey: Uint8Array | undefined;
82
- for await (const key of credentialStore.iterateKeys()) {
83
- privateKey = key;
84
- break;
85
- }
86
-
87
-
88
- if (!privateKey) {
89
- privateKey = await credentialStore.generateKey();
90
- }
91
-
92
- const publicKeyLength = calculatePublicKeyLength();
93
- const [publicKeyBase64Length] = calculateBase64EncodedLength(publicKeyLength);
94
-
95
- // The public key is null terminated,
96
- // So we allocate the buffer with one extra byte.
97
- const publicKeyBuffer = new Uint8Array(publicKeyBase64Length + 1);
98
-
99
- calculatePublicKey(privateKey, publicKeyBuffer);
100
- encodeBase64(
101
- publicKeyBuffer.subarray(0, publicKeyLength),
102
- publicKeyBuffer
103
- );
104
-
105
- yield {
106
- command: AdbCommand.Auth,
107
- arg0: AdbAuthType.PublicKey,
108
- arg1: 0,
109
- payload: publicKeyBuffer,
110
- };
111
- };
112
-
113
- export const ADB_DEFAULT_AUTHENTICATORS: AdbAuthenticator[] = [
114
- AdbSignatureAuthenticator,
115
- AdbPublicKeyAuthenticator,
116
- ];
117
-
118
- export class AdbAuthenticationProcessor implements Disposable {
119
- public readonly authenticators: readonly AdbAuthenticator[];
120
-
121
- private readonly credentialStore: AdbCredentialStore;
122
-
123
- private pendingRequest = new PromiseResolver<AdbPacketData>();
124
-
125
- private iterator: AsyncIterator<AdbPacketData, void, void> | undefined;
126
-
127
- public constructor(
128
- authenticators: readonly AdbAuthenticator[],
129
- credentialStore: AdbCredentialStore
130
- ) {
131
- this.authenticators = authenticators;
132
- this.credentialStore = credentialStore;
133
- }
134
-
135
- private getNextRequest = (): Promise<AdbPacketData> => {
136
- return this.pendingRequest.promise;
137
- };
138
-
139
- private async* invokeAuthenticator(): AsyncGenerator<AdbPacketData, void, void> {
140
- for (const authenticator of this.authenticators) {
141
- for await (const packet of authenticator(this.credentialStore, this.getNextRequest)) {
142
- // If the authenticator yielded a response
143
- // Prepare `nextRequest` for next authentication request
144
- this.pendingRequest = new PromiseResolver();
145
-
146
- // Yield the response to outer layer
147
- yield packet;
148
- }
149
-
150
- // If the authenticator returned,
151
- // Next authenticator will be given the same `pendingRequest`
152
- }
153
- }
154
-
155
- public async process(packet: AdbPacketData): Promise<AdbPacketData> {
156
- if (!this.iterator) {
157
- this.iterator = this.invokeAuthenticator();
158
- }
159
-
160
- this.pendingRequest.resolve(packet);
161
-
162
- const result = await this.iterator.next();
163
- if (result.done) {
164
- throw new Error('No authenticator can handle the request');
165
- }
166
-
167
- return result.value;
168
- }
169
-
170
- public dispose() {
171
- this.iterator?.return?.();
172
- }
173
- }
1
+ import { PromiseResolver } from '@yume-chan/async';
2
+ import type { Disposable } from '@yume-chan/event';
3
+ import type { ValueOrPromise } from '@yume-chan/struct';
4
+
5
+ import { calculatePublicKey, calculatePublicKeyLength, sign } from './crypto.js';
6
+ import { AdbCommand, type AdbPacketData } from './packet.js';
7
+ import { calculateBase64EncodedLength, encodeBase64 } from './utils/index.js';
8
+
9
+ export type AdbKeyIterable = Iterable<Uint8Array> | AsyncIterable<Uint8Array>;
10
+
11
+ export interface AdbCredentialStore {
12
+ /**
13
+ * Generate and store a RSA private key with modulus length `2048` and public exponent `65537`.
14
+ *
15
+ * The returned `Uint8Array` is the private key in PKCS #8 format.
16
+ */
17
+ generateKey(): ValueOrPromise<Uint8Array>;
18
+
19
+ /**
20
+ * Synchronously or asynchronously iterate through all stored RSA private keys.
21
+ *
22
+ * Each call to `iterateKeys` must return a different iterator that iterate through all stored keys.
23
+ */
24
+ iterateKeys(): AdbKeyIterable;
25
+ }
26
+
27
+ export enum AdbAuthType {
28
+ Token = 1,
29
+ Signature = 2,
30
+ PublicKey = 3,
31
+ }
32
+
33
+ export interface AdbAuthenticator {
34
+ /**
35
+ * @param getNextRequest
36
+ *
37
+ * Call this function to get the next authentication request packet from device.
38
+ *
39
+ * After calling `getNextRequest`, authenticator can `yield` a packet as response, or `return` to indicate its incapability of handling the request.
40
+ *
41
+ * After `return`, the `AdbAuthenticatorHandler` will move on to next authenticator and never go back.
42
+ *
43
+ * Calling `getNextRequest` multiple times without `yield` or `return` will always return the same request.
44
+ */
45
+ (
46
+ credentialStore: AdbCredentialStore,
47
+ getNextRequest: () => Promise<AdbPacketData>
48
+ ): AsyncIterable<AdbPacketData>;
49
+ }
50
+
51
+ export const AdbSignatureAuthenticator: AdbAuthenticator = async function* (
52
+ credentialStore: AdbCredentialStore,
53
+ getNextRequest: () => Promise<AdbPacketData>,
54
+ ): AsyncIterable<AdbPacketData> {
55
+ for await (const key of credentialStore.iterateKeys()) {
56
+ const packet = await getNextRequest();
57
+
58
+ if (packet.arg0 !== AdbAuthType.Token) {
59
+ return;
60
+ }
61
+
62
+ const signature = sign(key, packet.payload);
63
+ yield {
64
+ command: AdbCommand.Auth,
65
+ arg0: AdbAuthType.Signature,
66
+ arg1: 0,
67
+ payload: new Uint8Array(signature),
68
+ };
69
+ }
70
+ };
71
+
72
+ export const AdbPublicKeyAuthenticator: AdbAuthenticator = async function* (
73
+ credentialStore: AdbCredentialStore,
74
+ getNextRequest: () => Promise<AdbPacketData>,
75
+ ): AsyncIterable<AdbPacketData> {
76
+ const packet = await getNextRequest();
77
+
78
+ if (packet.arg0 !== AdbAuthType.Token) {
79
+ return;
80
+ }
81
+
82
+ let privateKey: Uint8Array | undefined;
83
+ for await (const key of credentialStore.iterateKeys()) {
84
+ privateKey = key;
85
+ break;
86
+ }
87
+
88
+
89
+ if (!privateKey) {
90
+ privateKey = await credentialStore.generateKey();
91
+ }
92
+
93
+ const publicKeyLength = calculatePublicKeyLength();
94
+ const [publicKeyBase64Length] = calculateBase64EncodedLength(publicKeyLength);
95
+
96
+ // The public key is null terminated,
97
+ // So we allocate the buffer with one extra byte.
98
+ const publicKeyBuffer = new Uint8Array(publicKeyBase64Length + 1);
99
+
100
+ calculatePublicKey(privateKey, publicKeyBuffer);
101
+ encodeBase64(
102
+ publicKeyBuffer.subarray(0, publicKeyLength),
103
+ publicKeyBuffer
104
+ );
105
+
106
+ yield {
107
+ command: AdbCommand.Auth,
108
+ arg0: AdbAuthType.PublicKey,
109
+ arg1: 0,
110
+ payload: publicKeyBuffer,
111
+ };
112
+ };
113
+
114
+ export const ADB_DEFAULT_AUTHENTICATORS: AdbAuthenticator[] = [
115
+ AdbSignatureAuthenticator,
116
+ AdbPublicKeyAuthenticator,
117
+ ];
118
+
119
+ export class AdbAuthenticationProcessor implements Disposable {
120
+ public readonly authenticators: readonly AdbAuthenticator[];
121
+
122
+ private readonly credentialStore: AdbCredentialStore;
123
+
124
+ private pendingRequest = new PromiseResolver<AdbPacketData>();
125
+
126
+ private iterator: AsyncIterator<AdbPacketData, void, void> | undefined;
127
+
128
+ public constructor(
129
+ authenticators: readonly AdbAuthenticator[],
130
+ credentialStore: AdbCredentialStore
131
+ ) {
132
+ this.authenticators = authenticators;
133
+ this.credentialStore = credentialStore;
134
+ }
135
+
136
+ private getNextRequest = (): Promise<AdbPacketData> => {
137
+ return this.pendingRequest.promise;
138
+ };
139
+
140
+ private async* invokeAuthenticator(): AsyncGenerator<AdbPacketData, void, void> {
141
+ for (const authenticator of this.authenticators) {
142
+ for await (const packet of authenticator(this.credentialStore, this.getNextRequest)) {
143
+ // If the authenticator yielded a response
144
+ // Prepare `nextRequest` for next authentication request
145
+ this.pendingRequest = new PromiseResolver();
146
+
147
+ // Yield the response to outer layer
148
+ yield packet;
149
+ }
150
+
151
+ // If the authenticator returned,
152
+ // Next authenticator will be given the same `pendingRequest`
153
+ }
154
+ }
155
+
156
+ public async process(packet: AdbPacketData): Promise<AdbPacketData> {
157
+ if (!this.iterator) {
158
+ this.iterator = this.invokeAuthenticator();
159
+ }
160
+
161
+ this.pendingRequest.resolve(packet);
162
+
163
+ const result = await this.iterator.next();
164
+ if (result.done) {
165
+ throw new Error('No authenticator can handle the request');
166
+ }
167
+
168
+ return result.value;
169
+ }
170
+
171
+ public dispose() {
172
+ this.iterator?.return?.();
173
+ }
174
+ }
package/src/backend.ts CHANGED
@@ -1,11 +1,12 @@
1
- import type { ValueOrPromise } from '@yume-chan/struct';
2
- import type { AdbPacketData, AdbPacketInit } from "./packet.js";
3
- import type { ReadableWritablePair } from "./stream/index.js";
4
-
5
- export interface AdbBackend {
6
- readonly serial: string;
7
-
8
- readonly name: string | undefined;
9
-
10
- connect(): ValueOrPromise<ReadableWritablePair<AdbPacketData, AdbPacketInit>>;
11
- }
1
+ import type { ReadableWritablePair } from '@yume-chan/stream-extra';
2
+ import type { ValueOrPromise } from '@yume-chan/struct';
3
+
4
+ import type { AdbPacketData, AdbPacketInit } from './packet.js';
5
+
6
+ export interface AdbBackend {
7
+ readonly serial: string;
8
+
9
+ readonly name: string | undefined;
10
+
11
+ connect(): ValueOrPromise<ReadableWritablePair<AdbPacketData, AdbPacketInit>>;
12
+ }
@@ -1,11 +1,12 @@
1
- import { AutoDisposable } from '@yume-chan/event';
2
- import type { Adb } from '../adb.js';
3
-
4
- export class AdbCommandBase extends AutoDisposable {
5
- protected adb: Adb;
6
-
7
- public constructor(adb: Adb) {
8
- super();
9
- this.adb = adb;
10
- }
11
- }
1
+ import { AutoDisposable } from '@yume-chan/event';
2
+
3
+ import type { Adb } from '../adb.js';
4
+
5
+ export class AdbCommandBase extends AutoDisposable {
6
+ protected adb: Adb;
7
+
8
+ public constructor(adb: Adb) {
9
+ super();
10
+ this.adb = adb;
11
+ }
12
+ }
@@ -1,73 +1,78 @@
1
- import Struct from "@yume-chan/struct";
2
- import type { Adb } from '../adb.js';
3
- import { AdbBufferedStream } from '../stream/index.js';
4
-
5
- const Version =
6
- new Struct({ littleEndian: true })
7
- .uint32('version');
8
-
9
- /*
10
- * ADB uses 8 int32 fields to describe bit depths
11
- * The only combination I have seen is RGBA8888, which is
12
- * red_offset: 0
13
- * red_length: 8
14
- * blue_offset: 16
15
- * blue_length: 8
16
- * green_offset: 8
17
- * green_length: 8
18
- * alpha_offset: 24
19
- * alpha_length: 8
20
- */
21
-
22
- export const AdbFrameBufferV1 =
23
- new Struct({ littleEndian: true })
24
- .uint32('bpp')
25
- .uint32('size')
26
- .uint32('width')
27
- .uint32('height')
28
- .uint32('red_offset')
29
- .uint32('red_length')
30
- .uint32('blue_offset')
31
- .uint32('blue_length')
32
- .uint32('green_offset')
33
- .uint32('green_length')
34
- .uint32('alpha_offset')
35
- .uint32('alpha_length')
36
- .uint8Array('data', { lengthField: 'size' });
37
-
38
- export type AdbFrameBufferV1 = typeof AdbFrameBufferV1['TDeserializeResult'];
39
-
40
- export const AdbFrameBufferV2 =
41
- new Struct({ littleEndian: true })
42
- .uint32('bpp')
43
- .uint32('colorSpace')
44
- .uint32('size')
45
- .uint32('width')
46
- .uint32('height')
47
- .uint32('red_offset')
48
- .uint32('red_length')
49
- .uint32('blue_offset')
50
- .uint32('blue_length')
51
- .uint32('green_offset')
52
- .uint32('green_length')
53
- .uint32('alpha_offset')
54
- .uint32('alpha_length')
55
- .uint8Array('data', { lengthField: 'size' });
56
-
57
- export type AdbFrameBufferV2 = typeof AdbFrameBufferV2['TDeserializeResult'];
58
-
59
- export type AdbFrameBuffer = AdbFrameBufferV1 | AdbFrameBufferV2;
60
-
61
- export async function framebuffer(adb: Adb): Promise<AdbFrameBuffer> {
62
- const socket = await adb.createSocket('framebuffer:');
63
- const stream = new AdbBufferedStream(socket);
64
- const { version } = await Version.deserialize(stream);
65
- switch (version) {
66
- case 1:
67
- return AdbFrameBufferV1.deserialize(stream);
68
- case 2:
69
- return AdbFrameBufferV2.deserialize(stream);
70
- default:
71
- throw new Error('Unknown FrameBuffer version');
72
- }
73
- }
1
+ import { BufferedReadableStream } from '@yume-chan/stream-extra';
2
+ import Struct from '@yume-chan/struct';
3
+
4
+ import type { Adb } from '../adb.js';
5
+
6
+ const Version =
7
+ new Struct({ littleEndian: true })
8
+ .uint32('version');
9
+
10
+ export const AdbFrameBufferV1 =
11
+ new Struct({ littleEndian: true })
12
+ .uint32('bpp')
13
+ .uint32('size')
14
+ .uint32('width')
15
+ .uint32('height')
16
+ .uint32('red_offset')
17
+ .uint32('red_length')
18
+ .uint32('blue_offset')
19
+ .uint32('blue_length')
20
+ .uint32('green_offset')
21
+ .uint32('green_length')
22
+ .uint32('alpha_offset')
23
+ .uint32('alpha_length')
24
+ .uint8Array('data', { lengthField: 'size' });
25
+
26
+ export type AdbFrameBufferV1 = typeof AdbFrameBufferV1['TDeserializeResult'];
27
+
28
+ export const AdbFrameBufferV2 =
29
+ new Struct({ littleEndian: true })
30
+ .uint32('bpp')
31
+ .uint32('colorSpace')
32
+ .uint32('size')
33
+ .uint32('width')
34
+ .uint32('height')
35
+ .uint32('red_offset')
36
+ .uint32('red_length')
37
+ .uint32('blue_offset')
38
+ .uint32('blue_length')
39
+ .uint32('green_offset')
40
+ .uint32('green_length')
41
+ .uint32('alpha_offset')
42
+ .uint32('alpha_length')
43
+ .uint8Array('data', { lengthField: 'size' });
44
+
45
+ export type AdbFrameBufferV2 = typeof AdbFrameBufferV2['TDeserializeResult'];
46
+
47
+ /**
48
+ * ADB uses 8 int32 fields to describe bit depths
49
+ *
50
+ * The only combination I have seen is RGBA8888, which is
51
+ *
52
+ * red_offset: 0
53
+ * red_length: 8
54
+ * blue_offset: 16
55
+ * blue_length: 8
56
+ * green_offset: 8
57
+ * green_length: 8
58
+ * alpha_offset: 24
59
+ * alpha_length: 8
60
+ *
61
+ * But it doesn't mean that other combinations are not possible.
62
+ */
63
+ export type AdbFrameBuffer = AdbFrameBufferV1 | AdbFrameBufferV2;
64
+
65
+ export async function framebuffer(adb: Adb): Promise<AdbFrameBuffer> {
66
+ const socket = await adb.createSocket('framebuffer:');
67
+ const stream = new BufferedReadableStream(socket.readable);
68
+ const { version } = await Version.deserialize(stream);
69
+ switch (version) {
70
+ case 1:
71
+ // TODO: AdbFrameBuffer: does all v1 responses uses the same color space? Add it so the command returns same format for all versions.
72
+ return AdbFrameBufferV1.deserialize(stream);
73
+ case 2:
74
+ return AdbFrameBufferV2.deserialize(stream);
75
+ default:
76
+ throw new Error('Unknown FrameBuffer version');
77
+ }
78
+ }
@@ -1,8 +1,8 @@
1
- export * from './base.js';
2
- export * from './framebuffer.js';
3
- export * from './install.js';
4
- export * from './power.js';
5
- export * from './reverse.js';
6
- export * from './subprocess/index.js';
7
- export * from './sync/index.js';
8
- export * from './tcpip.js';
1
+ export * from './base.js';
2
+ export * from './framebuffer.js';
3
+ export * from './install.js';
4
+ export * from './power.js';
5
+ export * from './reverse.js';
6
+ export * from './subprocess/index.js';
7
+ export * from './sync/index.js';
8
+ export * from './tcpip.js';
@@ -1,30 +1,32 @@
1
- import type { Adb } from "../adb.js";
2
- import { WrapWritableStream, WritableStream } from "../stream/index.js";
3
- import { escapeArg } from "./subprocess/index.js";
4
- import type { AdbSync } from "./sync/index.js";
5
-
6
- export function install(
7
- adb: Adb,
8
- ): WritableStream<Uint8Array> {
9
- const filename = `/data/local/tmp/${Math.random().toString().substring(2)}.apk`;
10
-
11
- let sync!: AdbSync;
12
- return new WrapWritableStream<Uint8Array>({
13
- async start() {
14
- // TODO: install: support other install apk methods (streaming, etc.)
15
-
16
- // Upload apk file to tmp folder
17
- sync = await adb.sync();
18
- return sync.write(filename, undefined, undefined);
19
- },
20
- async close() {
21
- sync.dispose();
22
-
23
- // Invoke `pm install` to install it
24
- await adb.subprocess.spawnAndWaitLegacy(['pm', 'install', escapeArg(filename)]);
25
-
26
- // Remove the temp file
27
- await adb.rm(filename);
28
- }
29
- });
30
- }
1
+ import { WrapWritableStream, WritableStream } from '@yume-chan/stream-extra';
2
+
3
+ import type { Adb } from '../adb.js';
4
+ import { escapeArg } from './subprocess/index.js';
5
+ import type { AdbSync } from './sync/index.js';
6
+
7
+ export function install(
8
+ adb: Adb,
9
+ ): WritableStream<Uint8Array> {
10
+ const filename = `/data/local/tmp/${Math.random().toString().substring(2)}.apk`;
11
+
12
+ let sync!: AdbSync;
13
+ return new WrapWritableStream<Uint8Array>({
14
+ async start() {
15
+ // TODO: install: support other install apk methods (streaming, etc.)
16
+ // TODO: install: support split apk formats (`adb install-multiple`)
17
+
18
+ // Upload apk file to tmp folder
19
+ sync = await adb.sync();
20
+ return sync.write(filename, undefined, undefined);
21
+ },
22
+ async close() {
23
+ sync.dispose();
24
+
25
+ // Invoke `pm install` to install it
26
+ await adb.subprocess.spawnAndWaitLegacy(['pm', 'install', escapeArg(filename)]);
27
+
28
+ // Remove the temp file
29
+ await adb.rm(filename);
30
+ }
31
+ });
32
+ }