Skip to content

Configure Android emulator launch options (headless, GPU, audio, boot animation) from the config file #148

Description

@V3RON

Standalone task opened by the maintainer; no parent feature.

Scope

The Android driver launches every emulator with a window, the default GPU mode, audio, and the boot animation, and none of it is configurable. Six agents on one Mac get six emulator windows, and a headless Linux CI host cannot boot an emulator at all.

After this PR an operator sets, in ~/.simlock/config.json, how this machine's emulators are launched, the same way ios.slim.* is set for simulators: once, by the operator, and never from a lease request, MCP, or HTTP.

{
  "android": {
    "emulator": {
      "headless": false,      // true adds -no-window
      "gpu": "auto",          // passed as -gpu <mode>; "auto" passes nothing
      "audio": true,          // false adds -no-audio
      "bootAnimation": true   // false adds -no-boot-anim
    }
  }
}

A changed setting applies at a device's next boot; a running emulator keeps the flags it started with. Changing headless or gpu also invalidates a device's clean-baseline snapshot, which the driver rebuilds on the next boot instead of silently degrading every later reclaim to a full wipe. There is no free-form launch-argument escape hatch: only these four keys, so config cannot inject -port, a different AVD home, or anything else that would break containment.

Technical spec

Modules touched

  • src/core/config.ts: new android.emulator block beside ios.slim with the defaults above; validators reject a non-boolean headless/audio/bootAnimation and a gpu that is not a non-empty string, naming the key. A gateway warns about and ignores it exactly as it does ios.* (extend the existing gateway-ignored key handling and its docs/CONFIGURATION.md list).
  • src/contract/schemas.ts: the config block so simlock config and config.get render it.
  • src/daemon/main.ts: thread config.android.emulator into discoverAndroidDriver the way config.ios.slim reaches the iOS driver.
  • src/drivers/android/index.ts: AndroidDriverOptions.emulator (optional; defaults equal the config defaults). #startEmulator appends the flags after -no-snapshot-save. #configHash and #currentConfigHash include headless and gpu in the hashed input so the baseline snapshot rebuilds when either changes. audio and bootAnimation do not enter the hash.
  • docs/CONFIGURATION.md: the four keys in the table, their validation in the rules paragraph, the "applies at next boot" and snapshot-rebuild notes, and the gateway-ignored list. README.md: no change unless a claim there becomes false.

Contract and event changes

None beyond the config schema. No new operation, event, or lease-request field. lease.request must not gain any of these keys.

Rules in play

  • docs/internal/agent-rules/architecture.md: the core hands the block to the driver unread; which emulator flag a key becomes is the driver's business.
  • docs/internal/agent-rules/safety.md rule 9: fail closed on config. Only the four named keys, validated at load; no pass-through of arbitrary flags.
  • docs/internal/adr/0002-opt-in-slim-ios-simulators.md: the precedent for driver-level, config-only settings.
  • docs/internal/agent-rules/testing.md.

Tests

  • The default config launches the emulator with the same arguments as before this change (unit, scripted ProcessRunner).
  • android.emulator.headless: true adds -no-window to the emulator launch, and audio: false and bootAnimation: false add -no-audio and -no-boot-anim.
  • android.emulator.gpu: "swiftshader_indirect" adds -gpu swiftshader_indirect, and "auto" adds nothing.
  • A non-boolean android.emulator.headless is rejected at config load, naming the key.
  • Changing headless or gpu changes the baseline config hash, so the next boot rebuilds the clean snapshot; changing audio or bootAnimation does not.
  • A gateway warns about and ignores android.emulator.*.
  • simlock config renders the android.emulator block with its defaults (e2e, fast lane).
  • lease.request carrying an android or emulator field is BAD_REQUEST.

Done when

  • Every test above passes and pnpm check is green.
  • simlock config shows the block; docs/CONFIGURATION.md documents the four keys, the next-boot rule, and the snapshot-rebuild rule.
  • The emulator launch command with default config is byte-for-byte what it was before.

Out of scope

  • A per-lease or per-request override of any of these keys.
  • A free-form launchArgs key.
  • An iOS equivalent (simctl boot is already headless; attaching Simulator.app is a separate idea).
  • RAM or CPU per emulator; that is capacity's business.

Depends on

Approval

  • Approved for delivery

Written by an agent.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

task:readyAn agent may implement it.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions