2020-03-08 10:51:05 +00:00
|
|
|
{ composeAndroidPackages, stdenv, lib, runtimeShell }:
|
2013-08-06 10:16:51 +01:00
|
|
|
{ name, app ? null
|
2019-08-17 09:48:06 +01:00
|
|
|
, platformVersion ? "16", abiVersion ? "armeabi-v7a", systemImageType ? "default"
|
2013-08-06 10:16:51 +01:00
|
|
|
, enableGPU ? false, extraAVDFiles ? []
|
2014-02-27 17:46:06 +00:00
|
|
|
, package ? null, activity ? null
|
2019-08-17 09:48:06 +01:00
|
|
|
, avdHomeDir ? null, sdkExtraArgs ? {}
|
|
|
|
}:
|
2012-11-07 20:10:39 +00:00
|
|
|
|
|
|
|
let
|
2019-08-17 09:48:06 +01:00
|
|
|
sdkArgs = {
|
androidenv/emulate-app: fix image id for recent device manager
Symptom:
```
Available Android targets:
----------
id: 1 or "android-28"
Name: Android 9
Type: Platform
API level: 28
Revision: 6
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
Tag/ABIs : google_ndk_playstore/x86
...
Error: Invalid --tag google_apis_playstore for the selected target.
```
For creation of AVD, switch from `android` to `avdmanager` as the
latter seems enabling selecting the image with less friction (and is
better documented as not deprecated). This requires using recent
tools - from https://developer.android.com/studio/releases/sdk-tools :
> SDK Tools, Revision 25.3.0 (March 2017)
> ...
> `android avd` command-line functionality replaced with new
> `avdmanager` tool.
For listing of targets, switch from `android` to `avdmanager` as the
`android` command invocation fails in recent tools. Symptom (not
missing `s` as backward incompatibility):
```
Invalid or unsupported command "list targets"
Supported commands are:
android list target
android list avd
android list device
android create avd
android move avd
android delete avd
android list sdk
android update sdk
```
References:
- https://developer.android.com/studio/tools/help/android
- https://developer.android.com/studio/command-line/avdmanager
2020-03-09 05:35:53 +00:00
|
|
|
toolsVersion = "26.1.1";
|
2013-07-31 17:56:27 +01:00
|
|
|
platformVersions = [ platformVersion ];
|
2018-11-27 19:36:27 +00:00
|
|
|
includeEmulator = true;
|
|
|
|
includeSystemImages = true;
|
|
|
|
systemImageTypes = [ systemImageType ];
|
2013-07-31 17:56:27 +01:00
|
|
|
abiVersions = [ abiVersion ];
|
2019-08-17 09:48:06 +01:00
|
|
|
} // sdkExtraArgs;
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2019-08-17 09:48:08 +01:00
|
|
|
sdk = (composeAndroidPackages sdkArgs).androidsdk;
|
2012-11-07 20:10:39 +00:00
|
|
|
in
|
|
|
|
stdenv.mkDerivation {
|
|
|
|
inherit name;
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2012-11-07 20:10:39 +00:00
|
|
|
buildCommand = ''
|
|
|
|
mkdir -p $out/bin
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2012-11-07 20:10:39 +00:00
|
|
|
cat > $out/bin/run-test-emulator << "EOF"
|
2020-03-08 10:51:05 +00:00
|
|
|
#!${runtimeShell} -e
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2012-11-07 20:10:39 +00:00
|
|
|
# We need a TMPDIR
|
|
|
|
if [ "$TMPDIR" = "" ]
|
|
|
|
then
|
|
|
|
export TMPDIR=/tmp
|
|
|
|
fi
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2014-02-27 17:46:06 +00:00
|
|
|
${if avdHomeDir == 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)
|
|
|
|
'' else ''
|
2014-02-27 18:26:18 +00:00
|
|
|
mkdir -p "${avdHomeDir}"
|
|
|
|
export ANDROID_SDK_HOME="${avdHomeDir}"
|
2014-02-27 17:46:06 +00:00
|
|
|
''}
|
2018-11-27 19:36:27 +00:00
|
|
|
|
|
|
|
# We need to specify the location of the Android SDK root folder
|
2019-08-17 09:48:08 +01:00
|
|
|
export ANDROID_SDK_ROOT=${sdk}/libexec/android-sdk
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2012-11-07 20:10:39 +00:00
|
|
|
# We have to look for a free TCP port
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2013-08-05 18:08:58 +01:00
|
|
|
echo "Looking for a free TCP port in range 5554-5584" >&2
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2012-11-07 20:10:39 +00:00
|
|
|
for i in $(seq 5554 2 5584)
|
|
|
|
do
|
2019-08-17 09:48:08 +01:00
|
|
|
if [ -z "$(${sdk}/libexec/android-sdk/platform-tools/adb devices | grep emulator-$i)" ]
|
2012-11-07 20:10:39 +00:00
|
|
|
then
|
|
|
|
port=$i
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2012-11-07 20:10:39 +00:00
|
|
|
if [ -z "$port" ]
|
|
|
|
then
|
2013-08-05 18:08:58 +01:00
|
|
|
echo "Unfortunately, the emulator port space is exhausted!" >&2
|
2012-11-07 20:10:39 +00:00
|
|
|
exit 1
|
|
|
|
else
|
2013-08-05 18:08:58 +01:00
|
|
|
echo "We have a free TCP port: $port" >&2
|
2012-11-07 20:10:39 +00:00
|
|
|
fi
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2012-11-07 20:10:39 +00:00
|
|
|
export ANDROID_SERIAL="emulator-$port"
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2014-02-27 18:26:18 +00:00
|
|
|
# Create a virtual android device for testing if it does not exists
|
androidenv/emulate-app: fix image id for recent device manager
Symptom:
```
Available Android targets:
----------
id: 1 or "android-28"
Name: Android 9
Type: Platform
API level: 28
Revision: 6
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
Tag/ABIs : google_ndk_playstore/x86
...
Error: Invalid --tag google_apis_playstore for the selected target.
```
For creation of AVD, switch from `android` to `avdmanager` as the
latter seems enabling selecting the image with less friction (and is
better documented as not deprecated). This requires using recent
tools - from https://developer.android.com/studio/releases/sdk-tools :
> SDK Tools, Revision 25.3.0 (March 2017)
> ...
> `android avd` command-line functionality replaced with new
> `avdmanager` tool.
For listing of targets, switch from `android` to `avdmanager` as the
`android` command invocation fails in recent tools. Symptom (not
missing `s` as backward incompatibility):
```
Invalid or unsupported command "list targets"
Supported commands are:
android list target
android list avd
android list device
android create avd
android move avd
android delete avd
android list sdk
android update sdk
```
References:
- https://developer.android.com/studio/tools/help/android
- https://developer.android.com/studio/command-line/avdmanager
2020-03-09 05:35:53 +00:00
|
|
|
${sdk}/libexec/android-sdk/tools/bin/avdmanager list target
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2019-08-17 09:48:08 +01:00
|
|
|
if [ "$(${sdk}/libexec/android-sdk/tools/android list avd | grep 'Name: device')" = "" ]
|
2014-02-27 18:26:18 +00:00
|
|
|
then
|
|
|
|
# Create a virtual android device
|
androidenv/emulate-app: fix image id for recent device manager
Symptom:
```
Available Android targets:
----------
id: 1 or "android-28"
Name: Android 9
Type: Platform
API level: 28
Revision: 6
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
Tag/ABIs : google_ndk_playstore/x86
...
Error: Invalid --tag google_apis_playstore for the selected target.
```
For creation of AVD, switch from `android` to `avdmanager` as the
latter seems enabling selecting the image with less friction (and is
better documented as not deprecated). This requires using recent
tools - from https://developer.android.com/studio/releases/sdk-tools :
> SDK Tools, Revision 25.3.0 (March 2017)
> ...
> `android avd` command-line functionality replaced with new
> `avdmanager` tool.
For listing of targets, switch from `android` to `avdmanager` as the
`android` command invocation fails in recent tools. Symptom (not
missing `s` as backward incompatibility):
```
Invalid or unsupported command "list targets"
Supported commands are:
android list target
android list avd
android list device
android create avd
android move avd
android delete avd
android list sdk
android update sdk
```
References:
- https://developer.android.com/studio/tools/help/android
- https://developer.android.com/studio/command-line/avdmanager
2020-03-09 05:35:53 +00:00
|
|
|
yes "" | ${sdk}/libexec/android-sdk/tools/bin/avdmanager create avd -n device -k "system-images;android-${platformVersion};${systemImageType};${abiVersion}" $NIX_ANDROID_AVD_FLAGS
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2019-08-17 09:48:09 +01:00
|
|
|
${lib.optionalString enableGPU ''
|
2014-02-27 18:26:18 +00:00
|
|
|
# Enable GPU acceleration
|
|
|
|
echo "hw.gpu.enabled=yes" >> $ANDROID_SDK_HOME/.android/avd/device.avd/config.ini
|
|
|
|
''}
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2019-08-17 09:48:09 +01:00
|
|
|
${lib.concatMapStrings (extraAVDFile: ''
|
2014-02-27 18:26:18 +00:00
|
|
|
ln -sf ${extraAVDFile} $ANDROID_SDK_HOME/.android/avd/device.avd
|
|
|
|
'') extraAVDFiles}
|
|
|
|
fi
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2012-11-07 20:10:39 +00:00
|
|
|
# Launch the emulator
|
2019-08-17 09:48:08 +01:00
|
|
|
${sdk}/libexec/android-sdk/emulator/emulator -avd device -no-boot-anim -port $port $NIX_ANDROID_EMULATOR_FLAGS &
|
2012-11-07 20:10:39 +00:00
|
|
|
|
|
|
|
# Wait until the device has completely booted
|
2013-08-05 18:08:58 +01:00
|
|
|
echo "Waiting until the emulator has booted the device and the package manager is ready..." >&2
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2019-08-17 09:48:08 +01:00
|
|
|
${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port wait-for-device
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2013-08-05 18:08:58 +01:00
|
|
|
echo "Device state has been reached" >&2
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2019-08-17 09:48:08 +01:00
|
|
|
while [ -z "$(${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell getprop dev.bootcomplete | grep 1)" ]
|
2012-11-07 20:10:39 +00:00
|
|
|
do
|
|
|
|
sleep 5
|
|
|
|
done
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2013-08-05 18:08:58 +01:00
|
|
|
echo "dev.bootcomplete property is 1" >&2
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2019-08-17 09:48:08 +01:00
|
|
|
#while [ -z "$(${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell getprop sys.boot_completed | grep 1)" ]
|
2012-11-07 20:10:39 +00:00
|
|
|
#do
|
|
|
|
#sleep 5
|
|
|
|
#done
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2013-08-05 18:08:58 +01:00
|
|
|
#echo "sys.boot_completed property is 1" >&2
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2013-08-05 18:08:58 +01:00
|
|
|
echo "ready" >&2
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2019-08-17 09:48:09 +01:00
|
|
|
${lib.optionalString (app != null) ''
|
2014-02-27 18:26:18 +00:00
|
|
|
# Install the App through the debugger, if it has not been installed yet
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2019-08-17 09:48:08 +01:00
|
|
|
if [ -z "${package}" ] || [ "$(${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell pm list packages | grep package:${package})" = "" ]
|
2014-01-28 18:09:08 +00:00
|
|
|
then
|
2014-02-27 18:26:18 +00:00
|
|
|
if [ -d "${app}" ]
|
|
|
|
then
|
|
|
|
appPath="$(echo ${app}/*.apk)"
|
|
|
|
else
|
|
|
|
appPath="${app}"
|
|
|
|
fi
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2019-08-17 09:48:08 +01:00
|
|
|
${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port install "$appPath"
|
2014-01-28 18:09:08 +00:00
|
|
|
fi
|
2018-11-27 19:36:27 +00:00
|
|
|
|
2013-08-05 18:08:58 +01:00
|
|
|
# Start the application
|
2019-08-17 09:48:09 +01:00
|
|
|
${lib.optionalString (package != null && activity != null) ''
|
2019-08-17 09:48:08 +01:00
|
|
|
${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell am start -a android.intent.action.MAIN -n ${package}/${activity}
|
2014-02-27 17:46:06 +00:00
|
|
|
''}
|
2013-08-05 18:08:58 +01:00
|
|
|
''}
|
2012-11-07 20:10:39 +00:00
|
|
|
EOF
|
|
|
|
chmod +x $out/bin/run-test-emulator
|
|
|
|
'';
|
|
|
|
}
|