Files
rea/src/application/AndroidAnalysisService.ts
T
N0zoM1z0andGitHub 904d03e987 feat(android): integrate static APK analysis with headless JADX (#738)
* feat(android): integrate static APK analysis with headless JADX

* test(android): include APK tools in explicit effects audit
2026-10-06 12:46:48 +00:00

55 lines
2.0 KiB
TypeScript

import type { AndroidAnalysisPort } from "./AndroidAnalysisPort.js";
import type { ExecutionOptions } from "./AnalysisProvider.js";
import { parseBinaryTarget } from "./BinaryTargetResolver.js";
import {
androidRequestSchema,
type AndroidOperation,
} from "../domain/androidAnalysis.js";
import {
AnalysisCancelledError,
AnalysisInputError,
} from "../domain/analysisErrorCore.js";
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import { createEvidence, type Evidence } from "../domain/evidence.js";
import { jsonObjectSchema } from "../domain/jsonValue.js";
import { err, ok, type Result } from "../domain/result.js";
/** Shared CLI/MCP admission, execution and Evidence composition for Android. */
export class AndroidAnalysisService {
constructor(readonly provider: AndroidAnalysisPort) {}
/** Inspect a caller-selected APK and retain producing-provider provenance inline. */
async execute(
operation: AndroidOperation,
input: unknown,
options?: ExecutionOptions,
): Promise<Result<Evidence, AnalysisError>> {
if (options?.signal?.aborted === true)
return err(new AnalysisCancelledError(operation));
const request = androidRequestSchema.safeParse({ operation, input });
if (!request.success)
return err(new AnalysisInputError(operation, { cause: request.error }));
const target = await parseBinaryTarget(request.data.input.path);
if (!target.ok) return target;
const executed = await this.provider.execute(
target.value,
request.data,
options,
);
if (!executed.ok) return executed;
const execution = executed.value;
return ok(
createEvidence(execution.subject ?? target.value, execution.provider, {
operation,
parameters: jsonObjectSchema.parse(request.data.input),
result: execution.result,
rawResult: execution.rawResult,
limitations: execution.limitations,
locations: execution.locations,
confidence:
operation === "inspect_android_method" ? "derived" : "observed",
}),
);
}
}