Android 8.1 provides a new mechanism for OEMs to push updated time zone rules data to devices without requiring a system update. This mechanism enables users to receive timely updates (thus extending the useful lifetime of an Android device) and enables OEMs to test time zone updates independently of system image updates.
The Android core libraries team will provide the necessary data files for updating time zone rules on a stock Android device. OEMs can choose to use these data files when creating time zone updates for their devices or can create their own data files if preferred. In all cases, OEMs retain control over the quality assurance/testing, timing, and launch of time zone rule updates for their supported devices.
All stock Android devices, even those not using this feature, need time zone
rules data and must ship with a default set of time zone rules data in the
/system
partition. This data is then used by code from the
following libraries in the Android source tree:
libcore/
(e.g.
java.util.TimeZone
) uses tzdata
and
tzlookup.xml
files.bionic/
(e.g. for mktime
,
localtime system calls) uses the tzdata
file.external/icu/
uses the icu .dat
file.These libraries are configured to be aware of overlay files that may be
present in the /data/misc/zoneinfo/current
directory. Overlay files
are expected to contain improved time zone rules data thereby enabling devices
to be updated without changing /system
.
Android system components that need time zone rule data check the following locations first:
libcore/
and bionic/
code use the
/data
copy of the tzdata
and tzlookup.xml
files./data
and fallback to
/system
files for data that isn't present (for formats, localized
strings, etc.).Distro .zip files contain the data files needed to populate the
/data/misc/zoneinfo/current
directory. The distro file also
contains metadata that allows devices to detect versioning issues.
The distro file format is Android-release dependent because the contents change with the ICU version, Android platform requirements, etc. Android provides distro files for supported Android releases for every IANA update (in addition to updating the platform system files). To keep their devices up to date, OEMs can choose to take this distro file or create their own distro file using the Android source tree (which contains the scripts and other files needed to generate distro files).
A time zone rules update involves the transmission of a distro file to a device and the safe installation of the files contained within. Transfer and installation requires the following:
/data/misc/zoneinfo/staged
. It can also replace or delete already
staged operations.The Android source tree contains generic source code for the above components, which the OEM can choose to use without modification. Test code is provided to enable OEMs to automatically check that they have enabled the feature correctly.
The distro installation process includes the following steps:
timezone.RulesManagerServer/timezone.PackageTracker
classes)
watches for changes to the configured, OEM-specific, Data App package
name.
/data
is being disabled or uninstalled and the device is
returning to the version present in /system
./data/misc/zoneinfo/current
files before
other system components have opened and started to use the files./data
are correct for the current platform
version, which might not be the case if the device has just received a system update
and the distro format version has changed./system
. This protects against a system update leaving a device
with older time zone rules data than is present in the /system
image.
The end-to-end installation process is asynchronous and split across three OS processes. At any point during the installation, the device may lose power, run out of disk space, etc., causing the installation check to not complete successfully. In the best unsuccessful case, the Updater App is able to inform the system server it was unsuccessful; in the worst unsuccessful case, the RulesManagerService receives no call at all.
To handle this, the system server code keeps track of whether a triggered update check has completed and what the last checked version code of the Data App is. When the device is idle and charging, the system server code can check the current state. If it discovers an incomplete update check or unexpected Data App version, it spontaneously triggers an update check.
When enabled, the RulesManagerService code in the system server performs several checks to ensure the system is safe to use.
/system/priv-app
.File permissions for the /data/misc/zoneinfo
directories are
enforced via SELinux rules. As with any APK, the Data App must be signed by the
same key used to sign the /system/priv-app
version. The Data App is
expected to have a dedicated, OEM-specific package name and key.
To enable the time zone update feature, OEMs typically:
Before starting, review the following policy, quality assurance, and security considerations:
AOSP includes all source code and build rules needed to create a Data App in
packages/apps/TimeZoneData
, with instructions and example templates
for AndroidManifest.xml
and other files located in
packages/apps/TimeZoneData/oem_template
. Example templates include
both a build target for the real Data App .apk file and extra targets for
creating test versions of the Data App.
OEMs can customize the Data App with their own icon, name, translations, etc. However, as the Data App cannot be launched, the icon appears only in the Settings > Apps screen.
The Data App is intended to be built with a tapas build that produces .apks suitable to be added to the system image (for the initial release) and signed and distributed via an app store (for subsequent updates). For details on using tapas, see Building the Data app using tapas.
OEMs must install the Data App prebuilt in the system image of a device in
/system/priv-app
. To include prebuilt .apks (generated by the tapas
build process) in the system image, OEMs can copy the example files in
packages/apps/TimeZoneData/oem_template/data_app_prebuilt
. The
example templates also include build targets for including test versions of the
Data App in test suites.
OEMs must place the Updater and Data App .apk files in the
/system/priv-app
directory of the system image. To do this, the
system image build must explicitly include the Updater App and Data App prebuilt
targets.
The Updater App should be signed with the platform key and included as any
other system app. The target is defined in
packages/apps/TimeZoneUpdater
as TimeZoneUpdater
. The
Data App inclusion is OEM-specific and depends on the target name chosen for the
prebuild.
To enable time zone updates, OEMs can configure the system server by
overriding configuration properties defined in
frameworks/base/core/res/res/values/config.xml
.
Property | Override Required? |
---|---|
config_enableUpdateableTimeZoneRulesMust be set to true to enable the RulesManagerService. |
Yes |
config_timeZoneRulesUpdateTrackingEnabledMust be set to true to have the system listen for changes to the Data App. |
Yes |
config_timeZoneRulesDataPackagePackage name of the OEM-specific Data App. |
Yes |
config_timeZoneRulesUpdaterPackageConfigured for the default Updater App. Change only when providing a different Updater App implementation. |
No |
config_timeZoneRulesCheckTimeMillisAllowedTime allowed between an update check being triggered by the RulesManagerService and an install, uninstall, or do nothing response. After this point, a spontaneous reliability trigger may be generated. |
No |
config_timeZoneRulesCheckRetryCountThe number of sequential unsuccessful update checks allowed before the RulesManagerService stops generating more. |
No |
Configuration overrides should be in the system image (not vendor or other)
as a misconfigured device can refuse to boot. If the configuration overrides
were in /vendor
, updating to a system image without a Data App (or
with different Data App/Updater App package names) would be considered a
misconfiguration.
xTS refers to any OEM-specific test suite that is similar to standard Android test suites using Tradefed (such as CTS and VTS). OEMs that have such test suites can add the Android time zone update tests provided in the following locations:
packages/apps/TimeZoneData/testing/xts
. Includes the code
needed for basic automated functional testing.packages/apps/TimeZoneData/oem_template/xts
. Contains a sample
directory structure for including tests in a Tradefed-like xTS suite. As with
other template directories, OEMs are expected to copy and customize to their
needs.packages/apps/TimeZoneData/oem_template/data_app_prebuilt
.
Contains build-time configuration for including the pre-built test .apk files
required by the test.When IANA releases a new set of time zone rules, the Android core libraries team generates patches to update releases in AOSP. OEMs using the stock Android system and distro files can pick up these commits, use them to create a new version of their Data App, then release the new version to update their devices in production.
Because Data Apps contain distro files closely tied to Android versions, OEMs must create a new version of the Data App for every supported Android release an OEM wants to update. For example, if an OEM wants to provide updates for O-MR1, P, and Q devices, they must complete the process three times.
In this step, OEMs take stock Android commits for
system/timezone
and external/icu
from the
release-dev branches in AOSP and apply those commits to their copy of
the Android source code.
The system/timezone AOSP patch contains updated files in
system/timezone/input_data
and
system/timezone/output_data
. OEMs who need to make additional local
fixes can modify the input files then use the files in
system/timezone/input_data
and external/icu
to
generate files in output_data
.
The most important file is
system/timezone/output_data/distro/distro.zip
, which is
automatically included when the Data App .apk is built.
In this step, OEMs update the version code of the Data App. The build
automatically picks up the distro.zip
, but the new version of the
Data App must have a new version code so it is recognized as new and is used to
replace a pre-loaded Data App or a Data App installed on a device by a previous
update.
When building the Data App using files copied from
package/apps/TimeZoneData/oem_template/data_app
, you can find the
version code/version name applied to the .apk in the Android.mk
:
TIME_ZONE_DATA_APP_VERSION_CODE := TIME_ZONE_DATA_APP_VERSION_NAME :=
Similar entries can be found in testing/Android.mk
(however, the
test version codes must be higher than the system image version). For details,
see the example version code strategy
scheme; if the example scheme or a similar scheme is used, the test
version codes do not need to be updated because they are guaranteed to be higher
than the real version codes.
In this step, OEMs rebuild the .apk files using tapas, sign the generated .apk files, then test and release the .apks:
OEMs are entirely responsible for quality assurance and testing the updated Data App on their devices before release.
The Data App must have a suitable versioning strategy to ensure that devices receive the correct .apk files. For example, if a system update is received that contains an older .apk than one downloaded from the app store, the app store version should be retained.
The .apk version code should include the following information:
Currently, platform API level is strongly correlated to distro format version because each API level is usually associated with a new version of ICU (which makes the distro files incompatible). In the future, Android may change this so that a distro file can work across multiple Android platform releases (and API level is not used in the Data App version code scheme).
This example versioning number scheme ensures that higher distro format
versions beat lower distro format versions. The AndroidManifest.xml
uses android:minSdkVersion
to ensure old devices don't receive
versions with a higher distro format version than they can handle.
Example | Value | Purpose |
---|---|---|
Y | Reserved | Allows for future alternative schemes and/or test APKs. It will initially be (implicitly) 0. Because the underlying type is a signed 32-bit int type, this scheme supports up to two future numbering scheme revisions. |
01 | Major format version | Tracks the 3 decimal digit major format version. The distro format supports 3 decimal digits but only 2 digits are used here. It is unlikely 100 will be reached given the expected major increment per API level. Major version 1 == API level 27. |
1 | Minor format version | Tracks the 3 decimal digit minor format version. The distro format supports 3 decimal digits but only 1 digit is used here. It is unlikely 10 will be reached. |
X | Reserved | Is 0 for production releases (and may be different for test APKs). |
ZZZZZ | Opaque version number | Decimal number allocated on demand. Includes gaps to allow interstitial updates to be made if required. |
The scheme could be packed better if binary were used instead of decimal, but this scheme has the advantage of being human-readable. If the full number range is exhausted, future releases could change the Data App package name and start again.
Version name will be a human-readable representation of the details, e.g.:
major=001,minor=001,iana=2017a, revision=1,respin=2
. Examples:
# | Version code | minSdkVersion | {Major format version}.{Minor format version}.{IANA rules version}.{Revision} |
---|---|---|---|
1 | 11000010 | O-MR1 | major=001,minor=001,iana=2017a,revision=1 |
2 | 21000010 | P | major=002,minor=001,iana=2017a,revision=1 |
3 | 11000020 | O-MR1 | major=001,minor=001,iana=2017a,revision=2 |
4 | 11000030 | O-MR1 | major=001,minor=001,iana=2017b,revision=1 |
5 | 21000020 | P | major=002,minor=001,iana=2017b,revision=1 |
6 | 11000040 | O-MR1 | major=001,minor=001,iana=2018a,revision=1 |
7 | 21000030 | P | major=002,minor=001,iana=2018a,revision=1 |
8 | 1123456789 | - | - |
9 | 11000021 | O-MR1 | major=001,minor=001,iana=2017a,revision=2,respin=2 |
As each device will ship with a default, appropriately versioned .apk in the
system image, there is no risk of an O-MR1 version being installed on a P device
because it will have a lower version number than a P system image version. A
device with an O-MR1 version installed in /data
that then receives
a system update to P will use the /system
version in preference to
the O-MR1 version in /data
because the P version will always be
higher than any app intended for O-MR1.
OEMs are responsible for managing most aspects of the time zone Data App and configuring the system image correctly. The Data App is intended to be built with a tapas build that produces .apks suitable to be added to the system image (for the initial release) and signed and distributed via an app store (for subsequent updates).
Tapas is a slimmed-down version of the Android build system that uses a reduced source tree to produce distributable versions of apps. OEMs familiar with the normal Android build system will recognize the build files from the normal Android platform build.
A reduced source tree is usually achieved with a custom manifest file that
refers only to the Git projects needed by the build system and for building the
app. After following the instructions in
Creating a Data App, OEMs should have at
least two OEM-specific git projects created by using the template files under
packages/apps/TimeZoneData/oem_template
:
vendor/oem/apps/TimeZoneData
). This project also contains
build rules for test APKs that can be used by xTS tests.The app build leverages several other git projects that are shared with the platform build or contain OEM-independent code libraries.
The following manifest snippet contains the minimal set of git projects needed to support an O-MR1 build of the time zone Data App (future versions of Android will have different lists or may even change the build system). OEMs must add their OEM-specific git projects (which typically include a project that contains the signing certificate) to this manifest, and may configure different branches accordingly.
<!-- Tapas Build --> <project path="build" name="platform/build"> <copyfile src="core/root.mk" dest="Makefile" /> </project> <project path="prebuilts/build-tools" name="platform/prebuilts/build-tools" clone-depth="1" /> <project path="prebuilts/go/linux-x86" name="platform/prebuilts/go/linux-x86" clone-depth="1" /> <project path="build/blueprint" name="platform/build/blueprint" /> <project path="build/kati" name="platform/build/kati" /> <project path="build/soong" name="platform/build/soong"> <linkfile src="root.bp" dest="Android.bp" /> <linkfile src="bootstrap.bash" dest="bootstrap.bash" /> </project> <!-- SDK for system / public API stubs --> <project path="prebuilts/sdk" name="platform/prebuilts/sdk" clone-depth="1" /> <!-- App source --> <project path="system/timezone" name="platform/system/timezone" /> <project path="packages/apps/TimeZoneData" name="platform/packages/apps/TimeZoneData" /> <!-- Enable repohooks --> <project path="tools/repohooks" name="platform/tools/repohooks" revision="master" clone_depth="1" /> <repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" />
After the source tree is established, invoke the tapas build using the following commands:
source build/envsetup.sh
tapas
make -j30 showcommands dist TARGET_BUILD_APPS='TimeZoneData TimeZoneData_test1 TimeZoneData_test2' TARGET_BUILD_VARIANT=userdebug
A successful build generates files in the out/dist
directory for
testing. These files can be placed into the prebuilts directory for inclusion in
the system image and/or distributed via an app store for compatible
devices.