Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{ composeAndroidPackages, stdenv, lib, runtimeShell }: 2{ name, app ? null 3, platformVersion ? "33" 4, abiVersion ? "armeabi-v7a" 5, systemImageType ? "default" 6, enableGPU ? false 7, extraAVDFiles ? [] 8, package ? null 9, activity ? null 10, androidUserHome ? null 11, avdHomeDir ? null # Support old variable with non-standard naming! 12, androidAvdHome ? avdHomeDir 13, sdkExtraArgs ? {} 14, androidAvdFlags ? null 15, androidEmulatorFlags ? null 16}: 17 18let 19 sdkArgs = { 20 includeEmulator = true; 21 includeSystemImages = true; 22 } // sdkExtraArgs // { 23 cmdLineToolsVersion = "8.0"; 24 platformVersions = [ platformVersion ]; 25 systemImageTypes = [ systemImageType ]; 26 abiVersions = [ abiVersion ]; 27 }; 28 29 sdk = (composeAndroidPackages sdkArgs).androidsdk; 30in 31stdenv.mkDerivation { 32 inherit name; 33 34 buildCommand = '' 35 mkdir -p $out/bin 36 37 cat > $out/bin/run-test-emulator << "EOF" 38 #!${runtimeShell} -e 39 40 # We need a TMPDIR 41 if [ "$TMPDIR" = "" ] 42 then 43 export TMPDIR=/tmp 44 fi 45 46 ${if androidUserHome == null then '' 47 # Store the virtual devices somewhere else, instead of polluting a user's HOME directory 48 export ANDROID_USER_HOME=$(mktemp -d $TMPDIR/nix-android-user-home-XXXX) 49 '' else '' 50 mkdir -p "${androidUserHome}" 51 export ANDROID_USER_HOME="${androidUserHome}" 52 ''} 53 54 ${if androidAvdHome == null then '' 55 export ANDROID_AVD_HOME=$ANDROID_USER_HOME/avd 56 '' else '' 57 mkdir -p "${androidAvdHome}" 58 export ANDROID_AVD_HOME="${androidAvdHome}" 59 ''} 60 61 # We need to specify the location of the Android SDK root folder 62 export ANDROID_SDK_ROOT=${sdk}/libexec/android-sdk 63 64 ${lib.optionalString (androidAvdFlags != null) '' 65 # If NIX_ANDROID_AVD_FLAGS is empty 66 if [[ -z "$NIX_ANDROID_AVD_FLAGS" ]]; then 67 NIX_ANDROID_AVD_FLAGS="${androidAvdFlags}" 68 fi 69 ''} 70 71 ${lib.optionalString (androidEmulatorFlags != null) '' 72 # If NIX_ANDROID_EMULATOR_FLAGS is empty 73 if [[ -z "$NIX_ANDROID_EMULATOR_FLAGS" ]]; then 74 NIX_ANDROID_EMULATOR_FLAGS="${androidEmulatorFlags}" 75 fi 76 ''} 77 78 # We have to look for a free TCP port 79 80 echo "Looking for a free TCP port in range 5554-5584" >&2 81 82 for i in $(seq 5554 2 5584) 83 do 84 if [ -z "$(${sdk}/bin/adb devices | grep emulator-$i)" ] 85 then 86 port=$i 87 break 88 fi 89 done 90 91 if [ -z "$port" ] 92 then 93 echo "Unfortunately, the emulator port space is exhausted!" >&2 94 exit 1 95 else 96 echo "We have a free TCP port: $port" >&2 97 fi 98 99 export ANDROID_SERIAL="emulator-$port" 100 101 # Create a virtual android device for testing if it does not exist 102 ${sdk}/bin/avdmanager list target 103 104 if [ "$(${sdk}/bin/avdmanager list avd | grep 'Name: device')" = "" ] 105 then 106 # Create a virtual android device 107 yes "" | ${sdk}/bin/avdmanager create avd --force -n device -k "system-images;android-${platformVersion};${systemImageType};${abiVersion}" -p $ANDROID_AVD_HOME $NIX_ANDROID_AVD_FLAGS 108 109 ${lib.optionalString enableGPU '' 110 # Enable GPU acceleration 111 echo "hw.gpu.enabled=yes" >> $ANDROID_AVD_HOME/device.avd/config.ini 112 ''} 113 114 ${lib.concatMapStrings (extraAVDFile: '' 115 ln -sf ${extraAVDFile} $ANDROID_AVD_HOME/device.avd 116 '') extraAVDFiles} 117 fi 118 119 # Launch the emulator 120 echo "\nLaunch the emulator" 121 $ANDROID_SDK_ROOT/emulator/emulator -avd device -no-boot-anim -port $port $NIX_ANDROID_EMULATOR_FLAGS & 122 123 # Wait until the device has completely booted 124 echo "Waiting until the emulator has booted the device and the package manager is ready..." >&2 125 126 ${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port wait-for-device 127 128 echo "Device state has been reached" >&2 129 130 while [ -z "$(${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell getprop dev.bootcomplete | grep 1)" ] 131 do 132 sleep 5 133 done 134 135 echo "dev.bootcomplete property is 1" >&2 136 137 #while [ -z "$(${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell getprop sys.boot_completed | grep 1)" ] 138 #do 139 #sleep 5 140 #done 141 142 #echo "sys.boot_completed property is 1" >&2 143 144 echo "ready" >&2 145 146 ${lib.optionalString (app != null) '' 147 # Install the App through the debugger, if it has not been installed yet 148 149 if [ -z "${package}" ] || [ "$(${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell pm list packages | grep package:${package})" = "" ] 150 then 151 if [ -d "${app}" ] 152 then 153 appPath="$(echo ${app}/*.apk)" 154 else 155 appPath="${app}" 156 fi 157 158 ${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port install "$appPath" 159 fi 160 161 # Start the application 162 ${lib.optionalString (package != null && activity != null) '' 163 ${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell am start -a android.intent.action.MAIN -n ${package}/${activity} 164 ''} 165 ''} 166 EOF 167 chmod +x $out/bin/run-test-emulator 168 ''; 169}