What is RRO in Android
RRO stands for Runtime Resource Overlay. These are the applications that can change the resource value of the target application on runtime. As an example, suppose there is a need to change the default behavior of the long press of the Power button (normally by default AOSP starts the voice assistance app), this can be done dynamically, without a need to rebuild the complete system image. Instead, an RRO can be installed and enabled on the device
All such device build resources that can be overlaid runtime can be found in this config.xml
The above resource XML is for the framework. Similarly, there are many modules in AOSP whose resources can be modified using RRO. For example, SystemUI, Telephony, etc.
Config for the SystemUI module can be found here:
Please note that RRO can modify/change the value of ONLY existing resources. It cannot add a new resource to the target application.
RRO are the applications that do NOT contain any code. These are meant to contain only resource files as they can ONLY overlay the resources of the target application and NOT the source code.
How to Enable/Disable RRO
Programmatically
Accessible only to system apps. Can't be done by 3rd party apps
OverlayManager API can be used to enable and disable overlays. The API is AOSP internal and not available for 3rd party apps.
try {
IOverlayManager overlayManager = IOverlayManager.Stub.asInterface(
ServiceManager.getService(Context.OVERLAY_SERVICE));
overlayManager.setEnabled(getPackageName(),
true, ActivityManager.getCurrentUser());
} catch (Exception e) {
Log.d(TAG, "Exception in enabling overlay: " + e);
}
Android is introducing new APIs related to overlay, and it will be available from Android U onwards. These APIs need to be explored more.
Please refer to the documentation for 3rd party APIs here
An overlay can be enabled only by the package it targets OR by a package with android.permission.CHANGE_OVERLAY_PACKAGES
permission
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<overlay
android:isStatic="false"
android:priority="1"
android:targetPackage="com.sap.dev.rro.target" />
</manifest>
Please refer to AndroidManifest of OverlayApp on how to define the application manifest - AndroidManifest.xml
Using ADB command
Once the target and overlay apps are installed on the device, we can use this adb command to enable the RRO
adb shell cmd overlay enable [overlay app package name]
When an overlay is enabled or disabled, configuration change events propagate to the target package and target activities relaunch.
Note: The target application and RRO application should be signed with the same certificate, or else the installation of the RRO will fail.
Debugging RRO
(ROOT access required)
OverlayManagerService uses idmap2 to map resource IDs in the target package to resource IDs in the overlay package. The generated ID mappings are stored in /data/resource-cache/. If your overlay isn't working correctly, find the corresponding idmap file for your overlay in /data/resource-cache/
# adb shell
Samsung:/ # cd /data/resource-cache
Samsung:/data/resource-cache # ls
com.android.systemui-accent-GHGr.frro
com.android.systemui-neutral-xHMl.frro
data@app@~~IyuBI7PKSlrS-bM6uglX5g==@com.sap.dev.rro.overlay-dLDfxEMBPMAIVPFAlAHPiQ==@base.apk@idmap
data@resource-cache@com.android.systemui-accent-GHGr.frro@idmap
data@resource-cache@com.android.systemui-neutral-xHMl.frro@idmap
then run the following command
adb shell idmap2 dump --idmap-path /data/resource-cache/[your app's idmap]
adb shell idmap2 dump --idmap-path /data/resource-cache/data@app@~~IyuBI7PKSlrS-bM6uglX5g==@com.sap.dev.rro.overlay-dLDfxEMBPMAIVPFAlAHPiQ==@base.apk@idmap
The output will be something like this:
Paths:
target path : /data/app/~~Z6zkP0Z6UrZfYFTe7JegMw==/com.sap.dev.rro.target-5poKNIbj_jjSdqmBGH89bA==/base.apk
overlay path : /data/app/~~IyuBI7PKSlrS-bM6uglX5g==/com.sap.dev.rro.overlay-dLDfxEMBPMAIVPFAlAHPiQ==/base.apk
Mapping:
0x7f0f001c -> 0x7f010000 (string/app_name -> ???)
0x7f0f008f -> 0x7f010001 (string/overlay_me -> ???)
As we can see this displays the path information of both the applications - Target app (com.sap.dev.rro.target) and Overlay app (com.sap.dev.rro.overlay) along with the resource mapping.
So the resource ID of the target app for app_name (id=0x7f0f001c) is mapped to app_name (id=0x7f010000) defined in overlay app and the resource ID of the target app for overlay_me (id=0x7f0f008f) is mapped to overlay_me (id=0x7f010001) defined in overlay app
List RRO on the device
To view all the overlay available on the device, we can use command
adb shell cmd overlay list
The output of this will list out all the applications along with the corresponding overlay's installed on the device along with their enabled state (marked as [x] OR [])
Sample output is
com.android.carrierconfig
[x] com.android.carrierconfig.overlay.common
android
[ ] com.android.internal.display.cutout.emulation.corner
[ ] com.android.internal.display.cutout.emulation.double
[ ] com.android.internal.systemui.navbar.gestural_wide_back
[ ] com.android.internal.display.cutout.emulation.hole
[ ] com.android.internal.display.cutout.emulation.tall
[ ] com.android.internal.systemui.navbar.threebutton
[ ] com.android.internal.systemui.navbar.gestural_extra_wide_back
[ ] com.android.theme.font.notoserifsource
[ ] com.android.internal.display.cutout.emulation.waterfall
[ ] com.android.internal.systemui.navbar.gestural
[ ] com.android.internal.systemui.navbar.gestural_narrow_back
[x] com.android.systemui:neutral
[x] com.android.systemui:accent
com.google.android.permissioncontroller
[x] com.google.android.overlay.modules.permissioncontroller
com.android.cellbroadcastreceiver
--- com.android.cellbroadcastreceiver.overlay.common
com.android.server.telecom
[x] com.android.server.telecom.overlay.common
com.google.android.documentsui
[x] com.google.android.overlay.modules.documentsui
com.android.settings
[x] com.android.settings.overlay.common
[x] com.sap.settings.overlay
com.android.phone
[x] com.android.phone.overlay.common
com.android.systemui
[x] com.android.systemui.overlay.common
Conclusion
The concept of RRO is mainly used by OEMs and firmware developers, but this concept is good to know for all Android developers. Moreover android is introducing the overlay APIs which will be available for 3rd party Android developers as well. So better be clear on the concept and ways to develop, debug, and execute it :)
Please refer to my GitHub repository to download and try RRO applications by yourself. Here is the link:
https://github.com/Rajan-Lal/AndroidRRO
Wishing you all happy learning!!!!