Zygote
AOSP source tourintermediate

The directory map

Where everything lives, top to bottom: what frameworks/base actually contains, why packages/apps is not the framework, what system/core owns, and which directories are reference targets rather than platform code.

12 minAPI 1–37 · 17interactiveverified 2026-10-27

AOSP's top-level directories are a map of the platform's responsibilities, and most of them are named after what they own rather than what they do. This page is the legend.

TL;DR#

  • frameworks/ is the platform itself: base/ holds the Java framework and the system services, native/ holds SurfaceFlinger and the native services, av/ holds the media stack.
  • packages/ holds the system apps and providers: Settings, Launcher3, SystemUI, and the contacts and media providers. They are apps, not platform code, even though they ship with it.
  • system/ is the low-level user space: core/ has init and the daemons, sepolicy/ has the SELinux policy.
  • art/, bionic/ and libcore/ are the runtime and the C and Java libraries that every process uses.
  • hardware/ contains the HAL interfaces; device/ and vendor/ are mostly reference targets in AOSP and are where an OEM's tree takes over.

Mental model#

Think of a ship's manifest.

The engine room and hull are system/, bionic/ and the kernel-facing code. Nobody visits unless something is wrong.

The bridge and navigation are frameworks/: the services that decide what happens.

The cabins and public rooms are packages/: what passengers see.

The shipyard drawings are build/: how the whole thing is assembled.

And the port authorities' paperwork is hardware/: the interface between this ship and the docks it visits.

Where the analogy breaks#

On a ship, the manifest is stable. AOSP's structure has been reorganised by Treble and Mainline, so some components that used to live in frameworks/base now live in packages/modules/ with their own APEX. The map is accurate for the platform's shape but not always for a specific component's location: when in doubt, search rather than assume.

The big picture#

Loading diagram…
Text description of this diagram

A treemap of the AOSP top-level directories sized by relative code weight. frameworks is the largest group, with base as its largest child, followed by native, av and libs. packages is the second group, with apps the largest child, then providers, input methods and modules. system contains core, sepolicy and helper libraries. art contains runtime and compiler. hardware contains interfaces and the legacy C HAL libraries. bionic contains libc and the linker. build contains soong and the legacy make tree. device and vendor contain reference device configurations.

Click a group in the treemap and the panel tells you what it owns. The useful exercise is to find the directory for a component you already know: SystemUI is in packages/apps, but the window manager it talks to is in frameworks/base/services. That split is the map's most important lesson.

Deep dive#

frameworks/ — the platform#

frameworks/base/ is the core. It contains two things that are easy to confuse:

  • core/java/ — the Java and Kotlin classes that make up the android.* API. This is what an app compiles against and what the SDK stubs are generated from.
  • services/ — the implementation of the system services, most of which run inside system_server. services/core/java/com/android/server/ is where ActivityManagerService, PackageManagerService, WindowManagerService and the rest live.

The split matters: core/ defines the contract, services/ implements it. A method you call on PackageManager is usually a facade in core/ that forwards over Binder to a service in services/.

frameworks/native/ is C++ and holds the native services: SurfaceFlinger, the input dispatcher, the sensor service, and the Binder libraries. When a Java service needs to draw or to receive input, the code that does it is here.

frameworks/av/ is the media framework: codec2, the camera stack, audio, and the media session machinery.

frameworks/libs/ holds support libraries shared across the framework: networking helpers, HWUI (the hardware-accelerated UI renderer), and the input library.

packages/ — the system apps#

packages/apps/ contains Settings, Launcher3, SystemUI, Dialer, Camera2 and the rest. They are ordinary APKs with privileged permissions and platform signing, and they are not part of system_server. That distinction is why SystemUI can crash and restart without taking the system down.

packages/providers/ contains the content providers for contacts, calendar, media and downloads. They are where a lot of the shared data model lives, and they are a good place to read if you want to see ContentProvider used at scale.

packages/modules/ is the Mainline tree: the components that ship as APEX modules and can be updated without a full OS update.1 This is the directory that changed most in the platform's recent history, and it is where the "is this part of the OS?" question gets complicated.

system/ — the low-level user space#

system/core/ contains init, logd, adbd and the fundamental daemons. system/core/init/README.md is the definitive description of the init language, and system/core/rootdir/init.rc is the main configuration file that starts the system.2

system/sepolicy/ contains the SELinux policy sources. This is where the rules that confine every process are written. It is dense and worth reading only with a specific question.

system/ also contains vold (the volume daemon), netd (networking), and the media and audio daemons. If a process appears in ps and is not an app, it is likely started from here.

art/, bionic/, libcore/ — the runtime and libraries#

art/ is the Android Runtime: the interpreter, the JIT, the AOT compiler, the garbage collector, and the JNI bridge. Mostly C++ with per-architecture assembly.

bionic/ is Android's C library: libc, libm, the dynamic linker. Every process links against it. It is deliberately smaller than glibc and designed for mobile constraints.

libcore/ is the Java core library: the implementation of java.* and javax.* that Android ships, based on OpenJDK.

These three are the parts of the platform that every app depends on and almost no app developer reads. They matter for performance, for ABI compatibility and for security.

hardware/ — the interface to the device#

hardware/interfaces/ contains the versioned HAL interface definitions: the AIDL and HIDL files that the vendor image and the framework agree on. hardware/libhardware/ contains the older C HAL loading mechanism.

This is the directory that Treble formalised. Before Treble, a HAL was often a shared library loaded into the framework process; after it, HALs are separate processes behind a versioned interface.3

The hidden glue: generated and overlays#

Two directories are frequently overlooked because they do not contain the code that runs.

frameworks/base/core/res/ holds the platform's own resources: the system theme, the default strings, the drawables that system UI uses. A change here can alter every app's appearance, because the platform resources are the fallback for every theme.

frameworks/base/packages/ holds framework packages that are not system apps in the usual sense: the Settings Provider, the shared storage backup agent, and the framework's own overlays. They ship with the framework rather than as separate apps.

Overlays are their own small world. product/, vendor/ and device/ trees often contain RRO packages that change resources in a target without editing it. When a string or a colour does not match the source, an overlay is the first thing to check.

build/ — how it is assembled#

build/soong/ is the Go implementation of the build system. build/make/ is the legacy Make build and the Kati translation layer. build/release/ contains the release configurations that trunk-stable builds select between.

The build is not incidental to reading the source. Android.bp files tell you what a module is, what it depends on, and whether it is platform code, an app, or a vendor component.

The directories that surprise people#

A few paths are not where you expect, and knowing them saves a search.

libcore/ is not under frameworks/. It is its own top-level project. The Java core library lives beside the platform rather than inside it because it is maintained as a separate body of code with its own upstream relationship to OpenJDK.

external/ is a top-level directory full of other people's code. The JSON parser, the image decoders, the compression libraries and the SQLite engine all live there. It is the largest directory by project count and the one you should read last, because a bug in it is usually not an Android bug.

test/ and tools/ are top-level. The platform's own test infrastructure and developer tools are not inside a subsystem. test/vts/ is the vendor test suite; tools/ contains the scripts that the build and CI use.

pdk/ and platform_testing/ exist in some checkouts and are easy to mistake for platform code. They are packaging and test configuration, and a change there affects how the platform is assembled or tested rather than what it does.

device/ and vendor/ — reference targets#

In AOSP, device/ contains reference configurations: the emulator, Cuttlefish, and Google's reference devices. A real phone's device tree comes from the OEM, not from AOSP. vendor/ is mostly empty in AOSP and is populated by the OEM's tree.

This is why "build AOSP for your phone" is not really a thing: your phone's device configuration is not in AOSP. You build AOSP for a reference target, or you build your OEM's tree.

How it evolved#

The updatability story9 releases
APIVersionWhat changed
11.0
  • Initial AOSP platform: Linux kernel, Dalvik VM, core libraries
174.2 Jelly Bean
  • SELinux enforcement begins in the kernel (behind the scenes)
194.4 KitKat
  • Kernel moved under a tighter vendor control
236.0 Marshmallow
  • Fingerprint HAL
247.0 Nougat
  • Project Treble groundwork
268.0 Oreo
  • Project Treble: the vendor interface separates vendor and system code
  • HIDL for HALs
289 Pie
  • Mainline groundwork
2910
  • Project Mainline: APEX and updatable system modules
  • Project Mainline starts shipping through Play
3011
  • GKI: the Generic Kernel Image splits the kernel into core + vendor modules

The treble rows show why the map keeps changing: each modularity project moved a boundary, and a moved boundary moves code. packages/modules/ is the newest major addition to the top-level map.

Under the hood#

  • the android.* API surface that apps compile against
  • the system services, mostly running inside system_server
  • README.mdthe init language that starts the native layer

Curiosity corner#

  • SystemUI is an app, not the framework. It lives in packages/apps, is signed with the platform key, and can restart without rebooting the device.
  • frameworks/base is not one module. Its Android.bp defines many modules, including the framework library, the services library and the test suites.
  • device/ is reference only. Your phone's device tree is not in AOSP, which is why AOSP builds target emulators and reference devices.

Try it#

Explore a checkout
repo list | head -40
ls frameworks/base
ls packages/apps
ls system/core
Example output
Illustrative — requires a local AOSP checkout.

Build it#

N01 — Build and boot AOSP walks through a checkout and a build, which is the practical version of this map.

Check yourself#

Three questions to answer without looking back. Open each one only after you have tried.

1. What does a Manager object in your app actually hold? A Binder proxy to a service, not the service itself. The policy lives on the service side, usually in system_server, and every call crosses a process boundary.

2. Why does the build use a declarative Android.bp instead of a script? Because a declarative module definition can be analysed. Soong can build a complete dependency graph before running anything, which is what makes Ninja parallel and incremental. Conditionals in a script would make the graph depend on execution.

3. What is the difference between reading a facade and reading a service? The facade defines the public contract — validation, defaults, deprecation. The service implements the behaviour and holds the state. A bug in behaviour is almost always on the service side; a compatibility question is almost always on the facade side.

Sources#

Sources

Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.

  1. docsModular system componentssource.android.comaccessed 2026-10-27↩
  2. sourcesystem/core/rootdir/init.rcandroid.googlesource.comaccessed 2026-10-27↩
  3. docsHardware abstraction layers (HALs)source.android.comaccessed 2026-10-27↩
  4. docsAndroid platform architecture (AOSP)source.android.comaccessed 2026-10-27↩
  5. docsBuild Androidsource.android.comaccessed 2026-10-27↩