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

Unverified Commit 6575d794 authored by Simon Chan's avatar Simon Chan
Browse files

fix: restore compaibility with Android 7

parent 0a3785e2
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -134,9 +134,9 @@ export class AdbScrcpyClient<TOptions extends AdbScrcpyOptions<object>> {
            }

            const args = [
                // Use `CLASSPATH=` as `-cp` argument requires Android 8.0
                `CLASSPATH=${path}`,
                "app_process",
                "-cp",
                path,
                /* unused */ "/",
                "com.genymobile.scrcpy.Server",
                options.version,
+48 −14
Original line number Diff line number Diff line
@@ -257,7 +257,7 @@ const PACKAGE_MANAGER_RESOLVE_ACTIVITY_OPTIONS_MAP: Partial<

function buildInstallArguments(
    command: string,
    options: Partial<PackageManagerInstallOptions> | undefined,
    options: Optional<PackageManagerInstallOptions> | undefined,
): string[] {
    const args = buildArguments(
        [PackageManager.ServiceName, command],
@@ -299,7 +299,7 @@ export class PackageManager extends AdbServiceBase {
     */
    async install(
        apks: readonly string[],
        options?: Partial<PackageManagerInstallOptions>,
        options?: Optional<PackageManagerInstallOptions>,
    ): Promise<string> {
        const args = buildInstallArguments("install", options);
        args[0] = PackageManager.CommandName;
@@ -328,7 +328,7 @@ export class PackageManager extends AdbServiceBase {

    async pushAndInstallStream(
        stream: ReadableStream<MaybeConsumable<Uint8Array>>,
        options?: Partial<PackageManagerInstallOptions>,
        options?: Optional<PackageManagerInstallOptions>,
    ): Promise<string> {
        const fileName = Math.random().toString().substring(2);
        const filePath = `/data/local/tmp/${fileName}.apk`;
@@ -354,7 +354,7 @@ export class PackageManager extends AdbServiceBase {
    async installStream(
        size: number,
        stream: ReadableStream<MaybeConsumable<Uint8Array>>,
        options?: Partial<PackageManagerInstallOptions>,
        options?: Optional<PackageManagerInstallOptions>,
    ): Promise<void> {
        // Android 7 added both `cmd` command and streaming install support,
        // It's hard to detect whether `pm` supports streaming install (unless actually trying),
@@ -439,7 +439,7 @@ export class PackageManager extends AdbServiceBase {
    }

    async *listPackages(
        options?: Partial<PackageManagerListPackagesOptions>,
        options?: Optional<PackageManagerListPackagesOptions>,
    ): AsyncGenerator<PackageManagerListPackagesResult, void, void> {
        const args = buildArguments(
            ["package", "list", "packages"],
@@ -481,7 +481,7 @@ export class PackageManager extends AdbServiceBase {

    async uninstall(
        packageName: string,
        options?: Partial<PackageManagerUninstallOptions>,
        options?: Optional<PackageManagerUninstallOptions>,
    ): Promise<void> {
        const args = buildArguments(
            [PackageManager.ServiceName, "uninstall"],
@@ -534,7 +534,7 @@ export class PackageManager extends AdbServiceBase {
     * @returns ID of the new install session
     */
    async sessionCreate(
        options?: Partial<PackageManagerInstallOptions>,
        options?: Optional<PackageManagerInstallOptions>,
    ): Promise<number> {
        const args = buildInstallArguments("install-create", options);

@@ -544,7 +544,7 @@ export class PackageManager extends AdbServiceBase {

        const sessionIdString = output.match(/.*\[(\d+)\].*/);
        if (!sessionIdString) {
            throw new Error("Failed to create install session");
            throw new Error(output);
        }

        return Number.parseInt(sessionIdString[1]!, 10);
@@ -601,15 +601,38 @@ export class PackageManager extends AdbServiceBase {
        ]);
    }

    async sessionCommit(sessionId: number): Promise<void> {
    /**
     * Commit an install session.
     * @param sessionId ID of install session returned by `createSession`
     * @param usePm
     * When `true`, always use `pm install-commit`,
     * even if `cmd package install-commit` is supported.
     *
     * `cmd package` starts faster because it connects to the already running `system` process.
     * But Android 7 doesn't write the "Success" message when `cmd package` is used,
     * causing this function to fail with an empty message.
     *
     * If you know the device's API level, you can use this parameter to force `pm install-commit`
     * on Android 7 to workaround this issue.
     *
     * https://cs.android.com/android/_/android/platform/frameworks/base/+/b6e96e52e379927859e82606c5b041d99f36a29e
     * @returns A `Promise` that resolves when the session is committed
     */
    async sessionCommit(sessionId: number, usePm?: boolean): Promise<void> {
        const args: string[] = [
            PackageManager.ServiceName,
            "install-commit",
            sessionId.toString(),
        ];
        if (usePm) {
            args[0] = PackageManager.CommandName;
            const process = await this.adb.subprocess.noneProtocol.spawn(args);
            await this.checkResult(process.output);
        } else {
            const process = await this.#cmd.spawn(args);
            await this.checkResult(process.output);
        }
    }

    async sessionAbandon(sessionId: number): Promise<void> {
        const args: string[] = [
@@ -622,10 +645,12 @@ export class PackageManager extends AdbServiceBase {
    }
}

export type Optional<T extends object> = { [K in keyof T]?: T[K] | undefined };

export class PackageManagerInstallSession {
    static async create(
        packageManager: PackageManager,
        options?: Partial<PackageManagerInstallOptions>,
        options?: Optional<PackageManagerInstallOptions>,
    ): Promise<PackageManagerInstallSession> {
        const id = await packageManager.sessionCreate(options);
        return new PackageManagerInstallSession(packageManager, id);
@@ -660,8 +685,17 @@ export class PackageManagerInstallSession {
        );
    }

    commit(): Promise<void> {
        return this.#packageManager.sessionCommit(this.#id);
    /**
     * Commit this install session.
     * @param usePm
     * When `true`, always use `pm install-commit`,
     * even if `cmd package install-commit` is supported.
     *
     * See {@link PackageManager.sessionCommit} for details
     * @returns A `Promise` that resolves when the session is committed
     */
    commit(usePm?: boolean): Promise<void> {
        return this.#packageManager.sessionCommit(this.#id, usePm);
    }

    abandon(): Promise<void> {