Skip to content

Building and Running the Emulator (Cuttlefish)

Jacob McSwain edited this page Mar 7, 2022 · 3 revisions

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.

Note: For arch, the cuttlefish-common package can be found in the AUR. This will install all the needed dependencies. A reboot may be required for the appropriate kernel modules to load.

Run emu init. (Tip: build/envsetup.sh will add this binary to the 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 emu command is the primary controller for Carbon Cuttlefish machines. It has a good --help output that explains the options available. When emu start 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, click somewhere on the screen, this should cause the screen to refresh and appear.

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

Here is the --help output of emu:

emu [global options] (init|start|stop) [command options]

Wrapper script to make Cuttlefish easy to run. Must run "emu init" once per host before "emu start" will work.
The simplest usage is just "emu start". It uses sane defaults. Once the emulator boots, a VNC viewer should appear. Closing this VNC viewer will not stop the emulator.
To stop the emulator, just run "emu stop". The init and stop commands do not have any options.

Global options

--help,-h     Show this help message and exit.
--verbose,-v   Enables verbose output.

"start" command options

--formfactor,--ff,-f  Set a predefined form factor for the emulated device. Options are "phone", "tablet", and "desktop". This option is overridden with --dpi and --resolution. Defaults to "phone".
--resolution,--res,-r Set the emulated device's screen resolution. Typically used with --dpi. Use of this option will override --formfactor.
--dpi,-d      Set the emulated device's screen DPI. Typcially used with --resolution. Use of this option will override --formfactor.
--cores,--cpu,-c      Set the emulator's allocated number of CPU cores. Defaults to "4".
--memory,--mem,-m     Set the emulator's allocated memory. Defaults to "4g".

Stopping the emulator

Once you're done and want to clean up the VMs, it's as simple as running emu stop