@yume-chan/adb 0.0.9 → 0.0.12

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 (407) hide show
  1. package/CHANGELOG.json +55 -0
  2. package/CHANGELOG.md +35 -0
  3. package/LICENSE +21 -21
  4. package/README.md +240 -257
  5. package/esm/adb.d.ts +48 -0
  6. package/esm/adb.d.ts.map +1 -0
  7. package/esm/adb.js +141 -145
  8. package/esm/adb.js.map +1 -1
  9. package/{dts → esm}/auth.d.ts +17 -7
  10. package/esm/auth.d.ts.map +1 -0
  11. package/esm/auth.js +69 -109
  12. package/esm/auth.js.map +1 -1
  13. package/esm/backend.d.ts +9 -0
  14. package/esm/backend.d.ts.map +1 -0
  15. package/{dts → esm}/commands/base.d.ts +1 -1
  16. package/esm/commands/base.d.ts.map +1 -0
  17. package/esm/commands/base.js +1 -0
  18. package/esm/commands/base.js.map +1 -1
  19. package/{dts → esm}/commands/framebuffer.d.ts +3 -3
  20. package/esm/commands/framebuffer.d.ts.map +1 -0
  21. package/esm/commands/framebuffer.js +15 -18
  22. package/esm/commands/framebuffer.js.map +1 -1
  23. package/esm/commands/index.d.ts +9 -0
  24. package/esm/commands/index.d.ts.map +1 -0
  25. package/esm/commands/index.js +8 -8
  26. package/esm/commands/index.js.map +1 -1
  27. package/esm/commands/install.d.ts +4 -0
  28. package/esm/commands/install.d.ts.map +1 -0
  29. package/esm/commands/install.js +21 -13
  30. package/esm/commands/install.js.map +1 -1
  31. package/esm/commands/power.d.ts +23 -0
  32. package/esm/commands/power.d.ts.map +1 -0
  33. package/esm/commands/power.js +45 -0
  34. package/esm/commands/power.js.map +1 -0
  35. package/{dts → esm}/commands/reverse.d.ts +3 -3
  36. package/esm/commands/reverse.d.ts.map +1 -0
  37. package/esm/commands/reverse.js +50 -60
  38. package/esm/commands/reverse.js.map +1 -1
  39. package/esm/commands/subprocess/index.d.ts +57 -0
  40. package/esm/commands/subprocess/index.d.ts.map +1 -0
  41. package/esm/commands/subprocess/index.js +83 -0
  42. package/esm/commands/subprocess/index.js.map +1 -0
  43. package/esm/commands/subprocess/legacy.d.ts +28 -0
  44. package/esm/commands/subprocess/legacy.d.ts.map +1 -0
  45. package/esm/commands/subprocess/legacy.js +44 -0
  46. package/esm/commands/subprocess/legacy.js.map +1 -0
  47. package/esm/commands/subprocess/protocol.d.ts +38 -0
  48. package/esm/commands/subprocess/protocol.d.ts.map +1 -0
  49. package/esm/commands/subprocess/protocol.js +155 -0
  50. package/esm/commands/subprocess/protocol.js.map +1 -0
  51. package/esm/commands/subprocess/types.d.ts +47 -0
  52. package/esm/commands/subprocess/types.d.ts.map +1 -0
  53. package/esm/commands/{shell → subprocess}/types.js +0 -0
  54. package/{cjs/commands/shell → esm/commands/subprocess}/types.js.map +1 -1
  55. package/{dts/commands/shell → esm/commands/subprocess}/utils.d.ts +0 -0
  56. package/esm/commands/subprocess/utils.d.ts.map +1 -0
  57. package/esm/commands/{shell → subprocess}/utils.js +0 -0
  58. package/esm/commands/subprocess/utils.js.map +1 -0
  59. package/esm/commands/sync/index.d.ts +8 -0
  60. package/esm/commands/sync/index.d.ts.map +1 -0
  61. package/esm/commands/sync/index.js +7 -7
  62. package/esm/commands/sync/index.js.map +1 -1
  63. package/{dts → esm}/commands/sync/list.d.ts +4 -4
  64. package/esm/commands/sync/list.d.ts.map +1 -0
  65. package/esm/commands/sync/list.js +16 -19
  66. package/esm/commands/sync/list.js.map +1 -1
  67. package/esm/commands/sync/pull.d.ts +11 -0
  68. package/esm/commands/sync/pull.d.ts.map +1 -0
  69. package/esm/commands/sync/pull.js +17 -11
  70. package/esm/commands/sync/pull.js.map +1 -1
  71. package/esm/commands/sync/push.d.ts +8 -0
  72. package/esm/commands/sync/push.d.ts.map +1 -0
  73. package/esm/commands/sync/push.js +19 -37
  74. package/esm/commands/sync/push.js.map +1 -1
  75. package/{dts → esm}/commands/sync/request.d.ts +3 -3
  76. package/esm/commands/sync/request.d.ts.map +1 -0
  77. package/esm/commands/sync/request.js +24 -26
  78. package/esm/commands/sync/request.js.map +1 -1
  79. package/{dts → esm}/commands/sync/response.d.ts +3 -3
  80. package/esm/commands/sync/response.d.ts.map +1 -0
  81. package/esm/commands/sync/response.js +16 -19
  82. package/esm/commands/sync/response.js.map +1 -1
  83. package/{dts → esm}/commands/sync/stat.d.ts +4 -4
  84. package/esm/commands/sync/stat.d.ts.map +1 -0
  85. package/esm/commands/sync/stat.js +22 -27
  86. package/esm/commands/sync/stat.js.map +1 -1
  87. package/esm/commands/sync/sync.d.ts +83 -0
  88. package/esm/commands/sync/sync.d.ts.map +1 -0
  89. package/esm/commands/sync/sync.js +92 -89
  90. package/esm/commands/sync/sync.js.map +1 -1
  91. package/{dts → esm}/commands/tcpip.d.ts +1 -1
  92. package/{dts → esm}/commands/tcpip.d.ts.map +1 -1
  93. package/esm/commands/tcpip.js +14 -19
  94. package/esm/commands/tcpip.js.map +1 -1
  95. package/esm/crypto.d.ts +24 -0
  96. package/esm/crypto.d.ts.map +1 -0
  97. package/esm/crypto.js +33 -31
  98. package/esm/crypto.js.map +1 -1
  99. package/{dts → esm}/features.d.ts +0 -0
  100. package/{dts → esm}/features.d.ts.map +0 -0
  101. package/esm/features.js +1 -1
  102. package/esm/features.js.map +1 -1
  103. package/esm/index.d.ts +11 -0
  104. package/esm/index.d.ts.map +1 -0
  105. package/esm/index.js +10 -10
  106. package/esm/index.js.map +1 -1
  107. package/esm/packet.d.ts +28 -0
  108. package/esm/packet.d.ts.map +1 -0
  109. package/esm/packet.js +26 -53
  110. package/esm/packet.js.map +1 -1
  111. package/esm/socket/controller.d.ts +37 -0
  112. package/esm/socket/controller.d.ts.map +1 -0
  113. package/esm/socket/controller.js +52 -66
  114. package/esm/socket/controller.js.map +1 -1
  115. package/{dts → esm}/socket/dispatcher.d.ts +10 -23
  116. package/esm/socket/dispatcher.d.ts.map +1 -0
  117. package/esm/socket/dispatcher.js +148 -164
  118. package/esm/socket/dispatcher.js.map +1 -1
  119. package/esm/socket/index.d.ts +3 -0
  120. package/esm/socket/index.d.ts.map +1 -0
  121. package/esm/socket/index.js +2 -6
  122. package/esm/socket/index.js.map +1 -1
  123. package/esm/socket/socket.d.ts +34 -0
  124. package/esm/socket/socket.d.ts.map +1 -0
  125. package/esm/socket/socket.js +69 -14
  126. package/esm/socket/socket.js.map +1 -1
  127. package/esm/stream/buffered.d.ts +35 -0
  128. package/esm/stream/buffered.d.ts.map +1 -0
  129. package/esm/stream/buffered.js +123 -0
  130. package/esm/stream/buffered.js.map +1 -0
  131. package/esm/stream/detect.bak.d.ts +240 -0
  132. package/esm/stream/detect.bak.d.ts.map +1 -0
  133. package/esm/stream/detect.bak.js +60 -0
  134. package/esm/stream/detect.bak.js.map +1 -0
  135. package/esm/stream/detect.d.ts +18 -0
  136. package/esm/stream/detect.d.ts.map +1 -0
  137. package/esm/stream/detect.js +6 -0
  138. package/esm/stream/detect.js.map +1 -0
  139. package/esm/stream/detect.native.d.ts +240 -0
  140. package/esm/stream/detect.native.d.ts.map +1 -0
  141. package/esm/stream/detect.native.js +60 -0
  142. package/esm/stream/detect.native.js.map +1 -0
  143. package/esm/stream/detect.polyfill.d.ts +18 -0
  144. package/esm/stream/detect.polyfill.d.ts.map +1 -0
  145. package/esm/stream/detect.polyfill.js +6 -0
  146. package/esm/stream/detect.polyfill.js.map +1 -0
  147. package/esm/stream/index.d.ts +4 -0
  148. package/esm/stream/index.d.ts.map +1 -0
  149. package/esm/stream/index.js +3 -2
  150. package/esm/stream/index.js.map +1 -1
  151. package/esm/stream/transform.d.ts +98 -0
  152. package/esm/stream/transform.d.ts.map +1 -0
  153. package/esm/stream/transform.js +352 -0
  154. package/esm/stream/transform.js.map +1 -0
  155. package/{dts → esm}/utils/auto-reset-event.d.ts +1 -1
  156. package/esm/utils/auto-reset-event.d.ts.map +1 -0
  157. package/esm/utils/auto-reset-event.js +2 -1
  158. package/esm/utils/auto-reset-event.js.map +1 -1
  159. package/esm/utils/base64.d.ts +5 -0
  160. package/esm/utils/base64.d.ts.map +1 -0
  161. package/esm/utils/base64.js +116 -80
  162. package/esm/utils/base64.js.map +1 -1
  163. package/esm/utils/encoding.d.ts +3 -0
  164. package/esm/utils/encoding.d.ts.map +1 -0
  165. package/esm/utils/encoding.js +11 -0
  166. package/esm/utils/encoding.js.map +1 -0
  167. package/esm/utils/index.d.ts +4 -0
  168. package/esm/utils/index.d.ts.map +1 -0
  169. package/esm/utils/index.js +3 -4
  170. package/esm/utils/index.js.map +1 -1
  171. package/package.json +49 -50
  172. package/src/adb.ts +247 -242
  173. package/src/auth.ts +170 -156
  174. package/src/backend.ts +11 -24
  175. package/src/commands/base.ts +11 -11
  176. package/src/commands/framebuffer.ts +73 -73
  177. package/src/commands/index.ts +8 -8
  178. package/src/commands/install.ts +32 -21
  179. package/src/commands/power.ts +54 -0
  180. package/src/commands/reverse.ts +136 -133
  181. package/src/commands/subprocess/index.ts +124 -0
  182. package/src/commands/subprocess/legacy.ts +58 -0
  183. package/src/commands/subprocess/protocol.ts +185 -0
  184. package/src/commands/subprocess/types.ts +55 -0
  185. package/src/commands/{shell → subprocess}/utils.ts +20 -20
  186. package/src/commands/sync/index.ts +7 -7
  187. package/src/commands/sync/list.ts +40 -39
  188. package/src/commands/sync/pull.ts +43 -34
  189. package/src/commands/sync/push.ts +41 -46
  190. package/src/commands/sync/request.ts +49 -48
  191. package/src/commands/sync/response.ts +58 -57
  192. package/src/commands/sync/stat.ts +123 -121
  193. package/src/commands/sync/sync.ts +145 -113
  194. package/src/commands/tcpip.ts +21 -21
  195. package/src/crypto.ts +280 -280
  196. package/src/features.ts +5 -5
  197. package/src/index.ts +11 -10
  198. package/src/packet.ts +69 -89
  199. package/src/socket/dispatcher.ts +256 -269
  200. package/src/socket/index.ts +2 -6
  201. package/src/socket/socket.ts +129 -28
  202. package/src/stream/buffered.ts +147 -0
  203. package/src/stream/detect.native.ts +362 -0
  204. package/src/stream/detect.polyfill.ts +25 -0
  205. package/src/stream/detect.ts +25 -0
  206. package/src/stream/index.ts +3 -2
  207. package/src/stream/transform.ts +427 -0
  208. package/src/utils/auto-reset-event.ts +41 -41
  209. package/src/utils/base64.ts +306 -274
  210. package/src/utils/encoding.ts +13 -0
  211. package/src/utils/index.ts +3 -4
  212. package/tsconfig.build.json +3 -0
  213. package/tsconfig.build.tsbuildinfo +1 -0
  214. package/tsconfig.test.json +10 -0
  215. package/cjs/adb.js +0 -205
  216. package/cjs/adb.js.map +0 -1
  217. package/cjs/auth.js +0 -141
  218. package/cjs/auth.js.map +0 -1
  219. package/cjs/backend.js +0 -3
  220. package/cjs/backend.js.map +0 -1
  221. package/cjs/commands/base.js +0 -12
  222. package/cjs/commands/base.js.map +0 -1
  223. package/cjs/commands/demo-mode.js +0 -174
  224. package/cjs/commands/demo-mode.js.map +0 -1
  225. package/cjs/commands/framebuffer.js +0 -66
  226. package/cjs/commands/framebuffer.js.map +0 -1
  227. package/cjs/commands/index.js +0 -12
  228. package/cjs/commands/index.js.map +0 -1
  229. package/cjs/commands/install.js +0 -20
  230. package/cjs/commands/install.js.map +0 -1
  231. package/cjs/commands/reverse.js +0 -105
  232. package/cjs/commands/reverse.js.map +0 -1
  233. package/cjs/commands/shell/index.js +0 -56
  234. package/cjs/commands/shell/index.js.map +0 -1
  235. package/cjs/commands/shell/legacy.js +0 -37
  236. package/cjs/commands/shell/legacy.js.map +0 -1
  237. package/cjs/commands/shell/protocol.js +0 -83
  238. package/cjs/commands/shell/protocol.js.map +0 -1
  239. package/cjs/commands/shell/types.js +0 -3
  240. package/cjs/commands/shell/utils.js +0 -23
  241. package/cjs/commands/shell/utils.js.map +0 -1
  242. package/cjs/commands/sync/index.js +0 -11
  243. package/cjs/commands/sync/index.js.map +0 -1
  244. package/cjs/commands/sync/list.js +0 -36
  245. package/cjs/commands/sync/list.js.map +0 -1
  246. package/cjs/commands/sync/pull.js +0 -34
  247. package/cjs/commands/sync/pull.js.map +0 -1
  248. package/cjs/commands/sync/push.js +0 -49
  249. package/cjs/commands/sync/push.js.map +0 -1
  250. package/cjs/commands/sync/request.js +0 -48
  251. package/cjs/commands/sync/request.js.map +0 -1
  252. package/cjs/commands/sync/response.js +0 -53
  253. package/cjs/commands/sync/response.js.map +0 -1
  254. package/cjs/commands/sync/stat.js +0 -109
  255. package/cjs/commands/sync/stat.js.map +0 -1
  256. package/cjs/commands/sync/sync.js +0 -118
  257. package/cjs/commands/sync/sync.js.map +0 -1
  258. package/cjs/commands/tcpip.js +0 -28
  259. package/cjs/commands/tcpip.js.map +0 -1
  260. package/cjs/crypto.js +0 -231
  261. package/cjs/crypto.js.map +0 -1
  262. package/cjs/features.js +0 -10
  263. package/cjs/features.js.map +0 -1
  264. package/cjs/index.js +0 -14
  265. package/cjs/index.js.map +0 -1
  266. package/cjs/packet.js +0 -77
  267. package/cjs/packet.js.map +0 -1
  268. package/cjs/socket/close-event-emitter.js +0 -32
  269. package/cjs/socket/close-event-emitter.js.map +0 -1
  270. package/cjs/socket/controller.js +0 -84
  271. package/cjs/socket/controller.js.map +0 -1
  272. package/cjs/socket/data-event-emitter.js +0 -29
  273. package/cjs/socket/data-event-emitter.js.map +0 -1
  274. package/cjs/socket/dispatcher.js +0 -219
  275. package/cjs/socket/dispatcher.js.map +0 -1
  276. package/cjs/socket/index.js +0 -10
  277. package/cjs/socket/index.js.map +0 -1
  278. package/cjs/socket/logger.js +0 -3
  279. package/cjs/socket/logger.js.map +0 -1
  280. package/cjs/socket/socket.js +0 -24
  281. package/cjs/socket/socket.js.map +0 -1
  282. package/cjs/stream/buffered-stream.js +0 -78
  283. package/cjs/stream/buffered-stream.js.map +0 -1
  284. package/cjs/stream/index.js +0 -6
  285. package/cjs/stream/index.js.map +0 -1
  286. package/cjs/stream/stream.js +0 -45
  287. package/cjs/stream/stream.js.map +0 -1
  288. package/cjs/utils/auto-reset-event.js +0 -37
  289. package/cjs/utils/auto-reset-event.js.map +0 -1
  290. package/cjs/utils/base64.js +0 -210
  291. package/cjs/utils/base64.js.map +0 -1
  292. package/cjs/utils/chunk.js +0 -75
  293. package/cjs/utils/chunk.js.map +0 -1
  294. package/cjs/utils/event-queue.js +0 -108
  295. package/cjs/utils/event-queue.js.map +0 -1
  296. package/cjs/utils/index.js +0 -8
  297. package/cjs/utils/index.js.map +0 -1
  298. package/dts/adb.d.ts +0 -46
  299. package/dts/adb.d.ts.map +0 -1
  300. package/dts/auth.d.ts.map +0 -1
  301. package/dts/backend.d.ts +0 -15
  302. package/dts/backend.d.ts.map +0 -1
  303. package/dts/commands/base.d.ts.map +0 -1
  304. package/dts/commands/demo-mode.d.ts +0 -41
  305. package/dts/commands/demo-mode.d.ts.map +0 -1
  306. package/dts/commands/framebuffer.d.ts.map +0 -1
  307. package/dts/commands/index.d.ts +0 -9
  308. package/dts/commands/index.d.ts.map +0 -1
  309. package/dts/commands/install.d.ts +0 -3
  310. package/dts/commands/install.d.ts.map +0 -1
  311. package/dts/commands/reverse.d.ts.map +0 -1
  312. package/dts/commands/shell/index.d.ts +0 -20
  313. package/dts/commands/shell/index.d.ts.map +0 -1
  314. package/dts/commands/shell/legacy.d.ts +0 -27
  315. package/dts/commands/shell/legacy.d.ts.map +0 -1
  316. package/dts/commands/shell/protocol.d.ts +0 -37
  317. package/dts/commands/shell/protocol.d.ts.map +0 -1
  318. package/dts/commands/shell/types.d.ts +0 -15
  319. package/dts/commands/shell/types.d.ts.map +0 -1
  320. package/dts/commands/shell/utils.d.ts.map +0 -1
  321. package/dts/commands/sync/index.d.ts +0 -8
  322. package/dts/commands/sync/index.d.ts.map +0 -1
  323. package/dts/commands/sync/list.d.ts.map +0 -1
  324. package/dts/commands/sync/pull.d.ts +0 -11
  325. package/dts/commands/sync/pull.d.ts.map +0 -1
  326. package/dts/commands/sync/push.d.ts +0 -8
  327. package/dts/commands/sync/push.d.ts.map +0 -1
  328. package/dts/commands/sync/request.d.ts.map +0 -1
  329. package/dts/commands/sync/response.d.ts.map +0 -1
  330. package/dts/commands/sync/stat.d.ts.map +0 -1
  331. package/dts/commands/sync/sync.d.ts +0 -68
  332. package/dts/commands/sync/sync.d.ts.map +0 -1
  333. package/dts/crypto.d.ts +0 -17
  334. package/dts/crypto.d.ts.map +0 -1
  335. package/dts/index.d.ts +0 -11
  336. package/dts/index.d.ts.map +0 -1
  337. package/dts/packet.d.ts +0 -27
  338. package/dts/packet.d.ts.map +0 -1
  339. package/dts/socket/close-event-emitter.d.ts +0 -8
  340. package/dts/socket/close-event-emitter.d.ts.map +0 -1
  341. package/dts/socket/controller.d.ts +0 -43
  342. package/dts/socket/controller.d.ts.map +0 -1
  343. package/dts/socket/data-event-emitter.d.ts +0 -10
  344. package/dts/socket/data-event-emitter.d.ts.map +0 -1
  345. package/dts/socket/dispatcher.d.ts.map +0 -1
  346. package/dts/socket/index.d.ts +0 -7
  347. package/dts/socket/index.d.ts.map +0 -1
  348. package/dts/socket/logger.d.ts +0 -9
  349. package/dts/socket/logger.d.ts.map +0 -1
  350. package/dts/socket/socket.d.ts +0 -22
  351. package/dts/socket/socket.d.ts.map +0 -1
  352. package/dts/stream/buffered-stream.d.ts +0 -30
  353. package/dts/stream/buffered-stream.d.ts.map +0 -1
  354. package/dts/stream/index.d.ts +0 -3
  355. package/dts/stream/index.d.ts.map +0 -1
  356. package/dts/stream/stream.d.ts +0 -15
  357. package/dts/stream/stream.d.ts.map +0 -1
  358. package/dts/utils/auto-reset-event.d.ts.map +0 -1
  359. package/dts/utils/base64.d.ts +0 -7
  360. package/dts/utils/base64.d.ts.map +0 -1
  361. package/dts/utils/chunk.d.ts +0 -3
  362. package/dts/utils/chunk.d.ts.map +0 -1
  363. package/dts/utils/event-queue.d.ts +0 -35
  364. package/dts/utils/event-queue.d.ts.map +0 -1
  365. package/dts/utils/index.d.ts +0 -5
  366. package/dts/utils/index.d.ts.map +0 -1
  367. package/esm/commands/demo-mode.js +0 -170
  368. package/esm/commands/demo-mode.js.map +0 -1
  369. package/esm/commands/shell/index.js +0 -52
  370. package/esm/commands/shell/index.js.map +0 -1
  371. package/esm/commands/shell/legacy.js +0 -33
  372. package/esm/commands/shell/legacy.js.map +0 -1
  373. package/esm/commands/shell/protocol.js +0 -79
  374. package/esm/commands/shell/protocol.js.map +0 -1
  375. package/esm/commands/shell/types.js.map +0 -1
  376. package/esm/commands/shell/utils.js.map +0 -1
  377. package/esm/socket/close-event-emitter.js +0 -28
  378. package/esm/socket/close-event-emitter.js.map +0 -1
  379. package/esm/socket/data-event-emitter.js +0 -25
  380. package/esm/socket/data-event-emitter.js.map +0 -1
  381. package/esm/socket/logger.js +0 -2
  382. package/esm/socket/logger.js.map +0 -1
  383. package/esm/stream/buffered-stream.js +0 -73
  384. package/esm/stream/buffered-stream.js.map +0 -1
  385. package/esm/stream/stream.js +0 -41
  386. package/esm/stream/stream.js.map +0 -1
  387. package/esm/utils/chunk.js +0 -70
  388. package/esm/utils/chunk.js.map +0 -1
  389. package/esm/utils/event-queue.js +0 -104
  390. package/esm/utils/event-queue.js.map +0 -1
  391. package/src/commands/demo-mode.ts +0 -160
  392. package/src/commands/shell/index.ts +0 -68
  393. package/src/commands/shell/legacy.ts +0 -42
  394. package/src/commands/shell/protocol.ts +0 -94
  395. package/src/commands/shell/types.ts +0 -21
  396. package/src/socket/close-event-emitter.ts +0 -28
  397. package/src/socket/controller.ts +0 -105
  398. package/src/socket/data-event-emitter.ts +0 -27
  399. package/src/socket/logger.ts +0 -12
  400. package/src/stream/buffered-stream.ts +0 -100
  401. package/src/stream/stream.ts +0 -50
  402. package/src/utils/chunk.ts +0 -70
  403. package/src/utils/event-queue.ts +0 -145
  404. package/tsconfig.cjs.json +0 -11
  405. package/tsconfig.esm.json +0 -28
  406. package/tsconfig.esm.tsbuildinfo +0 -1305
  407. package/tsconfig.json +0 -18
@@ -1,133 +1,136 @@
1
- import { AutoDisposable } from '@yume-chan/event';
2
- import Struct from '@yume-chan/struct';
3
- import { AdbPacket } from '../packet';
4
- import { AdbIncomingSocketEventArgs, AdbPacketDispatcher, AdbSocket } from '../socket';
5
- import { AdbBufferedStream } from '../stream';
6
-
7
- export interface AdbReverseHandler {
8
- onSocket(packet: AdbPacket, socket: AdbSocket): void;
9
- }
10
-
11
- export interface AdbForwardListener {
12
- deviceSerial: string;
13
-
14
- localName: string;
15
-
16
- remoteName: string;
17
- }
18
-
19
- const AdbReverseStringResponse =
20
- new Struct({ littleEndian: true })
21
- .string('length', { length: 4 })
22
- .string('content', { lengthField: 'length', lengthFieldBase: 16 });
23
-
24
- const AdbReverseErrorResponse =
25
- new Struct({ littleEndian: true })
26
- .fields(AdbReverseStringResponse)
27
- .postDeserialize((value) => {
28
- throw new Error(value.content);
29
- });
30
-
31
- export class AdbReverseCommand extends AutoDisposable {
32
- protected localPortToHandler = new Map<number, AdbReverseHandler>();
33
-
34
- protected deviceAddressToLocalPort = new Map<string, number>();
35
-
36
- protected dispatcher: AdbPacketDispatcher;
37
-
38
- protected listening = false;
39
-
40
- public constructor(dispatcher: AdbPacketDispatcher) {
41
- super();
42
-
43
- this.dispatcher = dispatcher;
44
- this.addDisposable(this.dispatcher.onIncomingSocket(this.handleIncomingSocket, this));
45
- }
46
-
47
- protected handleIncomingSocket(e: AdbIncomingSocketEventArgs): void {
48
- if (e.handled) {
49
- return;
50
- }
51
-
52
- const address = this.dispatcher.backend.decodeUtf8(e.packet.payload!);
53
- // tcp:1234\0
54
- const port = Number.parseInt(address.substring(4));
55
- if (this.localPortToHandler.has(port)) {
56
- this.localPortToHandler.get(port)!.onSocket(e.packet, e.socket);
57
- e.handled = true;
58
- }
59
- }
60
-
61
- private async createBufferedStream(service: string) {
62
- const socket = await this.dispatcher.createSocket(service);
63
- return new AdbBufferedStream(socket);
64
- }
65
-
66
- private async sendRequest(service: string) {
67
- const stream = await this.createBufferedStream(service);
68
- const success = this.dispatcher.backend.decodeUtf8(await stream.read(4)) === 'OKAY';
69
- if (!success) {
70
- await AdbReverseErrorResponse.deserialize(stream);
71
- }
72
- return stream;
73
- }
74
-
75
- public async list(): Promise<AdbForwardListener[]> {
76
- const stream = await this.createBufferedStream('reverse:list-forward');
77
-
78
- const response = await AdbReverseStringResponse.deserialize(stream);
79
- return response.content!.split('\n').map(line => {
80
- const [deviceSerial, localName, remoteName] = line.split(' ');
81
- return { deviceSerial, localName, remoteName };
82
- });
83
-
84
- // No need to close the stream, device will close it
85
- }
86
-
87
- /**
88
- * @param deviceAddress The address adbd on device is listening on. Can be `tcp:0` to let adbd choose an available TCP port by itself.
89
- * @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.
90
- * @param handler A callback to handle incoming connections
91
- * @returns If `deviceAddress` is `tcp:0`, return `tcp:{ACTUAL_LISTENING_PORT}`; otherwise, return `deviceAddress`.
92
- */
93
- public async add(
94
- deviceAddress: string,
95
- localPort: number,
96
- handler: AdbReverseHandler,
97
- ): Promise<string> {
98
- const stream = await this.sendRequest(`reverse:forward:${deviceAddress};tcp:${localPort}`);
99
-
100
- // `tcp:0` tells the device to pick an available port.
101
- // However, device will response with the selected port for all `tcp:` requests.
102
- if (deviceAddress.startsWith('tcp:')) {
103
- const response = await AdbReverseStringResponse.deserialize(stream);
104
- deviceAddress = `tcp:${Number.parseInt(response.content!, 10)}`;
105
- }
106
-
107
- this.localPortToHandler.set(localPort, handler);
108
- this.deviceAddressToLocalPort.set(deviceAddress, localPort);
109
- return deviceAddress;
110
-
111
- // No need to close the stream, device will close it
112
- }
113
-
114
- public async remove(deviceAddress: string): Promise<void> {
115
- await this.sendRequest(`reverse:killforward:${deviceAddress}`);
116
-
117
- if (this.deviceAddressToLocalPort.has(deviceAddress)) {
118
- this.localPortToHandler.delete(this.deviceAddressToLocalPort.get(deviceAddress)!);
119
- this.deviceAddressToLocalPort.delete(deviceAddress);
120
- }
121
-
122
- // No need to close the stream, device will close it
123
- }
124
-
125
- public async removeAll(): Promise<void> {
126
- await this.sendRequest(`reverse:killforward-all`);
127
-
128
- this.deviceAddressToLocalPort.clear();
129
- this.localPortToHandler.clear();
130
-
131
- // No need to close the stream, device will close it
132
- }
133
- }
1
+ // cspell: ignore killforward
2
+
3
+ import { AutoDisposable } from '@yume-chan/event';
4
+ import Struct from '@yume-chan/struct';
5
+ import type { AdbPacketCore } 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: AdbPacketCore, 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
+ }
@@ -0,0 +1,124 @@
1
+ import type { Adb } from '../../adb.js';
2
+ import { DecodeUtf8Stream, GatherStringStream } from "../../stream/index.js";
3
+ import { AdbNoneSubprocessProtocol } from './legacy.js';
4
+ import { AdbShellSubprocessProtocol } from './protocol.js';
5
+ import type { AdbSubprocessProtocol, AdbSubprocessProtocolConstructor } from './types.js';
6
+
7
+ export * from './legacy.js';
8
+ export * from './protocol.js';
9
+ export * from './types.js';
10
+ export * from './utils.js';
11
+
12
+ export interface AdbSubprocessOptions {
13
+ /**
14
+ * A list of `AdbShellConstructor`s to be used.
15
+ *
16
+ * Different `AdbShell` has different capabilities, thus requires specific adaptations.
17
+ * Check each `AdbShell`'s documentation for details.
18
+ *
19
+ * The first one whose `isSupported` returns `true` will be used.
20
+ * If no `AdbShell` is supported, an error will be thrown.
21
+ *
22
+ * The default value is `[AdbShellProtocol, AdbLegacyShell]`.
23
+ */
24
+ protocols: AdbSubprocessProtocolConstructor[];
25
+ }
26
+
27
+ const DefaultOptions: AdbSubprocessOptions = {
28
+ protocols: [AdbShellSubprocessProtocol, AdbNoneSubprocessProtocol],
29
+ };
30
+
31
+ export interface SubprocessResult {
32
+ stdout: string;
33
+ stderr: string;
34
+ exitCode: number;
35
+ }
36
+
37
+ export class AdbSubprocess {
38
+ public readonly adb: Adb;
39
+
40
+ public constructor(adb: Adb) {
41
+ this.adb = adb;
42
+ }
43
+
44
+ private async createProtocol(command: string, options?: Partial<AdbSubprocessOptions>): Promise<AdbSubprocessProtocol> {
45
+ let { protocols } = { ...DefaultOptions, ...options };
46
+
47
+ let Constructor: AdbSubprocessProtocolConstructor | undefined;
48
+ for (const item of protocols) {
49
+ if (await item.isSupported(this.adb)) {
50
+ Constructor = item;
51
+ break;
52
+ }
53
+ }
54
+
55
+ if (!Constructor) {
56
+ throw new Error('No specified protocol is supported by the device');
57
+ }
58
+
59
+ return await Constructor.spawn(this.adb, command);
60
+ }
61
+
62
+ /**
63
+ * Spawns the default shell in interactive mode.
64
+ * @param options The options for creating the `AdbShell`
65
+ * @returns A new `AdbShell` instance connecting to the spawned shell process.
66
+ */
67
+ public shell(options?: Partial<AdbSubprocessOptions>): Promise<AdbSubprocessProtocol> {
68
+ return this.createProtocol('', options);
69
+ }
70
+
71
+ /**
72
+ * Spawns a new process using the given `command`.
73
+ * @param command The command to run, or an array of strings containing both command and args.
74
+ * @param options The options for creating the `AdbShell`
75
+ * @returns A new `AdbShell` instance connecting to the spawned process.
76
+ */
77
+ public spawn(command: string | string[], options?: Partial<AdbSubprocessOptions>): Promise<AdbSubprocessProtocol> {
78
+ if (Array.isArray(command)) {
79
+ command = command.join(' ');
80
+ }
81
+ return this.createProtocol(command, options);
82
+ }
83
+
84
+ /**
85
+ * Spawns a new process, waits until it exits, and returns the entire output.
86
+ * @param command The command to run
87
+ * @param options The options for creating the `AdbShell`
88
+ * @returns The entire output of the command
89
+ */
90
+ public async spawnAndWait(
91
+ command: string | string[],
92
+ options?: Partial<AdbSubprocessOptions>
93
+ ): Promise<SubprocessResult> {
94
+ const shell = await this.spawn(command, options);
95
+
96
+ const stdout = new GatherStringStream();
97
+ shell.stdout
98
+ .pipeThrough(new DecodeUtf8Stream())
99
+ .pipeThrough(stdout);
100
+
101
+ const stderr = new GatherStringStream();
102
+ shell.stderr
103
+ .pipeThrough(new DecodeUtf8Stream())
104
+ .pipeThrough(stderr);
105
+
106
+ const exitCode = await shell.exit;
107
+
108
+ return {
109
+ stdout: stdout.result,
110
+ stderr: stderr.result,
111
+ exitCode,
112
+ };
113
+ }
114
+
115
+ /**
116
+ * Spawns a new process, waits until it exits, and returns the entire output.
117
+ * @param command The command to run
118
+ * @returns The entire output of the command
119
+ */
120
+ public async spawnAndWaitLegacy(command: string | string[]): Promise<string> {
121
+ const { stdout } = await this.spawnAndWait(command, { protocols: [AdbNoneSubprocessProtocol] });
122
+ return stdout;
123
+ }
124
+ }
@@ -0,0 +1,58 @@
1
+ import type { Adb } from "../../adb.js";
2
+ import type { AdbSocket } from "../../socket/index.js";
3
+ import { DuplexStreamFactory, type ReadableStream } from "../../stream/index.js";
4
+ import type { AdbSubprocessProtocol } from "./types.js";
5
+
6
+ /**
7
+ * The legacy shell
8
+ *
9
+ * Features:
10
+ * * `stderr`: No
11
+ * * `exit` exit code: No
12
+ * * `resize`: No
13
+ */
14
+ export class AdbNoneSubprocessProtocol implements AdbSubprocessProtocol {
15
+ public static isSupported() { return true; }
16
+
17
+ public static async spawn(adb: Adb, command: string) {
18
+ return new AdbNoneSubprocessProtocol(await adb.createSocket(`shell:${command}`));
19
+ }
20
+
21
+ private readonly socket: AdbSocket;
22
+
23
+ // Legacy shell forwards all data to stdin.
24
+ public get stdin() { return this.socket.writable; }
25
+
26
+ private _stdout: ReadableStream<Uint8Array>;
27
+ // Legacy shell doesn't support splitting output streams.
28
+ public get stdout() { return this._stdout; }
29
+
30
+ // `stderr` of Legacy shell is always empty.
31
+ private _stderr: ReadableStream<Uint8Array>;
32
+ public get stderr() { return this._stderr; }
33
+
34
+ private _exit: Promise<number>;
35
+ public get exit() { return this._exit; }
36
+
37
+ public constructor(socket: AdbSocket) {
38
+ this.socket = socket;
39
+
40
+ const factory = new DuplexStreamFactory<Uint8Array, Uint8Array>({
41
+ close: async () => {
42
+ await this.socket.close();
43
+ },
44
+ });
45
+
46
+ this._stdout = factory.createWrapReadable(this.socket.readable);
47
+ this._stderr = factory.createReadable();
48
+ this._exit = factory.closed.then(() => 0);
49
+ }
50
+
51
+ public resize() {
52
+ // Not supported
53
+ }
54
+
55
+ public kill() {
56
+ return this.socket.close();
57
+ }
58
+ }
@@ -0,0 +1,185 @@
1
+ import { PromiseResolver } from "@yume-chan/async";
2
+ import Struct, { placeholder, type StructValueType } from "@yume-chan/struct";
3
+ import type { Adb } from "../../adb.js";
4
+ import { AdbFeatures } from "../../features.js";
5
+ import type { AdbSocket } from "../../socket/index.js";
6
+ import { PushReadableStream, ReadableStream, StructDeserializeStream, StructSerializeStream, TransformStream, WritableStream, WritableStreamDefaultWriter, type PushReadableStreamController } from "../../stream/index.js";
7
+ import { encodeUtf8 } from "../../utils/index.js";
8
+ import type { AdbSubprocessProtocol } from "./types.js";
9
+
10
+ export enum AdbShellProtocolId {
11
+ Stdin,
12
+ Stdout,
13
+ Stderr,
14
+ Exit,
15
+ CloseStdin,
16
+ WindowSizeChange,
17
+ }
18
+
19
+ // This packet format is used in both direction.
20
+ const AdbShellProtocolPacket = new Struct({ littleEndian: true })
21
+ .uint8('id', placeholder<AdbShellProtocolId>())
22
+ .uint32('length')
23
+ .uint8Array('data', { lengthField: 'length' });
24
+
25
+ type AdbShellProtocolPacketInit = typeof AdbShellProtocolPacket['TInit'];
26
+
27
+ type AdbShellProtocolPacket = StructValueType<typeof AdbShellProtocolPacket>;
28
+
29
+ class StdinSerializeStream extends TransformStream<Uint8Array, AdbShellProtocolPacketInit>{
30
+ constructor() {
31
+ super({
32
+ transform(chunk, controller) {
33
+ controller.enqueue({
34
+ id: AdbShellProtocolId.Stdin,
35
+ data: chunk,
36
+ });
37
+ },
38
+ flush() {
39
+ // TODO: AdbShellSubprocessProtocol: support closing stdin
40
+ }
41
+ });
42
+ }
43
+ }
44
+
45
+ class StdoutDeserializeStream extends TransformStream<AdbShellProtocolPacket, Uint8Array>{
46
+ constructor(type: AdbShellProtocolId.Stdout | AdbShellProtocolId.Stderr) {
47
+ super({
48
+ transform(chunk, controller) {
49
+ if (chunk.id === type) {
50
+ controller.enqueue(chunk.data);
51
+ }
52
+ },
53
+ });
54
+ }
55
+ }
56
+
57
+ class MultiplexStream<T>{
58
+ private _readable: PushReadableStream<T>;
59
+ private _readableController!: PushReadableStreamController<T>;
60
+ public get readable() { return this._readable; }
61
+
62
+ private _activeCount = 0;
63
+
64
+ constructor() {
65
+ this._readable = new PushReadableStream(controller => {
66
+ this._readableController = controller;
67
+ });
68
+ }
69
+
70
+ public createWriteable() {
71
+ return new WritableStream<T>({
72
+ start: () => {
73
+ this._activeCount += 1;
74
+ },
75
+ write: async (chunk) => {
76
+ await this._readableController.enqueue(chunk);
77
+ },
78
+ abort: async (e) => {
79
+ this._activeCount -= 1;
80
+ if (this._activeCount === 0) {
81
+ this._readableController.close();
82
+ }
83
+ },
84
+ close: async () => {
85
+ this._activeCount -= 1;
86
+ if (this._activeCount === 0) {
87
+ this._readableController.close();
88
+ }
89
+ },
90
+ });
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Shell v2 a.k.a Shell Protocol
96
+ *
97
+ * Features:
98
+ * * `stderr`: Yes
99
+ * * `exit` exit code: Yes
100
+ * * `resize`: Yes
101
+ */
102
+ export class AdbShellSubprocessProtocol implements AdbSubprocessProtocol {
103
+ public static isSupported(adb: Adb) {
104
+ return adb.features!.includes(AdbFeatures.ShellV2);
105
+ }
106
+
107
+ public static async spawn(adb: Adb, command: string) {
108
+ // TODO: AdbShellSubprocessProtocol: Support raw mode
109
+ // TODO: AdbShellSubprocessProtocol: Support setting `XTERM` environment variable
110
+ return new AdbShellSubprocessProtocol(await adb.createSocket(`shell,v2,pty:${command}`));
111
+ }
112
+
113
+ private readonly _socket: AdbSocket;
114
+ private _socketWriter: WritableStreamDefaultWriter<AdbShellProtocolPacketInit>;
115
+
116
+ private _stdin: WritableStream<Uint8Array>;
117
+ public get stdin() { return this._stdin; }
118
+
119
+ private _stdout: ReadableStream<Uint8Array>;
120
+ public get stdout() { return this._stdout; }
121
+
122
+ private _stderr: ReadableStream<Uint8Array>;
123
+ public get stderr() { return this._stderr; }
124
+
125
+ private readonly _exit = new PromiseResolver<number>();
126
+ public get exit() { return this._exit.promise; }
127
+
128
+ public constructor(socket: AdbSocket) {
129
+ this._socket = socket;
130
+
131
+ // Check this image to help you understand the stream graph
132
+ // cspell: disable-next-line
133
+ // https://www.plantuml.com/plantuml/png/bL91QiCm4Bpx5SAdv90lb1JISmiw5XzaQKf5PIkiLZIqzEyLSg8ks13gYtOykpFhiOw93N6UGjVDqK7rZsxKqNw0U_NTgVAy4empOy2mm4_olC0VEVEE47GUpnGjKdgXoD76q4GIEpyFhOwP_m28hW0NNzxNUig1_JdW0bA7muFIJDco1daJ_1SAX9bgvoPJPyIkSekhNYctvIGXrCH6tIsPL5fs-s6J5yc9BpWXhKtNdF2LgVYPGM_6GlMwfhWUsIt4lbScANrwlgVVUifPSVi__t44qStnwPvZwobdSmHHlL57p2vFuHS0
134
+
135
+ // TODO: AdbShellSubprocessProtocol: Optimize stream graph
136
+
137
+ const [stdout, stderr] = socket.readable
138
+ .pipeThrough(new StructDeserializeStream(AdbShellProtocolPacket))
139
+ .pipeThrough(new TransformStream<AdbShellProtocolPacket, AdbShellProtocolPacket>({
140
+ transform: (chunk, controller) => {
141
+ if (chunk.id === AdbShellProtocolId.Exit) {
142
+ this._exit.resolve(new Uint8Array(chunk.data)[0]!);
143
+ // We can let `StdoutTransformStream` to process `AdbShellProtocolId.Exit`,
144
+ // but since we need this `TransformStream` to capture the exit code anyway,
145
+ // terminating child streams here is killing two birds with one stone.
146
+ controller.terminate();
147
+ return;
148
+ }
149
+ controller.enqueue(chunk);
150
+ }
151
+ }))
152
+ .tee();
153
+ this._stdout = stdout
154
+ .pipeThrough(new StdoutDeserializeStream(AdbShellProtocolId.Stdout));
155
+ this._stderr = stderr
156
+ .pipeThrough(new StdoutDeserializeStream(AdbShellProtocolId.Stderr));
157
+
158
+ const multiplexer = new MultiplexStream<AdbShellProtocolPacketInit>();
159
+ multiplexer.readable
160
+ .pipeThrough(new StructSerializeStream(AdbShellProtocolPacket))
161
+ .pipeTo(socket.writable);
162
+
163
+ const { readable, writable } = new StdinSerializeStream();
164
+ this._stdin = writable;
165
+ readable.pipeTo(multiplexer.createWriteable());
166
+
167
+ this._socketWriter = multiplexer.createWriteable().getWriter();
168
+ }
169
+
170
+ public async resize(rows: number, cols: number) {
171
+ await this._socketWriter.write({
172
+ id: AdbShellProtocolId.WindowSizeChange,
173
+ data: encodeUtf8(
174
+ // The "correct" format is `${rows}x${cols},${x_pixels}x${y_pixels}`
175
+ // However, according to https://linux.die.net/man/4/tty_ioctl
176
+ // `x_pixels` and `y_pixels` are not used, so always passing `0` is fine.
177
+ `${rows}x${cols},0x0\0`
178
+ ),
179
+ });
180
+ }
181
+
182
+ public kill() {
183
+ return this._socket.close();
184
+ }
185
+ }