AOSP Foundations
4 min read

Project Mainline Modules

Explore Project Mainline, the APEX packaging format, and how Android modularized the core OS for out-of-band updates.

While Project Treble separated the Android framework (/system) from the hardware implementation (/vendor), updating the framework still required an OEM to issue a full Over-The-Air (OTA) firmware update.

Introduced in Android 10, Project Mainline addressed this by modularizing the core Android framework itself, allowing critical system components to be updated directly by Google via Play System Updates.

The Need for Mainline

Before Android 10, if a critical security vulnerability was discovered in a core system component (such as the Media Framework or the Network Stack), Google had to patch AOSP, wait for OEMs to integrate the patch, and then wait for OEMs to push OTA updates. This left users vulnerable to exploits for months.

Project Mainline extracted these critical components from the monolithic /system partition, packaging them into independent modules that could be updated dynamically.

The APEX Format

To enable system-level updates, Google introduced a new package format called APEX (Android Pony EXpress).

Why not use APKs?

APKs are standard Android application packages. While APKs can be updated via the Play Store, they are parsed by the PackageManager relatively late in the Android boot sequence.

Many core system components (like the ART runtime or init configurations) must be loaded and active long before the PackageManager starts. An APK cannot be used to update lower-level OS components safely.

How APEX Works

An APEX file is fundamentally different from an APK. It is essentially an uncompressed ext4 file system image bundled inside a zip file.

  1. Early Boot Loading: During the boot sequence, a native daemon called apexd scans the device for APEX packages.
  2. Loopback Mounting: apexd verifies the signature of the APEX package and uses a loopback device to mount the ext4 image directly into the file system.
  3. Execution: Because it is mounted as a raw file system, the kernel and native init processes can access the executables, shared libraries, and configurations inside the APEX immediately, long before the Android framework starts.

You can inspect the currently active APEX modules on an Android device via ADB:

# List all mounted APEX modules
adb shell ls -l /apex/

# Example output:
# drwxr-xr-x 4 root root 4096 2024-01-01 12:00 com.android.art
# drwxr-xr-x 4 root root 4096 2024-01-01 12:00 com.android.media

Mainline Module Categories

Google gradually increased the number of Mainline modules with each Android release. These modules typically fall into three categories:

  1. Security: Modules that frequently patch critical vulnerabilities.
    • Examples: Media Codecs, Conscrypt (SSL/TLS), Permission Controller.
  2. Privacy: Modules that enforce user data protections.
    • Examples: ExtServices, AdServices.
  3. Consistency: Modules that standardize developer APIs across the ecosystem, preventing OEM fragmentation.
    • Examples: Android Runtime (ART), Network Stack, Time Zone Data.

The Update Process

When a Mainline module update is pushed via Google Play:

  1. The new APEX file is downloaded and staged in a specific directory (usually /data/apex/active).
  2. The system prompts the user to reboot the device.
  3. Upon reboot, apexd detects the new APEX package, validates its cryptographic signature, and loop-mounts the new version instead of the older version located in the /system partition.
  4. If a module update causes a critical boot failure, the apexd rollback mechanism detects the crash loop and automatically reverts to the previous APEX version.
// Example of an apex_manifest.json inside an APEX file
{
  "name": "com.android.tzdata",
  "version": 339990000,
  "provideNativeLibs": [],
  "requireNativeLibs": []
}

Summary

Project Mainline represents the granular modularization of the Android OS. By utilizing the APEX file format to mount system components early in the boot sequence, Google bypassed the traditional OEM OTA process. This ensures that critical security patches, runtime improvements, and consistent API behaviors are delivered rapidly and uniformly across the entire Android ecosystem.