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

Unverified Commit 2abec924 authored by Simon Chan's avatar Simon Chan
Browse files

feat(bin): add wrapper for bu

fixes #354
parent 721e14fa
Loading
Loading
Loading
Loading
+3 −7
Original line number Diff line number Diff line
module.exports = {
    "extends": [
        "@yume-chan"
    ],
    extends: ["@yume-chan"],
    parserOptions: {
        tsconfigRootDir: __dirname,
        project: [
            "./tsconfig.build.json"
        ],
        project: ["./tsconfig.test.json"],
    },
}
};
+14 −0
Original line number Diff line number Diff line
/** @type {import('ts-jest').JestConfigWithTsJest} */
export default {
    preset: "ts-jest/presets/default-esm",
    extensionsToTreatAsEsm: [".ts"],
    transform: {
        "^.+\\.tsx?$": [
            "ts-jest",
            { tsconfig: "tsconfig.test.json", useESM: true },
        ],
    },
    moduleNameMapper: {
        "^(\\.{1,2}/.*)\\.js$": "$1",
    },
};
+9 −4
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
    "scripts": {
        "build": "tsc -b tsconfig.build.json",
        "build:watch": "tsc -b tsconfig.build.json",
        "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage",
        "lint": "eslint src/**/*.ts --fix && prettier src/**/*.ts --write --tab-width 4",
        "prepublishOnly": "npm run build"
    },
@@ -34,13 +35,17 @@
        "@yume-chan/adb": "workspace:^0.0.20",
        "@yume-chan/stream-extra": "workspace:^0.0.20",
        "@yume-chan/struct": "workspace:^0.0.20",
        "tslib": "^2.5.2"
        "tslib": "^2.6.0"
    },
    "devDependencies": {
        "@jest/globals": "^29.6.1",
        "@yume-chan/eslint-config": "workspace:^1.0.0",
        "@yume-chan/tsconfig": "workspace:^1.0.0",
        "eslint": "^8.41.0",
        "prettier": "^2.8.8",
        "typescript": "^5.0.3"
        "cross-env": "^7.0.3",
        "eslint": "^8.44.0",
        "jest": "^29.5.0",
        "prettier": "^3.0.0",
        "ts-jest": "^29.1.1",
        "typescript": "^5.1.6"
    }
}
+62 −14
Original line number Diff line number Diff line
// cspell: ignore apks
// cspell: ignore obbs

import { AdbCommandBase } from "@yume-chan/adb";
import type { Consumable, ReadableStream } from "@yume-chan/stream-extra";

export interface AdbBackupOptions {
    apps: string[] | "all" | "all-including-system";
    apks: boolean;
    obbs: boolean;
    shared: boolean;
    widgets: boolean;
    user: number;
    saveSharedStorage?: boolean;
    saveWidgets?: boolean;
    packages: string[] | "user" | "all";
    savePackageApk: boolean;
    savePackageObb: boolean;
    savePackageKeyValue: boolean;
    compress: boolean;
}

export interface AdbRestoreOptions {
    user: number;
    file: ReadableStream<Consumable<Uint8Array>>;
}

export class AdbBackup extends AdbCommandBase {
    backup(options: AdbBackupOptions): Promise<void> {
        void options;
        throw new Error("Not implemented");
    /**
     * User must confirm backup on device within 60 seconds.
     */
    public async backup(
        options: AdbBackupOptions
    ): Promise<ReadableStream<Uint8Array>> {
        const args = ["bu", "backup"];

        if (options.user !== undefined) {
            args.push("--user", options.user.toString());
        }

        args.push(options.saveSharedStorage ? "--shared" : "--no-shared");
        args.push(options.saveWidgets ? "--widgets" : "--no-widgets");

        args.push(options.savePackageApk ? "--apk" : "--no-apk");
        args.push(options.savePackageObb ? "--obb" : "--no-obb");
        args.push(
            options.savePackageKeyValue ? "--key-value" : "--no-key-value"
        );

        args.push(options.compress ? "--compress" : "--no-compress");

        if (typeof options.packages === "string") {
            switch (options.packages) {
                case "user":
                    args.push("--all", "--no-system");
                    break;
                case "all":
                    args.push("--all", "--system");
                    break;
            }
        } else {
            args.push(...options.packages);
        }

    restore(options: AdbBackupOptions): Promise<void> {
        void options;
        throw new Error("Not implemented");
        const process = await this.adb.subprocess.spawn(args);
        return process.stdout;
    }

    /**
     * User must enter the password (if any) and
     * confirm restore on device within 60 seconds.
     */
    public async restore(options: AdbRestoreOptions): Promise<void> {
        const args = ["bu", "restore"];
        if (options.user !== undefined) {
            args.push("--user", options.user.toString());
        }
        const process = await this.adb.subprocess.spawn(args);
        await options.file.pipeTo(process.stdin);
        await process.exit;
    }
}
+56 −1
Original line number Diff line number Diff line
import { AdbCommandBase } from "@yume-chan/adb";

export class DumpSys extends AdbCommandBase {
    async diskStats() {
    public async diskStats() {
        const output = await this.adb.subprocess.spawnAndWaitLegacy([
            "dumpsys",
            "diskstats",
@@ -33,4 +33,59 @@ export class DumpSys extends AdbCommandBase {
            systemTotal,
        };
    }

    public async battery() {
        const output = await this.adb.subprocess.spawnAndWaitLegacy([
            "dumpsys",
            "battery",
        ]);

        let acPowered = false;
        let usbPowered = false;
        let wirelessPowered = false;
        let level: number | undefined;
        let scale: number | undefined;
        let voltage: number | undefined;
        let current: number | undefined;
        for (const line of output) {
            const parts = line.split(":");
            if (parts.length !== 2) {
                continue;
            }

            switch (parts[0]!.trim()) {
                case "AC powered":
                    acPowered = parts[1]!.trim() === "true";
                    break;
                case "USB powered":
                    usbPowered = parts[1]!.trim() === "true";
                    break;
                case "Wireless powered":
                    wirelessPowered = parts[1]!.trim() === "true";
                    break;
                case "level":
                    level = Number.parseInt(parts[1]!.trim(), 10);
                    break;
                case "scale":
                    scale = Number.parseInt(parts[1]!.trim(), 10);
                    break;
                case "voltage":
                    voltage = Number.parseInt(parts[1]!.trim(), 10);
                    break;
                case "current now":
                    current = Number.parseInt(parts[1]!.trim(), 10);
                    break;
            }
        }

        return {
            acPowered,
            usbPowered,
            wirelessPowered,
            level,
            scale,
            voltage,
            current,
        };
    }
}
Loading