290 lines
11 KiB
Plaintext
290 lines
11 KiB
Plaintext
|
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
|