Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 7edd616b authored by Simon Chan's avatar Simon Chan
Browse files

fix(scrcpy): fix UHID output stream from server version 2.6

This commit also replaced `ScrcpyOptions`'s `parseDeviceMessage`/`endDeviceMessageStream` methods with `deviceMessageParsers`. If you are using that two methods directly, you need to move to the new API
parent eff718ce
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
---
"@yume-chan/adb-scrcpy": patch
"@yume-chan/scrcpy": patch
---

Fix UHID output stream doesn't work from server version 2.6
+9 −6
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import {
    PushReadableStream,
    SplitStringStream,
    TextDecoderStream,
    tryCancel,
    WritableStream,
} from "@yume-chan/stream-extra";
import { ExactReadableEndedError } from "@yume-chan/struct";
@@ -321,22 +322,24 @@ export class AdbScrcpyClient<TOptions extends AdbScrcpyOptions<object>> {
        const buffered = new BufferedReadableStream(controlStream);
        try {
            while (true) {
                let type: number;
                let id: number;
                try {
                    const result = await buffered.readExactly(1);
                    type = result[0]!;
                    id = result[0]!;
                } catch (e) {
                    if (e instanceof ExactReadableEndedError) {
                        this.#options.endDeviceMessageStream();
                        this.#options.deviceMessageParsers.close();
                        break;
                    }

                    throw e;
                }
                await this.#options.parseDeviceMessage(type, buffered);

                await this.#options.deviceMessageParsers.parse(id, buffered);
            }
        } catch (e) {
            this.#options.endDeviceMessageStream(e);
            buffered.cancel(e).catch(() => {});
            this.#options.deviceMessageParsers.error(e);
            await tryCancel(buffered);
        }
    }

+5 −7
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ export class ClipboardStream
{
    #controller: PushReadableStreamController<string>;

    readonly id = 0;

    constructor() {
        let controller!: PushReadableStreamController<string>;
        super((controller_) => {
@@ -24,13 +26,9 @@ export class ClipboardStream
        this.#controller = controller;
    }

    async parse(id: number, stream: AsyncExactReadable): Promise<boolean> {
        if (id === 0) {
    async parse(_id: number, stream: AsyncExactReadable): Promise<undefined> {
        const message = await ClipboardDeviceMessage.deserialize(stream);
        await this.#controller.enqueue(message.content);
            return true;
        }
        return false;
    }

    close() {
+9 −21
Original line number Diff line number Diff line
import type { MaybePromiseLike } from "@yume-chan/async";
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
import type { AsyncExactReadable, ExactReadable } from "@yume-chan/struct";

import type {
    ScrcpyControlMessageType,
@@ -10,6 +9,7 @@ import type {
    ScrcpyScrollController,
    ScrcpyVideoStream,
} from "../base/index.js";
import { ScrcpyDeviceMessageParsers } from "../base/index.js";
import type {
    ScrcpyBackOrScreenOnControlMessage,
    ScrcpyInjectTouchControlMessage,
@@ -47,11 +47,18 @@ export class ScrcpyOptions1_15 implements ScrcpyOptions<Init> {
        return this.#clipboard;
    }

    #deviceMessageParsers = new ScrcpyDeviceMessageParsers();
    get deviceMessageParsers() {
        return this.#deviceMessageParsers;
    }

    constructor(init: Init) {
        this.value = { ...Defaults, ...init };

        if (this.value.control) {
            this.#clipboard = new ClipboardStream();
            this.#clipboard = this.#deviceMessageParsers.add(
                new ClipboardStream(),
            );
        }
    }

@@ -73,25 +80,6 @@ export class ScrcpyOptions1_15 implements ScrcpyOptions<Init> {
        return parseVideoStreamMetadata(stream);
    }

    async parseDeviceMessage(
        id: number,
        stream: ExactReadable | AsyncExactReadable,
    ): Promise<void> {
        if (await this.#clipboard!.parse(id, stream)) {
            return;
        }

        throw new Error("Unknown device message");
    }

    endDeviceMessageStream(e?: unknown): void {
        if (e) {
            this.#clipboard!.error(e);
        } else {
            this.#clipboard!.close();
        }
    }

    createMediaStreamTransformer(): TransformStream<
        Uint8Array,
        ScrcpyMediaStreamPacket
+9 −21
Original line number Diff line number Diff line
import type { MaybePromiseLike } from "@yume-chan/async";
import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra";
import type { AsyncExactReadable, ExactReadable } from "@yume-chan/struct";

import type {
    ScrcpyControlMessageType,
@@ -12,6 +11,7 @@ import type {
    ScrcpyScrollController,
    ScrcpyVideoStream,
} from "../base/index.js";
import { ScrcpyDeviceMessageParsers } from "../base/index.js";
import type {
    ScrcpyBackOrScreenOnControlMessage,
    ScrcpyInjectTouchControlMessage,
@@ -54,11 +54,18 @@ export class ScrcpyOptions1_17
        return this.#clipboard;
    }

    #deviceMessageParsers = new ScrcpyDeviceMessageParsers();
    get deviceMessageParsers() {
        return this.#deviceMessageParsers;
    }

    constructor(init: Init) {
        this.value = { ...Defaults, ...init };

        if (this.value.control) {
            this.#clipboard = new ClipboardStream();
            this.#clipboard = this.#deviceMessageParsers.add(
                new ClipboardStream(),
            );
        }
    }

@@ -88,25 +95,6 @@ export class ScrcpyOptions1_17
        return parseVideoStreamMetadata(stream);
    }

    async parseDeviceMessage(
        id: number,
        stream: ExactReadable | AsyncExactReadable,
    ): Promise<void> {
        if (await this.#clipboard!.parse(id, stream)) {
            return;
        }

        throw new Error("Unknown device message");
    }

    endDeviceMessageStream(e?: unknown): void {
        if (e) {
            this.#clipboard!.error(e);
        } else {
            this.#clipboard!.close();
        }
    }

    createMediaStreamTransformer(): TransformStream<
        Uint8Array,
        ScrcpyMediaStreamPacket
Loading