From cde7923856e38119e2a3876da07d9dc66cc2f229 Mon Sep 17 00:00:00 2001 From: Simon Chan <1330321+yume-chan@users.noreply.github.com> Date: Mon, 6 Mar 2023 13:12:41 +0800 Subject: [PATCH] refactor(adb): change sync push args to objects --- apps/demo/src/pages/file-manager.tsx | 12 ++-- libraries/adb/src/commands/sync/push.ts | 96 +++++++++++++++++-------- libraries/adb/src/commands/sync/sync.ts | 29 ++++---- libraries/android-bin/src/pm.ts | 5 +- libraries/scrcpy/src/adb/client.ts | 7 +- libraries/scrcpy/src/options/types.ts | 4 +- 6 files changed, 96 insertions(+), 57 deletions(-) diff --git a/apps/demo/src/pages/file-manager.tsx b/apps/demo/src/pages/file-manager.tsx index d3c9e068..22ef58cf 100644 --- a/apps/demo/src/pages/file-manager.tsx +++ b/apps/demo/src/pages/file-manager.tsx @@ -570,18 +570,18 @@ class FileManagerState { ); try { - await sync.write( - itemPath, - createFileStream(file).pipeThrough( + await sync.write({ + filename: itemPath, + file: createFileStream(file).pipeThrough( new ProgressStream( action((uploaded) => { this.uploadedSize = uploaded; }) ) ), - (LinuxFileType.File << 12) | 0o666, - file.lastModified / 1000 - ); + mode: (LinuxFileType.File << 12) | 0o666, + mtime: file.lastModified / 1000, + }); runInAction(() => { this.uploadSpeed = diff --git a/libraries/adb/src/commands/sync/push.ts b/libraries/adb/src/commands/sync/push.ts index c9c9b28f..420c671c 100644 --- a/libraries/adb/src/commands/sync/push.ts +++ b/libraries/adb/src/commands/sync/push.ts @@ -7,20 +7,39 @@ import { AdbSyncResponseId, adbSyncReadResponse } from "./response.js"; import type { AdbSyncSocket } from "./socket.js"; import { LinuxFileType } from "./stat.js"; +export const ADB_SYNC_MAX_PACKET_SIZE = 64 * 1024; + +export interface AdbSyncPushV1Options { + socket: AdbSyncSocket; + filename: string; + file: ReadableStream; + mode?: number; + mtime?: number; + packetSize?: number; +} + +export const AdbSyncPushV1DefaultOptions: { + [K in keyof AdbSyncPushV1Options as Pick< + AdbSyncPushV1Options, + K + > extends Required> + ? never + : K]-?: Exclude; +} = { + mode: (LinuxFileType.File << 12) | 0o666, + mtime: (Date.now() / 1000) | 0, + packetSize: ADB_SYNC_MAX_PACKET_SIZE, +}; + export const AdbSyncOkResponse = new Struct({ littleEndian: true }).uint32( "unused" ); -export const ADB_SYNC_MAX_PACKET_SIZE = 64 * 1024; - -export async function adbSyncPushV1( - socket: AdbSyncSocket, - filename: string, - file: ReadableStream, - mode: number = (LinuxFileType.File << 12) | 0o666, - mtime: number = (Date.now() / 1000) | 0, - packetSize: number = ADB_SYNC_MAX_PACKET_SIZE -) { +export async function adbSyncPushV1(options: AdbSyncPushV1Options) { + const { socket, filename, file, mode, mtime, packetSize } = { + ...AdbSyncPushV1DefaultOptions, + ...options, + }; const locked = await socket.lock(); try { const pathAndMode = `${filename},${mode.toString()}`; @@ -66,28 +85,45 @@ export enum AdbSyncSendV2Flags { DryRun = (1 << 31) >>> 0, } +export interface AdbSyncPushV2Options extends AdbSyncPushV1Options { + dryRun?: boolean; +} + +export const AdbSyncPushV2DefaultOptions: { + [K in keyof AdbSyncPushV2Options as Pick< + AdbSyncPushV2Options, + K + > extends Required> + ? never + : K]-?: Exclude; +} = { + ...AdbSyncPushV1DefaultOptions, + dryRun: false, +}; + export const AdbSyncSendV2Request = new Struct({ littleEndian: true }) .uint32("id", placeholder()) .uint32("mode") .uint32("flags", placeholder()); -export async function adbSyncPushV2( - socket: AdbSyncSocket, - filename: string, - file: ReadableStream, - mode: number = (LinuxFileType.File << 12) | 0o666, - mtime: number = (Date.now() / 1000) | 0, - packetSize: number = ADB_SYNC_MAX_PACKET_SIZE -) { +export async function adbSyncPushV2(options: AdbSyncPushV2Options) { + const { socket, filename, file, mode, mtime, packetSize, dryRun } = { + ...AdbSyncPushV2DefaultOptions, + ...options, + }; const locked = await socket.lock(); try { await adbSyncWriteRequest(locked, AdbSyncRequestId.SendV2, filename); + let flags: AdbSyncSendV2Flags = AdbSyncSendV2Flags.None; + if (dryRun) { + flags |= AdbSyncSendV2Flags.DryRun; + } await locked.write( AdbSyncSendV2Request.serialize({ id: AdbSyncRequestId.SendV2, mode, - flags: 0, + flags, }) ); @@ -114,18 +150,16 @@ export async function adbSyncPushV2( } } -export function adbSyncPush( - v2: boolean, - socket: AdbSyncSocket, - filename: string, - file: ReadableStream, - mode: number = (LinuxFileType.File << 12) | 0o666, - mtime: number = (Date.now() / 1000) | 0, - packetSize: number = ADB_SYNC_MAX_PACKET_SIZE -) { - if (v2) { - return adbSyncPushV2(socket, filename, file, mode, mtime, packetSize); +export interface AdbSyncPushOptions extends AdbSyncPushV2Options { + v2: boolean; +} + +export function adbSyncPush(options: AdbSyncPushOptions) { + if (options.v2) { + return adbSyncPushV2(options); + } else if (options.dryRun) { + throw new Error("dryRun is not supported in v1"); } else { - return adbSyncPushV1(socket, filename, file, mode, mtime, packetSize); + return adbSyncPushV1(options); } } diff --git a/libraries/adb/src/commands/sync/sync.ts b/libraries/adb/src/commands/sync/sync.ts index ff9ecacb..523015a0 100644 --- a/libraries/adb/src/commands/sync/sync.ts +++ b/libraries/adb/src/commands/sync/sync.ts @@ -29,6 +29,13 @@ export function dirname(path: string): string { return path.substring(0, end); } +export interface AdbSyncWriteOptions { + filename: string; + file: ReadableStream; + mode?: number; + mtime?: number; +} + export class AdbSync extends AutoDisposable { protected _adb: Adb; protected _socket: AdbSyncSocket; @@ -129,12 +136,7 @@ export class AdbSync extends AutoDisposable { * @param mtime The modified time of the file. * @returns A `WritableStream` that writes to the file. */ - public async write( - filename: string, - file: ReadableStream, - mode?: number, - mtime?: number - ) { + public async write(options: AdbSyncWriteOptions) { if (this.needPushMkdirWorkaround) { // It may fail if the path is already existed. // Ignore the result. @@ -142,18 +144,15 @@ export class AdbSync extends AutoDisposable { await this._adb.subprocess.spawnAndWait([ "mkdir", "-p", - escapeArg(dirname(filename)), + escapeArg(dirname(options.filename)), ]); } - await adbSyncPush( - this.supportsSendReceiveV2, - this._socket, - filename, - file, - mode, - mtime - ); + await adbSyncPush({ + v2: this.supportsSendReceiveV2, + socket: this._socket, + ...options, + }); } public override async dispose() { diff --git a/libraries/android-bin/src/pm.ts b/libraries/android-bin/src/pm.ts index 181f0483..856910fe 100644 --- a/libraries/android-bin/src/pm.ts +++ b/libraries/android-bin/src/pm.ts @@ -233,7 +233,10 @@ export class PackageManager extends AdbCommandBase { const filePath = `/data/local/tmp/${fileName}.apk`; try { - await sync.write(filePath, stream); + await sync.write({ + filename: filePath, + file: stream, + }); } finally { await sync.dispose(); } diff --git a/libraries/scrcpy/src/adb/client.ts b/libraries/scrcpy/src/adb/client.ts index 9c33115a..4debb2f2 100644 --- a/libraries/scrcpy/src/adb/client.ts +++ b/libraries/scrcpy/src/adb/client.ts @@ -98,11 +98,14 @@ export class AdbScrcpyClient { public static async pushServer( adb: Adb, file: ReadableStream, - path = DEFAULT_SERVER_PATH + filename = DEFAULT_SERVER_PATH ) { const sync = await adb.sync(); try { - await sync.write(path, file); + await sync.write({ + filename: filename, + file, + }); } finally { await sync.dispose(); } diff --git a/libraries/scrcpy/src/options/types.ts b/libraries/scrcpy/src/options/types.ts index 50e1cfe3..bc985f9b 100644 --- a/libraries/scrcpy/src/options/types.ts +++ b/libraries/scrcpy/src/options/types.ts @@ -65,8 +65,8 @@ export interface ScrcpyVideoStreamConfigurationPacket { export interface ScrcpyVideoStreamFramePacket { type: "frame"; - keyframe?: boolean | undefined; - pts?: bigint | undefined; + keyframe?: boolean; + pts?: bigint; data: Uint8Array; }