Files
elizaos--eliza/packages/os/android/README.md
T
wehub-resource-sync 426e9eeabd
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Waiting to run
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Waiting to run
Build Agent Image / build-and-push (push) Waiting to run
Chat shell gestures / Chat shell gesture + parity e2e (push) Waiting to run
ci / test (push) Waiting to run
ci / lint-and-format (push) Waiting to run
ci / build (push) Waiting to run
ci / dev-startup (push) Waiting to run
Cloud Gateway Discord / Test (push) Waiting to run
Cloud Gateway Webhook / Test (push) Waiting to run
Cloud Tests / lint-and-types (push) Waiting to run
Cloud Tests / unit-tests (push) Waiting to run
Cloud Tests / integration-tests (push) Waiting to run
Cloud Tests / e2e-tests (push) Blocked by required conditions
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Apps Worker (Product 2) / Determine environment (push) Waiting to run
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Blocked by required conditions
Deploy Eliza Provisioning Worker / Determine environment (push) Waiting to run
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Blocked by required conditions
Dev Smoke / Classify changed paths (push) Waiting to run
Dev Smoke / bun run dev onboarding chat (push) Blocked by required conditions
Dev Smoke / Vite HMR dependency-level smoke (push) Blocked by required conditions
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Waiting to run
gitleaks / gitleaks (push) Waiting to run
Markdown Links / Relative Markdown Links (push) Waiting to run
Publish @elizaos/example-code / check_npm (push) Waiting to run
Publish @elizaos/example-code / publish_npm (push) Blocked by required conditions
Publish @elizaos/plugin-elizacloud / verify_version (push) Waiting to run
Publish @elizaos/plugin-elizacloud / publish_npm (push) Blocked by required conditions
Quality (Extended) / Homepage Build (PR smoke) (push) Waiting to run
Quality (Extended) / Comment-only diff guard (push) Waiting to run
Quality (Extended) / Format + Type Safety Ratchet (push) Waiting to run
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Waiting to run
Quality (Extended) / Develop Gate (lint) (push) Waiting to run
Sandbox Live Smoke / Sandbox live smoke (push) Waiting to run
Snap Build & Test / Build Snap (amd64) (push) Waiting to run
Snap Build & Test / Build Snap (arm64) (push) Waiting to run
supply-chain / sbom (push) Waiting to run
supply-chain / vulnerability-scan (push) Waiting to run
Build, Push & Deploy to Phala Cloud / build-and-push (push) Waiting to run
Test Packaging / Validate Packaging Configs (push) Waiting to run
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Waiting to run
Test Packaging / Pack & Test JS Tarballs (push) Waiting to run
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Waiting to run
UI Fixture E2E / ui-fixture-e2e (push) Waiting to run
UI Fixture E2E / fixture-e2e (push) Waiting to run
UI Story Gate / story-gate (push) Waiting to run
vault-ci / test (macos-latest) (push) Waiting to run
vault-ci / test (ubuntu-latest) (push) Waiting to run
vault-ci / test (windows-latest) (push) Waiting to run
vault-ci / app-core wiring tests (push) Waiting to run
verify-patches / verify patches/CHECKSUMS.sha256 (push) Waiting to run
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Waiting to run
Voice Benchmark Smoke / voice bench smoke summary (push) Blocked by required conditions
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Waiting to run
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Waiting to run
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Waiting to run
Test Packaging / Build & Test PyPI Package (push) Waiting to run
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

6.9 KiB

Android distro layer

This directory contains the brand vendor tree for building a privileged-system-app Android distribution (Cuttlefish for CI validation, Pixel codenames for real devices). The toolchain is brand-aware: any downstream brand can build its own distribution by supplying a JSON brand config + vendor tree.

Layout

packages/os/android/
└── vendor/
    └── <brand>/                # Vendor tree for brand <brand>
        ├── AndroidProducts.mk
        ├── <brand>_common.mk
        ├── apps/<AppName>/Android.bp
        ├── bootanimation/{desc.txt,README.md}
        ├── init/init.<brand>.rc
        ├── overlays/frameworks/base/core/res/res/values/config.xml
        ├── permissions/{Android.bp,default-permissions-<pkg>.xml,privapp-permissions-<pkg>.xml}
        ├── products/<brand>_*_phone.mk
        └── sepolicy/{file_contexts,<brand>_agent.te,README.md}

The default brand shipped here is eliza (vendor/eliza/). The brand configs live at packages/scripts/distro-android/brand.eliza*.json — one per arch (brand.eliza.json = x86_64, brand.eliza-arm64.json, brand.eliza-riscv64.json), all pointing at this package's vendor/eliza/ overlay and the matching eliza_cf_<arch>_phone product.

Emulator + build entry point

Makefile here is the front door for the AOSP fork, parallel to packages/os/linux/Justfile for the canonical Debian fork. ARCH selects the brand config + Cuttlefish device dir; the eliza overlay (launcher, splash, permissions) is arch-agnostic and shared across all three:

make build ARCH=x86_64            # build + launch + boot-validate a Cuttlefish image
make build ARCH=arm64
make build ARCH=riscv64
make sim   ARCH=riscv64           # bring up + validate an already-built image
make bootanimation                # render + pack the elizaOS boot splash (needs ImageMagick)

Each target drives the brand-aware orchestrator in packages/scripts/distro-android/ (build-aosp.mjs, sim.mjs, build-bootanimation.mjs), which is the stack CI uses (.github/workflows/elizaos-cuttlefish.yml). Real builds need a Linux x86_64 host with KVM and a synced AOSP checkout (AOSP_ROOT, default $HOME/aosp); riscv64 Cuttlefish runs under QEMU TCG (no KVM) and boots slower — sim.mjs sizes its boot timeout for that automatically.

make build syncs vendor/eliza, validates the product layer against the AOSP source, runs lunch eliza_cf_<arch>_phone-trunk_staging-userdebug && m, launches Cuttlefish, and then runs the boot validator. The underlying command is node packages/scripts/distro-android/build-aosp.mjs --brand-config <arch-config> --aosp-root <root> --launch --boot-validate.

Note on orchestration: a second, divergent AOSP build/emulator stack exists at packages/app-core/scripts/aosp/ (wired into app-core's vitest

  • agent-payload staging). It currently ships only an x86_64 product path, so the eliza arm64/riscv64 images come from the distro-android stack that this Makefile drives. The two stacks share an identical-purpose core of ~11 files that have drifted; collapsing them to one canonical core is tracked as follow-up cleanup.

Boot experience: splash + launcher

Every eliza image boots straight into the elizaOS launcher with the elizaOS boot splash:

  • Launchereliza_common.mk strips the stock launchers and the Eliza APK overrides: ["Launcher3", "Launcher3QuickStep", "Trebuchet", …], so Eliza (ai.elizaos.app) is the only HOME app. The overlay sets config_defaultHome (alongside dialer/sms/assistant/browser) and ro.elizaos.home, and SetupWizard is disabled — no Google "Welcome" flow.
  • Splashscripts/generate-eliza-bootanimation.mjs renders the white elizaOS logo on the elizaOS blue field (#0B35F1) into vendor/eliza/bootanimation/ from the canonical brand SVG using sharp (the repo's image toolchain — no external ImageMagick needed), and build-bootanimation.mjs packs it into the uncompressed bootanimation.zip AOSP's bootanimation daemon requires. The rendered frames + zip are gitignored; run make bootanimation before make build to bake the splash in. If the zip is absent, eliza_common.mk guards the copy and the image falls through to the stock AOSP animation.

AOSP assistant/full-control contract

The AOSP image makes ai.elizaos.app the device assistant, not just another app that can answer an intent. The product overlay sets config_defaultAssistant, the APK declares ElizaAssistActivity for both android.intent.action.ASSIST and android.intent.action.VOICE_COMMAND, and the boot validator checks the role holder plus both activity resolutions.

The machine-readable contract lives at vendor/eliza/manifests/aosp-assistant-full-control.json and is copied into the image at /product/etc/eliza/aosp-assistant-full-control.json. It records the full AOSP-only control surface:

  • RoleManager.ROLE_ASSISTANT, Intent.ACTION_ASSIST, and Intent.ACTION_VOICE_COMMAND ownership and their concrete platform values.
  • Concrete AOSP-only ElizaAccessibilityService and ElizaNotificationListenerService declarations. The Play/cloud build strips the services, Java sources, and accessibility-service XML resource.
  • Usage stats through PACKAGE_USAGE_STATS plus the boot-time GET_USAGE_STATS appop grant path.
  • MediaProjection/foreground-service screen capture for user-consented paths and privileged READ_FRAME_BUFFER capture for system images.
  • Input control through accessibility gestures on user-consented paths and INJECT_EVENTS on privileged system images.
  • Direct-boot receiver coverage for LOCKED_BOOT_COMPLETED, BOOT_COMPLETED, and package replacement.
  • Foreground service declarations for the local agent runtime, gateway sync, background voice capture, and screen capture.
  • System-image requirements: /system/priv-app/Eliza/Eliza.apk, platform certificate, privileged: true, default-permissions XML, and privapp XML.

Google Play builds must use android-cloud. Static checks assert that the cloud build strips assistant/default-role components, boot/direct-boot receivers, RECEIVE_BOOT_COMPLETED, background microphone foreground service, MediaProjection service permission, privileged permissions, and native system-control plugins.

Whitelabel — building a downstream brand

Provide a brand config and a corresponding vendor tree, then drive every script in packages/scripts/distro-android/ with --brand-config <path>:

node packages/scripts/distro-android/build-aosp.mjs \
  --brand-config /path/to/your-brand.json \
  --source-vendor /path/to/your-vendor-tree \
  --aosp-root /path/to/aosp \
  --launch --boot-validate

See packages/scripts/distro-android/README.md for the brand config schema and the GitHub Actions workflow .github/workflows/elizaos-cuttlefish.yml for a reusable workflow that downstream brands can call.