Skip to content

Android emulator

Emulators are build with custom optimized settings for stability and performance. For example a low screen resolution 320x480, 4 inch. All settings you can find in ./ci/android-emulator/hardware/config_*.ini files

How to add an emulator that supports new SDK version#

All supported emulators configs you could find at ./ci/android-emulator/hardware/config_*.ini If there are no needed config you should:

  1. Copy-paste closest config_*.ini
  2. Change image.sysdir.1 property to your sdk path e.g. system-images/android-36/google_apis/x86_64/ for SDK 36
  3. Upload emulator system image to artifactory via Teamcity script
    OR
    Manually:
    1. You could find a link to system image at Android Studio SDK Manager. Try to download image you will see the link.
    2. Unzip image and change internal structure of folders to system-image/android-<sdk>/google_apis/<image-arch>. You could find example at any image in artifactory
      e.g. for api 25:
         unzip x86-25_r18.zip;
         mkdir -pv system-images/android-25/google_apis;
         mv x86 system-images/android-25/google_apis/x86;
         zip -r system-images-android-25-x86.zip system-images;
      
  4. Publish an emulator

Known build emulator image issues#

  • Waiting for emulator booting... is flaky because we hardcode time which we are waiting for boot
Info

We change internal structure of folders inside emulator system image zip archive because we want to add ability for users to extract and use images locally

How to build an emulator image#

To build an android emulator image you need:

  • Linux, docker
  • KVM

Better to build image at CI because image will guarantee more hermetic. And build locally only for testing

To build:

CI#

Run Teamcity configuration with the needed API level

Local#

Requirements:

  • Linux, docker
  • KVM
  • Container registry credentials with push authorization (env. variables DOCKER_REGISTRY_USERNAME, DOCKER_REGISTRY_PASSWORD)

Steps:

  1. Run script
    cd ci/docker
    ./publish_emulator.sh <hermetic/non-hermetic> <API level> <Emulator type: google_apis or google_atd> <debug>
    
  2. Find the image tag at logs. You can use it for testing image locally

How to test a new emulator image#

  1. Ensure that app supports SDK level of your emulator. Pass a correct maximumSupportedSdk version to the DeviceSettingsChecker instance and then simply run test against built from Android Studio emulator with same SDK level. Try to run it also with Orchestrator disabled.
  2. Run instrumentation dynamic for one test on one already supported emulators and your one
  3. Compare the test status, time execution, steps
  4. Run instrumentation dynamic for any component test with many executions i.e. 100
  5. It will help check memory leaks. If there are no strange errors everything is ok
  6. Run prCheck
  7. Compare amount of tests at all statuses. There should be no LOST,FAILED,ERROR tests

How to check amount of resources consumed by an emulator image#

CI#

Check dashboards

Local#

Use cAdvisor

sudo docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/dev/disk/:/dev/disk:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  google/cadvisor:latest

How to publish a new emulator image#

  1. Run at Teamcity Build and publish android-emulator (internal)
Info

You will need Image tag and Avd model when try to add new emulator to Test Runner. You could copy-paste them from Teamcity Build Log. Image tag from the end of the Build Log - search phrase Published the image. Avd model - Search phrase Print devices. We print adb devices -l from prepare_emulator.sh

How to run an emulator image#

MacOS and windows#

MacOS and Windows are unsupported because of virtualization haxm #51

But you could create emulator at Android Studio and configure it

Linux#

It's easier and reliable to use original CI emulator images

Requirements:

  • Docker
  • KVM

  • Find actual emulator image Emulator.kt.

  • Add permission for connection to Xorg from any host. In our case from emulator image container
    xhost +
    
  • Run emulator:
    docker run -d \
        -p 5555:5555 \
        -p 5554:5554 \
        -e "SNAPSHOT_ENABLED"="false" -e "WINDOW"="true" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
        --privileged \
        <registry>/android/emulator-27:<TAG>
    
    Or run with headless mode:
    docker run -d \
        -p 5555:5555 \
        -p 5554:5554 \
        --privileged \
        <registry>/android/emulator-27:<TAG>
    
  • Connect to emulator via adb
    adb connect localhost:5555