The complete stack
Android is a stack of layers, and each one only talks to its neighbours. Apps see the framework, the framework sees native libraries and the runtime, and everything below the HAL belongs to the hardware.
Applications
- System apps
- Third-party apps
Application framework
- Activity Manager
- Package Manager
- Window Manager
- Telephony Manager
- Location Manager
- Resource Manager
- Content Providers
- View System
Libraries and runtime
Native C and C++
- libc (bionic)
- Media framework
- OpenGL ES
- SQLite
- SSL
- WebKit
Android Runtime
- ART, ahead of time
- JIT compiler
- Core libraries
- Memory management
Hardware abstraction layer
- Audio HAL
- Camera HAL
- Sensors HAL
- and the rest
Linux kernel
- Drivers
- Memory management
- Process management
- I/O
From Make to Soong
Android grew too large for plain Make. The build first sped Make up, then replaced the way modules are described altogether.
Android.mk
Modules described in Make
Kati
Google's Make clone, much faster at parsing
Ninja
Runs the actual commands
Images
system.img, vendor.img and friends
Android.bp
Declarative Blueprint files
Soong
A Go program that reads them
Ninja
Runs the actual commands
Images
The same output
Both paths meet at Ninja, which is why a mixed tree of .mk and .bp files still builds as one.
Build commands
Set up the environment once per shell, then pick what to build.
source build/envsetup.sh
hmm
lunch aosp_arm64-engBuild everything, one module, or a directory:
m
m Settings
mm
mma
mmm packages/apps/Settings packages/apps/Launcher3
mmma packages/apps/Settings frameworks/base
m -j8
m -kmm builds the modules in the current directory, mma adds their dependencies, and mmm and mmma do the same for directories you name. -k keeps going when some targets fail.
Search the tree and move around it:
cgrep "pattern"
jgrep "pattern"
resgrep "pattern"
mangrep "pattern"
sepgrep "pattern"
sgrep "pattern"
godir filename
gomod module_name
pathmod module_name
refreshmod
allmodInspect the build and clean it:
m showcommands
m dist
m checkbuild
m modules
m clean-Settings
m installclean
m clobberWhere things live in the source
art/The Android Runtimecompiler/AOT and JIT compilersruntime/The runtime itselfdex2oat/Turns DEX into OATbionic/Android's C librarylibc/The C librarylibm/Mathslinker/The dynamic linkerframeworks/System services and APIsbase/Framework APIs and servicescore/java/android/services/core/native/av/Audio and videosystem/Core OS piecescore/init, logd and friendssepolicy/SELinux policyvold/The volume daemonhardware/HAL implementationsinterfaces/HAL interfaceslibhardware/The legacy HAL
The boot process
From the power button to the home screen, each stage hands over to the next.
Power on
The power management unit brings the hardware up.
Bootloader
Basic hardware checks, loads the kernel into memory, and offers recovery and fastboot.
Kernel
Initialises drivers, sets up memory management and starts the core subsystems.
init
Mounts filesystems, loads the SELinux policy, starts the property service and parses init.rc.
Zygote
Creates the runtime, preloads common classes and resources, and waits to launch apps.
system_server
Starts ActivityManager, PackageManager, WindowManager and PowerManager.
System UI
Brings up the status bar and navigation, then launches the home screen.
How system_server starts services
system_server starts its services in three passes, so that the ones everything else depends on are ready first.
startBootstrapServices()
- Installer
- ActivityManager
- PowerManager
- DisplayManager
- PackageManager
- SensorService
startCoreServices()
- BatteryService
- UsageStatsService
- WebViewUpdateService
- GpuService
startOtherServices()
- CameraService
- AlarmManager
- InputManager
- WindowManager
- BluetoothService
- AudioService
- NotificationManager
Device and board configuration
A device is described in two makefiles. device.mk says what the product is and what goes into it:
PRODUCT_NAME := aosp_device
PRODUCT_DEVICE := device
PRODUCT_BRAND := vendor
PRODUCT_MODEL := Device Name
PRODUCT_MANUFACTURER := Vendor
$(call inherit-product, device/vendor/device/device-common.mk)
DEVICE_PACKAGE_OVERLAYS += device/vendor/device/overlayBoardConfig.mk describes the hardware it runs on:
TARGET_ARCH := arm64
TARGET_CPU_ABI := arm64-v8a
TARGET_CPU_VARIANT := cortex-a53
TARGET_KERNEL_SOURCE := kernel/vendor/device
TARGET_KERNEL_CONFIG := device_defconfig
BOARD_BOOTIMAGE_PARTITION_SIZE := 67108864
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3221225472Runtime resource overlays
An overlay replaces resources in another package without touching its source. At runtime the app sees one merged set.
The app's resources
res/values/res/layout/res/drawable/
The overlay
overlay/res/values/
What the app sees
values, from the overlaylayout/drawable/
Making builds faster
Cache C and C++ compilation:
export USE_CCACHE=1
export CCACHE_DIR=/path/to/ccache
prebuilts/misc/linux-x86/ccache/ccache -M 50GThen rebuild only what changed, on every core:
m installclean && m
m -j$(nproc)
mmm frameworks/base/servicesA change, start to finish
Change
git statusgit addgit commit
Build
mmmma
Test
atestCTS and VTS
Debug
logcatdebuggerdsystrace
Submit
repo uploadGerrit review