feat(adb): auto close connection by default

This commit is contained in:
Simon Chan 2023-07-31 11:44:22 +08:00
parent 2835848800
commit b066ca01e7
No known key found for this signature in database
GPG key ID: A8B69F750B9BCEDD
4 changed files with 38 additions and 21 deletions

View file

@ -114,21 +114,21 @@ export class AdbScrcpyForwardConnection extends AdbScrcpyConnection {
const streams: AdbScrcpyConnectionStreams = {}; const streams: AdbScrcpyConnectionStreams = {};
if (this.options.video) { if (this.options.video) {
const video = await this.#connectAndRetry(sendDummyByte); const stream = await this.#connectAndRetry(sendDummyByte);
streams.video = video.readable; streams.video = stream.readable;
sendDummyByte = false; sendDummyByte = false;
} }
if (this.options.audio) { if (this.options.audio) {
const audio = await this.#connectAndRetry(sendDummyByte); const stream = await this.#connectAndRetry(sendDummyByte);
streams.audio = audio.readable; streams.audio = stream.readable;
sendDummyByte = false; sendDummyByte = false;
} }
if (this.options.control) { if (this.options.control) {
const control = await this.#connectAndRetry(sendDummyByte); const stream = await this.#connectAndRetry(sendDummyByte);
streams.control = stream;
sendDummyByte = false; sendDummyByte = false;
streams.control = control;
} }
return streams; return streams;
@ -180,18 +180,18 @@ export class AdbScrcpyReverseConnection extends AdbScrcpyConnection {
const streams: AdbScrcpyConnectionStreams = {}; const streams: AdbScrcpyConnectionStreams = {};
if (this.options.video) { if (this.options.video) {
const video = await this.#accept(); const stream = await this.#accept();
streams.video = video.readable; streams.video = stream.readable;
} }
if (this.options.audio) { if (this.options.audio) {
const audio = await this.#accept(); const stream = await this.#accept();
streams.audio = audio.readable; streams.audio = stream.readable;
} }
if (this.options.control) { if (this.options.control) {
const control = await this.#accept(); const stream = await this.#accept();
streams.control = control; streams.control = stream;
} }
return streams; return streams;

View file

@ -28,6 +28,10 @@ export interface AdbPacketDispatcherOptions {
*/ */
appendNullToServiceString: boolean; appendNullToServiceString: boolean;
maxPayloadSize: number; maxPayloadSize: number;
/**
* Whether to preserve the connection open after the `AdbPacketDispatcher` is closed.
*/
preserveConnection?: boolean | undefined;
} }
/** /**
@ -114,12 +118,7 @@ export class AdbPacketDispatcher implements Closeable {
}, },
}), }),
{ {
// There are multiple reasons for the pipe to stop, preventCancel: options.preserveConnection ?? false,
// (device disconnection, protocol error, or user abortion)
// if the underlying streams are still open,
// it's still possible to create another ADB connection.
// So don't close `readable` here.
preventCancel: true,
signal: this.#readAbortController.signal, signal: this.#readAbortController.signal,
}, },
) )

View file

@ -32,6 +32,10 @@ interface AdbDaemonAuthenticationOptions {
connection: ReadableWritablePair<AdbPacketData, Consumable<AdbPacketInit>>; connection: ReadableWritablePair<AdbPacketData, Consumable<AdbPacketInit>>;
credentialStore: AdbCredentialStore; credentialStore: AdbCredentialStore;
authenticators?: AdbAuthenticator[]; authenticators?: AdbAuthenticator[];
/**
* Whether to preserve the connection open after the `AdbDaemonTransport` is closed.
*/
preserveConnection?: boolean | undefined;
} }
interface AdbDaemonSocketConnectorConstructionOptions { interface AdbDaemonSocketConnectorConstructionOptions {
@ -40,6 +44,10 @@ interface AdbDaemonSocketConnectorConstructionOptions {
version: number; version: number;
maxPayloadSize: number; maxPayloadSize: number;
banner: string; banner: string;
/**
* Whether to preserve the connection open after the `AdbDaemonTransport` is closed.
*/
preserveConnection?: boolean | undefined;
} }
export class AdbDaemonTransport implements AdbTransport { export class AdbDaemonTransport implements AdbTransport {
@ -56,6 +64,7 @@ export class AdbDaemonTransport implements AdbTransport {
connection, connection,
credentialStore, credentialStore,
authenticators = ADB_DEFAULT_AUTHENTICATORS, authenticators = ADB_DEFAULT_AUTHENTICATORS,
preserveConnection,
}: AdbDaemonAuthenticationOptions): Promise<AdbDaemonTransport> { }: AdbDaemonAuthenticationOptions): Promise<AdbDaemonTransport> {
// Initially, set to highest-supported version and payload size. // Initially, set to highest-supported version and payload size.
let version = 0x01000001; let version = 0x01000001;
@ -180,6 +189,7 @@ export class AdbDaemonTransport implements AdbTransport {
version, version,
maxPayloadSize, maxPayloadSize,
banner, banner,
preserveConnection,
}); });
} }
@ -215,6 +225,7 @@ export class AdbDaemonTransport implements AdbTransport {
version, version,
maxPayloadSize, maxPayloadSize,
banner, banner,
preserveConnection,
}: AdbDaemonSocketConnectorConstructionOptions) { }: AdbDaemonSocketConnectorConstructionOptions) {
this.#serial = serial; this.#serial = serial;
this.#banner = AdbBanner.parse(banner); this.#banner = AdbBanner.parse(banner);
@ -233,6 +244,7 @@ export class AdbDaemonTransport implements AdbTransport {
calculateChecksum, calculateChecksum,
appendNullToServiceString, appendNullToServiceString,
maxPayloadSize, maxPayloadSize,
preserveConnection,
}); });
this.#protocolVersion = version; this.#protocolVersion = version;

View file

@ -1,5 +1,6 @@
import { AdbCommandBase } from "@yume-chan/adb"; import { AdbCommandBase } from "@yume-chan/adb";
import type { Consumable, ReadableStream } from "@yume-chan/stream-extra"; import type { Consumable, ReadableStream } from "@yume-chan/stream-extra";
import { ConcatStringStream, DecodeUtf8Stream } from "@yume-chan/stream-extra";
export interface AdbBackupOptions { export interface AdbBackupOptions {
user: number; user: number;
@ -62,13 +63,18 @@ export class AdbBackup extends AdbCommandBase {
* User must enter the password (if any) and * User must enter the password (if any) and
* confirm restore on device within 60 seconds. * confirm restore on device within 60 seconds.
*/ */
async restore(options: AdbRestoreOptions): Promise<void> { async restore(options: AdbRestoreOptions): Promise<string> {
const args = ["bu", "restore"]; const args = ["bu", "restore"];
if (options.user !== undefined) { if (options.user !== undefined) {
args.push("--user", options.user.toString()); args.push("--user", options.user.toString());
} }
const process = await this.adb.subprocess.spawn(args); const process = await this.adb.subprocess.spawn(args);
await options.file.pipeTo(process.stdin); const [output] = await Promise.all([
await process.exit; process.stdout
.pipeThrough(new DecodeUtf8Stream())
.pipeThrough(new ConcatStringStream()),
options.file.pipeTo(process.stdin),
]);
return output;
} }
} }