Merge "Revert "Build with OpenJDK 9 -target 1.8 by default (attempt 3).""
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1a84e8f..7e23ee0 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -450,6 +450,12 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/vndk)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/vndk-sp)
 
+# Remove old dex output directories
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/*/*_intermediates/with-local/)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/*/*_intermediates/no-local/)
+$(call add-clean-step, rm -rf $(HOST_OUT_COMMON_INTERMEDIATES)/*/*_intermediates/with-local/)
+$(call add-clean-step, rm -rf $(HOST_OUT_COMMON_INTERMEDIATES)/*/*_intermediates/no-local/)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index acdf180..cf22fbc 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -2313,9 +2313,7 @@
 $(BUILT_TARGET_FILES_PACKAGE): PRIVATE_TOOL_EXTENSION := $(tool_extension)
 
 ifeq ($(AB_OTA_UPDATER),true)
-# Build zlib fingerprint if using the AB Updater.
-updater_dep := $(TARGET_OUT_COMMON_GEN)/zlib_fingerprint
-updater_dep += system/update_engine/update_engine.conf
+updater_dep := system/update_engine/update_engine.conf
 else
 # Build OTA tools if not using the AB Updater.
 updater_dep := $(built_ota_tools)
@@ -2548,7 +2546,6 @@
 ifeq ($(AB_OTA_UPDATER),true)
 	@# When using the A/B updater, include the updater config files in the zip.
 	$(hide) cp $(TOPDIR)system/update_engine/update_engine.conf $(zip_root)/META/update_engine_config.txt
-	$(hide) cp $(TARGET_OUT_COMMON_GEN)/zlib_fingerprint $(zip_root)/META/zlib_fingerprint.txt
 	$(hide) for part in $(AB_OTA_PARTITIONS); do \
 	  echo "$${part}" >> $(zip_root)/META/ab_partitions.txt; \
 	done
diff --git a/core/autogen_test_config.mk b/core/autogen_test_config.mk
new file mode 100644
index 0000000..c359bac
--- /dev/null
+++ b/core/autogen_test_config.mk
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 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.
+#
+
+# This build rule allows TradeFed test config file to be created based on
+# following inputs:
+#   is_native: If the test is a native test.
+#   LOCAL_MANIFEST_FILE: Name of the AndroidManifest file for the test. If it's
+#       not set, default value `AndroidManifest.xml` will be used.
+# Output:
+#   autogen_test_config_file: Path to the test config file generated.
+
+autogen_test_config_file := $(dir $(LOCAL_BUILT_MODULE))$(LOCAL_MODULE).config
+ifeq (true,$(is_native))
+# Auto generating test config file for native test
+$(autogen_test_config_file) : $(NATIVE_TEST_CONFIG_TEMPLATE)
+	@echo "Auto generating test config $(notdir $@)"
+	$(hide) sed 's&{MODULE}&$(PRIVATE_MODULE)&g' $^ > $@
+my_auto_generate_config := true
+else
+# Auto generating test config file for instrumentation test
+ifeq ($(strip $(LOCAL_MANIFEST_FILE)),)
+  LOCAL_MANIFEST_FILE := AndroidManifest.xml
+endif
+ifdef LOCAL_FULL_MANIFEST_FILE
+  my_android_manifest := $(LOCAL_FULL_MANIFEST_FILE)
+else
+  my_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
+endif
+ifneq (,$(wildcard $(my_android_manifest)))
+$(autogen_test_config_file): PRIVATE_AUTOGEN_TEST_CONFIG_SCRIPT := $(AUTOGEN_TEST_CONFIG_SCRIPT)
+$(autogen_test_config_file): PRIVATE_TEST_CONFIG_ANDROID_MANIFEST := $(my_android_manifest)
+$(autogen_test_config_file): PRIVATE_EMPTY_TEST_CONFIG := $(EMPTY_TEST_CONFIG)
+$(autogen_test_config_file): PRIVATE_TEMPLATE := $(INSTRUMENTATION_TEST_CONFIG_TEMPLATE)
+$(autogen_test_config_file) : $(my_android_manifest) $(EMPTY_TEST_CONFIG) $(INSTRUMENTATION_TEST_CONFIG_TEMPLATE) $(AUTOGEN_TEST_CONFIG_SCRIPT)
+	@echo "Auto generating test config $(notdir $@)"
+	@rm -f $@
+	$(hide) $(PRIVATE_AUTOGEN_TEST_CONFIG_SCRIPT) $@ $(PRIVATE_TEST_CONFIG_ANDROID_MANIFEST) $(PRIVATE_EMPTY_TEST_CONFIG) $(PRIVATE_TEMPLATE)
+my_auto_generate_config := true
+endif # ifeq (,$(wildcard $(my_android_manifest)))
+endif # ifneq (true,$(is_native))
+
+ifeq (true,$(my_auto_generate_config))
+  LOCAL_INTERMEDIATE_TARGETS += $(autogen_test_config_file)
+  $(LOCAL_BUILT_MODULE): $(autogen_test_config_file)
+  ALL_MODULES.$(my_register_name).auto_test_config := true
+else
+  autogen_test_config_file :=
+endif
+
+my_android_manifest :=
+my_auto_generate_config :=
diff --git a/core/base_rules.mk b/core/base_rules.mk
index dc3a78b..9234abe 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -510,7 +510,6 @@
 endif
 ifdef is_native
   arch_dir := /$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
-  is_native :=
 endif
 
 # The module itself.
@@ -531,13 +530,35 @@
     $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
       $(s):$(dir)/$(n)))))
 
+test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
+ifeq (,$(test_config))
+  ifneq (true,$(is_native))
+    is_instrumentation_test := true
+    ifeq (true, $(LOCAL_IS_HOST_MODULE))
+      is_instrumentation_test := false
+    endif
+  endif
+  # CTS modules can be used for test data, so test config files must be
+  # explicitly created using AndroidTest.xml
+  ifeq (,$(filter cts, $(LOCAL_COMPATIBILITY_SUITE)))
+    ifeq (true, $(filter true,$(is_native) $(is_instrumentation_test)))
+      include $(BUILD_SYSTEM)/autogen_test_config.mk
+      test_config := $(autogen_test_config_file)
+      autogen_test_config_file :=
+    endif
+  endif
+endif
 
-ifneq (,$(wildcard $(LOCAL_PATH)/AndroidTest.xml))
+is_instrumentation_test :=
+
+ifneq (,$(test_config))
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
   $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
-    $(LOCAL_PATH)/AndroidTest.xml:$(dir)/$(LOCAL_MODULE).config)))
+    $(test_config):$(dir)/$(LOCAL_MODULE).config)))
 endif
 
+test_config :=
+
 ifneq (,$(wildcard $(LOCAL_PATH)/DynamicConfig.xml))
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
   $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
@@ -552,6 +573,9 @@
 endif
 endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
 
+arch_dir :=
+is_native :=
+
 ifneq ($(my_test_data_file_pairs),)
 $(foreach pair, $(my_test_data_file_pairs), \
   $(eval parts := $(subst :,$(space),$(pair))) \
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index d6e8c4c..fa6fd7a 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -93,6 +93,7 @@
 LOCAL_FULL_MANIFEST_FILE:=
 LOCAL_FULL_CLASSES_JACOCO_JAR:=
 LOCAL_FULL_CLASSES_PRE_JACOCO_JAR:=
+LOCAL_FUZZ_ENGINE:=
 LOCAL_GCNO_FILES:=
 LOCAL_GENERATED_SOURCES:=
 # Group static libraries with "-Wl,--start-group" and "-Wl,--end-group" when linking.
diff --git a/core/config.mk b/core/config.mk
index eda9b05..5411d08 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -60,11 +60,11 @@
 
 # Mark variables deprecated/obsolete
 CHANGES_URL := https://android.googlesource.com/platform/build/+/master/Changes.md
-$(KATI_deprecated_var PATH,Do not use PATH directly. See $(CHANGES_URL)#PATH)
+$(KATI_obsolete_var PATH,Do not use PATH directly. See $(CHANGES_URL)#PATH)
 $(KATI_obsolete_var PYTHONPATH,Do not use PYTHONPATH directly. See $(CHANGES_URL)#PYTHONPATH)
 $(KATI_obsolete_var OUT,Use OUT_DIR instead. See $(CHANGES_URL)#OUT)
 $(KATI_obsolete_var ANDROID_HOST_OUT,Use HOST_OUT instead. See $(CHANGES_URL)#ANDROID_HOST_OUT)
-$(KATI_deprecated_var ANDROID_PRODUCT_OUT,Use PRODUCT_OUT instead. See $(CHANGES_URL)#ANDROID_PRODUCT_OUT)
+$(KATI_obsolete_var ANDROID_PRODUCT_OUT,Use PRODUCT_OUT instead. See $(CHANGES_URL)#ANDROID_PRODUCT_OUT)
 $(KATI_obsolete_var ANDROID_HOST_OUT_TESTCASES,Use HOST_OUT_TESTCASES instead. See $(CHANGES_URL)#ANDROID_HOST_OUT_TESTCASES)
 $(KATI_obsolete_var ANDROID_TARGET_OUT_TESTCASES,Use TARGET_OUT_TESTCASES instead. See $(CHANGES_URL)#ANDROID_TARGET_OUT_TESTCASES)
 $(KATI_deprecated_var ANDROID_BUILD_TOP,Use '.' instead. See $(CHANGES_URL)#ANDROID_BUILD_TOP)
@@ -157,8 +157,15 @@
 BUILD_HOST_DALVIK_JAVA_LIBRARY := $(BUILD_SYSTEM)/host_dalvik_java_library.mk
 BUILD_HOST_DALVIK_STATIC_JAVA_LIBRARY := $(BUILD_SYSTEM)/host_dalvik_static_java_library.mk
 
-BUILD_HOST_TEST_CONFIG:= $(BUILD_SYSTEM)/host_test_config.mk
-BUILD_TARGET_TEST_CONFIG:= $(BUILD_SYSTEM)/target_test_config.mk
+BUILD_HOST_TEST_CONFIG := $(BUILD_SYSTEM)/host_test_config.mk
+BUILD_TARGET_TEST_CONFIG := $(BUILD_SYSTEM)/target_test_config.mk
+
+INSTRUMENTATION_TEST_CONFIG_TEMPLATE := $(BUILD_SYSTEM)/instrumentation_test_config_template.xml
+NATIVE_TEST_CONFIG_TEMPLATE := $(BUILD_SYSTEM)/native_test_config_template.xml
+EMPTY_TEST_CONFIG := $(BUILD_SYSTEM)/empty_test_config.xml
+
+# Tool to generate TradeFed test config file automatically.
+AUTOGEN_TEST_CONFIG_SCRIPT := build/make/tools/auto_gen_test_config.py
 
 # ###############################################################
 # Parse out any modifier targets.
@@ -811,7 +818,12 @@
   DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/testkey
 endif
 
-FRAMEWORK_MANIFEST_FILE := system/libhidl/manifest.xml
+FRAMEWORK_MANIFEST_INPUT_FILES := system/libhidl/manifest.xml
+ifdef DEVICE_FRAMEWORK_MANIFEST_FILE
+  FRAMEWORK_MANIFEST_INPUT_FILES += $(DEVICE_FRAMEWORK_MANIFEST_FILE)
+endif
+$(.KATI_obsolete_var DEVICE_FRAMEWORK_MANIFEST_FILE,No one should ever need to use this.)
+
 FRAMEWORK_COMPATIBILITY_MATRIX_FILES := $(wildcard hardware/interfaces/compatibility_matrix.*.xml)
 
 BUILD_NUMBER_FROM_FILE := $$(cat $(OUT_DIR)/build_number.txt)
diff --git a/core/definitions.mk b/core/definitions.mk
index 5ad78fd..a20bf44 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2421,8 +2421,7 @@
     --output $(dir $@) \
     --min-api $(PRIVATE_MIN_SDK_VERSION) \
     $(subst --main-dex-list=, --main-dex-list , \
-    $(subst --no-locals, --release, \
-        $(filter-out --core-library --multi-dex --minimal-main-dex,$(PRIVATE_DX_FLAGS)))) \
+        $(filter-out --core-library --multi-dex --minimal-main-dex,$(PRIVATE_DX_FLAGS))) \
     $(dir $@)d8_input.jar
 $(hide) rm -f $(dir $@)d8_input.jar
 endef
diff --git a/core/empty_test_config.xml b/core/empty_test_config.xml
new file mode 100644
index 0000000..7c9daff
--- /dev/null
+++ b/core/empty_test_config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<!-- No AndroidTest.xml was provided and the manifest does not include
+     instrumentation, hence this apk is not instrumentable.
+-->
+<configuration description="Empty Configuration" />
diff --git a/core/fuzz_test.mk b/core/fuzz_test.mk
index 7e3995a..29e1dde 100644
--- a/core/fuzz_test.mk
+++ b/core/fuzz_test.mk
@@ -8,8 +8,50 @@
     $(error $(LOCAL_PATH): $(LOCAL_MODULE): NDK fuzz tests are not supported.)
 endif
 
+my_fuzzer:=libFuzzer
+ifdef LOCAL_FUZZ_ENGINE
+    my_fuzzer:=$(LOCAL_FUZZ_ENGINE)
+else ifdef TARGET_FUZZ_ENGINE
+    my_fuzzer:=$(TARGET_FUZZ_ENGINE)
+endif
+
+
 LOCAL_CFLAGS += -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp
+
+ifeq ($(my_fuzzer),libFuzzer)
 LOCAL_STATIC_LIBRARIES += libFuzzer
+else ifeq ($(my_fuzzer),honggfuzz)
+LOCAL_STATIC_LIBRARIES += honggfuzz_libhfuzz
+
+LOCAL_LDFLAGS += \
+        "-Wl,--wrap=strcmp" \
+        "-Wl,--wrap=strcasecmp" \
+        "-Wl,--wrap=strncmp" \
+        "-Wl,--wrap=strncasecmp" \
+        "-Wl,--wrap=strstr" \
+        "-Wl,--wrap=strcasestr" \
+        "-Wl,--wrap=memcmp" \
+        "-Wl,--wrap=bcmp" \
+        "-Wl,--wrap=memmem" \
+        "-Wl,--wrap=ap_cstr_casecmp" \
+        "-Wl,--wrap=ap_cstr_casecmpn" \
+        "-Wl,--wrap=ap_strcasestr" \
+        "-Wl,--wrap=apr_cstr_casecmp" \
+        "-Wl,--wrap=apr_cstr_casecmpn" \
+        "-Wl,--wrap=CRYPTO_memcmp" \
+        "-Wl,--wrap=OPENSSL_memcmp" \
+        "-Wl,--wrap=OPENSSL_strcasecmp" \
+        "-Wl,--wrap=OPENSSL_strncasecmp" \
+        "-Wl,--wrap=xmlStrncmp" \
+        "-Wl,--wrap=xmlStrcmp" \
+        "-Wl,--wrap=xmlStrEqual" \
+        "-Wl,--wrap=xmlStrcasecmp" \
+        "-Wl,--wrap=xmlStrncasecmp" \
+        "-Wl,--wrap=xmlStrstr" \
+        "-Wl,--wrap=xmlStrcasestr"
+else
+$(call pretty-error, Unknown fuzz engine $(my_fuzzer))
+endif
 
 ifdef LOCAL_MODULE_PATH
 $(error $(LOCAL_PATH): Do not set LOCAL_MODULE_PATH when building test $(LOCAL_MODULE))
diff --git a/core/instrumentation_test_config_template.xml b/core/instrumentation_test_config_template.xml
new file mode 100644
index 0000000..a0badab
--- /dev/null
+++ b/core/instrumentation_test_config_template.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<!-- This test config file is auto-generated. -->
+<configuration description="Runs {LABEL}.">
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="test-file-name" value="{MODULE}.apk" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.{TEST_TYPE}" >
+        <option name="package" value="{PACKAGE}" />
+        <option name="runner" value="{RUNNER}" />
+    </test>
+</configuration>
diff --git a/core/java.mk b/core/java.mk
index 444a112..c74a0a5 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -59,15 +59,6 @@
 intermediates := $(call local-intermediates-dir)
 intermediates.COMMON := $(call local-intermediates-dir,COMMON)
 
-# Choose leaf name for the compiled jar file.
-ifeq ($(LOCAL_EMMA_INSTRUMENT),true)
-full_classes_compiled_jar_leaf := classes-no-debug-var.jar
-built_dex_intermediate_leaf := no-local
-else
-full_classes_compiled_jar_leaf := classes-full-debug.jar
-built_dex_intermediate_leaf := with-local
-endif
-
 ifeq ($(LOCAL_PROGUARD_ENABLED),disabled)
 LOCAL_PROGUARD_ENABLED :=
 endif
@@ -75,14 +66,13 @@
 full_classes_turbine_jar := $(intermediates.COMMON)/classes-turbine.jar
 full_classes_header_jarjar := $(intermediates.COMMON)/classes-header-jarjar.jar
 full_classes_header_jar := $(intermediates.COMMON)/classes-header.jar
-full_classes_compiled_jar := $(intermediates.COMMON)/$(full_classes_compiled_jar_leaf)
+full_classes_compiled_jar := $(intermediates.COMMON)/classes-full-debug.jar
 full_classes_processed_jar := $(intermediates.COMMON)/classes-processed.jar
 full_classes_desugar_jar := $(intermediates.COMMON)/classes-desugar.jar
-jarjar_leaf := classes-jarjar.jar
-full_classes_jarjar_jar := $(intermediates.COMMON)/$(jarjar_leaf)
+full_classes_jarjar_jar := $(intermediates.COMMON)/classes-jarjar.jar
 full_classes_proguard_jar := $(intermediates.COMMON)/classes-proguard.jar
 full_classes_combined_jar := $(intermediates.COMMON)/classes-combined.jar
-built_dex_intermediate := $(intermediates.COMMON)/$(built_dex_intermediate_leaf)/classes.dex
+built_dex_intermediate := $(intermediates.COMMON)/dex/classes.dex
 full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
 java_source_list_file := $(intermediates.COMMON)/java-source-list
 
@@ -603,7 +593,7 @@
 
 # Run proguard if necessary
 ifdef LOCAL_PROGUARD_ENABLED
-ifneq ($(filter-out full custom nosystem obfuscation optimization shrinktests,$(LOCAL_PROGUARD_ENABLED)),)
+ifneq ($(filter-out full custom nosystem obfuscation optimization,$(LOCAL_PROGUARD_ENABLED)),)
     $(warning while processing: $(LOCAL_MODULE))
     $(error invalid value for LOCAL_PROGUARD_ENABLED: $(LOCAL_PROGUARD_ENABLED))
 endif
@@ -644,15 +634,8 @@
 common_proguard_flag_files :=
 ifeq ($(filter nosystem,$(LOCAL_PROGUARD_ENABLED)),)
 common_proguard_flag_files += $(BUILD_SYSTEM)/proguard.flags
-ifeq ($(LOCAL_EMMA_INSTRUMENT),true)
-common_proguard_flags += -include $(BUILD_SYSTEM)/proguard.emma.flags
-endif
-# If this is a test package, add proguard keep flags for tests.
 ifneq ($(LOCAL_INSTRUMENTATION_FOR)$(filter tests,$(LOCAL_MODULE_TAGS)),)
-common_proguard_flag_files += $(BUILD_SYSTEM)/proguard_tests.flags
-ifeq ($(filter shrinktests,$(LOCAL_PROGUARD_ENABLED)),)
 common_proguard_flags += -dontshrink # don't shrink tests by default
-endif # shrinktests
 endif # test package
 ifneq ($(LOCAL_PROGUARD_ENABLED),custom)
   ifdef LOCAL_USE_AAPT2
@@ -757,15 +740,6 @@
 
 ifneq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
 $(built_dex_intermediate): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
-# If you instrument class files that have local variable debug information in
-# them emma does not correctly maintain the local variable table.
-# This will cause an error when you try to convert the class files for Android.
-# The workaround here is to build different dex file here based on emma switch
-# then later copy into classes.dex. When emma is on, dx is run with --no-locals
-# option to remove local variable information
-ifeq ($(LOCAL_EMMA_INSTRUMENT),true)
-$(built_dex_intermediate): PRIVATE_DX_FLAGS += --no-locals
-endif
 
 my_r8 :=
 ifdef LOCAL_PROGUARD_ENABLED
diff --git a/core/native_test_config_template.xml b/core/native_test_config_template.xml
new file mode 100644
index 0000000..a960529
--- /dev/null
+++ b/core/native_test_config_template.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<!-- This test config file is auto-generated. -->
+<configuration description="Runs {MODULE}.">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="{MODULE}" />
+    </test>
+</configuration>
diff --git a/core/proguard.emma.flags b/core/proguard.emma.flags
deleted file mode 100644
index bf94086..0000000
--- a/core/proguard.emma.flags
+++ /dev/null
@@ -1,4 +0,0 @@
-# Keep everything for the emma classes
--keep class com.vladium.** {
-  *;
-}
diff --git a/core/proguard_tests.flags b/core/proguard_tests.flags
deleted file mode 100644
index 1f840bc..0000000
--- a/core/proguard_tests.flags
+++ /dev/null
@@ -1,26 +0,0 @@
-# Keep everything for tests
-# This flag has been moved to the makefiles and is set for tests by default.
-#-dontshrink
-
-# But we may want to obfuscate if the main app gets obfuscated.
-# This flag has been moved to the makefiles.
-#-dontobfuscate
-
-#-keep class * extends junit.framework.TestCase {
-#  public void test*();
-#}
-
-#-keepclasseswithmembers class * {
-#  public static void run();
-#  public static junit.framework.Test suite();
-#}
-
-# some AllTests don't include run().
-#-keepclasseswithmembers class * {
-#  public static junit.framework.Test suite();
-#}
-
-#-keep class * extends junit.framework.TestSuite
-#-keep class * extends android.app.Instrumentation
-#-keep class * extends android.test.TestSuiteProvider
-
diff --git a/core/tasks/check_emu_boot.mk b/core/tasks/check_emu_boot.mk
new file mode 100644
index 0000000..4870677
--- /dev/null
+++ b/core/tasks/check_emu_boot.mk
@@ -0,0 +1,23 @@
+check_emu_boot0 := $(DIST_DIR)/$(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)-emulator-boot-test-result.txt
+$(check_emu_boot0) : PRIVATE_PREFIX := $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)
+$(check_emu_boot0) : PRIVATE_EMULATOR_BOOT_TEST_SH := device/generic/goldfish/tools/emulator_boot_test.sh
+$(check_emu_boot0) : PRIVATE_BOOT_COMPLETE_STRING := "emulator: INFO: boot completed"
+$(check_emu_boot0) : PRIVATE_BOOT_FAIL_STRING := "emulator: ERROR: fail to boot after"
+$(check_emu_boot0) : PRIVATE_SUCCESS_FILE := $(DIST_DIR)/$(PRIVATE_PREFIX)-BOOT-SUCCESS.txt
+$(check_emu_boot0) : PRIVATE_FAIL_FILE := $(DIST_DIR)/$(PRIVATE_PREFIX)-BOOT-FAIL.txt
+$(check_emu_boot0) : $(INSTALLED_QEMU_SYSTEMIMAGE)  $(INSTALLED_QEMU_VENDORIMAGE) \
+                 $(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(PRODUCT_OUT)/userdata.img) \
+                 $(PRODUCT_OUT)/ramdisk.img device/generic/goldfish/tools/emulator_boot_test.sh
+	@mkdir -p $(dir $(check_emu_boot0))
+	$(hide) rm -f $(check_emu_boot0)
+	$(hide) rm -f $(PRIVATE_SUCCESS_FILE)
+	$(hide) rm -f $(PRIVATE_FAIL_FILE)
+	(export ANDROID_PRODUCT_OUT=$$(cd $(PRODUCT_OUT);pwd);\
+		export ANDROID_BUILD_TOP=$$(pwd);\
+		$(PRIVATE_EMULATOR_BOOT_TEST_SH) > $(check_emu_boot0))
+	(if grep -q $(PRIVATE_BOOT_COMPLETE_STRING) $(check_emu_boot0);\
+	then echo boot_succeeded > $(PRIVATE_SUCCESS_FILE); fi)
+	(if grep -q $(PRIVATE_BOOT_FAIL_STRING) $(check_emu_boot0);\
+	then echo boot_failed > $(PRIVATE_FAIL_FILE); fi)
+.PHONY: check_emu_boot
+check_emu_boot: $(check_emu_boot0)
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index f6d688c..b45526f 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -12,6 +12,7 @@
 			'"tags": [$(foreach w,$(sort $(ALL_MODULES.$(m).TAGS)),"$(w)", )], ' \
 			'"installed": [$(foreach w,$(sort $(ALL_MODULES.$(m).INSTALLED)),"$(w)", )], ' \
 			'"compatibility_suites": [$(foreach w,$(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES)),"$(w)", )], ' \
+			'"auto_test_config": [$(ALL_MODULES.$(m).auto_test_config)], ' \
 			'},\n' \
 	 ) | sed -e 's/, *\]/]/g' -e 's/, *\}/ }/g' -e '$$s/,$$//' >> $@
 	$(hide) echo '}' >> $@
diff --git a/core/tasks/vndk.mk b/core/tasks/vndk.mk
index 1bbd3b0..fd7a696 100644
--- a/core/tasks/vndk.mk
+++ b/core/tasks/vndk.mk
@@ -17,6 +17,9 @@
 # BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
 ifeq ($(BOARD_VNDK_VERSION),current)
 
+# PLATFORM_VNDK_VERSION must be set.
+ifneq (,$(PLATFORM_VNDK_VERSION))
+
 # Returns arch-specific libclang_rt.ubsan* library name.
 # Because VNDK_CORE_LIBRARIES includes all arch variants for libclang_rt.ubsan*
 # libs, the arch-specific libs are selected separately.
@@ -233,6 +236,15 @@
 # vndk_snapshot_arch_2ND :=
 # endif
 
+else # PLATFORM_VNDK_VERSION is NOT set
+
+.PHONY: vndk
+vndk:
+	$(call echo-error,$(current_makefile),CANNOT generate VNDK snapshot. PLATFORM_VNDK_VERSION must be set.)
+	exit 1
+
+endif # PLATFORM_VNDK_VERSION
+
 else # BOARD_VNDK_VERSION is NOT set to 'current'
 
 .PHONY: vndk
diff --git a/target/board/Android.mk b/target/board/Android.mk
index fc32cd9..f4d6b93 100644
--- a/target/board/Android.mk
+++ b/target/board/Android.mk
@@ -89,8 +89,11 @@
 endif
 endif
 
-$(GEN): $(FRAMEWORK_MANIFEST_FILE) $(HOST_OUT_EXECUTABLES)/assemble_vintf
-	BOARD_SEPOLICY_VERS=$(BOARD_SEPOLICY_VERS) $(HOST_OUT_EXECUTABLES)/assemble_vintf -i $< -o $@ $(PRIVATE_FLAGS)
+$(GEN): PRIVATE_FRAMEWORK_MANIFEST_INPUT_FILES := $(FRAMEWORK_MANIFEST_INPUT_FILES)
+$(GEN): $(FRAMEWORK_MANIFEST_INPUT_FILES) $(HOST_OUT_EXECUTABLES)/assemble_vintf
+	BOARD_SEPOLICY_VERS=$(BOARD_SEPOLICY_VERS) $(HOST_OUT_EXECUTABLES)/assemble_vintf \
+		-i $(call normalize-path-list,$(PRIVATE_FRAMEWORK_MANIFEST_INPUT_FILES)) \
+		-o $@ $(PRIVATE_FLAGS)
 
 LOCAL_PREBUILT_MODULE_FILE := $(GEN)
 include $(BUILD_PREBUILT)
diff --git a/target/product/base.mk b/target/product/base.mk
index f4ac2eb..45cbf7e 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -130,6 +130,7 @@
     settings \
     sgdisk \
     sm \
+    statsd \
     svc \
     tc \
     telecom \
diff --git a/target/product/go_defaults_common.mk b/target/product/go_defaults_common.mk
index ca58c1d..ad5fe94 100644
--- a/target/product/go_defaults_common.mk
+++ b/target/product/go_defaults_common.mk
@@ -20,7 +20,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
      ro.config.low_ram=true \
      ro.lmk.critical_upgrade=true \
-     ro.lmk.upgrade_pressure=40
+     ro.lmk.upgrade_pressure=40 \
+     ro.lmk.downgrade_pressure=60 \
+     ro.lmk.kill_heaviest_task=false
 
 # set threshold to filter unused apps
 PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/target/product/treble_common.mk b/target/product/treble_common.mk
index 4acf52e..7c6ef8c 100644
--- a/target/product/treble_common.mk
+++ b/target/product/treble_common.mk
@@ -78,3 +78,7 @@
     system/core/rootdir/etc/ld.config.txt:system/etc/ld.config.noenforce.txt \
     build/make/target/product/vndk/init.gsi.rc:system/etc/init/init.gsi.rc \
     build/make/target/product/vndk/init.noenforce.rc:system/etc/init/gsi/init.noenforce.rc
+
+#Set current VNDK version for GSI
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
+    ro.gsi.vndk.version=$(PLATFORM_VNDK_VERSION)
diff --git a/target/product/vndk/init.noenforce.rc b/target/product/vndk/init.noenforce.rc
index 9371cc8..6cf1df7 100644
--- a/target/product/vndk/init.noenforce.rc
+++ b/target/product/vndk/init.noenforce.rc
@@ -1,3 +1,5 @@
 on early-init
     # If ro.vndk.version is not set, use ld.config.nonenforce.txt
     export LD_CONFIG_FILE /system/etc/ld.config.noenforce.txt
+    # To use current VNDK libs, set ro.vndk.version to system vndk version
+    setprop ro.vndk.version ${ro.gsi.vndk.version}
diff --git a/tools/auto_gen_test_config.py b/tools/auto_gen_test_config.py
new file mode 100755
index 0000000..da4443c
--- /dev/null
+++ b/tools/auto_gen_test_config.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 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.
+
+"""A tool to generate TradeFed test config file.
+"""
+
+import os
+import shutil
+import sys
+from xml.dom.minidom import parse
+
+ATTRIBUTE_LABEL = 'android:label'
+ATTRIBUTE_RUNNER = 'android:name'
+ATTRIBUTE_PACKAGE = 'package'
+
+PLACEHOLDER_LABEL = '{LABEL}'
+PLACEHOLDER_MODULE = '{MODULE}'
+PLACEHOLDER_PACKAGE = '{PACKAGE}'
+PLACEHOLDER_RUNNER = '{RUNNER}'
+PLACEHOLDER_TEST_TYPE = '{TEST_TYPE}'
+
+
+def main(argv):
+  """Entry point of auto_gen_test_config.
+
+  Args:
+    argv: A list of arguments.
+  Returns:
+    0 if no error, otherwise 1.
+  """
+  if len(argv) != 4:
+    sys.stderr.write(
+        'Invalid arguements. The script requires 4 arguments for file paths: '
+        'target_config android_manifest empty_config '
+        'instrumentation_test_config_template.\n')
+    return 1
+  target_config = argv[0]
+  android_manifest = argv[1]
+  empty_config = argv[2]
+  instrumentation_test_config_template = argv[3]
+
+  manifest = parse(android_manifest)
+  instrumentation_elements = manifest.getElementsByTagName('instrumentation')
+  manifest_elements = manifest.getElementsByTagName('manifest')
+  if len(instrumentation_elements) != 1 or len(manifest_elements) != 1:
+    # Failed to locate instrumentation or manifest element in AndroidManifest.
+    # file. Empty test config file will be created.
+    shutil.copyfile(empty_config, target_config)
+    return 0
+
+  module = os.path.splitext(os.path.basename(target_config))[0]
+  instrumentation = instrumentation_elements[0]
+  manifest = manifest_elements[0]
+  if instrumentation.attributes.has_key(ATTRIBUTE_LABEL):
+    label = instrumentation.attributes[ATTRIBUTE_LABEL].value
+  else:
+    label = module
+  runner = instrumentation.attributes[ATTRIBUTE_RUNNER].value
+  package = manifest.attributes[ATTRIBUTE_PACKAGE].value
+  test_type = ('AndroidJUnitTest' if runner.endswith('.AndroidJUnitRunner')
+               else 'InstrumentationTest')
+
+  with open(instrumentation_test_config_template) as template:
+    config = template.read()
+    config = config.replace(PLACEHOLDER_LABEL, label)
+    config = config.replace(PLACEHOLDER_MODULE, module)
+    config = config.replace(PLACEHOLDER_PACKAGE, package)
+    config = config.replace(PLACEHOLDER_TEST_TYPE, test_type)
+    config = config.replace(PLACEHOLDER_RUNNER, runner)
+    with open(target_config, 'w') as config_file:
+      config_file.write(config)
+  return 0
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv[1:]))
diff --git a/tools/auto_gen_test_config_test.py b/tools/auto_gen_test_config_test.py
new file mode 100644
index 0000000..e70eff8
--- /dev/null
+++ b/tools/auto_gen_test_config_test.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Unittests for auto_gen_test_config."""
+
+import os
+import shutil
+import tempfile
+import unittest
+
+import auto_gen_test_config
+
+TEST_MODULE = 'TestModule'
+
+MANIFEST_INVALID = """<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+</manifest>
+"""
+
+MANIFEST_JUNIT_TEST = """<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="com.android.my.tests.x">
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.my.tests" />
+</manifest>
+"""
+
+MANIFEST_INSTRUMENTATION_TEST = """<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="com.android.my.tests.x">
+    <instrumentation
+        android:name="android.test.InstrumentationTestRunner"
+        android:targetPackage="com.android.my.tests"
+        android:label="My Tests" />
+</manifest>
+"""
+
+EXPECTED_JUNIT_TEST_CONFIG = """<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<!-- This test config file is auto-generated. -->
+<configuration description="Runs TestModule.">
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="test-file-name" value="TestModule.apk" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.my.tests.x" />
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+    </test>
+</configuration>
+"""
+
+EXPECTED_INSTRUMENTATION_TEST_CONFIG = """<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<!-- This test config file is auto-generated. -->
+<configuration description="Runs My Tests.">
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="test-file-name" value="TestModule.apk" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+        <option name="package" value="com.android.my.tests.x" />
+        <option name="runner" value="android.test.InstrumentationTestRunner" />
+    </test>
+</configuration>
+"""
+
+TOOLS_DIR = os.path.dirname(os.path.dirname(__file__))
+EMPTY_TEST_CONFIG = os.path.join(
+    TOOLS_DIR, '..', 'core', 'empty_test_config.xml')
+INSTRUMENTATION_TEST_CONFIG_TEMPLATE = os.path.join(
+    TOOLS_DIR, '..', 'core', 'instrumentation_test_config_template.xml')
+
+
+class AutoGenTestConfigUnittests(unittest.TestCase):
+  """Unittests for auto_gen_test_config."""
+
+  def setUp(self):
+    """Setup directory for test."""
+    self.test_dir = tempfile.mkdtemp()
+    self.config_file = os.path.join(self.test_dir, TEST_MODULE + '.config')
+    self.manifest_file = os.path.join(self.test_dir, 'AndroidManifest.xml')
+
+  def tearDown(self):
+    """Cleanup the test directory."""
+    shutil.rmtree(self.test_dir, ignore_errors=True)
+
+  def testInvalidManifest(self):
+    """An empty test config should be generated if AndroidManifest is invalid.
+    """
+    with open(self.manifest_file, 'w') as f:
+      f.write(MANIFEST_INVALID)
+
+    argv = [self.config_file,
+            self.manifest_file,
+            EMPTY_TEST_CONFIG,
+            INSTRUMENTATION_TEST_CONFIG_TEMPLATE]
+    auto_gen_test_config.main(argv)
+    with open(self.config_file) as config_file:
+      with open(EMPTY_TEST_CONFIG) as empty_config:
+        self.assertEqual(config_file.read(), empty_config.read())
+
+  def testCreateJUnitTestConfig(self):
+    """Test creating test config for AndroidJUnitTest.
+    """
+    with open(self.manifest_file, 'w') as f:
+      f.write(MANIFEST_JUNIT_TEST)
+
+    argv = [self.config_file,
+            self.manifest_file,
+            EMPTY_TEST_CONFIG,
+            INSTRUMENTATION_TEST_CONFIG_TEMPLATE]
+    auto_gen_test_config.main(argv)
+    with open(self.config_file) as config_file:
+      self.assertEqual(config_file.read(), EXPECTED_JUNIT_TEST_CONFIG)
+
+  def testCreateInstrumentationTestConfig(self):
+    """Test creating test config for AndroidJUnitTest.
+    """
+    with open(self.manifest_file, 'w') as f:
+      f.write(MANIFEST_INSTRUMENTATION_TEST)
+
+    argv = [self.config_file,
+            self.manifest_file,
+            EMPTY_TEST_CONFIG,
+            INSTRUMENTATION_TEST_CONFIG_TEMPLATE]
+    auto_gen_test_config.main(argv)
+    with open(self.config_file) as config_file:
+      self.assertEqual(
+          config_file.read(), EXPECTED_INSTRUMENTATION_TEST_CONFIG)
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 8b55a45..9601d88 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -307,8 +307,7 @@
   if OPTIONS.info_dict.get("userdata_img_with_data") == "true":
     user_dir = os.path.join(OPTIONS.input_tmp, "DATA")
   else:
-    user_dir = tempfile.mkdtemp()
-    OPTIONS.tempfiles.append(user_dir)
+    user_dir = common.MakeTempDir()
 
   fstab = OPTIONS.info_dict["fstab"]
   if fstab:
@@ -363,9 +362,7 @@
   cmd = [avbtool, "make_vbmeta_image", "--output", img.name]
   common.AppendAVBSigningArgs(cmd, "vbmeta")
 
-  public_key_dir = tempfile.mkdtemp(prefix="avbpubkey-")
-  OPTIONS.tempfiles.append(public_key_dir)
-
+  public_key_dir = common.MakeTempDir(prefix="avbpubkey-")
   for partition, path in partitions.items():
     assert partition in common.AVB_PARTITIONS, 'Unknown partition: %s' % (
         partition,)
@@ -453,8 +450,7 @@
   timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
   image_props["timestamp"] = int(timestamp)
 
-  user_dir = tempfile.mkdtemp()
-  OPTIONS.tempfiles.append(user_dir)
+  user_dir = common.MakeTempDir()
 
   fstab = OPTIONS.info_dict["fstab"]
   if fstab:
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 8f06b95..69750b2 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -237,15 +237,23 @@
 class HeapItem(object):
   def __init__(self, item):
     self.item = item
-    # Negate the score since python's heap is a min-heap and we want
-    # the maximum score.
+    # Negate the score since python's heap is a min-heap and we want the
+    # maximum score.
     self.score = -item.score
+
   def clear(self):
     self.item = None
+
   def __bool__(self):
-    return self.item is None
+    return self.item is not None
+
+  # Python 2 uses __nonzero__, while Python 3 uses __bool__.
+  __nonzero__ = __bool__
+
+  # The rest operations are generated by functools.total_ordering decorator.
   def __eq__(self, other):
     return self.score == other.score
+
   def __le__(self, other):
     return self.score <= other.score
 
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 2a92d86..11a0055 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -323,7 +323,7 @@
   signer_args = OPTIONS.verity_signer_args
 
   # make a tempdir
-  tempdir_name = tempfile.mkdtemp(suffix="_verity_images")
+  tempdir_name = common.MakeTempDir(suffix="_verity_images")
 
   # get partial image paths
   verity_image_path = os.path.join(tempdir_name, "verity.img")
@@ -332,7 +332,6 @@
 
   # build the verity tree and get the root hash and salt
   if not BuildVerityTree(out_file, verity_image_path, prop_dict):
-    shutil.rmtree(tempdir_name, ignore_errors=True)
     return False
 
   # build the metadata blocks
@@ -342,7 +341,6 @@
   if not BuildVerityMetadata(image_size, verity_metadata_path, root_hash, salt,
                              block_dev, signer_path, signer_key, signer_args,
                              verity_disable):
-    shutil.rmtree(tempdir_name, ignore_errors=True)
     return False
 
   # build the full verified image
@@ -358,21 +356,16 @@
                             verity_fec_path,
                             padding_size,
                             fec_supported):
-    shutil.rmtree(tempdir_name, ignore_errors=True)
     return False
 
-  shutil.rmtree(tempdir_name, ignore_errors=True)
   return True
 
 def ConvertBlockMapToBaseFs(block_map_file):
-  fd, base_fs_file = tempfile.mkstemp(prefix="script_gen_",
-                                      suffix=".base_fs")
-  os.close(fd)
+  base_fs_file = common.MakeTempFile(prefix="script_gen_", suffix=".base_fs")
 
   convert_command = ["blk_alloc_to_base_fs", block_map_file, base_fs_file]
   (_, exit_code) = RunCommand(convert_command)
   if exit_code != 0:
-    os.remove(base_fs_file)
     return None
   return base_fs_file
 
@@ -426,17 +419,15 @@
   # /system and the ramdisk, and can be mounted at the root of the file system.
   origin_in = in_dir
   fs_config = prop_dict.get("fs_config")
-  base_fs_file = None
   if (prop_dict.get("system_root_image") == "true"
       and prop_dict["mount_point"] == "system"):
-    in_dir = tempfile.mkdtemp()
+    in_dir = common.MakeTempDir()
     # Change the mount point to "/"
     prop_dict["mount_point"] = "/"
     if fs_config:
       # We need to merge the fs_config files of system and ramdisk.
-      fd, merged_fs_config = tempfile.mkstemp(prefix="root_fs_config",
-                                              suffix=".txt")
-      os.close(fd)
+      merged_fs_config = common.MakeTempFile(prefix="root_fs_config",
+                                             suffix=".txt")
       with open(merged_fs_config, "w") as fw:
         if "ramdisk_fs_config" in prop_dict:
           with open(prop_dict["ramdisk_fs_config"]) as fr:
@@ -577,19 +568,10 @@
     shutil.copytree(origin_in, staging_system, symlinks=True)
 
   ext4fs_output = None
-  try:
-    if fs_type.startswith("ext4"):
-      (ext4fs_output, exit_code) = RunCommand(build_command)
-    else:
-      (_, exit_code) = RunCommand(build_command)
-  finally:
-    if in_dir != origin_in:
-      # Clean up temporary directories and files.
-      shutil.rmtree(in_dir, ignore_errors=True)
-      if fs_config:
-        os.remove(fs_config)
-    if base_fs_file is not None:
-      os.remove(base_fs_file)
+  if fs_type.startswith("ext4"):
+    (ext4fs_output, exit_code) = RunCommand(build_command)
+  else:
+    (_, exit_code) = RunCommand(build_command)
   if exit_code != 0:
     print("Error: '%s' failed with exit code %d" % (build_command, exit_code))
     return False
@@ -808,15 +790,18 @@
       mount_point = "oem"
     else:
       print >> sys.stderr, "error: unknown image file name ", image_filename
-      exit(1)
+      sys.exit(1)
 
     image_properties = ImagePropFromGlobalDict(glob_dict, mount_point)
 
   if not BuildImage(in_dir, image_properties, out_file, target_out):
     print >> sys.stderr, "error: failed to build %s from %s" % (out_file,
                                                                 in_dir)
-    exit(1)
+    sys.exit(1)
 
 
 if __name__ == '__main__':
-  main(sys.argv[1:])
+  try:
+    main(sys.argv[1:])
+  finally:
+    common.Cleanup()
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 829b8db..03e808f 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -574,18 +574,16 @@
 
 
 def UnzipTemp(filename, pattern=None):
-  """Unzip the given archive into a temporary directory and return the name.
+  """Unzips the given archive into a temporary directory and returns the name.
 
-  If filename is of the form "foo.zip+bar.zip", unzip foo.zip into a
-  temp dir, then unzip bar.zip into that_dir/BOOTABLE_IMAGES.
+  If filename is of the form "foo.zip+bar.zip", unzip foo.zip into a temp dir,
+  then unzip bar.zip into that_dir/BOOTABLE_IMAGES.
 
-  Returns (tempdir, zipobj) where zipobj is a zipfile.ZipFile (of the
-  main file), open for reading.
+  Returns:
+    (tempdir, zipobj): tempdir is the name of the temprary directory; zipobj is
+        a zipfile.ZipFile (of the main file), open for reading.
   """
 
-  tmp = tempfile.mkdtemp(prefix="targetfiles-")
-  OPTIONS.tempfiles.append(tmp)
-
   def unzip_to_dir(filename, dirname):
     cmd = ["unzip", "-o", "-q", filename, "-d", dirname]
     if pattern is not None:
@@ -596,6 +594,7 @@
       raise ExternalError("failed to unzip input target-files \"%s\"" %
                           (filename,))
 
+  tmp = MakeTempDir(prefix="targetfiles-")
   m = re.match(r"^(.*[.]zip)\+(.*[.]zip)$", filename, re.IGNORECASE)
   if m:
     unzip_to_dir(m.group(1), tmp)
@@ -955,12 +954,24 @@
   return fn
 
 
+def MakeTempDir(prefix='tmp', suffix=''):
+  """Makes a temporary dir that will be cleaned up with a call to Cleanup().
+
+  Returns:
+    The absolute pathname of the new directory.
+  """
+  dir_name = tempfile.mkdtemp(suffix=suffix, prefix=prefix)
+  OPTIONS.tempfiles.append(dir_name)
+  return dir_name
+
+
 def Cleanup():
   for i in OPTIONS.tempfiles:
     if os.path.isdir(i):
-      shutil.rmtree(i)
+      shutil.rmtree(i, ignore_errors=True)
     else:
       os.remove(i)
+  del OPTIONS.tempfiles[:]
 
 
 class PasswordManager(object):
@@ -1431,11 +1442,9 @@
     self.disable_imgdiff = disable_imgdiff
 
     if version is None:
-      version = 1
-      if OPTIONS.info_dict:
-        version = max(
-            int(i) for i in
-            OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
+      version = max(
+          int(i) for i in
+          OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
     assert version >= 3
     self.version = version
 
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 136c4ba..5f9b800 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -682,11 +682,10 @@
   system_src = GetImage("system", OPTIONS.source_tmp)
   system_tgt = GetImage("system", OPTIONS.target_tmp)
 
-  blockimgdiff_version = 1
-  if OPTIONS.info_dict:
-    blockimgdiff_version = max(
-        int(i) for i in
-        OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
+  blockimgdiff_version = max(
+      int(i) for i in
+      OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
+  assert blockimgdiff_version >= 3
 
   # Check the first block of the source system partition for remount R/W only
   # if the filesystem is ext4.
@@ -784,32 +783,20 @@
 
   device_specific.IncrementalOTA_VerifyBegin()
 
-  # When blockimgdiff version is less than 3 (non-resumable block-based OTA),
-  # patching on a device that's already on the target build will damage the
-  # system. Because operations like move don't check the block state, they
-  # always apply the changes unconditionally.
-  if blockimgdiff_version <= 2:
-    if source_oem_props is None:
-      script.AssertSomeFingerprint(source_fp)
-    else:
-      script.AssertSomeThumbprint(
-          GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
-
-  else: # blockimgdiff_version > 2
-    if source_oem_props is None and target_oem_props is None:
-      script.AssertSomeFingerprint(source_fp, target_fp)
-    elif source_oem_props is not None and target_oem_props is not None:
-      script.AssertSomeThumbprint(
-          GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
-          GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
-    elif source_oem_props is None and target_oem_props is not None:
-      script.AssertFingerprintOrThumbprint(
-          source_fp,
-          GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict))
-    else:
-      script.AssertFingerprintOrThumbprint(
-          target_fp,
-          GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
+  if source_oem_props is None and target_oem_props is None:
+    script.AssertSomeFingerprint(source_fp, target_fp)
+  elif source_oem_props is not None and target_oem_props is not None:
+    script.AssertSomeThumbprint(
+        GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
+        GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
+  elif source_oem_props is None and target_oem_props is not None:
+    script.AssertFingerprintOrThumbprint(
+        source_fp,
+        GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict))
+  else:
+    script.AssertFingerprintOrThumbprint(
+        target_fp,
+        GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
 
   # Check the required cache size (i.e. stashed blocks).
   size = []
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 7bfc04b..73d77e7 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -90,14 +90,9 @@
       the existing ones in info dict.
 """
 
-import sys
-
-if sys.hexversion < 0x02070000:
-  print >> sys.stderr, "Python 2.7 or newer is required."
-  sys.exit(1)
+from __future__ import print_function
 
 import base64
-import cStringIO
 import copy
 import errno
 import gzip
@@ -106,12 +101,19 @@
 import shutil
 import stat
 import subprocess
+import sys
 import tempfile
 import zipfile
 
 import add_img_to_target_files
 import common
 
+
+if sys.hexversion < 0x02070000:
+  print("Python 2.7 or newer is required.", file=sys.stderr)
+  sys.exit(1)
+
+
 OPTIONS = common.OPTIONS
 
 OPTIONS.extra_apks = {}
@@ -126,6 +128,7 @@
 OPTIONS.avb_algorithms = {}
 OPTIONS.avb_extra_args = {}
 
+
 def GetApkCerts(certmap):
   # apply the key remapping to the contents of the file
   for apk, cert in certmap.iteritems():
@@ -149,17 +152,18 @@
     compressed_apk_extension = ".apk" + compressed_extension
   for info in input_tf_zip.infolist():
     if (info.filename.endswith(".apk") or
-        (compressed_apk_extension and info.filename.endswith(compressed_apk_extension))):
+        (compressed_apk_extension and
+         info.filename.endswith(compressed_apk_extension))):
       name = os.path.basename(info.filename)
       if compressed_apk_extension and name.endswith(compressed_apk_extension):
         name = name[:-len(compressed_extension)]
       if name not in apk_key_map:
         unknown_apks.append(name)
   if unknown_apks:
-    print "ERROR: no key specified for:\n\n ",
-    print "\n  ".join(unknown_apks)
-    print "\nUse '-e <apkname>=' to specify a key (which may be an"
-    print "empty string to not sign this apk)."
+    print("ERROR: no key specified for:\n")
+    print("  " + "\n  ".join(unknown_apks))
+    print("\nUse '-e <apkname>=' to specify a key (which may be an empty "
+          "string to not sign this apk).")
     sys.exit(1)
 
 
@@ -171,7 +175,8 @@
 
   if is_compressed:
     uncompressed = tempfile.NamedTemporaryFile()
-    with gzip.open(unsigned.name, "rb") as in_file, open(uncompressed.name, "wb") as out_file:
+    with gzip.open(unsigned.name, "rb") as in_file, \
+         open(uncompressed.name, "wb") as out_file:
       shutil.copyfileobj(in_file, out_file)
 
     # Finally, close the "unsigned" file (which is gzip compressed), and then
@@ -203,14 +208,15 @@
     min_api_level = 1
 
   common.SignFile(unsigned.name, signed.name, keyname, pw,
-      min_api_level=min_api_level,
-      codename_to_api_level_map=codename_to_api_level_map)
+                  min_api_level=min_api_level,
+                  codename_to_api_level_map=codename_to_api_level_map)
 
-  data = None;
+  data = None
   if is_compressed:
     # Recompress the file after it has been signed.
     compressed = tempfile.NamedTemporaryFile()
-    with open(signed.name, "rb") as in_file, gzip.open(compressed.name, "wb") as out_file:
+    with open(signed.name, "rb") as in_file, \
+         gzip.open(compressed.name, "wb") as out_file:
       shutil.copyfileobj(in_file, out_file)
 
     data = compressed.read()
@@ -233,10 +239,11 @@
   if compressed_extension:
     compressed_apk_extension = ".apk" + compressed_extension
 
-  maxsize = max([len(os.path.basename(i.filename))
-                 for i in input_tf_zip.infolist()
-                 if i.filename.endswith('.apk') or
-                 (compressed_apk_extension and i.filename.endswith(compressed_apk_extension))])
+  maxsize = max(
+      [len(os.path.basename(i.filename)) for i in input_tf_zip.infolist()
+       if (i.filename.endswith('.apk') or
+           (compressed_apk_extension and
+            i.filename.endswith(compressed_apk_extension)))])
   system_root_image = misc_info.get("system_root_image") == "true"
 
   for info in input_tf_zip.infolist():
@@ -248,21 +255,23 @@
 
     # Sign APKs.
     if (info.filename.endswith(".apk") or
-        (compressed_apk_extension and info.filename.endswith(compressed_apk_extension))):
-      is_compressed = compressed_extension and info.filename.endswith(compressed_apk_extension)
+        (compressed_apk_extension and
+         info.filename.endswith(compressed_apk_extension))):
+      is_compressed = (compressed_extension and
+                       info.filename.endswith(compressed_apk_extension))
       name = os.path.basename(info.filename)
       if is_compressed:
         name = name[:-len(compressed_extension)]
 
       key = apk_key_map[name]
       if key not in common.SPECIAL_CERT_STRINGS:
-        print "    signing: %-*s (%s)" % (maxsize, name, key)
+        print("    signing: %-*s (%s)" % (maxsize, name, key))
         signed_data = SignApk(data, key, key_passwords[key], platform_api_level,
-            codename_to_api_level_map, is_compressed)
+                              codename_to_api_level_map, is_compressed)
         common.ZipWriteStr(output_tf_zip, out_info, signed_data)
       else:
         # an APK we're not supposed to sign.
-        print "NOT signing: %s" % (name,)
+        print("NOT signing: %s" % (name,))
         common.ZipWriteStr(output_tf_zip, out_info, data)
 
     # System properties.
@@ -274,7 +283,7 @@
                            "ROOT/default.prop",  # legacy
                            "RECOVERY/RAMDISK/prop.default",
                            "RECOVERY/RAMDISK/default.prop"):  # legacy
-      print "rewriting %s:" % (info.filename,)
+      print("Rewriting %s:" % (info.filename,))
       if stat.S_ISLNK(info.external_attr >> 16):
         new_data = data
       else:
@@ -282,7 +291,7 @@
       common.ZipWriteStr(output_tf_zip, out_info, new_data)
 
     elif info.filename.endswith("mac_permissions.xml"):
-      print "rewriting %s with new keys." % (info.filename,)
+      print("Rewriting %s with new keys." % (info.filename,))
       new_data = ReplaceCerts(data)
       common.ZipWriteStr(output_tf_zip, out_info, new_data)
 
@@ -333,10 +342,7 @@
     ReplaceVerityPrivateKey(misc_info, OPTIONS.replace_verity_private_key[1])
 
   if OPTIONS.replace_verity_public_key:
-    if system_root_image:
-      dest = "ROOT/verity_key"
-    else:
-      dest = "BOOT/RAMDISK/verity_key"
+    dest = "ROOT/verity_key" if system_root_image else "BOOT/RAMDISK/verity_key"
     # We are replacing the one in boot image only, since the one under
     # recovery won't ever be needed.
     ReplaceVerityPublicKey(
@@ -361,7 +367,7 @@
   for old, new in OPTIONS.key_map.iteritems():
     try:
       if OPTIONS.verbose:
-        print "    Replacing %s.x509.pem with %s.x509.pem" % (old, new)
+        print("    Replacing %s.x509.pem with %s.x509.pem" % (old, new))
       f = open(old + ".x509.pem")
       old_cert16 = base64.b16encode(common.ParseCertificate(f.read())).lower()
       f.close()
@@ -369,17 +375,17 @@
       new_cert16 = base64.b16encode(common.ParseCertificate(f.read())).lower()
       f.close()
       # Only match entire certs.
-      pattern = "\\b"+old_cert16+"\\b"
+      pattern = "\\b" + old_cert16 + "\\b"
       (data, num) = re.subn(pattern, new_cert16, data, flags=re.IGNORECASE)
       if OPTIONS.verbose:
-        print "    Replaced %d occurence(s) of %s.x509.pem with " \
-            "%s.x509.pem" % (num, old, new)
+        print("    Replaced %d occurence(s) of %s.x509.pem with "
+              "%s.x509.pem" % (num, old, new))
     except IOError as e:
       if e.errno == errno.ENOENT and not OPTIONS.verbose:
         continue
 
-      print "    Error accessing %s. %s. Skip replacing %s.x509.pem " \
-          "with %s.x509.pem." % (e.filename, e.strerror, old, new)
+      print("    Error accessing %s. %s. Skip replacing %s.x509.pem with "
+            "%s.x509.pem." % (e.filename, e.strerror, old, new))
 
   return data
 
@@ -445,8 +451,8 @@
         value = " ".join(value)
       line = key + "=" + value
     if line != original_line:
-      print "  replace: ", original_line
-      print "     with: ", line
+      print("  replace: ", original_line)
+      print("     with: ", line)
     output.append(line)
   return "\n".join(output) + "\n"
 
@@ -462,7 +468,7 @@
     extra_recovery_keys = [OPTIONS.key_map.get(k, k) + ".x509.pem"
                            for k in extra_recovery_keys.split()]
     if extra_recovery_keys:
-      print "extra recovery-only key(s): " + ", ".join(extra_recovery_keys)
+      print("extra recovery-only key(s): " + ", ".join(extra_recovery_keys))
   else:
     extra_recovery_keys = []
 
@@ -476,8 +482,8 @@
     mapped_keys.append(OPTIONS.key_map.get(k, k) + ".x509.pem")
 
   if mapped_keys:
-    print "using:\n   ", "\n   ".join(mapped_keys)
-    print "for OTA package verification"
+    print("using:\n   ", "\n   ".join(mapped_keys))
+    print("for OTA package verification")
   else:
     devkey = misc_info.get("default_system_dev_certificate",
                            "build/target/product/security/testkey")
@@ -511,7 +517,11 @@
   # put into a zipfile system/etc/security/otacerts.zip.
   # We DO NOT include the extra_recovery_keys (if any) here.
 
-  temp_file = cStringIO.StringIO()
+  try:
+    from StringIO import StringIO
+  except ImportError:
+    from io import StringIO
+  temp_file = StringIO()
   certs_zip = zipfile.ZipFile(temp_file, "w")
   for k in mapped_keys:
     common.ZipWrite(certs_zip, k)
@@ -527,7 +537,7 @@
       print("\n  WARNING: Found more than one OTA keys; Using the first one"
             " as payload verification key.\n\n")
 
-    print "Using %s for payload verification." % (mapped_keys[0],)
+    print("Using %s for payload verification." % (mapped_keys[0],))
     cmd = common.Run(
         ["openssl", "x509", "-pubkey", "-noout", "-in", mapped_keys[0]],
         stdout=subprocess.PIPE)
@@ -544,40 +554,53 @@
   return new_recovery_keys
 
 
-def ReplaceVerityPublicKey(targetfile_zip, filename, key_path):
-  print "Replacing verity public key with %s" % (key_path,)
-  common.ZipWrite(targetfile_zip, key_path, arcname=filename)
+def ReplaceVerityPublicKey(output_zip, filename, key_path):
+  """Replaces the verity public key at the given path in the given zip.
+
+  Args:
+    output_zip: The output target_files zip.
+    filename: The archive name in the output zip.
+    key_path: The path to the public key.
+  """
+  print("Replacing verity public key with %s" % (key_path,))
+  common.ZipWrite(output_zip, key_path, arcname=filename)
 
 
 def ReplaceVerityPrivateKey(misc_info, key_path):
-  print "Replacing verity private key with %s" % (key_path,)
+  """Replaces the verity private key in misc_info dict.
+
+  Args:
+    misc_info: The info dict.
+    key_path: The path to the private key in PKCS#8 format.
+  """
+  print("Replacing verity private key with %s" % (key_path,))
   misc_info["verity_key"] = key_path
 
 
-def ReplaceVerityKeyId(targetfile_input_zip, targetfile_output_zip, keypath):
+def ReplaceVerityKeyId(targetfile_input_zip, targetfile_output_zip, key_path):
   in_cmdline = targetfile_input_zip.read("BOOT/cmdline")
   # copy in_cmdline to output_zip if veritykeyid is not present in in_cmdline
   if "veritykeyid" not in in_cmdline:
     common.ZipWriteStr(targetfile_output_zip, "BOOT/cmdline", in_cmdline)
     return in_cmdline
-  out_cmdline = []
+  out_buffer = []
   for param in in_cmdline.split():
     if "veritykeyid" in param:
       # extract keyid using openssl command
       p = common.Run(
-          ["openssl", "x509", "-in", keypath, "-text"],
+          ["openssl", "x509", "-in", key_path, "-text"],
           stdout=subprocess.PIPE)
       keyid, stderr = p.communicate()
       keyid = re.search(
           r'keyid:([0-9a-fA-F:]*)', keyid).group(1).replace(':', '').lower()
-      print "Replacing verity keyid with %s error=%s" % (keyid, stderr)
-      out_cmdline.append("veritykeyid=id:%s" % (keyid,))
+      print("Replacing verity keyid with %s error=%s" % (keyid, stderr))
+      out_buffer.append("veritykeyid=id:%s" % (keyid,))
     else:
-      out_cmdline.append(param)
+      out_buffer.append(param)
 
-  out_cmdline = ' '.join(out_cmdline)
+  out_cmdline = ' '.join(out_buffer)
   out_cmdline = out_cmdline.strip()
-  print "out_cmdline %s" % (out_cmdline)
+  print("out_cmdline %s" % (out_cmdline))
   common.ZipWriteStr(targetfile_output_zip, "BOOT/cmdline", out_cmdline)
 
 
@@ -600,12 +623,12 @@
   """Replaces the AVB signing keys."""
 
   AVB_FOOTER_ARGS_BY_PARTITION = {
-    'boot' : 'avb_boot_add_hash_footer_args',
-    'dtbo' : 'avb_dtbo_add_hash_footer_args',
-    'recovery' : 'avb_recovery_add_hash_footer_args',
-    'system' : 'avb_system_add_hashtree_footer_args',
-    'vendor' : 'avb_vendor_add_hashtree_footer_args',
-    'vbmeta' : 'avb_vbmeta_args',
+      'boot' : 'avb_boot_add_hash_footer_args',
+      'dtbo' : 'avb_dtbo_add_hash_footer_args',
+      'recovery' : 'avb_recovery_add_hash_footer_args',
+      'system' : 'avb_system_add_hashtree_footer_args',
+      'vendor' : 'avb_vendor_add_hashtree_footer_args',
+      'vbmeta' : 'avb_vbmeta_args',
   }
 
   def ReplaceAvbPartitionSigningKey(partition):
@@ -616,15 +639,15 @@
     algorithm = OPTIONS.avb_algorithms.get(partition)
     assert algorithm, 'Missing AVB signing algorithm for %s' % (partition,)
 
-    print 'Replacing AVB signing key for %s with "%s" (%s)' % (
-        partition, key, algorithm)
+    print('Replacing AVB signing key for %s with "%s" (%s)' % (
+        partition, key, algorithm))
     misc_info['avb_' + partition + '_algorithm'] = algorithm
     misc_info['avb_' + partition + '_key_path'] = key
 
     extra_args = OPTIONS.avb_extra_args.get(partition)
     if extra_args:
-      print 'Setting extra AVB signing args for %s to "%s"' % (
-          partition, extra_args)
+      print('Setting extra AVB signing args for %s to "%s"' % (
+          partition, extra_args))
       args_key = AVB_FOOTER_ARGS_BY_PARTITION[partition]
       misc_info[args_key] = (misc_info.get(args_key, '') + ' ' + extra_args)
 
@@ -767,29 +790,29 @@
       argv, __doc__,
       extra_opts="e:d:k:ot:",
       extra_long_opts=[
-        "extra_apks=",
-        "default_key_mappings=",
-        "key_mapping=",
-        "replace_ota_keys",
-        "tag_changes=",
-        "replace_verity_public_key=",
-        "replace_verity_private_key=",
-        "replace_verity_keyid=",
-        "avb_vbmeta_algorithm=",
-        "avb_vbmeta_key=",
-        "avb_vbmeta_extra_args=",
-        "avb_boot_algorithm=",
-        "avb_boot_key=",
-        "avb_boot_extra_args=",
-        "avb_dtbo_algorithm=",
-        "avb_dtbo_key=",
-        "avb_dtbo_extra_args=",
-        "avb_system_algorithm=",
-        "avb_system_key=",
-        "avb_system_extra_args=",
-        "avb_vendor_algorithm=",
-        "avb_vendor_key=",
-        "avb_vendor_extra_args=",
+          "extra_apks=",
+          "default_key_mappings=",
+          "key_mapping=",
+          "replace_ota_keys",
+          "tag_changes=",
+          "replace_verity_public_key=",
+          "replace_verity_private_key=",
+          "replace_verity_keyid=",
+          "avb_vbmeta_algorithm=",
+          "avb_vbmeta_key=",
+          "avb_vbmeta_extra_args=",
+          "avb_boot_algorithm=",
+          "avb_boot_key=",
+          "avb_boot_extra_args=",
+          "avb_dtbo_algorithm=",
+          "avb_dtbo_key=",
+          "avb_dtbo_extra_args=",
+          "avb_system_algorithm=",
+          "avb_system_key=",
+          "avb_system_extra_args=",
+          "avb_vendor_algorithm=",
+          "avb_vendor_key=",
+          "avb_vendor_extra_args=",
       ],
       extra_option_handler=option_handler)
 
@@ -832,16 +855,14 @@
   new_args.append(args[1])
   add_img_to_target_files.main(new_args)
 
-  print "done."
+  print("done.")
 
 
 if __name__ == '__main__':
   try:
     main(sys.argv[1:])
-  except common.ExternalError, e:
-    print
-    print "   ERROR: %s" % (e,)
-    print
+  except common.ExternalError as e:
+    print("\n   ERROR: %s\n" % (e,))
     sys.exit(1)
   finally:
     common.Cleanup()
diff --git a/tools/releasetools/test_blockimgdiff.py b/tools/releasetools/test_blockimgdiff.py
index e5a3694..7084e21 100644
--- a/tools/releasetools/test_blockimgdiff.py
+++ b/tools/releasetools/test_blockimgdiff.py
@@ -16,12 +16,43 @@
 
 from __future__ import print_function
 
-import common
 import unittest
 
-from blockimgdiff import BlockImageDiff, EmptyImage, Transfer
+import common
+from blockimgdiff import BlockImageDiff, EmptyImage, HeapItem, Transfer
 from rangelib import RangeSet
 
+
+class HealpItemTest(unittest.TestCase):
+
+  class Item(object):
+    def __init__(self, score):
+      self.score = score
+
+  def test_init(self):
+    item1 = HeapItem(self.Item(15))
+    item2 = HeapItem(self.Item(20))
+    item3 = HeapItem(self.Item(15))
+    self.assertTrue(item1)
+    self.assertTrue(item2)
+    self.assertTrue(item3)
+
+    self.assertNotEqual(item1, item2)
+    self.assertEqual(item1, item3)
+    # HeapItem uses negated scores.
+    self.assertGreater(item1, item2)
+    self.assertLessEqual(item1, item3)
+    self.assertTrue(item1 <= item3)
+    self.assertFalse(item2 >= item1)
+
+  def test_clear(self):
+    item = HeapItem(self.Item(15))
+    self.assertTrue(item)
+
+    item.clear()
+    self.assertFalse(item)
+
+
 class BlockImageDiffTest(unittest.TestCase):
 
   def test_GenerateDigraphOrder(self):
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index bb93937..ed454ca 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -14,12 +14,10 @@
 # limitations under the License.
 #
 import os
-import shutil
 import tempfile
 import time
 import unittest
 import zipfile
-
 from hashlib import sha1
 
 import common
@@ -29,6 +27,7 @@
 MiB = 1024 * KiB
 GiB = 1024 * MiB
 
+
 def get_2gb_string():
   size = int(2 * GiB + 1)
   block_size = 4 * KiB
@@ -355,17 +354,18 @@
 
 
 class InstallRecoveryScriptFormatTest(unittest.TestCase):
-  """Check the format of install-recovery.sh
+  """Checks the format of install-recovery.sh.
 
-  Its format should match between common.py and validate_target_files.py."""
+  Its format should match between common.py and validate_target_files.py.
+  """
 
   def setUp(self):
-    self._tempdir = tempfile.mkdtemp()
+    self._tempdir = common.MakeTempDir()
     # Create a dummy dict that contains the fstab info for boot&recovery.
     self._info = {"fstab" : {}}
-    dummy_fstab = \
-        ["/dev/soc.0/by-name/boot /boot emmc defaults defaults",
-         "/dev/soc.0/by-name/recovery /recovery emmc defaults defaults"]
+    dummy_fstab = [
+        "/dev/soc.0/by-name/boot /boot emmc defaults defaults",
+        "/dev/soc.0/by-name/recovery /recovery emmc defaults defaults"]
     self._info["fstab"] = common.LoadRecoveryFSTab("\n".join, 2, dummy_fstab)
     # Construct the gzipped recovery.img and boot.img
     self.recovery_data = bytearray([
@@ -414,4 +414,4 @@
                                                         self._info)
 
   def tearDown(self):
-    shutil.rmtree(self._tempdir)
+    common.Cleanup()