repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/os-notifier/android/build.mjs
Rawimport { spawnSync } from "node:child_process";
import {
chmodSync,
copyFileSync,
mkdirSync,
mkdtempSync,
rmSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
const source = fileURLToPath(new URL(".", import.meta.url));
const temp = mkdtempSync(join(tmpdir(), "pi-os-notifier-focus-build-"));
const classes = join(temp, "classes");
const dex = join(temp, "dex");
function run(command, args) {
const result = spawnSync(command, args, {
stdio: "inherit",
timeout: 30_000,
});
if (result.error) throw result.error;
if (result.status !== 0)
throw new Error(`${command} failed: ${result.status ?? result.signal}`);
}
try {
mkdirSync(classes);
mkdirSync(dex);
run("javac", [
"--release",
"8",
"-g:none",
"-Xlint:-options",
"-d",
classes,
join(source, "stubs/android/app/ActivityManager.java"),
join(source, "stubs/android/app/IActivityManager.java"),
join(source, "F.java"),
]);
// Compile-only Android signatures are deliberately excluded from the DEX.
run("d8", [
"--release",
"--min-api",
"26",
"--lib",
classes,
"--output",
dex,
join(classes, "F.class"),
]);
run("jar", [
"--create",
"--no-manifest",
"--date=2000-01-01T00:00:00Z",
"--file",
join(temp, "focus.jar"),
"-C",
dex,
"classes.dex",
]);
const target = join(source, "focus.jar");
// Normal resource permissions; runtime removes write bits before Android loads it.
try {
chmodSync(target, 0o644);
} catch (error) {
if (error.code !== "ENOENT") throw error;
}
copyFileSync(join(temp, "focus.jar"), target);
} finally {
rmSync(temp, { recursive: true, force: true });
}