androidenv: add shell-with-emulator.nix to have test and more examples
androidenv: replace buildInputs with nativeBuildInputs
This commit is contained in:
parent
e5fbfd894f
commit
d511bfd0e2
|
@ -1,2 +1,3 @@
|
|||
/xml
|
||||
local.properties
|
||||
.android
|
||||
|
|
|
@ -188,9 +188,11 @@ rec {
|
|||
# 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}
|
||||
|
|
|
@ -1,20 +1,30 @@
|
|||
{ 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
|
||||
|
@ -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 "${avdHomeDir}"
|
||||
export ANDROID_SDK_HOME="${avdHomeDir}"
|
||||
mkdir -p "${androidUserHome}"
|
||||
export ANDROID_USER_HOME="${androidUserHome}"
|
||||
''}
|
||||
|
||||
${if androidAvdHome == null then ''
|
||||
export ANDROID_AVD_HOME=$ANDROID_USER_HOME/avd
|
||||
'' else ''
|
||||
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
|
||||
|
@ -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
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
{
|
||||
# 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;
|
||||
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"
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -146,8 +146,9 @@ pkgs.mkShell rec {
|
|||
'';
|
||||
|
||||
passthru.tests = {
|
||||
sdkmanager-licenses-test = pkgs.runCommand "sdkmanager-licenses-test" {
|
||||
buildInputs = [ androidSdk jdk ];
|
||||
|
||||
shell-sdkmanager-licenses-test = pkgs.runCommand "shell-sdkmanager-licenses-test" {
|
||||
nativeBuildInputs = [ androidSdk jdk ];
|
||||
} ''
|
||||
if [[ ! "$(sdkmanager --licenses)" =~ "All SDK package licenses accepted." ]]; then
|
||||
echo "At least one of SDK package licenses are not accepted."
|
||||
|
@ -156,8 +157,8 @@ pkgs.mkShell rec {
|
|||
touch $out
|
||||
'';
|
||||
|
||||
sdkmanager-packages-test = pkgs.runCommand "sdkmanager-packages-test" {
|
||||
buildInputs = [ androidSdk jdk ];
|
||||
shell-sdkmanager-packages-test = pkgs.runCommand "shell-sdkmanager-packages-test" {
|
||||
nativeBuildInputs = [ androidSdk jdk ];
|
||||
} ''
|
||||
output="$(sdkmanager --list)"
|
||||
installed_packages_section=$(echo "''${output%%Available Packages*}" | awk 'NR>4 {print $1}')
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{ stdenv, callPackage }:
|
||||
let
|
||||
examples-shell = callPackage ./examples/shell.nix {};
|
||||
examples-shell-with-emulator = callPackage ./examples/shell-with-emulator.nix {};
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
name = "androidenv-test-suite";
|
||||
|
@ -10,7 +11,8 @@ stdenv.mkDerivation {
|
|||
dontConfigure = true;
|
||||
dontBuild = true;
|
||||
|
||||
passthru.tests = { } // examples-shell.passthru.tests;
|
||||
passthru.tests = examples-shell.passthru.tests //
|
||||
examples-shell-with-emulator.passthru.tests;
|
||||
|
||||
meta.timeout = 60;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue