- Putting Android in Its Place
- The Android Service Model
- Exploring the Source
- Summary
Exploring the Source
The last of this chapter’s high-level views of Android is, as promised, much more practical. It’s time to look at the AOSP code-base.
The primary source for Android code is the Android Open Source Project (AOSP) site at https://source.android.com/. Android system developers should be familiar with this site whether it is the source of the code for their project or not. Android originates here, and documentation and update information are available here before being available anywhere else.
In particular, the Overview section of the AOSP website contains important information about source branching and tagging strategies and the legal constraints on the use of the Android name, logos, and so on. Anyone working with Android code should read this documentation and be, at the least, generally familiar with it.
Other Sources
Several other sources for forks of the AOSP code exist, each with its own advantages and disadvantages. Among these forks, perhaps the best known are AOKP and MIUI. Sadly, one of the most important forks, CyanogenMod, has disappeared from the scene. The support community has rebranded it as LineageOS, and it may return to viability in the future.
What’s in the Box?
The remaining sections of this chapter assume that the developer/build machine has been set up as described in Chapter 2. Let’s take a quick walk through the source, just to get the lay of the land. Listing 3.2 shows the top-level directory structure.
Listing 3.2 Source Top Level
lrwxr-xr-x 1 aosp staff 19 Oct 13 09:26 Android.bp -r--r--r-- 1 aosp staff 92 Oct 13 09:26 Makefile drwxr-xr-x 35 aosp staff 1564 Oct 13 09:26 art drwxr-xr-x 14 aosp staff 816 Oct 13 09:26 bionic drwxr-xr-x 3 aosp staff 102 Oct 13 09:26 bootable lrwxr-xr-x 1 aosp staff 26 Oct 13 09:26 bootstrap.bash drwxr-xr-x 5 aosp staff 374 Oct 13 09:26 build drwxr-xr-x 3 aosp staff 102 Oct 13 09:26 compatibility drwxr-xr-x 12 aosp staff 748 Oct 13 09:26 cts drwxr-xr-x 8 aosp staff 476 Oct 13 09:26 dalvik drwxr-xr-x 5 aosp staff 170 Oct 13 09:26 developers drwxr-xr-x 20 aosp staff 748 Oct 13 09:26 development drwxr-xr-x 10 aosp staff 340 Oct 13 09:27 device drwxr-xr-x 310 aosp staff 10540 Oct 13 09:30 external drwxr-xr-x 15 aosp staff 510 Oct 13 09:31 frameworks drwxr-xr-x 12 aosp staff 408 Oct 13 09:31 hardware drwxr-xr-x 5 aosp staff 170 Oct 13 09:31 kernel drwxr-xr-x 20 aosp staff 1258 Oct 13 09:31 libcore drwxr-xr-x 8 aosp staff 680 Oct 13 09:31 libnativehelper drwxr-xr-x 9 aosp staff 306 Oct 13 09:32 packages drwxr-xr-x 6 aosp staff 272 Oct 13 09:32 pdk drwxr-xr-x 10 aosp staff 374 Oct 13 09:32 platform_testing drwxr-xr-x 30 aosp staff 1020 Oct 13 09:36 prebuilts drwxr-xr-x 24 aosp staff 1054 Oct 13 09:36 sdk drwxr-xr-x 37 aosp staff 1258 Oct 13 09:36 system drwxr-xr-x 10 aosp staff 340 Oct 13 09:36 test drwxr-xr-x 4 aosp staff 136 Oct 13 09:36 toolchain drwxr-xr-x 21 aosp staff 714 Oct 13 09:37 tools
Android.bp
The build system for Android is in transition. Up through the Marshmallow release, Android used an extension of GNU make as the underlying build system. The system used build files named Android.mk dispersed throughout the build tree, selected using a configuration describing the particular device being built. The process resulted in a large in-memory makefile to do the build. While powerful, this approach had limitations and never scaled well, especially noticeable as the Android source tree grew in size.
Nougat introduced a new build system, Soong, which is inspired by Bazel and uses a Go syntax. With Soong, the Android.mk files are replaced with Android.bp (blue print) files. As announced in late 2020, Google will be further transitioning the build system to Bazel in the near future.
Makefile
Makefile is the top-level makefile used in the legacy GNU make build system. It is copied here from the build directory when repo sync is executed.
art
The art directory contains the code for the Android Runtime (ART), an ahead-of-time compiled runtime that replaces the original Android virtual machine, Dalvik.
bionic
The bionic directory contains the code for the Android Standard-C-like library, Bionic. The earlier section of this chapter, “System Libraries,” describes Bionic.
bootable
The bootable directory contains the source for the recovery executable. Recovery is used to apply OTA updates, write new firmware, and perform a factory data wipe.
bootstrap.bash
The bootstrap.bash script is part of the new build system, Soong.
build
The build directory contains the both the old and the new build systems. In particular, it contains the shell script envsetup.sh, used to configure the build environment. In addition to setting up required environment variables, this script introduces helper aliases and shell functions, such as lunch, which are used to configure and execute the build, as discussed in detail in Chapter 2.
cts
The cts directory contains the Android Compatibility Test Suite tests. Passing these tests is the minimum requirement for certification as an Android device.
dalvik
The dalvik directory contains the source for Android’s original VM, Dalvik.
developers
The developers directory contains three different repositories of mostly legacy example code. The example Gradle plug-ins may be of interest.
development
The development directory contains odds and ends that may be useful to developers. It contains things such as tools for editing Android source using one of the popular IDEs, Eclipse or IntelliJ; more example code; developer debug applications; configurations for checkstyle, the emulator; and other tools.
device
device is an extremely important directory for a device developer. The Android source and build system are designed with the intention that all device-specific code—device-specific configuration of the build system, toolchain customizations, kernel selection, and even specialized versions of applications—go here. Although most device developers will find that very constraining, it is a smart strategy to keep as much device-specific code as possible in this directory. Only broader, more generic cross-platform changes should be made outside of the device-specific directory. Much of the work in the rest of this book will happen in this directory.
external
external contains all the buildable packages that are used, but not maintained, as part of Android. It contains things like bouncycastle, the Android cryptography library; expat, an XML parser; junit, a standard testing framework; and so on. All of these things are essential components of a running Android system but are obtained from external providers. Placing the code for these components in this directory makes the dependency explicit and makes Android less susceptible to versioning issues.
frameworks
The frameworks directory is the heart of Android. The public Android API is located here, in the directory frameworks/base/core/java. Core system services such as the ActivityManagerService and PackageManagerService are in frameworks/base/services/core/java. Input event management and sensors code can be found under frameworks/base/native. You can usually find native implementation code next to java directories in sibling jni directories and static resources in directories named res.
hardware
The hardware directory contains the HAL. This is the abstraction layer code for common devices: Wi-Fi, Bluetooth, and baseband radios; sensors; cameras; and so on. Although this directory contains shim code for many common devices, it is the device directory that contains customizations for a specific board and any one-off hardware on that board.
libcore
The most interesting things that live in the libcore directory are the sources for the Apache Harmony base implementations of the Java API. For example, the file
libcore/ojluni/src/main/java/java/lang/Class.java
is the source for Android’s implementation of the Java type Class.
libnativehelper
As the name implies, the libnativehelper directory contains native helper functions. It is sort of a “commons” directory for HAL code that leverages Java Native Interface (JNI) to bridge the gap between the runtime code and backing native code.
packages
The packages directory contains applications that will be included as part of the system. The directory packages/apps, for instance, contains the standard DeskClock, Phone, and Camera apps that are pre-installed (and not uninstallable) on a typical Android device.
pdk
The pdk directory contains the platform development toolkit (PDK). It is given to original device manufacturers (ODMs) so that they can develop HAL and other specialization software for their devices. The PDK is a subset of the full Android source, so this directory doesn’t contain much that is useful as part of the Android source tree.
platform-testing
The platform-testing directory contains odds and ends of tools for testing device functionality.
prebuilts
The large prebuilts directory is very similar to the external directory, except that the things that it contains are not built as part of the system build process. For instance, it contains the binaries for the clang and gcc, C compilers; the Python and Go language SDKs; and the kernel for the QEMU-based Android emulator.
sdk
sdk, a mostly historical directory, contains source for some of the Android development tools as they were just before Android Studio was introduced. Since Android Studio, the SDK tools have their own, partially overlapping, repo-maintained build tree (see http://tools.android.com/build). Most of the code here is obsolete.
system
Another very important directory, system contains the native daemons, system libraries, and data essential to an Android system. In here are the sources for vold, the SE Linux policies, and the system trusted certificates. These are the parts of the Android system that are illustrated in the top-left of Figure 3.1 and discussed in Chapter 7.
toolchain
The toolchain directory contains a set of automated tests that can be executed to gather benchmarking data. Building and running these tests require patching the source tree.
tools
The tools directory contains a number of helper tools, such as ones to ease the creation of Android AVDs and to analyze atrace data captures.
out
The out directory is not part of the build environment maintained by repo. It is, however, the default scratchpad for the build system. None of the previously mentioned directories should be affected in any way by a system build. From the build’s point of view, they are all read only. Restoring a build environment to its pristine state should always be possible by simply deleting this directory. All intermediates as well as the final build artifacts are put here.