The Framework Matrix, officially known as the Framework Compatibility Matrix (FCM), is the Android operating system's dependency contract. It meticulously details the hardware abstractions, kernel features, and SELinux policies the system partition requires to operate correctly. Understanding the FCM is critical for diagnosing boot loops and OTA update failures on Treble-compliant devices.
Framework Matrix Versioning
To manage the evolution of Android, the FCM uses a strict versioning system known as FCM Levels. Each major Android release introduces a new FCM Level, representing the updated baseline requirements for new devices.
- Android 9 (Pie): FCM Level 3
- Android 10 (Q): FCM Level 4
- Android 11 (R): FCM Level 5
- Android 12 (S): FCM Level 6
- Android 13 (T): FCM Level 7
- Android 14 (U): FCM Level 8
A system.img for a modern Android version contains multiple FCM files. For instance, an Android 14 system image will include FCMs for Level 8 (its native level), but also Levels 7, 6, and 5. This backward compatibility allows the new OS to boot on older vendor implementations, fulfilling the core promise of Project Treble.
HAL Interface Version Negotiation
When the Android framework boots, it needs to connect to the Hardware Abstraction Layers (HALs). Because the framework might be newer than the vendor image, it must gracefully negotiate interface versions.
The FCM defines acceptable version ranges. For example:
<hal format="aidl" optional="true">
<name>android.hardware.vibrator</name>
<version>1-2</version>
<interface>
<name>IVibrator</name>
<instance>default</instance>
</interface>
</hal>
When a framework service (like the VibratorService in Java) attempts to get the IVibrator HAL, it queries hwservicemanager (for HIDL) or servicemanager (for AIDL). The service manager checks the device manifest to see which version is available.
If the vendor provides version 1, the framework must adapt its behavior to only use version 1 features. The framework code typically checks the version at runtime:
// Example C++ framework code connecting to a HAL
std::shared_ptr<IVibrator> vibrator = IVibrator::fromBinder(
ndk::SpAIBinder(AServiceManager_waitForService("android.hardware.vibrator.IVibrator/default"))
);
if (vibrator != nullptr) {
int32_t halVersion;
vibrator->getInterfaceVersion(&halVersion);
if (halVersion >= 2) {
// Use new features available in version 2
vibrator->performAdvancedEffect(...);
} else {
// Fallback to basic features for version 1
vibrator->on(...);
}
}
Detecting Vendor Interface Breakage
The primary purpose of the FCM is to detect breakages before they cause harm.
During an OTA update, the update client parses the payload's system.img to extract its new FCMs. It then compares these against the device's current /vendor/etc/vintf/manifest.xml.
A breakage occurs if:
- The new FCM marks a HAL as
optional="false", but the vendor manifest does not provide it. - The new FCM requires a HAL version range (e.g.,
3.0-4.0), but the vendor provides an incompatible version (e.g.,2.0). - The new FCM requires a specific kernel
CONFIG_flag that is missing from the vendor's declared kernel configs.
If libvintf detects any of these conditions, it returns a failure, and the OTA is safely aborted, preserving the user's working system.
Frozen AIDL Interface Enforcement
With the transition from HIDL to Stable AIDL for HALs, Android enforces API stability rigorously.
When a new Android version is finalized, the AIDL interfaces are "frozen." This means their definitions cannot change. Any new features must be added in a new version of the AIDL interface.
The build system enforces this. If a developer attempts to modify a frozen AIDL file (e.g., adding a new method to version 1 of IVibrator.aidl), the build will immediately fail. The FCM relies on this freeze; when it requires android.hardware.vibrator@1, it knows with cryptographic certainty exactly what methods and data structures that interface contains, ensuring rock-solid stability across framework-vendor boundaries.