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