chore: format code

This commit is contained in:
Simon Chan 2023-02-03 18:02:05 +08:00
parent 0046c76ee1
commit 19ee58ce29
No known key found for this signature in database
GPG key ID: A8B69F750B9BCEDD
12 changed files with 122 additions and 51 deletions

View file

@ -1,5 +1,3 @@
// cspell: ignore libusb
import { PromiseResolver } from "@yume-chan/async";
import {
AbortController,
@ -269,6 +267,10 @@ export class Adb implements Closeable {
}
}
public supportsFeature(feature: AdbFeatures): boolean {
return this._features.includes(feature);
}
/**
* Add a handler for incoming socket.
* @param handler A function to call with new incoming sockets. It must return `true` if it accepts the socket.

View file

@ -97,9 +97,9 @@ export const AdbPublicKeyAuthenticator: AdbAuthenticator = async function* (
const [publicKeyBase64Length] =
calculateBase64EncodedLength(publicKeyLength);
// The public key is null terminated,
// So we allocate the buffer with one extra byte.
const publicKeyBuffer = new Uint8Array(publicKeyBase64Length + 1);
const publicKeyBuffer = new Uint8Array(
publicKeyBase64Length + 1 // Null character
);
calculatePublicKey(privateKey, publicKeyBuffer);
encodeBase64(publicKeyBuffer.subarray(0, publicKeyLength), publicKeyBuffer);

View file

@ -69,6 +69,6 @@ export async function framebuffer(adb: Adb): Promise<AdbFrameBuffer> {
case 2:
return AdbFrameBufferV2.deserialize(stream);
default:
throw new Error("Unknown FrameBuffer version");
throw new Error("Unsupported FrameBuffer version");
}
}

View file

@ -14,16 +14,22 @@ import { type AdbSubprocessProtocol } from "./types.js";
* * `resize`: No
*/
export class AdbSubprocessNoneProtocol implements AdbSubprocessProtocol {
public static isSupported() { return true; }
public static isSupported() {
return true;
}
public static async pty(adb: Adb, command: string) {
return new AdbSubprocessNoneProtocol(await adb.createSocket(`shell:${command}`));
return new AdbSubprocessNoneProtocol(
await adb.createSocket(`shell:${command}`)
);
}
public static async raw(adb: Adb, command: string) {
// `shell,raw:${command}` also triggers raw mode,
// But is not supported on Android version <7.
return new AdbSubprocessNoneProtocol(await adb.createSocket(`exec:${command}`));
return new AdbSubprocessNoneProtocol(
await adb.createSocket(`exec:${command}`)
);
}
private readonly socket: AdbSocket;
@ -31,22 +37,30 @@ export class AdbSubprocessNoneProtocol implements AdbSubprocessProtocol {
private readonly duplex: DuplexStreamFactory<Uint8Array, Uint8Array>;
// Legacy shell forwards all data to stdin.
public get stdin() { return this.socket.writable; }
public get stdin() {
return this.socket.writable;
}
private _stdout: ReadableStream<Uint8Array>;
/**
* Legacy shell mixes stdout and stderr.
*/
public get stdout() { return this._stdout; }
public get stdout() {
return this._stdout;
}
private _stderr: ReadableStream<Uint8Array>;
/**
* `stderr` will always be empty.
*/
public get stderr() { return this._stderr; }
public get stderr() {
return this._stderr;
}
private _exit: Promise<number>;
public get exit() { return this._exit; }
public get exit() {
return this._exit;
}
public constructor(socket: AdbSocket) {
this.socket = socket;

View file

@ -13,9 +13,9 @@ import {
import Struct, { placeholder, type StructValueType } from '@yume-chan/struct';
import { type Adb } from "../../../adb.js";
import { AdbFeatures } from '../../../features.js';
import { AdbFeatures } from "../../../features.js";
import { type AdbSocket } from "../../../socket/index.js";
import { encodeUtf8 } from '../../../utils/index.js';
import { encodeUtf8 } from "../../../utils/index.js";
import { type AdbSubprocessProtocol } from "./types.js";
@ -29,17 +29,19 @@ export enum AdbShellProtocolId {
}
// This packet format is used in both direction.
const AdbShellProtocolPacket =
new Struct({ littleEndian: true })
.uint8('id', placeholder<AdbShellProtocolId>())
.uint32('length')
.uint8Array('data', { lengthField: 'length' });
const AdbShellProtocolPacket = new Struct({ littleEndian: true })
.uint8("id", placeholder<AdbShellProtocolId>())
.uint32("length")
.uint8Array("data", { lengthField: "length" });
type AdbShellProtocolPacketInit = typeof AdbShellProtocolPacket['TInit'];
type AdbShellProtocolPacketInit = typeof AdbShellProtocolPacket["TInit"];
type AdbShellProtocolPacket = StructValueType<typeof AdbShellProtocolPacket>;
class StdinSerializeStream extends TransformStream<Uint8Array, AdbShellProtocolPacketInit>{
class StdinSerializeStream extends TransformStream<
Uint8Array,
AdbShellProtocolPacketInit
> {
constructor() {
super({
transform(chunk, controller) {
@ -50,12 +52,15 @@ class StdinSerializeStream extends TransformStream<Uint8Array, AdbShellProtocolP
},
flush() {
// TODO: AdbShellSubprocessProtocol: support closing stdin
}
},
});
}
}
class StdoutDeserializeStream extends TransformStream<AdbShellProtocolPacket, Uint8Array>{
class StdoutDeserializeStream extends TransformStream<
AdbShellProtocolPacket,
Uint8Array
> {
constructor(type: AdbShellProtocolId.Stdout | AdbShellProtocolId.Stderr) {
super({
transform(chunk, controller) {
@ -116,7 +121,7 @@ class MultiplexStream<T> {
*/
export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
public static isSupported(adb: Adb) {
return adb.features.includes(AdbFeatures.ShellV2);
return adb.supportsFeature(AdbFeatures.ShellV2);
}
public static async pty(adb: Adb, command: string) {

View file

@ -46,21 +46,21 @@ export class AdbSync extends AutoDisposable {
protected sendLock = this.addDisposable(new AutoResetEvent());
public get supportsStat(): boolean {
return this.adb.features.includes(AdbFeatures.StatV2);
return this.adb.supportsFeature(AdbFeatures.StatV2);
}
public get supportsList2(): boolean {
return this.adb.features.includes(AdbFeatures.ListV2);
return this.adb.supportsFeature(AdbFeatures.ListV2);
}
public get fixedPushMkdir(): boolean {
return this.adb.features.includes(AdbFeatures.FixedPushMkdir);
return this.adb.supportsFeature(AdbFeatures.FixedPushMkdir);
}
public get needPushMkdirWorkaround(): boolean {
// https://android.googlesource.com/platform/packages/modules/adb/+/91768a57b7138166e0a3d11f79cd55909dda7014/client/file_sync_client.cpp#1361
return (
this.adb.features.includes(AdbFeatures.ShellV2) &&
this.adb.supportsFeature(AdbFeatures.ShellV2) &&
!this.fixedPushMkdir
);
}
@ -84,7 +84,7 @@ export class AdbSync extends AutoDisposable {
this.supportsStat
);
} finally {
this.sendLock.notify();
this.sendLock.notifyOne();
}
}
@ -98,7 +98,7 @@ export class AdbSync extends AutoDisposable {
try {
return adbSyncStat(this.stream, this.writer, path);
} finally {
this.sendLock.notify();
this.sendLock.notifyOne();
}
}
@ -124,7 +124,7 @@ export class AdbSync extends AutoDisposable {
this.supportsList2
);
} finally {
this.sendLock.notify();
this.sendLock.notifyOne();
}
}
@ -149,7 +149,7 @@ export class AdbSync extends AutoDisposable {
return adbSyncPull(this.stream, this.writer, filename);
},
close: () => {
this.sendLock.notify();
this.sendLock.notifyOne();
},
});
}
@ -191,7 +191,7 @@ export class AdbSync extends AutoDisposable {
);
},
close: () => {
this.sendLock.notify();
this.sendLock.notifyOne();
},
});
}

View file

@ -2,40 +2,39 @@ import { PromiseResolver } from "@yume-chan/async";
import { type Disposable } from "@yume-chan/event";
export class AutoResetEvent implements Disposable {
private readonly list: PromiseResolver<void>[] = [];
private blocking: boolean;
private _set: boolean;
private readonly _queue: PromiseResolver<void>[] = [];
public constructor(initialSet = false) {
this.blocking = initialSet;
this._set = initialSet;
}
public wait(): Promise<void> {
if (!this.blocking) {
this.blocking = true;
if (!this._set) {
this._set = true;
if (this.list.length === 0) {
if (this._queue.length === 0) {
return Promise.resolve();
}
}
const resolver = new PromiseResolver<void>();
this.list.push(resolver);
this._queue.push(resolver);
return resolver.promise;
}
public notify() {
if (this.list.length !== 0) {
this.list.pop()!.resolve();
public notifyOne() {
if (this._queue.length !== 0) {
this._queue.pop()!.resolve();
} else {
this.blocking = false;
this._set = false;
}
}
public dispose() {
for (const item of this.list) {
for (const item of this._queue) {
item.reject(new Error("The AutoResetEvent has been disposed"));
}
this.list.length = 0;
this._queue.length = 0;
}
}

View file

@ -0,0 +1,45 @@
import { PromiseResolver } from "@yume-chan/async";
import { type Disposable } from "@yume-chan/event";
interface WaitEntry {
condition: () => boolean;
resolver: PromiseResolver<void>;
}
export class ConditionalVariable implements Disposable {
private _locked = false;
private readonly _queue: WaitEntry[] = [];
public wait(condition: () => boolean): Promise<void> {
if (!this._locked) {
this._locked = true;
if (this._queue.length === 0 && condition()) {
return Promise.resolve();
}
}
const resolver = new PromiseResolver<void>();
this._queue.push({ condition, resolver });
return resolver.promise;
}
public notifyOne() {
const entry = this._queue.shift();
if (entry) {
if (entry.condition()) {
entry.resolver.resolve();
}
} else {
this._locked = false;
}
}
public dispose(): void {
for (const item of this._queue) {
item.resolver.reject(
new Error("The ConditionalVariable has been disposed")
);
}
this._queue.length = 0;
}
}

View file

@ -1,3 +1,4 @@
export { decodeUtf8, encodeUtf8 } from '@yume-chan/struct';
export * from './auto-reset-event.js';
export * from './base64.js';
export * from "./conditional-variable.js";

View file

@ -4,7 +4,7 @@
// cspell: ignore systemui
// cspell: ignore sysui
import { type Adb, AdbCommandBase } from "@yume-chan/adb";
import { AdbCommandBase, type Adb } from "@yume-chan/adb";
import { Settings } from "./settings.js";

View file

@ -2,9 +2,9 @@ import { type Adb } from "@yume-chan/adb";
import { type ScrcpyOptionsInit1_22 } from "../../options/index.js";
import {
type AdbScrcpyConnection,
AdbScrcpyForwardConnection,
AdbScrcpyReverseConnection,
type AdbScrcpyConnection,
} from "../connection.js";
import { AdbScrcpyOptions1_16 } from "./1_16.js";

View file

@ -18,8 +18,12 @@ export class BufferedReadableStream {
private bufferedOffset = 0;
private bufferedLength = 0;
protected readonly stream: ReadableStream<Uint8Array>;
private _position = 0;
public get position() {
return this._position;
}
protected readonly stream: ReadableStream<Uint8Array>;
protected readonly reader: ReadableStreamDefaultReader<Uint8Array>;
public constructor(stream: ReadableStream<Uint8Array>) {
@ -32,6 +36,7 @@ export class BufferedReadableStream {
if (done) {
throw new BufferedReadableStreamEndedError();
}
this._position += value.byteLength;
return value;
}