UNPKG

@yume-chan/adb

Version:

TypeScript implementation of Android Debug Bridge (ADB) protocol.

83 lines 3.13 kB
import { AbortController, DistributionStream, MaybeConsumable, } from "@yume-chan/stream-extra"; import { struct, u32 } from "@yume-chan/struct"; import { NOOP } from "../../utils/index.js"; import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js"; import { AdbSyncResponseId, adbSyncReadResponse } from "./response.js"; import { LinuxFileType } from "./stat.js"; export const ADB_SYNC_MAX_PACKET_SIZE = 64 * 1024; export const AdbSyncOkResponse = struct({ unused: u32 }, { littleEndian: true }); async function pipeFileData(locked, file, packetSize, mtime) { // Read and write in parallel, // allow error response to abort the write. const abortController = new AbortController(); file.pipeThrough(new DistributionStream(packetSize, true)) .pipeTo(new MaybeConsumable.WritableStream({ write(chunk) { return adbSyncWriteRequest(locked, AdbSyncRequestId.Data, chunk); }, }), { signal: abortController.signal }) .then(async () => { await adbSyncWriteRequest(locked, AdbSyncRequestId.Done, mtime); await locked.flush(); }, NOOP); await adbSyncReadResponse(locked, AdbSyncResponseId.Ok, AdbSyncOkResponse).catch((e) => { abortController.abort(); throw e; }); } export async function adbSyncPushV1({ socket, filename, file, type = LinuxFileType.File, permission = 0o666, mtime = (Date.now() / 1000) | 0, packetSize = ADB_SYNC_MAX_PACKET_SIZE, }) { const locked = await socket.lock(); try { const mode = (type << 12) | permission; const pathAndMode = `${filename},${mode.toString()}`; await adbSyncWriteRequest(locked, AdbSyncRequestId.Send, pathAndMode); await pipeFileData(locked, file, packetSize, mtime); } finally { locked.release(); } } export const AdbSyncSendV2Flags = { None: 0, Brotli: 1, /** * 2 */ Lz4: 1 << 1, /** * 4 */ Zstd: 1 << 2, DryRun: 0x80000000, }; export const AdbSyncSendV2Request = struct({ id: u32, mode: u32, flags: u32() }, { littleEndian: true }); export async function adbSyncPushV2({ socket, filename, file, type = LinuxFileType.File, permission = 0o666, mtime = (Date.now() / 1000) | 0, packetSize = ADB_SYNC_MAX_PACKET_SIZE, dryRun = false, }) { const locked = await socket.lock(); try { await adbSyncWriteRequest(locked, AdbSyncRequestId.SendV2, filename); const mode = (type << 12) | permission; let flags = AdbSyncSendV2Flags.None; if (dryRun) { flags |= AdbSyncSendV2Flags.DryRun; } await locked.write(AdbSyncSendV2Request.serialize({ id: AdbSyncRequestId.SendV2, mode, flags, })); await pipeFileData(locked, file, packetSize, mtime); } finally { locked.release(); } } export function adbSyncPush(options) { if (options.v2) { return adbSyncPushV2(options); } if (options.dryRun) { throw new Error("dryRun is not supported in v1"); } return adbSyncPushV1(options); } //# sourceMappingURL=push.js.map