Skip to content

Building and Running the Emulator (Cuttlefish)

Jacob McSwain edited this page Jan 1, 2022 · 3 revisions

Building and Running the Emulator (Cuttlefish)

What is Cuttlefish and what does it have to do with the emulator?

Google publishes a quick-start guide for Cuttlefish in AOSP. Carbon adapts this process for emulator builds: https://source.android.com/setup/create/cuttlefish

Cuttlefish is a massive undertaking that allows you to run a set of virtual Android devices of heterogeneous hardware sizing quickly and efficiently. It can even run in Docker or natively in Google Cloud.

The major reason to use it over emulator is that the traditional emulator has many workarounds and "hacks" implemented in AOSP plaform code that makes the codebase behave differently on emulator when compared to a real device. Google states it best:

There are many similarities with the Android Emulator, but Cuttlefish guarantees full fidelity with Android framework (whether this is pure AOSP or a custom implementation in your own tree). In real-world application, this means that you should expect Cuttlefish to respond to your interactions at the OS level just like a physical phone target built with the same customized or pure Android OS source.

Google even runs CTS and CI on Cuttlefish targets.

First time Cuttlefish setup

Make sure your BIOS has virtualization enabled. You will be running virtual machines. To quickly check this you can run grep -c -w "vmx\|svm" /proc/cpuinfo. If it doesn't return any text then you probably need to check your BIOS.

Cuttlefish has a few host dependencies in order to run. Mostly this is a network setup that allows transport inside of the Android virtual machines. This package is called cuttlefish-common.

PLEASE NOTE: On ALL system types, you MUST run sudo systemctl enable --now cuttlefish-common.service after installing, and a reboot will probably be required for the kernel modules to load.

Ubuntu

If you are on Ubuntu, run acloud setup --host from the prebuilts directory. (Tip: lunching a target will add this binary to your PATH). This should prompt as appropriate and following the instructions will setup the host for Cuttlefish.

Debian-based

lunch a Carbon emulator target, [as detailed below](#Lunch targets), and run m acloud. This will build the Debian-based host compatible acloud-dev binary. Then run acloud setup --host from the prebuilts directory. (Tip: lunching a target will add this binary to your PATH). This should prompt as appropriate and following the instructions will setup the host for Cuttlefish.

Arch-based

Google doesn't support Arch-based systems with Cuttlefish. Docker technically works but it is complex to manage for most workflows. Carbon has extended their acloud tool used for Cuttlefish to support Arch-based systems. This requires compiling it in the source code tree with m acloud. It can be ran with acloud-dev. Please note that the command acloud will work, but it will not be the Carbon-specific version and it will refuse to work on Arch.

First, install the cuttlefish-common-git package from the AUR. This will install all the needed dependencies. A reboot may be required for the appropriate kernel modules to load.

Then lunch a Carbon emulator target, [as detailed below](#Lunch targets), and run m acloud. This will build the Debian-based host compatible acloud-dev binary. Then run acloud setup --host from the prebuilts directory. (Tip: lunching a target will add this binary to your PATH). This should prompt as appropriate and following the instructions will setup the host for Cuttlefish.

Building the emulator

This assumes Carbon is already synced, and that you are in the same directory.

. build/envsetup.sh
lunch carbon_emulator_<arch>-userdebug
m

Lunch targets

In this case, for lunch options, the arch can be arm64, x86, or x86_64.

There's not much reason to use an architecture other than x86, unless you're testing something architecture-specific. It'll save some iteration time using a 32-bit target since 64-bit versions of binaries won't need to be compiled. arm64 emulation with be graphically SLOW, and significantly slower than x86 in other ways.

Why no arm Cuttlefish target?

Simply put, arm processors were phased out before Cuttlefish was created. Google doesn't publish tooling for arm targets anymore. If we need arm targets for Cuttlefish, we can definitely look at adding them.

Running the emulator

The acloud-dev binary is the primary controller for Cuttlefish machines. It has a good --help output, and there exists a "quick-start" guide on it in the AOSP tree. When acloud-dev create is ran, it will open a VNC viewer after the device boots. adb should automatically work for the Cuttlefish device as well. It will also output the logs to files and output the paths. If the VNC screen is black, try to click near where the status bar would be and drag it down as if opening the quick settings drawer, this should cause the screen to refresh and appear.

. build/envsetup.sh
lunch carbon_emulator_<arch>-userdebug
acloud-dev create --local-image --local-instance <options>

A typical invocation might look like this:

acloud-dev create --local-instance --local-image --gpu -v --hw-property cpu:6,resolution:1080x1920,dpi:420,memory:4g

Some options you may be interested in:

--gpu should auto detect the GPU and allow acceleration inside the VM.

-v is for verbosity.

If acloud-dev --help doesn't give the output you're looking for, check out launch_cvd --help. All of the launch_cvd commands can be passed in to acloud via --launch-args. For example, to have a kernel TTY console, use `acloud-dev --launch-args='--console=true'

--hw-property is pretty self-explanatory from the example. The cpu, resolution, dpi, and memory can be changed at will.

Stopping the emulator

Once you're done and want to clean up the VMs, it's as simple as running acloud-dev delete --local-only

Clone this wiki locally