3

Getting Started

This chapter is an overview that provides context for the rest of the book. It will present three different, high-level views of the Android system. It is divided into two parts, a conceptual section followed by a practical section.

The conceptual half of the chapter explores Android, metaphorically, from the side. This section models Android as a geologist might, as a stack of strata. Each layer in the model has its own significance, and each supports the layer above it. The exploration will reveal most of the major components of the Android system as well as several key architectural structures.

The second half of the chapter—the practical half—explores the AOSP source. It addresses acquiring the code, its organization, its customization, and some of the tools used to maintain it.

Putting Android in Its Place

You have almost certainly seen one of the many illustrations of Android as a layer cake before. Figure 3.1 is another version.

Images

Figure 3.1 Android Layer Cake

Figure 3.1 shows the Android system in its context. The left half of the figure could be a generic Linux distribution such as Ubuntu or Mint. The right half illustrates the components specific to Android.

In the model, the system is divided into four major layers, each based on the one underneath it. Starting at the bottom, they are:

  • Hardware: This is the physical device; a piece of metal you can hold in your hand.

  • Linux Kernel: The kernel is software that creates the process and memory environments in which all applications run. As noted in Chapter 1, Android uses the very popular Linux kernel.

  • System Libraries: System libraries are software libraries, frequently supplied as opaque binaries by third-party providers that implement services used by multiple applications.

  • Applications and System Services: Applications use the environment provided by the lower layers to do work useful to the user. A set of special, long-running applications, called system services or sometimes “daemons,” perform periodic tasks and manage system state.

In this model, most Android developers work predominantly in the block labeled “Android Applications” at the top right of the figure. They develop the applications that run in the Android environment. These developers spend their time learning and using the environment provided by the surrounding Android system.

The rest of this book is about customizing Android itself to adapt it to new hardware. Its focus is the shaded areas outlined with the bold border, most of which is in the System Services layer of Figure 3.1. Before launching into the discussion of the Android-specific components, though, reviewing the rest of the environment in which those components run will be useful.

Hardware

In this model, the bottom of the stack is the hardware. The hardware is the motivation: some device with cool new features. It is the part that you, the reader, bring to the party. The purpose of the entire software stack above the hardware is to enable the creation of applications that provide a human user with appropriate and intuitive control of some new, innovative hardware features.

Designing and bringing up hardware are dark arts that are well outside the scope of this book. Roger Ye’s book, Embedded Programming with Android (Ye, 2016), part of the Android Deep Dive Series, is an excellent introduction to “bare-metal” programming and the process of bringing up a device from scratch.

The Linux Kernel

As noted in Chapter 1, Android’s kernel is a variant of the Linux kernel. Linux is wildly popular, especially in embedded devices because it is open source and fairly easy to adapt to new hardware. Chapter 4 discusses it again in more detail.

The kernel is the Android system’s primary porting layer. The process of porting Android to a new device consists in large part of getting an Android variant of the Linux kernel running on the target device and then pulling the rest of the Android stack over on top of it.

Although a kernel is a key part of Android, building a kernel is not normally part of building an Android system. Instead, the Android build tools treat the kernel as a black box: a pre-built, third-party binary. As Chapter 4 will illustrate, it is a device developer’s responsibility to assemble the working kernel and to provide it for inclusion into the device-installable file system image that the Android build system creates.

You might be surprised to hear that the kernel is Android’s primary porting layer. Much of Android programming is done in the Java programming language, whose motto was “write once, run anywhere.” For Android, however, Java source code is compiled into instructions for Dalvik and ART, not instructions for the Java Virtual Machine (JVM). The purpose of the Android VM is to make applications portable across Android devices. Unlike the JVM, multi-platform and OS portability was not a goal at all in the design of Android’s virtual machine.

System Libraries

There are common capabilities and functions that are used by multiple applications. Some of these capabilities—cryptography, video and audio rendering, a web browser—are large and complex. Implementing them as libraries that can be used by multiple applications makes sense.

Most system libraries are included in the Android system, as is the kernel, as third-party, black box binaries. They are essential to Android but are neither built nor maintained as part of the Android source tree.

This is an important area of customization for the developer of a new device. If software already exists—and that definitely includes software written in a language other than Java—that can be used as part of the interface to a new device, it can be included as part of this layer.

Enterprises that already have extensive investments in software may be, quite understandably, reluctant to abandon that investment simply to move to the Android platform. Including the proprietary code as a system library and then plumbing it into the Android framework with Java bindings may preserve the investment at a reasonable cost.

One of the system libraries that is part of a standard Android system and that deserves particular attention is Bionic. Bionic is Android’s equivalent of the standard C library.

Most applications do not request kernel services directly. Instead, they use a standard library, the C library, to request them. The standard C library interface was specified originally as part of the ANSI C standard and subsequently accepted by ISO. The widely established POSIX C library standard is an incremental superset.

The C library standards are expressed as C header files (.h) against which applications are compiled. These header files define symbols that allow a compiler to emit code for macros, constants, variables, and functions in the application source code. Building an application requires only the header files. The actual implementations of the C library are not included in the compiled application.

Instead, at run time, a linker binds the compiled application dynamically to the implementation of the C library that is present on the system on which the application is running. Because the API definitions against which the application was compiled are (with luck!) identical to those actually implemented by the host system library, everything works. Usually, this just means that the C library is compiled using the exact same header files that the library clients use when they are compiled. A given piece of code can be binary compatible across multiple, similar platforms, as long as all the platforms have C libraries that implement the exact
same API.

Bionic is Android’s version of the standard C library. As part of Android’s ongoing battle for frugality, it has been pruned relentlessly and is dramatically smaller than its BSD ancestors. It is so small, in fact, that it does not meet even the ANSI standard, let alone the ubiquitous POSIX standard. Applications that run perfectly well on other platforms may not run at all on Android, because Bionic does not support the functionality they require.

The implication that Bionic has its roots in BSD may come as a surprise. Most operating systems based on a Linux kernel use a version of the GNU C library, glibc. Instead, Bionic is derived from the BSD UNIX, libc. There are several reasons for this but the most obvious is that libc is licensed under the BSD license and is thus free of the constraints that its LGPL licensing imposes on glibc. One of the goals in Android’s design was to eliminate any possible impediment to its acceptance. That goal absolutely implies removing any possible licensing constraints.

Many existing applications, libraries, and utilities may be used on Android as long as they are recompiled against the Android platform. Obviously, some limits exist because of the extent of the pruning in Bionic. For example, existing code that uses System V IPC or certain functions in the kernel concurrency feature, pthreads, cannot be built or run on Android. Additionally, as this chapter will make clearer, the Android software stack is fundamentally different than a typical Linux stack, which sometimes makes the use of existing Linux programs difficult or impossible.

Augmenting an Android system by adding one of the standard C-library implementations is entirely feasible. This simple and very common augmentation makes it possible to run many standard Unix applications and libraries on an Android system.

Applications

System services are those special applications, typically with minimal user interfaces, that maintain various subsystems: indexing files for search, locating and connecting to Wi-Fi networks, mounting and unmounting removable media, and so on. One special system service, init, is the first application run on system startup. It is responsible for much of the system startup process, including bringing up the other system services. It is discussed in more detail in Chapter 6.

The Android system service environment is not the same as that on typical Linux systems. On a Linux system, running the command:

ps -ef

produces a list of currently running applications. On one of these systems, running this command will typically result in tens of lines of output describing many processes. Even if the system has just been finished booting and is not yet running many user applications, there are still likely to be quite a few applications running. These are the system services: the long running “daemons.”

Comparing the list of system services for a generic Linux system with a similar list from an Android system is instructive. Although the 30 to 40 system services that run as part of most common Linux distributions are fairly similar, the overlap with those running on an Android system is relatively small. The Android system has unfamiliar system services such as installd, rild, surfaceflinger, and vold instead of more common services such as udevd and syslogd. Although Chapter 6 addresses some of these daemons in a bit more detail, in-depth discussion of the differences between the daemons in the Android universe and those in the standard Linux universe are not the focus of this book. Linux daemons are well documented elsewhere. Although slightly dated, Karim Yaghmour’s excellent book Embedded Android (Yaghmour, 2013) is a fantastic resource for work in this area.

The Android Framework

Figure 3.1 illustrates some of the Android-specific components of an Android system and their positions within the broader model of a working Linux system. The right side of the figure shows the Android framework in relation to the larger OS. Android has components that operate within each of the layers of the system model. From the bottom up, the components of the Android system are

  • Binder and other kernel plug-ins: Android requires several non-standard kernel
    capabilities to function. These extensions are implemented as standard kernel extension modules. Chief among these extensions is Binder. Binder is an Interprocess Communi-cations service and is, perhaps, the heart of Android.

  • HAL: The Hardware Abstraction Layer (HAL) is a system library that supports binary compatibility for the Android system across multiple hardware/driver platforms. The HAL, actually a group of libraries, serves as the interface between Android and certain generic types of hardware devices. Like the C library, the HAL is, essentially, a set of header (.h) files that define an API for each of several common categories of hardware. The HAL abstracts an interface between the underlying hardware and Android almost exactly as the C library abstracts the interface to the kernel and other common functionality. The HAL has evolved over Android’s lifetime. Newer versions of Android combine a library and a daemon/service to push the abstraction even farther. Most HAL code is written in C or C++ and compiled to device native binaries. Chapters 8 and 10 cover this in greater detail.

  • Dalvik, ART, and the Native Libraries: These are the special system libraries that comprise the virtual machine and runtime environment in which Android applications execute. ART (and Dalvik, which it replaced) are Android’s analog of the Java virtual machine and the libraries it provides. Both the runtime and many of the libraries that support it are written in C/C++ and compiled to native code for the device. Above this layer, however, nearly all source code is written in Java and compiled to virtual instructions. Chapter 7 discusses ART and Dalvik.

  • Android API Libraries: These are system libraries written in Java, compiled to dex virtual machine code, and translated to near-machine code (.oat files) during installation. They are bound to Android applications at runtime, almost exactly as the C Library is bound to native applications. The code they contain, though, cannot be executed without the help of the virtual machine and its runtime environment. These libraries are the APIs to Android services.

  • Android Services: The Android analog of a system service, these privileged Android applications written in Java provide essential Android functionality. The Zygote service, especially, plays a key role in an Android system. Zygote is covered in Chapter 6. The Android service model is covered in the next section and seen again in Chapters 10 and 11 as part of the binderized HAL.

  • Android Applications: These applications are developed for Android, compiled against the Android API, and run within the runtime environment. Building an Android application is unlike developing applications either for other varieties of Linux or for other mobile platforms. Many other resources are available to a developer building an application. Application building is discussed only peripherally in this book.

The Android Service Model

A second, side-on view of the Android system gives a more functional perspective. Shown in Figure 3.2, it illustrates the basic structure of Android’s service model.

Images

Figure 3.2 The Android System Model

This diagram is key. It illustrates two applications in two separate processes, one on the right and one on the left. The application in the process on the left side of the diagram needs access to the scarce resource at the bottom of the diagram. The arrow from the application to the scarce resource represents its request.

In the diagram the scarce resource is shown as hardware because it often is. Examples of scarce hardware resources might include a phone’s screen, status lights, or a buzzer. Allowing all applications unrestricted access to these things wouldn’t make sense. At best, applications would have to coordinate access among themselves. At worst, a malicious application could make a device unusable by seizing one or more of the essential resources and refusing to release them.

Hardware resources, of course, are not the only things that can be scarce or that need protection. A list of accounts or a database of acquaintances might require similar protection. Android uses the same mechanism to protect non-hardware resources.

In Figure 3.2, the arrow illustrating the application’s intended request for the scarce resource is marked with an “X.” The “X” indicates that application is blocked by the system from making the request directly.

The portal through which an application interacts with hardware—its driver—is almost certainly catalogued as a file in the /dev directory. Recall that as the creator of the file system abstraction, the kernel is able to represent nearly anything as a file. The driver is a special kind of file but still a file. To interact with the resource directly, the application must open the driver file and read and write from it.

Like all files in the Linux file system, the driver file is catalogued with permissions. These permissions determine which processes the kernel will allow to open the file.

Listing 3.1 shows excerpts from the listing of the contents of the /dev directory from a typical Android device. Most of these files are drivers for one device or another. In most cases, the file’s permissions (the first column) limit access to the file’s owner (second column) or owning group (third column). Only a couple of the files in this example allow unrestricted access (crw-rw-rw).
The others are accessible only by processes with specific UIDs.

Listing 3.1 Files in /dev

crw------- root     root     233,   0 1970-07-29 16:48 adsprpc-smd
crw-rw-r-- system   radio     10,  56 1970-07-29 16:48 alarm
...
crw-rw---- system   audio     10,  40 1970-07-29 16:48 audio_slimslave
crw-rw---- nfc      nfc       10,  70 1970-07-29 16:48 bcm2079x-i2c
crw-rw-rw- root     root      10,  62 1970-07-29 16:48 binder

crw-r----- radio    radio    230,   0 1970-07-29 16:48 hsicctl0
crw-r----- radio    radio    230,   1 1970-07-29 16:48 hsicctl1
crw-r----- radio    radio    230,  10 1970-07-29 16:48 hsicctl10
...
cr--r----- root     system    10, 183 1970-07-29 16:48 hw_random
crw------- root     root      89,   0 1970-07-29 16:48 i2c-0
...
crw-rw---- system   camera   239,   0 1970-07-29 16:48 jpeg0
...
crw-rw---- system   camera   251,   0 1970-07-29 16:48 media0
...
crw-rw---- root     mtp       10,  43 1970-07-29 16:48 mtp_usb
...
crw-rw---- radio    vpn      108,   0 1970-07-29 16:48 ppp
...
crw-rw---- system   drmrpc   244,   0 1970-07-29 16:48 qseecom
crw------- root     root      10,  92 1970-07-29 16:48 ramdump_adsp
...
crw------- root     root     232,   3 1970-07-29 16:48 smd3
crw------- root     root     232,  36 1970-07-29 16:48 smd36
crw-rw---- system   system   232,   4 1970-07-29 16:48 smd4
crw-rw---- system   system   232,   5 1970-07-29 16:48 smd5
crw-rw---- system   system   232,   6 1970-07-29 16:48 smd6
crw-rw---- bluetooth bluetooth 232,   7 1970-07-29 16:48 smd7
crw------- root     root     232,   8 1970-07-29 16:48 smd8
crw-r----- radio    radio    231,  25 1970-07-29 16:48 smd_cxm_qmi

crw-rw---- bluetooth net_bt_stack 248,   0 2017-01-22 12:16 ttyHS0
crw------- media    media    248,   3 2017-01-22 12:16 ttyHS3
crw------- root     root     247,   0 1970-07-29 16:48 ttyHSL0
crw-rw---- system   vpn       10, 200 1970-07-29 16:48 tun
crw-rw---- system   net_bt_stack  10, 239 1970-07-29 16:48 uhid
...
crw-rw-rw- root     root       1,   9 1970-07-29 16:48 urandom
crw-rw---- root     usb       10,  41 1970-07-29 16:48 usb_accessory

When Linux was first developed in the 1990s, it was designed for computers that were shared by many users. At that time, security in an operating system meant, exactly, protecting users of the same computer from each other. Although attacks from across a network were not unknown, it was far more likely that one of the users of a system would compromise another’s resources on a single system than it was that an attack would originate externally. Over years of use, the ability of the Linux system to protect individual user accounts from one another has been tested, retested, and tested again. It is quite secure.

The permissions system is what prevents the request for the scarce resource shown in Figure 3.2
from succeeding. The application’s process is not running with the user and group IDs that protect the resource and, therefore, the application does not have read or write permission on the driver. It does not have any way to obtain direct access to the resource.

Starting with KitKat, Android included an adaptation of SE Linux that further enhanced access controls. The original discretionary access control (DAC) model of permissions was not enough to prevent a system from being compromised. For example, using only DAC, a highly privileged system service (such as init), 43if compromised, might allow unfettered access to the system. SE Linux for Android introduced mandatory access control (MAC). It allows each running process to be further constrained from a security standpoint. All applications, including system processes, are assigned SE context that is enforced by the kernel. This limits the damage any one process can do, if compromised.

As Chapter 5 will demonstrate, writing and extending SE policies is a non-trivial task. Unless absolutely necessary, not altering the SE policies that are provided in the AOSP tree is best because they are CDD/CTS compliant. This is particularly important if the device is to be certified as an Android device.

The series of unblocked arrows in Figure 3.2 show how Android applications actually do get access to scarce resources when they need them. Instead of requesting the access directly, they use an interprocess communication (IPC) mechanism, Binder, to make a request to a system service. Normally, the IPC request is completely hidden from the caller because it is wrapped in in the Android API libraries. The client app sees only a call to a local method.

When the client app wants to obtain access to a scarce resource, it simply calls one of the methods in the Android API. The method call actually initiates an IPC conversation with Android service applications in one or more remote processes. These service processes, unlike the client, have the necessary security privileges that do permit them to access the scarce resource. The service can coordinate the requests as appropriate and manage access and control client use of the resource. Services provide fine-grained control over application access to the scarce resources they manage by declaring permissions. A permission is nothing more than a unique string that is recognized by the Android system. Android strictly manages permissions: Applications that want to use them must declare their intentions in their manifests and must get explicit approval from the application user before the permissions are granted. When an application requests access to a scarce resource from a service, the service can provide access in the firm knowledge that the application is acting on behalf of an informed user.

This mechanism, access to resources through a proxy service, is the key to hardware access in Android.

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.

Summary

This chapter has been a very high-level tour of the Android system. It inspects Android from three very broad points of view: as a series of layers of abstraction, starting at the hardware and ending with user applications; as a client-server architecture in which servers regulate access to scarce resources; and as a build environment, with source and tools for generating the running system.

Subsequent chapters walk up the stack illustrated in Figure 3.1, illustrating the relation between the source code and the running system and demonstrating at each layer how to customize behavior.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.224.147.211