A runtime resource overlay (RRO) is a package that changes the resource values of a target package at runtime. For example, an app installed on the system image might change its behavior based upon the value of a resource. Rather than hardcoding the resource value at build time, an RRO installed on a different partition can change the values of the app's resources at runtime.
RROs can be enabled or disabled. You can programmatically set the enable/disable state to toggle an RRO's ability to change resource values. RROs are disabled by default (however, static RROs are enabled by default).
Overlay resources
Overlays work by mapping resources defined in the overlay package to resources defined in the target package. When an app attempts to resolve the value of a resource in the target package, the value of the overlay resource the target resource is mapped to is returned instead.
Set up the manifest
A package is considered an RRO package if it contains an <overlay>
tag as a
child of the <manifest>
tag.
The value of the required
android:targetPackage
attribute specifies the name of the package the RRO intends to overlay.The value of the optional
android:targetName
attribute specifies the name of the overlayable subset of resources of the target package the RRO intends to overlay. If the target doesn't define an overlayable set of resources, this attribute shouldn't be present.
The following code shows an example overlay AndroidManifest.xml
.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.overlay">
<application android:hasCode="false" />
<overlay android:targetPackage="com.example.target"
android:targetName="OverlayableResources"/>
</manifest>
Overlays can't overlay code, so they can't have DEX files. In addition, the
android:hasCode
attribute of the <application
> tag in the manifest must be
set to false
.
Define the resources map
In Android 11 or higher, the recommended mechanism for
defining the overlay resources map is to create a file in the res/xml
directory of the overlay package, enumerate the target resources that should be
overlaid and their replacement values, then set the value of the
android:resourcesMap
attribute of the <overlay>
manifest tag to a reference
to the resource mapping file.
The following code shows an example res/xml/overlays.xml
file.
<?xml version="1.0" encoding="utf-8"?>
<overlay xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Overlays string/config1 and string/config2 with the same resource. -->
<item target="string/config1" value="@string/overlay1" />
<item target="string/config2" value="@string/overlay1" />
<!-- Overlays string/config3 with the string "yes". -->
<item target="string/config3" value="@android:string/yes" />
<!-- Overlays string/config4 with the string "Hardcoded string". -->
<item target="string/config4" value="Hardcoded string" />
<!-- Overlays integer/config5 with the integer "42". -->
<item target="integer/config5" value="42" />
</overlay>
The following code shows an example overlay manifest.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.overlay">
<application android:hasCode="false" />
<overlay android:targetPackage="com.example.target"
android:targetName="OverlayableResources"
android:resourcesMap="@xml/overlays"/>
</manifest>
Build the package
Android 11 or higher supports a Soong build rule for
overlays that prevents Android Asset Packaging Tool 2 (AAPT2) from attempting to
dedupe configurations of resources with the same value
(--no-resource-deduping
) and from removing resources without default
configurations (--no-resource-removal
). The following code shows an example
Android.bp
file.
runtime_resource_overlay {
name: "ExampleOverlay",
sdk_version: "current",
}
Resolve resources
If a target resource or overlay resource has multiple configurations defined for the resource being queried, the resources runtime returns the value of the configuration that best matches the configuration of the device configuration. To determine which configuration is the best matching configuration, merge the set of the overlay resource configurations into the set of target resource configurations and then follow the regular resource resolution flow (for details, refer to How Android finds the best-matching resource).
For example, if an overlay defines a value for the drawable-en
configuration
and the target defines a value for drawable-en-port
, drawable-en-port
has a better match so the value of the target configuration drawable-en-port
is chosen at runtime. To overlay all drawable-en
configurations, the overlay
must define a value for each drawable-en
configuration the target defines.
Overlays can reference their own resources, with differing behaviors between Android releases.
In Android 11 or higher, each overlay has its own reserved resource ID space that doesn't overlap target resource ID space or other overlay resource ID spaces, so overlays referencing their own resources work as expected.
In Android 10 or lower, overlays and target packages share the same resource ID space, which can cause collisions and unexpected behavior when they attempt to reference their own resources using the
@type/name
syntax.
Enable/disable overlays
Use the OverlayManager
API to enable and disable mutable overlays (retrieve
the API interface using Context#getSystemService(Context.OVERLAY_SERVICE)
). An
overlay can be enabled only by the package it targets or by a package with the
android.permission.CHANGE_OVERLAY_PACKAGES
permission. When an overlay is
enabled or disabled, configuration change events propagate to the target package
and target activities relaunch.
Restrict overlayable resources
In Android 10 or higher, the <overlayable>
XML tag exposes a set of resources
that RROs are allowed to overlay. In the following example
res/values/overlayable.xml
file, 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.
<!-- 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>
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.
The following code shows an example of an overlay in the AndroidManifest.xml
file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my.theme.overlay">
<application android:hasCode="false" />
<!-- This overlay will override the ThemeResources resources -->
<overlay android:targetPackage="android" android:targetName="ThemeResources">
</manifest>
When an app defines an <overlayable>
tag, overlays targeting that app:
Must specify
targetName
.Can overlay only the resources listed within the
<overlayable>
tag.Can target only one
<overlayable>
name.
You can't enable an overlay targeting a package that exposes overlayable
resources but doesn't use android:targetName
to target a specific
<overlayable>
tag.
Restrict policies
Use the <policy>
tag to enforce restrictions on overlayable resources. The
type
attribute specifies which policies an overlay must fulfill to override
the included resources. Supported types include the following.
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.oem
. Any overlay on the oem partition can override the resources.odm
. Any overlay on the odm partition can override the resources.signature
. Any overlay signed with the same signature as the target APK can override the resources.actor
. Any overlay signed with the same signature as the actor APK can override the resources. The actor is declared in named-actor tag in system config.config_signature
. Any overlay signed with the same signature as the overlay-config apk can override the resources. The overlay-config is declared in overlay-config-signature tag in system config.
The following code shows an example <policy>
tag in the
res/values/overlayable.xml
file.
<overlayable name="ThemeResources">
<policy type="vendor" >
<item type="string" name="foo" />
</policy>
<policy type="product|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.
Configure overlays
Android supports different mechanisms for configuring the mutability, default state, and priority of overlays depending on the Android release version.
Devices running Android 11 or higher can use an
OverlayConfig
file (config.xml
) instead of manifest attributes. Using an overlay file is the recommended method for overlays.All devices can use manifest attributes (
android:isStatic
andandroid:priority
) to configure static RROs.
Use OverlayConfig
In Android 11 or higher, you can use OverlayConfig
to
configure the mutability, default state, and priority of overlays. To configure
an overlay, create or modify the file located at
partition/overlay/config/config.xml
, where partition
is the partition of the
overlay to be configured. To be configured, an overlay must reside in the
overlay/
directory of the partition in which the overlay is configured. The
following code shows an example product/overlay/config/config.xml
.
<config>
<merge path="OEM-common-rros-config.xml" />
<overlay package="com.oem.overlay.device" mutable="false" enabled="true" />
<overlay package="com.oem.green.theme" enabled="true" />
</config>"
The <overlay>
tag requires a package
attribute that indicates which overlay
package is being configured. The optional enabled
attribute controls whether
or not the overlay is enabled by default (default is false
). The optional
mutable
attribute controls whether or not the overlay is mutable and can have
its enabled state changed programmatically at runtime (default is true
).
Overlays not listed within a configuration file are mutable and disabled by
default.
Overlay precedence
When multiple overlays override the same resources, the order of the overlays is important. An overlay has greater precedence than overlays with configurations preceding its own configuration. The precedence order of overlays in different partitions (from least to greatest precedence) is as follows.
system
vendor
odm
oem
product
system_ext
Merge files
Using <merge>
tags allows for other configuration files to be merged at the
specified position into the configuration file. The path
attribute of the tag
represents the path of the file to merge relative to the directory containing
overlay configuration files.
Use manifest attributes/static RROs
In Android 10 or lower, overlay immutability and precedence are configured using the following manifest attributes.
android:isStatic
. When the value of this boolean attribute is set totrue
, the overlay is enabled by default and is immutable, which prevents the overlay from being disabled.android:priority
. The value of this numeric attribute (which affects only static overlays) configures the precedence of the overlay when multiple static overlays target the same resource value. A higher number indicates a higher precedence.
The following code shows an example AndroidManifest.xml
.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.overlay">
<application android:hasCode="false" />
<overlay android:targetPackage="com.example.target"
android:isStatic="true"
android:priority="5"/>
</manifest>
Changes in Android 11
In Android 11 or higher, if a configuration file is
located in partition/overlay/config/config.xml
, overlays are configured using
that file and android:isStatic
and android:priority
don't have an effect on
overlays located in the partition. Defining an overlay configuration file in any
partition enforces the overlay partition precedence.
In addition, Android 11 or higher removes the ability
to use static overlays to affect the values of resources read during package
installation. For the common use case of using static overlays to change the
value of booleans that configure component enabled state, use the
<component-override>
SystemConfig
tag (new in Android
11).
Debug overlays
To manually enable, disable, and dump overlays, use the following overlay manager shell command.
adb shell cmd overlay
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/
, then
run the following command.
adb shell idmap2 dump --idmap-path [file]
This command prints the mapping of resources as shown below.
[target res id] - > [overlay res id] [resource name]
0x01040151 -> 0x01050001 string/config_dozeComponent
0x01040152 -> 0x01050002 string/config_dozeDoubleTapSensorType
0x01040153 -> 0x01050003 string/config_dozeLongPressSensorType