Files
AetherForge/android

AetherForge Agent APK (Phase 1)

Install the APK on your own devices so the embedded fleet agent joins the command-deck fleet table over WebSocket/C2. CPU mining is off by default in the baked config.

Main project overview: README.md · test coverage: tests/README.md.

Build

Requirements:

  • Go 1.26+
  • JDK 17+ (Android Gradle Plugin 8.x; Java 8 on PATH is not sufficient)
  • Android SDK (ANDROID_HOME or ANDROID_SDK_ROOT)
  • Gradle wrapper in agent-app/ (included; downloads Gradle 8.2 on first run)
# Windows
$env:AETHERFORGE_SERVER_URL = "https://your-deck.example.com:8989"
$env:AETHERFORGE_WORKER_NAME = "pixel-tab-01"
$env:AETHERFORGE_FLEET_SECRET = "your-fleet-secret"   # optional; do not commit
.\android\build-apk.ps1
# Linux/macOS
export AETHERFORGE_SERVER_URL="https://your-deck.example.com:8989"
export AETHERFORGE_WORKER_NAME="pixel-tab-01"
export AETHERFORGE_FLEET_SECRET="your-fleet-secret"
./android/build-apk.sh

Output:

android/agent-app/build/outputs/apk/debug/aetherforge-agent.apk

The build script:

  1. Renders assets/config.json and a temporary agent/config/builtin.go
  2. Cross-compiles GOOS=linux GOARCH=arm64 CGO_ENABLED=0 from agent/ into assets/agent
  3. Runs assembleDebug

Install (adb)

adb install -r android/agent-app/build/outputs/apk/debug/aetherforge-agent.apk
adb shell am start -n com.aetherforge.agent/.MainActivity

First launch — permissions

Open the app once. You will see:

Your fleet node — tap Allow on each prompt.

The app requests all runtime permissions in one batch:

  • POST_NOTIFICATIONS (API 33+) — required for the foreground service notification
  • NEARBY_WIFI_DEVICES / location — fleet WiFi diagnostics where the OS requires it

Then it opens battery optimization settings (REQUEST_IGNORE_BATTERY_OPTIMIZATIONS). Android cannot auto-grant these; you must tap Allow / Don't optimize.

After permissions, a low-priority persistent notification (Fleet sync) keeps AgentService alive. BootReceiver restarts the service on BOOT_COMPLETED.

How it runs

  1. AgentService extracts assets/agent (linux/arm64) to filesDir/bin/agent-arm64, marks it executable, and spawns it with --run.
  2. Environment sets HOME/TMPDIR to the app private files directory.
  3. The agent uses forge-baked builtin.go values (server URL, worker name, fleet secret). Mining defaults to idle with IdleThresholdPct: 0 (no CPU mining unless re-forged or changed by policy).
  4. Wrapper sets AETHERFORGE_PLATFORM=android before spawn — Crucible shows 🤖, Access Depth uses Wi-Fi/battery/foreground probes, shortened mining onion (foreground service → in-process CPU).

Limitations

  • No root — cannot install as system app or disable OEM kill policies globally.
  • Notification required — foreground service must show a notification on modern Android.
  • Binary execution — spawning a GOOS=linux binary via ProcessBuilder works on many arm64 devices (static Go build) but some OEMs block exec from app sandboxes. If the agent never appears in the fleet table, check adb logcat -s AetherForge AetherForge:agent. A native GOOS=android JNI approach is Phase 2 if exec fails on your hardware.
  • Secrets — pass AETHERFORGE_FLEET_SECRET at build time via environment; never commit fleet secrets.

Tests

go test ./android/forge/... -count=1
bash android/smoke-gradle.sh
go test ./android/forge/... -count=1
.\android\smoke-gradle.ps1

smoke-gradle.sh validates the Gradle project layout and runs ./gradlew help when the wrapper is present.