Loading pkgs/development/mobile/androidenv/.gitignore +1 −0 Original line number Diff line number Diff line /xml local.properties .android pkgs/development/mobile/androidenv/compose-android-packages.nix +37 −15 Original line number Diff line number Diff line Loading @@ -185,20 +185,38 @@ rec { system-images = lib.flatten (map (apiVersion: map (type: map (abiVersion: lib.optionals (lib.hasAttrByPath [apiVersion type abiVersion] system-images-packages) ( deployAndroidPackage { inherit os; package = system-images-packages.${apiVersion}.${type}.${abiVersion}; # Deploy all system images with the same systemImageType in one derivation to avoid the `null` problem below # with avdmanager when trying to create an avd! # # ``` # $ yes "" | avdmanager create avd --force --name testAVD --package 'system-images;android-33;google_apis;x86_64' # Error: Package path is not valid. Valid system image paths are: # null # ``` let availablePackages = map (abiVersion: system-images-packages.${apiVersion}.${type}.${abiVersion} ) (builtins.filter (abiVersion: lib.hasAttrByPath [apiVersion type abiVersion] system-images-packages ) abiVersions); instructions = builtins.listToAttrs (map (package: { name = package.name; value = lib.optionalString (lib.hasPrefix "google_apis" type) '' # Patch 'google_apis' system images so they're recognized by the sdk. # Without this, `android list targets` shows 'Tag/ABIs : no ABIs' instead # of 'Tag/ABIs : google_apis*/*' and the emulator fails with an ABI-related error. patchInstructions = lib.optionalString (lib.hasPrefix "google_apis" type) '' sed -i '/^Addon.Vendor/d' source.properties ''; } ) ) abiVersions }) availablePackages ); in lib.optionals (availablePackages != []) (deployAndroidPackages { inherit os; packages = availablePackages; patchesInstructions = instructions; }) ) systemImageTypes ) platformVersions); Loading Loading @@ -271,8 +289,8 @@ rec { ${lib.concatMapStrings (system-image: '' apiVersion=$(basename $(echo ${system-image}/libexec/android-sdk/system-images/*)) type=$(basename $(echo ${system-image}/libexec/android-sdk/system-images/*/*)) mkdir -p system-images/$apiVersion/$type ln -s ${system-image}/libexec/android-sdk/system-images/$apiVersion/$type/* system-images/$apiVersion/$type mkdir -p system-images/$apiVersion ln -s ${system-image}/libexec/android-sdk/system-images/$apiVersion/$type system-images/$apiVersion/$type '') images} ''; Loading @@ -294,7 +312,11 @@ rec { You must accept the following licenses: ${lib.concatMapStringsSep "\n" (str: " - ${str}") licenseNames} a) by setting nixpkgs config option 'android_sdk.accept_license = true;'. b) by an environment variable for a single invocation of the nix tools. $ export NIXPKGS_ACCEPT_ANDROID_SDK_LICENSE=1 '' else callPackage ./cmdline-tools.nix { inherit deployAndroidPackage os cmdLineToolsVersion; Loading pkgs/development/mobile/androidenv/default.nix +1 −1 Original line number Diff line number Diff line { config, pkgs ? import <nixpkgs> {} , licenseAccepted ? config.android_sdk.accept_license or false , licenseAccepted ? config.android_sdk.accept_license or (builtins.getEnv "NIXPKGS_ACCEPT_ANDROID_SDK_LICENSE" == "1") }: rec { Loading pkgs/development/mobile/androidenv/emulate-app.nix +50 −18 Original line number Diff line number Diff line { composeAndroidPackages, stdenv, lib, runtimeShell }: { name, app ? null , platformVersion ? "16", abiVersion ? "armeabi-v7a", systemImageType ? "default" , enableGPU ? false, extraAVDFiles ? [] , package ? null, activity ? null , avdHomeDir ? null, sdkExtraArgs ? {} , platformVersion ? "33" , abiVersion ? "armeabi-v7a" , systemImageType ? "default" , enableGPU ? false , extraAVDFiles ? [] , package ? null , activity ? null , androidUserHome ? null , avdHomeDir ? null # Support old variable with non-standard naming! , androidAvdHome ? avdHomeDir , sdkExtraArgs ? {} , androidAvdFlags ? null , androidEmulatorFlags ? null }: let sdkArgs = { toolsVersion = "26.1.1"; platformVersions = [ platformVersion ]; includeEmulator = true; includeSystemImages = true; } // sdkExtraArgs // { cmdLineToolsVersion = "8.0"; platformVersions = [ platformVersion ]; systemImageTypes = [ systemImageType ]; abiVersions = [ abiVersion ]; } // sdkExtraArgs; }; sdk = (composeAndroidPackages sdkArgs).androidsdk; in Loading @@ -33,24 +43,45 @@ stdenv.mkDerivation { export TMPDIR=/tmp fi ${if avdHomeDir == null then '' ${if androidUserHome == null then '' # Store the virtual devices somewhere else, instead of polluting a user's HOME directory export ANDROID_SDK_HOME=$(mktemp -d $TMPDIR/nix-android-vm-XXXX) export ANDROID_USER_HOME=$(mktemp -d $TMPDIR/nix-android-user-home-XXXX) '' else '' mkdir -p "${androidUserHome}" export ANDROID_USER_HOME="${androidUserHome}" ''} ${if androidAvdHome == null then '' export ANDROID_AVD_HOME=$ANDROID_USER_HOME/avd '' else '' mkdir -p "${avdHomeDir}" export ANDROID_SDK_HOME="${avdHomeDir}" mkdir -p "${androidAvdHome}" export ANDROID_AVD_HOME="${androidAvdHome}" ''} # We need to specify the location of the Android SDK root folder export ANDROID_SDK_ROOT=${sdk}/libexec/android-sdk ${lib.optionalString (androidAvdFlags != null) '' # If NIX_ANDROID_AVD_FLAGS is empty if [[ -z "$NIX_ANDROID_AVD_FLAGS" ]]; then NIX_ANDROID_AVD_FLAGS="${androidAvdFlags}" fi ''} ${lib.optionalString (androidEmulatorFlags != null) '' # If NIX_ANDROID_EMULATOR_FLAGS is empty if [[ -z "$NIX_ANDROID_EMULATOR_FLAGS" ]]; then NIX_ANDROID_EMULATOR_FLAGS="${androidEmulatorFlags}" fi ''} # We have to look for a free TCP port echo "Looking for a free TCP port in range 5554-5584" >&2 for i in $(seq 5554 2 5584) do if [ -z "$(${sdk}/libexec/android-sdk/platform-tools/adb devices | grep emulator-$i)" ] if [ -z "$(${sdk}/bin/adb devices | grep emulator-$i)" ] then port=$i break Loading @@ -68,25 +99,26 @@ stdenv.mkDerivation { export ANDROID_SERIAL="emulator-$port" # Create a virtual android device for testing if it does not exist ${sdk}/libexec/android-sdk/tools/bin/avdmanager list target ${sdk}/bin/avdmanager list target if [ "$(${sdk}/libexec/android-sdk/tools/android list avd | grep 'Name: device')" = "" ] if [ "$(${sdk}/bin/avdmanager list avd | grep 'Name: device')" = "" ] then # Create a virtual android device yes "" | ${sdk}/libexec/android-sdk/tools/bin/avdmanager create avd -n device -k "system-images;android-${platformVersion};${systemImageType};${abiVersion}" $NIX_ANDROID_AVD_FLAGS yes "" | ${sdk}/bin/avdmanager create avd --force -n device -k "system-images;android-${platformVersion};${systemImageType};${abiVersion}" -p $ANDROID_AVD_HOME $NIX_ANDROID_AVD_FLAGS ${lib.optionalString enableGPU '' # Enable GPU acceleration echo "hw.gpu.enabled=yes" >> $ANDROID_SDK_HOME/.android/avd/device.avd/config.ini echo "hw.gpu.enabled=yes" >> $ANDROID_AVD_HOME/device.avd/config.ini ''} ${lib.concatMapStrings (extraAVDFile: '' ln -sf ${extraAVDFile} $ANDROID_SDK_HOME/.android/avd/device.avd ln -sf ${extraAVDFile} $ANDROID_AVD_HOME/device.avd '') extraAVDFiles} fi # Launch the emulator ${sdk}/libexec/android-sdk/emulator/emulator -avd device -no-boot-anim -port $port $NIX_ANDROID_EMULATOR_FLAGS & echo "\nLaunch the emulator" $ANDROID_SDK_ROOT/emulator/emulator -avd device -no-boot-anim -port $port $NIX_ANDROID_EMULATOR_FLAGS & # Wait until the device has completely booted echo "Waiting until the emulator has booted the device and the package manager is ready..." >&2 Loading pkgs/development/mobile/androidenv/examples/shell-with-emulator.nix 0 → 100644 +151 −0 Original line number Diff line number Diff line { # To test your changes in androidEnv run `nix-shell android-sdk-with-emulator-shell.nix` # If you copy this example out of nixpkgs, use these lines instead of the next. # This example pins nixpkgs: https://nix.dev/tutorials/towards-reproducibility-pinning-nixpkgs.html /*nixpkgsSource ? (builtins.fetchTarball { name = "nixpkgs-20.09"; url = "https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz"; sha256 = "1wg61h4gndm3vcprdcg7rc4s1v3jkm5xd7lw8r2f67w502y94gcy"; }), pkgs ? import nixpkgsSource { config.allowUnfree = true; }, */ # If you want to use the in-tree version of nixpkgs: pkgs ? import ../../../../.. { config.allowUnfree = true; }, config ? pkgs.config }: # Copy this file to your Android project. let # Declaration of versions for everything. This is useful since these # versions may be used in multiple places in this Nix expression. android = { platforms = [ "33" ]; systemImageTypes = [ "google_apis" ]; abis = [ "arm64-v8a" "x86_64" ]; }; # If you copy this example out of nixpkgs, something like this will work: /*androidEnvNixpkgs = fetchTarball { name = "androidenv"; url = "https://github.com/NixOS/nixpkgs/archive/<fill me in from Git>.tar.gz"; sha256 = "<fill me in with nix-prefetch-url --unpack>"; }; androidEnv = pkgs.callPackage "${androidEnvNixpkgs}/pkgs/development/mobile/androidenv" { inherit config pkgs; licenseAccepted = true; };*/ # Otherwise, just use the in-tree androidenv: androidEnv = pkgs.callPackage ./.. { inherit config pkgs; # You probably need to uncomment below line to express consent. # licenseAccepted = true; }; sdkArgs = { platformVersions = android.platforms; abiVersions = android.abis; systemImageTypes = android.systemImageTypes; includeSystemImages = true; includeEmulator = true; # Accepting more licenses declaratively: extraLicenses = [ # Already accepted for you with the global accept_license = true or # licenseAccepted = true on androidenv. # "android-sdk-license" # These aren't, but are useful for more uncommon setups. "android-sdk-preview-license" "android-googletv-license" "android-sdk-arm-dbt-license" "google-gdk-license" "intel-android-extra-license" "intel-android-sysimage-license" "mips-android-sysimage-license" ]; }; androidComposition = androidEnv.composeAndroidPackages sdkArgs; androidEmulator = androidEnv.emulateApp { name = "android-sdk-emulator-demo"; sdkExtraArgs = sdkArgs; }; androidSdk = androidComposition.androidsdk; platformTools = androidComposition.platform-tools; jdk = pkgs.jdk; in pkgs.mkShell rec { name = "androidenv-demo"; packages = [ androidSdk platformTools androidEmulator jdk pkgs.android-studio ]; LANG = "C.UTF-8"; LC_ALL = "C.UTF-8"; JAVA_HOME = jdk.home; # Note: ANDROID_HOME is deprecated. Use ANDROID_SDK_ROOT. ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk"; ANDROID_NDK_ROOT = "${ANDROID_SDK_ROOT}/ndk-bundle"; shellHook = '' # Write out local.properties for Android Studio. cat <<EOF > local.properties # This file was automatically generated by nix-shell. sdk.dir=$ANDROID_SDK_ROOT ndk.dir=$ANDROID_NDK_ROOT EOF ''; passthru.tests = { shell-with-emulator-sdkmanager-packages-test = pkgs.runCommand "shell-with-emulator-sdkmanager-packages-test" { nativeBuildInputs = [ androidSdk jdk ]; } '' output="$(sdkmanager --list)" installed_packages_section=$(echo "''${output%%Available Packages*}" | awk 'NR>4 {print $1}') echo "installed_packages_section: ''${installed_packages_section}" packages=( "build-tools;33.0.1" "cmdline-tools;8.0" \ "emulator" "patcher;v4" "platform-tools" "platforms;android-33" \ "system-images;android-33;google_apis;arm64-v8a" \ "system-images;android-33;google_apis;x86_64" ) for package in "''${packages[@]}"; do if [[ ! $installed_packages_section =~ "$package" ]]; then echo "$package package was not installed." exit 1 fi done touch "$out" ''; shell-with-emulator-avdmanager-create-avd-test = pkgs.runCommand "shell-with-emulator-avdmanager-create-avd-test" { nativeBuildInputs = [ androidSdk androidEmulator jdk ]; } '' avdmanager delete avd -n testAVD || true echo "" | avdmanager create avd --force --name testAVD --package 'system-images;android-33;google_apis;x86_64' result=$(avdmanager list avd) if [[ ! $result =~ "Name: testAVD" ]]; then echo "avdmanager couldn't create the avd! The output is :''${result}" exit 1 fi avdmanager delete avd -n testAVD || true touch "$out" ''; }; } Loading
pkgs/development/mobile/androidenv/.gitignore +1 −0 Original line number Diff line number Diff line /xml local.properties .android
pkgs/development/mobile/androidenv/compose-android-packages.nix +37 −15 Original line number Diff line number Diff line Loading @@ -185,20 +185,38 @@ rec { system-images = lib.flatten (map (apiVersion: map (type: map (abiVersion: lib.optionals (lib.hasAttrByPath [apiVersion type abiVersion] system-images-packages) ( deployAndroidPackage { inherit os; package = system-images-packages.${apiVersion}.${type}.${abiVersion}; # Deploy all system images with the same systemImageType in one derivation to avoid the `null` problem below # with avdmanager when trying to create an avd! # # ``` # $ yes "" | avdmanager create avd --force --name testAVD --package 'system-images;android-33;google_apis;x86_64' # Error: Package path is not valid. Valid system image paths are: # null # ``` let availablePackages = map (abiVersion: system-images-packages.${apiVersion}.${type}.${abiVersion} ) (builtins.filter (abiVersion: lib.hasAttrByPath [apiVersion type abiVersion] system-images-packages ) abiVersions); instructions = builtins.listToAttrs (map (package: { name = package.name; value = lib.optionalString (lib.hasPrefix "google_apis" type) '' # Patch 'google_apis' system images so they're recognized by the sdk. # Without this, `android list targets` shows 'Tag/ABIs : no ABIs' instead # of 'Tag/ABIs : google_apis*/*' and the emulator fails with an ABI-related error. patchInstructions = lib.optionalString (lib.hasPrefix "google_apis" type) '' sed -i '/^Addon.Vendor/d' source.properties ''; } ) ) abiVersions }) availablePackages ); in lib.optionals (availablePackages != []) (deployAndroidPackages { inherit os; packages = availablePackages; patchesInstructions = instructions; }) ) systemImageTypes ) platformVersions); Loading Loading @@ -271,8 +289,8 @@ rec { ${lib.concatMapStrings (system-image: '' apiVersion=$(basename $(echo ${system-image}/libexec/android-sdk/system-images/*)) type=$(basename $(echo ${system-image}/libexec/android-sdk/system-images/*/*)) mkdir -p system-images/$apiVersion/$type ln -s ${system-image}/libexec/android-sdk/system-images/$apiVersion/$type/* system-images/$apiVersion/$type mkdir -p system-images/$apiVersion ln -s ${system-image}/libexec/android-sdk/system-images/$apiVersion/$type system-images/$apiVersion/$type '') images} ''; Loading @@ -294,7 +312,11 @@ rec { You must accept the following licenses: ${lib.concatMapStringsSep "\n" (str: " - ${str}") licenseNames} a) by setting nixpkgs config option 'android_sdk.accept_license = true;'. b) by an environment variable for a single invocation of the nix tools. $ export NIXPKGS_ACCEPT_ANDROID_SDK_LICENSE=1 '' else callPackage ./cmdline-tools.nix { inherit deployAndroidPackage os cmdLineToolsVersion; Loading
pkgs/development/mobile/androidenv/default.nix +1 −1 Original line number Diff line number Diff line { config, pkgs ? import <nixpkgs> {} , licenseAccepted ? config.android_sdk.accept_license or false , licenseAccepted ? config.android_sdk.accept_license or (builtins.getEnv "NIXPKGS_ACCEPT_ANDROID_SDK_LICENSE" == "1") }: rec { Loading
pkgs/development/mobile/androidenv/emulate-app.nix +50 −18 Original line number Diff line number Diff line { composeAndroidPackages, stdenv, lib, runtimeShell }: { name, app ? null , platformVersion ? "16", abiVersion ? "armeabi-v7a", systemImageType ? "default" , enableGPU ? false, extraAVDFiles ? [] , package ? null, activity ? null , avdHomeDir ? null, sdkExtraArgs ? {} , platformVersion ? "33" , abiVersion ? "armeabi-v7a" , systemImageType ? "default" , enableGPU ? false , extraAVDFiles ? [] , package ? null , activity ? null , androidUserHome ? null , avdHomeDir ? null # Support old variable with non-standard naming! , androidAvdHome ? avdHomeDir , sdkExtraArgs ? {} , androidAvdFlags ? null , androidEmulatorFlags ? null }: let sdkArgs = { toolsVersion = "26.1.1"; platformVersions = [ platformVersion ]; includeEmulator = true; includeSystemImages = true; } // sdkExtraArgs // { cmdLineToolsVersion = "8.0"; platformVersions = [ platformVersion ]; systemImageTypes = [ systemImageType ]; abiVersions = [ abiVersion ]; } // sdkExtraArgs; }; sdk = (composeAndroidPackages sdkArgs).androidsdk; in Loading @@ -33,24 +43,45 @@ stdenv.mkDerivation { export TMPDIR=/tmp fi ${if avdHomeDir == null then '' ${if androidUserHome == null then '' # Store the virtual devices somewhere else, instead of polluting a user's HOME directory export ANDROID_SDK_HOME=$(mktemp -d $TMPDIR/nix-android-vm-XXXX) export ANDROID_USER_HOME=$(mktemp -d $TMPDIR/nix-android-user-home-XXXX) '' else '' mkdir -p "${androidUserHome}" export ANDROID_USER_HOME="${androidUserHome}" ''} ${if androidAvdHome == null then '' export ANDROID_AVD_HOME=$ANDROID_USER_HOME/avd '' else '' mkdir -p "${avdHomeDir}" export ANDROID_SDK_HOME="${avdHomeDir}" mkdir -p "${androidAvdHome}" export ANDROID_AVD_HOME="${androidAvdHome}" ''} # We need to specify the location of the Android SDK root folder export ANDROID_SDK_ROOT=${sdk}/libexec/android-sdk ${lib.optionalString (androidAvdFlags != null) '' # If NIX_ANDROID_AVD_FLAGS is empty if [[ -z "$NIX_ANDROID_AVD_FLAGS" ]]; then NIX_ANDROID_AVD_FLAGS="${androidAvdFlags}" fi ''} ${lib.optionalString (androidEmulatorFlags != null) '' # If NIX_ANDROID_EMULATOR_FLAGS is empty if [[ -z "$NIX_ANDROID_EMULATOR_FLAGS" ]]; then NIX_ANDROID_EMULATOR_FLAGS="${androidEmulatorFlags}" fi ''} # We have to look for a free TCP port echo "Looking for a free TCP port in range 5554-5584" >&2 for i in $(seq 5554 2 5584) do if [ -z "$(${sdk}/libexec/android-sdk/platform-tools/adb devices | grep emulator-$i)" ] if [ -z "$(${sdk}/bin/adb devices | grep emulator-$i)" ] then port=$i break Loading @@ -68,25 +99,26 @@ stdenv.mkDerivation { export ANDROID_SERIAL="emulator-$port" # Create a virtual android device for testing if it does not exist ${sdk}/libexec/android-sdk/tools/bin/avdmanager list target ${sdk}/bin/avdmanager list target if [ "$(${sdk}/libexec/android-sdk/tools/android list avd | grep 'Name: device')" = "" ] if [ "$(${sdk}/bin/avdmanager list avd | grep 'Name: device')" = "" ] then # Create a virtual android device yes "" | ${sdk}/libexec/android-sdk/tools/bin/avdmanager create avd -n device -k "system-images;android-${platformVersion};${systemImageType};${abiVersion}" $NIX_ANDROID_AVD_FLAGS yes "" | ${sdk}/bin/avdmanager create avd --force -n device -k "system-images;android-${platformVersion};${systemImageType};${abiVersion}" -p $ANDROID_AVD_HOME $NIX_ANDROID_AVD_FLAGS ${lib.optionalString enableGPU '' # Enable GPU acceleration echo "hw.gpu.enabled=yes" >> $ANDROID_SDK_HOME/.android/avd/device.avd/config.ini echo "hw.gpu.enabled=yes" >> $ANDROID_AVD_HOME/device.avd/config.ini ''} ${lib.concatMapStrings (extraAVDFile: '' ln -sf ${extraAVDFile} $ANDROID_SDK_HOME/.android/avd/device.avd ln -sf ${extraAVDFile} $ANDROID_AVD_HOME/device.avd '') extraAVDFiles} fi # Launch the emulator ${sdk}/libexec/android-sdk/emulator/emulator -avd device -no-boot-anim -port $port $NIX_ANDROID_EMULATOR_FLAGS & echo "\nLaunch the emulator" $ANDROID_SDK_ROOT/emulator/emulator -avd device -no-boot-anim -port $port $NIX_ANDROID_EMULATOR_FLAGS & # Wait until the device has completely booted echo "Waiting until the emulator has booted the device and the package manager is ready..." >&2 Loading
pkgs/development/mobile/androidenv/examples/shell-with-emulator.nix 0 → 100644 +151 −0 Original line number Diff line number Diff line { # To test your changes in androidEnv run `nix-shell android-sdk-with-emulator-shell.nix` # If you copy this example out of nixpkgs, use these lines instead of the next. # This example pins nixpkgs: https://nix.dev/tutorials/towards-reproducibility-pinning-nixpkgs.html /*nixpkgsSource ? (builtins.fetchTarball { name = "nixpkgs-20.09"; url = "https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz"; sha256 = "1wg61h4gndm3vcprdcg7rc4s1v3jkm5xd7lw8r2f67w502y94gcy"; }), pkgs ? import nixpkgsSource { config.allowUnfree = true; }, */ # If you want to use the in-tree version of nixpkgs: pkgs ? import ../../../../.. { config.allowUnfree = true; }, config ? pkgs.config }: # Copy this file to your Android project. let # Declaration of versions for everything. This is useful since these # versions may be used in multiple places in this Nix expression. android = { platforms = [ "33" ]; systemImageTypes = [ "google_apis" ]; abis = [ "arm64-v8a" "x86_64" ]; }; # If you copy this example out of nixpkgs, something like this will work: /*androidEnvNixpkgs = fetchTarball { name = "androidenv"; url = "https://github.com/NixOS/nixpkgs/archive/<fill me in from Git>.tar.gz"; sha256 = "<fill me in with nix-prefetch-url --unpack>"; }; androidEnv = pkgs.callPackage "${androidEnvNixpkgs}/pkgs/development/mobile/androidenv" { inherit config pkgs; licenseAccepted = true; };*/ # Otherwise, just use the in-tree androidenv: androidEnv = pkgs.callPackage ./.. { inherit config pkgs; # You probably need to uncomment below line to express consent. # licenseAccepted = true; }; sdkArgs = { platformVersions = android.platforms; abiVersions = android.abis; systemImageTypes = android.systemImageTypes; includeSystemImages = true; includeEmulator = true; # Accepting more licenses declaratively: extraLicenses = [ # Already accepted for you with the global accept_license = true or # licenseAccepted = true on androidenv. # "android-sdk-license" # These aren't, but are useful for more uncommon setups. "android-sdk-preview-license" "android-googletv-license" "android-sdk-arm-dbt-license" "google-gdk-license" "intel-android-extra-license" "intel-android-sysimage-license" "mips-android-sysimage-license" ]; }; androidComposition = androidEnv.composeAndroidPackages sdkArgs; androidEmulator = androidEnv.emulateApp { name = "android-sdk-emulator-demo"; sdkExtraArgs = sdkArgs; }; androidSdk = androidComposition.androidsdk; platformTools = androidComposition.platform-tools; jdk = pkgs.jdk; in pkgs.mkShell rec { name = "androidenv-demo"; packages = [ androidSdk platformTools androidEmulator jdk pkgs.android-studio ]; LANG = "C.UTF-8"; LC_ALL = "C.UTF-8"; JAVA_HOME = jdk.home; # Note: ANDROID_HOME is deprecated. Use ANDROID_SDK_ROOT. ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk"; ANDROID_NDK_ROOT = "${ANDROID_SDK_ROOT}/ndk-bundle"; shellHook = '' # Write out local.properties for Android Studio. cat <<EOF > local.properties # This file was automatically generated by nix-shell. sdk.dir=$ANDROID_SDK_ROOT ndk.dir=$ANDROID_NDK_ROOT EOF ''; passthru.tests = { shell-with-emulator-sdkmanager-packages-test = pkgs.runCommand "shell-with-emulator-sdkmanager-packages-test" { nativeBuildInputs = [ androidSdk jdk ]; } '' output="$(sdkmanager --list)" installed_packages_section=$(echo "''${output%%Available Packages*}" | awk 'NR>4 {print $1}') echo "installed_packages_section: ''${installed_packages_section}" packages=( "build-tools;33.0.1" "cmdline-tools;8.0" \ "emulator" "patcher;v4" "platform-tools" "platforms;android-33" \ "system-images;android-33;google_apis;arm64-v8a" \ "system-images;android-33;google_apis;x86_64" ) for package in "''${packages[@]}"; do if [[ ! $installed_packages_section =~ "$package" ]]; then echo "$package package was not installed." exit 1 fi done touch "$out" ''; shell-with-emulator-avdmanager-create-avd-test = pkgs.runCommand "shell-with-emulator-avdmanager-create-avd-test" { nativeBuildInputs = [ androidSdk androidEmulator jdk ]; } '' avdmanager delete avd -n testAVD || true echo "" | avdmanager create avd --force --name testAVD --package 'system-images;android-33;google_apis;x86_64' result=$(avdmanager list avd) if [[ ! $result =~ "Name: testAVD" ]]; then echo "avdmanager couldn't create the avd! The output is :''${result}" exit 1 fi avdmanager delete avd -n testAVD || true touch "$out" ''; }; }