1{
2 # To test your changes in androidEnv run `nix-shell android-sdk-with-emulator-shell.nix`
3
4 # If you copy this example out of nixpkgs, use these lines instead of the next.
5 # This example pins nixpkgs: https://nix.dev/tutorials/first-steps/towards-reproducibility-pinning-nixpkgs.html
6 /*
7 nixpkgsSource ? (builtins.fetchTarball {
8 name = "nixpkgs-20.09";
9 url = "https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz";
10 sha256 = "1wg61h4gndm3vcprdcg7rc4s1v3jkm5xd7lw8r2f67w502y94gcy";
11 }),
12 pkgs ? import nixpkgsSource {
13 config.allowUnfree = true;
14 },
15 */
16
17 # If you want to use the in-tree version of nixpkgs:
18 pkgs ? import ../../../../.. {
19 config.allowUnfree = true;
20 },
21
22 # You probably need to set it to true to express consent.
23 licenseAccepted ? pkgs.callPackage ../license.nix { },
24}:
25
26# Copy this file to your Android project.
27let
28 # If you copy this example out of nixpkgs, something like this will work:
29 /*
30 androidEnvNixpkgs = fetchTarball {
31 name = "androidenv";
32 url = "https://github.com/NixOS/nixpkgs/archive/<fill me in from Git>.tar.gz";
33 sha256 = "<fill me in with nix-prefetch-url --unpack>";
34 };
35
36 androidEnv = pkgs.callPackage "${androidEnvNixpkgs}/pkgs/development/mobile/androidenv" {
37 inherit pkgs;
38 licenseAccepted = true;
39 };
40 */
41
42 # Otherwise, just use the in-tree androidenv:
43 androidEnv = pkgs.callPackage ./.. {
44 inherit pkgs licenseAccepted;
45 };
46
47 emulatorSupported = pkgs.stdenv.hostPlatform.isx86_64 || pkgs.stdenv.hostPlatform.isDarwin;
48
49 sdkArgs = {
50 includeSystemImages = true;
51 includeEmulator = "if-supported";
52
53 # Accepting more licenses declaratively:
54 extraLicenses = [
55 # Already accepted for you with the global accept_license = true or
56 # licenseAccepted = true on androidenv.
57 # "android-sdk-license"
58
59 # These aren't, but are useful for more uncommon setups.
60 "android-sdk-preview-license"
61 "android-googletv-license"
62 "android-sdk-arm-dbt-license"
63 "google-gdk-license"
64 "intel-android-extra-license"
65 "intel-android-sysimage-license"
66 "mips-android-sysimage-license"
67 ];
68 };
69
70 androidComposition = androidEnv.composeAndroidPackages sdkArgs;
71 androidEmulator = androidEnv.emulateApp {
72 name = "android-sdk-emulator-demo";
73 configOptions = {
74 "hw.keyboard" = "yes";
75 };
76 sdkExtraArgs = sdkArgs;
77 };
78 androidSdk = androidComposition.androidsdk;
79 platformTools = androidComposition.platform-tools;
80 latestSdk = pkgs.lib.foldl' pkgs.lib.max 0 androidComposition.platformVersions;
81 jdk = pkgs.jdk;
82in
83pkgs.mkShell rec {
84 name = "androidenv-demo";
85 packages = [
86 androidSdk
87 platformTools
88 androidEmulator
89 jdk
90 ];
91
92 LANG = "C.UTF-8";
93 LC_ALL = "C.UTF-8";
94 JAVA_HOME = jdk.home;
95
96 # Note: ANDROID_HOME is deprecated. Use ANDROID_SDK_ROOT.
97 ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk";
98 ANDROID_NDK_ROOT = "${ANDROID_SDK_ROOT}/ndk-bundle";
99
100 shellHook = ''
101 # Write out local.properties for Android Studio.
102 cat <<EOF > local.properties
103 # This file was automatically generated by nix-shell.
104 sdk.dir=$ANDROID_SDK_ROOT
105 ndk.dir=$ANDROID_NDK_ROOT
106 EOF
107 '';
108
109 passthru.tests = {
110
111 shell-with-emulator-sdkmanager-packages-test =
112 pkgs.runCommand "shell-with-emulator-sdkmanager-packages-test"
113 {
114 nativeBuildInputs = [
115 androidSdk
116 jdk
117 ];
118 }
119 ''
120 output="$(sdkmanager --list)"
121 installed_packages_section=$(echo "''${output%%Available Packages*}" | awk 'NR>4 {print $1}')
122 echo "installed_packages_section: ''${installed_packages_section}"
123
124 packages=(
125 "build-tools" "cmdline-tools" \
126 "platform-tools" "platforms;android-${toString latestSdk}" \
127 "system-images;android-${toString latestSdk};google_apis;x86_64"
128 )
129 ${pkgs.lib.optionalString emulatorSupported ''packages+=("emulator")''}
130
131 for package in "''${packages[@]}"; do
132 if [[ ! $installed_packages_section =~ "$package" ]]; then
133 echo "$package package was not installed."
134 exit 1
135 fi
136 done
137
138 touch "$out"
139 '';
140
141 shell-with-emulator-sdkmanager-excluded-packages-test =
142 pkgs.runCommand "shell-with-emulator-sdkmanager-excluded-packages-test"
143 {
144 nativeBuildInputs = [
145 androidSdk
146 jdk
147 ];
148 }
149 ''
150 output="$(sdkmanager --list)"
151 installed_packages_section=$(echo "''${output%%Available Packages*}" | awk 'NR>4 {print $1}')
152
153 excluded_packages=(ndk)
154 for x in $(seq 1 ${toString latestSdk}); do
155 excluded_packages+=(
156 "platforms;android-$x"
157 "sources;android-$x"
158 "system-images;android-$x"
159 )
160 done
161
162 for package in "''${excluded_packages[@]}"; do
163 if [[ $installed_packages_section =~ ^"$package"$ ]]; then
164 echo "$package package was installed, while it was excluded!"
165 exit 1
166 fi
167 done
168
169 touch "$out"
170 '';
171
172 shell-with-emulator-avdmanager-create-avd-test =
173 pkgs.runCommand "shell-with-emulator-avdmanager-create-avd-test"
174 {
175 nativeBuildInputs = [
176 androidSdk
177 androidEmulator
178 jdk
179 ];
180 }
181 (
182 pkgs.lib.optionalString emulatorSupported ''
183 export ANDROID_USER_HOME=$PWD/.android
184 mkdir -p $ANDROID_USER_HOME
185
186 avdmanager delete avd -n testAVD || true
187 echo "" | avdmanager create avd --force --name testAVD --package 'system-images;android-${toString latestSdk};google_apis;x86_64'
188 result=$(avdmanager list avd)
189
190 if [[ ! $result =~ "Name: testAVD" ]]; then
191 echo "avdmanager couldn't create the avd! The output is :''${result}"
192 exit 1
193 fi
194
195 avdmanager delete avd -n testAVD || true
196 ''
197 + ''
198 touch $out
199 ''
200 );
201 };
202}