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
141 lines
6.9 KiB
Markdown
141 lines
6.9 KiB
Markdown
# 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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
- **Launcher** — `eliza_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.
|
|
- **Splash** — `scripts/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>`:
|
|
|
|
```bash
|
|
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.
|