@yume-chan/adb 2.6.0 → 3.0.0-beta.0

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 (449) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/esm/adb.d.ts +18 -15
  4. package/esm/adb.d.ts.map +1 -1
  5. package/esm/adb.js +18 -11
  6. package/esm/adb.js.map +1 -1
  7. package/esm/banner.d.ts +1 -1
  8. package/esm/banner.d.ts.map +1 -1
  9. package/esm/daemon/auth/authenticator.d.ts +28 -0
  10. package/esm/daemon/auth/authenticator.d.ts.map +1 -0
  11. package/esm/daemon/auth/authenticator.js +108 -0
  12. package/esm/daemon/auth/authenticator.js.map +1 -0
  13. package/esm/daemon/auth/index.d.ts +5 -0
  14. package/esm/daemon/auth/index.d.ts.map +1 -0
  15. package/esm/daemon/auth/index.js +5 -0
  16. package/esm/daemon/auth/index.js.map +1 -0
  17. package/esm/daemon/auth/packet-processor.d.ts +42 -0
  18. package/esm/daemon/auth/packet-processor.d.ts.map +1 -0
  19. package/esm/daemon/auth/packet-processor.js +129 -0
  20. package/esm/daemon/auth/packet-processor.js.map +1 -0
  21. package/esm/daemon/auth/public-key.d.ts +8 -0
  22. package/esm/daemon/auth/public-key.d.ts.map +1 -0
  23. package/esm/daemon/auth/public-key.js +74 -0
  24. package/esm/daemon/auth/public-key.js.map +1 -0
  25. package/esm/daemon/auth/type.d.ts +5 -0
  26. package/esm/daemon/auth/type.d.ts.map +1 -0
  27. package/esm/daemon/auth/type.js +2 -0
  28. package/esm/daemon/auth/type.js.map +1 -0
  29. package/esm/daemon/crypto.d.ts +6 -5
  30. package/esm/daemon/crypto.d.ts.map +1 -1
  31. package/esm/daemon/crypto.js +23 -73
  32. package/esm/daemon/crypto.js.map +1 -1
  33. package/esm/daemon/dispatcher.d.ts +3 -3
  34. package/esm/daemon/dispatcher.d.ts.map +1 -1
  35. package/esm/daemon/dispatcher.js +11 -4
  36. package/esm/daemon/dispatcher.js.map +1 -1
  37. package/esm/daemon/index.d.ts +1 -1
  38. package/esm/daemon/index.d.ts.map +1 -1
  39. package/esm/daemon/index.js +1 -1
  40. package/esm/daemon/index.js.map +1 -1
  41. package/esm/daemon/socket.d.ts +3 -3
  42. package/esm/daemon/socket.d.ts.map +1 -1
  43. package/esm/daemon/transport.d.ts +13 -65
  44. package/esm/daemon/transport.d.ts.map +1 -1
  45. package/esm/daemon/transport.js +18 -140
  46. package/esm/daemon/transport.js.map +1 -1
  47. package/esm/device-observer.d.ts +2 -3
  48. package/esm/device-observer.d.ts.map +1 -1
  49. package/esm/features-value.d.ts +40 -0
  50. package/esm/features-value.d.ts.map +1 -0
  51. package/esm/features-value.js +46 -0
  52. package/esm/features-value.js.map +1 -0
  53. package/esm/features.d.ts +4 -12
  54. package/esm/features.d.ts.map +1 -1
  55. package/esm/features.js +27 -13
  56. package/esm/features.js.map +1 -1
  57. package/esm/index.d.ts +1 -1
  58. package/esm/index.d.ts.map +1 -1
  59. package/esm/index.js +1 -1
  60. package/esm/index.js.map +1 -1
  61. package/esm/server/client.d.ts +7 -7
  62. package/esm/server/client.d.ts.map +1 -1
  63. package/esm/server/client.js +69 -86
  64. package/esm/server/client.js.map +1 -1
  65. package/esm/server/commands/wireless.js +1 -1
  66. package/esm/server/commands/wireless.js.map +1 -1
  67. package/esm/server/{stream.d.ts → data-connection.d.ts} +5 -5
  68. package/esm/server/data-connection.d.ts.map +1 -0
  69. package/esm/server/{stream.js → data-connection.js} +4 -4
  70. package/esm/server/data-connection.js.map +1 -0
  71. package/esm/server/index.d.ts +1 -1
  72. package/esm/server/index.d.ts.map +1 -1
  73. package/esm/server/index.js +1 -1
  74. package/esm/server/index.js.map +1 -1
  75. package/esm/server/observer.d.ts.map +1 -1
  76. package/esm/server/observer.js +14 -13
  77. package/esm/server/observer.js.map +1 -1
  78. package/esm/server/transport.d.ts +4 -6
  79. package/esm/server/transport.d.ts.map +1 -1
  80. package/esm/server/transport.js +9 -24
  81. package/esm/server/transport.js.map +1 -1
  82. package/esm/service/framebuffer.d.ts.map +1 -0
  83. package/esm/service/framebuffer.js.map +1 -0
  84. package/esm/{commands → service}/index.d.ts +1 -2
  85. package/esm/service/index.d.ts.map +1 -0
  86. package/esm/{commands → service}/index.js +1 -2
  87. package/esm/service/index.js.map +1 -0
  88. package/esm/{commands → service}/power.d.ts +4 -2
  89. package/esm/service/power.d.ts.map +1 -0
  90. package/esm/{commands → service}/power.js +11 -5
  91. package/esm/service/power.js.map +1 -0
  92. package/esm/service/reverse/error.d.ts +14 -0
  93. package/esm/service/reverse/error.d.ts.map +1 -0
  94. package/esm/service/reverse/error.js +21 -0
  95. package/esm/service/reverse/error.js.map +1 -0
  96. package/esm/service/reverse/index.d.ts +3 -0
  97. package/esm/service/reverse/index.d.ts.map +1 -0
  98. package/esm/service/reverse/index.js +4 -0
  99. package/esm/service/reverse/index.js.map +1 -0
  100. package/esm/service/reverse/response.d.ts +2 -0
  101. package/esm/service/reverse/response.d.ts.map +1 -0
  102. package/esm/service/reverse/response.js +30 -0
  103. package/esm/service/reverse/response.js.map +1 -0
  104. package/esm/service/reverse/service.d.ts +59 -0
  105. package/esm/service/reverse/service.d.ts.map +1 -0
  106. package/esm/{commands/reverse.js → service/reverse/service.js} +16 -45
  107. package/esm/service/reverse/service.js.map +1 -0
  108. package/esm/{commands → service}/subprocess/index.d.ts +1 -0
  109. package/esm/service/subprocess/index.d.ts.map +1 -0
  110. package/esm/{commands → service}/subprocess/index.js +1 -0
  111. package/esm/service/subprocess/index.js.map +1 -0
  112. package/esm/service/subprocess/none/index.d.ts.map +1 -0
  113. package/esm/service/subprocess/none/index.js.map +1 -0
  114. package/esm/{commands → service}/subprocess/none/process.d.ts +2 -2
  115. package/esm/service/subprocess/none/process.d.ts.map +1 -0
  116. package/esm/service/subprocess/none/process.js.map +1 -0
  117. package/esm/{commands → service}/subprocess/none/pty.d.ts +4 -4
  118. package/esm/service/subprocess/none/pty.d.ts.map +1 -0
  119. package/esm/{commands → service}/subprocess/none/pty.js +1 -1
  120. package/esm/service/subprocess/none/pty.js.map +1 -0
  121. package/esm/service/subprocess/none/service.d.ts +10 -0
  122. package/esm/service/subprocess/none/service.d.ts.map +1 -0
  123. package/esm/service/subprocess/none/service.js +44 -0
  124. package/esm/service/subprocess/none/service.js.map +1 -0
  125. package/esm/service/subprocess/none/spawner.d.ts +15 -0
  126. package/esm/service/subprocess/none/spawner.d.ts.map +1 -0
  127. package/esm/service/subprocess/none/spawner.js +31 -0
  128. package/esm/service/subprocess/none/spawner.js.map +1 -0
  129. package/esm/{commands → service}/subprocess/pty.d.ts +1 -1
  130. package/esm/service/subprocess/pty.d.ts.map +1 -0
  131. package/esm/{commands → service}/subprocess/pty.js.map +1 -1
  132. package/esm/service/subprocess/service.d.ts.map +1 -0
  133. package/esm/{commands → service}/subprocess/service.js +1 -1
  134. package/esm/service/subprocess/service.js.map +1 -0
  135. package/esm/service/subprocess/shell/index.d.ts +5 -0
  136. package/esm/{commands/subprocess/none → service/subprocess/shell}/index.d.ts.map +1 -1
  137. package/esm/service/subprocess/shell/index.js +6 -0
  138. package/esm/{commands/subprocess/none → service/subprocess/shell}/index.js.map +1 -1
  139. package/esm/{commands → service}/subprocess/shell/process.d.ts +2 -2
  140. package/esm/service/subprocess/shell/process.d.ts.map +1 -0
  141. package/esm/{commands → service}/subprocess/shell/process.js +4 -6
  142. package/esm/service/subprocess/shell/process.js.map +1 -0
  143. package/esm/{commands → service}/subprocess/shell/pty.d.ts +4 -4
  144. package/esm/service/subprocess/shell/pty.d.ts.map +1 -0
  145. package/esm/{commands → service}/subprocess/shell/pty.js +11 -9
  146. package/esm/service/subprocess/shell/pty.js.map +1 -0
  147. package/esm/service/subprocess/shell/service.d.ts +34 -0
  148. package/esm/service/subprocess/shell/service.d.ts.map +1 -0
  149. package/esm/service/subprocess/shell/service.js +52 -0
  150. package/esm/service/subprocess/shell/service.js.map +1 -0
  151. package/esm/service/subprocess/shell/shared.d.ts +2 -0
  152. package/esm/service/subprocess/shell/shared.d.ts.map +1 -0
  153. package/esm/{commands → service}/subprocess/shell/shared.js +2 -0
  154. package/esm/service/subprocess/shell/shared.js.map +1 -0
  155. package/esm/{commands → service}/subprocess/shell/spawner.d.ts +3 -7
  156. package/esm/service/subprocess/shell/spawner.d.ts.map +1 -0
  157. package/esm/service/subprocess/shell/spawner.js +45 -0
  158. package/esm/service/subprocess/shell/spawner.js.map +1 -0
  159. package/esm/service/subprocess/types.d.ts +14 -0
  160. package/esm/service/subprocess/types.d.ts.map +1 -0
  161. package/esm/service/subprocess/types.js +2 -0
  162. package/esm/service/subprocess/types.js.map +1 -0
  163. package/esm/service/subprocess/utils.d.ts +39 -0
  164. package/esm/service/subprocess/utils.d.ts.map +1 -0
  165. package/esm/service/subprocess/utils.js +142 -0
  166. package/esm/service/subprocess/utils.js.map +1 -0
  167. package/esm/service/sync/android.d.ts +34 -0
  168. package/esm/service/sync/android.d.ts.map +1 -0
  169. package/esm/service/sync/android.js +34 -0
  170. package/esm/service/sync/android.js.map +1 -0
  171. package/esm/service/sync/compression/compression.d.ts +17 -0
  172. package/esm/service/sync/compression/compression.d.ts.map +1 -0
  173. package/esm/service/sync/compression/compression.js +92 -0
  174. package/esm/service/sync/compression/compression.js.map +1 -0
  175. package/esm/service/sync/compression/format-ns.d.ts +5 -0
  176. package/esm/service/sync/compression/format-ns.d.ts.map +1 -0
  177. package/esm/service/sync/compression/format-ns.js +5 -0
  178. package/esm/service/sync/compression/format-ns.js.map +1 -0
  179. package/esm/service/sync/compression/format.d.ts +4 -0
  180. package/esm/service/sync/compression/format.d.ts.map +1 -0
  181. package/esm/service/sync/compression/format.js +3 -0
  182. package/esm/service/sync/compression/format.js.map +1 -0
  183. package/esm/service/sync/compression/index.d.ts +2 -0
  184. package/esm/service/sync/compression/index.d.ts.map +1 -0
  185. package/esm/service/sync/compression/index.js +2 -0
  186. package/esm/service/sync/compression/index.js.map +1 -0
  187. package/esm/service/sync/id/common.d.ts +17 -0
  188. package/esm/service/sync/id/common.d.ts.map +1 -0
  189. package/esm/service/sync/id/common.js +29 -0
  190. package/esm/service/sync/id/common.js.map +1 -0
  191. package/esm/service/sync/id/index.d.ts +4 -0
  192. package/esm/service/sync/id/index.d.ts.map +1 -0
  193. package/esm/service/sync/id/index.js +6 -0
  194. package/esm/service/sync/id/index.js.map +1 -0
  195. package/esm/service/sync/id/request.d.ts +7 -0
  196. package/esm/service/sync/id/request.d.ts.map +1 -0
  197. package/esm/service/sync/id/request.js +9 -0
  198. package/esm/service/sync/id/request.js.map +1 -0
  199. package/esm/service/sync/id/response.d.ts +6 -0
  200. package/esm/service/sync/id/response.d.ts.map +1 -0
  201. package/esm/service/sync/id/response.js +8 -0
  202. package/esm/service/sync/id/response.js.map +1 -0
  203. package/esm/service/sync/index-ns.d.ts +7 -0
  204. package/esm/service/sync/index-ns.d.ts.map +1 -0
  205. package/esm/service/sync/index-ns.js +7 -0
  206. package/esm/service/sync/index-ns.js.map +1 -0
  207. package/esm/service/sync/index.d.ts +3 -0
  208. package/esm/service/sync/index.d.ts.map +1 -0
  209. package/esm/service/sync/index.js +3 -0
  210. package/esm/service/sync/index.js.map +1 -0
  211. package/esm/service/sync/request/index.d.ts +5 -0
  212. package/esm/service/sync/request/index.d.ts.map +1 -0
  213. package/esm/service/sync/request/index.js +5 -0
  214. package/esm/service/sync/request/index.js.map +1 -0
  215. package/esm/{commands/sync → service/sync/request}/list.d.ts +21 -19
  216. package/esm/service/sync/request/list.d.ts.map +1 -0
  217. package/esm/service/sync/request/list.js +77 -0
  218. package/esm/service/sync/request/list.js.map +1 -0
  219. package/esm/service/sync/request/pull.d.ts +12 -0
  220. package/esm/service/sync/request/pull.d.ts.map +1 -0
  221. package/esm/service/sync/request/pull.js +28 -0
  222. package/esm/service/sync/request/pull.js.map +1 -0
  223. package/esm/service/sync/request/push.d.ts +54 -0
  224. package/esm/service/sync/request/push.d.ts.map +1 -0
  225. package/esm/service/sync/request/push.js +95 -0
  226. package/esm/service/sync/request/push.js.map +1 -0
  227. package/esm/{commands/sync → service/sync/request}/stat.d.ts +40 -50
  228. package/esm/service/sync/request/stat.d.ts.map +1 -0
  229. package/esm/service/sync/request/stat.js +89 -0
  230. package/esm/service/sync/request/stat.js.map +1 -0
  231. package/esm/service/sync/service.d.ts +123 -0
  232. package/esm/service/sync/service.d.ts.map +1 -0
  233. package/esm/service/sync/service.js +170 -0
  234. package/esm/service/sync/service.js.map +1 -0
  235. package/esm/service/sync/socket-pool.d.ts +11 -0
  236. package/esm/service/sync/socket-pool.d.ts.map +1 -0
  237. package/esm/service/sync/socket-pool.js +80 -0
  238. package/esm/service/sync/socket-pool.js.map +1 -0
  239. package/esm/service/sync/socket.d.ts +40 -0
  240. package/esm/service/sync/socket.d.ts.map +1 -0
  241. package/esm/service/sync/socket.js +153 -0
  242. package/esm/service/sync/socket.js.map +1 -0
  243. package/esm/{commands → service}/tcpip.d.ts +4 -2
  244. package/esm/service/tcpip.d.ts.map +1 -0
  245. package/esm/{commands → service}/tcpip.js +10 -7
  246. package/esm/service/tcpip.js.map +1 -0
  247. package/esm/utils/array-buffer.d.ts.map +1 -1
  248. package/esm/utils/array-buffer.js +2 -3
  249. package/esm/utils/array-buffer.js.map +1 -1
  250. package/esm/utils/base64.d.ts.map +1 -1
  251. package/esm/utils/base64.js +22 -12
  252. package/esm/utils/base64.js.map +1 -1
  253. package/esm/utils/index.d.ts +1 -0
  254. package/esm/utils/index.d.ts.map +1 -1
  255. package/esm/utils/index.js +1 -0
  256. package/esm/utils/index.js.map +1 -1
  257. package/esm/utils/md5.d.ts +8 -0
  258. package/esm/utils/md5.d.ts.map +1 -0
  259. package/esm/utils/md5.js +149 -0
  260. package/esm/utils/md5.js.map +1 -0
  261. package/package.json +10 -10
  262. package/src/adb.ts +44 -34
  263. package/src/daemon/auth/authenticator.ts +186 -0
  264. package/src/daemon/auth/index.ts +4 -0
  265. package/src/daemon/auth/packet-processor.ts +212 -0
  266. package/src/daemon/auth/public-key.ts +112 -0
  267. package/src/daemon/auth/type.ts +5 -0
  268. package/src/daemon/crypto.ts +36 -102
  269. package/src/daemon/dispatcher.ts +15 -8
  270. package/src/daemon/index.ts +1 -1
  271. package/src/daemon/socket.ts +3 -3
  272. package/src/daemon/transport.ts +35 -253
  273. package/src/device-observer.ts +3 -3
  274. package/src/features-value.ts +47 -0
  275. package/src/features.ts +31 -14
  276. package/src/index.ts +1 -1
  277. package/src/server/client.ts +96 -94
  278. package/src/server/commands/wireless.ts +1 -1
  279. package/src/server/{stream.ts → data-connection.ts} +4 -4
  280. package/src/server/index.ts +1 -1
  281. package/src/server/observer.ts +21 -19
  282. package/src/server/transport.ts +13 -34
  283. package/src/{commands → service}/index.ts +1 -2
  284. package/src/{commands → service}/power.ts +14 -5
  285. package/src/service/reverse/error.ts +35 -0
  286. package/src/service/reverse/index.ts +3 -0
  287. package/src/service/reverse/response.ts +38 -0
  288. package/src/{commands/reverse.ts → service/reverse/service.ts} +32 -72
  289. package/src/{commands → service}/subprocess/index.ts +1 -0
  290. package/src/{commands → service}/subprocess/none/process.ts +3 -3
  291. package/src/{commands → service}/subprocess/none/pty.ts +5 -5
  292. package/src/service/subprocess/none/service.ts +57 -0
  293. package/src/service/subprocess/none/spawner.ts +81 -0
  294. package/src/{commands → service}/subprocess/pty.ts +1 -1
  295. package/src/{commands → service}/subprocess/service.ts +1 -1
  296. package/src/{commands → service}/subprocess/shell/index.ts +1 -1
  297. package/src/{commands → service}/subprocess/shell/process.ts +6 -7
  298. package/src/{commands → service}/subprocess/shell/pty.ts +15 -13
  299. package/src/service/subprocess/shell/service.ts +75 -0
  300. package/src/{commands → service}/subprocess/shell/shared.ts +5 -0
  301. package/src/service/subprocess/shell/spawner.ts +109 -0
  302. package/src/service/subprocess/types.ts +19 -0
  303. package/src/service/subprocess/utils.ts +166 -0
  304. package/src/service/sync/android.ts +43 -0
  305. package/src/service/sync/compression/compression.ts +126 -0
  306. package/src/service/sync/compression/format-ns.ts +4 -0
  307. package/src/service/sync/compression/format.ts +5 -0
  308. package/src/service/sync/compression/index.ts +1 -0
  309. package/src/service/sync/id/common.ts +33 -0
  310. package/src/service/sync/id/index.ts +7 -0
  311. package/src/service/sync/id/request.ts +12 -0
  312. package/src/service/sync/id/response.ts +11 -0
  313. package/src/service/sync/index-ns.ts +6 -0
  314. package/src/service/sync/index.ts +2 -0
  315. package/src/service/sync/request/index.ts +4 -0
  316. package/src/service/sync/request/list.ts +110 -0
  317. package/src/service/sync/request/pull.ts +49 -0
  318. package/src/service/sync/request/push.ts +184 -0
  319. package/src/service/sync/request/stat.ts +127 -0
  320. package/src/service/sync/service.ts +255 -0
  321. package/src/service/sync/socket-pool.ts +97 -0
  322. package/src/service/sync/socket.ts +201 -0
  323. package/src/{commands → service}/tcpip.ts +13 -7
  324. package/src/utils/array-buffer.ts +2 -3
  325. package/src/utils/base64.ts +24 -12
  326. package/src/utils/index.ts +1 -0
  327. package/src/utils/md5.ts +185 -0
  328. package/yume-chan-adb-3.0.0-beta.0.tgz +0 -0
  329. package/CHANGELOG.md +0 -251
  330. package/esm/commands/base.d.ts +0 -8
  331. package/esm/commands/base.d.ts.map +0 -1
  332. package/esm/commands/base.js +0 -12
  333. package/esm/commands/base.js.map +0 -1
  334. package/esm/commands/framebuffer.d.ts.map +0 -1
  335. package/esm/commands/framebuffer.js.map +0 -1
  336. package/esm/commands/index.d.ts.map +0 -1
  337. package/esm/commands/index.js.map +0 -1
  338. package/esm/commands/power.d.ts.map +0 -1
  339. package/esm/commands/power.js.map +0 -1
  340. package/esm/commands/reverse.d.ts +0 -48
  341. package/esm/commands/reverse.d.ts.map +0 -1
  342. package/esm/commands/reverse.js.map +0 -1
  343. package/esm/commands/subprocess/index.d.ts.map +0 -1
  344. package/esm/commands/subprocess/index.js.map +0 -1
  345. package/esm/commands/subprocess/none/process.d.ts.map +0 -1
  346. package/esm/commands/subprocess/none/process.js.map +0 -1
  347. package/esm/commands/subprocess/none/pty.d.ts.map +0 -1
  348. package/esm/commands/subprocess/none/pty.js.map +0 -1
  349. package/esm/commands/subprocess/none/service.d.ts +0 -10
  350. package/esm/commands/subprocess/none/service.d.ts.map +0 -1
  351. package/esm/commands/subprocess/none/service.js +0 -34
  352. package/esm/commands/subprocess/none/service.js.map +0 -1
  353. package/esm/commands/subprocess/none/spawner.d.ts +0 -19
  354. package/esm/commands/subprocess/none/spawner.d.ts.map +0 -1
  355. package/esm/commands/subprocess/none/spawner.js +0 -26
  356. package/esm/commands/subprocess/none/spawner.js.map +0 -1
  357. package/esm/commands/subprocess/pty.d.ts.map +0 -1
  358. package/esm/commands/subprocess/service.d.ts.map +0 -1
  359. package/esm/commands/subprocess/service.js.map +0 -1
  360. package/esm/commands/subprocess/shell/index.d.ts +0 -6
  361. package/esm/commands/subprocess/shell/index.d.ts.map +0 -1
  362. package/esm/commands/subprocess/shell/index.js +0 -6
  363. package/esm/commands/subprocess/shell/index.js.map +0 -1
  364. package/esm/commands/subprocess/shell/process.d.ts.map +0 -1
  365. package/esm/commands/subprocess/shell/process.js.map +0 -1
  366. package/esm/commands/subprocess/shell/pty.d.ts.map +0 -1
  367. package/esm/commands/subprocess/shell/pty.js.map +0 -1
  368. package/esm/commands/subprocess/shell/service.d.ts +0 -14
  369. package/esm/commands/subprocess/shell/service.d.ts.map +0 -1
  370. package/esm/commands/subprocess/shell/service.js +0 -41
  371. package/esm/commands/subprocess/shell/service.js.map +0 -1
  372. package/esm/commands/subprocess/shell/shared.d.ts +0 -19
  373. package/esm/commands/subprocess/shell/shared.d.ts.map +0 -1
  374. package/esm/commands/subprocess/shell/shared.js.map +0 -1
  375. package/esm/commands/subprocess/shell/spawner.d.ts.map +0 -1
  376. package/esm/commands/subprocess/shell/spawner.js +0 -38
  377. package/esm/commands/subprocess/shell/spawner.js.map +0 -1
  378. package/esm/commands/subprocess/utils.d.ts +0 -3
  379. package/esm/commands/subprocess/utils.d.ts.map +0 -1
  380. package/esm/commands/subprocess/utils.js +0 -56
  381. package/esm/commands/subprocess/utils.js.map +0 -1
  382. package/esm/commands/sync/index.d.ts +0 -9
  383. package/esm/commands/sync/index.d.ts.map +0 -1
  384. package/esm/commands/sync/index.js +0 -9
  385. package/esm/commands/sync/index.js.map +0 -1
  386. package/esm/commands/sync/list.d.ts.map +0 -1
  387. package/esm/commands/sync/list.js +0 -64
  388. package/esm/commands/sync/list.js.map +0 -1
  389. package/esm/commands/sync/pull.d.ts +0 -12
  390. package/esm/commands/sync/pull.d.ts.map +0 -1
  391. package/esm/commands/sync/pull.js +0 -33
  392. package/esm/commands/sync/pull.js.map +0 -1
  393. package/esm/commands/sync/push.d.ts +0 -61
  394. package/esm/commands/sync/push.d.ts.map +0 -1
  395. package/esm/commands/sync/push.js +0 -83
  396. package/esm/commands/sync/push.js.map +0 -1
  397. package/esm/commands/sync/request.d.ts +0 -24
  398. package/esm/commands/sync/request.d.ts.map +0 -1
  399. package/esm/commands/sync/request.js +0 -32
  400. package/esm/commands/sync/request.js.map +0 -1
  401. package/esm/commands/sync/response.d.ts +0 -28
  402. package/esm/commands/sync/response.d.ts.map +0 -1
  403. package/esm/commands/sync/response.js +0 -81
  404. package/esm/commands/sync/response.js.map +0 -1
  405. package/esm/commands/sync/socket.d.ts +0 -22
  406. package/esm/commands/sync/socket.d.ts.map +0 -1
  407. package/esm/commands/sync/socket.js +0 -78
  408. package/esm/commands/sync/socket.js.map +0 -1
  409. package/esm/commands/sync/stat.d.ts.map +0 -1
  410. package/esm/commands/sync/stat.js +0 -121
  411. package/esm/commands/sync/stat.js.map +0 -1
  412. package/esm/commands/sync/sync.d.ts +0 -82
  413. package/esm/commands/sync/sync.d.ts.map +0 -1
  414. package/esm/commands/sync/sync.js +0 -138
  415. package/esm/commands/sync/sync.js.map +0 -1
  416. package/esm/commands/tcpip.d.ts.map +0 -1
  417. package/esm/commands/tcpip.js.map +0 -1
  418. package/esm/daemon/auth.d.ts +0 -54
  419. package/esm/daemon/auth.d.ts.map +0 -1
  420. package/esm/daemon/auth.js +0 -104
  421. package/esm/daemon/auth.js.map +0 -1
  422. package/esm/server/stream.d.ts.map +0 -1
  423. package/esm/server/stream.js.map +0 -1
  424. package/src/commands/base.ts +0 -15
  425. package/src/commands/subprocess/none/service.ts +0 -45
  426. package/src/commands/subprocess/none/spawner.ts +0 -68
  427. package/src/commands/subprocess/shell/service.ts +0 -58
  428. package/src/commands/subprocess/shell/spawner.ts +0 -90
  429. package/src/commands/subprocess/utils.ts +0 -61
  430. package/src/commands/sync/index.ts +0 -8
  431. package/src/commands/sync/list.ts +0 -99
  432. package/src/commands/sync/pull.ts +0 -55
  433. package/src/commands/sync/push.ts +0 -172
  434. package/src/commands/sync/request.ts +0 -53
  435. package/src/commands/sync/response.ts +0 -105
  436. package/src/commands/sync/socket.ts +0 -109
  437. package/src/commands/sync/stat.ts +0 -177
  438. package/src/commands/sync/sync.ts +0 -175
  439. package/src/daemon/auth.ts +0 -204
  440. package/tsconfig.build.tsbuildinfo +0 -1
  441. /package/esm/{commands → service}/framebuffer.d.ts +0 -0
  442. /package/esm/{commands → service}/framebuffer.js +0 -0
  443. /package/esm/{commands → service}/subprocess/none/index.d.ts +0 -0
  444. /package/esm/{commands → service}/subprocess/none/index.js +0 -0
  445. /package/esm/{commands → service}/subprocess/none/process.js +0 -0
  446. /package/esm/{commands → service}/subprocess/pty.js +0 -0
  447. /package/esm/{commands → service}/subprocess/service.d.ts +0 -0
  448. /package/src/{commands → service}/framebuffer.ts +0 -0
  449. /package/src/{commands → service}/subprocess/none/index.ts +0 -0
@@ -0,0 +1,255 @@
1
+ import type {
2
+ AbortSignal,
3
+ MaybeConsumable,
4
+ ReadableStream,
5
+ } from "@yume-chan/stream-extra";
6
+
7
+ import type { Adb } from "../../adb.js";
8
+ import { AdbFeature } from "../../features.js";
9
+ import { escapeArg } from "../subprocess/index.js";
10
+
11
+ import type { LinuxFileType } from "./android.js";
12
+ import { Compression } from "./compression/index.js";
13
+ import { OpenDir, Receive, Send, Stat } from "./request/index.js";
14
+ import { SocketPool } from "./socket-pool.js";
15
+ import type { Socket } from "./socket.js";
16
+ import { Error as AdbSyncError } from "./socket.js";
17
+
18
+ export interface ServiceOptions {
19
+ /**
20
+ * Maximum number of sockets to keep in the pool for reuse.
21
+ * Extra sockets beyond this limit will be closed when released.
22
+ * @default 4
23
+ */
24
+ maxPoolSize?: number | undefined;
25
+
26
+ /**
27
+ * Time in milliseconds to keep idle sockets in the pool before closing them.
28
+ * Set to 0 to disable idle timeout (sockets will remain until pool is disposed).
29
+ * @default 60000 (1 minute)
30
+ */
31
+ idleTimeout?: number | undefined;
32
+
33
+ /**
34
+ * Abort signal to dispose the socket pool when aborted.
35
+ */
36
+ signal?: AbortSignal | undefined;
37
+ }
38
+
39
+ /**
40
+ * A simplified `dirname` function that only handles absolute unix paths.
41
+ * @param path an absolute unix path
42
+ * @returns the directory name of the input path
43
+ */
44
+ export function dirname(path: string): string {
45
+ const end = path.lastIndexOf("/");
46
+ if (end === -1) {
47
+ throw new Error(`Invalid absolute unix path: ${path}`);
48
+ }
49
+ if (end === 0) {
50
+ return "/";
51
+ }
52
+ return path.substring(0, end);
53
+ }
54
+
55
+ export interface WriteOptions {
56
+ filename: string;
57
+ file: ReadableStream<MaybeConsumable<Uint8Array>>;
58
+ type?: LinuxFileType | undefined;
59
+ permission?: number | undefined;
60
+ mtime?: number | undefined;
61
+ /**
62
+ * The format to compress the file stream for sending.
63
+ *
64
+ * If the device doesn't support compressed sending, it will be ignored.
65
+ *
66
+ * If the device or current runtime doesn't support the specified format,
67
+ * an Error will be thrown.
68
+ * {@link Compression.canUseFormat} can be used to check if
69
+ * the device and current runtime both supports the format.
70
+ */
71
+ compression?: Compression.Format | undefined;
72
+ dryRun?: boolean | undefined;
73
+ }
74
+
75
+ export class Service {
76
+ protected _adb: Adb;
77
+ readonly #socketPool: SocketPool;
78
+
79
+ readonly #supportsStat2: boolean;
80
+ readonly #supportsLs2: boolean;
81
+ readonly #fixedPushMkdir: boolean;
82
+ readonly #supportsSendReceive2: boolean;
83
+ readonly #needPushMkdirWorkaround: boolean;
84
+
85
+ get supportsStat2(): boolean {
86
+ return this.#supportsStat2;
87
+ }
88
+
89
+ get supportsLs2(): boolean {
90
+ return this.#supportsLs2;
91
+ }
92
+
93
+ get fixedPushMkdir(): boolean {
94
+ return this.#fixedPushMkdir;
95
+ }
96
+
97
+ get supportsSendReceive2(): boolean {
98
+ return this.#supportsSendReceive2;
99
+ }
100
+
101
+ get needPushMkdirWorkaround(): boolean {
102
+ return this.#needPushMkdirWorkaround;
103
+ }
104
+
105
+ constructor(adb: Adb, options?: ServiceOptions) {
106
+ this._adb = adb;
107
+ this.#socketPool = new SocketPool(
108
+ adb,
109
+ options?.maxPoolSize,
110
+ options?.idleTimeout,
111
+ );
112
+
113
+ // Dispose the socket pool when the abort signal is triggered
114
+ options?.signal?.addEventListener("abort", () => {
115
+ void this.#socketPool.dispose();
116
+ });
117
+
118
+ this.#supportsStat2 = adb.canUseFeature(AdbFeature.Stat2);
119
+ this.#supportsLs2 = adb.canUseFeature(AdbFeature.Ls2);
120
+ this.#fixedPushMkdir = adb.canUseFeature(AdbFeature.FixedPushMkdir);
121
+ this.#supportsSendReceive2 = adb.canUseFeature(AdbFeature.SendReceive2);
122
+ // https://android.googlesource.com/platform/packages/modules/adb/+/91768a57b7138166e0a3d11f79cd55909dda7014/client/file_sync_client.cpp#1361
123
+ this.#needPushMkdirWorkaround =
124
+ this._adb.canUseFeature(AdbFeature.Shell2) && !this.fixedPushMkdir;
125
+ }
126
+
127
+ /**
128
+ * Acquires a socket from the pool for direct use.
129
+ *
130
+ * The socket must be returned to the pool using {@link releaseSocket} after use.
131
+ *
132
+ * @returns A socket from the pool
133
+ */
134
+ async acquireSocket() {
135
+ return await this.#socketPool.acquire();
136
+ }
137
+
138
+ /**
139
+ * Returns a socket to the pool after use.
140
+ *
141
+ * @param socket The socket to return to the pool
142
+ * @param discard Whether to discard the socket instead of returning it to the pool
143
+ */
144
+ async releaseSocket(socket: Socket, discard = false) {
145
+ await this.#socketPool.release(socket, discard);
146
+ }
147
+
148
+ /**
149
+ * Gets information of a file or folder.
150
+ *
151
+ * If `path` points to a symbolic link, the returned information is about the link itself (with `type` being `LinuxFileType.Link`).
152
+ */
153
+ lstat(path: string): Promise<Stat.Stat> {
154
+ return Stat.lstat(this.#socketPool, path, {
155
+ version: this.#supportsStat2 ? 2 : 1,
156
+ });
157
+ }
158
+
159
+ /**
160
+ * Gets the information of a file or folder.
161
+ *
162
+ * If `path` points to a symbolic link, it will be resolved and the returned information is about the target (with `type` being `LinuxFileType.File` or `LinuxFileType.Directory`).
163
+ */
164
+ stat(path: string) {
165
+ if (!this.#supportsStat2) {
166
+ throw new Error("Not supported");
167
+ }
168
+
169
+ return Stat.stat(this.#socketPool, path);
170
+ }
171
+
172
+ /**
173
+ * Checks if `path` is a directory, or a symbolic link to a directory.
174
+ *
175
+ * This uses `lstat` internally, thus works on all Android versions.
176
+ */
177
+ async isDirectory(path: string): Promise<boolean> {
178
+ try {
179
+ await this.lstat(path + "/");
180
+ return true;
181
+ } catch (e) {
182
+ if (e instanceof AdbSyncError) {
183
+ return false;
184
+ } else {
185
+ throw e;
186
+ }
187
+ }
188
+ }
189
+
190
+ opendir(path: string): AsyncGenerator<OpenDir.Entry, void, void> {
191
+ return OpenDir.opendir(this.#socketPool, path, {
192
+ version: this.supportsLs2 ? 2 : 1,
193
+ });
194
+ }
195
+
196
+ async readdir(path: string) {
197
+ // TODO: Convert to `Array.fromAsync`
198
+ const results: OpenDir.Entry[] = [];
199
+ for await (const entry of this.opendir(path)) {
200
+ results.push(entry);
201
+ }
202
+ return results;
203
+ }
204
+
205
+ /**
206
+ * Reads the content of a file on device.
207
+ *
208
+ * @param filename The full path of the file on device to read.
209
+ * @returns A `ReadableStream` that contains the file content.
210
+ */
211
+ read(filename: string): ReadableStream<Uint8Array> {
212
+ return Receive.stream(this.#socketPool, filename);
213
+ }
214
+
215
+ /**
216
+ * Writes a file on device. If the file name already exists, it will be overwritten.
217
+ *
218
+ * @param options The content and options of the file to write.
219
+ */
220
+ async write(options: WriteOptions): Promise<void> {
221
+ if (this.needPushMkdirWorkaround) {
222
+ // It may fail if `filename` already exists.
223
+ // Ignore the result.
224
+ // TODO: sync: test push mkdir workaround (need an Android 8 device)
225
+ await this._adb.subprocess.noneProtocol
226
+ .spawn(["mkdir", "-p", escapeArg(dirname(options.filename))])
227
+ .wait();
228
+ }
229
+
230
+ if (this.supportsSendReceive2) {
231
+ if (options.compression === undefined) {
232
+ options.compression = Compression.chooseFormat(
233
+ this._adb,
234
+ Compression.Mode.Compress,
235
+ );
236
+ } else if (
237
+ !Compression.canUseFormat(
238
+ this._adb,
239
+ options.compression,
240
+ Compression.Mode.Compress,
241
+ )
242
+ ) {
243
+ throw new Error(
244
+ `Compression type ${options.compression} is not supported`,
245
+ );
246
+ }
247
+ }
248
+
249
+ await Send.send({
250
+ version: this.supportsSendReceive2 ? 2 : 1,
251
+ pool: this.#socketPool,
252
+ ...options,
253
+ });
254
+ }
255
+ }
@@ -0,0 +1,97 @@
1
+ import type { Adb } from "../../adb.js";
2
+
3
+ import { Error as AdbSyncError, Socket } from "./socket.js";
4
+
5
+ export class SocketPool {
6
+ readonly #adb: Adb;
7
+ readonly #maxSize: number;
8
+ readonly #idleTimeout: number;
9
+ readonly #availableSockets: Socket[] = [];
10
+ readonly #inUseSockets = new Set<Socket>();
11
+ #closed = false;
12
+
13
+ constructor(adb: Adb, maxSize = 4, idleTimeout = 60000) {
14
+ this.#adb = adb;
15
+ this.#maxSize = maxSize;
16
+ this.#idleTimeout = idleTimeout;
17
+ }
18
+
19
+ async acquire(): Promise<Socket> {
20
+ if (this.#closed) {
21
+ throw new Error("SocketPool is closed");
22
+ }
23
+ // Try to reuse an available socket
24
+ if (this.#availableSockets.length > 0) {
25
+ const socket = this.#availableSockets.pop()!;
26
+ // Clear the idle timeout
27
+ socket.clearIdleTimer();
28
+ this.#inUseSockets.add(socket);
29
+ return socket;
30
+ }
31
+
32
+ // Create a new socket
33
+ const adbSocket = await this.#adb.createSocket("sync:");
34
+ if (this.#closed) {
35
+ await adbSocket.close();
36
+ throw new Error("SocketPool is closed");
37
+ }
38
+ const socket = new Socket(adbSocket, this.#adb.maxPayloadSize);
39
+ this.#inUseSockets.add(socket);
40
+ return socket;
41
+ }
42
+
43
+ async withSocket<T>(fn: (socket: Socket) => Promise<T>): Promise<T> {
44
+ const socket = await this.acquire();
45
+ try {
46
+ const result = await fn(socket);
47
+ await this.release(socket);
48
+ return result;
49
+ } catch (e) {
50
+ await this.release(socket, !(e instanceof AdbSyncError));
51
+ throw e;
52
+ }
53
+ }
54
+
55
+ async release(socket: Socket, discard = false): Promise<void> {
56
+ this.#inUseSockets.delete(socket);
57
+
58
+ // If discarding or we already have enough sockets in the pool, close this socket
59
+ if (discard || this.#availableSockets.length >= this.#maxSize) {
60
+ await socket.close();
61
+ return;
62
+ }
63
+
64
+ // Otherwise, return it to the pool and start idle timeout
65
+ socket.startIdleTimer(this.#idleTimeout, () => {
66
+ this.#closeIdleSocket(socket);
67
+ });
68
+ this.#availableSockets.push(socket);
69
+ }
70
+
71
+ #closeIdleSocket(socket: Socket): void {
72
+ // Remove from available sockets
73
+ const index = this.#availableSockets.indexOf(socket);
74
+ if (index !== -1) {
75
+ this.#availableSockets.splice(index, 1);
76
+ void socket.close();
77
+ }
78
+ }
79
+
80
+ async dispose(): Promise<void> {
81
+ this.#closed = true;
82
+
83
+ // Close all available sockets
84
+ const closePromises = this.#availableSockets.map((socket) =>
85
+ socket.close(),
86
+ );
87
+ this.#availableSockets.length = 0;
88
+
89
+ // Force close all in-use sockets immediately
90
+ const inUseClosePromises = Array.from(this.#inUseSockets).map(
91
+ (socket) => socket.close(),
92
+ );
93
+ this.#inUseSockets.clear();
94
+
95
+ await Promise.all([...closePromises, ...inUseClosePromises]);
96
+ }
97
+ }
@@ -0,0 +1,201 @@
1
+ import { getUint32LittleEndian } from "@yume-chan/no-data-view";
2
+ import type {
3
+ MaybeConsumable,
4
+ WritableStreamDefaultWriter,
5
+ } from "@yume-chan/stream-extra";
6
+ import {
7
+ BufferCombiner,
8
+ BufferedReadableStream,
9
+ clearTimeout,
10
+ Consumable,
11
+ setTimeout,
12
+ tryCancel,
13
+ } from "@yume-chan/stream-extra";
14
+ import type { AsyncExactReadable, StructDeserializer } from "@yume-chan/struct";
15
+ import { decodeUtf8, string, struct, u32 } from "@yume-chan/struct";
16
+
17
+ import type { Adb } from "../../adb.js";
18
+ import { AutoResetEvent, encodeUtf8, unreachable } from "../../utils/index.js";
19
+
20
+ import { ResponseId } from "./id/index.js";
21
+
22
+ const NumberRequest = struct({ id: u32, arg: u32 }, { littleEndian: true });
23
+
24
+ class AdbSyncError extends Error {}
25
+ export { AdbSyncError as Error };
26
+
27
+ const FailResponse = struct(
28
+ { message: string(u32) },
29
+ {
30
+ littleEndian: true,
31
+ postDeserialize(value) {
32
+ throw new AdbSyncError(value.message);
33
+ },
34
+ },
35
+ );
36
+
37
+ function i32ToHex(i: number) {
38
+ return "0x" + i.toString(16).padStart(8, "0");
39
+ }
40
+
41
+ export class Socket implements AsyncExactReadable {
42
+ static readonly NumberRequest = NumberRequest;
43
+ static readonly FailResponse = FailResponse;
44
+
45
+ readonly #socket: Adb.Socket;
46
+ readonly #writer: WritableStreamDefaultWriter<MaybeConsumable<Uint8Array>>;
47
+ readonly #readable: BufferedReadableStream;
48
+ readonly #writeLock = new AutoResetEvent();
49
+ readonly #combiner: BufferCombiner;
50
+ #idleTimeoutId: ReturnType<typeof setTimeout> | null = null;
51
+
52
+ get position() {
53
+ return this.#readable.position;
54
+ }
55
+
56
+ get closed(): Promise<undefined> {
57
+ return this.#socket.closed;
58
+ }
59
+
60
+ constructor(socket: Adb.Socket, bufferSize: number) {
61
+ this.#socket = socket;
62
+ this.#writer = socket.writable.getWriter();
63
+ this.#readable = new BufferedReadableStream(socket.readable);
64
+ this.#combiner = new BufferCombiner(bufferSize);
65
+ }
66
+
67
+ /**
68
+ * Start an idle timer that will close the socket after the specified duration.
69
+ * The timer is automatically cancelled when the socket is used.
70
+ * @param timeout The timeout in milliseconds
71
+ * @param callback The callback to invoke when the timeout expires
72
+ */
73
+ startIdleTimer(timeout: number, callback: () => void) {
74
+ this.clearIdleTimer();
75
+ this.#idleTimeoutId = setTimeout(callback, timeout);
76
+ }
77
+
78
+ /**
79
+ * Clear the idle timer.
80
+ */
81
+ clearIdleTimer() {
82
+ if (this.#idleTimeoutId !== null) {
83
+ clearTimeout(this.#idleTimeoutId);
84
+ this.#idleTimeoutId = null;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Write a packet to the socket.
90
+ * @param packet The packet to write. Must be smaller than the buffer size.
91
+ */
92
+ #writeOne(packet: Uint8Array) {
93
+ // `#combiner` will reuse the buffer, so we need to use the Consumable pattern
94
+ return Consumable.WritableStream.write(this.#writer, packet);
95
+ }
96
+
97
+ async #withWriteLock(callback: () => Promise<void>) {
98
+ try {
99
+ await this.#writeLock.wait();
100
+ await callback();
101
+ } finally {
102
+ this.#writeLock.notifyOne();
103
+ }
104
+ }
105
+
106
+ async flush() {
107
+ const buffer = this.#combiner.flush();
108
+ if (buffer) {
109
+ await this.#withWriteLock(() => this.#writeOne(buffer));
110
+ }
111
+ }
112
+
113
+ async #write(data: Uint8Array) {
114
+ for (const buffer of this.#combiner.push(data)) {
115
+ await this.#writeOne(buffer);
116
+ }
117
+ }
118
+
119
+ write(data: Uint8Array) {
120
+ return this.#withWriteLock(() => this.#write(data));
121
+ }
122
+
123
+ async writeRequest(id: number, value: number | string | Uint8Array) {
124
+ return this.#withWriteLock(async () => {
125
+ if (typeof value === "number") {
126
+ await this.#write(NumberRequest.serialize({ id, arg: value }));
127
+ return;
128
+ }
129
+
130
+ if (typeof value === "string") {
131
+ value = encodeUtf8(value);
132
+ }
133
+
134
+ await this.#write(
135
+ NumberRequest.serialize({ id, arg: value.length }),
136
+ );
137
+ await this.#write(value);
138
+ });
139
+ }
140
+
141
+ async readExactly(length: number) {
142
+ // The request may still be in the internal buffer.
143
+ // Call `flush` to send it before starting reading
144
+ await this.flush();
145
+ return await this.#readable.readExactly(length);
146
+ }
147
+
148
+ async readResponse<T>(id: number, type: StructDeserializer<T>) {
149
+ const buffer = await this.readExactly(4);
150
+ switch (getUint32LittleEndian(buffer, 0)) {
151
+ case ResponseId.Fail:
152
+ await FailResponse.deserialize(this.#readable);
153
+ unreachable();
154
+ case id:
155
+ return await type.deserialize(this.#readable);
156
+ default:
157
+ // non-recoverable
158
+ throw new Error(
159
+ `Expected '${id}', but got '${decodeUtf8(buffer)}'`,
160
+ );
161
+ }
162
+ }
163
+
164
+ async *readResponses<T>(
165
+ expectedId: number,
166
+ type: StructDeserializer<T>,
167
+ ): AsyncGenerator<T, void, void> {
168
+ await this.flush();
169
+
170
+ while (true) {
171
+ const buffer = await this.#readable.readExactly(4);
172
+ const actualId = getUint32LittleEndian(buffer, 0);
173
+ switch (actualId) {
174
+ case ResponseId.Fail:
175
+ await FailResponse.deserialize(this.#readable);
176
+ unreachable();
177
+ case ResponseId.Done:
178
+ // `DONE` responses' size are always same as the request's normal response.
179
+ //
180
+ // For example, `DONE` responses for `LIST` requests are 16 bytes (same as `DENT` responses),
181
+ // but `DONE` responses for `STAT` requests are 12 bytes (same as `STAT` responses).
182
+ await this.#readable.readExactly(type.size);
183
+ return;
184
+ case expectedId:
185
+ yield await type.deserialize(this.#readable);
186
+ break;
187
+ default:
188
+ // non-recoverable
189
+ throw new Error(
190
+ `Expected ${i32ToHex(expectedId)} or ${i32ToHex(ResponseId.Done)}, but got ${i32ToHex(actualId)}`,
191
+ );
192
+ }
193
+ }
194
+ }
195
+
196
+ async close() {
197
+ this.clearIdleTimer();
198
+ await tryCancel(this.#readable);
199
+ await this.#socket.close();
200
+ }
201
+ }
@@ -1,4 +1,4 @@
1
- import { AdbServiceBase } from "./base.js";
1
+ import type { Adb } from "../adb.js";
2
2
 
3
3
  /**
4
4
  * ADB daemon checks for the following properties in the order of
@@ -27,13 +27,19 @@ function parsePort(value: string): number | undefined {
27
27
  return Number.parseInt(value, 10);
28
28
  }
29
29
 
30
- export class AdbTcpIpService extends AdbServiceBase {
30
+ export class AdbTcpIpService {
31
+ readonly #adb: Adb;
32
+
33
+ constructor(adb: Adb) {
34
+ this.#adb = adb;
35
+ }
36
+
31
37
  async getListenAddresses(): Promise<AdbTcpIpListenAddresses> {
32
- const serviceListenAddresses = await this.adb.getProp(
38
+ const serviceListenAddresses = await this.#adb.getProp(
33
39
  "service.adb.listen_addrs",
34
40
  );
35
- const servicePort = await this.adb.getProp("service.adb.tcp.port");
36
- const persistPort = await this.adb.getProp("persist.adb.tcp.port");
41
+ const servicePort = await this.#adb.getProp("service.adb.tcp.port");
42
+ const persistPort = await this.#adb.getProp("persist.adb.tcp.port");
37
43
 
38
44
  return {
39
45
  serviceListenAddresses:
@@ -50,7 +56,7 @@ export class AdbTcpIpService extends AdbServiceBase {
50
56
  throw new TypeError(`Invalid port ${port}`);
51
57
  }
52
58
 
53
- const output = await this.adb.createSocketAndWait(`tcpip:${port}`);
59
+ const output = await this.#adb.createSocketAndWait(`tcpip:${port}`);
54
60
  if (output !== `restarting in TCP mode port: ${port}\n`) {
55
61
  throw new Error(output);
56
62
  }
@@ -58,7 +64,7 @@ export class AdbTcpIpService extends AdbServiceBase {
58
64
  }
59
65
 
60
66
  async disable(): Promise<string> {
61
- const output = await this.adb.createSocketAndWait("usb:");
67
+ const output = await this.#adb.createSocketAndWait("usb:");
62
68
  if (output !== "restarting in USB mode\n") {
63
69
  throw new Error(output);
64
70
  }
@@ -3,7 +3,6 @@ export function toLocalUint8Array(value: Uint8Array): Uint8Array<ArrayBuffer> {
3
3
  return value as Uint8Array<ArrayBuffer>;
4
4
  }
5
5
 
6
- const copy = new Uint8Array(value.length);
7
- copy.set(value);
8
- return copy;
6
+ // This invokes the `constructor(Iterable<number>)` overload and copies the data
7
+ return new Uint8Array(value);
9
8
  }
@@ -180,7 +180,6 @@ function encodeForward(
180
180
  /* cspell: disable-next-line */
181
181
  // aaaaaabb
182
182
  const x = input[inputIndex]!;
183
- inputIndex += 1;
184
183
 
185
184
  output[outputIndex] = indexToChar[x >> 2]!;
186
185
  outputIndex += 1;
@@ -201,7 +200,6 @@ function encodeForward(
201
200
  /* cspell: disable-next-line */
202
201
  // bbbbcccc
203
202
  const y = input[inputIndex]!;
204
- inputIndex += 1;
205
203
 
206
204
  output[outputIndex] = indexToChar[x >> 2]!;
207
205
  outputIndex += 1;
@@ -295,7 +293,20 @@ function encodeBackward(
295
293
  }
296
294
  }
297
295
 
296
+ function getCharIndex(input: string, offset: number) {
297
+ const charCode = input.charCodeAt(offset);
298
+ const index = charToIndex[charCode];
299
+ if (index === undefined) {
300
+ throw new Error("Invalid Base64 character: " + input[offset]);
301
+ }
302
+ return index;
303
+ }
304
+
298
305
  export function decodeBase64(input: string): Uint8Array<ArrayBuffer> {
306
+ if (input.length % 4 !== 0) {
307
+ throw new Error("Invalid Base64 length: " + input.length);
308
+ }
309
+
299
310
  let padding: number;
300
311
  if (input[input.length - 2] === "=") {
301
312
  padding = 2;
@@ -309,17 +320,18 @@ export function decodeBase64(input: string): Uint8Array<ArrayBuffer> {
309
320
  let sIndex = 0;
310
321
  let dIndex = 0;
311
322
 
312
- while (sIndex < input.length - (padding !== 0 ? 4 : 0)) {
313
- const a = charToIndex[input.charCodeAt(sIndex)]!;
323
+ const loopEnd = input.length - (padding !== 0 ? 4 : 0);
324
+ while (sIndex < loopEnd) {
325
+ const a = getCharIndex(input, sIndex);
314
326
  sIndex += 1;
315
327
 
316
- const b = charToIndex[input.charCodeAt(sIndex)]!;
328
+ const b = getCharIndex(input, sIndex);
317
329
  sIndex += 1;
318
330
 
319
- const c = charToIndex[input.charCodeAt(sIndex)]!;
331
+ const c = getCharIndex(input, sIndex);
320
332
  sIndex += 1;
321
333
 
322
- const d = charToIndex[input.charCodeAt(sIndex)]!;
334
+ const d = getCharIndex(input, sIndex);
323
335
  sIndex += 1;
324
336
 
325
337
  result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
@@ -333,23 +345,23 @@ export function decodeBase64(input: string): Uint8Array<ArrayBuffer> {
333
345
  }
334
346
 
335
347
  if (padding === 1) {
336
- const a = charToIndex[input.charCodeAt(sIndex)]!;
348
+ const a = getCharIndex(input, sIndex);
337
349
  sIndex += 1;
338
350
 
339
- const b = charToIndex[input.charCodeAt(sIndex)]!;
351
+ const b = getCharIndex(input, sIndex);
340
352
  sIndex += 1;
341
353
 
342
- const c = charToIndex[input.charCodeAt(sIndex)]!;
354
+ const c = getCharIndex(input, sIndex);
343
355
 
344
356
  result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
345
357
  dIndex += 1;
346
358
 
347
359
  result[dIndex] = ((b & 0b1111) << 4) | ((c & 0b11_1100) >> 2);
348
360
  } else if (padding === 2) {
349
- const a = charToIndex[input.charCodeAt(sIndex)]!;
361
+ const a = getCharIndex(input, sIndex);
350
362
  sIndex += 1;
351
363
 
352
- const b = charToIndex[input.charCodeAt(sIndex)]!;
364
+ const b = getCharIndex(input, sIndex);
353
365
 
354
366
  result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
355
367
  }