Always use x86 emulators (or x86_64 for testing 64-bit APKs). Although arm emulators exist, they are so slow that they are not worth your time.
You need to target the correct architecture via GN args:
target_cpu = "x86" # or "x64" if you have an x86_64 emulator
Chromium has a set of prebuilt images stored as CIPD packages. These are used by various builders to run tests on the emulator. Their configurations are currently stored in //tools/android/avd/proto
. You can run this command to list them:
tools/android/avd/avd.py list
Configurations | Android Version | CPU Arch | AVD Target | Builder |
---|---|---|---|---|
generic_android26.textpb | 8.0 (O) | x86 | google_apis | N/A |
generic_android27.textpb | 8.1 (O_MR1) | x86 | google_apis | N/A |
android_28_google_apis_x86.textpb | 9 (P) | x86 | google_apis | android-pie-x86-rel |
android_29_google_apis_x86.textpb | 10 (Q) | x86 | google_apis | N/A |
android_30_google_apis_x86.textpb | 11 (R) | x86 | google_apis | android-11-x86-rel |
android_31_google_apis_x64.textpb | 12 (S) | x86_64 | google_apis | android-12-x64-rel |
android_32_google_apis_x64_foldable.textpb | 12L (S_V2) | x86_64 | google_apis | android-12l-x64-dbg-tests |
android_33_google_apis_x64.textpb | 13 (T) | x86_64 | google_apis | android-13-x64-rel |
android_34_google_apis_x64.textpb | 14 (U) | x86_64 | google_apis | android-14-x64-rel |
You can use these configuration files to run the same emulator images locally.
Make sure KVM (Kernel-based Virtual Machine) is enabled. See this link from android studio for more details and instructions.
You need to have the permissions to use KVM. Use the following command to see if you are in group kvm
:
$ grep kvm /etc/group
If your username is not shown in the group, add yourself to the group:
$ sudo adduser $USER kvm $ newgrp kvm
You need to log out and log back in so the new groups take effect.
The android test runner can run emulator instances on its own. In doing so, it starts the emulator instances, runs tests against them, and then shuts them down. This is how builders run the emulator.
--avd-config
To have the test runner run an emulator instance, use --avd-config
:
$ out/Debug/bin/run_base_unittests \ --avd-config tools/android/avd/proto/android_33_google_apis_x64.textpb
--emulator-count
The test runner will launch one instance by default. To have it run multiple instances, use --emulator-count
:
$ out/Debug/bin/run_base_unittests \ --avd-config tools/android/avd/proto/android_33_google_apis_x64.textpb \ --emulator-count 4
--emulator-enable-network
The test runner runs the emulator without network access by default. To have it run with network access, use --emulator-enable-network
:
$ out/Debug/bin/run_base_unittests \ --avd-config tools/android/avd/proto/android_33_google_apis_x64.textpb \ --emulator-enable-network
--emulator-window
The test runner runs the emulator in headless mode by default. To have it run with a window, use --emulator-window
:
$ out/Debug/bin/run_base_unittests \ --avd-config tools/android/avd/proto/android_33_google_apis_x64.textpb \ --emulator-window
The test runner will set up and tear down the emulator on each invocation. To manage emulator lifetime independently, use tools/android/avd/avd.py
.
--avd-config
This behaves the same as it does for the test runner.
$ tools/android/avd/avd.py start \ --avd-config tools/android/avd/proto/android_33_google_apis_x64.textpb
Note:
avd.py start
will start an emulator instance and then terminate. To shut down the emulator, useadb emu kill
.
--enable-network
Like the test runner, avd.py
runs the emulator without network access by default. To enable network access, use --enable-network
:
$ tools/android/avd/avd.py start \ --avd-config tools/android/avd/proto/android_33_google_apis_x64.textpb \ --enable-network
--emulator-window
Like the test runner, avd.py
runs the emulator in headless mode by default. To have it run with a window, use --emulator-window
:
$ tools/android/avd/avd.py start \ --avd-config tools/android/avd/proto/android_33_google_apis_x64.textpb \ --emulator-window
--gpu-mode GPU_MODE
Override the mode of hardware OpenGL ES emulation indicated by the AVD. See “emulator -help-gpu” for a full list of modes.
--no-read-only
avd.py
runs the emulator in read-only mode by default. To run a modifiable emulator, use --no-read-only
:
$ tools/android/avd/avd.py start \ --avd-config tools/android/avd/proto/android_33_google_apis_x64.textpb \ --no-read-only
--wipe-data
Reset the /data partition to the factory defaults. This removes all user settings from the AVD.
$ tools/android/avd/avd.py start \ --avd-config tools/android/avd/proto/android_33_google_apis_x64.textpb \ --wipe-data
--writable-system
Makes system & vendor image writable. It's necessary to run
adb root adb remount
after the emulator starts.
--debug-tags
avd.py
disables the emulator log by default. When this option is used, emulator log will be enabled. It is useful when the emulator cannot be launched correctly. See emulator -help-debug-tags
for a full list of tags. Use --debug-tags=all
if you want to output all logs (warning: it is quite verbose).
$ tools/android/avd/avd.py start \ --avd-config tools/android/avd/proto/android_33_google_apis_x64.textpb \ --debug-tags init,snapshot
By far the easiest way to set up emulator images is to use Android Studio. If you don't have an Android Studio project already, you can create a blank one to be able to reach the Virtual Device Manager screen.
Refer to: https://developer.android.com/studio/run/managing-avds.html
Where files live:
~/.android/avd/
.Choose a skin with a small screen for better performance (unless you care about testing large screens).
Android Studio's image labels roughly translate to the following:
AVD “Target” | Virtual Device Configuration tab | GMS? | Build Properties |
---|---|---|---|
Google Play | “Recommended” (the default tab) | This has GMS | user /release-keys |
Google APIs | “x86 Images” | This has GMS | userdebug /dev-keys |
No label | “x86 Images” | AOSP image, does not have GMS | eng /test-keys |
“Show Advanced Settings” > scroll down:
adb -s emulator-5554 shell mount
(look for /sdcard)~/.android/avd/YOUR_DEVICE/config.ini
.hw.sdCard=no
and set it to yes
com.android.webview
). This does not resemble production devices with GMS, which expect the “Google WebView” configuration (com.google.android.webview
on L and M). See Removing preinstalled WebView if you need to install a local build or official build.Refer to: https://developer.android.com/studio/run/emulator-commandline.html.
emulator
command line tool.$ # List virtual devices that you've created: $ ~/Android/Sdk/emulator/emulator -list-avds $ # Start a named device: $ ~/Android/Sdk/emulator/emulator @EMULATOR_ID
You can run an emulator without creating a window on your desktop (useful for ssh
):
$ ~/Android/Sdk/emulator/emulator -no-window @EMULATOR_ID $ # This also works for new enough emulator builds: $ ~/Android/Sdk/emulator/emulator-headless @EMULATOR_ID
Tests are automatically sharded amongst available devices. If you run multiple emulators, then running test suites becomes much faster. Refer to the “Multiple AVD instances” section of these emulator release notes for more about how this works.
$ # Start 8 emulators. Press Ctrl-C to stop them all. $ ( for i in $(seq 8); do ~/Android/Sdk/emulator/emulator @EMULATOR_ID -read-only & done; wait ) $ # Start 12 emulators. More than 10 requires disabling audio on some OS's. Reducing cores increases parallelism. $ ( for i in $(seq 12); do ~/Android/Sdk/emulator/emulator @EMULATOR_ID -read-only -no-audio -cores 2 & done; wait )
Unlike physical devices, an emulator's /system
partition cannot be modified by default (even on rooted devices). If you need to do so (such as to remove a system app), you can start your emulator like so:
$ ~/Android/Sdk/emulator/emulator -writable-system @EMULATOR_ID
adb devices
scp
or ssh port forwarding to copy the APK from your workstation and install on a local device. Emulators run on your workstation, so there's no ssh slow-down.userdebug
/eng
emulators don‘t come with the Play Store installed, so you can’t install third party applications. Sideloading is tricky, as not all third-party apps support x86.