Understanding Android's Trichrome Architecture
This article provides a comprehensive overview of the Trichrome architecture introduced in Android 10. It explains the historical evolution of Chrome and Android System WebView packaging, defines the three core components that make up Trichrome, and details the exact technical mechanisms—such as Android static libraries and memory mapping—that allow the Chromium browser and WebView to share native code, ultimately saving device storage, memory, and bandwidth.
The Evolution Before Trichrome
To understand Trichrome, it is necessary to look at how Android previously handled Chrome and the Android System WebView (the component that allows third-party apps to display web content). Both rely on the exact same underlying Chromium rendering engine, which consists of a massive amount of compiled C++ native code.
- Android 5 to 6 (Standalone): Chrome and WebView were completely separate apps. They duplicated the massive Chromium native library on the device, wasting disk space, RAM, and download bandwidth.
- Android 7 to 9 (Monochrome): Google combined Chrome and WebView into a single APK called Monochrome. The Chrome APK acted as both the browser and the WebView provider. While this saved space and RAM, it created a major issue: if a user disabled the Chrome app, the system lost its WebView provider, forcing a fallback to a separate, outdated standalone WebView APK.
What is the Trichrome Architecture?
Introduced in Android 10, Trichrome solves the limitations of Monochrome by splitting the browser, the WebView, and their shared code into three distinct APKs.
The three components of Trichrome are:
- TrichromeChrome.apk: Contains only the Java code and resources specific to the Chrome browser interface and features.
- TrichromeWebView.apk: Contains only the Java code and resources required to run the Android System WebView.
- TrichromeLibrary.apk: A shared static library APK
that contains the massive compiled native C++ Chromium engine
(
libmonochrome.so) and common resources used by both Chrome and WebView.
How Trichrome Shares Native Library Code
Trichrome relies on specific Android OS features to allow two separate applications to execute the same native binary code from a third package.
1. Android Static Shared Libraries
Trichrome utilizes Android's shared library mechanism. The
TrichromeLibrary.apk is defined in its
AndroidManifest.xml using the
<static-library> tag. Conversely, both the Chrome and
WebView APKs declare a dependency on this library in their respective
manifests using the <uses-static-library> tag.
This declaration instructs the Android Package Manager to link the
applications together. It grants the Chrome and WebView processes
permission to access the code and resources stored inside the
TrichromeLibrary.apk file path. Because static libraries on
Android are versioned, both Chrome and WebView must be updated to match
the exact version of the Trichrome Library they are targeting.
2. Uncompressed Native Libraries and Memory Mapping
In the TrichromeLibrary.apk, the compiled native
Chromium code (libmonochrome.so) is stored uncompressed and
aligned on page boundaries.
Because the native library is not compressed, the Android system does
not need to extract it to a separate directory upon installation. Both
Chrome and WebView can load and execute the native code directly from
the TrichromeLibrary.apk file sitting on the disk.
3. Kernel-Level Memory Sharing
The primary benefit of sharing native code is reducing RAM usage.
When Chrome runs, and when a third-party app initializes a WebView,
their respective processes load libmonochrome.so into
memory using the mmap (memory map) system call.
Because both Chrome and WebView are mapping the exact same physical
file from the disk (inside TrichromeLibrary.apk) at the
exact same file offsets, the underlying Linux kernel recognizes that the
data is identical. The kernel loads the read-only segments of the native
library into physical RAM only once, sharing those physical memory pages
across the Chrome process and all active WebView processes.
4. RelRO (Relocation Read-Only) Sharing
Native libraries contain a section of memory called RELRO, which holds pointers that are dynamically updated when the library is loaded into a specific process's memory space. Because these pointers change, this memory is normally marked as writable, meaning the Linux kernel cannot share it between processes.
Trichrome overcomes this by creating a shared RELRO file. When the Android system initializes the WebView Zygote (a special process that spawns WebViews), it calculates the RELRO data and saves it to a shared memory file. When Chrome or other WebView processes start, they load the native library at the exact same virtual memory address and map that pre-calculated RELRO file as read-only. This allows the processes to share even the dynamically linked portions of the native library in RAM.
Benefits of the Trichrome Architecture
- Disk Space Savings: The heavy C++ Chromium engine is stored on the device only once inside the Trichrome Library APK.
- Reduced RAM Usage: By loading the native code from the same physical file, the OS kernel shares the memory pages between the browser and any app using WebView.
- Independent App States: Unlike Monochrome, users or enterprise administrators can completely disable the Chrome browser without breaking the Android System WebView, as the WebView APK and the Library APK remain active.
- Smaller Updates: If Google needs to push a fix that
only affects the Chrome UI (Java code), users only need to download the
small
TrichromeChrome.apkupdate rather than redownloading the entire native engine.