Merge "Correct some GSI settings to board makefile"
diff --git a/core/Makefile b/core/Makefile
index 85ae96e..a3fbe33 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -2312,9 +2312,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)
@@ -2547,7 +2545,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/allowed_ndk_types.mk b/core/allowed_ndk_types.mk
new file mode 100644
index 0000000..fb6d43c
--- /dev/null
+++ b/core/allowed_ndk_types.mk
@@ -0,0 +1,62 @@
+# Determines the types of NDK modules the current module is allowed to link to.
+# Input variables:
+#   LOCAL_MODULE
+#   LOCAL_MODULE_CLASS
+#   LOCAL_NDK_STL_VARIANT
+#   LOCAL_SDK_VERSION
+# Output variables:
+#   my_ndk_stl_family: Family of the NDK STL.
+#   my_allowed_ndk_types: Types of NDK modules that may be linked.
+#   my_warn_ndk_types: Types of NDK modules that shouldn't be linked, but are.
+
+my_allowed_ndk_types :=
+my_warn_ndk_types :=
+my_ndk_stl_family :=
+
+ifdef LOCAL_SDK_VERSION
+    ifeq ($(LOCAL_NDK_STL_VARIANT),)
+        my_ndk_stl_family := system
+    else ifeq ($(LOCAL_NDK_STL_VARIANT),system)
+        my_ndk_stl_family := system
+    else ifeq ($(LOCAL_NDK_STL_VARIANT),c++_shared)
+        my_ndk_stl_family := libc++
+    else ifeq ($(LOCAL_NDK_STL_VARIANT),c++_static)
+        my_ndk_stl_family := libc++
+    else ifeq ($(LOCAL_NDK_STL_VARIANT),gnustl_static)
+        my_ndk_stl_family := gnustl
+    else ifeq ($(LOCAL_NDK_STL_VARIANT),stlport_shared)
+        my_ndk_stl_family := stlport
+    else ifeq ($(LOCAL_NDK_STL_VARIANT),stlport_static)
+        my_ndk_stl_family := stlport
+    else ifeq ($(LOCAL_NDK_STL_VARIANT),none)
+        my_ndk_stl_family := none
+    else
+        $(call pretty-error,invalid LOCAL_NDK_STL_VARIANT: $(LOCAL_NDK_STL_VARIANT))
+    endif
+
+    # The system STL is only the C++ ABI layer, so it's compatible with any STL.
+    my_allowed_ndk_types += native:ndk:system
+
+    # Libaries that don't use the STL can be linked to anything.
+    my_allowed_ndk_types += native:ndk:none
+
+    # And it's okay to link your own STL type. Strictly speaking there are more
+    # restrictions depending on static vs shared STL, but that will be a follow
+    # up patch.
+    my_allowed_ndk_types += native:ndk:$(my_ndk_stl_family)
+
+    ifeq ($(LOCAL_MODULE_CLASS),APPS)
+        # For an app package, it's actually okay to depend on any set of STLs.
+        # If any of the individual libraries depend on each other they've
+        # already been checked for consistency, and if they don't they'll be
+        # kept isolated by RTLD_LOCAL anyway.
+        my_allowed_ndk_types += \
+            native:ndk:gnustl native:ndk:libc++ native:ndk:stlport
+    endif
+else
+    my_allowed_ndk_types := native:ndk:none native:ndk:system
+    ifeq ($(LOCAL_MODULE_CLASS),APPS)
+        # CTS is bad and it should feel bad: http://b/13249737
+        my_warn_ndk_types += native:ndk:libc++
+    endif
+endif
diff --git a/core/autogen_test_config.mk b/core/autogen_test_config.mk
index 9f3a2a6..c359bac 100644
--- a/core/autogen_test_config.mk
+++ b/core/autogen_test_config.mk
@@ -40,10 +40,14 @@
   my_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
 endif
 ifneq (,$(wildcard $(my_android_manifest)))
-$(autogen_test_config_file) : $(my_android_manifest) $(EMPTY_TEST_CONFIG) $(INSTRUMENTATION_TEST_CONFIG_TEMPLATE)
+$(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) $(AUTOGEN_TEST_CONFIG_SCRIPT) $@ $^
+	$(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))
diff --git a/core/binary.mk b/core/binary.mk
index 6920373..9e0697b 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1404,10 +1404,12 @@
 ## other NDK-built libraries
 ####################################################
 
+include $(BUILD_SYSTEM)/allowed_ndk_types.mk
+
 ifdef LOCAL_SDK_VERSION
-my_link_type := native:ndk
-my_warn_types :=
-my_allowed_types := native:ndk
+my_link_type := native:ndk:$(my_ndk_stl_family)
+my_warn_types := $(my_warn_ndk_types)
+my_allowed_types := $(my_allowed_ndk_types)
 else ifdef LOCAL_USE_VNDK
     _name := $(patsubst %.vendor,%,$(LOCAL_MODULE))
     ifneq ($(filter $(_name),$(VNDK_CORE_LIBRARIES) $(VNDK_SAMEPROCESS_LIBRARIES) $(LLNDK_LIBRARIES)),)
@@ -1427,8 +1429,8 @@
     endif
 else
 my_link_type := native:platform
-my_warn_types :=
-my_allowed_types := native:ndk native:platform
+my_warn_types := $(my_warn_ndk_types)
+my_allowed_types := $(my_allowed_ndk_types) native:platform
 endif
 
 my_link_deps := $(addprefix STATIC_LIBRARIES:,$(my_whole_static_libraries) $(my_static_libraries))
@@ -1721,13 +1723,13 @@
     endif
     # If clang-tidy is not enabled globally, add the -quiet flag.
     ifeq (,$(filter 1 true,$(WITH_TIDY)))
-      my_tidy_flags += -quiet
+      my_tidy_flags += -quiet -extra-arg-before=-fno-caret-diagnostics
     endif
 
     # We might be using the static analyzer through clang-tidy.
     # https://bugs.llvm.org/show_bug.cgi?id=32914
     ifneq ($(my_tidy_checks),)
-      my_tidy_flags += "-extra-arg-before=-D__clang_analyzer__"
+      my_tidy_flags += -extra-arg-before=-D__clang_analyzer__
     endif
   endif
 endif
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 09f9be5..b4a03ea 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -78,6 +78,7 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS:=
 LOCAL_EXPORT_HEADER_LIBRARY_HEADERS:=
 LOCAL_EXPORT_PACKAGE_RESOURCES:=
+LOCAL_EXPORT_PROGUARD_FLAG_FILES:=
 LOCAL_EXPORT_SHARED_LIBRARY_HEADERS:=
 LOCAL_EXPORT_STATIC_LIBRARY_HEADERS:=
 LOCAL_EXTRACT_APK:=
@@ -193,7 +194,7 @@
 LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES:=
 LOCAL_PREBUILT_STRIP_COMMENTS:=
 LOCAL_PRIVILEGED_MODULE:=
-# '',full,custom,nosystem,disabled,obfuscation,optimization
+# '',full,custom,disabled,obfuscation,optimization
 LOCAL_PROGUARD_ENABLED:=
 LOCAL_PROGUARD_FLAG_FILES:=
 LOCAL_PROGUARD_FLAGS:=
@@ -231,6 +232,7 @@
 LOCAL_SOONG_DEX_JAR :=
 LOCAL_SOONG_HEADER_JAR :=
 LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=
+LOCAL_SOONG_PROGUARD_DICT :=
 LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=
 LOCAL_SOONG_RRO_DIRS :=
 # '',true
diff --git a/core/config.mk b/core/config.mk
index 5fc0101..b03f21f 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -60,14 +60,14 @@
 
 # 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)
+$(KATI_obsolete_var ANDROID_BUILD_TOP,Use '.' instead. See $(CHANGES_URL)#ANDROID_BUILD_TOP)
 $(KATI_obsolete_var \
   ANDROID_TOOLCHAIN \
   ANDROID_TOOLCHAIN_2ND_ARCH \
@@ -581,8 +581,6 @@
   ZIPALIGN := $(prebuilt_build_tools_bin)/zipalign
 endif # TARGET_BUILD_APPS || TARGET_BUILD_PDK
 
-R8_COMPAT_PROGUARD := $(HOST_OUT_EXECUTABLES)/r8-compat-proguard
-
 ifeq (,$(TARGET_BUILD_APPS))
   # Use RenderScript prebuilts for unbundled builds but not PDK builds
   LLVM_RS_CC := $(HOST_OUT_EXECUTABLES)/llvm-rs-cc
@@ -707,7 +705,11 @@
 COLUMN:= column
 
 ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
+ifeq ($(RUN_ERROR_PRONE),true)
 USE_OPENJDK9 :=
+else
+USE_OPENJDK9 := true
+endif
 TARGET_OPENJDK9 :=
 else ifeq ($(EXPERIMENTAL_USE_OPENJDK9),false)
 USE_OPENJDK9 :=
@@ -817,7 +819,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/envsetup.mk b/core/envsetup.mk
index 89a39a8..255c02b 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -287,7 +287,7 @@
 # Check BOARD_VNDK_VERSION
 define check_vndk_version
   $(eval vndk_path := prebuilts/vndk/v$(1)) \
-  $(if $(wildcard $(vndk_path)/Android.bp),,$(error VNDK version $(1) not found))
+  $(if $(wildcard $(vndk_path)/*/Android.bp),,$(error VNDK version $(1) not found))
 endef
 
 ifdef BOARD_VNDK_VERSION
diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
index 265d482..80e0c24 100644
--- a/core/install_jni_libs_internal.mk
+++ b/core/install_jni_libs_internal.mk
@@ -108,15 +108,16 @@
 endif  # outer my_prebuilt_jni_libs
 
 # Verify that all included libraries are built against the NDK
+include $(BUILD_SYSTEM)/allowed_ndk_types.mk
 ifneq ($(strip $(LOCAL_JNI_SHARED_LIBRARIES)),)
 ifneq ($(LOCAL_SDK_VERSION),)
 my_link_type := app:sdk
-my_warn_types := native:platform
-my_allowed_types := native:ndk
+my_warn_types := native:platform $(my_warn_ndk_types)
+my_allowed_types := $(my_allowed_ndk_types)
 else
 my_link_type := app:platform
-my_warn_types :=
-my_allowed_types := native:ndk native:platform native:vendor native:vndk native:vndk_private
+my_warn_types := $(my_warn_ndk_types)
+my_allowed_types := $(my_allowed_ndk_types) native:platform native:vendor native:vndk native:vndk_private
 endif
 
 my_link_deps := $(addprefix SHARED_LIBRARIES:,$(LOCAL_JNI_SHARED_LIBRARIES))
diff --git a/core/jacoco.mk b/core/jacoco.mk
index f51790d..6406df4 100644
--- a/core/jacoco.mk
+++ b/core/jacoco.mk
@@ -84,8 +84,8 @@
 	mkdir -p $(PRIVATE_INSTRUMENTED_PATH)
 	java -jar $(JACOCO_CLI_JAR) \
 	  instrument \
-	  -quiet \
-	  -dest '$(PRIVATE_INSTRUMENTED_PATH)' \
+	  --quiet \
+	  --dest '$(PRIVATE_INSTRUMENTED_PATH)' \
 	  $(PRIVATE_UNZIPPED_PATH)
 	touch $(PRIVATE_INSTRUMENTED_TIMESTAMP_PATH)
 
diff --git a/core/java.mk b/core/java.mk
index 3e0123b..ee071c9 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -558,6 +558,12 @@
 
 $(eval $(call copy-one-file,$(full_classes_jarjar_jar),$(full_classes_jar)))
 
+LOCAL_FULL_CLASSES_PRE_JACOCO_JAR := $(full_classes_jar)
+
+#######################################
+include $(BUILD_SYSTEM)/jacoco.mk
+#######################################
+
 # Temporarily enable --multi-dex until proguard supports v53 class files
 # ( http://b/67673860 ) or we move away from proguard altogether.
 ifdef TARGET_OPENJDK9
@@ -569,7 +575,7 @@
 ifndef LOCAL_IS_STATIC_JAVA_LIBRARY
 my_desugaring := true
 $(full_classes_desugar_jar): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
-$(full_classes_desugar_jar): $(full_classes_jar) $(full_java_header_libs) $(DESUGAR)
+$(full_classes_desugar_jar): $(LOCAL_FULL_CLASSES_JACOCO_JAR) $(full_java_header_libs) $(DESUGAR)
 	$(desugar-classes-jar)
 endif
 else
@@ -577,23 +583,17 @@
 endif
 
 ifndef my_desugaring
-full_classes_desugar_jar := $(full_classes_jar)
+full_classes_desugar_jar := $(LOCAL_FULL_CLASSES_JACOCO_JAR)
 endif
 
-LOCAL_FULL_CLASSES_PRE_JACOCO_JAR := $(full_classes_desugar_jar)
-
-#######################################
-include $(BUILD_SYSTEM)/jacoco.mk
-#######################################
-
-full_classes_pre_proguard_jar := $(LOCAL_FULL_CLASSES_JACOCO_JAR)
+full_classes_pre_proguard_jar := $(full_classes_desugar_jar)
 
 # Keep a copy of the jar just before proguard processing.
 $(eval $(call copy-one-file,$(full_classes_pre_proguard_jar),$(intermediates.COMMON)/classes-pre-proguard.jar))
 
 # 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 obfuscation optimization,$(LOCAL_PROGUARD_ENABLED)),)
     $(warning while processing: $(LOCAL_MODULE))
     $(error invalid value for LOCAL_PROGUARD_ENABLED: $(LOCAL_PROGUARD_ENABLED))
 endif
@@ -631,19 +631,16 @@
 
 common_proguard_flags := -forceprocessing
 
-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.
+common_proguard_flag_files := $(BUILD_SYSTEM)/proguard.flags
 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
+    common_proguard_flag_files += $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES),\
+        $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/export_proguard_flags)
+  endif
+endif
 ifneq ($(common_proguard_flag_files),)
 common_proguard_flags += $(addprefix -include , $(common_proguard_flag_files))
 # This is included from $(BUILD_SYSTEM)/proguard.flags
@@ -685,7 +682,6 @@
 
 endif # no obfuscation
 endif # LOCAL_INSTRUMENTATION_FOR
-endif  # LOCAL_PROGUARD_ENABLED is not nosystem
 
 proguard_flag_files := $(addprefix $(LOCAL_PATH)/, $(LOCAL_PROGUARD_FLAG_FILES))
 ifeq ($(USE_R8),true)
diff --git a/core/java_library.mk b/core/java_library.mk
index e4916b8..8cf0074 100644
--- a/core/java_library.mk
+++ b/core/java_library.mk
@@ -42,6 +42,8 @@
 ifeq (true,$(LOCAL_EMMA_INSTRUMENT))
 ifeq (true,$(EMMA_INSTRUMENT_STATIC))
 LOCAL_STATIC_JAVA_LIBRARIES += jacocoagent
+# Exclude jacoco classes from proguard
+LOCAL_PROGUARD_FLAGS += -include $(BUILD_SYSTEM)/proguard.jacoco.flags
 endif # LOCAL_EMMA_INSTRUMENT
 endif # EMMA_INSTRUMENT_STATIC
 else
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 2a63817..e153a8a 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -275,6 +275,8 @@
 ifneq ($(LOCAL_SRC_FILES)$(LOCAL_STATIC_JAVA_LIBRARIES)$(LOCAL_SOURCE_FILES_ALL_GENERATED),)
 # Only add jacocoagent if the package contains some java code
 LOCAL_STATIC_JAVA_LIBRARIES += jacocoagent
+# Exclude jacoco classes from proguard
+LOCAL_PROGUARD_FLAGS += -include $(BUILD_SYSTEM)/proguard.jacoco.flags
 endif # Contains java code
 else
 ifdef LOCAL_SDK_VERSION
@@ -361,6 +363,8 @@
 $(full_classes_compiled_jar): $(data_binding_stamp)
 endif  # LOCAL_DATA_BINDING
 
+resource_export_package :=
+
 ifeq ($(need_compile_res),true)
 
 ###############################
@@ -427,7 +431,6 @@
 
 $(proguard_options_file): $(R_file_stamp)
 
-resource_export_package :=
 ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
 # Put this module's resources into a PRODUCT-agnositc package that
 # other packages can use to build their own PRODUCT-agnostic R.java (etc.)
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 69df2d1..dbfa64a 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -173,8 +173,10 @@
 endif
 export_cflags :=
 
+include $(BUILD_SYSTEM)/allowed_ndk_types.mk
+
 ifdef LOCAL_SDK_VERSION
-my_link_type := native:ndk
+my_link_type := native:ndk:$(my_ndk_stl_family)
 else ifdef LOCAL_USE_VNDK
     _name := $(patsubst %.vendor,%,$(LOCAL_MODULE))
     ifneq ($(filter $(_name),$(VNDK_CORE_LIBRARIES) $(VNDK_SAMEPROCESS_LIBRARIES) $(LLNDK_LIBRARIES)),)
@@ -566,12 +568,16 @@
 ifneq ($(my_src_aar),)
 # This is .aar file, archive of classes.jar and Android resources.
 my_src_jar := $(intermediates.COMMON)/aar/classes.jar
+my_src_proguard_options := $(intermediates.COMMON)/aar/proguard.txt
 
+$(my_src_jar) : .KATI_IMPLICIT_OUTPUTS := $(my_src_proguard_options)
 $(my_src_jar) : $(my_src_aar)
 	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@) $(dir $@)/res
 	$(hide) unzip -qo -d $(dir $@) $<
 	# Make sure the extracted classes.jar has a new timestamp.
 	$(hide) touch $@
+	# Make sure the proguard file exists and has a new timestamp.
+	$(hide) touch $(dir $@)/proguard.txt
 
 endif
 
@@ -595,6 +601,10 @@
 
 ifdef LOCAL_USE_AAPT2
 ifneq ($(my_src_aar),)
+
+$(intermediates.COMMON)/export_proguard_flags : $(my_src_proguard_options)
+	$(transform-prebuilt-to-target)
+
 LOCAL_SDK_RES_VERSION:=$(strip $(LOCAL_SDK_RES_VERSION))
 ifeq ($(LOCAL_SDK_RES_VERSION),)
   LOCAL_SDK_RES_VERSION:=$(LOCAL_SDK_VERSION)
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/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index 633ef0c..65aabff 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -13,13 +13,6 @@
 include $(BUILD_SYSTEM)/base_rules.mk
 #######################################
 
-ifdef LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
-  $(eval $(call copy-one-file,$(LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR),\
-    $(intermediates.COMMON)/jacoco-report-classes.jar))
-  $(call add-dependency,$(common_javalib.jar),\
-    $(intermediates.COMMON)/jacoco-report-classes.jar)
-endif
-
 full_classes_jar := $(intermediates.COMMON)/classes.jar
 full_classes_pre_proguard_jar := $(intermediates.COMMON)/classes-pre-proguard.jar
 full_classes_header_jar := $(intermediates.COMMON)/classes-header.jar
@@ -27,6 +20,20 @@
 $(eval $(call copy-one-file,$(LOCAL_SOONG_CLASSES_JAR),$(full_classes_jar)))
 $(eval $(call copy-one-file,$(LOCAL_SOONG_CLASSES_JAR),$(full_classes_pre_proguard_jar)))
 
+ifdef LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
+  $(eval $(call copy-one-file,$(LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR),\
+    $(intermediates.COMMON)/jacoco-report-classes.jar))
+  $(call add-dependency,$(LOCAL_BUILT_MODULE),\
+    $(intermediates.COMMON)/jacoco-report-classes.jar)
+endif
+
+ifdef LOCAL_SOONG_PROGUARD_DICT
+  $(eval $(call copy-one-file,$(LOCAL_SOONG_PROGUARD_DICT),\
+    $(intermediates.COMMON)/proguard_dictionary))
+  $(call add-dependency,$(LOCAL_BUILT_MODULE),\
+    $(intermediates.COMMON)/proguard_dictionary)
+endif
+
 ifneq ($(TURBINE_DISABLED),false)
 ifdef LOCAL_SOONG_HEADER_JAR
 $(eval $(call copy-one-file,$(LOCAL_SOONG_HEADER_JAR),$(full_classes_header_jar)))
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 6645af5..8348349 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -118,6 +118,13 @@
 endif
 endif
 
+ifdef LOCAL_USE_AAPT2
+$(intermediates.COMMON)/export_proguard_flags: $(addprefix $(LOCAL_PATH)/,$(LOCAL_EXPORT_PROGUARD_FLAG_FILES))
+	@echo "Export proguard flags: $@"
+	rm -f $@
+	cat $+ >$@
+endif
+
 # add --non-constant-id to prevent inlining constants.
 # AAR needs text symbol file R.txt.
 ifdef LOCAL_USE_AAPT2
diff --git a/core/tasks/check_emu_boot.mk b/core/tasks/check_emu_boot.mk
index f8daee0..4870677 100644
--- a/core/tasks/check_emu_boot.mk
+++ b/core/tasks/check_emu_boot.mk
@@ -5,7 +5,8 @@
 $(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) $(PRODUCT_OUT)/userdata.img \
+$(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)
@@ -20,4 +21,3 @@
 	then echo boot_failed > $(PRIVATE_FAIL_FILE); fi)
 .PHONY: check_emu_boot
 check_emu_boot: $(check_emu_boot0)
-
diff --git a/core/tasks/vndk.mk b/core/tasks/vndk.mk
index 1bbd3b0..3604aed 100644
--- a/core/tasks/vndk.mk
+++ b/core/tasks/vndk.mk
@@ -17,6 +17,12 @@
 # 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))
+
+# BOARD_VNDK_RUNTIME_DISABLE must not be set to 'true'.
+ifneq ($(BOARD_VNDK_RUNTIME_DISABLE),true)
+
 # 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.
@@ -33,15 +39,17 @@
 # Returns list of file paths of the intermediate objs
 #
 # Args:
-#   $(1): list of obj names (e.g., libfoo.vendor, ld.config.txt, ...)
+#   $(1): list of module and filename pairs (e.g., ld.config.txt:ld.config.27.txt ...)
 #   $(2): target class (e.g., SHARED_LIBRARIES, STATIC_LIBRARIES, ETC)
 #   $(3): if not empty, evaluates for TARGET_2ND_ARCH
 define paths-of-intermediates
 $(strip \
-  $(foreach obj,$(1), \
-    $(eval file_name := $(if $(filter SHARED_LIBRARIES,$(2)),$(patsubst %.so,%,$(obj)).so,$(obj))) \
-    $(eval dir := $(call intermediates-dir-for,$(2),$(obj),,,$(3))) \
-    $(call append-path,$(dir),$(file_name)) \
+  $(foreach pair,$(1), \
+    $(eval split_pair := $(subst :,$(space),$(pair))) \
+    $(eval module := $(word 1,$(split_pair))) \
+    $(eval filename := $(word 2,$(split_pair))) \
+    $(eval dir := $(call intermediates-dir-for,$(2),$(module),,,$(3))) \
+    $(call append-path,$(dir),$(filename)) \
   ) \
 )
 endef
@@ -70,13 +78,10 @@
 else
   vndk_core_libs := $(addsuffix .vendor,$(filter-out libclang_rt.ubsan%,$(VNDK_CORE_LIBRARIES)))
 
-  # for TARGET_ARCH
   vndk_core_libs += $(call clang-ubsan-vndk-core)
-
-  # TODO(b/69834489): Package additional arch variants
-  # ifdef TARGET_2ND_ARCH
-  #   vndk_core_libs += $(call clang-ubsan-vndk-core,true)
-  # endif
+  ifdef TARGET_2ND_ARCH
+    vndk_core_libs += $(call clang-ubsan-vndk-core,true)
+  endif
 endif
 
 vndk_sp_libs := $(addsuffix .vendor,$(VNDK_SAMEPROCESS_LIBRARIES))
@@ -135,39 +140,41 @@
 
 #######################################
 # vndk_snapshot_zip
-vndk_snapshot_arch := $(vndk_snapshot_out)/arch-$(TARGET_ARCH)-$(TARGET_ARCH_VARIANT)
+vndk_snapshot_variant := $(vndk_snapshot_out)/$(TARGET_ARCH)
+vndk_lib_dir := $(vndk_snapshot_variant)/arch-$(TARGET_ARCH)-$(TARGET_ARCH_VARIANT)
+vndk_lib_dir_2nd := $(vndk_snapshot_variant)/arch-$(TARGET_2ND_ARCH)-$(TARGET_2ND_ARCH_VARIANT)
 vndk_snapshot_zip := $(PRODUCT_OUT)/android-vndk-$(TARGET_ARCH).zip
 
 $(vndk_snapshot_zip): PRIVATE_VNDK_SNAPSHOT_OUT := $(vndk_snapshot_out)
 
-$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT := $(vndk_snapshot_arch)/shared/vndk-core
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT := $(vndk_lib_dir)/shared/vndk-core
 $(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES := \
-  $(call paths-of-intermediates,$(vndk_core_libs),SHARED_LIBRARIES)
+  $(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(lib).so),SHARED_LIBRARIES)
 
-$(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT := $(vndk_snapshot_arch)/shared/vndk-sp
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT := $(vndk_lib_dir)/shared/vndk-sp
 $(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES := \
-  $(call paths-of-intermediates,$(vndk_sp_libs),SHARED_LIBRARIES)
+  $(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(lib).so),SHARED_LIBRARIES)
 
-$(vndk_snapshot_zip): PRIVATE_CONFIGS_OUT := $(vndk_snapshot_arch)/configs
+$(vndk_snapshot_zip): PRIVATE_CONFIGS_OUT := $(vndk_snapshot_variant)/configs
 $(vndk_snapshot_zip): PRIVATE_CONFIGS_INTERMEDIATES := \
-  $(call paths-of-intermediates,$(vndk_prebuilt_txts),ETC) \
+  $(call paths-of-intermediates,$(foreach txt,$(vndk_prebuilt_txts), \
+    $(txt):$(patsubst %.txt,%.$(PLATFORM_VNDK_VERSION).txt,$(txt))),ETC) \
   $(vndk_snapshot_configs)
 
-$(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_OUT := $(vndk_snapshot_arch)/NOTICE_FILES
+$(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_OUT := $(vndk_snapshot_variant)/NOTICE_FILES
 $(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_INTERMEDIATES := \
   $(call paths-of-notice-files,$(vndk_core_libs),vndk) \
   $(call paths-of-notice-files,$(vndk_sp_libs),vndk-sp)
 
-# TODO(b/69834489): Package additional arch variants
-# ifdef TARGET_2ND_ARCH
-# vndk_snapshot_arch_2ND := $(vndk_snapshot_out)/arch-$(TARGET_2ND_ARCH)-$(TARGET_2ND_ARCH_VARIANT)
-# $(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT_2ND := $(vndk_snapshot_arch_2ND)/shared/vndk-core
-# $(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES_2ND := \
-#   $(call paths-of-intermediates,$(vndk_core_libs),SHARED_LIBRARIES,true)
-# $(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT_2ND := $(vndk_snapshot_arch_2ND)/shared/vndk-sp
-# $(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES_2ND := \
-#   $(call paths-of-intermediates,$(vndk_sp_libs),SHARED_LIBRARIES,true)
-# endif
+ifdef TARGET_2ND_ARCH
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT_2ND := $(vndk_lib_dir_2nd)/shared/vndk-core
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES_2ND := \
+  $(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(lib).so),SHARED_LIBRARIES,true)
+
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT_2ND := $(vndk_lib_dir_2nd)/shared/vndk-sp
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES_2ND := \
+  $(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(lib).so),SHARED_LIBRARIES,true)
+endif
 
 # Args
 #   $(1): destination directory
@@ -200,13 +207,12 @@
 		$(PRIVATE_CONFIGS_OUT),$(PRIVATE_CONFIGS_INTERMEDIATES))
 	$(call private-copy-vndk-intermediates, \
 		$(PRIVATE_NOTICE_FILES_OUT),$(PRIVATE_NOTICE_FILES_INTERMEDIATES))
-# TODO(b/69834489): Package additional arch variants
-# ifdef TARGET_2ND_ARCH
-# 	$(call private-copy-vndk-intermediates, \
-# 		$(PRIVATE_VNDK_CORE_OUT_2ND),$(PRIVATE_VNDK_CORE_INTERMEDIATES_2ND))
-# 	$(call private-copy-vndk-intermediates, \
-# 		$(PRIVATE_VNDK_SP_OUT_2ND),$(PRIVATE_VNDK_SP_INTERMEDIATES_2ND))
-# endif
+ifdef TARGET_2ND_ARCH
+	$(call private-copy-vndk-intermediates, \
+		$(PRIVATE_VNDK_CORE_OUT_2ND),$(PRIVATE_VNDK_CORE_INTERMEDIATES_2ND))
+	$(call private-copy-vndk-intermediates, \
+		$(PRIVATE_VNDK_SP_OUT_2ND),$(PRIVATE_VNDK_SP_INTERMEDIATES_2ND))
+endif
 	$(hide) $(SOONG_ZIP) -o $@ -C $(PRIVATE_VNDK_SNAPSHOT_OUT) -D $(PRIVATE_VNDK_SNAPSHOT_OUT)
 
 .PHONY: vndk
@@ -226,18 +232,28 @@
 vndk_snapshot_top :=
 vndk_snapshot_out :=
 vndk_snapshot_configs_out :=
-vndk_snapshot_arch :=
+vndk_snapshot_variant :=
+vndk_lib_dir :=
+vndk_lib_dir_2nd :=
 vndk_snapshot_dependencies :=
-# TODO(b/69834489): Package additional arch variants
-# ifdef TARGET_2ND_ARCH
-# vndk_snapshot_arch_2ND :=
-# endif
+
+else # BOARD_VNDK_RUNTIME_DISABLE is set to 'true'
+error_msg := "CANNOT generate VNDK snapshot. BOARD_VNDK_RUNTIME_DISABLE must not be set to 'true'."
+endif # BOARD_VNDK_RUNTIME_DISABLE
+
+else # PLATFORM_VNDK_VERSION is NOT set
+error_msg := "CANNOT generate VNDK snapshot. PLATFORM_VNDK_VERSION must be set."
+endif # PLATFORM_VNDK_VERSION
 
 else # BOARD_VNDK_VERSION is NOT set to 'current'
+error_msg := "CANNOT generate VNDK snapshot. BOARD_VNDK_VERSION must be set to 'current'."
+endif # BOARD_VNDK_VERSION
+
+ifneq (,$(error_msg))
 
 .PHONY: vndk
 vndk:
-	$(call echo-error,$(current_makefile),CANNOT generate VNDK snapshot. BOARD_VNDK_VERSION must be set to 'current'.)
+	$(call echo-error,$(current_makefile),$(error_msg))
 	exit 1
 
-endif # BOARD_VNDK_VERSION
+endif
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/embedded.mk b/target/product/embedded.mk
index 55ee6dc..20f0ebf 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -23,6 +23,7 @@
     android.hardware.configstore@1.0-service \
     android.hidl.allocator@1.0-service \
     android.hidl.memory@1.0-impl \
+    android.hidl.memory@1.0-impl.vendor \
     atrace \
     bootanimation \
     bootstat \
diff --git a/target/product/treble_common.mk b/target/product/treble_common.mk
index 16c2402..5880bf8 100644
--- a/target/product/treble_common.mk
+++ b/target/product/treble_common.mk
@@ -75,3 +75,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/Android.mk b/target/product/vndk/Android.mk
index ea8c95e..a134d02 100644
--- a/target/product/vndk/Android.mk
+++ b/target/product/vndk/Android.mk
@@ -94,9 +94,9 @@
     vndk_current
 else
 LOCAL_REQUIRED_MODULES := \
-    vndk_v$(BOARD_VNDK_VERSION)
+    vndk_v$(BOARD_VNDK_VERSION)_$(TARGET_ARCH)
 endif
 LOCAL_REQUIRED_MODULES += \
-    $(foreach vndk_ver,$(PRODUCT_EXTRA_VNDK_VERSIONS),vndk_v$(vndk_ver))
+    $(foreach vndk_ver,$(PRODUCT_EXTRA_VNDK_VERSIONS),vndk_v$(vndk_ver)_$(TARGET_ARCH))
 include $(BUILD_PHONY_PACKAGE)
 endif # BOARD_VNDK_VERSION is set
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/adbs b/tools/adbs
index a8f06c0..8d73630 100755
--- a/tools/adbs
+++ b/tools/adbs
@@ -20,7 +20,7 @@
 import string
 import sys
 
-sys.path.insert(0, os.path.dirname(__file__) + "/../../development/scripts")
+sys.path.insert(0, os.path.dirname(__file__) + "/../../../development/scripts")
 import stack_core
 import symbol
 
diff --git a/tools/auto_gen_test_config.py b/tools/auto_gen_test_config.py
index fa018f4..da4443c 100755
--- a/tools/auto_gen_test_config.py
+++ b/tools/auto_gen_test_config.py
@@ -24,7 +24,7 @@
 
 ATTRIBUTE_LABEL = 'android:label'
 ATTRIBUTE_RUNNER = 'android:name'
-ATTRIBUTE_TARGET_PACKAGE = 'android:targetPackage'
+ATTRIBUTE_PACKAGE = 'package'
 
 PLACEHOLDER_LABEL = '{LABEL}'
 PLACEHOLDER_MODULE = '{MODULE}'
@@ -54,20 +54,22 @@
 
   manifest = parse(android_manifest)
   instrumentation_elements = manifest.getElementsByTagName('instrumentation')
-  if len(instrumentation_elements) != 1:
-    # Failed to locate instrumentation element in AndroidManifest file.
-    # Empty test config file will be created.
+  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 = instrumentation.attributes[ATTRIBUTE_TARGET_PACKAGE].value
+  package = manifest.attributes[ATTRIBUTE_PACKAGE].value
   test_type = ('AndroidJUnitTest' if runner.endswith('.AndroidJUnitRunner')
                else 'InstrumentationTest')
 
diff --git a/tools/auto_gen_test_config_test.py b/tools/auto_gen_test_config_test.py
index a438b73..e70eff8 100644
--- a/tools/auto_gen_test_config_test.py
+++ b/tools/auto_gen_test_config_test.py
@@ -31,7 +31,8 @@
 """
 
 MANIFEST_JUNIT_TEST = """<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+<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" />
@@ -39,7 +40,8 @@
 """
 
 MANIFEST_INSTRUMENTATION_TEST = """<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+<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"
@@ -69,7 +71,7 @@
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.android.my.tests" />
+        <option name="package" value="com.android.my.tests.x" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
 </configuration>
@@ -97,16 +99,17 @@
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.InstrumentationTest" >
-        <option name="package" value="com.android.my.tests" />
+        <option name="package" value="com.android.my.tests.x" />
         <option name="runner" value="android.test.InstrumentationTestRunner" />
     </test>
 </configuration>
 """
 
-MAKE_ROOT = os.path.dirname(os.path.dirname(__file__))
-EMPTY_TEST_CONFIG = os.path.join(MAKE_ROOT, 'core', 'empty_test_config.xml')
+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(
-    MAKE_ROOT, 'core', 'instrumentation_test_config_template.xml')
+    TOOLS_DIR, '..', 'core', 'instrumentation_test_config_template.xml')
 
 
 class AutoGenTestConfigUnittests(unittest.TestCase):
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..ed60188 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -15,27 +15,33 @@
 # limitations under the License.
 
 """
-Build image output_image_file from input_directory, properties_file, and target_out_dir
+Builds output_image from the given input_directory, properties_file,
+and writes the image to target_output_directory.
 
-Usage:  build_image input_directory properties_file output_image_file target_out_dir
-
+Usage:  build_image.py input_directory properties_file output_image \\
+            target_output_directory
 """
+
+from __future__ import print_function
+
 import os
 import os.path
 import re
-import subprocess
-import sys
-import common
 import shlex
 import shutil
+import subprocess
+import sys
+
+import common
 import sparse_img
-import tempfile
+
 
 OPTIONS = common.OPTIONS
 
 FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
 BLOCK_SIZE = 4096
 
+
 def RunCommand(cmd, verbose=None):
   """Echo and run the given command.
 
@@ -56,6 +62,7 @@
     print(output.rstrip())
   return (output, p.returncode)
 
+
 def GetVerityFECSize(partition_size):
   cmd = ["fec", "-s", str(partition_size)]
   output, exit_code = RunCommand(cmd, False)
@@ -63,6 +70,7 @@
     return False, 0
   return True, int(output)
 
+
 def GetVerityTreeSize(partition_size):
   cmd = ["build_verity_tree", "-s", str(partition_size)]
   output, exit_code = RunCommand(cmd, False)
@@ -70,6 +78,7 @@
     return False, 0
   return True, int(output)
 
+
 def GetVerityMetadataSize(partition_size):
   cmd = ["system/extras/verity/build_verity_metadata.py", "size",
          str(partition_size)]
@@ -78,6 +87,7 @@
     return False, 0
   return True, int(output)
 
+
 def GetVeritySize(partition_size, fec_supported):
   success, verity_tree_size = GetVerityTreeSize(partition_size)
   if not success:
@@ -93,16 +103,19 @@
     return verity_size + fec_size
   return verity_size
 
+
 def GetSimgSize(image_file):
   simg = sparse_img.SparseImage(image_file, build_map=False)
   return simg.blocksize * simg.total_blocks
 
+
 def ZeroPadSimg(image_file, pad_size):
   blocks = pad_size // BLOCK_SIZE
   print("Padding %d blocks (%d bytes)" % (blocks, pad_size))
   simg = sparse_img.SparseImage(image_file, mode="r+b", build_map=False)
   simg.AppendFillChunk(0, blocks)
 
+
 def AVBCalcMaxImageSize(avbtool, footer_type, partition_size, additional_args):
   """Calculates max image size for a given partition size.
 
@@ -115,8 +128,8 @@
   Returns:
     The maximum image size or 0 if an error occurred.
   """
-  cmd =[avbtool, "add_%s_footer" % footer_type,
-        "--partition_size", partition_size, "--calc_max_image_size"]
+  cmd = [avbtool, "add_%s_footer" % footer_type,
+         "--partition_size", partition_size, "--calc_max_image_size"]
   cmd.extend(shlex.split(additional_args))
 
   (output, exit_code) = RunCommand(cmd)
@@ -125,6 +138,7 @@
   else:
     return int(output)
 
+
 def AVBAddFooter(image_path, avbtool, footer_type, partition_size,
                  partition_name, key_path, algorithm, salt,
                  additional_args):
@@ -140,14 +154,15 @@
     algorithm: Name of algorithm to use or None.
     salt: The salt to use (a hexadecimal string) or None.
     additional_args: Additional arguments to pass to 'avbtool
-      add_hashtree_image'.
+        add_hashtree_image'.
+
   Returns:
     True if the operation succeeded.
   """
-  cmd =[avbtool, "add_%s_footer" % footer_type,
-        "--partition_size", partition_size,
-        "--partition_name", partition_name,
-        "--image", image_path]
+  cmd = [avbtool, "add_%s_footer" % footer_type,
+         "--partition_size", partition_size,
+         "--partition_name", partition_name,
+         "--image", image_path]
 
   if key_path and algorithm:
     cmd.extend(["--key", key_path, "--algorithm", algorithm])
@@ -159,12 +174,15 @@
   (_, exit_code) = RunCommand(cmd)
   return exit_code == 0
 
+
 def AdjustPartitionSizeForVerity(partition_size, fec_supported):
   """Modifies the provided partition size to account for the verity metadata.
 
   This information is used to size the created image appropriately.
+
   Args:
     partition_size: the size of the partition to be verified.
+
   Returns:
     A tuple of the size of the partition adjusted for verity metadata, and
     the size of verity metadata.
@@ -201,30 +219,34 @@
   AdjustPartitionSizeForVerity.results[key] = (result, verity_size)
   return (result, verity_size)
 
+
 AdjustPartitionSizeForVerity.results = {}
 
+
 def BuildVerityFEC(sparse_image_path, verity_path, verity_fec_path,
                    padding_size):
   cmd = ["fec", "-e", "-p", str(padding_size), sparse_image_path,
          verity_path, verity_fec_path]
   output, exit_code = RunCommand(cmd)
   if exit_code != 0:
-    print "Could not build FEC data! Error: %s" % output
+    print("Could not build FEC data! Error: %s" % output)
     return False
   return True
 
+
 def BuildVerityTree(sparse_image_path, verity_image_path, prop_dict):
   cmd = ["build_verity_tree", "-A", FIXED_SALT, sparse_image_path,
          verity_image_path]
   output, exit_code = RunCommand(cmd)
   if exit_code != 0:
-    print "Could not build verity tree! Error: %s" % output
+    print("Could not build verity tree! Error: %s" % output)
     return False
   root, salt = output.split()
   prop_dict["verity_root_hash"] = root
   prop_dict["verity_salt"] = salt
   return True
 
+
 def BuildVerityMetadata(image_size, verity_metadata_path, root_hash, salt,
                         block_device, signer_path, key, signer_args,
                         verity_disable):
@@ -237,10 +259,11 @@
     cmd.append("--verity_disable")
   output, exit_code = RunCommand(cmd)
   if exit_code != 0:
-    print "Could not build verity metadata! Error: %s" % output
+    print("Could not build verity metadata! Error: %s" % output)
     return False
   return True
 
+
 def Append2Simg(sparse_image_path, unsparse_image_path, error_message):
   """Appends the unsparse image to the given sparse image.
 
@@ -253,18 +276,23 @@
   cmd = ["append2simg", sparse_image_path, unsparse_image_path]
   output, exit_code = RunCommand(cmd)
   if exit_code != 0:
-    print "%s: %s" % (error_message, output)
+    print("%s: %s" % (error_message, output))
     return False
   return True
 
+
 def Append(target, file_to_append, error_message):
-  # appending file_to_append to target
-  with open(target, "a") as out_file:
-    with open(file_to_append, "r") as input_file:
+  """Appends file_to_append to target."""
+  try:
+    with open(target, "a") as out_file, open(file_to_append, "r") as input_file:
       for line in input_file:
         out_file.write(line)
+  except IOError:
+    print(error_message)
+    return False
   return True
 
+
 def BuildVerifiedImage(data_image_path, verity_image_path,
                        verity_metadata_path, verity_fec_path,
                        padding_size, fec_supported):
@@ -286,6 +314,7 @@
     return False
   return True
 
+
 def UnsparseImage(sparse_image_path, replace=True):
   img_dir = os.path.dirname(sparse_image_path)
   unsparse_image_path = "unsparse_" + os.path.basename(sparse_image_path)
@@ -302,6 +331,7 @@
     return False, None
   return True, unsparse_image_path
 
+
 def MakeVerityEnabledImage(out_file, fec_supported, prop_dict):
   """Creates an image that is verifiable using dm-verity.
 
@@ -323,7 +353,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 +362,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 +371,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,23 +386,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)
 
+def ConvertBlockMapToBaseFs(block_map_file):
+  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
+  return base_fs_file if exit_code == 0 else None
 
 
 def CheckHeadroom(ext4fs_output, prop_dict):
@@ -391,17 +412,26 @@
 
   Returns:
     The check result.
+
+  Raises:
+    AssertionError: On invalid input.
   """
+  assert ext4fs_output is not None
+  assert prop_dict.get('fs_type', '').startswith('ext4')
+  assert 'partition_headroom' in prop_dict
+  assert 'mount_point' in prop_dict
+
   ext4fs_stats = re.compile(
       r'Created filesystem with .* (?P<used_blocks>[0-9]+)/'
       r'(?P<total_blocks>[0-9]+) blocks')
-  m = ext4fs_stats.match(ext4fs_output.strip().split('\n')[-1])
+  last_line = ext4fs_output.strip().split('\n')[-1]
+  m = ext4fs_stats.match(last_line)
   used_blocks = int(m.groupdict().get('used_blocks'))
   total_blocks = int(m.groupdict().get('total_blocks'))
-  headroom_blocks = int(prop_dict.get('partition_headroom')) / BLOCK_SIZE
+  headroom_blocks = int(prop_dict['partition_headroom']) / BLOCK_SIZE
   adjusted_blocks = total_blocks - headroom_blocks
   if used_blocks > adjusted_blocks:
-    mount_point = prop_dict.get("mount_point")
+    mount_point = prop_dict["mount_point"]
     print("Error: Not enough room on %s (total: %d blocks, used: %d blocks, "
           "headroom: %d blocks, available: %d blocks)" % (
               mount_point, total_blocks, used_blocks, headroom_blocks,
@@ -417,7 +447,8 @@
     in_dir: path of input directory.
     prop_dict: property dictionary.
     out_file: path of the output image file.
-    target_out: path of the product out directory to read device specific FS config files.
+    target_out: path of the product out directory to read device specific FS
+        config files.
 
   Returns:
     True iff the image is built successfully.
@@ -426,17 +457,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()
-    # Change the mount point to "/"
+  if (prop_dict.get("system_root_image") == "true" and
+      prop_dict["mount_point"] == "system"):
+    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:
@@ -447,7 +476,7 @@
 
   build_command = []
   fs_type = prop_dict.get("fs_type", "")
-  run_fsck = False
+  run_e2fsck = False
 
   fs_spans_partition = True
   if fs_type.startswith("squash"):
@@ -461,8 +490,8 @@
   # verified.
   if verity_supported and is_verity_partition:
     partition_size = int(prop_dict.get("partition_size"))
-    (adjusted_size, verity_size) = AdjustPartitionSizeForVerity(partition_size,
-                                                                verity_fec_supported)
+    (adjusted_size, verity_size) = AdjustPartitionSizeForVerity(
+        partition_size, verity_fec_supported)
     if not adjusted_size:
       return False
     prop_dict["partition_size"] = str(adjusted_size)
@@ -481,8 +510,8 @@
     partition_size = prop_dict["partition_size"]
     # avb_add_hash_footer_args or avb_add_hashtree_footer_args.
     additional_args = prop_dict["avb_add_" + avb_footer_type + "_footer_args"]
-    max_image_size = AVBCalcMaxImageSize(avbtool, avb_footer_type, partition_size,
-                                         additional_args)
+    max_image_size = AVBCalcMaxImageSize(avbtool, avb_footer_type,
+                                         partition_size, additional_args)
     if max_image_size == 0:
       return False
     prop_dict["partition_size"] = str(max_image_size)
@@ -492,7 +521,7 @@
     build_command = [prop_dict["ext_mkuserimg"]]
     if "extfs_sparse_flag" in prop_dict:
       build_command.append(prop_dict["extfs_sparse_flag"])
-      run_fsck = True
+      run_e2fsck = True
     build_command.extend([in_dir, out_file, fs_type,
                           prop_dict["mount_point"]])
     build_command.append(prop_dict["partition_size"])
@@ -546,7 +575,7 @@
       build_command.extend(["-zo", prop_dict["squashfs_compressor_opt"]])
     if "squashfs_block_size" in prop_dict:
       build_command.extend(["-b", prop_dict["squashfs_block_size"]])
-    if "squashfs_disable_4k_align" in prop_dict and prop_dict.get("squashfs_disable_4k_align") == "true":
+    if prop_dict.get("squashfs_disable_4k_align") == "true":
       build_command.extend(["-a"])
   elif fs_type.startswith("f2fs"):
     build_command = ["mkf2fsuserimg.sh"]
@@ -576,28 +605,14 @@
     shutil.rmtree(staging_system, ignore_errors=True)
     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)
+  (mkfs_output, exit_code) = RunCommand(build_command)
   if exit_code != 0:
     print("Error: '%s' failed with exit code %d" % (build_command, exit_code))
     return False
 
   # Check if there's enough headroom space available for ext4 image.
   if "partition_headroom" in prop_dict and fs_type.startswith("ext4"):
-    assert ext4fs_output is not None
-    if not CheckHeadroom(ext4fs_output, prop_dict):
+    if not CheckHeadroom(mkfs_output, prop_dict):
       return False
 
   if not fs_spans_partition:
@@ -611,7 +626,7 @@
     if verity_supported and is_verity_partition:
       ZeroPadSimg(out_file, partition_size - image_size)
 
-  # create the verified image if this is to be verified
+  # Create the verified image if this is to be verified.
   if verity_supported and is_verity_partition:
     if not MakeVerityEnabledImage(out_file, verity_fec_supported, prop_dict):
       return False
@@ -627,11 +642,12 @@
     salt = prop_dict.get("avb_salt")
     # avb_add_hash_footer_args or avb_add_hashtree_footer_args
     additional_args = prop_dict["avb_add_" + avb_footer_type + "_footer_args"]
-    if not AVBAddFooter(out_file, avbtool, avb_footer_type, original_partition_size,
-                        partition_name, key_path, algorithm, salt, additional_args):
+    if not AVBAddFooter(out_file, avbtool, avb_footer_type,
+                        original_partition_size, partition_name, key_path,
+                        algorithm, salt, additional_args):
       return False
 
-  if run_fsck and prop_dict.get("skip_fsck") != "true":
+  if run_e2fsck and prop_dict.get("skip_fsck") != "true":
     success, unsparse_image = UnsparseImage(out_file, replace=False)
     if not success:
       return False
@@ -643,7 +659,8 @@
     os.remove(unsparse_image)
 
     if exit_code != 0:
-      print("Error: '%s' failed with exit code %d" % (e2fsck_command, exit_code))
+      print("Error: '%s' failed with exit code %d" % (e2fsck_command,
+                                                      exit_code))
       return False
 
   return True
@@ -710,7 +727,8 @@
     copy_prop("system_base_fs_file", "base_fs_file")
     copy_prop("system_extfs_inode_count", "extfs_inode_count")
   elif mount_point == "system_other":
-    # We inherit the selinux policies of /system since we contain some of its files.
+    # We inherit the selinux policies of /system since we contain some of its
+    # files.
     d["mount_point"] = "system"
     copy_prop("avb_system_hashtree_enable", "avb_hashtree_enable")
     copy_prop("avb_system_add_hashtree_footer_args",
@@ -732,7 +750,7 @@
     copy_prop("fs_type", "fs_type")
     copy_prop("userdata_fs_type", "fs_type")
     copy_prop("userdata_size", "partition_size")
-    copy_prop("flash_logical_block_size","flash_logical_block_size")
+    copy_prop("flash_logical_block_size", "flash_logical_block_size")
     copy_prop("flash_erase_block_size", "flash_erase_block_size")
   elif mount_point == "cache":
     copy_prop("cache_fs_type", "fs_type")
@@ -778,7 +796,7 @@
 
 def main(argv):
   if len(argv) != 4:
-    print __doc__
+    print(__doc__)
     sys.exit(1)
 
   in_dir = argv[0]
@@ -807,16 +825,19 @@
     elif image_filename == "oem.img":
       mount_point = "oem"
     else:
-      print >> sys.stderr, "error: unknown image file name ", image_filename
-      exit(1)
+      print("error: unknown image file name ", image_filename, file=sys.stderr)
+      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)
+    print("error: failed to build %s from %s" % (out_file, in_dir),
+          file=sys.stderr)
+    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 12e757d..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):
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 7bfc04b..7a1126c 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,41 +554,62 @@
   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):
-  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 = []
-  for param in in_cmdline.split():
-    if "veritykeyid" in param:
-      # extract keyid using openssl command
-      p = common.Run(
-          ["openssl", "x509", "-in", keypath, "-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,))
-    else:
-      out_cmdline.append(param)
+def ReplaceVerityKeyId(input_zip, output_zip, key_path):
+  """Replaces the veritykeyid parameter in BOOT/cmdline.
 
-  out_cmdline = ' '.join(out_cmdline)
-  out_cmdline = out_cmdline.strip()
-  print "out_cmdline %s" % (out_cmdline)
-  common.ZipWriteStr(targetfile_output_zip, "BOOT/cmdline", out_cmdline)
+  Args:
+    input_zip: The input target_files zip, which should be already open.
+    output_zip: The output target_files zip, which should be already open and
+        writable.
+    key_path: The path to the PEM encoded X.509 certificate.
+  """
+  in_cmdline = input_zip.read("BOOT/cmdline")
+  # Copy in_cmdline to output_zip if veritykeyid is not present.
+  if "veritykeyid" not in in_cmdline:
+    common.ZipWriteStr(output_zip, "BOOT/cmdline", in_cmdline)
+    return
+
+  out_buffer = []
+  for param in in_cmdline.split():
+    if "veritykeyid" not in param:
+      out_buffer.append(param)
+      continue
+
+    # Extract keyid using openssl command.
+    p = common.Run(["openssl", "x509", "-in", key_path, "-text"],
+                   stdout=subprocess.PIPE)
+    keyid, stderr = p.communicate()
+    assert p.returncode == 0, "Failed to dump certificate: {}".format(stderr)
+    keyid = re.search(
+        r'keyid:([0-9a-fA-F:]*)', keyid).group(1).replace(':', '').lower()
+    print("Replacing verity keyid with {}".format(keyid))
+    out_buffer.append("veritykeyid=id:%s" % (keyid,))
+
+  out_cmdline = ' '.join(out_buffer).strip() + '\n'
+  common.ZipWriteStr(output_zip, "BOOT/cmdline", out_cmdline)
 
 
 def ReplaceMiscInfoTxt(input_zip, output_zip, misc_info):
@@ -600,12 +631,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 +647,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 +798,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 +863,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_build_image.py b/tools/releasetools/test_build_image.py
index 6566a5a..161faff 100644
--- a/tools/releasetools/test_build_image.py
+++ b/tools/releasetools/test_build_image.py
@@ -14,52 +14,81 @@
 # limitations under the License.
 #
 
-import shutil
-import tempfile
 import unittest
 
+import common
 from build_image import CheckHeadroom, RunCommand
 
 
 class BuildImageTest(unittest.TestCase):
 
+  # Available: 1000 blocks.
+  EXT4FS_OUTPUT = (
+      "Created filesystem with 2777/129024 inodes and 515099/516099 blocks")
+
   def test_CheckHeadroom_SizeUnderLimit(self):
-    ext4fs_output = ("Created filesystem with 2777/129024 inodes and "
-                     "508140/516099 blocks")
+    # Required headroom: 1000 blocks.
     prop_dict = {
-        'partition_headroom' : '4194304',
+        'fs_type' : 'ext4',
+        'partition_headroom' : '4096000',
         'mount_point' : 'system',
     }
-    self.assertTrue(CheckHeadroom(ext4fs_output, prop_dict))
+    self.assertTrue(CheckHeadroom(self.EXT4FS_OUTPUT, prop_dict))
 
   def test_CheckHeadroom_InsufficientHeadroom(self):
-    ext4fs_output = ("Created filesystem with 2777/129024 inodes and "
-                     "515099/516099 blocks")
+    # Required headroom: 1001 blocks.
     prop_dict = {
+        'fs_type' : 'ext4',
         'partition_headroom' : '4100096',
         'mount_point' : 'system',
     }
-    self.assertFalse(CheckHeadroom(ext4fs_output, prop_dict))
+    self.assertFalse(CheckHeadroom(self.EXT4FS_OUTPUT, prop_dict))
+
+  def test_CheckHeadroom_WrongFsType(self):
+    prop_dict = {
+        'fs_type' : 'f2fs',
+        'partition_headroom' : '4100096',
+        'mount_point' : 'system',
+    }
+    self.assertRaises(
+        AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict)
+
+  def test_CheckHeadroom_MissingProperties(self):
+    prop_dict = {
+        'fs_type' : 'ext4',
+        'partition_headroom' : '4100096',
+    }
+    self.assertRaises(
+        AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict)
+
+    prop_dict = {
+        'fs_type' : 'ext4',
+        'mount_point' : 'system',
+    }
+    self.assertRaises(
+        AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict)
 
   def test_CheckHeadroom_WithMke2fsOutput(self):
     """Tests the result parsing from actual call to mke2fs."""
-    input_dir = tempfile.mkdtemp()
-    output_image = tempfile.NamedTemporaryFile(suffix='.img')
-    command = ['mkuserimg_mke2fs.sh', input_dir, output_image.name, 'ext4',
+    input_dir = common.MakeTempDir()
+    output_image = common.MakeTempFile(suffix='.img')
+    command = ['mkuserimg_mke2fs.sh', input_dir, output_image, 'ext4',
                '/system', '409600', '-j', '0']
     ext4fs_output, exit_code = RunCommand(command)
     self.assertEqual(0, exit_code)
 
     prop_dict = {
+        'fs_type' : 'ext4',
         'partition_headroom' : '40960',
         'mount_point' : 'system',
     }
     self.assertTrue(CheckHeadroom(ext4fs_output, prop_dict))
 
     prop_dict = {
+        'fs_type' : 'ext4',
         'partition_headroom' : '413696',
         'mount_point' : 'system',
     }
     self.assertFalse(CheckHeadroom(ext4fs_output, prop_dict))
 
-    shutil.rmtree(input_dir)
+    common.Cleanup()
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()
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 90afdc7..726d6b9 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -16,13 +16,22 @@
 
 from __future__ import print_function
 
+import tempfile
 import unittest
+import zipfile
 
-from sign_target_files_apks import EditTags, RewriteProps
+import common
+from sign_target_files_apks import EditTags, ReplaceVerityKeyId, RewriteProps
 
 
 class SignTargetFilesApksTest(unittest.TestCase):
 
+  def setUp(self):
+    self.tempdir = common.MakeTempDir()
+
+  def tearDown(self):
+    common.Cleanup()
+
   def test_EditTags(self):
     self.assertEqual(EditTags('dev-keys'), ('release-keys'))
     self.assertEqual(EditTags('test-keys'), ('release-keys'))
@@ -59,9 +68,132 @@
     )
 
     # Assert the case for each individual line.
-    for input, output in props:
-      self.assertEqual(RewriteProps(input), output)
+    for prop, output in props:
+      self.assertEqual(RewriteProps(prop), output)
 
     # Concatenate all the input lines.
     self.assertEqual(RewriteProps('\n'.join([prop[0] for prop in props])),
                      ''.join([prop[1] for prop in props]))
+
+  def test_ReplaceVerityKeyId(self):
+    BOOT_CMDLINE1 = (
+        "console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 "
+        "androidboot.hardware=marlin user_debug=31 ehci-hcd.park=3 "
+        "lpm_levels.sleep_disabled=1 cma=32M@0-0xffffffff loop.max_part=7 "
+        "buildvariant=userdebug "
+        "veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f\n")
+
+    BOOT_CMDLINE2 = (
+        "console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 "
+        "androidboot.hardware=marlin user_debug=31 ehci-hcd.park=3 "
+        "lpm_levels.sleep_disabled=1 cma=32M@0-0xffffffff loop.max_part=7 "
+        "buildvariant=userdebug "
+        "veritykeyid=id:485900563d272c46ae118605a47419ac09ca8c11\n")
+
+    # From build/target/product/security/verity.x509.pem.
+    VERITY_CERTIFICATE1 = """-----BEGIN CERTIFICATE-----
+MIID/TCCAuWgAwIBAgIJAJcPmDkJqolJMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
+VmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UE
+AwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0xNDExMDYxOTA3NDBaFw00MjAzMjQxOTA3NDBaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UEAwwHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAOjreE0vTVSRenuzO9vnaWfk0eQzYab0gqpi
+6xAzi6dmD+ugoEKJmbPiuE5Dwf21isZ9uhUUu0dQM46dK4ocKxMRrcnmGxydFn6o
+fs3ODJMXOkv2gKXL/FdbEPdDbxzdu8z3yk+W67udM/fW7WbaQ3DO0knu+izKak/3
+T41c5uoXmQ81UNtAzRGzGchNVXMmWuTGOkg6U+0I2Td7K8yvUMWhAWPPpKLtVH9r
+AL5TzjYNR92izdKcz3AjRsI3CTjtpiVABGeX0TcjRSuZB7K9EK56HV+OFNS6I1NP
+jdD7FIShyGlqqZdUOkAUZYanbpgeT5N7QL6uuqcGpoTOkalu6kkCAwEAAaNQME4w
+HQYDVR0OBBYEFH5DM/m7oArf4O3peeKO0ZIEkrQPMB8GA1UdIwQYMBaAFH5DM/m7
+oArf4O3peeKO0ZIEkrQPMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
+AHO3NSvDE5jFvMehGGtS8BnFYdFKRIglDMc4niWSzhzOVYRH4WajxdtBWc5fx0ix
+NF/+hVKVhP6AIOQa+++sk+HIi7RvioPPbhjcsVlZe7cUEGrLSSveGouQyc+j0+m6
+JF84kszIl5GGNMTnx0XRPO+g8t6h5LWfnVydgZfpGRRg+WHewk1U2HlvTjIceb0N
+dcoJ8WKJAFWdcuE7VIm4w+vF/DYX/A2Oyzr2+QRhmYSv1cusgAeC1tvH4ap+J1Lg
+UnOu5Kh/FqPLLSwNVQp4Bu7b9QFfqK8Moj84bj88NqRGZgDyqzuTrFxn6FW7dmyA
+yttuAJAEAymk1mipd9+zp38=
+-----END CERTIFICATE-----
+"""
+
+    # From build/target/product/security/testkey.x509.pem.
+    VERITY_CERTIFICATE2 = """-----BEGIN CERTIFICATE-----
+MIIEqDCCA5CgAwIBAgIJAJNurL4H8gHfMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
+VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE
+AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0wODAyMjkwMTMzNDZaFw0zNTA3MTcwMTMzNDZaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4G
+A1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
+hvcNAQEBBQADggENADCCAQgCggEBANaTGQTexgskse3HYuDZ2CU+Ps1s6x3i/waM
+qOi8qM1r03hupwqnbOYOuw+ZNVn/2T53qUPn6D1LZLjk/qLT5lbx4meoG7+yMLV4
+wgRDvkxyGLhG9SEVhvA4oU6Jwr44f46+z4/Kw9oe4zDJ6pPQp8PcSvNQIg1QCAcy
+4ICXF+5qBTNZ5qaU7Cyz8oSgpGbIepTYOzEJOmc3Li9kEsBubULxWBjf/gOBzAzU
+RNps3cO4JFgZSAGzJWQTT7/emMkod0jb9WdqVA2BVMi7yge54kdVMxHEa5r3b97s
+zI5p58ii0I54JiCUP5lyfTwE/nKZHZnfm644oLIXf6MdW2r+6R8CAQOjgfwwgfkw
+HQYDVR0OBBYEFEhZAFY9JyxGrhGGBaR0GawJyowRMIHJBgNVHSMEgcEwgb6AFEhZ
+AFY9JyxGrhGGBaR0GawJyowRoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UE
+CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMH
+QW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAG
+CSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJAJNurL4H8gHfMAwGA1Ud
+EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHqvlozrUMRBBVEY0NqrrwFbinZa
+J6cVosK0TyIUFf/azgMJWr+kLfcHCHJsIGnlw27drgQAvilFLAhLwn62oX6snb4Y
+LCBOsVMR9FXYJLZW2+TcIkCRLXWG/oiVHQGo/rWuWkJgU134NDEFJCJGjDbiLCpe
++ZTWHdcwauTJ9pUbo8EvHRkU3cYfGmLaLfgn9gP+pWA7LFQNvXwBnDa6sppCccEX
+31I828XzgXpJ4O+mDL1/dBd+ek8ZPUP0IgdyZm5MTYPhvVqGCHzzTy3sIeJFymwr
+sBbmg2OAUNLEMO6nwmocSdN2ClirfxqCzJOLSDE4QyS9BAH6EhY6UFcOaE0=
+-----END CERTIFICATE-----
+"""
+
+    input_file = tempfile.NamedTemporaryFile(
+        delete=False, suffix='.zip', dir=self.tempdir)
+    with zipfile.ZipFile(input_file.name, 'w') as input_zip:
+      input_zip.writestr('BOOT/cmdline', BOOT_CMDLINE1)
+
+    # Test with the first certificate.
+    cert_file = tempfile.NamedTemporaryFile(
+        delete=False, suffix='.x509.pem', dir=self.tempdir)
+    cert_file.write(VERITY_CERTIFICATE1)
+    cert_file.close()
+
+    output_file = tempfile.NamedTemporaryFile(
+        delete=False, suffix='.zip', dir=self.tempdir)
+    with zipfile.ZipFile(input_file.name, 'r') as input_zip, \
+         zipfile.ZipFile(output_file.name, 'w') as output_zip:
+      ReplaceVerityKeyId(input_zip, output_zip, cert_file.name)
+
+    with zipfile.ZipFile(output_file.name) as output_zip:
+      self.assertEqual(BOOT_CMDLINE1, output_zip.read('BOOT/cmdline'))
+
+    # Test with the second certificate.
+    with open(cert_file.name, 'w') as cert_file_fp:
+      cert_file_fp.write(VERITY_CERTIFICATE2)
+
+    with zipfile.ZipFile(input_file.name, 'r') as input_zip, \
+         zipfile.ZipFile(output_file.name, 'w') as output_zip:
+      ReplaceVerityKeyId(input_zip, output_zip, cert_file.name)
+
+    with zipfile.ZipFile(output_file.name) as output_zip:
+      self.assertEqual(BOOT_CMDLINE2, output_zip.read('BOOT/cmdline'))
+
+  def test_ReplaceVerityKeyId_no_veritykeyid(self):
+    BOOT_CMDLINE = (
+        "console=ttyHSL0,115200,n8 androidboot.hardware=bullhead boot_cpus=0-5 "
+        "lpm_levels.sleep_disabled=1 msm_poweroff.download_mode=0 "
+        "loop.max_part=7\n")
+
+    input_file = tempfile.NamedTemporaryFile(
+        delete=False, suffix='.zip', dir=self.tempdir)
+    with zipfile.ZipFile(input_file.name, 'w') as input_zip:
+      input_zip.writestr('BOOT/cmdline', BOOT_CMDLINE)
+
+    output_file = tempfile.NamedTemporaryFile(
+        delete=False, suffix='.zip', dir=self.tempdir)
+    with zipfile.ZipFile(input_file.name, 'r') as input_zip, \
+         zipfile.ZipFile(output_file.name, 'w') as output_zip:
+      ReplaceVerityKeyId(input_zip, output_zip, None)
+
+    with zipfile.ZipFile(output_file.name) as output_zip:
+      self.assertEqual(BOOT_CMDLINE, output_zip.read('BOOT/cmdline'))