Android Resources Overlay Mechanism
Overlay Mechanism
The Android overlay mechanism allows the framework and package resources to be customized without changing the base packages.The customizable resourses fall into the following categories:
- Configurations (string, bool, bool-array)
- Localization (string, string-array)
- UI Appearance (color, drawable, layout, style, theme, animation)
- Raw resources (audio, video, xml)
Add Overlay Directories for Product
Product Overlays vs Device Overlays
There are two types of overaly directories that affect a product:
- PRODUCT_PACKAGE_OVERLAYS: used by a particular product
- DEVICE_PACKAGE_OVERLAYS: used several products that sharea common device model
The PRODUCT_PACKAGE_OVERLAYS will override theDEVICE_PACKAGE_OVERLAYS if they contain same resources, thebehavior is defined by:
build/core/package.mk (Line: 93)
LOCAL_RESOURCE_DIR := \ $(wildcard $(foreach dir, $(PRODUCT_PACKAGE_OVERLAYS), \ $(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \ $(wildcard $(foreach dir, $(DEVICE_PACKAGE_OVERLAYS), \ $(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \ $(LOCAL_RESOURCE_DIR)
Change the makefile to add overlays
To add an overlay directory to a product, change the productconfiguration makefile (for example:device/vendor-name/device-name/product-name.mk) to add thefollowing lines:
PRODUCT_PACKAGE_OVERLAYS := device/vendor-name/device-name/product-name/overlay $(PRODUCT_PACKAGE_OVERLAYS)
or:
DEVICE_PACKAGE_OVERLAYS := device/vendor-name/device-name/common/overlay $(DEVICE_PACKAGE_OVERLAYS)
If multiple overlay directories are required to be added,separate them with blank charactors. The directories definedfirst in the line will override the following directories ifthey contain the same set of resources.
Create resources under the overlay directory
To overlay the resources in a base package, the subdirectorycontaining the overlay resources under the overlaydirectory, must has the same path as the base packageresource directory relative to the Android project root.
For example, if we want to overlay the resources under thebase package directory:
packages/apps/Settings/res/
we need to create the directory:
<overlay-dir>/packages/apps/Settings/res/
and in the directory, put the overlay resources in the fileswith the same path and file names as where they are defined inthe base package.
Note that:
- For color, bool, string, array, style/theme types,the resource values are identifed by their keys, so forthese types, there is no need to put the resources in afile with the same name as in the original base package.
- For layout, animation, picture drawables and raw types,the resources are indentifed by their file name, and overlayfor these resources should keep the file name same as in thebase packages.
Determine the overlays for a product
Because there may exist multiple overlay directories for aproduct, sometimes, it is required to determine all thesedirectories used by the product.
1. First, launch a full build on the target product.
2. Put the following 2 lines in packages/apps/Settings/Android.mk
:
$(warning product overlay $(PRODUCT_PACKAGE_OVERLAYS)) $(error device overlay $(DEVICE_PACKAGE_OVERLAYS))
3. run the following commands:
cd $ANDROID_SRC_ROOT . build/envsetup.sh lunch <product-config> cd packages/apps/Settings mm
4. The build system of Android will print the the two variables and exit:
packages/apps/Settings/Android.mk:6: product overlay device/vendor-name/device-name/product-name/overlay vendor/vendor-name/media/common/overlay
packages/apps/Settings/Android.mk:7: *** device overlay device/vendor-name/device-name/common/overlay device/vendor-name/omap4/overlay device/vendor-name/common/overlay. Stop.
Check the resource in APK
After changed the overlay resources and built the target packages, sometimes we need to check if the overlay directory took effects and the values are changed in the finally generated apks.
Using AAPT
Run the following aapt commands on the final APK packages:
Usage: aapt l[ist] [-v] [-a] file.{zip,jar,apk} List contents of Zip-compatible archive. aapt d[ump] [--values] WHAT file.{apk} [asset [asset ...]] badging Print the label and icon for the app declared in APK. permissions Print the permissions from the APK. resources Print the resource table from the APK. configurations Print the configurations in the APK. xmltree Print the compiled xmls in the given assets. xmlstrings Print the strings of the given compiled xml assets.
For example:
1. To dump string, bool values:
aapt dump resources Settings.apk
2. To dump a raw xml file:
aapt dump xmltree Settings.apk res/xml/appwidget_info.xml
3. To dump the current configurations/localizations:
aapt dump configurations Settings.apk
Using apktools
Usage:
Apktool v1.5.0.5a056e3 - a tool for reengineering Android apk files Copyright 2010 Ryszard Wi??niewski <[email protected]> with smali v1.3.4-ibot8, and baksmali v1.3.4-ibot8 Updated by iBotPeaches <[email protected]> Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) Usage: apktool [-q|--quiet OR -v|--verbose] COMMAND [...] COMMANDs are: d[ecode] [OPTS] <file.apk> [<dir>] Decode <file.apk> to <dir>. OPTS: -s, --no-src Do not decode sources. -r, --no-res Do not decode resources. -d, --debug Decode in debug mode. Check project page for more info. -f, --force Force delete destination directory. -t <tag>, --frame-tag <tag> Try to use framework files tagged by <tag>. --keep-broken-res Use if there was an error and some resources were dropped, e.g.: "Invalid config flags detected. Dropping resources", but you want to decode them anyway, even with errors. You will have to fix them manually before building. b[uild] [OPTS] [<app_path>] [<out_file>] Build an apk from already decoded application located in <app_path>. It will automatically detect, whether files was changed and perform needed steps only. If you omit <app_path> then current directory will be used. If you omit <out_file> then <app_path>/dist/<name_of_original.apk> will be used. OPTS: -f, --force-all Skip changes detection and build all files. -d, --debug Build in debug mode. Check project page for more info. if|install-framework <framework.apk> [<tag>] Install framework file to your system. For additional info, see: https://github.com/iBotPeaches/brut.apktool For smali/baksmali info, see: http://code.google.com/p/smali/
Using dumpres
For more readable dumping messages for complex values, wecan use some other tool, such as dumpres
tool.
More on AAPT and Overlay
How overlay works
While building the package APKs, the overlay directories arepassed to aapt command lines using -S
optionsin the same order as they are defined inPRODUCT_PACKAGE_OVERLAYS
andDEVICE_PACKAGE_OVERLAYS
.
For example, while building the Settings
APK,the following command are executed:
out/host/linux-x86/bin/aapt package -u -z \ -M packages/apps/Settings/AndroidManifest.xml \ -S device/vendor-name/device-name/product-name/overlay/packages/apps/Settings/res \ -S vendor/vendor-name/media/common/overlay/packages/apps/Settings/res -S packages/apps/Settings/res \ -I out/target/common/obj/APPS/framework-res_intermediates/package-export.apk \ --min-sdk-version 16 --target-sdk-version 16 --product default \ --version-code 16 --version-name 4.1.2-eng.xxxx.20121121.152327 \ -F out/target/product/product-name/obj/APPS/Settings_intermediates/package.apk
Note: some overlay directories that don't contain theSettings resources will be filtered first, and do not appearin the above command line.
Add extra resources in Overlay
Though not recommanded, we can add new resources in overlaydirectory, for example, if base packageSettings
doesn't define a bool value with keyno_such_key
, we can add it in the overlay filebool.xml
like
this:
<resources> ... ... <add-resource type="bool" name="no_such_key"/> <bool name="no_such_key">true</bool> ... ... </resource>
If the add-resource
line is missing,aapt
tool will complain while creating the apkfile:
device/vendor-name/device-name/product-name/overlay/packages/apps/Settings/res/values/bools.xml:30: error: Resource at no_such_key appears in overlay but \
not in the base package; use <add-resource> to add.
Another way to avoid the complaint is to run aapt
with the option:
--auto-add-overlay Automatically add resources that are only in overlays.
Note: For picture drawables, we can always add new images inthe overlay directory without extra work.