Runtime Resource Overlay (RRO) Explained With Real AOSP Examples
If you’ve worked on AOSP customization long enough, you’ve probably heard something like:
Runtime Resource Overlay (RRO) Explained With Real AOSP Examples
Photo by The Average Tech Guy on Unsplash
If you’ve worked on AOSP customization long enough, you’ve probably heard something like:
“Don’t modify framework resources directly. Use an overlay.”
At first, that sounds simple.
Then real-world questions start appearing:
- What exactly is RRO?
- Why use RRO instead of modifying source code?
- What is the difference between static and dynamic overlays?
- Where do overlays live in AOSP?
- How does Android know which resource to replace?
- When should we use RRO and when should we modify Java business logic instead?
For many Android and Automotive developers, RRO becomes one of the first customization mechanisms they interact with.
This article walks through Runtime Resource Overlay (RRO) using real AOSP examples and explains where it fits in production customization workflows.
In this article we will cover:
- What RRO is
- Why Android introduced overlays
- Static vs Dynamic overlays
- AOSP folder structure
- Create an overlay package
- Real implementation example
- Enable and disable overlays
- Production use cases
- Common debugging commands
Why Android Needed RRO
Suppose a customer asks:
Change navigation bar color Replace launcher icon Update status bar dimensions Customize AAOS top bar layout
One option:
Modify framework code directly.
Example:
frameworks/base/core/res/
But direct changes create problems:
- difficult upgrades
- merge conflicts
- repeated maintenance
- customer-specific branches
Android introduced overlays:
Base Resource
+
Overlay Resource
↓
Final Resource
Instead of changing original files, Android replaces resources at runtime.
What Exactly Is RRO?
RRO stands for:
Runtime Resource Overlay
RRO allows one package to replace resources of another package without modifying source code.
Examples:
Replace:
<string name="car_name">
Android Automotive
</string>
With:
<string name="car_name">
My Custom Vehicle
</string>
without touching original implementation.
High-Level Architecture
Target Package
↓
Framework Resources
+
Overlay Package
↓
OverlayManagerService
↓
Modified Resources
Android decides which resources to override.
Static vs Dynamic Overlay
Static Overlay
Enabled automatically during boot.
Configured:
android:isStatic="true"
Examples:
- OEM customization
- product branding
- production UI changes
Dynamic Overlay
Enabled during runtime.
Commands:
adb shell cmd overlay enable
Examples:
- themes
- runtime customization
- feature switching
Real AOSP Folder Structure
Example:
device/company/product/overlay/
AndroidManifest.xml
res/
values/
config.xml
Another example:
vendor/company/overlay/
Automotive projects commonly use:
device/
product/
vendor/
overlay/
AndroidManifest Configuration
Example:
<manifest>
<overlay
android:targetPackage=
"com.android.systemui"
android:isStatic="true"
android:priority="10"/>
</manifest>
Important fields:
| Field | Purpose |
| ------------- | ------------------ |
| targetPackage | package to modify |
| isStatic | boot enabled |
| priority | overlay precedence |
Android.bp Example
runtime_resource_overlay {
name:"SystemUIOverlay",
product_specific:true,
theme:"SystemUIOverlay"
}
This builds overlay package.
Real Example: Modify Status Bar Height
Suppose original resource:
Location:
frameworks/base/packages/SystemUI/res/
values/dimens.xml
Original:
<dimen name="status_bar_height">
24dp
</dimen>
Overlay:
res/values/dimens.xml
Add:
<resources>
<dimen name="status_bar_height">
32dp
</dimen>
</resources>
No framework modification needed.
Real AAOS Example
Suppose customer requests:
- change top bar icon
- modify bottom bar layout
- replace dimensions
- customize spacing
Overlay:
packages/apps/Car/SystemUI
Replace:
car_top_system_bar.xml
or:
dimens.xml
without touching framework code.
Enable Overlay
List overlays:
adb shell cmd overlay list
Enable:
adb shell cmd overlay enable \
package_name
Disable:
adb shell cmd overlay disable \
package_name
Verify Active Overlay
adb shell dumpsys overlay
Check:
enabled
priority
target package
Common Production Mistake
Developers often try:
RRO everything
But overlays cannot modify:
- Java business logic
- Binder implementation
- service behavior
- controller flow
Example:
CarSystemBarController.java
If logic changes:
if(vehicleState)
RRO cannot help.
Source modification becomes necessary.
RRO vs Source Changes
Use RRO:
✅ colors ✅ dimensions ✅ strings ✅ layouts ✅ icons
Modify source:
✅ Java logic ✅ service behavior ✅ controller flow ✅ framework implementation
Useful Commands
List:
adb shell cmd overlay list
Enable:
adb shell cmd overlay enable package
Disable:
adb shell cmd overlay disable package
Dump:
adb shell dumpsys overlay
Common Interview Questions
What is RRO?
Runtime Resource Overlay.
Can RRO modify Java code?
No.
Resources only.
Difference between static and dynamic?
Static:
boot enabled
Dynamic:
runtime enabled
Which service manages overlays?
OverlayManagerService
Final Thoughts
RRO is one of the most widely used Android customization mechanisms.
It enables customization without touching framework resources directly and helps reduce maintenance overhead.
But understanding where RRO stops is equally important.
Resources
↓
RRO
Business Logic
↓
Source modification 메타데이터
- post_id
- 5689a6038daa
- slug
- runtime-resource-overlay-rro-explained-with-real-aosp-examples-5689a6038daa
- url
- https://medium.com/@codewithvikram/runtime-resource-overlay-rro-explained-with-real-aosp-examples-5689a6038daa
- canonical_url
- https://medium.com/@codewithvikram/runtime-resource-overlay-rro-explained-with-real-aosp-examples-5689a6038daa
- author_url
- https://medium.com/@codewithvikram
- status
- ok
- fetched_at
- 2026-06-12 07:40:50