211 lines
7.2 KiB
Nix
211 lines
7.2 KiB
Nix
{ config, pkgs, lib, ... }:
|
|
|
|
let
|
|
cfg = config.modules.android;
|
|
in
|
|
{
|
|
options.modules.android = {
|
|
enable = lib.mkEnableOption "Android development environment with emulator support";
|
|
|
|
enableEmulator = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = true;
|
|
description = "Enable Android emulator for testing Flutter and Android apps";
|
|
};
|
|
|
|
apiLevel = lib.mkOption {
|
|
type = lib.types.int;
|
|
default = 34;
|
|
description = "Default Android API level for the emulator";
|
|
};
|
|
|
|
enableFlutterSupport = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = true;
|
|
description = "Enable Flutter SDK and related tools";
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
home.packages = with pkgs; [
|
|
# Android Studio Full with FHS environment (recommended for NixOS)
|
|
# This includes SDK, emulator, and all necessary tools
|
|
android-studio-full
|
|
|
|
# Core Android command-line tools
|
|
android-tools
|
|
|
|
# Build and compilation tools
|
|
gradle
|
|
maven
|
|
ninja
|
|
cmake
|
|
gnumake
|
|
pkg-config
|
|
|
|
# Java/Kotlin development
|
|
jdk
|
|
jdk21
|
|
kotlin
|
|
|
|
# Flutter SDK for app development
|
|
(if cfg.enableFlutterSupport then flutter else null)
|
|
|
|
# Flutter Version Manager
|
|
(if cfg.enableFlutterSupport then fvm else null)
|
|
|
|
# Additional Android tools
|
|
scrcpy # Screen sharing for Android devices
|
|
apksigner # Sign APKs
|
|
];
|
|
|
|
# Environment variables for Android development
|
|
home.sessionVariables = lib.mkIf cfg.enable {
|
|
ANDROID_HOME = "$HOME/.android";
|
|
ANDROID_SDK_ROOT = "$HOME/Android/Sdk";
|
|
ANDROID_USER_HOME = "$HOME/.android";
|
|
JAVA_HOME = "${pkgs.jdk}/lib/openjdk";
|
|
# For Flutter development
|
|
ANDROID_JAVA_HOME = "${pkgs.jdk}";
|
|
};
|
|
|
|
# Create a script to launch the Android emulator
|
|
# Note: This works with the NixOS androidenv setup
|
|
home.file.".local/share/bin/android-emulator" = lib.mkIf cfg.enableEmulator {
|
|
executable = true;
|
|
text = ''
|
|
#!/usr/bin/env bash
|
|
# Android Emulator launcher script for NixOS
|
|
# Uses android-studio-full's built-in tools
|
|
|
|
set -e
|
|
|
|
EMULATOR_NAME="''${1:-flutter-dev}"
|
|
API_LEVEL="''${2:-${toString cfg.apiLevel}}"
|
|
|
|
echo "Starting Android Emulator: $EMULATOR_NAME (API $API_LEVEL)"
|
|
|
|
# Check if AVD exists, if not create it
|
|
if ! grep -q "^[^#]*name=$EMULATOR_NAME" ~/.android/avd/devices.txt 2>/dev/null; then
|
|
echo "Creating AVD: $EMULATOR_NAME..."
|
|
|
|
# Try using avdmanager from Android Studio
|
|
if command -v avdmanager &> /dev/null; then
|
|
echo "no" | avdmanager create avd \
|
|
--name "$EMULATOR_NAME" \
|
|
--package "system-images;android-$API_LEVEL;google_apis;x86_64" \
|
|
--device "pixel_6" \
|
|
--force 2>&1 || {
|
|
echo "Error: Could not create AVD"
|
|
echo "Try running: android-studio to set up SDK from the IDE"
|
|
exit 1
|
|
}
|
|
else
|
|
echo "Error: avdmanager not found"
|
|
echo "Please open Android Studio and complete the SDK setup:"
|
|
echo " android-studio"
|
|
echo ""
|
|
echo "Then use SDK Manager to download system images for API $API_LEVEL"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Launch emulator with optimizations for NixOS
|
|
emulator -avd "$EMULATOR_NAME" \
|
|
-memory 2048 \
|
|
-partition-size 4096 \
|
|
-dns-server 8.8.8.8 \
|
|
-no-snapshot-load \
|
|
-no-snapshot-save \
|
|
-gpu auto \
|
|
-no-boot-anim \
|
|
&
|
|
|
|
EMULATOR_PID=$!
|
|
echo "Emulator starting in background (PID: $EMULATOR_PID)"
|
|
echo "Waiting for boot..."
|
|
|
|
# Wait for emulator to boot
|
|
for i in {1..90}; do
|
|
if adb shell getprop sys.boot_completed 2>/dev/null | grep -q "1"; then
|
|
echo "✓ Emulator fully booted!"
|
|
exit 0
|
|
fi
|
|
echo -n "."
|
|
sleep 2
|
|
done
|
|
|
|
echo ""
|
|
echo "⚠ Timeout waiting for emulator to boot"
|
|
exit 1
|
|
'';
|
|
};
|
|
|
|
# Create a setup script to initialize Android environment on first use
|
|
home.file.".local/share/bin/android-setup" = lib.mkIf cfg.enable {
|
|
executable = true;
|
|
text = ''
|
|
#!/usr/bin/env bash
|
|
# One-time setup script for Android development on NixOS
|
|
|
|
echo "Setting up Android development environment..."
|
|
echo ""
|
|
|
|
# Check if sdkmanager is available
|
|
if ! command -v sdkmanager &> /dev/null; then
|
|
echo "Warning: sdkmanager not found in PATH"
|
|
echo "This is normal on NixOS. You'll need to use Android Studio to manage SDKs."
|
|
echo ""
|
|
echo "Opening Android Studio for SDK setup..."
|
|
android-studio &
|
|
echo ""
|
|
echo "In Android Studio:"
|
|
echo " 1. Go to Tools → SDK Manager"
|
|
echo " 2. Select API levels you want to download"
|
|
echo " 3. Click 'Apply' and 'OK'"
|
|
echo " 4. Close Android Studio when done"
|
|
exit 0
|
|
fi
|
|
|
|
# Accept Android licenses
|
|
echo "Accepting Android licenses..."
|
|
yes | sdkmanager --licenses 2>&1 | tail -10
|
|
|
|
echo ""
|
|
echo "✓ Android environment setup complete!"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo " 1. Run: android-emulator (to create and start emulator)"
|
|
echo " 2. For Flutter: flutter doctor"
|
|
echo " 3. For Android Studio: android-studio"
|
|
echo ""
|
|
'';
|
|
};
|
|
|
|
# Optional: Add udev rules for Android devices
|
|
# This allows debugging on physical devices without root
|
|
home.file.".config/udev/rules.d/51-android.rules" = lib.mkIf cfg.enable {
|
|
text = ''
|
|
# Android debug bridge - allows USB debugging without sudo
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="0e79", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="0502", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="0b05", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="413c", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="0489", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="091e", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="0d4d", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="04e8", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="04da", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="04b7", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="04b8", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="04b9", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="0bed", MODE="0666", GROUP="adbusers"
|
|
SUBSYSTEM=="usb", ATTR{idVendor}=="1d4d", MODE="0666", GROUP="adbusers"
|
|
'';
|
|
};
|
|
};
|
|
}
|