Google is committed to advancing racial equity for Black communities. See how.

Runtime Resource Overlays (RROs)

In Android 10 and higher, you can use the Android Asset Packaging Tool 2 (AAPT2) to define which resources your APK allows Runtime Resource Overlays (RRO) to overlay at runtime.

Implementing RROs

Android 10 introduces a new <overlayable> XML tag that collects resources that should be overlaid together under a common name. In the example below, string/foo and integer/bar are resources used for theming the device's appearance. To overlay these resources, an overlay must explicitly target the collection of overlayable resources by name.

An APK can define multiple <overlayable> tags, but each tag must have a unique name within the package. For example, it is:

  • OK for two different packages to both define <overlayable name="foo">.

  • Not OK for a single APK to have two <overlayable name="foo"> blocks.

Example res/values/overlayable.xml file:

<!-- The collection of resources for theming the appearance of the device -->
<overlayable name=”ThemeResources”>
       <policy type=”public”>
               <item type=”string” name=”foo/” />
               <item type=”integer” name=”bar/” />
       </policy>
       ...
</overlayable>

Example of overlay in the AndroidManifest.xml file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.my.theme.overlay">

       <!-- This overlay will override the ThemeResources resources -->
       <overlay android:targetPackage="android" android:targetName="ThemeResources">
</manifest>

When an application defines an <overlayable> tag, overlays targeting that application:

  • Must specify "targetName".

  • Can overlay only the resources listed within the tag.

  • Can target only one <overlayable> name.

An overlay targeting a package that exposes overlayable resources but does not use android:targetName to target a specific <overlayable> tag cannot be enabled.

Restricting policies

The <policy> tag enforces restrictions on overlayable resources. The type attribute specifies which policies an overlay must fulfill to override the included resources. Supported types include:

  • public - any overlay can override the resource

  • system - any overlay on the system partition can override the resources

  • vendor - any overlay on the vendor partition can override the resources

  • product - any overlay on the product partition can override the resources

  • signature - any overlay signed with the same signature as the target APK can override the resources

Example <policy> tag in the res/values/overlayable.xml file:

<overlayable name=”ThemeResources”>
   <policy type=“product” >
       <item type=”string” name=”foo” />
   </policy>
   <policy type=“system|signature”  >
       <item type=”string” name=”bar” />
       <item type=”string” name=”baz” />
   </policy>
</overlayable>

To specify multiple policies, use vertical bars (|) as separator characters. When multiple policies are specified, an overlay needs to fulfill only one policy to override the resources listed within the <policy> tag.

Managing RROs

  • To enable, disable, or reorder overlays you must have the CHANGE_OVERLAY_PACKAGES permission.

  • To enable overlays for users other than the current user, you must have the INTERACT_ACROSS_USERS permission.

Compliance

The overlayable declarations of resources in the framework must be consistent across all Android devices for a given SDK level. All additions, removals, policy changes, and any other changes that affect the overlayable definitions of framework resources must be merged to AOSP to achieve consistency across all Android devices. CTS testing enforces that the overlayable API of the Android framework does not deviate from the overlayable definitions defined in AOSP.

Installing RROs

In Android 9 and lower, overlays must be preinstalled or signed with the platform signature to be installed by PackageManagerService. Android 9 overlays on Android 9 devices will continue working normally after the device upgrades to Android 10.

In Android 10 and higher, overlays that are not signed with the platform signature can be installed onto the data partition. An overlay that targets a package that does not declare overlayable resources must be signed with the same signature as the target package or must be preinstalled to be enabled.

Debugging

Install overlays and target applications onto the device using:

adb install

To manually enable, disable, and dump overlays, use the overlay manager shell command:

adb shell cmd overlay

The OverlayManagerService uses idmap 2 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 is not working correctly, find the corresponding idmap file for your overlay in /data/resource-cache/, then run:

adb shell idmap2 dump --idmap-path [file]

This command prints the mapping of resources:

[target res id] - > [overlay res id] [resource name]
0x01040151 -> 0x01050001 string/config_dozeComponent
0x01040152 -> 0x01050002 string/config_dozeDoubleTapSensorType
0x01040153 -> 0x01050003 string/config_dozeLongPressSensorType
...

Overlayable XML schema

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
 elementFormDefault="qualified">

 <xs:element name="overlayable">
   <xs:complexType>
     <xs:sequence>
       <xs:element maxOccurs="unbounded" ref="policy"/>
     </xs:sequence>
     <xs:attribute name="actor" type="xs:anyURI"/>
     <xs:attribute name="name" use="required" type="xs:NCName"/>
   </xs:complexType>
 </xs:element>

 <xs:element name="policy">
   <xs:complexType>
     <xs:sequence>
       <xs:element maxOccurs="unbounded" ref="item"/>
     </xs:sequence>
     <xs:attribute name="type" use="required"/>
   </xs:complexType>
 </xs:element>

 <xs:element name="item">
   <xs:complexType>
     <xs:attribute name="name" use="required"/>
     <xs:attribute name="type" use="required" type="xs:NCName"/>
   </xs:complexType>
 </xs:element>
</xs:schema>