Loading apps/demo/src/pages/file-manager.tsx +6 −6 Original line number Diff line number Diff line Loading @@ -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 = Loading libraries/adb/src/commands/sync/push.ts +65 −31 Original line number Diff line number Diff line Loading @@ -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<Uint8Array>; mode?: number; mtime?: number; packetSize?: number; } export const AdbSyncPushV1DefaultOptions: { [K in keyof AdbSyncPushV1Options as Pick< AdbSyncPushV1Options, K > extends Required<Pick<AdbSyncPushV1Options, K>> ? never : K]-?: Exclude<AdbSyncPushV1Options[K], undefined>; } = { 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<Uint8Array>, 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()}`; Loading Loading @@ -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<Pick<AdbSyncPushV2Options, K>> ? never : K]-?: Exclude<AdbSyncPushV2Options[K], undefined>; } = { ...AdbSyncPushV1DefaultOptions, dryRun: false, }; export const AdbSyncSendV2Request = new Struct({ littleEndian: true }) .uint32("id", placeholder<AdbSyncRequestId>()) .uint32("mode") .uint32("flags", placeholder<AdbSyncSendV2Flags>()); export async function adbSyncPushV2( socket: AdbSyncSocket, filename: string, file: ReadableStream<Uint8Array>, 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, }) ); Loading @@ -114,18 +150,16 @@ export async function adbSyncPushV2( } } export function adbSyncPush( v2: boolean, socket: AdbSyncSocket, filename: string, file: ReadableStream<Uint8Array>, 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); } } libraries/adb/src/commands/sync/sync.ts +14 −15 Original line number Diff line number Diff line Loading @@ -29,6 +29,13 @@ export function dirname(path: string): string { return path.substring(0, end); } export interface AdbSyncWriteOptions { filename: string; file: ReadableStream<Uint8Array>; mode?: number; mtime?: number; } export class AdbSync extends AutoDisposable { protected _adb: Adb; protected _socket: AdbSyncSocket; Loading Loading @@ -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<Uint8Array>, mode?: number, mtime?: number ) { public async write(options: AdbSyncWriteOptions) { if (this.needPushMkdirWorkaround) { // It may fail if the path is already existed. // Ignore the result. Loading @@ -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() { Loading libraries/android-bin/src/pm.ts +4 −1 Original line number Diff line number Diff line Loading @@ -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(); } Loading libraries/scrcpy/src/adb/client.ts +5 −2 Original line number Diff line number Diff line Loading @@ -98,11 +98,14 @@ export class AdbScrcpyClient { public static async pushServer( adb: Adb, file: ReadableStream<Uint8Array>, 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(); } Loading Loading
apps/demo/src/pages/file-manager.tsx +6 −6 Original line number Diff line number Diff line Loading @@ -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 = Loading
libraries/adb/src/commands/sync/push.ts +65 −31 Original line number Diff line number Diff line Loading @@ -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<Uint8Array>; mode?: number; mtime?: number; packetSize?: number; } export const AdbSyncPushV1DefaultOptions: { [K in keyof AdbSyncPushV1Options as Pick< AdbSyncPushV1Options, K > extends Required<Pick<AdbSyncPushV1Options, K>> ? never : K]-?: Exclude<AdbSyncPushV1Options[K], undefined>; } = { 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<Uint8Array>, 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()}`; Loading Loading @@ -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<Pick<AdbSyncPushV2Options, K>> ? never : K]-?: Exclude<AdbSyncPushV2Options[K], undefined>; } = { ...AdbSyncPushV1DefaultOptions, dryRun: false, }; export const AdbSyncSendV2Request = new Struct({ littleEndian: true }) .uint32("id", placeholder<AdbSyncRequestId>()) .uint32("mode") .uint32("flags", placeholder<AdbSyncSendV2Flags>()); export async function adbSyncPushV2( socket: AdbSyncSocket, filename: string, file: ReadableStream<Uint8Array>, 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, }) ); Loading @@ -114,18 +150,16 @@ export async function adbSyncPushV2( } } export function adbSyncPush( v2: boolean, socket: AdbSyncSocket, filename: string, file: ReadableStream<Uint8Array>, 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); } }
libraries/adb/src/commands/sync/sync.ts +14 −15 Original line number Diff line number Diff line Loading @@ -29,6 +29,13 @@ export function dirname(path: string): string { return path.substring(0, end); } export interface AdbSyncWriteOptions { filename: string; file: ReadableStream<Uint8Array>; mode?: number; mtime?: number; } export class AdbSync extends AutoDisposable { protected _adb: Adb; protected _socket: AdbSyncSocket; Loading Loading @@ -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<Uint8Array>, mode?: number, mtime?: number ) { public async write(options: AdbSyncWriteOptions) { if (this.needPushMkdirWorkaround) { // It may fail if the path is already existed. // Ignore the result. Loading @@ -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() { Loading
libraries/android-bin/src/pm.ts +4 −1 Original line number Diff line number Diff line Loading @@ -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(); } Loading
libraries/scrcpy/src/adb/client.ts +5 −2 Original line number Diff line number Diff line Loading @@ -98,11 +98,14 @@ export class AdbScrcpyClient { public static async pushServer( adb: Adb, file: ReadableStream<Uint8Array>, 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(); } Loading