| #!/bin/bash |
| |
| # This template is used to generate a script that can be used to launch or kill |
| # an emulator: |
| # <target_name> [kill] port |
| # Where port is the ADB port to open and kill is supplied to kill the emulator |
| # on the supplied port. |
| |
| # The path to the source.properties inside the system image. |
| source_properties_path="%source_properties_path%" |
| |
| # Boot time might vary depending on API level. The value below was tested |
| # with API level 33 (TiramisuPrivacySandbox). 200 is default unless the |
| # variable is set. |
| emulator_boot_timeout=${EMULATOR_BOOT_TIMEOUT:-200} |
| echo "timeout is $emulator_boot_timeout" |
| |
| # Emulator gRPC port. This is used when setting up emulator gRPC connection. |
| # Emulator gRPC connection is required by embedded emulator and Android Test |
| # Retention. |
| emulator_grpc_port=8554 |
| |
| if [ "$(uname)" = "Darwin" ]; then |
| OS_DIR_NAME=darwin |
| elif [ "$(uname)" = "Linux" ]; then |
| OS_DIR_NAME=linux |
| else |
| OS_DIR_NAME=windows |
| fi |
| |
| # Set environment variables. |
| export HOME=$(pwd) |
| export ANDROID_PREFS_ROOT=$HOME |
| export ANDROID_SDK_ROOT=$HOME/prebuilts/studio/sdk/$OS_DIR_NAME |
| export ANDROID_EMULATOR_HOME=$HOME/.android |
| export ANDROID_AVD_HOME=$ANDROID_EMULATOR_HOME/avd |
| |
| # Relevant binaries. |
| emulator=$1 |
| adb=prebuilts/studio/sdk/$OS_DIR_NAME/platform-tools/adb |
| |
| # Kill the emulator if requested. This is needed to kill the emulator for |
| # local development. |
| if [ "$2" = "kill" ]; then |
| port=$3 |
| echo "Killing emulator-$port" |
| $adb -s emulator-$port emu kill 2> /dev/null |
| |
| # Wait for the emulator to disconnect. |
| while true; do |
| # Update adb to make sure it knows the emulator is killed. |
| $adb reconnect 2>&1 |
| output=$($adb -s emulator-$port get-state 2> /dev/null) |
| if [ -z "$output" ]; then |
| break |
| fi |
| echo "Emulator state=$output" |
| sleep 1 |
| done |
| exit $? |
| fi |
| port=$2 |
| |
| # Clear emulator files. |
| rm -rf .android 2> /dev/null |
| mkdir .android 2> /dev/null |
| |
| # Generate keys to be injected into emulator to allow authorization for user builds. |
| $adb keygen $ANDROID_EMULATOR_HOME/adbkey |
| |
| # Read system image properties. |
| api_level="$(cat $source_properties_path | sed -rn 's/AndroidVersion.ApiLevel=(.*)/\1/p')" |
| abi_type="$(cat $source_properties_path | sed -rn 's/SystemImage.Abi=(.*)/\1/p')" |
| if [ -z "$api_level" ]; then |
| echo "No API level found" |
| exit 1 |
| fi |
| if [ -z "$abi_type" ]; then |
| echo "No ABI type found" |
| exit 1 |
| fi |
| |
| if [ "$abi_type" = "arm64-v8a" ]; then |
| # On arm64 emulator, hw.cpu.arch is different from abi.type. |
| hw_cpu_arch="arm64" |
| else |
| hw_cpu_arch="$abi_type" |
| fi |
| |
| # Create an AVD named "emu" with hardware properties from pixel. |
| echo "Creating AVD with API level $api_level and ABI type $abi_type" |
| system_image_dir=$(pwd)/$(dirname "$source_properties_path") |
| mkdir -p $ANDROID_AVD_HOME/emu.avd |
| cat > $ANDROID_AVD_HOME/emu.ini << EOF |
| avd.ini.encoding=UTF-8 |
| path=$ANDROID_AVD_HOME/emu.avd |
| path.rel=avd/emu.avd |
| target=android-$api_level |
| EOF |
| cat > $ANDROID_AVD_HOME/emu.avd/config.ini << EOF |
| PlayStore.enabled=false |
| abi.type=$abi_type |
| avd.ini.encoding=UTF-8 |
| hw.accelerometer=yes |
| hw.audioInput=yes |
| hw.battery=yes |
| hw.cpu.arch=$hw_cpu_arch |
| hw.dPad=no |
| hw.device.hash2=MD5:524882cfa9f421413193056700a29392 |
| hw.device.manufacturer=Google |
| hw.device.name=pixel |
| hw.gps=yes |
| hw.lcd.density=480 |
| hw.lcd.height=1920 |
| hw.lcd.width=1080 |
| hw.mainKeys=no |
| hw.sdCard=yes |
| hw.sensors.orientation=yes |
| hw.sensors.proximity=yes |
| hw.trackBall=no |
| image.sysdir.1=$system_image_dir |
| EOF |
| |
| # Launch the emulator. |
| echo "Launching emulator-$port" |
| boot_complete=false |
| # Try to launch the emulator. Keep relaunching if it takes too long. |
| for i in 1 2 3 |
| do |
| start_time=$SECONDS |
| # ModemSimulator doesn't work in bazel sandbox due to not available ports |
| # MultiDisplay is not used, generates some red herring error messages |
| $emulator @emu\ |
| -port $port\ |
| -grpc $emulator_grpc_port\ |
| -delay-adb\ |
| -no-snapshot\ |
| -no-window\ |
| -verbose\ |
| -feature -ModemSimulator\ |
| -feature -MultiDisplay 2>&1 & |
| emu_pid=$! |
| |
| # Wait for the emulator to boot. |
| echo "Waiting for emulator to boot" |
| while true; do |
| output=$($adb -s emulator-$port shell getprop sys.boot_completed 2>&1) |
| if [[ $output == *"unauthorized"* ]]; then |
| echo "Emulator requires authentication" |
| exit 1 |
| fi |
| if [ "$output" = "1" ]; then |
| echo "Emulator booted in $elapsed_time seconds" |
| boot_complete=true |
| break |
| fi |
| elapsed_time=$(( SECONDS - start_time )) |
| if [ "$elapsed_time" -gt "$emulator_boot_timeout" ]; then |
| break |
| fi |
| sleep 1 |
| done |
| if [ "$boot_complete" = true ]; then |
| break |
| fi |
| echo "Emulator failed to come online in $emulator_boot_timeout seconds. Retrying $i ..." |
| kill -9 $emu_pid 2> /dev/null |
| done |
| if [ "$boot_complete" = true ]; then |
| echo "Emulator boot complete" |
| else |
| echo "Emulator boot failed" |
| exit 1 |
| fi |