| Android Utility Function Library | |
| ================================ | |
| If you need a feature that is native to Linux but not present on other | |
| platforms, construct a platform-dependent implementation that shares | |
| the Linux interface. That way the actual device runs as "light" as | |
| possible. | |
| If that isn't feasible, create a system-independent interface and hide | |
| the details. | |
| The ultimate goal is *not* to create a super-duper platform abstraction | |
| layer. The goal is to provide an optimized solution for Linux with | |
| reasonable implementations for other platforms. | |
| Resource overlay | |
| ================ | |
| Introduction | |
| ------------ | |
| Overlay packages are special .apk files which provide no code but | |
| additional resource values (and possibly new configurations) for | |
| resources in other packages. When an application requests resources, | |
| the system will return values from either the application's original | |
| package or any associated overlay package. Any redirection is completely | |
| transparent to the calling application. | |
| Resource values have the following precedence table, listed in | |
| descending precedence. | |
| * overlay package, matching config (eg res/values-en-land) | |
| * original package, matching config | |
| * overlay package, no config (eg res/values) | |
| * original package, no config | |
| During compilation, overlay packages are differentiated from regular | |
| packages by passing the -o flag to aapt. | |
| Background | |
| ---------- | |
| This section provides generic background material on resources in | |
| Android. | |
| How resources are bundled in .apk files | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| Android .apk files are .zip files, usually housing .dex code, | |
| certificates and resources, though packages containing resources but | |
| no code are possible. Resources can be divided into the following | |
| categories; a `configuration' indicates a set of phone language, display | |
| density, network operator, etc. | |
| * assets: uncompressed, raw files packaged as part of an .apk and | |
| explicitly referenced by filename. These files are | |
| independent of configuration. | |
| * res/drawable: bitmap or xml graphics. Each file may have different | |
| values depending on configuration. | |
| * res/values: integers, strings, etc. Each resource may have different | |
| values depending on configuration. | |
| Resource meta information and information proper is stored in a binary | |
| format in a named file resources.arsc, bundled as part of the .apk. | |
| Resource IDs and lookup | |
| ~~~~~~~~~~~~~~~~~~~~~~~ | |
| During compilation, the aapt tool gathers application resources and | |
| generates a resources.arsc file. Each resource name is assigned an | |
| integer ID 0xppttiii (translated to a symbolic name via R.java), where | |
| * pp: corresponds to the package namespace (details below). | |
| * tt: corresponds to the resource type (string, int, etc). Every | |
| resource of the same type within the same package has the same | |
| tt value, but depending on available types, the actual numerical | |
| value may be different between packages. | |
| * iiii: sequential number, assigned in the order resources are found. | |
| Resource values are specified paired with a set of configuration | |
| constraints (the default being the empty set), eg res/values-sv-port | |
| which imposes restrictions on language (Swedish) and display orientation | |
| (portrait). During lookup, every constraint set is matched against the | |
| current configuration, and the value corresponding to the best matching | |
| constraint set is returned (ResourceTypes.{h,cpp}). | |
| Parsing of resources.arsc is handled by ResourceTypes.cpp; this utility | |
| is governed by AssetManager.cpp, which tracks loaded resources per | |
| process. | |
| Assets are looked up by path and filename in AssetManager.cpp. The path | |
| to resources in res/drawable are located by ResourceTypes.cpp and then | |
| handled like assets by AssetManager.cpp. Other resources are handled | |
| solely by ResourceTypes.cpp. | |
| Package ID as namespace | |
| ~~~~~~~~~~~~~~~~~~~~~~~ | |
| The pp part of a resource ID defines a namespace. Android currently | |
| defines two namespaces: | |
| * 0x01: system resources (pre-installed in framework-res.apk) | |
| * 0x7f: application resources (bundled in the application .apk) | |
| ResourceTypes.cpp supports package IDs between 0x01 and 0x7f | |
| (inclusive); values outside this range are invalid. | |
| Each running (Dalvik) process is assigned a unique instance of | |
| AssetManager, which in turn keeps a forest structure of loaded | |
| resource.arsc files. Normally, this forest is structured as follows, | |
| where mPackageMap is the internal vector employed in ResourceTypes.cpp. | |
| mPackageMap[0x00] -> system package | |
| mPackageMap[0x01] -> NULL | |
| mPackageMap[0x02] -> NULL | |
| ... | |
| mPackageMap[0x7f - 2] -> NULL | |
| mPackageMap[0x7f - 1] -> application package | |
| The resource overlay extension | |
| ------------------------------ | |
| The resource overlay mechanism aims to (partly) shadow and extend | |
| existing resources with new values for defined and new configurations. | |
| Technically, this is achieved by adding resource-only packages (called | |
| overlay packages) to existing resource namespaces, like so: | |
| mPackageMap[0x00] -> system package -> system overlay package | |
| mPackageMap[0x01] -> NULL | |
| mPackageMap[0x02] -> NULL | |
| ... | |
| mPackageMap[0x7f - 2] -> NULL | |
| mPackageMap[0x7f - 1] -> application package -> overlay 1 -> overlay 2 | |
| The use of overlay resources is completely transparent to | |
| applications; no additional resource identifiers are introduced, only | |
| configuration/value pairs. Any number of overlay packages may be loaded | |
| at a time; overlay packages are agnostic to what they target -- both | |
| system and application resources are fair game. | |
| The package targeted by an overlay package is called the target or | |
| original package. | |
| Resource overlay operates on symbolic resources names. Hence, to | |
| override the string/str1 resources in a package, the overlay package | |
| would include a resource also named string/str1. The end user does not | |
| have to worry about the numeric resources IDs assigned by aapt, as this | |
| is resolved automatically by the system. | |
| As of this writing, the use of resource overlay has not been fully | |
| explored. Until it has, only OEMs are trusted to use resource overlay. | |
| For this reason, overlay packages must reside in /system/overlay. | |
| Resource ID mapping | |
| ~~~~~~~~~~~~~~~~~~~ | |
| Resource identifiers must be coherent within the same namespace (ie | |
| PackageGroup in ResourceTypes.cpp). Calling applications will refer to | |
| resources using the IDs defined in the original package, but there is no | |
| guarantee aapt has assigned the same ID to the corresponding resource in | |
| an overlay package. To translate between the two, a resource ID mapping | |
| {original ID -> overlay ID} is created during package installation | |
| (PackageManagerService.java) and used during resource lookup. The | |
| mapping is stored in /data/resource-cache, with a @idmap file name | |
| suffix. | |
| The idmap file format is documented in a separate section, below. | |
| Package management | |
| ~~~~~~~~~~~~~~~~~~ | |
| Packages are managed by the PackageManagerService. Addition and removal | |
| of packages are monitored via the inotify framework, exposed via | |
| android.os.FileObserver. | |
| During initialization of a Dalvik process, ActivityThread.java requests | |
| the process' AssetManager (by proxy, via AssetManager.java and JNI) | |
| to load a list of packages. This list includes overlay packages, if | |
| present. | |
| When a target package or a corresponding overlay package is installed, | |
| the target package's process is stopped and a new idmap is generated. | |
| This is similar to how applications are stopped when their packages are | |
| upgraded. | |
| Creating overlay packages | |
| ------------------------- | |
| Overlay packages should contain no code, define (some) resources with | |
| the same type and name as in the original package, and be compiled with | |
| the -o flag passed to aapt. | |
| The aapt -o flag instructs aapt to create an overlay package. | |
| Technically, this means the package will be assigned package id 0x00. | |
| There are no restrictions on overlay packages names, though the naming | |
| convention <original.package.name>.overlay.<name> is recommended. | |
| Example overlay package | |
| ~~~~~~~~~~~~~~~~~~~~~~~ | |
| To overlay the resource bool/b in package com.foo.bar, to be applied | |
| when the display is in landscape mode, create a new package with | |
| no source code and a single .xml file under res/values-land, with | |
| an entry for bool/b. Compile with aapt -o and place the results in | |
| /system/overlay by adding the following to Android.mk: | |
| LOCAL_AAPT_FLAGS := -o com.foo.bar | |
| LOCAL_MODULE_PATH := $(TARGET_OUT)/overlay | |
| The ID map (idmap) file format | |
| ------------------------------ | |
| The idmap format is designed for lookup performance. However, leading | |
| and trailing undefined overlay values are discarded to reduce the memory | |
| footprint. | |
| idmap grammar | |
| ~~~~~~~~~~~~~ | |
| All atoms (names in square brackets) are uint32_t integers. The | |
| idmap-magic constant spells "idmp" in ASCII. Offsets are given relative | |
| to the data_header, not to the beginning of the file. | |
| map := header data | |
| header := idmap-magic <crc32-original-pkg> <crc32-overlay-pkg> | |
| idmap-magic := <0x706d6469> | |
| data := data_header type_block+ | |
| data_header := <m> header_block{m} | |
| header_block := <0> | <type_block_offset> | |
| type_block := <n> <id_offset> entry{n} | |
| entry := <resource_id_in_target_package> | |
| idmap example | |
| ~~~~~~~~~~~~~ | |
| Given a pair of target and overlay packages with CRC sums 0x216a8fe2 | |
| and 0x6b9beaec, each defining the following resources | |
| Name Target package Overlay package | |
| string/str0 0x7f010000 - | |
| string/str1 0x7f010001 0x7f010000 | |
| string/str2 0x7f010002 - | |
| string/str3 0x7f010003 0x7f010001 | |
| string/str4 0x7f010004 - | |
| bool/bool0 0x7f020000 - | |
| integer/int0 0x7f030000 0x7f020000 | |
| integer/int1 0x7f030001 - | |
| the corresponding resource map is | |
| 0x706d6469 0x216a8fe2 0x6b9beaec 0x00000003 \ | |
| 0x00000004 0x00000000 0x00000009 0x00000003 \ | |
| 0x00000001 0x7f010000 0x00000000 0x7f010001 \ | |
| 0x00000001 0x00000000 0x7f020000 | |
| or, formatted differently | |
| 0x706d6469 # magic: all idmap files begin with this constant | |
| 0x216a8fe2 # CRC32 of the resources.arsc file in the original package | |
| 0x6b9beaec # CRC32 of the resources.arsc file in the overlay package | |
| 0x00000003 # header; three types (string, bool, integer) in the target package | |
| 0x00000004 # header_block for type 0 (string) is located at offset 4 | |
| 0x00000000 # no bool type exists in overlay package -> no header_block | |
| 0x00000009 # header_block for type 2 (integer) is located at offset 9 | |
| 0x00000003 # header_block for string; overlay IDs span 3 elements | |
| 0x00000001 # the first string in target package is entry 1 == offset | |
| 0x7f010000 # target 0x7f01001 -> overlay 0x7f010000 | |
| 0x00000000 # str2 not defined in overlay package | |
| 0x7f010001 # target 0x7f010003 -> overlay 0x7f010001 | |
| 0x00000001 # header_block for integer; overlay IDs span 1 element | |
| 0x00000000 # offset == 0 | |
| 0x7f020000 # target 0x7f030000 -> overlay 0x7f020000 |