Zygote
HALs, Treble & Mainlinenerd

Project Treble

Android 8.0 drew a line through the platform. On one side the system image, on the other the vendor image, and between them a versioned, declared, testable interface that neither side could silently break.

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

Project Treble is often described as "Android 8.0 made HALs separate processes". That is true and it is the least interesting part. The interesting part is that Treble made the boundary between vendor and platform explicit, versioned and machine-checkable, which is what turned an organisational problem into an engineering one.

TL;DR#

  • Treble arrived with Android 8.0 (API 26Android 8.0) and split the device into a system image and a vendor image with a formal interface between them.
  • The interface has three parts: (the interface language, later AIDL), the (the native libraries vendors may link), and (the manifest and compatibility matrix).
  • At boot the device reconciles what the vendor provides against what the framework requires. A mismatch is meant to stop the boot.
  • The is the proof: a stock AOSP system image that boots on any compliant device demonstrates that the seam is real.
  • is the measurement: it tests the vendor implementation against the interface, separately from which tests the public API.

Mental model#

Think of a shipping container.

Before containers, every cargo was loaded piece by piece by hand, and the shape of the cargo decided the shape of the ship. After containers, the port handles a standard box and does not care what is inside. The ship, the crane and the truck are all designed around the box, not around the cargo.

Treble made the vendor image a container. The framework no longer needs to know what is inside; it needs to know the box's dimensions and that it will be where the manifest says it is.

Where the analogy breaks#

A container is one interface. A Treble device has dozens of interfaces — one per HAL — and they are versioned independently. The camera provider can be at version 2.4 while the audio HAL is at 7.1 while the keymaster HAL is at 4.1. The "interface" is a family of contracts, not a single one, and that is why the compatibility matrix is a structured document rather than a version number.

The big picture#

Loading diagram…
Text description of this diagram

A side-by-side comparison of the platform before and after Android 8.0. Before: the framework and a vendor shared library live in one address space, the library is reached by a direct C call with no version, and a framework change means a vendor rebuild. After: the framework checks a VINTF manifest and compatibility matrix, then makes a Binder call to a HAL service in its own process; the system image and vendor image can be replaced independently. A comparison table below the diagrams covers address space, call mechanism, compatibility checking, update unit and failure mode.

Deep dive#

The three-legged interface#

Treble's vendor interface is not one mechanism; it is three, and each addresses a different kind of coupling.

1. HIDL — the interface language. A .hal file declares a package, a version and an interface. hidl-gen generates the C++ (and Java) bindings, including a passthrough implementation for in-process use. The version is part of the package name: android.hardware.camera.provider@2.4. Minor versions may add types and methods but not change existing ones; published interfaces are frozen.

2. VNDK — the native library set. Vendor code does not only call HAL interfaces; it links against platform libraries. Those libraries' ABIs would otherwise change freely. The VNDK is the subset that vendor code is permitted to use, and it is versioned alongside the platform. Everything outside the VNDK is free to change.

3. VINTF — the declaration. A manifest describes what the device provides. A compatibility matrix describes what the framework requires. At boot, libvintf reads both, including files contributed by the vendor and by the platform, and checks them against each other.

The third leg is the one that turns a convention into an enforcement. Without VINTF, a vendor could claim compliance and be wrong. With it, the device refuses to boot.

Passthrough and binderized#

HIDL had two modes, and the distinction is important for understanding the migration.

Binderized means the HAL runs in its own process and is reached over Binder via hwbinder. This is the modern mode and the one Treble encourages.

Passthrough means the HAL is a shared library dlopened into the client's process, with the same interface but no process boundary. It existed to make the transition possible: an old HAL could be wrapped in a generated passthrough shim and keep working while the rest of the system moved to Binder. Devices launched with Android 8.0 or later are expected to be fully binderized.

The passthrough mode is also why some people's mental model of Treble is wrong. If you only ever saw a passthrough HAL, you saw a library, not a process — and the vendor interface was doing less work than it appears to.

The VNDK in practice#

The VNDK exists because of a specific failure mode: vendor code links against a platform library, the platform changes the library's ABI, and the vendor binary crashes at load time or, worse, at a random call site weeks later.

The rule is simple: vendor code may link only against VNDK libraries. Everything else is private to the platform. In practice this means a vendor module is built with a restricted set of headers and shared libraries, and the build system enforces it.

GSIs and the testable seam#

A Generic System Image is a stock AOSP system image built to run on any Treble-compliant device. It is the most convincing demonstration that Treble works: you replace the entire framework and the device still boots, because the only thing connecting the framework to the hardware is the vendor interface.

The GSI is used for three things:

  • Compliance: if a device will not boot a GSI, its vendor interface is not really separate.
  • Development: app developers and platform engineers can test against a known framework.
  • Upgrade testing: an OEM can check whether a new framework will work with an existing vendor image before committing to an OTA.

The GSI is not a product. It is a control experiment.

VTS versus CTS#

Both are test suites, and they test different halves.

CTSVTS
TestsThe public API and documented behaviourThe vendor interface and HAL implementations
AudienceApps and compatibilityThe vendor image and the platform boundary
Failure meansThe device is not Android-compatibleThe vendor image does not honour the contract
Licensing roleRequired for Google appsRequired for Treble compliance

A device can pass CTS and fail VTS. That combination means the public API works but the vendor interface is not what it claims. It is also the combination that produces a device which passes review and then fails to take an update.

The boot-time reconciliation#

The VINTF check happens early in boot, before system_server. If the vendor image provides a HAL at a version the framework cannot use, or omits a required HAL, the device is not supposed to proceed.

That behaviour is worth thinking about carefully. It means a mismatched OTA can brick a device into a non-booting state — and that is considered better than the alternative, which is booting into a system that half-works. It also means that when you flash a system image from a different release onto a device, the VINTF check is the thing most likely to stop you.

What it cost#

Treble was expensive in ways that are still visible.

  • Every HAL had to be rewritten or wrapped. The HIDL transition was years of vendor work.
  • The build system grew a second axis. System and vendor images became separate build targets with their own dependency rules.
  • Debugging got harder. A crash that used to be one stack trace is now two processes and a Binder transaction.
  • The vendor interface is now frozen for years. A mistake in a HAL interface is much more expensive to fix than a mistake in an internal API.

The trade was accepted because the alternative — a fork per device — was worse.

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 trajectory after 2017 is a sequence of extensions to the same idea. Mainline extended "independently updatable" from vendor code to platform code. GKI extended it to the kernel. AIDL extended the interface language from a Treble-specific IDL to the one the rest of the platform already used. Each step made the same move: find a boundary, formalise it, and make it checkable.

Under the hood#

  • the HAL tree; each directory is a package with versioned interfaces
  • the manifest/matrix reconciliation, including the runtime VINTF object
  • current.txtthe frozen HAL API surface for a release
  • the Vendor Test Suite

Curiosity corner#

  • The GSI is a stock AOSP image with no vendor customisation at all. That is the point: if your phone boots it, your vendor interface is clean.
  • The compatibility matrix is versioned by framework version, not by device. A device carries one vendor manifest and the framework carries the matrix that applies to it.
  • VINTF fragments exist so that separate partitions can each contribute. /vendor and /odm can both declare HALs without editing one another's files.

Try it#

Inspect the vendor interface

adb shell cat /vendor/etc/vintf/manifest.xml | head -40 adb shell getprop ro.vndk.version adb shell getprop ro.treble.enabled adb shell ls /vendor/etc/vintf/manifest_fragments 2>/dev/null

The manifest is the vendor's declaration. The ro.vndk.version property tells you which VNDK generation the vendor code was built against.

Check yourself#

Check yourself

1 / 12

What was the core technical barrier that kept Android phones on old software before 2017?

0 answered · 0 correct

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. docsVendor interface objects (VINTF)source.android.comaccessed 2026-10-27↩
  2. docsVendor NDK (VNDK)source.android.comaccessed 2026-10-27↩
  3. docsHIDLsource.android.comaccessed 2026-10-27↩
  4. docsHardware abstraction layers (HALs)source.android.comaccessed 2026-10-27↩
  5. docsCompatibility Test Suite (CTS)source.android.comaccessed 2026-10-27↩
  6. docsAndroid Compatibility Definition Document (CDD)source.android.comaccessed 2026-10-27↩
  7. docsVerified boot flowsource.android.comaccessed 2026-10-27↩
  8. docsAIDL for HALssource.android.comaccessed 2026-10-27↩