Merge "Add a script for creating distro files"
diff --git a/distro/README b/distro/README
new file mode 100644
index 0000000..8ead13f
--- /dev/null
+++ b/distro/README
@@ -0,0 +1,9 @@
+This directory contains tools and code associated with time zone "distro"
+files.
+
+A distro file is a zip archive containing the files needed to update the time
+zone rules on a correctly configured Android device, i.e. files required by
+ICU4J / ICU4C / libcore and bionic libraries.
+
+The .zip file also contains versioning information that can be used to prevent
+a distro file being installed on an unsupported device.
diff --git a/distro/tools/create-distro.py b/distro/tools/create-distro.py
new file mode 100755
index 0000000..e89e54d
--- /dev/null
+++ b/distro/tools/create-distro.py
@@ -0,0 +1,108 @@
+#!/usr/bin/python -B
+
+# Copyright 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Generates a time zone distro file"""
+
+import argparse
+import os
+import shutil
+import subprocess
+import sys
+
+sys.path.append('../../../../external/icu/tools')
+import i18nutil
+
+
+android_build_top = i18nutil.GetAndroidRootOrDie()
+android_host_out_dir = i18nutil.GetAndroidHostOutOrDie()
+timezone_dir = os.path.realpath('%s/system/timezone' % android_build_top)
+i18nutil.CheckDirExists(timezone_dir, 'system/timezone')
+
+def RunCreateTimeZoneDistro(properties_file, distro_file):
+  # Build the libraries needed.
+  subprocess.check_call(['make', '-C', android_build_top, 'time_zone_distro_tools-host'])
+
+  libs = [ 'time_zone_distro_tools-host', 'time_zone_distro-host' ]
+  host_java_libs_dir = '%s/../common/obj/JAVA_LIBRARIES' % android_host_out_dir
+  classpath_components = []
+  for lib in libs:
+      classpath_components.append('%s/%s_intermediates/javalib.jar' % (host_java_libs_dir, lib))
+
+  classpath = ':'.join(classpath_components)
+
+  # Run the CreateTimeZoneDistro tool
+  subprocess.check_call(['java', '-cp', classpath,
+      'com.android.timezone.distro.tools.CreateTimeZoneDistro', properties_file, distro_file])
+
+
+def CreateTimeZoneDistro(iana_version, revision, tzdata_file, icu_file, tzlookup_file, output_file):
+  original_cwd = os.getcwd()
+
+  i18nutil.SwitchToNewTemporaryDirectory()
+  working_dir = os.getcwd()
+
+  # Generate the properties file.
+  properties_file = '%s/distro.properties' % working_dir
+  with open(properties_file, "w") as properties:
+    properties.write('rules.version=%s\n' % iana_version)
+    properties.write('revision=%s\n' % revision)
+    properties.write('tzdata.file=%s\n' % tzdata_file)
+    properties.write('icu.file=%s\n' % icu_file)
+    properties.write('tzlookup.file=%s\n' % tzlookup_file)
+
+  distro_file = '%s/distro.zip' % working_dir
+  RunCreateTimeZoneDistro(properties_file, distro_file)
+
+  shutil.copyfile(distro_file, output_file)
+
+  os.chdir(original_cwd)
+
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('-iana_version', required=True,
+      help='The IANA time zone rules release version, e.g. 2017b')
+  parser.add_argument('-revision', type=int, default=1,
+      help='The distro revision for the IANA version, default = 1')
+  parser.add_argument('-tzdata', required=True, help='The location of the tzdata file to include')
+  parser.add_argument('-icu', required=True,
+      help='The location of the ICU overlay .dat file to include')
+  parser.add_argument('-tzlookup', required=True,
+      help='The location of the tzlookup.xml file to include')
+  parser.add_argument('-output', required=True, help='The output file')
+  args = parser.parse_args()
+
+  iana_version = args.iana_version
+  revision = args.revision
+  tzdata_file = os.path.abspath(args.tzdata)
+  icu_file = os.path.abspath(args.icu)
+  tzlookup_file = os.path.abspath(args.tzlookup)
+  output_file = os.path.abspath(args.output)
+
+  CreateTimeZoneDistro(
+      iana_version=iana_version,
+      revision=revision,
+      tzdata_file=tzdata_file,
+      icu_file=icu_file,
+      tzlookup_file=tzlookup_file,
+      output_file=output_file)
+
+  print 'Distro file created: %s' % output_file
+  sys.exit(0)
+
+
+if __name__ == '__main__':
+  main()
diff --git a/distro/tools/createTimeZoneDistro.sh b/distro/tools/createTimeZoneDistro.sh
deleted file mode 100755
index b8b6748..0000000
--- a/distro/tools/createTimeZoneDistro.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-# A script to generate TZ data updates.
-#
-# Usage: ./createTimeZoneDistro.sh <tzupdate.properties file> <output file>
-# See com.android.timezone.distro.tools.CreateTimeZoneDistro for more information.
-
-# Fail if anything below fails
-set -e
-
-if [[ -z "${ANDROID_BUILD_TOP}" ]]; then
-  echo "Configure your environment with build/envsetup.sh and lunch"
-  exit 1
-fi
-
-cd ${ANDROID_BUILD_TOP}
-make time_zone_distro_tools-host
-
-TOOLS_LIB=${ANDROID_BUILD_TOP}/out/host/common/obj/JAVA_LIBRARIES/time_zone_distro_tools-host_intermediates/javalib.jar
-SHARED_LIB=${ANDROID_BUILD_TOP}/out/host/common/obj/JAVA_LIBRARIES/time_zone_distro-host_intermediates/javalib.jar
-
-cd -
-java -cp ${TOOLS_LIB}:${SHARED_LIB} com.android.timezone.distro.tools.CreateTimeZoneDistro $@
diff --git a/distro/tools/testing/prepareTzDataUpdates.sh b/distro/tools/testing/prepareTzDataUpdates.sh
deleted file mode 100755
index 5d127f5..0000000
--- a/distro/tools/testing/prepareTzDataUpdates.sh
+++ /dev/null
@@ -1,174 +0,0 @@
-#!/bin/bash
-
-# Used as part of manual testing of tzdata update mechanism.
-
-if [[ -z "${ANDROID_BUILD_TOP}" ]]; then
-  echo "Configure your environment with build/envsetup.sh and lunch"
-  exit 1
-fi
-
-# Fail if anything below fails
-set -e
-
-cd $ANDROID_BUILD_TOP
-
-# Get the ICU version by looking at the stubdata file
-ICU_STUB_FILE=$(ls external/icu/icu4c/source/stubdata/icudt*l.dat)
-if [ $(echo "$ICU_STUB_FILE" | wc -l) -ne 1 ]; then
-  echo "Could not find unique ICU version from external/icu/icu4c/source/stubdata/icudt*l.dat"
-  exit 1
-fi
-
-ICU_VERSION=${ICU_STUB_FILE##*icudt}
-ICU_VERSION=${ICU_VERSION%l.dat}
-
-echo "Current ICU version is ${ICU_VERSION}"
-
-# Get the current tzdata version and find both the previous and new versions.
-TZDATA=output_data/iana/tzdata
-TZLOOKUP=output_data/android/tzlookup.xml
-
-TZHEADER=$(head -n1 system/timezone/$TZDATA | cut -c1-11)
-
-TZ_CURRENT=${TZHEADER:6}
-
-let currentYear=${TZ_CURRENT:0:4}
-update=${TZ_CURRENT:4:1}
-
-let currentUpdate=$(LC_CTYPE=C printf '%d' "'$update")
-let previousUpdate=currentUpdate-1
-if [ $previousUpdate -lt 97 ]; then
-  let previousYear=currentYear-1
-  PREVIOUSCOMMIT=$(cd system/timezone; git log --format=oneline ${TZDATA} | grep -E "${previousYear}.$" | head -n1)
-  TZ_PREVIOUS=$(echo $PREVIOUSCOMMIT | sed "s|.*\(${previousYear}.\)\$|\1|")
-else
-  TZ_PREVIOUS=${currentYear}$(printf "\\$(printf '%03o' "${previousUpdate}")")
-  PREVIOUSCOMMIT=$(cd system/timezone; git log --format=oneline ${TZDATA} | grep -E "${TZ_PREVIOUS}$" | head -n1)
-fi
-
-let nextUpdate=currentUpdate+1
-TZ_NEXT=${currentYear}$(printf "\\$(printf '%03o' "${nextUpdate}")")
-
-echo "Current version of system/timezone/${TZDATA} is ${TZ_CURRENT}"
-echo "Previous version of system/timezone/${TZDATA} is ${TZ_PREVIOUS} from commit:"
-echo "    ${PREVIOUSCOMMIT}"
-echo "Next version of system/timezone/${TZDATA} is ${TZ_NEXT}"
-
-TMP=$(mktemp -d)
-
-TZ_PREVIOUS_SHA=${PREVIOUSCOMMIT%% *}
-
-TMP_PREVIOUS=${TMP}/${TZ_PREVIOUS}_test
-mkdir -p ${TMP_PREVIOUS}
-
-echo "Copied ${TZ_PREVIOUS} tzdata to ${TMP_PREVIOUS}"
-(cd system/timezone; git show ${TZ_PREVIOUS_SHA}:${TZDATA} > ${TMP_PREVIOUS}/tzdata)
-
-cd system/timezone/distro/tools
-
-################################################################
-# Preparing previous update version.
-################################################################
-
-# Create an icu_tzdata.dat for the previous tzdata version.
-# Download the archive for the previous tzdata version.
-PREVIOUS_TAR_GZ="tzdata${TZ_PREVIOUS}.tar.gz"
-TMP_PREVIOUS_TAR_GZ=${TMP}/${PREVIOUS_TAR_GZ}
-IANA_PREVIOUS_URL="ftp://ftp.iana.org/tz/releases/${PREVIOUS_TAR_GZ}"
-echo "Downloading archive for ${TZ_PREVIOUS} version from ${IANA_PREVIOUS_URL}"
-wget -O ${TMP_PREVIOUS_TAR_GZ} ftp://ftp.iana.org/tz/releases/tzdata2016d.tar.gz -o ${TMP}/${PREVIOUS_TAR_GZ}.log
-
-ICU_UPDATE_RESOURCES_LOG=${TMP}/icuUpdateResources.log
-echo "Creating icu_tzdata.dat file for ${TZ_PREVIOUS}/ICU ${ICU_VERSION}, may take a while, check ${ICU_UPDATE_RESOURCES_LOG} for details"
-./createIcuUpdateResources.sh ${TMP_PREVIOUS_TAR_GZ} ${ICU_VERSION} &> ${ICU_UPDATE_RESOURCES_LOG}
-mv icu_tzdata.dat ${TMP_PREVIOUS}
-
-TZ_PREVIOUS_UPDATE_PROPERTIES=${TMP}/tzupdate.properties.${TZ_PREVIOUS}
-cat > ${TZ_PREVIOUS_UPDATE_PROPERTIES} <<EOF
-revision=1
-rules.version=${TZ_PREVIOUS}
-tzdata.file=${TMP_PREVIOUS}/tzdata
-icu.file=${TMP_PREVIOUS}/icu_tzdata.dat
-tzlookup.file=${ANDROID_BUILD_TOP}/system/timezone/${TZLOOKUP}
-EOF
-
-TZ_PREVIOUS_UPDATE_ZIP=update_${TZ_PREVIOUS}_test.zip
-./createTimeZoneDistro.sh ${TZ_PREVIOUS_UPDATE_PROPERTIES} ${TMP}/update_${TZ_PREVIOUS}_test.zip
-adb push ${TMP}/${TZ_PREVIOUS_UPDATE_ZIP} /data/local/tmp
-echo "Pushed ${TZ_PREVIOUS_UPDATE_ZIP} to /data/local/tmp"
-
-################################################################
-# Preparing current update version.
-################################################################
-
-# Replace the version number in the current tzdata to create the current version
-TMP_CURRENT=${TMP}/${TZ_CURRENT}_test
-mkdir -p ${TMP_CURRENT}
-sed "1s/^tzdata${TZ_PREVIOUS}/tzdata${TZ_NEXT}/" ${TMP_PREVIOUS}/tzdata > ${TMP_CURRENT}/tzdata
-echo "Transformed version ${TZ_PREVIOUS} of tzdata into version ${TZ_CURRENT}"
-
-# Replace the version number in the previous icu_tzdata to create the next version
-SEARCH=$(echo ${TZ_PREVIOUS} | sed "s/\(.\)/\1\\\x00/g")
-REPLACE=$(echo ${TZ_CURRENT} | sed "s/\(.\)/\1\\\x00/g")
-sed "s/$SEARCH/$REPLACE/" ${TMP_PREVIOUS}/icu_tzdata.dat > ${TMP_CURRENT}/icu_tzdata.dat
-echo "Transformed version ${TZ_PREVIOUS} of icu_tzdata into version ${TZ_CURRENT}"
-
-TZ_CURRENT_UPDATE_PROPERTIES=${TMP}/tzupdate.properties.${TZ_CURRENT}
-cat > ${TZ_CURRENT_UPDATE_PROPERTIES} <<EOF
-revision=1
-rules.version=${TZ_CURRENT}
-tzdata.file=${TMP_CURRENT}/tzdata
-icu.file=${TMP_CURRENT}/icu_tzdata.dat
-tzlookup.file=${ANDROID_BUILD_TOP}/system/timezone/${TZLOOKUP}
-EOF
-
-TZ_CURRENT_UPDATE_ZIP=update_${TZ_CURRENT}_test.zip
-./createTimeZoneDistro.sh ${TZ_CURRENT_UPDATE_PROPERTIES} ${TMP}/update_${TZ_CURRENT}_test.zip
-adb push ${TMP}/${TZ_CURRENT_UPDATE_ZIP} /data/local/tmp
-echo "Pushed ${TZ_CURRENT_UPDATE_ZIP} to /data/local/tmp"
-
-################################################################
-# Preparing next update version.
-################################################################
-
-# Replace the version number in the previous tzdata to create the next version
-TMP_NEXT=${TMP}/${TZ_NEXT}_test
-mkdir -p ${TMP_NEXT}
-sed "1s/^tzdata${TZ_PREVIOUS}/tzdata${TZ_NEXT}/" ${TMP_PREVIOUS}/tzdata > ${TMP_NEXT}/tzdata
-echo "Transformed version ${TZ_PREVIOUS} of tzdata into version ${TZ_NEXT}"
-
-# Replace the version number in the previous icu_tzdata to create the next version
-SEARCH=$(echo ${TZ_PREVIOUS} | sed "s/\(.\)/\1\\\x00/g")
-REPLACE=$(echo ${TZ_NEXT} | sed "s/\(.\)/\1\\\x00/g")
-sed "s/$SEARCH/$REPLACE/" ${TMP_PREVIOUS}/icu_tzdata.dat > ${TMP_NEXT}/icu_tzdata.dat
-echo "Transformed version ${TZ_PREVIOUS} of icu_tzdata into version ${TZ_NEXT}"
-
-TZ_NEXT_UPDATE_PROPERTIES=${TMP}/tzupdate.properties.${TZ_NEXT}
-cat > ${TZ_NEXT_UPDATE_PROPERTIES} <<EOF
-revision=1
-rules.version=${TZ_NEXT}
-tzdata.file=${TMP_NEXT}/tzdata
-icu.file=${TMP_NEXT}/icu_tzdata.dat
-tzlookup.file=${ANDROID_BUILD_TOP}/system/timezone/${TZLOOKUP}
-EOF
-
-TZ_NEXT_UPDATE_ZIP=update_${TZ_NEXT}_test.zip
-./createTimeZoneDistro.sh ${TZ_NEXT_UPDATE_PROPERTIES} ${TMP}/update_${TZ_NEXT}_test.zip
-adb push ${TMP}/${TZ_NEXT_UPDATE_ZIP} /data/local/tmp
-echo "Pushed ${TZ_NEXT_UPDATE_ZIP} to /data/local/tmp"
-
-################################################################
-# Preparing UpdateTestApp
-################################################################
-
-UPDATE_TEST_APP_LOG=${TMP}/updateTestApp.log
-echo "Building and installing UpdateTestApp, check ${UPDATE_TEST_APP_LOG}"
-cd $ANDROID_BUILD_TOP
-make -j -l8 UpdateTestApp &> ${UPDATE_TEST_APP_LOG}
-adb install -r ${ANDROID_PRODUCT_OUT}/data/app/UpdateTestApp/UpdateTestApp.apk &>> ${UPDATE_TEST_APP_LOG}
-
-echo
-echo "Paste the following into your shell"
-echo "OLD_TZUPDATE=${TMP}/${TZ_PREVIOUS_UPDATE_ZIP}"
-echo "CURRENT_TZUPDATE=${TMP}/${TZ_CURRENT_UPDATE_ZIP}"
-echo "NEW_TZUPDATE=${TMP}/${TZ_NEXT_UPDATE_ZIP}"
diff --git a/distro/tools/testing/rebootAndGrabLogs.sh b/distro/tools/testing/rebootAndGrabLogs.sh
deleted file mode 100755
index a85481f..0000000
--- a/distro/tools/testing/rebootAndGrabLogs.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-# Used as part of manual testing of tzdata update mechanism.
-
-PREFIX=${1-bootlogs}
-
-echo "Rebooting...."
-adb reboot && adb wait-for-device
-
-TIME=${2-5}
-LOGCAT=${PREFIX}.logcat
-echo "Dumping logcat output in ${LOGCAT}, waiting for ${TIME} seconds"
-adb logcat > ${LOGCAT} 2>/dev/null &
-LOGCAT_PID=$!
-
-sleep ${TIME}
-
-# Kill the logcat process and wait, suppresses the Terminated message
-# output by the shell.
-kill ${LOGCAT_PID}
-wait ${LOGCAT_PID} 2>/dev/null
-
-DMESG=${PREFIX}.dmesg
-echo "Dumping dmesg output in ${DMESG}"
-adb shell dmesg > ${DMESG}