Merge "Change tzdatacheck to avoid hardcoding"
diff --git a/README.android b/README.android
index 127bd99..0a00001 100644
--- a/README.android
+++ b/README.android
@@ -117,24 +117,22 @@
Changing the distro format version
----------------------------------
-1) Modify distro/core/src/main/com/android/timezone/distro/DistroVersion.java:
+1) Modify libcore/luni/src/main/java/libcore/timezone/TzDataSetVersion.java
- CURRENT_FORMAT_MAJOR_VERSION, CURRENT_FORMAT_MINOR_VERSION
-2) Modify: tzdatacheck/tzdatacheck.cpp
- - SUPPORTED_DISTRO_MAJOR_VERSION, SUPPORTED_DISTRO_MINOR_VERSION
-3) Run update-tzdata.py to regenerate the system/timezone/output_data,
+2) Run update-tzdata.py to regenerate the system/timezone/output_data,
system/timezone/testing/data, external/icu runtime files and testing equivalents.
-4) Build/flash a device image with the changes and run CTS:
+3) Build/flash a device image with the changes and run CTS:
cts-tradefed
run cts -m CtsHostTzDataTests
run cts -m CtsLibcoreTestCases
-5) Run non-CTS test cases:
+4) Run non-CTS test cases:
make -j30 FrameworksServicesTests
adb install -r -g \
"${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk"
adb shell am instrument -e package com.android.server.timezone -w \
com.android.frameworks.servicestests \
"com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner"
-6) Upload, review, submit the changes from system/timezone.
+5) Upload, review, submit the changes from system/timezone, libcore and external/icu.
REMINDER: Any prebuilt apks of OEM-specific time zone data apps .apk files
(i.e. ones that that contain distro files) will also need to be regenerated
diff --git a/tzdatacheck/tzdatacheck.cpp b/tzdatacheck/tzdatacheck.cpp
index 2a1defc..a117dce 100644
--- a/tzdatacheck/tzdatacheck.cpp
+++ b/tzdatacheck/tzdatacheck.cpp
@@ -47,47 +47,41 @@
// See also com.android.timezone.distro.TimeZoneDistro / com.android.timezone.distro.DistroVersion.
static const char* DISTRO_VERSION_FILENAME = "/distro_version";
-// distro_version is an ASCII file consisting of 17 bytes in the form: AAA.BBB|CCCCC|DDD
-// AAA.BBB is the major/minor version of the distro format (e.g. 001.001),
-// CCCCC is the rules version (e.g. 2016g)
-// DDD is the android revision for this rules version to allow for distro corrections (e.g. 001)
-// We only need the first 13 to determine if it is suitable for the device.
-static const int DISTRO_VERSION_LENGTH = 13;
+// The name of the file containing the base tz data set version information.
+// See also libcore.timezone.TzDataSetVersion.
+static const char* BASE_VERSION_FILENAME = "/tz_version";
-// The major version of the distro format supported by this code as a null-terminated char[].
-// See also com.android.timezone.distro.TimeZoneDistro / libcore.timezone.TzDataSetVersion.
-static const char SUPPORTED_DISTRO_MAJOR_VERSION[] = "003";
+// distro_version / tz_version are ASCII files consisting of at least 17 bytes in the
+// form: AAA.BBB|CCCCC|DDD
+// AAA.BBB is the major/minor version of the format (e.g. 004.001),
+// CCCCC is the rules version (e.g. 2016g),
+// DDD is the android revision for this rules version to allow for data corrections (e.g. 001),
+// We only use the first 13 to determine suitability of format / data.
+static const int READ_DATA_LENGTH = 13;
-// The length of the distro format major version excluding the \0
-static const size_t SUPPORTED_DISTRO_MAJOR_VERSION_LEN = sizeof(SUPPORTED_DISTRO_MAJOR_VERSION) - 1;
+// Version bytes are: AAA.BBB|CCCCC - the format version is AAA.BBB
+// The length of the format version, e.g. "004.001" == 7 bytes
+static const size_t FORMAT_VERSION_LEN = 7;
-// The minor version of the distro format supported by this code as a null-terminated char[].
-// See also com.android.timezone.distro.TimeZoneDistro /
-// libcore.timezone.TzDataSetVersion
-static const char SUPPORTED_DISTRO_MINOR_VERSION[] = "001";
+// Version bytes are: AAA.BBB|CCCCC - the format major version is AAA
+static const size_t FORMAT_MAJOR_VERSION_LEN = 3;
-// The length of the distro format minor version excluding the \0
-static const size_t SUPPORTED_DISTRO_MINOR_VERSION_LEN = sizeof(SUPPORTED_DISTRO_MINOR_VERSION) - 1;
+// Version bytes are: AAA.BBB|CCCCC - the format major version is AAA
+static const size_t FORMAT_MAJOR_VERSION_IDX = 0;
-// The length of the distro format version. e.g. 001.001
-static const size_t SUPPORTED_DISTRO_VERSION_LEN =
- SUPPORTED_DISTRO_MAJOR_VERSION_LEN + SUPPORTED_DISTRO_MINOR_VERSION_LEN + 1;
+// Version bytes are: AAA.BBB|CCCCC - the format major version is AAA
+static const size_t FORMAT_MINOR_VERSION_LEN = 3;
-// The length of the IANA rules version bytes. e.g. 2016a
+// Version bytes are: AAA.BBB|CCCCC - the format minor version is BBB
+static const size_t FORMAT_MINOR_VERSION_IDX = 4;
+
+// Version bytes are: AAA.BBB|CCCCC - the IANA rules version is CCCCC
+// The length of the IANA rules version bytes, e.g. 2016a
static const size_t RULES_VERSION_LEN = 5;
-// Distro version bytes are: AAA.BBB|CCCCC - the rules version is CCCCC
-static const size_t DISTRO_VERSION_RULES_IDX = 8;
+// Version bytes are: AAA.BBB|CCCCC - the rules version is CCCCC
+static const size_t VERSION_RULES_IDX = 8;
-// See also com.android.timezone.distro.TimeZoneDistro.
-static const char* TZDATA_FILENAME = "/tzdata";
-
-// tzdata file header (as much as we need for the version):
-// byte[11] tzdata_version -- e.g. "tzdata2012f"
-static const int TZ_HEADER_LENGTH = 11;
-
-static const char TZ_DATA_HEADER_PREFIX[] = "tzdata";
-static const size_t TZ_DATA_HEADER_PREFIX_LEN = sizeof(TZ_DATA_HEADER_PREFIX) - 1; // exclude \0
static void usage() {
std::cerr << "Usage: tzdatacheck SYSTEM_TZ_DIR DATA_TZ_DIR\n"
@@ -121,18 +115,6 @@
return true;
}
-/*
- * Checks the contents of headerBytes. Returns true if it is valid (starts with "tzdata"), false
- * otherwise.
- */
-static bool checkValidTzDataHeader(const std::string& fileName, const char* headerBytes) {
- if (strncmp("tzdata", headerBytes, 6) != 0) {
- LOG(WARNING) << fileName << " does not start with the expected bytes (tzdata)";
- return false;
- }
- return true;
-}
-
static bool checkDigits(const char* buffer, const size_t count, size_t* i) {
for (size_t j = 0; j < count; j++) {
char toCheck = buffer[(*i)++];
@@ -143,8 +125,8 @@
return true;
}
-static bool checkValidDistroVersion(const char* buffer) {
- // See DISTRO_VERSION_LENGTH comments above for a description of the format.
+static bool checkValidVersionBytes(const char* buffer) {
+ // See READ_DATA_LENGTH comments above for a description of the format.
size_t i = 0;
if (!checkDigits(buffer, 3, &i)) {
return false;
@@ -437,7 +419,7 @@
}
/*
- * After a platform update it is likely that timezone data found on the system partition will be
+ * After a platform update it is likely that the "base" timezone data found on the device will be
* newer than the version found in the data partition. This tool detects this case and removes the
* version in /data.
*
@@ -455,7 +437,7 @@
return 1;
}
- const char* systemZoneInfoDir = argv[1];
+ const char* baseZoneInfoDir = argv[1];
const char* dataZoneInfoDir = argv[2];
std::string dataStagedDirName(dataZoneInfoDir);
@@ -490,9 +472,9 @@
std::string distroVersionFileName(dataCurrentDirName);
distroVersionFileName += DISTRO_VERSION_FILENAME;
std::vector<char> distroVersion;
- distroVersion.reserve(DISTRO_VERSION_LENGTH);
+ distroVersion.reserve(READ_DATA_LENGTH);
bool distroVersionReadOk =
- readBytes(distroVersionFileName, distroVersion.data(), DISTRO_VERSION_LENGTH);
+ readBytes(distroVersionFileName, distroVersion.data(), READ_DATA_LENGTH);
if (!distroVersionReadOk) {
LOG(WARNING) << "distro version file " << distroVersionFileName
<< " does not exist or is too short. Deleting distro dir.";
@@ -501,7 +483,7 @@
return 3;
}
- if (!checkValidDistroVersion(distroVersion.data())) {
+ if (!checkValidVersionBytes(distroVersion.data())) {
LOG(WARNING) << "distro version file " << distroVersionFileName
<< " is not valid. Deleting distro dir.";
// Implies the contents of the data partition is corrupt in some way. Try to clean up.
@@ -509,63 +491,65 @@
return 4;
}
- std::string actualDistroVersion =
- std::string(distroVersion.data(), SUPPORTED_DISTRO_VERSION_LEN);
- // Check the first 3 bytes of the distro version: these are the major version (e.g. 001).
+ // Check the base tz data set version.
+ std::string baseVersionFileName(baseZoneInfoDir);
+ baseVersionFileName += BASE_VERSION_FILENAME;
+ std::vector<char> baseVersion;
+ baseVersion.reserve(READ_DATA_LENGTH);
+ bool baseVersionReadOk =
+ readBytes(baseVersionFileName, baseVersion.data(), READ_DATA_LENGTH);
+ if (!baseVersionReadOk) {
+ // Implies the contents of the system partition is corrupt in some way. Nothing we can do.
+ LOG(WARNING) << baseVersionFileName << " does not exist or could not be opened";
+ return 6;
+ }
+
+ if (!checkValidVersionBytes(baseVersion.data())) {
+ // Implies the contents of the system partition is corrupt in some way. Nothing we can do.
+ LOG(WARNING) << baseVersionFileName << " is not valid.";
+ return 7;
+ }
+
+ std::string actualDistroVersion = std::string(distroVersion.data(), FORMAT_VERSION_LEN);
+ std::string baseTzVersion = std::string(baseVersion.data(), FORMAT_VERSION_LEN);
+
+ // Check the first 3 bytes of the format version: these are the major version (e.g. 001).
// It must match the one we support exactly to be ok.
if (strncmp(
- &distroVersion[0],
- SUPPORTED_DISTRO_MAJOR_VERSION,
- SUPPORTED_DISTRO_MAJOR_VERSION_LEN) != 0) {
+ &distroVersion[FORMAT_MAJOR_VERSION_IDX],
+ &baseTzVersion[FORMAT_MAJOR_VERSION_IDX],
+ FORMAT_MAJOR_VERSION_LEN) != 0) {
LOG(INFO) << "distro version file " << distroVersionFileName
- << " major version is not the required version " << SUPPORTED_DISTRO_MAJOR_VERSION
+ << " major version is not the required version " << baseTzVersion
<< ", was \"" << actualDistroVersion << "\". Deleting distro dir.";
- // This implies there has been an OTA and the installed distro is not compatible with the
+ // This implies there has been an OTA and the installed distro is not compatible with a
// new version of Android. Remove the installed distro.
deleteUpdateDistroDir(dataCurrentDirName);
return 5;
}
- // Check the last 3 bytes of the distro version: these are the minor version (e.g. 001).
+ // Check the last 3 bytes of the format version: these are the minor version (e.g. 001).
// If the version in the distro is < the minor version required by this device it cannot be
// used.
if (strncmp(
- &distroVersion[4],
- SUPPORTED_DISTRO_MINOR_VERSION,
- SUPPORTED_DISTRO_MINOR_VERSION_LEN) < 0) {
+ &distroVersion[FORMAT_MINOR_VERSION_IDX],
+ &baseTzVersion[FORMAT_MINOR_VERSION_IDX],
+ FORMAT_MINOR_VERSION_LEN) < 0) {
LOG(INFO) << "distro version file " << distroVersionFileName
- << " minor version is not the required version " << SUPPORTED_DISTRO_MINOR_VERSION
+ << " minor version is not the required version " << baseTzVersion
<< ", was \"" << actualDistroVersion << "\". Deleting distro dir.";
- // This implies there has been an OTA and the installed distro is not compatible with the
+ // This implies there has been an OTA and the installed distro is not compatible with a
// new version of Android. Remove the installed distro.
deleteUpdateDistroDir(dataCurrentDirName);
return 5;
}
- // Read the system rules version out of the /system tzdata file.
- std::string systemTzDataFileName(systemZoneInfoDir);
- systemTzDataFileName += TZDATA_FILENAME;
- std::vector<char> systemTzDataHeader;
- systemTzDataHeader.reserve(TZ_HEADER_LENGTH);
- bool systemFileExists =
- readBytes(systemTzDataFileName, systemTzDataHeader.data(), TZ_HEADER_LENGTH);
- if (!systemFileExists) {
- // Implies the contents of the system partition is corrupt in some way. Nothing we can do.
- LOG(WARNING) << systemTzDataFileName << " does not exist or could not be opened";
- return 6;
- }
- if (!checkValidTzDataHeader(systemTzDataFileName, systemTzDataHeader.data())) {
- // Implies the contents of the system partition is corrupt in some way. Nothing we can do.
- LOG(WARNING) << systemTzDataFileName << " does not have a valid header.";
- return 7;
- }
-
// Compare the distro rules version against the system rules version.
if (strncmp(
- &systemTzDataHeader[TZ_DATA_HEADER_PREFIX_LEN],
- &distroVersion[DISTRO_VERSION_RULES_IDX],
+ &baseVersion[VERSION_RULES_IDX],
+ &distroVersion[VERSION_RULES_IDX],
RULES_VERSION_LEN) <= 0) {
LOG(INFO) << "Found an installed distro but it is valid. No action taken.";
// Implies there is an installed update, but it is good.
@@ -575,7 +559,7 @@
// Implies there has been an OTA and the system version of the timezone rules is now newer
// than the version installed in /data. Remove the installed distro.
LOG(INFO) << "timezone distro in " << dataCurrentDirName << " is older than data in "
- << systemTzDataFileName << "; fixing...";
+ << baseVersionFileName << "; fixing...";
deleteUpdateDistroDir(dataCurrentDirName);
return 0;