Try Android development

This tutorial lets you try Android operating system development for the first time.

Set up for Android development

Before you download and build the main branch of the Android source, ensure that your hardware meets the necessary requirements and that required software is properly installed. You should also be familiar with the following terms:

Git
Git is a free and open source distributed version control system. Android uses Git for local operations such as branching, commits, diffs, and edits. For help learning Git, refer to the Git documentation.
Repo
Repo is a Python wrapper around Git that simplifies performing complex operations across multiple Git repositories. Repo doesn't replace Git for all version control operations, it only makes complex Git operations easier to accomplish. Repo uses manifest files to aggregate Git projects into the Android superproject.
manifest file
A manifest file is an XML file specifying where the various Git projects in the Android source are placed within an AOSP source tree.

Meet hardware requirements

Your development workstation should meet or exceed these hardware requirements:

  • A 64-bit x86 system.

  • At least 400 GB of free disk space to check out and build the code (250 GB to check out + 150 GB to build).

  • A minimum of 64 GB of RAM. Google uses 72-core machines with 64 GB of RAM to build Android. With this hardware configuration, it takes approximately 40 minutes for a full build of Android and only a few minutes for incremental build of Android. By contrast, it takes approximately 6 hours for a full build with a 6-core machine with 64 GB of RAM.

Meet operating system requirements

Your development workstation must run any 64-bit Linux distribution with GNU C Library (glibc) 2.17 or later.

Install required packages

To install required packages for Ubuntu 18.04 or later, run the following command:

sudo apt-get install git-core gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig

Install required software

Before you can work with AOSP, you must have installations of OpenJDK, Make, Python 3, and Repo. The AOSP main branch of Android comes with prebuilt versions of OpenJDK, Make, and Python 3, so additional installation steps aren't required. The following section explains how to install Repo.

Install Repo

Follow these steps to install Repo:

  1. Download the current package information:

    sudo apt-get update
    
  2. Run the following command to install the Repo launcher:

    sudo apt-get install repo
    

    The Repo launcher provides a Python script that initializes a checkout and downloads the full Repo tool.

    If successful, skip to step 4.

  3. (optional) Manually install Repo using the following series of commands:

    export REPO=$(mktemp /tmp/repo.XXXXXXXXX)
    curl -o ${REPO} https://storage.googleapis.com/git-repo-downloads/repo
    gpg --recv-keys 8BB9AD793E8E6153AF0F9A4416530D5E920F5C65
    curl -s https://storage.googleapis.com/git-repo-downloads/repo.asc | gpg --verify - ${REPO} && install -m 755 ${REPO} ~/bin/repo
    

    The first three commands set up a temp file, download Repo to the file, and verify that the key provided matches the required key. If these commands are successful, the final command installs the Repo launcher.

  4. Verify the Repo launcher version:

    repo version
    

    The output should indicate a version of 2.4 or higher, for example:

    repo launcher version 2.45

Download the Android source

The Android source is located in a collection of Git repositories hosted by Google. Each Git repository includes the entire history of the Android source, including changes to the source and when the changes were made. To download the Android source:

  1. Navigate into your home directory:

    cd ~
    
  2. Create a local working subdirectory within it:

    mkdir aosp
    
  3. Navigate into the directory:

    cd aosp
    
  4. Initialize the AOSP repository source code main branch (the default):

    repo init --partial-clone -b main -u https://android.googlesource.com/platform/manifest
    
  5. Enter or accept your Git credentials (name, email address).

  6. Sync the source code:

    repo sync -c -j8
    

    If you have any problems during download, refer to Troubleshoot and fix sync issues.

Build the code

To build the code:

  1. From within your working directory, source the envsetup.sh script to set up your build environment:

    source build/envsetup.sh
    
  2. Specify a target device type to build with the lunch command. A target is a device permutation, such as a specific model or form factor. Specify this target:

    lunch aosp_cf_x86_64_phone-trunk_staging-userdebug
    

    You should see a synopsis of your target and build environment:

    ============================================
    PLATFORM_VERSION_CODENAME=VanillaIceCream
    PLATFORM_VERSION=VanillaIceCream
    PRODUCT_INCLUDE_TAGS=com.android.mainline
    TARGET_PRODUCT=aosp_arm
    TARGET_BUILD_VARIANT=eng
    TARGET_ARCH=arm
    TARGET_ARCH_VARIANT=armv7-a-neon
    TARGET_CPU_VARIANT=generic
    HOST_OS=linux
    HOST_OS_EXTRA=Linux-6.5.13-1rodete2-amd64-x86_64-Debian-GNU/Linux-rodete
    HOST_CROSS_OS=windows
    BUILD_ID=AOSP.MAIN
    OUT_DIR=out
    ============================================
    
  3. Build the target:

    m
    

Expect the first build to take hours. Subsequent builds take significantly less time. The output of your build appears in $OUT_DIR.

Launch Cuttlefish

Cuttlefish is the Android emulator used to test your builds.

  1. Run the following commands to download, build, and install the host Debian packages:

    sudo apt install -y git devscripts equivs config-package-dev debhelper-compat golang curl
    git clone https://github.com/google/android-cuttlefish
    cd android-cuttlefish
    for dir in base frontend; do
    pushd $dir
    # Install build dependencies
    sudo mk-build-deps -i
    dpkg-buildpackage -uc -us
    popd
    done
    sudo dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -f
    sudo dpkg -i ./cuttlefish-user_*_*64.deb || sudo apt-get install -f
    sudo usermod -aG kvm,cvdnetwork,render $USER
    sudo reboot
    

    The reboot triggers installing additional kernel modules and applies udev rules.

  2. Launch Cuttlefish:

    launch_cvd --daemon
    
  3. Connect to the Cuttlefish device by navigating to https://localhost:8443 in your web browser. Your virtual Android-powered device is displayed.

Make a change

Update the source code following this example changelist.

  1. From the root of your checkout (aosp/ directory), navigate to the frameworks/native Git project:

    cd frameworks/native
    
  2. Start a temporary project with this command:

    repo start <some-name> .
    
  3. Use your editor to edit SurfaceFlinger.cpp at the following location:

    aosp/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
    
  4. Find this line:

    void SurfaceFlinger::updateColorMatrixLocked() {
    
  5. Add this line at the start of updateColorMatrixLocked():

    mClientColorMatrix = mat4(vec4{1.0f, 0.0f, 0.0f, 0.0f}, vec4{0.0f, -1.0f, 0.0f, 0.0f},
                              vec4{0.0f, 0.0f, -1.0f, 0.0f}, vec4{0.0f, 1.0f, 1.0f, 1.0f});
    
  6. Build the code:

    m
    
  7. Update the build on the device:

    adb root
    adb remount -R
    adb root
    adb sync
    adb reboot
    
  8. Verify that you see a color change on your selected device similar to what is shown in Figure 1.

    Example of a successful color change

    Figure 1. Screen appearance after successful color change

Fix a test

This portion of the codelab utilizes an example test that's in the source tree and is failing.

To run, debug, and fix the test, follow these instructions:

  1. Run:

    atest DevCodelabTest
    

    The test fails.

  2. Examine the stack trace of the failing test:

    STACKTRACE:
    java.lang.AssertionError
     at org.junit.Assert.fail(Assert.java:87)
     at org.junit.Assert.assertTrue(Assert.java:42)
     at org.junit.Assert.assertTrue(Assert.java:53)
     at android.test.example.devcodelab.DevCodelabTest.testHelloWorld(DevCodelabTest.java:29)
    

    The last line of the stack trace shows the test that is failing (testHelloWorld). This test is in a file called DevCodelabTest.java.

  3. To determine the location of the test to fix, append WORKING_DIRECTORY/platform_testing/tests/example/devcodelab/src/ to the last line of the stack trace up to and including the name of the test file. So, android.test.example.devcodelab.DevCodelabTest becomes WORKING_DIRECTORY/platform_testing/tests/example/devcodelab/src/android/test/example/devcodelab/DevCodelabTest.java.

  4. Edit platform_testing/tests/example/devcodelab/src/android/test/example/devcodelab/DevCodelabTest.java and replace Assert.assertTrue(false) with Assert.assertTrue(true)

  5. Run the test again to verify you fixed the issue:

    atest DevCodelabTest
    

Upload your code for review

Repo simplifies Git usage by bundling commands such as git clone to work across numerous Git repositories (or projects) at once.

For code review of your projects in Git, use the Gerrit web-based code review system.

  1. Assuming you made your changes in the frameworks/native project, run these commands to upload your changes:

    cd frameworks/native
    repo start codelab .
    git add .
    git commit
    
  2. For your commit message, enter the following:

    Android codelab change
    Test: manual atest
    
  3. Upload your change:

    repo upload
    

    If you're successful, you see a message resembling this one:

    Upload project frameworks/native/ to remote branch main:
     branch codelab ( 1 commit, Wed Aug 7 09:32:33 2019 -0700):
            ff46b36d android codelab change
    to https://android-review.googlesource.com/ (y/N)? y
    remote: Processing changes: refs: 1, new: 1, done
    remote:
    remote: SUCCESS
    remote:
    remote:   https://android-review.googlesource.com/c/platform/frameworks/native/+/1098432 android codelab change [NEW]
    remote:
    To https://android-review.googlesource.com/platform/frameworks/native
    * [new branch]          codelab -> refs/for/main
    

View your change in Gerrit

To view your change in Gerrit, navigate to the link output in the terminal. The link is similar to the following:

https://android-review.googlesource.com/c/platform/frameworks/native/+/1098432

Revert your change

Normally, post-testing and upon review and approval, you submit your change in Gerrit and merge it into the repository. Instead, for the purposes of this codelab, revert your work:

  1. In Gerrit, click Abandon.

  2. Abandon the associated temporary branch in the frameworks/native project directory (or its subdirectories):

    repo abandon codelab .
    
  3. Revert the changes you made to the test file. Because you didn't run repo start, git commit, and repo upload on the test change, you can reset the file itself. Assuming you're in the aosp/platform_testing directory, use the following command to reset the file:

    git reset HEAD tests/example/devcodelab/src/android/test/example/devcodelab/DevCodelabTest.java
    git checkout .
    

This completes the codelab for Android platform development.

Get help

If you encounter errors during this codelab, report them using the Issue Tracker link on the bottom of any page. Send questions to the android-building group.

Type ps -A | grep crosvm to see if crosvm is running already. If crossvm is running, type stop_cvd || true or kill crosvm process with process PID.