Add reproducible Android emulator to the dev shell

Pin the Android SDK composition (platform 36 + google_apis x86_64 system
image + emulator) via composeAndroidPackages so the emulator image is
always available and reproducible across machines. Auto-create the
"oott_api36" AVD idempotently on dev-shell entry, and add
frontend/android-emulator.sh to launch it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
rzuasti
2026-06-02 19:23:33 -04:00
co-authored by Claude Opus 4.8
parent c3acd29e97
commit ada989c11b
2 changed files with 52 additions and 1 deletions
+28 -1
View File
@@ -34,9 +34,20 @@
# Development shell to test the app locally
devShells = forEachSystem (system: let
pythonEnv = pkgsBySystem.${system}.python3.withPackages (ps: [ps.anthropic]);
# Pin the Android SDK composition so the emulator system image is always
# available and reproducible across machines, instead of relying on the
# contents of the default androidPkgs bundle (which can drift over time).
androidComposition = pkgsBySystem.${system}.androidenv.composeAndroidPackages {
platformVersions = ["36"]; # matches Flutter 3.41 compileSdk/targetSdk
includeEmulator = true;
includeSystemImages = true;
systemImageTypes = ["google_apis"];
abiVersions = ["x86_64"];
};
in {
default = pkgsBySystem.${system}.mkShell rec {
androidSdk = pkgsBySystem.${system}.androidenv.androidPkgs.androidsdk;
androidSdk = androidComposition.androidsdk;
ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk";
nativeBuildInputs = with pkgsBySystem.${system}; [
@@ -60,6 +71,22 @@
# fish > all
shellHook = ''
export PATH="${pythonEnv}/bin:$PATH"
# Create the reproducible Android emulator (AVD) on first entry.
# The system image is pinned by the flake, but an AVD is mutable state
# that lives in ~/.android/avd and cannot reside in the read-only Nix
# store, so we (re)create it here. Idempotent: a no-op once it exists.
export ANDROID_AVD_NAME="oott_api36"
if ! emulator -list-avds 2>/dev/null | grep -qx "$ANDROID_AVD_NAME"; then
echo "Creating Android emulator '$ANDROID_AVD_NAME'..."
echo no | avdmanager create avd \
--name "$ANDROID_AVD_NAME" \
--package "system-images;android-36;google_apis;x86_64" \
--device pixel_6 >/dev/null 2>&1 \
&& echo " Android emulator '$ANDROID_AVD_NAME' ready." \
|| echo " WARNING: failed to create Android emulator '$ANDROID_AVD_NAME'."
fi
DEV_SHELL=oott exec fish
'';
};
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
#
# Launch the OOTT Android emulator created by the Nix dev shell.
#
# The AVD (named "oott_api36" by default) is auto-created from the pinned
# system image when you enter the flake dev shell. This script just boots it.
# Any extra arguments are forwarded to `emulator` (e.g. -no-window -no-audio).
set -euo pipefail
AVD_NAME="${ANDROID_AVD_NAME:-oott_api36}"
if ! command -v emulator >/dev/null 2>&1; then
echo "error: 'emulator' not found on PATH." >&2
echo " Enter the dev shell first (e.g. 'nix develop')." >&2
exit 1
fi
if ! emulator -list-avds | grep -qx "$AVD_NAME"; then
echo "error: Android emulator '$AVD_NAME' not found." >&2
echo " Re-enter the dev shell to have it created automatically." >&2
exit 1
fi
exec emulator -avd "$AVD_NAME" "$@"