RRO - Change the resource at runtime

RRO - Change the resource at runtime

·

4 min read

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

AOSP A13 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:

AOSP A13 SystemUI config.xml

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!!!!