Last active
August 29, 2015 14:08
-
-
Save idiottiger/12811468825aeeee276d to your computer and use it in GitHub Desktop.
Android Utility Function Library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment