Back to Architecture Deep Dive

Android Layer 4: Native Userspace

Android Internals Team
2026-02-08
5 min read

Android Layer 4: Native Userspace

[!NOTE] Official AOSP Definition: Native daemons and libraries in this layer (such as init, healthd, logd, storaged, libc, liblog, libbinder) interact directly with the kernel or other interfaces and don't depend on a userspace-based HAL implementation. This distinguishes them from HAL components which provide hardware abstraction.

Native Libraries (C/C++)

This layer provides the high-performance building blocks for the OS. It includes:

  1. Bionic (libc): Android's custom C standard library, optimized for mobile (smaller, faster than glibc).

Bionic vs glibc

Featureglibc (Linux)Bionic (Android)
Size~2.5 MB~1 MB
StartupSlowerFaster (optimized for Zygote fork)
ThreadingNPTL (full POSIX)Custom (lighter, faster)
DNSnsswitchNetD integration
LocaleFull ICUMinimal (saves RAM)
Dynamic Linkerld.solinker64 (namespace isolation)
POSIX ComplianceFullPartial (mobile-optimized)

Why Bionic?

  • Memory: Smaller footprint critical for devices with limited RAM
  • Speed: Optimized for fork() performance (Zygote model)
  • Security: Custom allocator with hardening features
  • Isolation: Linker namespaces enforce Treble separation

Bionic sacrifices some POSIX compatibility for speed and size, but provides all APIs needed for Android.

📁 AOSP Source: bionic/

  1. SurfaceFlinger: The display compositor that combines all app surfaces into the final frame buffer.

SurfaceFlinger: The Display Compositor

SurfaceFlinger is the native daemon responsible for compositing all app surfaces into the final frame buffer displayed on screen.

How it works:

  1. Apps render to Surfaces (backed by BufferQueues)
  2. SurfaceFlinger receives Surface Layers from multiple apps
  3. It composites them using the Hardware Composer (HWC) HAL
  4. The final frame is sent to the display driver

Key Concepts:

  • VSync: Synchronization signal (60Hz = 16.6ms per frame, 120Hz = 8.3ms)
  • Triple Buffering: Prevents tearing (front/back/pending buffers)
  • HWC Offloading: Modern GPUs can composite layers in hardware (saves CPU/GPU power)
  • BufferQueue: Producer-consumer pattern for graphics buffers

Composition Modes:

  • Client Composition: GPU renders all layers (power-hungry)
  • Device Composition: HWC composites in hardware (efficient)
  • Hybrid: Mix of both (common in practice)

📁 AOSP Source: frameworks/native/services/surfaceflinger/

  1. Media Framework: Codecs for audio/video playback (Stagefright).
  2. AudioFlinger: The audio server that mixes multiple audio streams (music, notifications, calls) into a single PCM stream for the hardware.
  3. WebCore/Skia: Rendering engines for WebView and 2D graphics.
  4. BoringSSL: Google's fork of OpenSSL, providing cryptographic functions (SSL/TLS, certificate validation, encryption/decryption) used throughout Android.

BoringSSL: Android's Crypto Library

BoringSSL is Google's maintained fork of OpenSSL, optimized for Android and Chrome.

Why BoringSSL instead of OpenSSL?

  • Stability: Google removed rarely-used features to reduce attack surface
  • API Simplification: Cleaner API, easier to maintain
  • Security: Faster security patches, no legacy baggage
  • Size: Smaller binary footprint (critical for mobile)

What uses BoringSSL:

  • HTTPS connections (all network traffic)
  • Certificate validation (Play Store, system updates)
  • VPN connections (IPsec, WireGuard)
  • Bluetooth pairing (encryption)
  • Keystore operations (hardware-backed crypto)

Check BoringSSL version:

📁 AOSP Source: external/boringssl/


Linker Namespaces & VNDK

To enforce Project Treble (separating System from Vendor), Android uses Linker Namespaces.

  • The Problem: In the past, Vendor apps would link to internal System libraries. When Android updated, these internal libs changed, crashing the Vendor apps.
  • The Solution: The dynamic linker (/system/bin/linker64) prevents Vendor processes from opening /system/lib64/*.
  • The Bridge (VNDK): Google designates a specific set of stable system libraries (like libc.so, liblog.so) as VNDK (Vendor NDK). These are the only system libraries that vendor code is allowed to use.

Native Daemons (Init & Services)

These are background processes written in C++ that start at boot and keep the system running.

Init Boot Sequence

1. Init (PID 1)

The grandfather of all processes. It is the first user-space process started by the Kernel.

  • Role: Parses /init.rc configuration files to start specific daemons and mount filesystems.

System Properties

Init also manages System Properties, a global key-value store acting as a system registry.

Triggers: Changing a property can trigger actions in init.rc (e.g., on property:sys.boot_completed=1).

Boot Stages:

  1. First Stage Init: Minimal environment, mounts /system and /vendor.
  2. SELinux Setup: Loads security policies.
  3. Second Stage Init: Parses .rc files and starts system services.

2. Service Manager (Binder Context)

The "Phone Book" of Android. When a client (like an App) wants to talk to a system service (like LocationManager), it asks Service Manager for the handle.

  • Context Manager: It is the special Binder node 0.
  • Registration: All system services register themselves here by name.

3. Logd (Log Daemon)

Manages the logcat buffers. When you run adb logcat, you are talking to logd.

4. Installd

Responsible for installing APKs, creating directories, and performing DEX optimization (dex2oat calls).

5. Vold (Volume Daemon)

Manages storage devices (mounting SD cards, encrypting data partitions).

6. Netd (Network Daemon)

Configures network interfaces, firewalls (iptables), and tethering. It essentially manages the Linux networking stack for Android.

<div id="keystore"></div>

7. Keystore / Keystore2

The hardware-backed security storage for cryptographic keys. It ensures keys are generated and used inside a TEE (Trusted Execution Environment) and never exposed to the OS logic.

8. Media & Camera Services

Android splits media handling into specialized daemons to improve stability and security.

  • audioserver: Hosts AudioFlinger (mixing) and AudioPolicyService (routing types). If this crashes, your music stops, but the phone doesn't reboot.
  • cameraserver: Manages access to camera hardware (multiple apps can't open camera at once).
  • mediaserver: Hosts Stagefright (handling playback, recording, and codecs).
  • drmserver: Handles DRM (Digital Rights Management) for protected content (Widevine).

9. Core Infrastructure Daemons

Crucial for system stability and maintenance.

  • tombstoned: The Crash Reporter. When a native process crashes (segmentation fault), it connects here to write a stack trace (tombstone) to /data/tombstones/.
  • lmkd (Low Memory Killer Daemon): Monitors memory pressure. When RAM is full, it kills cached apps based on their OOM Score to keep the system responsive.
  • statsd: Collects metrics (battery usage, app starts) for system analysis.

10. adbd (Android Debug Bridge Daemon)

The daemon that talks to your computer when you run adb commands.

  • User builds: Runs as shell user (limited permissions).
  • Userdebug builds: Can run as root (full control).

11. VINTF (Vendor Interface) Object

VINTF (Vendor Interface Object) is the compatibility enforcement mechanism for Project Treble. It ensures that the Android Framework (from Google) can work with vendor HAL implementations (from OEMs like Samsung, Qualcomm).

The Problem VINTF Solves: Before Treble, if Google updated the Framework to require a new HAL version, old vendor implementations would break. VINTF prevents this by declaring requirements upfront.

Two Key XML Files:

  1. Device Manifest (/vendor/etc/vintf/manifest.xml)

    • Owner: OEM/Vendor
    • Purpose: Declares which HALs the device provides
    • Example: "I provide Camera HAL 3.5, Audio HAL 7.0"
  2. Framework Compatibility Matrix (/system/etc/vintf/compatibility_matrix.xml)

    • Owner: Google/AOSP
    • Purpose: Declares which HAL versions the Framework requires
    • Example: "I require Camera HAL ≥ 3.2, Audio HAL ≥ 6.0"

How It Works:

Boot Time:
1. init reads Device Manifest (what vendor provides)
2. init reads Framework Compatibility Matrix (what Framework needs)
3. If vendor HALs meet Framework requirements → Boot succeeds ✅
4. If vendor HALs are too old → Boot fails ❌ (prevents crashes)

Check VINTF Compatibility:

Example Manifest Entry:

Why This Matters:

  • Prevents Boot Failures: Incompatible vendor images won't boot
  • Enables Treble: Framework and Vendor can update independently
  • Clear Contracts: OEMs know exactly what HALs to implement

VINTF Compatibility Check Flow:

📁 Official Documentation: VINTF Objects

12. APEX Daemon (apexd)

APEX (Android Pony EXpress) is a container format introduced in Android 10 that allows updating core OS components (like the ART Runtime, Media Codecs, or Native Libraries) via the Google Play Store, without a full system update.

  • apexd: The native daemon responsible for verifying and mounting APEX files at boot.
  • Mount Point: APEX files are mounted as individual filesystems under /apex/ (e.g., /apex/com.android.art).
  • Benefit: Allows Google to push security patches to the Runtime faster.

APEX File Structure:

Components:

  • Outer Zip Container (blue box):
    • apex_manifest.json - Name, version, dependencies
    • AndroidManifest.xml - Android package metadata
    • apex_pubkey - Google's public key for verification
    • apex_payload.img - ext4 filesystem image
  • Inner Payload (green box - apex_payload.img):
    • apex_manifest.json - Duplicate manifest inside payload
    • bin/myservice - Native executables
    • lib/libFoo.so - Native libraries (.so)
    • javalib/bar.jar - Java libraries (.jar)

Mounting Process:

  1. Verify: apexd checks signature using apex_pubkey
  2. Extract: Unpack apex_payload.img from the zip
  3. Mount: Mount as loopback device at /apex/[package.name]

Check APEX modules:

Init Language (.rc files)

Android uses a custom language for boot scripts:

📁 Official Documentation: Android Init Language