Merge "Revert "Fix build error for sdk_gphone_x86_64-userdebug""
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 398a006..a96dd83 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -503,6 +503,12 @@
 # Remove obsolete recovery etc files
 $(call add-clean-step, rm -rf $(TARGET_RECOVERY_ROOT_OUT)/etc)
 
+# Remove *_OUT_INTERMEDIATE_LIBRARIES
+$(call add-clean-step, rm -rf $(addsuffix /lib,\
+  $(HOST_OUT_INTERMEDIATES) $(2ND_HOST_OUT_INTERMEDIATES) \
+  $(HOST_CROSS_OUT_INTERMEDIATES) $(2ND_HOST_CROSS_OUT_INTERMEDIATES) \
+  $(TARGET_OUT_INTERMEDIATES) $(2ND_TARGET_OUT_INTERMEDIATES)))
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index 23f4788..a2d9339 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -144,6 +144,21 @@
 endif
 FINAL_VENDOR_DEFAULT_PROPERTIES += \
     $(call collapse-pairs, $(PRODUCT_DEFAULT_PROPERTY_OVERRIDES))
+
+# Although these variables are prefixed with TARGET_RECOVERY_, they are also needed under charger
+# mode (via libminui).
+ifdef TARGET_RECOVERY_DEFAULT_ROTATION
+FINAL_VENDOR_DEFAULT_PROPERTIES += \
+    ro.minui.default_rotation=$(TARGET_RECOVERY_DEFAULT_ROTATION)
+endif
+ifdef TARGET_RECOVERY_OVERSCAN_PERCENT
+FINAL_VENDOR_DEFAULT_PROPERTIES += \
+    ro.minui.overscan_percent=$(TARGET_RECOVERY_OVERSCAN_PERCENT)
+endif
+ifdef TARGET_RECOVERY_PIXEL_FORMAT
+FINAL_VENDOR_DEFAULT_PROPERTIES += \
+    ro.minui.pixel_format=$(TARGET_RECOVERY_PIXEL_FORMAT)
+endif
 FINAL_VENDOR_DEFAULT_PROPERTIES := $(call uniq-pairs-by-first-component, \
     $(FINAL_VENDOR_DEFAULT_PROPERTIES),=)
 
@@ -670,7 +685,7 @@
 # for future OTA packages installed by this system.  Actual product
 # deliverables will be re-signed by hand.  We expect this file to
 # exist with the suffixes ".x509.pem" and ".pk8".
-DEFAULT_KEY_CERT_PAIR := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
+DEFAULT_KEY_CERT_PAIR := $(strip $(DEFAULT_SYSTEM_DEV_CERTIFICATE))
 
 
 # Rules that need to be present for the all targets, even
@@ -832,13 +847,6 @@
     --os_version $(PLATFORM_VERSION) \
     --os_patch_level $(PLATFORM_SECURITY_PATCH)
 
-# BOARD_USES_RECOVERY_AS_BOOT = true must have BOARD_BUILD_SYSTEM_ROOT_IMAGE = true.
-ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
-ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
-  $(error BOARD_BUILD_SYSTEM_ROOT_IMAGE must be enabled for BOARD_USES_RECOVERY_AS_BOOT.)
-endif
-endif
-
 # We build recovery as boot image if BOARD_USES_RECOVERY_AS_BOOT is true.
 ifneq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
 ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true)
@@ -1132,12 +1140,12 @@
 # This rule adds to ALL_DEFAULT_INSTALLED_MODULES, so it needs to come
 # before the rules that use that variable to build the image.
 ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT_ETC)/security/otacerts.zip
-$(TARGET_OUT_ETC)/security/otacerts.zip: KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
-$(TARGET_OUT_ETC)/security/otacerts.zip: $(addsuffix .x509.pem,$(DEFAULT_KEY_CERT_PAIR)) | $(ZIPTIME)
+$(TARGET_OUT_ETC)/security/otacerts.zip: PRIVATE_CERT := $(DEFAULT_KEY_CERT_PAIR).x509.pem
+$(TARGET_OUT_ETC)/security/otacerts.zip: $(SOONG_ZIP)
+$(TARGET_OUT_ETC)/security/otacerts.zip: $(DEFAULT_KEY_CERT_PAIR).x509.pem
 	$(hide) rm -f $@
 	$(hide) mkdir -p $(dir $@)
-	$(hide) zip -qjX $@ $<
-	$(remove-timestamps-from-package)
+	$(hide) $(SOONG_ZIP) -o $@ -C $(dir $(PRIVATE_CERT)) -f $(PRIVATE_CERT)
 
 # Carry the public key for update_engine if it's a non-IoT target that
 # uses the AB updater. We use the same key as otacerts but in RSA public key
@@ -1145,7 +1153,7 @@
 ifeq ($(AB_OTA_UPDATER),true)
 ifneq ($(PRODUCT_IOT),true)
 ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT_ETC)/update_engine/update-payload-key.pub.pem
-$(TARGET_OUT_ETC)/update_engine/update-payload-key.pub.pem: $(addsuffix .x509.pem,$(DEFAULT_KEY_CERT_PAIR))
+$(TARGET_OUT_ETC)/update_engine/update-payload-key.pub.pem: $(DEFAULT_KEY_CERT_PAIR).x509.pem
 	$(hide) rm -f $@
 	$(hide) mkdir -p $(dir $@)
 	$(hide) openssl x509 -pubkey -noout -in $< > $@
@@ -1537,17 +1545,14 @@
 #      (BOARD_USES_FULL_RECOVERY_IMAGE = true);
 #   b) We build a single image that contains boot and recovery both - no recovery image to install
 #      (BOARD_USES_RECOVERY_AS_BOOT = true);
-#   c) We build the root into system image - not needing the resource file as we do bsdiff
+#   c) We mount the system image as / and therefore do not have a ramdisk in boot.img
 #      (BOARD_BUILD_SYSTEM_ROOT_IMAGE = true).
 #   d) We include the recovery DTBO image within recovery - not needing the resource file as we
 #      do bsdiff because boot and recovery will contain different number of entries
 #      (BOARD_INCLUDE_RECOVERY_DTBO = true).
-# Note that condition b) implies condition c), because of the earlier check in this file:
-# "BOARD_USES_RECOVERY_AS_BOOT = true must have BOARD_BUILD_SYSTEM_ROOT_IMAGE = true" (not vice
-# versa though).
 
-ifeq (,$(filter true, $(BOARD_USES_FULL_RECOVERY_IMAGE) $(BOARD_BUILD_SYSTEM_ROOT_IMAGE) \
-  $(BOARD_INCLUDE_RECOVERY_DTBO)))
+ifeq (,$(filter true, $(BOARD_USES_FULL_RECOVERY_IMAGE) $(BOARD_USES_RECOVERY_AS_BOOT) \
+  $(BOARD_BUILD_SYSTEM_ROOT_IMAGE) $(BOARD_INCLUDE_RECOVERY_DTBO)))
 # Named '.dat' so we don't attempt to use imgdiff for patching it.
 RECOVERY_RESOURCE_ZIP := $(TARGET_OUT)/etc/recovery-resource.dat
 else
@@ -1557,9 +1562,6 @@
 INSTALLED_RECOVERY_BUILD_PROP_TARGET := $(TARGET_RECOVERY_ROOT_OUT)/prop.default
 
 $(INSTALLED_RECOVERY_BUILD_PROP_TARGET): PRIVATE_RECOVERY_UI_PROPERTIES := \
-    TARGET_RECOVERY_DEFAULT_ROTATION:default_rotation \
-    TARGET_RECOVERY_OVERSCAN_PERCENT:overscan_percent \
-    TARGET_RECOVERY_PIXEL_FORMAT:pixel_format \
     TARGET_RECOVERY_UI_ANIMATION_FPS:animation_fps \
     TARGET_RECOVERY_UI_MARGIN_HEIGHT:margin_height \
     TARGET_RECOVERY_UI_MARGIN_WIDTH:margin_width \
@@ -1594,7 +1596,7 @@
 		$(INSTALLED_ODM_BUILD_PROP_TARGET) \
 		$(INSTALLED_PRODUCT_BUILD_PROP_TARGET) \
 		$(INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET)
-	@echo "Target recovery buildinfo: $@
+	@echo "Target recovery buildinfo: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) rm -f $@
 	$(hide) cat $(INSTALLED_DEFAULT_PROP_TARGET) > $@
@@ -2024,6 +2026,7 @@
 ## PDK_PLATFORM_ZIP_PRODUCT_BINARIES is used to store specified files to platform.zip.
 ## The variable will be typically set from BoardConfig.mk.
 ## Files under out dir will be rejected to prevent possible conflicts with other rules.
+ifneq (,$(BUILD_PLATFORM_ZIP))
 pdk_odex_javalibs := $(strip $(foreach m,$(DEXPREOPT.MODULES.JAVA_LIBRARIES),\
   $(if $(filter $(DEXPREOPT.$(m).INSTALLED),$(ALL_DEFAULT_INSTALLED_MODULES)),$(m))))
 pdk_odex_apps := $(strip $(foreach m,$(DEXPREOPT.MODULES.APPS),\
@@ -2063,39 +2066,45 @@
 
 $(INSTALLED_PLATFORM_ZIP): PRIVATE_DEX_FILES := $(pdk_classes_dex)
 $(INSTALLED_PLATFORM_ZIP): PRIVATE_ODEX_CONFIG := $(pdk_odex_config_mk)
-$(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_SYSTEMIMAGE_FILES) $(pdk_odex_config_mk)
+$(INSTALLED_PLATFORM_ZIP) : $(SOONG_ZIP)
+# dependencies for the other partitions are defined below after their file lists
+# are known
+$(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_SYSTEMIMAGE_FILES) $(pdk_classes_dex) $(pdk_odex_config_mk)
 	$(call pretty,"Platform zip package: $(INSTALLED_PLATFORM_ZIP)")
-	$(hide) rm -f $@
-	$(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
-		$(TARGET_COPY_OUT_SYSTEM) \
-		$(patsubst $(PRODUCT_OUT)/%, %, $(TARGET_OUT_NOTICE_FILES)) \
-		$(addprefix symbols/,$(PDK_SYMBOL_FILES_LIST))
+	rm -f $@ $@.lst
+	echo "-C $(PRODUCT_OUT)" >> $@.lst
+	echo "-D $(TARGET_OUT)" >> $@.lst
+	echo "-D $(TARGET_OUT_NOTICE_FILES)" >> $@.lst
+	echo "$(addprefix -f $(TARGET_OUT_UNSTRIPPED)/,$(PDK_SYMBOL_FILES_LIST))" >> $@.lst
 ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
-	$(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
-		$(TARGET_COPY_OUT_VENDOR)
+	echo "-D $(TARGET_OUT_VENDOR)" >> $@.lst
 endif
 ifdef BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE
-	$(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
-		$(TARGET_COPY_OUT_PRODUCT)
+	echo "-D $(TARGET_OUT_PRODUCT)" >> $@.lst
 endif
 ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
-	$(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
-		$(TARGET_COPY_OUT_PRODUCT_SERVICES)
+	echo "-D $(TARGET_OUT_PRODUCT_SERVICES)" >> $@.lst
 endif
 ifdef BOARD_ODMIMAGE_FILE_SYSTEM_TYPE
-	$(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
-		$(TARGET_COPY_OUT_ODM)
+	echo "-D $(TARGET_OUT_ODM)" >> $@.lst
 endif
 ifneq ($(PDK_PLATFORM_JAVA_ZIP_CONTENTS),)
-	$(hide) cd $(OUT_DIR) && zip -qryX $(patsubst $(OUT_DIR)/%,%,$@) $(PDK_PLATFORM_JAVA_ZIP_CONTENTS)
+	echo "-C $(OUT_DIR)" >> $@.lst
+	for f in $(filter-out $(PRIVATE_DEX_FILES),$(addprefix -f $(OUT_DIR)/,$(PDK_PLATFORM_JAVA_ZIP_CONTENTS))); do \
+	  if [ -e $$f ]; then \
+	    echo "-f $$f"; \
+	  fi \
+	done >> $@.lst
 endif
 ifneq ($(PDK_PLATFORM_ZIP_PRODUCT_BINARIES),)
-	$(hide) zip -qryX $@ $(PDK_PLATFORM_ZIP_PRODUCT_BINARIES)
+        echo "-C . $(addprefix -f ,$(PDK_PLATFORM_ZIP_PRODUCT_BINARIES))" >> $@.lst
 endif
 	@# Add dex-preopt files and config.
-	$(if $(PRIVATE_DEX_FILES),$(hide) cd $(OUT_DIR) && zip -qryX $(patsubst $(OUT_DIR)/%,%,$@ $(PRIVATE_DEX_FILES)))
-	$(hide) touch $(PRODUCT_OUT)/pdk.mk
-	$(hide) zip -qryXj $@ $(PRIVATE_ODEX_CONFIG) $(PRODUCT_OUT)/pdk.mk
+	$(if $(PRIVATE_DEX_FILES),\
+	  echo "-C $(OUT_DIR) $(addprefix -f ,$(PRIVATE_DEX_FILES))") >> $@.lst
+	touch $(PRODUCT_OUT)/pdk.mk
+	echo "-C $(PRODUCT_OUT) -f $(PRIVATE_ODEX_CONFIG) -f $(PRODUCT_OUT)/pdk.mk" >> $@.lst
+	$(SOONG_ZIP) --ignore_missing_files -o $@ @$@.lst
 
 .PHONY: platform
 platform: $(INSTALLED_PLATFORM_ZIP)
@@ -2108,6 +2117,8 @@
 $(call dist-for-goals, platform platform-java, $(INSTALLED_PLATFORM_ZIP))
 endif
 
+endif # BUILD_PLATFORM_ZIP
+
 # -----------------------------------------------------------------
 ## boot tarball
 define build-boottarball-target
@@ -2645,6 +2656,15 @@
 BOARD_AVB_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
 endif
 
+INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES := \
+    $(BOARD_AVB_VBMETA_MAINLINE) \
+    $(BOARD_AVB_VBMETA_VENDOR)
+
+# Not allowing the same partition to appear in multiple groups.
+ifneq ($(words $(sort $(INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES))),$(words $(INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES)))
+  $(error BOARD_AVB_VBMETA_MAINLINE and BOARD_AVB_VBMETA_VENDOR cannot have duplicates)
+endif
+
 BOOT_FOOTER_ARGS := BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS
 DTBO_FOOTER_ARGS := BOARD_AVB_DTBO_ADD_HASH_FOOTER_ARGS
 SYSTEM_FOOTER_ARGS := BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS
@@ -2655,7 +2675,7 @@
 ODM_FOOTER_ARGS := BOARD_AVB_ODM_ADD_HASHTREE_FOOTER_ARGS
 
 # Helper function that checks and sets required build variables for an AVB chained partition.
-# $(1): the partition to enable AVB chain, e.g., boot or system.
+# $(1): the partition to enable AVB chain, e.g., boot or system or vbmeta_mainline.
 define _check-and-set-avb-chain-args
 $(eval part := $(1))
 $(eval PART=$(call to-upper,$(part)))
@@ -2677,20 +2697,27 @@
 $(eval INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
     --chain_partition $(part):$($(_rollback_index_location)):$(AVB_CHAIN_KEY_DIR)/$(part).avbpubkey)
 
-# Set rollback_index via footer args
-$(eval _footer_args := $(PART)_FOOTER_ARGS)
-$(eval $($(_footer_args)) += --rollback_index $($(_rollback_index)))
+# Set rollback_index via footer args for non-chained vbmeta image. Chained vbmeta image will pick up
+# the index via a separate flag (e.g. BOARD_AVB_VBMETA_MAINLINE_ROLLBACK_INDEX).
+$(if $(filter $(part),$(part:vbmeta_%=%)),\
+    $(eval _footer_args := $(PART)_FOOTER_ARGS) \
+    $(eval $($(_footer_args)) += --rollback_index $($(_rollback_index))))
 endef
 
 # Checks and sets the required build variables for an AVB partition. The partition will be
 # configured as a chained partition, if BOARD_AVB_<partition>_KEY_PATH is defined. Otherwise the
-# image descriptor will be included into vbmeta.img.
+# image descriptor will be included into vbmeta.img, unless it has been already added to any chained
+# VBMeta image.
 # $(1): Partition name, e.g. boot or system.
 define check-and-set-avb-args
+$(eval _in_chained_vbmeta := $(filter $(1),$(INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES)))
 $(if $(BOARD_AVB_$(call to-upper,$(1))_KEY_PATH),\
+    $(if $(_in_chained_vbmeta),\
+        $(error Chaining partition "$(1)" in chained VBMeta image is not supported)) \
     $(call _check-and-set-avb-chain-args,$(1)),\
-    $(eval INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
-        --include_descriptors_from_image $(call images-for-partitions,$(1))))
+    $(if $(_in_chained_vbmeta),,\
+        $(eval INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
+            --include_descriptors_from_image $(call images-for-partitions,$(1)))))
 endef
 
 ifdef INSTALLED_BOOTIMAGE_TARGET
@@ -2723,6 +2750,15 @@
 $(eval $(call check-and-set-avb-args,recovery))
 endif
 
+# Not using INSTALLED_VBMETA_MAINLINEIMAGE_TARGET as it won't be set yet.
+ifdef BOARD_AVB_VBMETA_MAINLINE
+$(eval $(call check-and-set-avb-args,vbmeta_mainline))
+endif
+
+ifdef BOARD_AVB_VBMETA_VENDOR
+$(eval $(call check-and-set-avb-args,vbmeta_vendor))
+endif
+
 # Add kernel cmdline descriptor for kernel to mount system.img as root with
 # dm-verity. This works when system.img is either chained or not-chained:
 # - chained: The --setup_as_rootfs_from_kernel option will add dm-verity kernel
@@ -2730,17 +2766,33 @@
 # - not-chained: The --include_descriptors_from_image option for make_vbmeta_image
 #   will include the kernel cmdline descriptor from system.img into vbmeta.img
 ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+ifeq ($(filter system, $(BOARD_SUPER_PARTITION_PARTITION_LIST)),)
 BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS += --setup_as_rootfs_from_kernel
 endif
+endif
 
 BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --padding_size 4096
+BOARD_AVB_MAKE_VBMETA_MAINLINE_IMAGE_ARGS += --padding_size 4096
+BOARD_AVB_MAKE_VBMETA_VENDOR_IMAGE_ARGS += --padding_size 4096
+
+ifeq (eng,$(filter eng, $(TARGET_BUILD_VARIANT)))
+BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --set_hashtree_disabled_flag
+BOARD_AVB_MAKE_VBMETA_MAINLINE_IMAGE_ARGS += --set_hashtree_disabled_flag
+BOARD_AVB_MAKE_VBMETA_VENDOR_IMAGE_ARGS += --set_hashtree_disabled_flag
+endif
 
 ifdef BOARD_AVB_ROLLBACK_INDEX
 BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --rollback_index $(BOARD_AVB_ROLLBACK_INDEX)
 endif
 
-ifeq (eng,$(filter eng, $(TARGET_BUILD_VARIANT)))
-BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --set_hashtree_disabled_flag
+ifdef BOARD_AVB_VBMETA_MAINLINE_ROLLBACK_INDEX
+BOARD_AVB_MAKE_VBMETA_MAINLINE_IMAGE_ARGS += \
+    --rollback_index $(BOARD_AVB_VBMETA_MAINLINE_ROLLBACK_INDEX)
+endif
+
+ifdef BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX
+BOARD_AVB_MAKE_VBMETA_VENDOR_IMAGE_ARGS += \
+    --rollback_index $(BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX)
 endif
 
 # $(1): the directory to extract public keys to
@@ -2769,8 +2821,50 @@
   $(if $(BOARD_AVB_RECOVERY_KEY_PATH),\
     $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_RECOVERY_KEY_PATH) \
       --output $(1)/recovery.avbpubkey)
+  $(if $(BOARD_AVB_VBMETA_MAINLINE_KEY_PATH),\
+    $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_VBMETA_MAINLINE_KEY_PATH) \
+        --output $(1)/vbmeta_mainline.avbpubkey)
+  $(if $(BOARD_AVB_VBMETA_VENDOR_KEY_PATH),\
+    $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_VBMETA_VENDOR_KEY_PATH) \
+        --output $(1)/vbmeta_vendor.avbpubkey)
 endef
 
+# Builds a chained VBMeta image. This VBMeta image will contain the descriptors for the partitions
+# specified in BOARD_AVB_VBMETA_<NAME>. The built VBMeta image will be included into the top-level
+# vbmeta image as a chained partition. For example, if a target defines `BOARD_AVB_VBMETA_MAINLINE
+# := system product_services`, `vbmeta_mainline.img` will be created that includes the descriptors
+# for `system.img` and `product_services.img`. `vbmeta_mainline.img` itself will be included into
+# `vbmeta.img` as a chained partition.
+# $(1): VBMeta image name, such as "vbmeta_mainline", "vbmeta_vendor" etc.
+# $(2): Output filename.
+define build-chained-vbmeta-image
+  $(call pretty,"Target chained vbmeta image: $@")
+  $(hide) $(AVBTOOL) make_vbmeta_image \
+      $(INTERNAL_AVB_$(call to-upper,$(1))_SIGNING_ARGS) \
+      $(BOARD_AVB_MAKE_$(call to-upper,$(1))_IMAGE_ARGS) \
+      $(foreach image,$(BOARD_AVB_$(call to-upper,$(1))), \
+          --include_descriptors_from_image $(call images-for-partitions,$(image))) \
+      --output $@
+endef
+
+ifdef BOARD_AVB_VBMETA_MAINLINE
+INSTALLED_VBMETA_MAINLINEIMAGE_TARGET := $(PRODUCT_OUT)/vbmeta_mainline.img
+$(INSTALLED_VBMETA_MAINLINEIMAGE_TARGET): \
+		$(AVBTOOL) \
+		$(call images-for-partitions,$(BOARD_AVB_VBMETA_MAINLINE)) \
+		$(BOARD_AVB_VBMETA_MAINLINE_KEY_PATH)
+	$(call build-chained-vbmeta-image,vbmeta_mainline)
+endif
+
+ifdef BOARD_AVB_VBMETA_VENDOR
+INSTALLED_VBMETA_VENDORIMAGE_TARGET := $(PRODUCT_OUT)/vbmeta_vendor.img
+$(INSTALLED_VBMETA_VENDORIMAGE_TARGET): \
+		$(AVBTOOL) \
+		$(call images-for-partitions,$(BOARD_AVB_VBMETA_VENDOR)) \
+		$(BOARD_AVB_VBMETA_VENDOR_KEY_PATH)
+	$(call build-chained-vbmeta-image,vbmeta_vendor)
+endif
+
 define build-vbmetaimage-target
   $(call pretty,"Target vbmeta image: $(INSTALLED_VBMETAIMAGE_TARGET)")
   $(hide) mkdir -p $(AVB_CHAIN_KEY_DIR)
@@ -2797,6 +2891,10 @@
 		$(INSTALLED_ODMIMAGE_TARGET) \
 		$(INSTALLED_DTBOIMAGE_TARGET) \
 		$(INSTALLED_RECOVERYIMAGE_TARGET) \
+		$(INSTALLED_VBMETA_MAINLINEIMAGE_TARGET) \
+		$(INSTALLED_VBMETA_VENDORIMAGE_TARGET) \
+		$(BOARD_AVB_VBMETA_MAINLINE_KEY_PATH) \
+		$(BOARD_AVB_VBMETA_VENDOR_KEY_PATH) \
 		$(BOARD_AVB_KEY_PATH)
 	$(build-vbmetaimage-target)
 
@@ -2892,13 +2990,15 @@
 check_android_partition_sizes:
 	partition_size_list="$(call read-size-of-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))"; \
 	sum_sizes_expr=$$(sed -e 's/ /+/g' <<< "$${partition_size_list}"); \
-	if [ $$(( $${sum_sizes_expr} )) -gt $(BOARD_SUPER_PARTITION_SIZE) ]; then \
-		echo 'The sum of sizes of all logical partitions is larger than BOARD_SUPER_PARTITION_SIZE.'; \
-		echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' $(BOARD_SUPER_PARTITION_SIZE); \
+	max_size_tail=$(if $(filter true,$(AB_OTA_UPDATER))," / 2"); \
+	max_size_expr=$(BOARD_SUPER_PARTITION_SIZE)$${max_size_tail}; \
+	if [ $$(( $${sum_sizes_expr} )) -gt $$(( $${max_size_expr} )) ]; then \
+		echo "The sum of sizes of all logical partitions is larger than BOARD_SUPER_PARTITION_SIZE$${max_size_tail}:"; \
+		echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' $${max_size_expr} '==' $$(( $${max_size_expr} )); \
 		exit 1; \
 	else \
-		echo 'The sum of sizes of all logical partitions is within BOARD_SUPER_PARTITION_SIZE:' \
-		    $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '<=' $(BOARD_SUPER_PARTITION_SIZE); \
+		echo "The sum of sizes of all logical partitions is within BOARD_SUPER_PARTITION_SIZE$${max_size_tail}:"; \
+		echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '<=' $${max_size_expr} '==' $$(( $${max_size_expr} )); \
 	fi
 
 endif # BOARD_SUPER_PARTITION_PARTITION_LIST
@@ -3047,15 +3147,15 @@
   $(sort $(shell find external/vboot_reference/tests/devkeys -type f))
 endif
 
-$(BUILT_OTATOOLS_PACKAGE): $(OTATOOLS) $(OTATOOLS_DEPS) $(OTATOOLS_RELEASETOOLS) | $(ACP)
+$(BUILT_OTATOOLS_PACKAGE): $(OTATOOLS) $(OTATOOLS_DEPS) $(OTATOOLS_RELEASETOOLS) $(SOONG_ZIP)
 	@echo "Package OTA tools: $@"
 	$(hide) rm -rf $@ $(zip_root)
 	$(hide) mkdir -p $(dir $@) $(zip_root)/bin $(zip_root)/framework $(zip_root)/releasetools
 	$(call copy-files-with-structure,$(OTATOOLS),$(HOST_OUT)/,$(zip_root))
-	$(hide) $(ACP) -r -d -p build/make/tools/releasetools/* $(zip_root)/releasetools
+	$(hide) cp -r -d -p build/make/tools/releasetools/* $(zip_root)/releasetools
 	$(hide) rm -rf $@ $(zip_root)/releasetools/*.pyc
-	$(hide) (cd $(zip_root) && zip -qryX $(abspath $@) *)
-	$(hide) echo $(OTATOOLS_DEPS) | xargs zip -qryX $(abspath $@)>/dev/null || true
+	$(hide) $(SOONG_ZIP) -o $@ -C $(zip_root) -D $(zip_root) \
+	  -C . $(addprefix -f ,$(OTATOOLS_DEPS))
 
 .PHONY: otatools-package
 otatools-package: $(BUILT_OTATOOLS_PACKAGE)
@@ -3372,6 +3472,20 @@
 	$(hide) echo "avb_recovery_algorithm=$(BOARD_AVB_RECOVERY_ALGORITHM)" >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "avb_recovery_rollback_index_location=$(BOARD_AVB_RECOVERY_ROLLBACK_INDEX_LOCATION)" >> $(zip_root)/META/misc_info.txt
 endif # BOARD_AVB_RECOVERY_KEY_PATH
+ifneq (,$(strip $(BOARD_AVB_VBMETA_MAINLINE)))
+	$(hide) echo "avb_vbmeta_mainline=$(BOARD_AVB_VBMETA_MAINLINE)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "avb_vbmeta_mainline_args=$(BOARD_AVB_MAKE_VBMETA_MAINLINE_IMAGE_ARGS)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "avb_vbmeta_mainline_key_path=$(BOARD_AVB_VBMETA_MAINLINE_KEY_PATH)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "avb_vbmeta_mainline_algorithm=$(BOARD_AVB_VBMETA_MAINLINE_ALGORITHM)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "avb_vbmeta_mainline_rollback_index_location=$(BOARD_AVB_VBMETA_MAINLINE_ROLLBACK_INDEX_LOCATION)" >> $(zip_root)/META/misc_info.txt
+endif # BOARD_AVB_VBMETA_MAINLINE
+ifneq (,$(strip $(BOARD_AVB_VBMETA_VENDOR)))
+	$(hide) echo "avb_vbmeta_vendor=$(BOARD_AVB_VBMETA_VENDOR)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "avb_vbmeta_vendor_args=$(BOARD_AVB_MAKE_VBMETA_MAINLINE_IMAGE_ARGS)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "avb_vbmeta_vendor_key_path=$(BOARD_AVB_VBMETA_VENDOR_KEY_PATH)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "avb_vbmeta_vendor_algorithm=$(BOARD_AVB_VBMETA_VENDOR_ALGORITHM)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "avb_vbmeta_vendor_rollback_index_location=$(BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION)" >> $(zip_root)/META/misc_info.txt
+endif # BOARD_AVB_VBMETA_VENDOR_KEY_PATH
 endif # BOARD_AVB_ENABLE
 ifdef BOARD_BPT_INPUT_FILES
 	$(hide) echo "board_bpt_enable=true" >> $(zip_root)/META/misc_info.txt
@@ -3465,12 +3579,12 @@
 endif
 	@# ROOT always contains the files for the root under normal boot.
 	$(hide) $(call fs_config,$(zip_root)/ROOT,) > $(zip_root)/META/root_filesystem_config.txt
-ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
-	@# BOOT/RAMDISK exists only if additionally using BOARD_USES_RECOVERY_AS_BOOT.
 ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+	@# BOOT/RAMDISK exists and contains the ramdisk for recovery if using BOARD_USES_RECOVERY_AS_BOOT.
 	$(hide) $(call fs_config,$(zip_root)/BOOT/RAMDISK,) > $(zip_root)/META/boot_filesystem_config.txt
 endif
-else # BOARD_BUILD_SYSTEM_ROOT_IMAGE != true
+ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+	@# BOOT/RAMDISK also exists and contains the first stage ramdisk if not using BOARD_BUILD_SYSTEM_ROOT_IMAGE.
 	$(hide) $(call fs_config,$(zip_root)/BOOT/RAMDISK,) > $(zip_root)/META/boot_filesystem_config.txt
 endif
 ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
@@ -3772,6 +3886,18 @@
 odmimage: $(INSTALLED_QEMU_ODMIMAGE)
 droidcore: $(INSTALLED_QEMU_ODMIMAGE)
 endif
+
+ifeq ($(BOARD_AVB_ENABLE),true)
+QEMU_VERIFIED_BOOT_PARAMS := $(PRODUCT_OUT)/VerifiedBootParams.textproto
+MK_VERIFIED_BOOT_KERNEL_CMDLINE_SH := device/generic/goldfish/tools/mk_verified_boot_params.sh
+$(QEMU_VERIFIED_BOOT_PARAMS): $(INSTALLED_QEMU_SYSTEMIMAGE) $(MK_VERIFIED_BOOT_KERNEL_CMDLINE_SH) $(INSTALLED_VBMETAIMAGE_TARGET) $(SGDISK_HOST) $(AVBTOOL)
+	@echo Creating $@
+	(export SGDISK=$(SGDISK_HOST) AVBTOOL=$(AVBTOOL); $(MK_VERIFIED_BOOT_KERNEL_CMDLINE_SH) $(INSTALLED_SYSTEMIMAGE_TARGET) $(INSTALLED_QEMU_SYSTEMIMAGE) $(QEMU_VERIFIED_BOOT_PARAMS))
+
+
+systemimage: $(QEMU_VERIFIED_BOOT_PARAMS)
+droidcore: $(QEMU_VERIFIED_BOOT_PARAMS)
+endif
 endif
 # -----------------------------------------------------------------
 # The emulator package
@@ -3872,6 +3998,7 @@
 	$(INSTALLED_SYSTEMIMAGE_TARGET) \
 	$(INSTALLED_QEMU_SYSTEMIMAGE) \
 	$(INSTALLED_QEMU_VENDORIMAGE) \
+	$(QEMU_VERIFIED_BOOT_PARAMS) \
 	$(INSTALLED_USERDATAIMAGE_TARGET) \
 	$(INSTALLED_RAMDISK_TARGET) \
 	$(INSTALLED_SDK_BUILD_PROP_TARGET) \
diff --git a/core/apicheck_msg_current.txt b/core/apicheck_msg_current.txt
deleted file mode 100644
index 440e7f8..0000000
--- a/core/apicheck_msg_current.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-
-******************************
-You have tried to change the API from what has been previously approved.
-
-To make these errors go away, you have two choices:
-   1) You can add "@hide" javadoc comments to the methods, etc. listed in the
-      errors above.
-
-   2) You can update current.txt by executing the following command:
-         make update-api
-
-      To submit the revised current.txt to the main Android repository,
-      you will need approval.
-******************************
-
-
-
diff --git a/core/apicheck_msg_last.txt b/core/apicheck_msg_last.txt
deleted file mode 100644
index 2993157..0000000
--- a/core/apicheck_msg_last.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-
-******************************
-You have tried to change the API from what has been previously released in
-an SDK.  Please fix the errors listed above.
-******************************
-
-
diff --git a/core/apidiff.mk b/core/apidiff.mk
deleted file mode 100644
index 8887ea4..0000000
--- a/core/apidiff.mk
+++ /dev/null
@@ -1,180 +0,0 @@
-#
-# 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.
-#
-
-##
-##
-## Common to both jdiff and javadoc
-##
-##
-
-LOCAL_IS_HOST_MODULE := $(call true-or-empty,$(LOCAL_IS_HOST_MODULE))
-ifeq ($(LOCAL_IS_HOST_MODULE),true)
-my_prefix := HOST_
-LOCAL_HOST_PREFIX :=
-else
-my_prefix := TARGET_
-endif
-
-LOCAL_MODULE_CLASS := $(strip $(LOCAL_MODULE_CLASS))
-ifndef LOCAL_MODULE_CLASS
-$(error $(LOCAL_PATH): LOCAL_MODULE_CLASS not defined)
-endif
-
-full_src_files := $(patsubst %,$(LOCAL_PATH)/%,$(LOCAL_SRC_FILES))
-out_dir := $(OUT_DOCS)/$(LOCAL_MODULE)/api_diff/current
-full_target := $(call doc-timestamp-for,$(LOCAL_MODULE)-diff)
-
-ifeq ($(LOCAL_IS_HOST_MODULE),true)
-$(full_target): PRIVATE_BOOTCLASSPATH :=
-full_java_libs := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/,\
-  $(addsuffix $(COMMON_JAVA_PACKAGE_SUFFIX),$(LOCAL_JAVA_LIBRARIES)))
-full_java_lib_deps := $(full_java_libs)
-
-else
-
-ifneq ($(LOCAL_SDK_VERSION),)
-  ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),current)
-    # Use android_stubs_current if LOCAL_SDK_VERSION is current and no TARGET_BUILD_APPS.
-    LOCAL_JAVA_LIBRARIES := android_stubs_current $(LOCAL_JAVA_LIBRARIES)
-    $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, android_stubs_current)
-  else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),system_current)
-    LOCAL_JAVA_LIBRARIES := android_system_stubs_current $(LOCAL_JAVA_LIBRARIES)
-    $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, android_system_stubs_current)
-  else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),test_current)
-    LOCAL_JAVA_LIBRARIES := android_test_stubs_current $(LOCAL_JAVA_LIBRARIES)
-    $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, android_test_stubs_current)
-  else
-    # TARGET_BUILD_APPS is set. Use the modules defined in prebuilts/sdk/Android.mk.
-    _module_name := $(call resolve-prebuilt-sdk-module,$(LOCAL_SDK_VERSION))
-    LOCAL_JAVA_LIBRARIES := $(_module_name) $(LOCAL_JAVA_LIBRARIES)
-    $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, $(_module_name))
-    _module_name :=
-  endif
-else
-  LOCAL_JAVA_LIBRARIES := core-oj core-libart core-simple ext framework $(LOCAL_JAVA_LIBRARIES)
-  $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, core-oj):$(call java-lib-files, core-libart):$(call java-lib-files, core-simple)
-endif  # LOCAL_SDK_VERSION
-LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
-
-full_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES)) $(LOCAL_CLASSPATH)
-full_java_lib_deps := $(call java-lib-deps,$(LOCAL_JAVA_LIBRARIES)) $(LOCAL_CLASSPATH)
-endif # !LOCAL_IS_HOST_MODULE
-
-$(full_target): PRIVATE_CLASSPATH := $(subst $(space),:,$(full_java_libs))
-$(full_target): PRIVATE_DOCLAVA_CLASSPATH := $(HOST_OUT_JAVA_LIBRARIES)/jsilver$(COMMON_JAVA_PACKAGE_SUFFIX):$(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX)
-
-intermediates.COMMON := $(call local-intermediates-dir,COMMON)
-
-$(full_target): PRIVATE_SOURCE_PATH := $(call normalize-path-list,$(LOCAL_DROIDDOC_SOURCE_PATH))
-$(full_target): PRIVATE_JAVA_FILES := $(filter %.java,$(full_src_files))
-$(full_target): PRIVATE_JAVA_FILES += $(addprefix $($(my_prefix)OUT_COMMON_INTERMEDIATES)/, $(filter %.java,$(LOCAL_INTERMEDIATE_SOURCES)))
-$(full_target): PRIVATE_SOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/src
-$(full_target): PRIVATE_SRC_LIST_FILE := $(intermediates.COMMON)/droiddoc-src-list
-
-ifneq ($(strip $(LOCAL_ADDITIONAL_JAVA_DIR)),)
-$(full_target): PRIVATE_ADDITIONAL_JAVA_DIR := $(LOCAL_ADDITIONAL_JAVA_DIR)
-endif
-
-# Lists the input files for the doc build into a text file
-# suitable for the @ syntax of javadoc.
-# $(1): the file to create
-# $(2): files to include
-# $(3): list of directories to search for java files in
-define prepare-doc-source-list
-$(hide) mkdir -p $(dir $(1))
-$(call dump-words-to-file, $(2), $(1))
-$(hide) for d in $(3) ; do find $$d -name '*.java' -and -not -name '.*' >> $(1) 2> /dev/null ; done ; true
-endef
-
-##
-##
-## jdiff only
-##
-##
-
-jdiff := \
-	$(HOST_JDK_TOOLS_JAR) \
-	$(HOST_OUT_JAVA_LIBRARIES)/jdiff$(COMMON_JAVA_PACKAGE_SUFFIX)
-
-doclava := \
-	$(HOST_JDK_TOOLS_JAR) \
-	$(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX)
-
-$(full_target): PRIVATE_NEWAPI := $(LOCAL_APIDIFF_NEWAPI)
-$(full_target): PRIVATE_OLDAPI := $(LOCAL_APIDIFF_OLDAPI)
-$(full_target): PRIVATE_OUT_DIR := $(out_dir)
-$(full_target): PRIVATE_OUT_NEWAPI := $(out_dir)/current.xml
-$(full_target): PRIVATE_OUT_OLDAPI := $(out_dir)/$(notdir $(basename $(LOCAL_APIDIFF_OLDAPI))).xml
-$(full_target): PRIVATE_DOCLETPATH := $(HOST_OUT_JAVA_LIBRARIES)/jdiff$(COMMON_JAVA_PACKAGE_SUFFIX)
-$(full_target): \
-		$(full_src_files) \
-		$(full_java_lib_deps) \
-		$(jdiff) \
-		$(doclava) \
-		$(OUT_DOCS)/$(LOCAL_MODULE)-docs-stubs.srcjar \
-		$(LOCAL_ADDITIONAL_DEPENDENCIES)
-	@echo Generating API diff: $(PRIVATE_OUT_DIR)
-	@echo   Old API: $(PRIVATE_OLDAPI)
-	@echo   New API: $(PRIVATE_NEWAPI)
-	@echo   Old XML: $(PRIVATE_OUT_OLDAPI)
-	@echo   New XML: $(PRIVATE_OUT_NEWAPI)
-	$(hide) mkdir -p $(dir $@)
-	@echo Converting API files to XML...
-	$(hide) mkdir -p $(PRIVATE_OUT_DIR)
-	$(hide) ( \
-		$(JAVA) \
-				$(addprefix -classpath ,$(PRIVATE_CLASSPATH):$(PRIVATE_DOCLAVA_CLASSPATH):$(PRIVATE_BOOTCLASSPATH):$(HOST_JDK_TOOLS_JAR)) \
-				com.google.doclava.apicheck.ApiCheck \
-				-convert2xml \
-					$(basename $(PRIVATE_NEWAPI)).txt \
-					$(basename $(PRIVATE_OUT_NEWAPI)).xml \
-	) || (rm -rf $(PRIVATE_OUT_DIR) $(PRIVATE_SRC_LIST_FILE); exit 45)
-	$(hide) ( \
-		$(JAVA) \
-				$(addprefix -classpath ,$(PRIVATE_CLASSPATH):$(PRIVATE_DOCLAVA_CLASSPATH):$(PRIVATE_BOOTCLASSPATH):$(HOST_JDK_TOOLS_JAR)) \
-				com.google.doclava.apicheck.ApiCheck \
-				-convert2xml \
-					$(basename $(PRIVATE_OLDAPI)).txt \
-					$(basename $(PRIVATE_OUT_OLDAPI)).xml \
-	) || (rm -rf $(PRIVATE_OUT_DIR) $(PRIVATE_SRC_LIST_FILE); exit 45)
-	@echo Running JDiff...
-	$(call prepare-doc-source-list,$(PRIVATE_SRC_LIST_FILE),$(PRIVATE_JAVA_FILES), \
-			$(PRIVATE_SOURCE_INTERMEDIATES_DIR) $(PRIVATE_ADDITIONAL_JAVA_DIR))
-	$(hide) ( \
-		$(JAVADOC) \
-				-encoding UTF-8 \
-				\@$(PRIVATE_SRC_LIST_FILE) \
-				-J-Xmx1600m \
-				-XDignore.symbol.file \
-				-quiet \
-				-doclet jdiff.JDiff \
-				-docletpath $(PRIVATE_DOCLETPATH) \
-				$(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH)) \
-				$(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
-				-sourcepath $(PRIVATE_SOURCE_PATH)$(addprefix :,$(PRIVATE_CLASSPATH)) \
-				-d $(PRIVATE_OUT_DIR) \
-				-newapi $(notdir $(basename $(PRIVATE_OUT_NEWAPI))) \
-				-newapidir $(dir $(PRIVATE_OUT_NEWAPI)) \
-				-oldapi $(notdir $(basename $(PRIVATE_OUT_OLDAPI))) \
-				-oldapidir $(dir $(PRIVATE_OUT_OLDAPI)) \
-				-javadocnew ../../../reference/ \
-		&& touch -f $@ \
-	) || (rm -rf $(PRIVATE_OUT_DIR) $(PRIVATE_SRC_LIST_FILE); exit 45)
-
-ALL_DOCS += $(full_target)
-
-.PHONY: $(LOCAL_MODULE)-diff
-$(LOCAL_MODULE)-diff : $(full_target)
diff --git a/core/aux_config.mk b/core/aux_config.mk
index 6a5cd63..d382ff5 100644
--- a/core/aux_config.mk
+++ b/core/aux_config.mk
@@ -47,7 +47,6 @@
 $(eval AUX_OUT_INTERMEDIATES_$(1) := $(AUX_OUT_$(1))/obj) \
 $(eval AUX_OUT_COMMON_INTERMEDIATES_$(1) := $(AUX_COMMON_OUT_ROOT_$(1))/obj) \
 $(eval AUX_OUT_HEADERS_$(1) := $(AUX_OUT_INTERMEDIATES_$(1))/include) \
-$(eval AUX_OUT_INTERMEDIATE_LIBRARIES_$(1) := $(AUX_OUT_INTERMEDIATES_$(1))/lib) \
 $(eval AUX_OUT_NOTICE_FILES_$(1) := $(AUX_OUT_INTERMEDIATES_$(1))/NOTICE_FILES) \
 $(eval AUX_OUT_FAKE_$(1) := $(AUX_OUT_$(1))/fake_packages) \
 $(eval AUX_OUT_GEN_$(1) := $(AUX_OUT_$(1))/gen) \
@@ -78,7 +77,6 @@
 $(eval AUX_OUT_INTERMEDIATES := $(AUX_OUT_INTERMEDIATES_$(1))) \
 $(eval AUX_OUT_COMMON_INTERMEDIATES := $(AUX_OUT_COMMON_INTERMEDIATES_$(1))) \
 $(eval AUX_OUT_HEADERS := $(AUX_OUT_HEADERS_$(1))) \
-$(eval AUX_OUT_INTERMEDIATE_LIBRARIES := $(AUX_OUT_INTERMEDIATE_LIBRARIES_$(1))) \
 $(eval AUX_OUT_NOTICE_FILES := $(AUX_OUT_NOTICE_FILES_$(1))) \
 $(eval AUX_OUT_FAKE := $(AUX_OUT_FAKE_$(1))) \
 $(eval AUX_OUT_GEN := $(AUX_OUT_GEN_$(1))) \
diff --git a/core/aux_executable.mk b/core/aux_executable.mk
index daf30e7..5395e61 100644
--- a/core/aux_executable.mk
+++ b/core/aux_executable.mk
@@ -80,7 +80,6 @@
     $(linked_module) \
 
 # Define PRIVATE_ variables from global vars
-$(linked_module): PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES := $(AUX_OUT_INTERMEDIATE_LIBRARIES)
 $(linked_module): PRIVATE_POST_LINK_CMD := $(LOCAL_POST_LINK_CMD)
 
 ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
diff --git a/core/base_rules.mk b/core/base_rules.mk
index fce7a1f..fcc8ede 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -295,16 +295,6 @@
 
 LOCAL_BUILT_MODULE := $(intermediates)/$(my_built_module_stem)
 
-# OVERRIDE_BUILT_MODULE_PATH is only allowed to be used by the
-# internal SHARED_LIBRARIES build files.
-OVERRIDE_BUILT_MODULE_PATH := $(strip $(OVERRIDE_BUILT_MODULE_PATH))
-ifdef OVERRIDE_BUILT_MODULE_PATH
-  ifneq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
-    $(error $(LOCAL_PATH): Illegal use of OVERRIDE_BUILT_MODULE_PATH)
-  endif
-  $(eval $(call copy-one-file,$(LOCAL_BUILT_MODULE),$(OVERRIDE_BUILT_MODULE_PATH)/$(my_built_module_stem)))
-endif
-
 ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
   # Apk and its attachments reside in its own subdir.
   ifeq ($(LOCAL_MODULE_CLASS),APPS)
@@ -328,7 +318,11 @@
 # As .KATI_RESTAT is specified to .toc files and commit-change-for-toc is used,
 # dependent binaries of a .toc file will be rebuilt only when the content of
 # the .toc file is changed.
+#
+# Don't create .toc files for Soong shared libraries, that is handled in
+# Soong and soong_cc_prebuilt.mk
 ###########################################################
+ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
 ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
 LOCAL_INTERMEDIATE_TARGETS += $(LOCAL_BUILT_MODULE).toc
 $(LOCAL_BUILT_MODULE).toc: $(LOCAL_BUILT_MODULE)
@@ -339,10 +333,6 @@
 .KATI_RESTAT: $(LOCAL_BUILT_MODULE).toc
 # Build .toc file when using mm, mma, or make $(my_register_name)
 $(my_all_targets): $(LOCAL_BUILT_MODULE).toc
-
-ifdef OVERRIDE_BUILT_MODULE_PATH
-$(eval $(call copy-one-file,$(LOCAL_BUILT_MODULE).toc,$(OVERRIDE_BUILT_MODULE_PATH)/$(my_built_module_stem).toc))
-$(OVERRIDE_BUILT_MODULE_PATH)/$(my_built_module_stem).toc: $(OVERRIDE_BUILT_MODULE_PATH)/$(my_built_module_stem)
 endif
 endif
 
@@ -769,6 +759,8 @@
 ALL_MODULES.$(my_register_name).MODULE_NAME := $(LOCAL_MODULE)
 ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES := $(LOCAL_COMPATIBILITY_SUITE)
 ALL_MODULES.$(my_register_name).TEST_CONFIG := $(test_config)
+ALL_MODULES.$(my_register_name).SRCS := \
+    $(ALL_MODULES.$(my_register_name).SRCS) $(LOCAL_SRC_FILES)
 test_config :=
 
 INSTALLABLE_FILES.$(LOCAL_INSTALLED_MODULE).MODULE := $(my_register_name)
diff --git a/core/binary.mk b/core/binary.mk
index 2ccdb41..b8ee423 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -281,13 +281,18 @@
 # all code is position independent, and then those warnings get promoted to
 # errors.
 ifneq ($(LOCAL_NO_PIC),true)
-ifneq ($($(my_prefix)OS),windows)
-ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
-my_cflags += -fPIE
-else
-my_cflags += -fPIC
-endif
-endif
+  ifneq ($($(my_prefix)OS),windows)
+    ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
+      my_cflags += -fPIE
+      ifndef BUILD_HOST_static
+        ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+          my_ldflags += -pie
+        endif
+      endif
+    else
+      my_cflags += -fPIC
+    endif
+  endif
 endif
 
 ifdef LOCAL_IS_HOST_MODULE
@@ -372,10 +377,7 @@
 my_whole_static_libraries := $(LOCAL_WHOLE_STATIC_LIBRARIES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_WHOLE_STATIC_LIBRARIES_$(my_32_64_bit_suffix)) $(my_whole_static_libraries)
 my_header_libraries := $(LOCAL_HEADER_LIBRARIES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_HEADER_LIBRARIES_$(my_32_64_bit_suffix)) $(my_header_libraries)
 
-# soong defined modules already have done through this
-ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
 include $(BUILD_SYSTEM)/cxx_stl_setup.mk
-endif
 
 # Add static HAL libraries
 ifdef LOCAL_HAL_STATIC_LIBRARIES
@@ -392,8 +394,6 @@
   my_linker := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)LINKER)
 endif
 
-# Modules from soong do not need this since the dependencies are already handled there.
-ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
 include $(BUILD_SYSTEM)/config_sanitizers.mk
 
 ifneq ($(LOCAL_NO_LIBCOMPILER_RT),true)
@@ -407,7 +407,6 @@
 ifeq ($($(my_prefix)OS),windows)
   my_static_libraries += libwinpthread
 endif
-endif # this module is not from soong
 
 ifneq ($(filter ../%,$(my_src_files)),)
 my_soong_problems += dotdot_srcs
@@ -1270,29 +1269,23 @@
   ## switch all soong libraries over to the /vendor
   ## variant.
   ####################################################
-  ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-    # We don't do this renaming for soong-defined modules since they already have correct
-    # names (with .vendor suffix when necessary) in their LOCAL_*_LIBRARIES.
-    my_whole_static_libraries := $(foreach l,$(my_whole_static_libraries),\
-      $(if $(SPLIT_VENDOR.STATIC_LIBRARIES.$(l)),$(l).vendor,$(l)))
-    my_static_libraries := $(foreach l,$(my_static_libraries),\
-      $(if $(SPLIT_VENDOR.STATIC_LIBRARIES.$(l)),$(l).vendor,$(l)))
-    my_shared_libraries := $(foreach l,$(my_shared_libraries),\
-      $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
-    my_system_shared_libraries := $(foreach l,$(my_system_shared_libraries),\
-      $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
-    my_header_libraries := $(foreach l,$(my_header_libraries),\
-      $(if $(SPLIT_VENDOR.HEADER_LIBRARIES.$(l)),$(l).vendor,$(l)))
-  endif
+  my_whole_static_libraries := $(foreach l,$(my_whole_static_libraries),\
+    $(if $(SPLIT_VENDOR.STATIC_LIBRARIES.$(l)),$(l).vendor,$(l)))
+  my_static_libraries := $(foreach l,$(my_static_libraries),\
+    $(if $(SPLIT_VENDOR.STATIC_LIBRARIES.$(l)),$(l).vendor,$(l)))
+  my_shared_libraries := $(foreach l,$(my_shared_libraries),\
+    $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
+  my_system_shared_libraries := $(foreach l,$(my_system_shared_libraries),\
+    $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
+  my_header_libraries := $(foreach l,$(my_header_libraries),\
+    $(if $(SPLIT_VENDOR.HEADER_LIBRARIES.$(l)),$(l).vendor,$(l)))
 endif
 
 # Platform can use vendor public libraries. If a required shared lib is one of
 # the vendor public libraries, the lib is switched to the stub version of the lib.
 ifeq ($(LOCAL_USE_VNDK),)
-  ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-    my_shared_libraries := $(foreach l,$(my_shared_libraries),\
-      $(if $(filter $(l),$(VENDOR_PUBLIC_LIBRARIES)),$(l).vendorpublic,$(l)))
-  endif
+  my_shared_libraries := $(foreach l,$(my_shared_libraries),\
+    $(if $(filter $(l),$(VENDOR_PUBLIC_LIBRARIES)),$(l).vendorpublic,$(l)))
 endif
 
 ##########################################################
@@ -1372,7 +1365,7 @@
         my_warn_types :=
         my_allowed_types := native:vendor native:vndk
     endif
-else ifneq ($(filter $(TARGET_RECOVERY_OUT)/%,$(LOCAL_MODULE_PATH)),)
+else ifneq ($(filter $(TARGET_RECOVERY_OUT)/%,$(call get_non_asan_path,$(LOCAL_MODULE_PATH))),)
 my_link_type := native:recovery
 my_warn_types :=
 # TODO(b/113303515) remove native:platform and my_allowed_ndk_types
@@ -1492,9 +1485,9 @@
 
 ifneq ($(LOCAL_SDK_VERSION),)
 built_shared_libraries := \
-    $(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
-      $(addsuffix $(so_suffix), \
-        $(my_shared_libraries)))
+    $(foreach lib,$(my_shared_libraries), \
+      $(call intermediates-dir-for, \
+        SHARED_LIBRARIES,$(lib),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/$(lib)$(so_suffix))
 built_shared_library_deps := $(addsuffix .toc, $(built_shared_libraries))
 
 # Add the NDK libraries to the built module dependency
@@ -1518,9 +1511,9 @@
 
 else
 built_shared_libraries := \
-    $(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
-      $(addsuffix $(so_suffix), \
-        $(installed_shared_library_module_names)))
+    $(foreach lib,$(installed_shared_library_module_names), \
+      $(call intermediates-dir-for, \
+        SHARED_LIBRARIES,$(lib),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/$(lib)$(so_suffix))
 built_shared_library_deps := $(addsuffix .toc, $(built_shared_libraries))
 my_system_shared_libraries_fullpath :=
 endif
@@ -1613,26 +1606,23 @@
 endif
 
 # Check if -Werror or -Wno-error is used in C compiler flags.
-# Modules defined in $(SOONG_ANDROID_MK) are checked in soong's cc.go.
-ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-  # Header libraries do not need cflags.
-  ifneq (HEADER_LIBRARIES,$(LOCAL_MODULE_CLASS))
-    # Prebuilt modules do not need cflags.
-    ifeq (,$(LOCAL_PREBUILT_MODULE_FILE))
-      my_all_cflags := $(my_cflags) $(my_cppflags) $(my_cflags_no_override)
-      # Issue warning if -Wno-error is used.
-      ifneq (,$(filter -Wno-error,$(my_all_cflags)))
-        $(eval MODULES_USING_WNO_ERROR := $(MODULES_USING_WNO_ERROR) $(LOCAL_MODULE_MAKEFILE):$(LOCAL_MODULE))
-      else
-        # Issue warning if -Werror is not used. Add it.
-        ifeq (,$(filter -Werror,$(my_all_cflags)))
-          # Add -Wall -Werror unless the project is in the WARNING_ALLOWED project list.
-          ifeq (,$(strip $(call find_warning_allowed_projects,$(LOCAL_PATH))))
-            my_cflags := -Wall -Werror $(my_cflags)
-          else
-            $(eval MODULES_ADDED_WALL := $(MODULES_ADDED_WALL) $(LOCAL_MODULE_MAKEFILE):$(LOCAL_MODULE))
-            my_cflags := -Wall $(my_cflags)
-          endif
+# Header libraries do not need cflags.
+ifneq (HEADER_LIBRARIES,$(LOCAL_MODULE_CLASS))
+  # Prebuilt modules do not need cflags.
+  ifeq (,$(LOCAL_PREBUILT_MODULE_FILE))
+    my_all_cflags := $(my_cflags) $(my_cppflags) $(my_cflags_no_override)
+    # Issue warning if -Wno-error is used.
+    ifneq (,$(filter -Wno-error,$(my_all_cflags)))
+      $(eval MODULES_USING_WNO_ERROR := $(MODULES_USING_WNO_ERROR) $(LOCAL_MODULE_MAKEFILE):$(LOCAL_MODULE))
+    else
+      # Issue warning if -Werror is not used. Add it.
+      ifeq (,$(filter -Werror,$(my_all_cflags)))
+        # Add -Wall -Werror unless the project is in the WARNING_ALLOWED project list.
+        ifeq (,$(strip $(call find_warning_allowed_projects,$(LOCAL_PATH))))
+          my_cflags := -Wall -Werror $(my_cflags)
+        else
+          $(eval MODULES_ADDED_WALL := $(MODULES_ADDED_WALL) $(LOCAL_MODULE_MAKEFILE):$(LOCAL_MODULE))
+          my_cflags := -Wall $(my_cflags)
         endif
       endif
     endif
@@ -1664,7 +1654,7 @@
   ifneq ($(LOCAL_TIDY_CHECKS),)
     my_tidy_checks := $(my_tidy_checks),$(LOCAL_TIDY_CHECKS)
   endif
-  my_tidy_flags += $(WITH_TIDY_FLAGS) $(LOCAL_TIDY_FLAGS)
+  my_tidy_flags := $(strip $(WITH_TIDY_FLAGS) $(LOCAL_TIDY_FLAGS))
   # If tidy flags are not specified, default to check all header files.
   ifeq ($(my_tidy_flags),)
     my_tidy_flags := $(call default_tidy_header_filter,$(LOCAL_PATH))
@@ -1764,12 +1754,6 @@
 ###########################################################
 export_includes := $(intermediates)/export_includes
 export_cflags := $(foreach d,$(my_export_c_include_dirs),-I $(d))
-# Soong exports cflags instead of include dirs, so that -isystem can be included.
-ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-export_cflags += $(LOCAL_EXPORT_CFLAGS)
-else ifdef LOCAL_EXPORT_CFLAGS
-$(call pretty-error,LOCAL_EXPORT_CFLAGS can only be used by Soong, use LOCAL_EXPORT_C_INCLUDE_DIRS instead)
-endif
 $(export_includes): PRIVATE_EXPORT_CFLAGS := $(export_cflags)
 # Headers exported by whole static libraries are also exported by this library.
 export_include_deps := $(strip \
@@ -1814,7 +1798,6 @@
 # Make sure export_includes gets generated when you are running mm/mmm
 $(LOCAL_BUILT_MODULE) : | $(export_includes)
 
-ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
 ifneq (,$(filter-out $(LOCAL_PATH)/%,$(my_export_c_include_dirs)))
 my_soong_problems += non_local__export_c_include_dirs
 endif
@@ -1830,7 +1813,6 @@
         $(my_system_shared_libraries))
 SOONG_CONV.$(LOCAL_MODULE).TYPE := native
 SOONG_CONV := $(SOONG_CONV) $(LOCAL_MODULE)
-endif
 
 ###########################################################
 # Coverage packaging.
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 07c7e51..5aa27ca 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -3,6 +3,7 @@
 ###########################################################
 
 # '',true
+LOCAL_2ND_ARCH_VAR_PREFIX:=
 LOCAL_32_BIT_ONLY:=
 LOCAL_AAPT2_ONLY:=
 LOCAL_AAPT_FLAGS:=
@@ -42,7 +43,6 @@
 LOCAL_CONLYFLAGS:=
 LOCAL_COPY_HEADERS:=
 LOCAL_COPY_HEADERS_TO:=
-LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES:=
 LOCAL_CPP_EXTENSION:=
 LOCAL_CPPFLAGS:=
 LOCAL_CPP_STD:=
@@ -66,13 +66,18 @@
 LOCAL_DONT_MERGE_MANIFESTS:=
 LOCAL_DPI_FILE_STEM:=
 LOCAL_DPI_VARIANTS:=
+LOCAL_DROIDDOC_ANNOTATIONS_ZIP :=
+LOCAL_DROIDDOC_API_VERSIONS_XML :=
 LOCAL_DROIDDOC_ASSET_DIR:=
 LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=
+LOCAL_DROIDDOC_DOC_ZIP :=
+LOCAL_DROIDDOC_JDIFF_DOC_ZIP :=
 LOCAL_DROIDDOC_HTML_DIR:=
 LOCAL_DROIDDOC_OPTIONS:=
 LOCAL_DROIDDOC_SOURCE_PATH:=
 LOCAL_DROIDDOC_STUB_OUT_DIR:=
+LOCAL_DROIDDOC_STUBS_SRCJAR :=
 LOCAL_DROIDDOC_TEMPLATE_DIR:=
 LOCAL_DROIDDOC_USE_STANDARD_DOCLET:=
 LOCAL_DX_FLAGS:=
@@ -107,6 +112,7 @@
 LOCAL_GTEST:=true
 LOCAL_HAL_STATIC_LIBRARIES:=
 LOCAL_HEADER_LIBRARIES:=
+LOCAL_HOST_PREFIX:=
 LOCAL_HOST_REQUIRED_MODULES:=
 LOCAL_INIT_RC:=
 LOCAL_INSTALLED_MODULE:=
@@ -252,13 +258,13 @@
 LOCAL_SOONG_EXPORT_PROGUARD_FLAGS :=
 LOCAL_SOONG_HEADER_JAR :=
 LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=
+LOCAL_SOONG_LINK_TYPE :=
 LOCAL_SOONG_PROGUARD_DICT :=
 LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=
 LOCAL_SOONG_RRO_DIRS :=
 LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=
-LOCAL_DROIDDOC_STUBS_SRCJAR :=
-LOCAL_DROIDDOC_DOC_ZIP :=
-LOCAL_DROIDDOC_ANNOTATIONS_ZIP :=
+LOCAL_SOONG_TOC :=
+LOCAL_SOONG_UNSTRIPPED_BINARY :=
 # '',true
 LOCAL_SOURCE_FILES_ALL_GENERATED:=
 LOCAL_SRC_FILES:=
@@ -292,6 +298,7 @@
 LOCAL_WARNINGS_ENABLE:=
 LOCAL_WHOLE_STATIC_LIBRARIES:=
 LOCAL_YACCFLAGS:=
+# TODO: deprecate, it does nothing
 OVERRIDE_BUILT_MODULE_PATH:=
 
 # arch specific variables
diff --git a/core/config.mk b/core/config.mk
index b114462..483bc77 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -48,19 +48,6 @@
 # Prevent accidentally changing these variables
 .KATI_READONLY := SHELL empty space comma newline pound backslash
 
-# this turns off the suffix rules built into make
-.SUFFIXES:
-
-# this turns off the RCS / SCCS implicit rules of GNU Make
-% : RCS/%,v
-% : RCS/%
-% : %,v
-% : s.%
-% : SCCS/s.%
-
-# If a rule fails, delete $@.
-.DELETE_ON_ERROR:
-
 # Mark variables that should be coming as environment variables from soong_ui
 # as readonly
 .KATI_READONLY := OUT_DIR TMPDIR BUILD_DATETIME_FILE
@@ -85,6 +72,7 @@
 $(KATI_obsolete_var PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE,Set FCM Version in device manifest instead. See $(CHANGES_URL)#PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE)
 $(KATI_obsolete_var USE_CLANG_PLATFORM_BUILD,Clang is the only supported Android compiler. See $(CHANGES_URL)#USE_CLANG_PLATFORM_BUILD)
 $(KATI_obsolete_var BUILD_DROIDDOC,Droiddoc is only supported in Soong. See details on build/soong/java/droiddoc.go)
+$(KATI_obsolete_var BUILD_APIDIFF,Apidiff is only supported in Soong. See details on build/soong/java/droiddoc.go)
 $(KATI_obsolete_var \
   DEFAULT_GCC_CPP_STD_VERSION \
   HOST_GLOBAL_CFLAGS 2ND_HOST_GLOBAL_CFLAGS \
@@ -143,6 +131,8 @@
 # Here since this file is included by envsetup as well as during build.
 include $(BUILD_SYSTEM)/math.mk
 
+include $(BUILD_SYSTEM)/strings.mk
+
 # Various mappings to avoid hard-coding paths all over the place
 include $(BUILD_SYSTEM)/pathmap.mk
 
@@ -174,7 +164,6 @@
 BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk
 BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk
 BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk
-BUILD_APIDIFF:= $(BUILD_SYSTEM)/apidiff.mk
 BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk
 BUILD_NATIVE_TEST := $(BUILD_SYSTEM)/native_test.mk
 BUILD_NATIVE_BENCHMARK := $(BUILD_SYSTEM)/native_benchmark.mk
@@ -819,12 +808,16 @@
 PRODUCT_FULL_TREBLE_OVERRIDE ?=
 $(foreach req,$(requirements),$(eval $(req)_OVERRIDE ?=))
 
+# TODO(b/114488870): disallow PRODUCT_FULL_TREBLE_OVERRIDE from being used.
 .KATI_READONLY := \
     PRODUCT_FULL_TREBLE_OVERRIDE \
     $(foreach req,$(requirements),$(req)_OVERRIDE) \
     $(requirements) \
     PRODUCT_FULL_TREBLE \
 
+$(KATI_obsolete_var $(foreach req,$(requirements),$(req)_OVERRIDE) \
+    ,This should be referenced without the _OVERRIDE suffix.)
+
 requirements :=
 
 # BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED can be true only if early-mount of
diff --git a/core/definitions.mk b/core/definitions.mk
index 8393e4c..51eeadc 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -891,41 +891,6 @@
 endef
 
 ###########################################################
-## Package filtering
-###########################################################
-
-# Given a list of installed modules (short or long names)
-# return a list of the packages (yes, .apk packages, not
-# modules in general) that are overridden by this list and,
-# therefore, should not be installed.
-# $(1): mixed list of installed modules
-# TODO: This is fragile; find a reliable way to get this information.
-define _get-package-overrides
- $(eval ### Discard any words containing slashes, unless they end in .apk, \
-        ### in which case trim off the directory component and the suffix. \
-        ### If there are no slashes, keep the entire word.)
- $(eval _gpo_names := $(subst /,@@@ @@@,$(1)))
- $(eval _gpo_names := \
-     $(filter %.apk,$(_gpo_names)) \
-     $(filter-out %@@@ @@@%,$(_gpo_names)))
- $(eval _gpo_names := $(patsubst %.apk,%,$(_gpo_names)))
- $(eval _gpo_names := $(patsubst @@@%,%,$(_gpo_names)))
-
- $(eval ### Remove any remaining words that contain dots.)
- $(eval _gpo_names := $(subst .,@@@ @@@,$(_gpo_names)))
- $(eval _gpo_names := $(filter-out %@@@ @@@%,$(_gpo_names)))
-
- $(eval ### Now we have a list of any words that could possibly refer to \
-        ### packages, although there may be words that do not.  Only \
-        ### real packages will be present under PACKAGES.*, though.)
- $(foreach _gpo_name,$(_gpo_names),$(PACKAGES.$(_gpo_name).OVERRIDES))
-endef
-
-define get-package-overrides
-$(sort $(strip $(call _get-package-overrides,$(1))))
-endef
-
-###########################################################
 ## Output the command lines, or not
 ###########################################################
 
@@ -1764,7 +1729,6 @@
 ifneq ($(HOST_CUSTOM_LD_COMMAND),true)
 define transform-host-o-to-shared-lib-inner
 $(hide) $(PRIVATE_CXX) \
-	-Wl,-rpath-link=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_INTERMEDIATE_LIBRARIES) \
 	-Wl,-rpath,\$$ORIGIN/../$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_SHARED_LIBRARIES)) \
 	-Wl,-rpath,\$$ORIGIN/$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_SHARED_LIBRARIES)) \
 	-shared -Wl,-soname,$(notdir $@) \
@@ -1844,7 +1808,6 @@
 	-Wl,-dynamic-linker,$(PRIVATE_LINKER) \
 	-Wl,--gc-sections \
 	-Wl,-z,nocopyreloc \
-	-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \
 	$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O) \
 	$(PRIVATE_ALL_OBJECTS) \
 	-Wl,--whole-archive \
@@ -1916,11 +1879,6 @@
 ###########################################################
 ## Commands for running gcc to link a host executable
 ###########################################################
-ifdef BUILD_HOST_static
-HOST_FPIE_FLAGS :=
-else
-HOST_FPIE_FLAGS := -pie
-endif
 
 ifneq ($(HOST_CUSTOM_LD_COMMAND),true)
 define transform-host-o-to-executable-inner
@@ -1935,7 +1893,6 @@
 	$(if $(filter true,$(NATIVE_COVERAGE)),-lgcov) \
 	$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_HOST_LIBPROFILE_RT)) \
 	$(PRIVATE_ALL_SHARED_LIBRARIES) \
-	-Wl,-rpath-link=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_INTERMEDIATE_LIBRARIES) \
 	$(foreach path,$(PRIVATE_RPATHS), \
 	  -Wl,-rpath,\$$ORIGIN/$(path)) \
 	$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
@@ -2329,6 +2286,7 @@
 $(hide) $(ZIP2ZIP) -j -i $< -o $(dir $@)d8_input.jar "**/*.class"
 $(hide) $(DX_COMMAND) \
     --output $(dir $@) \
+    $(addprefix --lib ,$(PRIVATE_D8_LIBS)) \
     --min-api $(PRIVATE_MIN_SDK_VERSION) \
     $(subst --main-dex-list=, --main-dex-list , \
         $(filter-out --core-library --multi-dex --minimal-main-dex,$(PRIVATE_DX_FLAGS))) \
@@ -2336,36 +2294,6 @@
 $(hide) rm -f $(dir $@)d8_input.jar
 endef
 
-# Create a mostly-empty .jar file that we'll add to later.
-# The MacOS jar tool doesn't like creating empty jar files,
-# so we need to give it something.
-# $(1) package to create
-define create-empty-package-at
-@mkdir -p $(dir $(1))
-$(hide) touch $(dir $(1))zipdummy
-$(hide) $(JAR) cf $(1) -C $(dir $(1)) zipdummy
-$(hide) zip -qd $(1) zipdummy
-$(hide) rm $(dir $(1))zipdummy
-endef
-
-# Create a mostly-empty .jar file that we'll add to later.
-# The MacOS jar tool doesn't like creating empty jar files,
-# so we need to give it something.
-define create-empty-package
-$(call create-empty-package-at,$@)
-endef
-
-# Copy an arhchive file and delete any class files and empty folders inside.
-# $(1): the source archive file.
-# $(2): the destination archive file.
-define initialize-package-file
-@mkdir -p $(dir $(2))
-$(hide) cp -f $(1) $(2)
-$(hide) zip -qd $(2) "*.class" \
-    $(if $(strip $(PRIVATE_DONT_DELETE_JAR_DIRS)),,"*/") \
-    || true # Ignore the error when nothing to delete.
-endef
-
 #TODO: we kinda want to build different asset packages for
 #      different configurations, then combine them later (or something).
 #      Per-locale, etc.
@@ -2375,8 +2303,9 @@
 #Note that the version numbers are given to aapt as simple default
 #values; applications can override these by explicitly stating
 #them in their manifest.
-define add-assets-to-package
-$(hide) $(AAPT_ASAN_OPTIONS) $(AAPT) package -u $(PRIVATE_AAPT_FLAGS) \
+# $(1) the package file
+define create-assets-package
+$(hide) $(AAPT_ASAN_OPTIONS) $(AAPT) package $(PRIVATE_AAPT_FLAGS) \
     $(addprefix -c , $(PRIVATE_PRODUCT_AAPT_CONFIG)) \
     $(addprefix --preferred-density , $(PRIVATE_PRODUCT_AAPT_PREF_CONFIG)) \
     $(addprefix -M , $(PRIVATE_ANDROID_MANIFEST)) \
@@ -2391,16 +2320,17 @@
     $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
     $(addprefix --rename-instrumentation-target-package , $(PRIVATE_MANIFEST_INSTRUMENTATION_FOR)) \
     --skip-symbols-without-default-localization \
-    -F $@
+    -F $(1)
 # So that we re-run aapt when the list of input files change
 $(hide) echo $(PRIVATE_RESOURCE_LIST) >/dev/null
 endef
 
 # We need the extra blank line, so that the command will be on a separate line.
-# $(1): the ABI name
-# $(2): the list of shared libraies
+# $(1): the package
+# $(2): the ABI name
+# $(3): the list of shared libraies
 define _add-jni-shared-libs-to-package-per-abi
-$(hide) cp $(2) $(dir $@)lib/$(1)
+$(hide) cp $(3) $(dir $(1))lib/$(2)
 
 endef
 
@@ -2410,36 +2340,43 @@
 JNI_COMPRESS_FLAGS :=
 ZIPALIGN_PAGE_ALIGN_FLAGS :=
 else
-JNI_COMPRESS_FLAGS := -0
+JNI_COMPRESS_FLAGS := -L 0
 ZIPALIGN_PAGE_ALIGN_FLAGS := -p
 endif
 
-define add-jni-shared-libs-to-package
-$(hide) rm -rf $(dir $@)lib
-$(hide) mkdir -p $(addprefix $(dir $@)lib/,$(PRIVATE_JNI_SHARED_LIBRARIES_ABI))
+# $(1): the package file
+define create-jni-shared-libs-package
+rm -rf $(dir $(1))lib
+mkdir -p $(addprefix $(dir $(1))lib/,$(PRIVATE_JNI_SHARED_LIBRARIES_ABI))
 $(foreach abi,$(PRIVATE_JNI_SHARED_LIBRARIES_ABI),\
-  $(call _add-jni-shared-libs-to-package-per-abi,$(abi),\
+  $(call _add-jni-shared-libs-to-package-per-abi,$(1),$(abi),\
     $(patsubst $(abi):%,%,$(filter $(abi):%,$(PRIVATE_JNI_SHARED_LIBRARIES)))))
-$(hide) (cd $(dir $@) && zip -qrX $(JNI_COMPRESS_FLAGS) $(notdir $@) lib)
-$(hide) rm -rf $(dir $@)lib
+$(SOONG_ZIP) $(JNI_COMPRESS_FLAGS) -o $(1) -C $(dir $(1)) -D $(dir $(1))lib
+rm -rf $(dir $(1))lib
 endef
 
-#TODO: update the manifest to point to the dex file
-define add-dex-to-package
-$(call add-dex-to-package-arg,$@)
+# $(1): the jar file.
+# $(2): the classes.dex file.
+define create-dex-jar
+find $(dir $(2)) -maxdepth 1 -name "classes*.dex" | sort > $(1).lst
+$(SOONG_ZIP) -o $(1) -C $(dir $(2)) -l $(1).lst
 endef
 
-# $(1): the package file.
-define add-dex-to-package-arg
-$(hide) find $(dir $(PRIVATE_DEX_FILE)) -maxdepth 1 -name "classes*.dex" | sort | xargs zip -qjX $(1)
-endef
-
-# Add java resources added by the current module.
-# $(1) destination package
-#
+# Add java resources added by the current module to an existing package.
+# $(1) destination package.
 define add-java-resources-to
+  $(call _java-resources,$(1),u)
+endef
+
+# Add java resources added by the current module to a new jar.
+# $(1) destination jar.
+define create-java-resources-jar
+  $(call _java-resources,$(1),c)
+endef
+
+define _java-resources
 $(call dump-words-to-file, $(PRIVATE_EXTRA_JAR_ARGS), $(1).jar-arg-list)
-$(hide) $(JAR) uf $(1) @$(1).jar-arg-list
+$(hide) $(JAR) $(2)f $(1) @$(1).jar-arg-list
 @rm -f $(1).jar-arg-list
 endef
 
@@ -2454,6 +2391,12 @@
   $(JAR) uf $(1) $(call jar-args-sorted-files-in-directory,$(3))
 endef
 
+# $(1): the output resources jar.
+# $(2): the input jar
+define extract-resources-jar
+  $(ZIP2ZIP) -i $(2) -o $(1) -x '**/*.class' -x '**/*/'
+endef
+
 # Sign a package using the specified key/cert.
 #
 define sign-package
@@ -2513,12 +2456,23 @@
 define run-appcompat
 $(hide) \
   echo "appcompat.sh output:" >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log && \
-  art/tools/veridex/appcompat.sh --dex-file=$@ 2>&1 >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log
+  PACKAGING=$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING art/tools/veridex/appcompat.sh --dex-file=$@ 2>&1 >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log
 endef
+appcompat-files = \
+  art/tools/veridex/appcompat.sh \
+  $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST) \
+  $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
+  $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \
+  $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST) \
+  $(HOST_OUT_EXECUTABLES)/veridex \
+  $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/core_dex_intermediates/classes.dex \
+  $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/oahl_dex_intermediates/classes.dex
 else
 appcompat-header =
 run-appcompat =
+appcompat-files =
 endif  # HOST_OS == linux
+.KATI_READONLY: appcompat-header run-appcompat appcompat-files
 
 # Remove dynamic timestamps from packages
 #
@@ -2871,6 +2825,7 @@
 $(hide) rm -f $(PRIVATE_PROGUARD_DICTIONARY)
 $(hide) $(R8_COMPAT_PROGUARD) -injars '$<' \
     --min-api $(PRIVATE_MIN_SDK_VERSION) \
+    --no-data-resources \
     --force-proguard-compatibility --output $(subst classes.dex,,$@) \
     $(PRIVATE_PROGUARD_FLAGS) \
     $(addprefix -injars , $(PRIVATE_EXTRA_INPUT_JAR)) \
@@ -3279,7 +3234,7 @@
 ##
 ## $(1): path to validate
 define try-validate-path-is-subdir
-$(strip 
+$(strip \
     $(if $(filter /%,$(1)),
         $(1) starts with a slash
     )
@@ -3489,35 +3444,6 @@
 endef
 
 ###########################################################
-## Convert to lower case without requiring a shell, which isn't cacheable.
-##
-## $(1): string
-###########################################################
-to-lower=$(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
-
-###########################################################
-## Convert to upper case without requiring a shell, which isn't cacheable.
-##
-## $(1): string
-###########################################################
-to-upper=$(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$1))))))))))))))))))))))))))
-
-# Sanity-check to-lower and to-upper
-lower := abcdefghijklmnopqrstuvwxyz-_
-upper := ABCDEFGHIJKLMNOPQRSTUVWXYZ-_
-
-ifneq ($(lower),$(call to-lower,$(upper)))
-  $(error to-lower sanity check failure)
-endif
-
-ifneq ($(upper),$(call to-upper,$(lower)))
-  $(error to-upper sanity check failure)
-endif
-
-lower :=
-upper :=
-
-###########################################################
 ## Verify module name meets character requirements:
 ##   a-z A-Z 0-9
 ##   _.+-,@~
@@ -3555,3 +3481,9 @@
   $(call pretty-error,Invalid characters in module stem \($(1)\): $(call _invalid-name-chars,$($(1)))))
 endef
 .KATI_READONLY := verify-module-stem
+
+$(KATI_obsolete_var \
+  create-empty-package \
+  initialize-package-file \
+  add-jni-shared-libs-to-package,\
+  These functions have been removed)
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index aa24c20..1527047 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -159,7 +159,7 @@
 $(boot_profile_jars_zip): $(all_boot_jars) $(SOONG_ZIP)
 	echo "Create boot profiles package: $@"
 	rm -f $@
-	$(SOONG_ZIP) -o $@ -C $(PRODUCT_OUT) $(PRIVATE_JARS)
+	$(SOONG_ZIP) -o $@ -C $(PRODUCT_OUT) $(addprefix -f ,$(PRIVATE_JARS))
 
 droidcore: $(boot_profile_jars_zip)
 
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index 504cc57..6981916 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -7,14 +7,11 @@
 # Set USE_DEX2OAT_DEBUG to false for only building non-debug versions.
 ifeq ($(USE_DEX2OAT_DEBUG),false)
 DEX2OAT := $(HOST_OUT_EXECUTABLES)/dex2oat$(HOST_EXECUTABLE_SUFFIX)
-PATCHOAT := $(HOST_OUT_EXECUTABLES)/patchoat$(HOST_EXECUTABLE_SUFFIX)
 else
 DEX2OAT := $(HOST_OUT_EXECUTABLES)/dex2oatd$(HOST_EXECUTABLE_SUFFIX)
-PATCHOAT := $(HOST_OUT_EXECUTABLES)/patchoatd$(HOST_EXECUTABLE_SUFFIX)
 endif
 
 DEX2OAT_DEPENDENCY += $(DEX2OAT)
-PATCHOAT_DEPENDENCY += $(PATCHOAT)
 
 # Use the first preloaded-classes file in PRODUCT_COPY_FILES.
 PRELOADED_CLASSES := $(call word-colon,1,$(firstword \
@@ -85,8 +82,8 @@
 # is converted into to boot.art (to match the legacy assumption that boot.art
 # exists), and the rest are converted to boot-<name>.art.
 # In addition, each .art file has an associated .oat file.
-LIBART_TARGET_BOOT_ART_EXTRA_FILES := $(foreach jar,$(wordlist 2,999,$(LIBART_TARGET_BOOT_JARS)),boot-$(jar).art boot-$(jar).art.rel boot-$(jar).oat)
-LIBART_TARGET_BOOT_ART_EXTRA_FILES += boot.art.rel boot.oat
+LIBART_TARGET_BOOT_ART_EXTRA_FILES := $(foreach jar,$(wordlist 2,999,$(LIBART_TARGET_BOOT_JARS)),boot-$(jar).art boot-$(jar).oat)
+LIBART_TARGET_BOOT_ART_EXTRA_FILES += boot.oat
 LIBART_TARGET_BOOT_ART_VDEX_FILES := $(foreach jar,$(wordlist 2,999,$(LIBART_TARGET_BOOT_JARS)),boot-$(jar).vdex)
 LIBART_TARGET_BOOT_ART_VDEX_FILES += boot.vdex
 
diff --git a/core/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index 5a68738..8764d1d 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -85,16 +85,14 @@
 
 $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME): PRIVATE_BOOT_IMAGE_FLAGS := $(my_boot_image_flags)
 $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME): PRIVATE_2ND_ARCH_VAR_PREFIX := $(my_2nd_arch_prefix)
-$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME): PRIVATE_IMAGE_LOCATION := $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION)
 # Use dex2oat debug version for better error reporting
-$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) : $(LIBART_TARGET_BOOT_DEX_FILES) $(PRELOADED_CLASSES) $(DIRTY_IMAGE_OBJECTS) $(DEX2OAT_DEPENDENCY) $(PATCHOAT_DEPENDENCY) $(my_out_boot_image_profile_location)
+$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) : $(LIBART_TARGET_BOOT_DEX_FILES) $(PRELOADED_CLASSES) $(DIRTY_IMAGE_OBJECTS) $(DEX2OAT_DEPENDENCY) $(my_out_boot_image_profile_location)
 	@echo "target dex2oat: $@"
 	@mkdir -p $(dir $@)
 	@mkdir -p $(dir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED))
-	@rm -f $(dir $@)/*.art $(dir $@)/*.oat $(dir $@)/*.art.rel
+	@rm -f $(dir $@)/*.art $(dir $@)/*.oat
 	@rm -f $(dir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED))/*.art
 	@rm -f $(dir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED))/*.oat
-	@rm -f $(dir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED))/*.art.rel
 	$(hide) $(DEX2OAT_BOOT_IMAGE_LOG_TAGS) $(DEX2OAT) --runtime-arg -Xms$(DEX2OAT_IMAGE_XMS) \
 		--runtime-arg -Xmx$(DEX2OAT_IMAGE_XMX) \
 		$(PRIVATE_BOOT_IMAGE_FLAGS) \
@@ -115,11 +113,6 @@
 		--abort-on-hard-verifier-error \
 		--abort-on-soft-verifier-error \
 		$(PRODUCT_DEX_PREOPT_BOOT_FLAGS) $(GLOBAL_DEXPREOPT_FLAGS) $(ART_BOOT_IMAGE_EXTRA_ARGS) \
-		|| ( echo "$(DEX2OAT_FAILURE_MESSAGE)" ; false ) && \
-	$(DEX2OAT_BOOT_IMAGE_LOG_TAGS) ANDROID_ROOT=$(PRODUCT_OUT)/system ANDROID_DATA=$(dir $@) $(PATCHOAT) \
-		--input-image-location=$(PRIVATE_IMAGE_LOCATION) \
-		--output-image-relocation-directory=$(dir $@) \
-		--instruction-set=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) \
-		--base-offset-delta=0x10000000
+		|| ( echo "$(DEX2OAT_FAILURE_MESSAGE)" ; false )
 
 endif
diff --git a/core/dpi_specific_apk.mk b/core/dpi_specific_apk.mk
index f32daf5..88d2fe6 100644
--- a/core/dpi_specific_apk.mk
+++ b/core/dpi_specific_apk.mk
@@ -47,21 +47,24 @@
 $(built_dpi_apk) : $(all_library_res_package_export_deps)
 $(built_dpi_apk) : $(private_key) $(certificate) $(SIGNAPK_JAR)
 $(built_dpi_apk) : $(AAPT)
+$(built_dpi_apk) : $(MERGE_ZIPS) $(SOONG_ZIP) $(ZIP2ZIP)
 $(built_dpi_apk) : $(all_res_assets) $(jni_shared_libraries) $(full_android_manifest)
 	@echo "target Package: $(PRIVATE_MODULE) ($@)"
-	$(if $(PRIVATE_SOURCE_ARCHIVE),\
-	  $(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@),\
-	  $(create-empty-package))
-	$(add-assets-to-package)
+	rm -rf $@.parts
+	mkdir -p $@.parts
+	$(call create-assets-package,$@.parts/apk.zip)
 ifneq ($(jni_shared_libraries),)
-	$(add-jni-shared-libs-to-package)
+	$(call create-jni-shared-libs-package,$@.parts/jni.zip)
 endif
 ifeq ($(full_classes_jar),)
 # We don't build jar, need to add the Java resources here.
-	$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call add-java-resources-to,$@))
+	$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call create-java-resources-jar,$@.parts/res.zip))
 else
-	$(add-dex-to-package)
+	$(call create-dex-jar,$@.parts/dex.zip,$(PRIVATE_DEX_FILE))
+	$(call extract-resources-jar,$@.parts/res.zip,$(PRIVATE_SOURCE_ARCHIVE))
 endif
+	$(MERGE_ZIPS) $@ $@.parts/*.zip
+	rm -rf $@.parts
 	$(sign-package)
 
 # Set up global variables to register this apk to the higher-level dependency graph.
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 4396dd2..7128e3a 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -183,62 +183,26 @@
 TARGET_COPY_OUT_DATA := data
 TARGET_COPY_OUT_ASAN := $(TARGET_COPY_OUT_DATA)/asan
 TARGET_COPY_OUT_OEM := oem
-TARGET_COPY_OUT_ODM := odm
-TARGET_COPY_OUT_PRODUCT := product
-TARGET_COPY_OUT_PRODUCT_SERVICES := product_services
 TARGET_COPY_OUT_RAMDISK := ramdisk
 TARGET_COPY_OUT_ROOT := root
 TARGET_COPY_OUT_RECOVERY := recovery
+# The directory used for optional partitions depend on the BoardConfig, so
+# they're defined to placeholder values here and swapped after reading the
+# BoardConfig, to be either the partition dir, or a subdir within 'system'.
+_vendor_path_placeholder := ||VENDOR-PATH-PH||
+_product_path_placeholder := ||PRODUCT-PATH-PH||
+_product_services_path_placeholder := ||PRODUCT_SERVICES-PATH-PH||
+_odm_path_placeholder := ||ODM-PATH-PH||
+TARGET_COPY_OUT_VENDOR := $(_vendor_path_placeholder)
+TARGET_COPY_OUT_PRODUCT := $(_product_path_placeholder)
+TARGET_COPY_OUT_PRODUCT_SERVICES := $(_product_services_path_placeholder)
+TARGET_COPY_OUT_ODM := $(_odm_path_placeholder)
 
 # Returns the non-sanitized version of the path provided in $1.
 define get_non_asan_path
 $(patsubst $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/%,$(PRODUCT_OUT)/%,$1)
 endef
 
-###########################################
-# Define TARGET_COPY_OUT_VENDOR to a placeholder, for at this point
-# we don't know if the device wants to build a separate vendor.img
-# or just build vendor stuff into system.img.
-# A device can set up TARGET_COPY_OUT_VENDOR to "vendor" in its
-# BoardConfig.mk.
-# We'll substitute with the real value after loading BoardConfig.mk.
-_vendor_path_placeholder := ||VENDOR-PATH-PH||
-TARGET_COPY_OUT_VENDOR := $(_vendor_path_placeholder)
-###########################################
-
-###########################################
-# Define TARGET_COPY_OUT_PRODUCT to a placeholder, for at this point
-# we don't know if the device wants to build a separate product.img
-# or just build product stuff into system.img.
-# A device can set up TARGET_COPY_OUT_PRODUCT to "product" in its
-# BoardConfig.mk.
-# We'll substitute with the real value after loading BoardConfig.mk.
-_product_path_placeholder := ||PRODUCT-PATH-PH||
-TARGET_COPY_OUT_PRODUCT := $(_product_path_placeholder)
-###########################################
-
-###########################################
-# Define TARGET_COPY_OUT_PRODUCT_SERVICES to a placeholder, for at this point
-# we don't know if the device wants to build a separate product_services.img
-# or just build product stuff into system.img.
-# A device can set up TARGET_COPY_OUT_PRODUCT_SERVICES to "product_services" in its
-# BoardConfig.mk.
-# We'll substitute with the real value after loading BoardConfig.mk.
-_product_services_path_placeholder := ||PRODUCT_SERVICES-PATH-PH||
-TARGET_COPY_OUT_PRODUCT_SERVICES := $(_product_services_path_placeholder)
-###########################################
-
-###########################################
-# Define TARGET_COPY_OUT_ODM to a placeholder, for at this point
-# we don't know if the device wants to build a separate odm.img
-# or just build odm stuff into vendor.img.
-# A device can set up TARGET_COPY_OUT_ODM to "odm" in its
-# BoardConfig.mk.
-# We'll substitute with the real value after loading BoardConfig.mk.
-_odm_path_placeholder := ||ODM-PATH-PH||
-TARGET_COPY_OUT_ODM := $(_odm_path_placeholder)
-###########################################
-
 #################################################################
 # Set up minimal BOOTCLASSPATH list of jars to build/execute
 # java code with dalvikvm/art.
@@ -446,9 +410,11 @@
   TARGET_VENDOR_TEST_SUFFIX :=
 endif
 
+ifeq (,$(TARGET_BUILD_APPS))
 ifdef PRODUCT_EXTRA_VNDK_VERSIONS
   $(foreach v,$(PRODUCT_EXTRA_VNDK_VERSIONS),$(call check_vndk_version,$(v)))
 endif
+endif
 
 # Ensure that BOARD_SYSTEMSDK_VERSIONS are all within PLATFORM_SYSTEMSDK_VERSIONS
 _unsupported_systemsdk_versions := $(filter-out $(PLATFORM_SYSTEMSDK_VERSIONS),$(BOARD_SYSTEMSDK_VERSIONS))
@@ -543,13 +509,11 @@
   HOST_CROSS_OUT_TESTCASES
 
 HOST_OUT_INTERMEDIATES := $(HOST_OUT)/obj
-HOST_OUT_INTERMEDIATE_LIBRARIES := $(HOST_OUT_INTERMEDIATES)/lib
 HOST_OUT_NOTICE_FILES := $(HOST_OUT_INTERMEDIATES)/NOTICE_FILES
 HOST_OUT_COMMON_INTERMEDIATES := $(HOST_COMMON_OUT_ROOT)/obj
 HOST_OUT_FAKE := $(HOST_OUT)/fake_packages
 .KATI_READONLY := \
   HOST_OUT_INTERMEDIATES \
-  HOST_OUT_INTERMEDIATE_LIBRARIES \
   HOST_OUT_NOTICE_FILES \
   HOST_OUT_COMMON_INTERMEDIATES \
   HOST_OUT_FAKE
@@ -558,11 +522,9 @@
 include $(BUILD_SYSTEM)/aux_config.mk
 
 HOST_CROSS_OUT_INTERMEDIATES := $(HOST_CROSS_OUT)/obj
-HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES := $(HOST_CROSS_OUT_INTERMEDIATES)/lib
 HOST_CROSS_OUT_NOTICE_FILES := $(HOST_CROSS_OUT_INTERMEDIATES)/NOTICE_FILES
 .KATI_READONLY := \
   HOST_CROSS_OUT_INTERMEDIATES \
-  HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES \
   HOST_CROSS_OUT_NOTICE_FILES
 
 HOST_OUT_GEN := $(HOST_OUT)/gen
@@ -581,7 +543,6 @@
 HOST_2ND_ARCH_VAR_PREFIX := 2ND_
 HOST_2ND_ARCH_MODULE_SUFFIX := _32
 $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATES := $(HOST_OUT)/obj32
-$(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES := $($(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATES)/lib
 $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES := $(HOST_OUT)/lib
 $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_EXECUTABLES := $(HOST_OUT_EXECUTABLES)
 $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_JAVA_LIBRARIES := $(HOST_OUT_JAVA_LIBRARIES)
@@ -591,7 +552,6 @@
   HOST_2ND_ARCH_VAR_PREFIX \
   HOST_2ND_ARCH_MODULE_SUFFIX \
   $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATES \
-  $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES \
   $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES \
   $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_EXECUTABLES \
   $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_JAVA_LIBRARIES \
@@ -607,7 +567,6 @@
 HOST_CROSS_2ND_ARCH_VAR_PREFIX := 2ND_
 HOST_CROSS_2ND_ARCH_MODULE_SUFFIX := _64
 $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_INTERMEDIATES := $(HOST_CROSS_OUT)/obj64
-$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES := $($(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_INTERMEDIATES)/lib
 $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_SHARED_LIBRARIES := $(HOST_CROSS_OUT)/lib64
 $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_EXECUTABLES := $(HOST_CROSS_OUT_EXECUTABLES)
 $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_NATIVE_TESTS := $(HOST_CROSS_OUT)/nativetest64
@@ -615,7 +574,6 @@
   HOST_CROSS_2ND_ARCH_VAR_PREFIX \
   HOST_CROSS_2ND_ARCH_MODULE_SUFFIX \
   $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_INTERMEDIATES \
-  $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES \
   $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_SHARED_LIBRARIES \
   $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_EXECUTABLES \
   $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_NATIVE_TESTS
@@ -626,8 +584,7 @@
   TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj
 endif
 TARGET_OUT_HEADERS := $(TARGET_OUT_INTERMEDIATES)/include
-TARGET_OUT_INTERMEDIATE_LIBRARIES := $(TARGET_OUT_INTERMEDIATES)/lib
-.KATI_READONLY := TARGET_OUT_INTERMEDIATES TARGET_OUT_HEADERS TARGET_OUT_INTERMEDIATE_LIBRARIES
+.KATI_READONLY := TARGET_OUT_INTERMEDIATES TARGET_OUT_HEADERS
 
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
   TARGET_OUT_COMMON_INTERMEDIATES := $(TARGET_COMMON_OUT_ROOT)/obj_asan
@@ -716,7 +673,6 @@
 else
   $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj_$(TARGET_2ND_ARCH)
 endif
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES)/lib
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES := $(target_out_shared_libraries_base)/lib/$(TARGET_2ND_ARCH)
 else
@@ -729,7 +685,6 @@
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_TESTCASES := $(TARGET_OUT_TESTCASES)
 .KATI_READONLY := \
   $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES \
-  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES \
   $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES \
   $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_RENDERSCRIPT_BITCODE \
   $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_EXECUTABLES \
@@ -986,11 +941,11 @@
 
 TARGET_OUT_PRODUCT_SERVICES := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_PRODUCT_SERVICES)
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
-target_out_product_services_shared_libraries_base := $(PRODUCT_SERVICES_OUT)/$(TARGET_COPY_OUT_ASAN)/product_services
+target_out_product_services_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/product_services
 ifeq ($(SANITIZE_LITE),true)
 # When using SANITIZE_LITE, APKs must not be packaged with sanitized libraries, as they will not
 # work with unsanitized app_process. For simplicity, generate APKs into /data/asan/.
-target_out_product_services_app_base := $(PRODUCT_SERVICES_OUT)/$(TARGET_COPY_OUT_ASAN)/product_services
+target_out_product_services_app_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/product_services
 else
 target_out_product_services_app_base := $(TARGET_OUT_PRODUCT_SERVICES)
 endif
diff --git a/core/executable.mk b/core/executable.mk
index f1b2462..e8b2f30 100644
--- a/core/executable.mk
+++ b/core/executable.mk
@@ -79,7 +79,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # non-preferred arch is supported
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
diff --git a/core/executable_internal.mk b/core/executable_internal.mk
index 4a62fbf..70b2ea8 100644
--- a/core/executable_internal.mk
+++ b/core/executable_internal.mk
@@ -47,13 +47,13 @@
 my_target_crtbegin_static_o :=
 my_target_crtend_o :=
 else ifdef LOCAL_USE_VNDK
-my_target_crtbegin_dynamic_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.vendor.o
-my_target_crtbegin_static_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.vendor.o
-my_target_crtend_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.vendor.o
+my_target_crtbegin_dynamic_o := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJECT_crtbegin_dynamic.vendor)
+my_target_crtbegin_static_o := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJECT_crtbegin_static.vendor)
+my_target_crtend_o := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJECT_crtend_android.vendor)
 else
-my_target_crtbegin_dynamic_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
-my_target_crtbegin_static_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
-my_target_crtend_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.o
+my_target_crtbegin_dynamic_o := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJECT_crtbegin_dynamic)
+my_target_crtbegin_static_o := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJECT_crtbegin_static)
+my_target_crtend_o := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJECT_crtend_android)
 endif
 ifneq ($(LOCAL_SDK_VERSION),)
 my_target_crtbegin_dynamic_o := $(wildcard $(my_ndk_sysroot_lib)/crtbegin_dynamic.o)
@@ -65,7 +65,6 @@
 $(linked_module): PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O := $(my_target_crtbegin_dynamic_o)
 $(linked_module): PRIVATE_TARGET_CRTBEGIN_STATIC_O := $(my_target_crtbegin_static_o)
 $(linked_module): PRIVATE_TARGET_CRTEND_O := $(my_target_crtend_o)
-$(linked_module): PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)
 $(linked_module): PRIVATE_POST_LINK_CMD := $(LOCAL_POST_LINK_CMD)
 
 ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
diff --git a/core/header_library.mk b/core/header_library.mk
index 5144679..3f2730e 100644
--- a/core/header_library.mk
+++ b/core/header_library.mk
@@ -25,7 +25,6 @@
 
   ifeq ($(my_module_arch_supported),true)
     # Build for 2ND_ARCH
-    OVERRIDE_BUILT_MODULE_PATH :=
     LOCAL_BUILT_MODULE :=
     LOCAL_INSTALLED_MODULE :=
     LOCAL_INTERMEDIATE_TARGETS :=
@@ -43,7 +42,6 @@
 
     ifeq ($(my_module_arch_supported),true)
       # Build for 2ND_ARCH
-      OVERRIDE_BUILT_MODULE_PATH :=
       LOCAL_BUILT_MODULE :=
       LOCAL_INSTALLED_MODULE :=
       LOCAL_INTERMEDIATE_TARGETS :=
@@ -56,7 +54,6 @@
 
       ifeq ($(my_module_arch_supported),true)
         # Build for HOST_CROSS_2ND_ARCH
-        OVERRIDE_BUILT_MODULE_PATH :=
         LOCAL_BUILT_MODULE :=
         LOCAL_INSTALLED_MODULE :=
         LOCAL_INTERMEDIATE_TARGETS :=
diff --git a/core/header_library_internal.mk b/core/header_library_internal.mk
index 3e4958f..35ee1bc 100644
--- a/core/header_library_internal.mk
+++ b/core/header_library_internal.mk
@@ -11,16 +11,6 @@
 $(error $(LOCAL_PATH): Cannot set module stem for a library)
 endif
 
-ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-  ifdef LOCAL_USE_VNDK
-    name_without_suffix := $(patsubst %.vendor,%,$(LOCAL_MODULE))
-    ifneq ($(name_without_suffix),$(LOCAL_MODULE))
-      SPLIT_VENDOR.$(LOCAL_MODULE_CLASS).$(name_without_suffix) := 1
-    endif
-    name_without_suffix :=
-  endif
-endif
-
 include $(BUILD_SYSTEM)/binary.mk
 
 ifneq ($(strip $(all_objects)),)
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index d35f39d..6a32ff9 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -171,11 +171,15 @@
 
 $(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
 $(LOCAL_BUILT_MODULE): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar)
-$(LOCAL_BUILT_MODULE): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
+$(LOCAL_BUILT_MODULE): $(MERGE_ZIPS) $(SOONG_ZIP) $(ZIP2ZIP)
 $(LOCAL_BUILT_MODULE): $(built_dex) $(java_resource_sources)
 	@echo "Host Jar: $(PRIVATE_MODULE) ($@)"
-	$(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@)
-	$(add-dex-to-package)
+	rm -rf $@.parts
+	mkdir -p $@.parts
+	$(call create-dex-jar,$@.parts/dex.zip,$(PRIVATE_DEX_FILE))
+	$(call extract-resources-jar,$@.parts/res.zip,$(PRIVATE_SOURCE_ARCHIVE))
+	$(MERGE_ZIPS) -j $@ $@.parts/dex.zip $@.parts/res.zip
+	rm -rf $@.parts
 
 endif # !LOCAL_IS_STATIC_JAVA_LIBRARY
 
diff --git a/core/host_executable.mk b/core/host_executable.mk
index 1480c2c..a2111a1 100644
--- a/core/host_executable.mk
+++ b/core/host_executable.mk
@@ -11,10 +11,6 @@
 endif
 endif
 
-ifeq ($(LOCAL_NO_FPIE),)
-LOCAL_LDFLAGS += $(HOST_FPIE_FLAGS)
-endif
-
 ifeq ($(my_module_multilib),both)
 ifneq ($(LOCAL_MODULE_CLASS),NATIVE_TESTS)
 ifeq ($(LOCAL_MODULE_PATH_32)$(LOCAL_MODULE_STEM_32),)
@@ -40,7 +36,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # Build for HOST_2ND_ARCH
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
@@ -56,7 +51,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # Build for Windows
-OVERRIDE_BUILT_MODULE_PATH :=
 # we don't want others using the cross compiled version
 saved_LOCAL_BUILT_MODULE := $(LOCAL_BUILT_MODULE)
 saved_LOCAL_INSTALLED_MODULE := $(LOCAL_INSTALLED_MODULE)
@@ -65,10 +59,6 @@
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
 
-ifeq ($(LOCAL_NO_FPIE),)
-LOCAL_LDFLAGS += $(HOST_CROSS_FPIE_FLAGS)
-endif
-
 include $(BUILD_SYSTEM)/host_executable_internal.mk
 LOCAL_LDFLAGS := $(saved_LOCAL_LDFLAGS)
 LOCAL_BUILT_MODULE := $(saved_LOCAL_BUILT_MODULE)
@@ -79,7 +69,6 @@
 LOCAL_2ND_ARCH_VAR_PREFIX := $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
-OVERRIDE_BUILT_MODULE_PATH :=
 # we don't want others using the cross compiled version
 saved_LOCAL_BUILT_MODULE := $(LOCAL_BUILT_MODULE)
 saved_LOCAL_INSTALLED_MODULE := $(LOCAL_INSTALLED_MODULE)
@@ -88,10 +77,6 @@
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
 
-ifeq ($(LOCAL_NO_FPIE),)
-LOCAL_LDFLAGS += $(HOST_CROSS_FPIE_FLAGS)
-endif
-
 include $(BUILD_SYSTEM)/host_executable_internal.mk
 LOCAL_LDFLAGS := $(saved_LOCAL_LDFLAGS)
 LOCAL_BUILT_MODULE := $(saved_LOCAL_BUILT_MODULE)
diff --git a/core/host_shared_library.mk b/core/host_shared_library.mk
index 5da7913..e9b3dad 100644
--- a/core/host_shared_library.mk
+++ b/core/host_shared_library.mk
@@ -23,7 +23,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # Build for HOST_2ND_ARCH
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
@@ -39,7 +38,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # Build for Windows
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_MODULE_SUFFIX :=
 # We don't want makefiles using the cross-compiled host tool
@@ -56,7 +54,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # Build for HOST_CROSS_2ND_ARCH
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_MODULE_SUFFIX :=
 # We don't want makefiles using the cross-compiled host tool
diff --git a/core/host_shared_library_internal.mk b/core/host_shared_library_internal.mk
index 0a3b317..da20874 100644
--- a/core/host_shared_library_internal.mk
+++ b/core/host_shared_library_internal.mk
@@ -13,9 +13,6 @@
 ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
 LOCAL_MODULE_SUFFIX := $($(my_prefix)SHLIB_SUFFIX)
 endif
-ifneq ($(strip $(OVERRIDE_BUILT_MODULE_PATH)),)
-$(error $(LOCAL_PATH): Illegal use of OVERRIDE_BUILT_MODULE_PATH)
-endif
 ifneq ($(strip $(LOCAL_MODULE_STEM)$(LOCAL_BUILT_MODULE_STEM)),)
 $(error $(LOCAL_PATH): Cannot set module stem for a library)
 endif
@@ -34,10 +31,6 @@
 
 ifndef skip_build_from_source
 
-# Put the built modules of all shared libraries in a common directory
-# to simplify the link line.
-OVERRIDE_BUILT_MODULE_PATH := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)
-
 include $(BUILD_SYSTEM)/binary.mk
 
 my_host_libprofile_rt := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)LIBPROFILE_RT)
diff --git a/core/host_static_library.mk b/core/host_static_library.mk
index aa0421e..71f4fd9 100644
--- a/core/host_static_library.mk
+++ b/core/host_static_library.mk
@@ -23,7 +23,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # Build for HOST_2ND_ARCH
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
@@ -39,7 +38,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # Build for Windows
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
@@ -52,7 +50,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # Build for HOST_CROSS_2ND_ARCH
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
index a99d88a..e786691 100644
--- a/core/install_jni_libs_internal.mk
+++ b/core/install_jni_libs_internal.mk
@@ -13,9 +13,8 @@
 #
 
 my_jni_shared_libraries := \
-    $(addprefix $($(my_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/, \
-      $(addsuffix .so, \
-          $(LOCAL_JNI_SHARED_LIBRARIES)))
+    $(foreach lib,$(LOCAL_JNI_SHARED_LIBRARIES), \
+      $(call intermediates-dir-for,SHARED_LIBRARIES,$(lib),,,$(my_2nd_arch_prefix))/$(lib).so)
 
 # App-specific lib path.
 my_app_lib_path := $(dir $(LOCAL_INSTALLED_MODULE))lib/$(TARGET_$(my_2nd_arch_prefix)ARCH)
@@ -52,7 +51,9 @@
 my_shared_library_path := $(call get_non_asan_path,\
   $($(my_2nd_arch_prefix)TARGET_OUT$(partition_tag)_SHARED_LIBRARIES))
 # Do not use order-only dependency, because we want to rebuild the image if an jni is updated.
-$(LOCAL_INSTALLED_MODULE) : $(addprefix $(my_shared_library_path)/, $(my_jni_filenames))
+my_installed_library := $(addprefix $(my_shared_library_path)/, $(my_jni_filenames))
+$(LOCAL_INSTALLED_MODULE) : $(my_installed_library)
+ALL_MODULES.$(LOCAL_MODULE).INSTALLED += $(my_installed_library)
 
 # Create symlink in the app specific lib path
 # Skip creating this symlink when running the second part of a target sanitization build.
@@ -97,7 +98,9 @@
 $(foreach lib, $(my_prebuilt_jni_libs), \
     $(eval $(call copy-one-file, $(lib), $(my_app_lib_path)/$(notdir $(lib)))))
 
-$(LOCAL_INSTALLED_MODULE) : $(addprefix $(my_app_lib_path)/, $(notdir $(my_prebuilt_jni_libs)))
+my_installed_library := $(addprefix $(my_app_lib_path)/, $(notdir $(my_prebuilt_jni_libs)))
+$(LOCAL_INSTALLED_MODULE) : $(my_installed_library)
+ALL_MODULES.$(LOCAL_MODULE).INSTALLED += $(my_installed_library)
 endif  # my_embed_jni
 endif  # inner my_prebuilt_jni_libs
 endif  # outer my_prebuilt_jni_libs
diff --git a/core/java.mk b/core/java.mk
index cf9bf56..6ca2904 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -494,6 +494,8 @@
   $(built_dex_intermediate) : $(full_classes_pre_proguard_jar) $(extra_input_jar) $(my_proguard_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) $(legacy_proguard_lib_deps) $(R8_COMPAT_PROGUARD)
 	$(transform-jar-to-dex-r8)
 else # !LOCAL_PROGUARD_ENABLED
+  $(built_dex_intermediate): PRIVATE_D8_LIBS := $(full_java_bootclasspath_libs) $(full_shared_java_header_libs)
+  $(built_dex_intermediate): $(full_java_bootclasspath_libs) $(full_shared_java_header_libs)
   $(built_dex_intermediate): $(full_classes_pre_proguard_jar) $(DX) $(ZIP2ZIP)
 	$(transform-classes.jar-to-dex)
 endif
diff --git a/core/java_library.mk b/core/java_library.mk
index 9a7422d..5716f4c 100644
--- a/core/java_library.mk
+++ b/core/java_library.mk
@@ -65,11 +65,14 @@
 
 $(common_javalib.jar): PRIVATE_DEX_FILE := $(built_dex)
 $(common_javalib.jar): PRIVATE_SOURCE_ARCHIVE := $(full_classes_pre_proguard_jar)
-$(common_javalib.jar): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
+$(common_javalib.jar): $(MERGE_ZIPS) $(SOONG_ZIP) $(ZIP2ZIP)
 $(common_javalib.jar) : $(built_dex) $(java_resource_sources) | $(ZIPTIME) $(ZIPALIGN)
 	@echo "target Jar: $(PRIVATE_MODULE) ($@)"
-	$(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@.tmp)
-	$(call add-dex-to-package-arg,$@.tmp)
+	rm -rf $@.parts && mkdir -p $@.parts
+	$(call create-dex-jar,$@.parts/dex.zip,$(PRIVATE_DEX_FILE))
+	$(call extract-resources-jar,$@.parts/res.zip,$(PRIVATE_SOURCE_ARCHIVE))
+	$(MERGE_ZIPS) -j $@.tmp $@.parts/dex.zip $@.parts/res.zip
+	rm -rf $@.parts
 	$(hide) $(ZIPTIME) $@.tmp
 	$(call commit-change-for-toc,$@)
 ifeq (true, $(LOCAL_UNCOMPRESS_DEX))
diff --git a/core/java_renderscript.mk b/core/java_renderscript.mk
index cf75910..406d679 100644
--- a/core/java_renderscript.mk
+++ b/core/java_renderscript.mk
@@ -107,7 +107,7 @@
 # Prevent these from showing up on the device
 # One exception is librsjni.so, which is needed for
 # both native path and compat path.
-rs_jni_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/librsjni.so
+rs_jni_lib := $(call intermediates-dir-for,SHARED_LIBRARIES,librsjni.so)/librsjni.so
 LOCAL_JNI_SHARED_LIBRARIES += librsjni
 
 ifneq (,$(TARGET_BUILD_APPS)$(FORCE_BUILD_RS_COMPAT))
@@ -118,13 +118,13 @@
 
 $(rs_generated_src_jar): .KATI_IMPLICIT_OUTPUTS += $(rs_generated_bc)
 
-rs_support_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/libRSSupport.so
+rs_support_lib := $(call intermediates-dir-for,SHARED_LIBRARIES,libRSSupport)/libRSSupport.so
 LOCAL_JNI_SHARED_LIBRARIES += libRSSupport
 
 rs_support_io_lib :=
 # check if the target api level support USAGE_IO
 ifeq ($(filter $(RSCOMPAT_NO_USAGEIO_API_LEVELS),$(renderscript_target_api)),)
-rs_support_io_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/libRSSupportIO.so
+rs_support_io_lib := $(call intermediates-dir-for,SHARED_LIBRARIES,libRSSupportIO)/libRSSupportIO.so
 LOCAL_JNI_SHARED_LIBRARIES += libRSSupportIO
 endif
 
diff --git a/core/main.mk b/core/main.mk
index 1b00124..7f673e9 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -317,8 +317,6 @@
   ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=1
   # Enable Dalvik lock contention logging.
   ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.lockprof.threshold=500
-  # Include the debugging/testing OTA keys in this build.
-  INCLUDE_TEST_OTA_KEYS := true
 else # !enable_target_debugging
   # Target is less debuggable and adbd is off by default
   ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=0
@@ -902,18 +900,31 @@
 # Of the modules defined by the component makefiles,
 # determine what we actually want to build.
 
+
+# Expand a list of modules to the modules that they override (if any)
+# $(1): The list of modules.
+define module-overrides
+$(foreach m,$(1),$(PACKAGES.$(m).OVERRIDES) $(EXECUTABLES.$(m).OVERRIDES))
+endef
+
 ###########################################################
 ## Expand a module name list with REQUIRED modules
 ###########################################################
 # $(1): The variable name that holds the initial module name list.
 #       the variable will be modified to hold the expanded results.
 # $(2): The initial module name list.
+# $(3): The list of overridden modules.
 # Returns empty string (maybe with some whitespaces).
 define expand-required-modules
 $(eval _erm_req := $(foreach m,$(2),$(ALL_MODULES.$(m).REQUIRED))) \
-$(eval _erm_new_modules := $(sort $(filter-out $($(1)),$(_erm_req))))\
-$(if $(_erm_new_modules),$(eval $(1) += $(_erm_new_modules))\
-  $(call expand-required-modules,$(1),$(_erm_new_modules)))
+$(eval _erm_new_modules := $(sort $(filter-out $($(1)),$(_erm_req)))) \
+$(eval _erm_new_overrides := $(call module-overrides,$(_erm_new_modules))) \
+$(eval _erm_all_overrides := $(3) $(_erm_new_overrides)) \
+$(eval _erm_new_modules := $(filter-out $(_erm_all_overrides), $(_erm_new_modules))) \
+$(eval $(1) := $(filter-out $(_erm_new_overrides),$($(1)))) \
+$(eval $(1) += $(_erm_new_modules)) \
+$(if $(_erm_new_modules),\
+  $(call expand-required-modules,$(1),$(_erm_new_modules),$(_erm_all_overrides)))
 endef
 
 # Transforms paths relative to PRODUCT_OUT to absolute paths.
@@ -944,11 +955,16 @@
 # $(1): product makefile
 define product-installed-files
   $(eval _mk := $(strip $(1))) \
-  $(eval _pif_modules := $(PRODUCTS.$(_mk).PRODUCT_PACKAGES)) \
-  $(if $(BOARD_VNDK_VERSION),$(eval _pif_modules += vndk_package)) \
+  $(eval _pif_modules := \
+    $(PRODUCTS.$(_mk).PRODUCT_PACKAGES) \
+    $(if $(filter eng,$(tags_to_install)),$(PRODUCTS.$(_mk).PRODUCT_PACKAGES_ENG)) \
+    $(if $(filter debug,$(tags_to_install)),$(PRODUCTS.$(_mk).PRODUCT_PACKAGES_DEBUG)) \
+    $(if $(filter tests,$(tags_to_install)),$(PRODUCTS.$(_mk).PRODUCT_PACKAGES_TESTS)) \
+    $(if $(filter asan,$(tags_to_install)),$(PRODUCTS.$(_mk).PRODUCT_PACKAGES_DEBUG_ASAN)) \
+    $(if $(BOARD_VNDK_VERSION),vndk_package) \
+  ) \
   $(eval ### Filter out the overridden packages and executables before doing expansion) \
-  $(eval _pif_overrides := $(foreach p, $(_pif_modules), $(PACKAGES.$(p).OVERRIDES))) \
-  $(eval _pif_overrides += $(foreach m, $(_pif_modules), $(EXECUTABLES.$(m).OVERRIDES))) \
+  $(eval _pif_overrides := $(call module-overrides,$(_pif_modules))) \
   $(eval _pif_modules := $(filter-out $(_pif_overrides), $(_pif_modules))) \
   $(eval ### Resolve the :32 :64 module name) \
   $(eval _pif_modules_32 := $(patsubst %:32,%,$(filter %:32, $(_pif_modules)))) \
@@ -960,7 +976,7 @@
   $(eval ### For the rest we add both) \
   $(eval _pif_modules += $(call get-32-bit-modules, $(_pif_modules_rest))) \
   $(eval _pif_modules += $(_pif_modules_rest)) \
-  $(call expand-required-modules,_pif_modules,$(_pif_modules)) \
+  $(call expand-required-modules,_pif_modules,$(_pif_modules),$(_pif_overrides)) \
   $(call module-installed-files, $(_pif_modules)) \
   $(call resolve-product-relative-paths,\
     $(foreach cf,$(PRODUCTS.$(_mk).PRODUCT_COPY_FILES),$(call word-colon,2,$(cf))))
@@ -1035,49 +1051,15 @@
   product_FILES :=
 endif
 
-ifeq (0,1)
-  $(info product_FILES for $(TARGET_DEVICE) ($(INTERNAL_PRODUCT)):)
-  $(foreach p,$(product_FILES),$(info :   $(p)))
-  $(error done)
-endif
-
-eng_MODULES := $(sort \
-        $(call get-tagged-modules,eng) \
-        $(call module-installed-files, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES_ENG)) \
-    )
-debug_MODULES := $(sort \
-        $(call get-tagged-modules,debug) \
-        $(call module-installed-files, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES_DEBUG)) \
-    )
-tests_MODULES := $(sort \
-        $(call get-tagged-modules,tests) \
-        $(call module-installed-files, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES_TESTS)) \
-    )
-asan_MODULES := $(sort \
-        $(call module-installed-files, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES_DEBUG_ASAN)) \
-    )
-
 # TODO: Remove the 3 places in the tree that use ALL_DEFAULT_INSTALLED_MODULES
 # and get rid of it from this list.
 modules_to_install := $(sort \
     $(ALL_DEFAULT_INSTALLED_MODULES) \
     $(product_FILES) \
-    $(foreach tag,$(tags_to_install),$($(tag)_MODULES)) \
+    $(call get-tagged-modules,$(tags_to_install)) \
     $(CUSTOM_MODULES) \
   )
 
-# Some packages may override others using LOCAL_OVERRIDES_PACKAGES.
-# Filter out (do not install) any overridden packages.
-overridden_packages := $(call get-package-overrides,$(modules_to_install))
-ifdef overridden_packages
-#  old_modules_to_install := $(modules_to_install)
-  modules_to_install := \
-      $(filter-out $(foreach p,$(overridden_packages),$(p) %/$(p).apk %/$(p).odex %/$(p).vdex), \
-          $(modules_to_install))
-endif
-#$(error filtered out
-#           $(filter-out $(modules_to_install),$(old_modules_to_install)))
-
 # Don't include any GNU General Public License shared objects or static
 # libraries in SDK images.  GPL executables (not static/dynamic libraries)
 # are okay if they don't link against any closed source libraries (directly
@@ -1264,6 +1246,7 @@
 # dist_files only for putting your library into the dist directory with a full build.
 .PHONY: dist_files
 
+.PHONY: apps_only
 ifneq ($(TARGET_BUILD_APPS),)
   # If this build is just for apps, only build apps and not the full system by default.
 
@@ -1300,7 +1283,6 @@
   $(COVERAGE_ZIP) : $(apps_only_installed_files)
   $(call dist-for-goals,apps_only, $(COVERAGE_ZIP))
 
-.PHONY: apps_only
 apps_only: $(unbundled_build_modules)
 
 droid_targets: apps_only
@@ -1455,6 +1437,12 @@
 	$(dump-products)
 	@echo Successfully dumped products
 
+.PHONY: dump-files
+dump-files:
+	$(info product_FILES for $(TARGET_DEVICE) ($(INTERNAL_PRODUCT)):)
+	$(foreach p,$(product_FILES),$(info :   $(p)))
+	@echo Successfully dumped product file list
+
 .PHONY: nothing
 nothing:
 	@echo Successfully read the makefiles.
diff --git a/core/multi_prebuilt.mk b/core/multi_prebuilt.mk
index 77c57ab..c97d481 100644
--- a/core/multi_prebuilt.mk
+++ b/core/multi_prebuilt.mk
@@ -38,7 +38,6 @@
 # $(2): IS_HOST_MODULE
 # $(3): MODULE_CLASS
 # $(4): MODULE_TAGS
-# $(5): OVERRIDE_BUILT_MODULE_PATH
 # $(6): UNINSTALLABLE_MODULE
 # $(7): BUILT_MODULE_STEM
 # $(8): LOCAL_STRIP_MODULE
@@ -56,7 +55,6 @@
   $(eval LOCAL_IS_HOST_MODULE := $(2)) \
   $(eval LOCAL_MODULE_CLASS := $(3)) \
   $(eval LOCAL_MODULE_TAGS := $(4)) \
-  $(eval OVERRIDE_BUILT_MODULE_PATH := $(5)) \
   $(eval LOCAL_UNINSTALLABLE_MODULE := $(6)) \
   $(eval tw := $(subst :, ,$(strip $(t)))) \
   $(if $(word 3,$(tw)),$(error $(LOCAL_PATH): Bad prebuilt filename '$(t)')) \
@@ -98,7 +96,7 @@
     $(prebuilt_is_host), \
     SHARED_LIBRARIES, \
     $(prebuilt_module_tags), \
-    $($(if $(prebuilt_is_host),HOST,TARGET)_OUT_INTERMEDIATE_LIBRARIES), \
+    , \
     , \
     , \
     $(prebuilt_strip_module))
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 0208288..9343415 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -413,15 +413,14 @@
     resource_export_package := $(intermediates.COMMON)/package-export.apk
     $(R_file_stamp): $(resource_export_package)
 
-    # add-assets-to-package looks at PRODUCT_AAPT_CONFIG, but this target
+    # create-assets-package looks at PRODUCT_AAPT_CONFIG, but this target
     # can't know anything about PRODUCT.  Clear it out just for this target.
     $(resource_export_package): PRIVATE_PRODUCT_AAPT_CONFIG :=
     $(resource_export_package): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
     $(resource_export_package): PRIVATE_RESOURCE_LIST := $(all_res_assets)
     $(resource_export_package): $(all_res_assets) $(full_android_manifest) $(rs_generated_res_zip) $(AAPT)
 	@echo "target Export Resources: $(PRIVATE_MODULE) ($@)"
-	$(create-empty-package)
-	$(add-assets-to-package)
+	$(call create-assets-package,$@)
   endif
 
 endif  # LOCAL_USE_AAPT2
@@ -604,15 +603,13 @@
 endif
 
 ifeq ($(module_run_appcompat),true)
-$(LOCAL_BUILT_MODULE) : $(call intermediates-dir-for,PACKAGING,veridex,HOST)/veridex.zip
+$(LOCAL_BUILT_MODULE) : $(appcompat-files)
 $(LOCAL_BUILT_MODULE): PRIVATE_INSTALLED_MODULE := $(LOCAL_INSTALLED_MODULE)
 endif
 
-$(LOCAL_BUILT_MODULE): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
 $(LOCAL_BUILT_MODULE): PRIVATE_RESOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/resources
-$(LOCAL_BUILT_MODULE): PRIVATE_FULL_CLASSES_JAR := $(full_classes_jar)
 $(LOCAL_BUILT_MODULE) : $(jni_shared_libraries)
-$(LOCAL_BUILT_MODULE) : $(JAR_ARGS)
+$(LOCAL_BUILT_MODULE) : $(JAR_ARGS) $(SOONG_ZIP) $(MERGE_ZIPS) $(ZIP2ZIP)
 ifeq ($(LOCAL_USE_AAPT2),true)
 $(LOCAL_BUILT_MODULE): PRIVATE_RES_PACKAGE := $(my_res_package)
 $(LOCAL_BUILT_MODULE) : $(my_res_package) $(AAPT2) | $(ACP)
@@ -623,27 +620,30 @@
 ifdef LOCAL_COMPRESSED_MODULE
 $(LOCAL_BUILT_MODULE) : $(MINIGZIP)
 endif
+ifneq ($(BUILD_PLATFORM_ZIP),)
+$(LOCAL_BUILT_MODULE) : .KATI_IMPLICIT_OUTPUTS := $(dir $(LOCAL_BUILT_MODULE))package.dex.apk
+endif
+$(LOCAL_BUILT_MODULE):
 	@echo "target Package: $(PRIVATE_MODULE) ($@)"
+	rm -rf $@.parts
+	mkdir -p $@.parts
 ifeq ($(LOCAL_USE_AAPT2),true)
-	$(call copy-file-to-new-target)
+	cp -f $(PRIVATE_RES_PACKAGE) $@.parts/apk.zip
 else  # ! LOCAL_USE_AAPT2
-	$(if $(PRIVATE_SOURCE_ARCHIVE),\
-	  $(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@),\
-	  $(create-empty-package))
-	$(add-assets-to-package)
+	$(call create-assets-package,$@.parts/apk.zip)
 endif  # LOCAL_USE_AAPT2
 ifneq ($(jni_shared_libraries),)
-	$(add-jni-shared-libs-to-package)
+	$(call create-jni-shared-libs-package,$@.parts/jni.zip)
 endif
 ifeq ($(full_classes_jar),)
 # We don't build jar, need to add the Java resources here.
-	$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call add-java-resources-to,$@))
+	$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call create-java-resources-jar,$@.parts/res.zip))
 else  # full_classes_jar
-	$(add-dex-to-package)
-ifeq ($(LOCAL_USE_AAPT2),true)
-	$(call add-jar-resources-to-package,$@,$(PRIVATE_FULL_CLASSES_JAR),$(PRIVATE_RESOURCE_INTERMEDIATES_DIR))
-endif
+	$(call create-dex-jar,$@.parts/dex.zip,$(PRIVATE_DEX_FILE))
+	$(call extract-resources-jar,$@.parts/res.zip,$(PRIVATE_SOURCE_ARCHIVE))
 endif  # full_classes_jar
+	$(MERGE_ZIPS) $@ $@.parts/*.zip
+	rm -rf $@.parts
 ifeq (true, $(LOCAL_UNCOMPRESS_DEX))
 	@# No need to align, sign-package below will do it.
 	$(uncompress-dexs)
@@ -688,7 +688,7 @@
 # Use pattern rule - we may have multiple built odex files.
 $(built_odex) : $(dir $(LOCAL_BUILT_MODULE))% : $(built_dex)
 	$(hide) mkdir -p $(dir $@) && rm -f $@
-	$(add-dex-to-package)
+	$(call create-dex-jar,$@,$(PRIVATE_DEX_FILE))
 ifeq (true, $(LOCAL_UNCOMPRESS_DEX))
 	$(uncompress-dexs)
 	$(align-package)
diff --git a/core/pdk_config.mk b/core/pdk_config.mk
index 4c582e3..b2c9e9e 100644
--- a/core/pdk_config.mk
+++ b/core/pdk_config.mk
@@ -13,8 +13,6 @@
 # all paths under out dir
 PDK_PLATFORM_JAVA_ZIP_JAVA_TARGET_LIB_DIR += \
   target/common/obj/JAVA_LIBRARIES/android.test.runner_intermediates \
-  target/common/obj/JAVA_LIBRARIES/android.hidl.base-V1.0-java_intermediates \
-  target/common/obj/JAVA_LIBRARIES/android.hidl.manager-V1.0-java_intermediates \
   target/common/obj/JAVA_LIBRARIES/android-common_intermediates \
   target/common/obj/JAVA_LIBRARIES/android-ex-camera2_intermediates \
   target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates \
@@ -176,11 +174,15 @@
   # files under $(PRODUCT_OUT)/symbols to help debugging.
   # Source not included to PDK due to dependency issue, so provide symbols instead.
 
-  # We may not be building all of them.
-  # The platform.zip just silently ignores the nonexistent ones.
-  PDK_SYMBOL_FILES_LIST := \
-      system/bin/app_process32 \
-      system/bin/app_process64
+  PDK_SYMBOL_FILES_LIST :=
+  ifeq ($(TARGET_IS_64_BIT),true)
+    PDK_SYMBOL_FILES_LIST += system/bin/app_process64
+    ifdef TARGET_2ND_ARCH
+      PDK_SYMBOL_FILES_LIST += system/bin/app_process32
+    endif
+  else
+    PDK_SYMBOL_FILES_LIST += system/bin/app_process32
+  endif
 
   ifneq (,$(PDK_FUSION_PLATFORM_ZIP)$(PDK_FUSION_PLATFORM_DIR))
     # symbols should be explicitly pulled for fusion build
diff --git a/core/prebuilt.mk b/core/prebuilt.mk
index 839e14f..fb08625 100644
--- a/core/prebuilt.mk
+++ b/core/prebuilt.mk
@@ -47,7 +47,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # secondary arch is supported
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
@@ -66,7 +65,6 @@
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # host cross compilation is supported
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
@@ -81,7 +79,6 @@
 LOCAL_HOST_PREFIX := $(my_prefix)
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 78da421..9ea29fa 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -44,18 +44,6 @@
   $(LOCAL_STRIP_MODULE))
 
 ifeq (SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS))
-  # LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES indicates that this prebuilt should be
-  # installed to the common directory of libraries. This is needed for the NDK
-  # shared libraries built by soong, as we build many different versions of each
-  # library (one for each API level). Since they all have the same basename,
-  # they'd clobber each other (as well as any platform libraries by the same
-  # name).
-  ifneq ($(LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES),false)
-    # Put the built targets of all shared libraries in a common directory
-    # to simplify the link line.
-    OVERRIDE_BUILT_MODULE_PATH :=  \
-        $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)
-  endif
   ifeq ($(LOCAL_IS_HOST_MODULE)$(my_strip_module),)
     # Strip but not try to add debuglink
     my_strip_module := no_debuglink
@@ -68,20 +56,6 @@
   prebuilt_module_is_a_library :=
 endif
 
-ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-  ifeq ($(prebuilt_module_is_a_library),true)
-    SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
-  endif
-
-  ifdef LOCAL_USE_VNDK
-    name_without_suffix := $(patsubst %.vendor,%,$(LOCAL_MODULE))
-    ifneq ($(name_without_suffix),$(LOCAL_MODULE)
-      SPLIT_VENDOR.$(LOCAL_MODULE_CLASS).$(name_without_suffix) := 1
-    endif
-    name_without_suffix :=
-  endif
-endif
-
 # Don't install static libraries by default.
 ifndef LOCAL_UNINSTALLABLE_MODULE
 ifeq (STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS))
@@ -156,12 +130,6 @@
 ifdef prebuilt_module_is_a_library
 export_includes := $(intermediates)/export_includes
 export_cflags := $(foreach d,$(LOCAL_EXPORT_C_INCLUDE_DIRS),-I $(d))
-# Soong exports cflags instead of include dirs, so that -isystem can be included.
-ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-export_cflags += $(LOCAL_EXPORT_CFLAGS)
-else ifdef LOCAL_EXPORT_CFLAGS
-$(call pretty-error,LOCAL_EXPORT_CFLAGS can only be used by Soong, use LOCAL_EXPORT_C_INCLUDE_DIRS instead)
-endif
 $(export_includes): PRIVATE_EXPORT_CFLAGS := $(export_cflags)
 $(export_includes): $(LOCAL_EXPORT_C_INCLUDE_DEPS)
 	@echo Export includes file: $< -- $@
@@ -210,21 +178,11 @@
 # Extra shared libraries introduced by LOCAL_CXX_STL.
 include $(BUILD_SYSTEM)/cxx_stl_setup.mk
 ifdef LOCAL_USE_VNDK
-  ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-    my_shared_libraries := $(foreach l,$(my_shared_libraries),\
-      $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
-  endif
+  my_shared_libraries := $(foreach l,$(my_shared_libraries),\
+    $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
 endif
 $(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
   $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(my_shared_libraries))
-
-# We also need the LOCAL_BUILT_MODULE dependency,
-# since we use -rpath-link which points to the built module's path.
-my_built_shared_libraries := \
-    $(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
-    $(addsuffix $($(my_prefix)SHLIB_SUFFIX), \
-        $(my_shared_libraries)))
-$(LOCAL_BUILT_MODULE) : $(my_built_shared_libraries)
 endif
 endif
 
@@ -390,10 +348,13 @@
 endif
 
 ifeq ($(module_run_appcompat),true)
-$(built_module) : $(call intermediates-dir-for,PACKAGING,veridex,HOST)/veridex.zip
+$(built_module) : $(appcompat-files)
 $(LOCAL_BUILT_MODULE): PRIVATE_INSTALLED_MODULE := $(LOCAL_INSTALLED_MODULE)
 endif
 
+ifneq ($(BUILD_PLATFORM_ZIP),)
+$(built_module) : .KATI_IMPLICIT_OUTPUTS := $(dir $(LOCAL_BUILT_MODULE))package.dex.apk
+endif
 $(built_module) : $(my_prebuilt_src_file) | $(ZIPALIGN) $(SIGNAPK_JAR)
 	$(transform-prebuilt-to-target)
 	$(uncompress-shared-libs)
diff --git a/core/shared_library.mk b/core/shared_library.mk
index a15b1a6..2832c17 100644
--- a/core/shared_library.mk
+++ b/core/shared_library.mk
@@ -36,7 +36,6 @@
 
 ifeq ($(my_module_arch_supported),true)
 # Build for TARGET_2ND_ARCH
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
diff --git a/core/shared_library_internal.mk b/core/shared_library_internal.mk
index ab887e0..41e6a95 100644
--- a/core/shared_library_internal.mk
+++ b/core/shared_library_internal.mk
@@ -13,9 +13,6 @@
 ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
 LOCAL_MODULE_SUFFIX := $(TARGET_SHLIB_SUFFIX)
 endif
-ifneq ($(strip $(OVERRIDE_BUILT_MODULE_PATH)),)
-$(error $(LOCAL_PATH): Illegal use of OVERRIDE_BUILT_MODULE_PATH)
-endif
 ifneq ($(strip $(LOCAL_MODULE_STEM)$(LOCAL_BUILT_MODULE_STEM)$(LOCAL_MODULE_STEM_32)$(LOCAL_MODULE_STEM_64)),)
 $(error $(LOCAL_PATH): Cannot set module stem for a library)
 endif
@@ -34,10 +31,6 @@
 
 ifndef skip_build_from_source
 
-# Put the built targets of all shared libraries in a common directory
-# to simplify the link line.
-OVERRIDE_BUILT_MODULE_PATH := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)
-
 include $(BUILD_SYSTEM)/dynamic_binary.mk
 
 # Define PRIVATE_ variables from global vars
@@ -51,11 +44,11 @@
 my_target_crtbegin_so_o :=
 my_target_crtend_so_o :=
 else ifdef LOCAL_USE_VNDK
-my_target_crtbegin_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.vendor.o
-my_target_crtend_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.vendor.o
+my_target_crtbegin_so_o := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJECT_crtbegin_so.vendor)
+my_target_crtend_so_o := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJECT_crtend_so.vendor)
 else
-my_target_crtbegin_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
-my_target_crtend_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
+my_target_crtbegin_so_o := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJECT_crtbegin_so)
+my_target_crtend_so_o := $(SOONG_$(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJECT_crtend_so)
 endif
 ifneq ($(LOCAL_SDK_VERSION),)
 my_target_crtbegin_so_o := $(wildcard $(my_ndk_sysroot_lib)/crtbegin_so.o)
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index 241a2f4..d02cba6 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -43,8 +43,6 @@
 endif # TURBINE_ENABLED != false
 
 
-$(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_BUILT_MODULE)))
-
 ifdef LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE
 resource_export_package := $(intermediates.COMMON)/package-export.apk
 resource_export_stamp := $(intermediates.COMMON)/src/R.stamp
@@ -61,14 +59,22 @@
 
 java-dex: $(LOCAL_SOONG_DEX_JAR)
 
-ifdef LOCAL_DEX_PREOPT
 # defines built_odex along with rule to install odex
 include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
 
-$(built_odex): $(LOCAL_SOONG_DEX_JAR)
-	$(call dexpreopt-one-file,$<,$@)
+ifneq ($(BUILD_PLATFORM_ZIP),)
+  $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(dir $(LOCAL_BUILT_MODULE))package.dex.apk))
 endif
 
+ifdef LOCAL_DEX_PREOPT
+  $(built_odex): $(LOCAL_SOONG_DEX_JAR)
+	$(call dexpreopt-one-file,$<,$@)
+  $(eval $(call dexpreopt-copy-jar,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_BUILT_MODULE),$(LOCAL_DEX_PREOPT)))
+else
+  $(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_BUILT_MODULE)))
+endif
+
+
 PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
 ifdef LOCAL_CERTIFICATE
   PACKAGES.$(LOCAL_MODULE).CERTIFICATE := $(LOCAL_CERTIFICATE)
diff --git a/core/soong_cc_prebuilt.mk b/core/soong_cc_prebuilt.mk
new file mode 100644
index 0000000..9f2030e
--- /dev/null
+++ b/core/soong_cc_prebuilt.mk
@@ -0,0 +1,180 @@
+# Native prebuilt coming from Soong.
+# Extra inputs:
+# LOCAL_SOONG_LINK_TYPE
+# LOCAL_SOONG_TOC
+# LOCAL_SOONG_UNSTRIPPED_BINARY
+
+ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+  $(call pretty-error,soong_cc_prebuilt.mk may only be used from Soong)
+endif
+
+skip_module :=
+ifdef LOCAL_IS_HOST_MODULE
+  ifneq ($(HOST_OS),$(LOCAL_MODULE_HOST_OS))
+    my_prefix := HOST_CROSS_
+    LOCAL_HOST_PREFIX := $(my_prefix)
+  else
+    my_prefix := HOST_
+    LOCAL_HOST_PREFIX :=
+  endif
+else
+  my_prefix := TARGET_
+endif
+
+ifeq ($($(my_prefix)ARCH),$(LOCAL_MODULE_$(my_prefix)ARCH))
+  # primary arch
+  LOCAL_2ND_ARCH_VAR_PREFIX :=
+else ifeq ($($(my_prefix)2ND_ARCH),$(LOCAL_MODULE_$(my_prefix)ARCH))
+  # secondary arch
+  LOCAL_2ND_ARCH_VAR_PREFIX := $($(my_prefix)2ND_ARCH_VAR_PREFIX)
+else
+  $(call pretty-error,Unsupported LOCAL_MODULE_$(my_prefix)ARCH=$(LOCAL_MODULE_$(my_prefix)ARCH))
+endif
+
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+  ifndef LOCAL_IS_HOST_MODULE
+    ifdef LOCAL_2ND_ARCH_VAR_PREFIX
+      # Only support shared and static libraries and tests for translated arch
+      ifeq ($(filter SHARED_LIBRARIES STATIC_LIBRARIES HEADER_LIBRARIES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
+        skip_module := true
+      endif
+    endif
+  endif
+endif
+
+ifndef skip_module
+
+# Don't install static libraries by default.
+ifndef LOCAL_UNINSTALLABLE_MODULE
+  ifeq (STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS))
+    LOCAL_UNINSTALLABLE_MODULE := true
+  endif
+endif
+
+#######################################
+include $(BUILD_SYSTEM)/base_rules.mk
+#######################################
+
+ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES HEADER_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
+  # Soong module is a static or shared library
+  export_includes := $(intermediates)/export_includes
+  $(export_includes): PRIVATE_EXPORT_CFLAGS := $(LOCAL_EXPORT_CFLAGS)
+  $(export_includes): $(LOCAL_EXPORT_C_INCLUDE_DEPS)
+	@echo Export includes file: $< -- $@
+	$(hide) mkdir -p $(dir $@) && rm -f $@
+  ifdef LOCAL_EXPORT_CFLAGS
+	$(hide) echo "$(PRIVATE_EXPORT_CFLAGS)" >$@
+  else
+	$(hide) touch $@
+  endif
+
+  ifdef LOCAL_SOONG_TOC
+    $(eval $(call copy-one-file,$(LOCAL_SOONG_TOC),$(LOCAL_BUILT_MODULE).toc))
+    $(call add-dependency,$(LOCAL_BUILT_MODULE).toc,$(LOCAL_BUILT_MODULE))
+    $(my_all_targets): $(LOCAL_BUILT_MODULE).toc
+  endif
+
+  SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
+
+  my_link_type := $(LOCAL_SOONG_LINK_TYPE)
+  my_warn_types :=
+  my_allowed_types :=
+  my_link_deps :=
+  my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+  my_common :=
+  include $(BUILD_SYSTEM)/link_type.mk
+endif
+
+ifdef LOCAL_USE_VNDK
+  name_without_suffix := $(patsubst %.vendor,%,$(LOCAL_MODULE))
+  ifneq ($(name_without_suffix),$(LOCAL_MODULE)
+    SPLIT_VENDOR.$(LOCAL_MODULE_CLASS).$(name_without_suffix) := 1
+  endif
+  name_without_suffix :=
+endif
+
+# The real dependency will be added after all Android.mks are loaded and the install paths
+# of the shared libraries are determined.
+ifdef LOCAL_INSTALLED_MODULE
+  ifdef LOCAL_SHARED_LIBRARIES
+    my_shared_libraries := $(LOCAL_SHARED_LIBRARIES)
+    ifdef LOCAL_USE_VNDK
+      my_shared_libraries := $(foreach l,$(my_shared_libraries),\
+        $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
+    endif
+    $(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
+      $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(my_shared_libraries))
+  endif
+endif
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_PREBUILT_MODULE_FILE)
+	$(transform-prebuilt-to-target)
+ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
+	$(hide) chmod +x $@
+endif
+
+ifndef LOCAL_IS_HOST_MODULE
+  ifdef LOCAL_SOONG_UNSTRIPPED_BINARY
+    # Store a copy with symbols for symbolic debugging
+    my_unstripped_path := $(TARGET_OUT_UNSTRIPPED)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
+    symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem)
+    $(eval $(call copy-one-file,$(LOCAL_SOONG_UNSTRIPPED_BINARY),$(symbolic_output)))
+    $(call add-dependency,$(LOCAL_BUILT_MODULE),$(symbolic_output))
+
+    ifeq ($(BREAKPAD_GENERATE_SYMBOLS),true)
+      my_breakpad_path := $(TARGET_OUT_BREAKPAD)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
+      breakpad_output := $(my_breakpad_path)/$(my_installed_module_stem).sym
+      $(breakpad_output) : $(LOCAL_SOONG_UNSTRIPPED_BINARY) | $(BREAKPAD_DUMP_SYMS) $(PRIVATE_READELF)
+	@echo "target breakpad: $(PRIVATE_MODULE) ($@)"
+	@mkdir -p $(dir $@)
+	$(hide) if $(PRIVATE_READELF) -S $< > /dev/null 2>&1 ; then \
+	  $(BREAKPAD_DUMP_SYMS) -c $< > $@ ; \
+	else \
+	  echo "skipped for non-elf file."; \
+	  touch $@; \
+	fi
+      $(call add-dependency,$(LOCAL_BUILT_MODULE),$(breakpad_output))
+    endif
+  endif
+endif
+
+ifeq ($(NATIVE_COVERAGE),true)
+  ifneq (,$(strip $(LOCAL_PREBUILT_COVERAGE_ARCHIVE)))
+    $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(intermediates)/$(LOCAL_MODULE).gcnodir))
+    ifneq ($(LOCAL_UNINSTALLABLE_MODULE),true)
+      ifdef LOCAL_IS_HOST_MODULE
+        my_coverage_path := $($(my_prefix)OUT_COVERAGE)/$(patsubst $($(my_prefix)OUT)/%,%,$(my_module_path))
+      else
+        my_coverage_path := $(TARGET_OUT_COVERAGE)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
+      endif
+      my_coverage_path := $(my_coverage_path)/$(patsubst %.so,%,$(my_installed_module_stem)).gcnodir
+      $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(my_coverage_path)))
+      $(LOCAL_BUILT_MODULE): $(my_coverage_path)
+    endif
+  else
+    # Coverage information is needed when static lib is a dependency of another
+    # coverage-enabled module.
+    ifeq (STATIC_LIBRARIES, $(LOCAL_MODULE_CLASS))
+      GCNO_ARCHIVE := $(LOCAL_MODULE).gcnodir
+      $(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_OBJECTS :=
+      $(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_WHOLE_STATIC_LIBRARIES :=
+      $(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_PREFIX := $(my_prefix)
+      $(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_2ND_ARCH_VAR_PREFIX := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+      $(intermediates)/$(GCNO_ARCHIVE) :
+	$(transform-o-to-static-lib)
+    endif
+  endif
+endif
+
+# A product may be configured to strip everything in some build variants.
+# We do the stripping as a post-install command so that LOCAL_BUILT_MODULE
+# is still with the symbols and we don't need to clean it (and relink) when
+# you switch build variant.
+ifneq ($(filter $(STRIP_EVERYTHING_BUILD_VARIANTS),$(TARGET_BUILD_VARIANT)),)
+$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := \
+  $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP) --strip-all $(LOCAL_INSTALLED_MODULE)
+endif
+
+endif # !skip_module
+
+skip_module :=
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 998e23d..e61aad0 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -115,6 +115,7 @@
 $(call add_json_str,  BtConfigIncludeDir,                $(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR))
 $(call add_json_bool, Device_uses_hwc2,                  $(filter true,$(TARGET_USES_HWC2)))
 $(call add_json_list, DeviceKernelHeaders,               $(TARGET_PROJECT_SYSTEM_INCLUDES))
+$(call add_json_bool, DevicePrefer32BitApps,             $(filter true,$(TARGET_PREFER_32_BIT_APPS)))
 $(call add_json_bool, DevicePrefer32BitExecutables,      $(filter true,$(TARGET_PREFER_32_BIT_EXECUTABLES)))
 $(call add_json_str,  DeviceVndkVersion,                 $(BOARD_VNDK_VERSION))
 $(call add_json_str,  Platform_vndk_version,             $(PLATFORM_VNDK_VERSION))
diff --git a/core/soong_droiddoc_prebuilt.mk b/core/soong_droiddoc_prebuilt.mk
index 510609b..08df019 100644
--- a/core/soong_droiddoc_prebuilt.mk
+++ b/core/soong_droiddoc_prebuilt.mk
@@ -23,3 +23,17 @@
 ifdef LOCAL_DROIDDOC_ANNOTATIONS_ZIP
 $(eval $(call copy-one-file,$(LOCAL_DROIDDOC_ANNOTATIONS_ZIP),$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(LOCAL_MODULE)_annotations.zip))
 endif
+
+ifdef LOCAL_DROIDDOC_API_VERSIONS_XML
+$(eval $(call copy-one-file,$(LOCAL_DROIDDOC_API_VERSIONS_XML),$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(LOCAL_MODULE)_generated-api-versions.xml))
+endif
+
+ifdef LOCAL_DROIDDOC_JDIFF_DOC_ZIP
+$(eval $(call copy-one-file,$(LOCAL_DROIDDOC_JDIFF_DOC_ZIP),$(OUT_DOCS)/$(LOCAL_MODULE)-jdiff-docs.zip))
+$(call dist-for-goals,docs,$(OUT_DOCS)/$(LOCAL_MODULE)-jdiff-docs.zip)
+
+ALL_DOCS += $(OUT_DOCS)/$(LOCAL_MODULE)-jdiff-docs.zip
+
+.PHONY: $(LOCAL_MODULE)-jdiff
+$(LOCAL_MODULE)-jdiff : $(OUT_DOCS)/$(LOCAL_MODULE)-jdiff-docs.zip
+endif
diff --git a/core/static_library.mk b/core/static_library.mk
index 25e5279..8002e5c 100644
--- a/core/static_library.mk
+++ b/core/static_library.mk
@@ -21,7 +21,6 @@
 
 ifeq ($(my_module_arch_supported),true)
 # Build for TARGET_2ND_ARCH
-OVERRIDE_BUILT_MODULE_PATH :=
 LOCAL_BUILT_MODULE :=
 LOCAL_INSTALLED_MODULE :=
 LOCAL_INTERMEDIATE_TARGETS :=
diff --git a/core/strings.mk b/core/strings.mk
new file mode 100644
index 0000000..98dbb0f
--- /dev/null
+++ b/core/strings.mk
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2018 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.
+#
+
+###########################################################
+## Convert to lower case without requiring a shell, which isn't cacheable.
+##
+## $(1): string
+###########################################################
+to-lower=$(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
+
+###########################################################
+## Convert to upper case without requiring a shell, which isn't cacheable.
+##
+## $(1): string
+###########################################################
+to-upper=$(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$1))))))))))))))))))))))))))
+
+# Sanity-check to-lower and to-upper
+lower := abcdefghijklmnopqrstuvwxyz-_
+upper := ABCDEFGHIJKLMNOPQRSTUVWXYZ-_
+
+ifneq ($(lower),$(call to-lower,$(upper)))
+  $(error to-lower sanity check failure)
+endif
+
+ifneq ($(upper),$(call to-upper,$(lower)))
+  $(error to-upper sanity check failure)
+endif
+
+lower :=
+upper :=
diff --git a/core/tasks/apidiff.mk b/core/tasks/apidiff.mk
index 4eb59af..76e4749 100644
--- a/core/tasks/apidiff.mk
+++ b/core/tasks/apidiff.mk
@@ -18,4 +18,4 @@
 
 .PHONY: api-diff
 
-api-diff: offline-sdk-referenceonly-diff
+api-diff: api-stubs-docs-jdiff
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index ff83357..9eb3ab3 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -15,6 +15,8 @@
 			'"auto_test_config": [$(ALL_MODULES.$(m).auto_test_config)], ' \
 			'"module_name": "$(ALL_MODULES.$(m).MODULE_NAME)", ' \
 			'"test_config": [$(if $(ALL_MODULES.$(m).TEST_CONFIG),"$(ALL_MODULES.$(m).TEST_CONFIG)")], ' \
+			'"dependencies": [$(foreach w,$(sort $(ALL_DEPS.$(m).ALL_DEPS)),"$(w)", )], ' \
+			'"srcs": [$(foreach w,$(sort $(ALL_MODULES.$(m).SRCS)),"$(w)", )], ' \
 			'},\n' \
 	 ) | sed -e 's/, *\]/]/g' -e 's/, *\}/ }/g' -e '$$s/,$$//' >> $@
 	$(hide) echo '}' >> $@
@@ -26,3 +28,4 @@
 files: $(MODULE_INFO_JSON)
 endif
 
+$(call dist-for-goals, general-tests, $(MODULE_INFO_JSON))
diff --git a/core/tasks/owners.mk b/core/tasks/owners.mk
new file mode 100644
index 0000000..6f32aaf
--- /dev/null
+++ b/core/tasks/owners.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2018 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.
+# Create an artifact to include TEST_MAPPING files in source tree.
+
+.PHONY: owners
+
+intermediates := $(call intermediates-dir-for,PACKAGING,owners)
+owners_zip := $(intermediates)/owners.zip
+owners_list := $(OUT_DIR)/.module_paths/OWNERS.list
+owners := $(file <$(owners_list))
+$(owners_zip) : PRIVATE_owners := $(subst $(newline),\n,$(owners))
+
+$(owners_zip) : $(owners) $(SOONG_ZIP)
+	@echo "Building artifact to include OWNERS files."
+	rm -rf $@
+	echo -e "$(PRIVATE_owners)" > $@.list
+	$(SOONG_ZIP) -o $@ -C . -l $@.list
+	rm -f $@.list
+
+owners : $(owners_zip)
+
+$(call dist-for-goals, general-tests, $(owners_zip))
diff --git a/core/tasks/sdk-addon.mk b/core/tasks/sdk-addon.mk
index 29abf48..8baac5a 100644
--- a/core/tasks/sdk-addon.mk
+++ b/core/tasks/sdk-addon.mk
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+ifndef ONE_SHOT_MAKEFILE
+
 .PHONY: sdk_addon
 
 # If they didn't define PRODUCT_SDK_ADDON_NAME, then we won't define
@@ -71,6 +73,12 @@
 	$(addon_dir_img):$(target_notice_file_txt):images/$(TARGET_CPU_ABI)/NOTICE.txt \
 	$(addon_dir_img):$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SDK_ADDON_SYS_IMG_SOURCE_PROP):images/source.properties
 
+
+ifeq ($(BOARD_AVB_ENABLE),true)
+files_to_copy += \
+	$(addon_dir_img):$(QEMU_VERIFIED_BOOT_PARAMS):images/$(TARGET_CPU_ABI)/VerifiedBootParams.textproto
+endif
+
 # Generate rules to copy the requested files
 $(foreach cf,$(files_to_copy), \
   $(eval _root := $(call word-colon,1,$(cf))) \
@@ -141,3 +149,5 @@
 $(error Trying to build sdk_addon, but product '$(INTERNAL_PRODUCT)' does not define one)
 endif
 endif # addon_name
+
+endif # !ONE_SHOT_MAKEFILE
diff --git a/envsetup.sh b/envsetup.sh
index 5894144..5cbd9eb 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -585,7 +585,13 @@
         local choices=($(TARGET_BUILD_APPS= LUNCH_MENU_CHOICES="${LUNCH_MENU_CHOICES[@]}" get_build_var COMMON_LUNCH_CHOICES))
         if [ $answer -le ${#choices[@]} ]
         then
-            selection=${choices[$(($answer-1))]}
+            # array in zsh starts from 1 instead of 0.
+            if [ -n "$ZSH_VERSION" ]
+            then
+                selection=${choices[$(($answer))]}
+            else
+                selection=${choices[$(($answer-1))]}
+            fi
         fi
     else
         selection=$answer
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index c1983ad..25e51ba 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -23,7 +23,7 @@
 TARGET_2ND_CPU_ABI := armeabi-v7a
 TARGET_2ND_CPU_ABI2 := armeabi
 
-ifneq ($(TARGET_BUILD_APPS)$(filter cts sdk,$(MAKECMDGOALS)),)
+ifneq ($(TARGET_BUILD_APPS)$(filter cts vts sdk,$(MAKECMDGOALS)),)
 # DO NOT USE
 # DO NOT USE
 #
diff --git a/target/product/aosp_arm.mk b/target/product/aosp_arm.mk
index f0752a8..795f8aa 100644
--- a/target/product/aosp_arm.mk
+++ b/target/product/aosp_arm.mk
@@ -38,4 +38,7 @@
 # Needed by Pi newly launched device to pass VtsTrebleSysProp on GSI
 PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true
 
+# Support addtional P vendor interface
+PRODUCT_EXTRA_VNDK_VERSIONS := 28
+
 PRODUCT_NAME := aosp_arm
diff --git a/target/product/aosp_arm64.mk b/target/product/aosp_arm64.mk
index ab23111..f3f3c5a 100644
--- a/target/product/aosp_arm64.mk
+++ b/target/product/aosp_arm64.mk
@@ -54,6 +54,9 @@
 # Needed by Pi newly launched device to pass VtsTrebleSysProp on GSI
 PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true
 
+# Support addtional P vendor interface
+PRODUCT_EXTRA_VNDK_VERSIONS := 28
+
 PRODUCT_NAME := aosp_arm64
 PRODUCT_DEVICE := generic_arm64
 PRODUCT_BRAND := Android
diff --git a/target/product/aosp_x86.mk b/target/product/aosp_x86.mk
index 9d1b14b..e3167af 100644
--- a/target/product/aosp_x86.mk
+++ b/target/product/aosp_x86.mk
@@ -38,4 +38,7 @@
 # Needed by Pi newly launched device to pass VtsTrebleSysProp on GSI
 PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true
 
+# Support addtional P vendor interface
+PRODUCT_EXTRA_VNDK_VERSIONS := 28
+
 PRODUCT_NAME := aosp_x86
diff --git a/target/product/aosp_x86_64.mk b/target/product/aosp_x86_64.mk
index b38c417..222adaa 100644
--- a/target/product/aosp_x86_64.mk
+++ b/target/product/aosp_x86_64.mk
@@ -54,6 +54,9 @@
 # Needed by Pi newly launched device to pass VtsTrebleSysProp on GSI
 PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true
 
+# Support addtional P vendor interface
+PRODUCT_EXTRA_VNDK_VERSIONS := 28
+
 ifdef NET_ETH0_STARTONBOOT
   PRODUCT_PROPERTY_OVERRIDES += net.eth0.startonboot=1
 endif
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index bcbb951..b282048 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -211,6 +211,7 @@
     pppd \
     privapp-permissions-platform.xml \
     racoon \
+    recovery-persist \
     resize2fs \
     run-as \
     schedtest \
@@ -270,9 +271,7 @@
     framework \
     telephony-common \
     voip-common \
-    ims-common \
-    android.hidl.base-V1.0-java \
-    android.hidl.manager-V1.0-java
+    ims-common
 
 # Add the compatibility library that is needed when org.apache.http.legacy
 # is removed from the bootclasspath.
@@ -306,6 +305,7 @@
 # Packages included only for eng or userdebug builds, previously debug tagged
 PRODUCT_PACKAGES_DEBUG := \
     adb_keys \
+    apex_debug_key \
     iotop \
     logpersist.start \
     perfprofd \
diff --git a/target/product/full_base_telephony.mk b/target/product/full_base_telephony.mk
index af4097d..ee59090 100644
--- a/target/product/full_base_telephony.mk
+++ b/target/product/full_base_telephony.mk
@@ -28,4 +28,5 @@
     frameworks/native/data/etc/handheld_core_hardware.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/handheld_core_hardware.xml
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_vendor.mk)
diff --git a/target/product/generic.mk b/target/product/generic.mk
index cc856f4..7a9732d 100644
--- a/target/product/generic.mk
+++ b/target/product/generic.mk
@@ -18,7 +18,8 @@
 # It includes the base Android platform.
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/generic_no_telephony.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_vendor.mk)
 
 # Overrides
 PRODUCT_BRAND := generic
diff --git a/target/product/mainline_arm64.mk b/target/product/mainline_arm64.mk
index 92954db..4e511e1 100644
--- a/target/product/mainline_arm64.mk
+++ b/target/product/mainline_arm64.mk
@@ -16,7 +16,8 @@
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/base_vendor.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_vendor.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_vendor.mk)
 
 PRODUCT_NAME := mainline_arm64
 PRODUCT_DEVICE := generic_arm64
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index 3581c4a..8dec2d9 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -14,15 +14,42 @@
 # limitations under the License.
 #
 
-# This makefile is the basis of a generic system image for a handheld
-# device with no telephony.
+# This makefile is the basis of a generic system image for a handheld device.
 $(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk)
 
-# OTA support.
+# Shared java libs
+PRODUCT_PACKAGES += \
+    com.android.nfc_extras \
+
+# Applications
+PRODUCT_PACKAGES += \
+    DMService \
+    LiveWallpapersPicker \
+    PartnerBookmarksProvider \
+    RcsService \
+    SafetyRegulatoryInfo \
+    Stk \
+
+# OTA support
 PRODUCT_PACKAGES += \
     update_engine \
     update_verifier \
 
+# Wrapped net utils for /vendor access.
+PRODUCT_PACKAGES += \
+    netutils-wrapper-1.0 \
+
+# system_other support
+PRODUCT_PACKAGES += \
+    cppreopts.sh \
+    otapreopt_script \
+
+# Bluetooth libraries
+PRODUCT_PACKAGES += \
+    audio.a2dp.default \
+    audio.hearing_aid.default \
+
 # Enable dynamic partition size
 PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
 
diff --git a/target/product/security/Android.mk b/target/product/security/Android.mk
index 4142ea9..73ebd75 100644
--- a/target/product/security/Android.mk
+++ b/target/product/security/Android.mk
@@ -12,6 +12,19 @@
 include $(BUILD_PREBUILT)
 
 #######################################
+# apex_debug_key for eng/userdebug
+ifneq ($(filter eng userdebug,$(TARGET_BUILD_VARIANT)),)
+  include $(CLEAR_VARS)
+
+  LOCAL_MODULE := apex_debug_key
+  LOCAL_SRC_FILES := $(LOCAL_MODULE)
+  LOCAL_MODULE_CLASS := ETC
+  LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/security/apex
+
+  include $(BUILD_PREBUILT)
+endif
+
+#######################################
 # adb key, if configured via PRODUCT_ADB_KEYS
 ifdef PRODUCT_ADB_KEYS
   ifneq ($(filter eng userdebug,$(TARGET_BUILD_VARIANT)),)
diff --git a/target/product/security/apex_debug_key b/target/product/security/apex_debug_key
new file mode 100644
index 0000000..28bc8f7
--- /dev/null
+++ b/target/product/security/apex_debug_key
Binary files differ
diff --git a/target/product/security/apex_debug_key.pem b/target/product/security/apex_debug_key.pem
new file mode 100644
index 0000000..bd56778
--- /dev/null
+++ b/target/product/security/apex_debug_key.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKgIBAAKCAgEAt4iSfTF+e2khGQf0bUzTMwWFsgaiQbwQB3cvyBlE9XekFXUt
+GdOEhC2J0p+930UoF6gjjRRrgGF+8K5iV1m3oEbB3qGz6UUOurvVkt4tq96e/Q5a
+ogCOZEuWHjZfs2tQUVNJJtptIp9+0cM768vdf+qnK2JNFIhBqSY0FhjVljKevMcM
+w2tWFRZnKPQ3JoRnWqi5CIauQtBcWRFKIApyf41uHGMjpQRd8aTGeLXBRTi/yD73
+HltuKwSF2SXpj1F+9j4stqskQvipjQnid/Wb+nN3CNgyrGuRrtGvz71WWYcK3DLM
+jvGLOl06QrN6a7ZfLUN4qQjJ6Is5SLTSw/sfFE7Fpcbg6/Geh+jSvChuo6EUtzoX
+Qu42HsVXhrJLQ9/AVTWNmGc9IDr4PMtDiQc4FN8MOpUtR6V/zwrZFoeR3PHl9Z7v
+uTxLIcQLIott0mAjPhbNgbFBs5HP1Z8TfFcyZWpShlx+aM1V2mzYQ7sgsWjFKMSQ
+wIUk/YZ9QK/H5WKjC5M0yxueCU0ocvWFaAZ4RyS/r/SUyQpvyNXNwUsdp1a8sNxp
+LP9U7FG64C+T791yoQJ0sKVbts5SEu/Tojw6miYbH6Fspdo2xxfCbrv6SAbkjlct
+afOnEepgTlHet0G+y0N7OZRJ9WRGyLJNgGjmmDy9XSYGAykwwe4Fv348D0cCAwEA
+AQKCAgBuFra/78NNpXbb++CK+20oCqTyb3Y+dd8rizuXDElH8Fb1JA9EkZLIckRc
+mcMbvPDal9mTU29UV6b8Ga4VdVRnCGpb76TqRKkcK3Vlnm3IzUWSx1xoFmtTD9/h
+CX6IMdPApHOZoaWbAg7hJfm4a9XWV9ukc1eG/GBeZPMTWhwr9vsugztNsQG2rnR8
+pVi7eupAADrVOWwn2bG7H1rWM04Q4rXswy7rWd48BzmhyGxA6FRpehNjGzbPCOx8
+n3gkpp7Ad/T8MVYT8fJKDmbQy/ue1EnPfVeQAwok0dRiiNDV7OH/yVzYVVzNSoSa
+4+uH1qHqlbE3u3TZT0GyMfzG38f4scsbvG/AhH1fuPsy4QcWyLlMV6KUnk3KPc3Q
+yOeRR82qndQMTYQ5/PFiilk7cNbTU0OBjuNpu/t1LIE2J2gGZ5Jw+g2NGtM/xsgC
+jOahpRYvZB8fZ/bSjirwwmSSU+v0ZoPDHtt75R/QxqwPG2jai8kaGr7GEXWJfrfv
+CktMnb6LoCyNiiiZSMUgdDHOQEkVNmt9fxiVaxsaIL4BygropwlD4WbuyRMevfYz
+EffvvmaqC24zJi8WzDszCNLgP/piNhXDyxZX+KaQXj0Do/tzWBBkO0OO6mVGOkX2
+6dadXfhOIggWO8K2lKCUKwWMO9LaKwSwZ4gzcc1a+U9rpE8kUQKCAQEA8lBGLzOL
+Ht8+d13SY+NdPbL6qGvoqsKd5BfIhaNbH04Cp2zQs2TWySxmV47df03pGUpQOCKn
+tFRxoczUrf1gfFDCCC95+A/crls8QJHG+MScTBH5U8Q0s9ReUo/0xaa55u77x5uS
+0fAtdnOdqP8/pf1fSXUJvyLW85LWdkge1c7jk7I5MnWVO2Ak9/GkuRgITSSgVdBa
+kr8nU1BCzDY0gOTWo5J1+NqqVH2eYfEI621iD4SAE3n2JrCC4K/Nt2enEJwup2TR
+ym15g9nClicUQP5Y67eDfqTZu1d0I0Ezl1tL8UPxcLI+ucN4V6KL8RvqTVMnGX/R
+s1FwkPVMQ6dKaQKCAQEAweZeggcSFukr+tTbnzDAHxg4YqiR+30wo7i8NadGu6W/
+EiAdcCdmZYMI9KKc+B/N3cuFqBnaSd7VM7XvINdwZRanRj56Ya8LvQMi0S9YPiRn
+T4TXC3EeewN5+SSO0Dkw83tW1PLqgSINy5ijBs5lGoIYMCC+GSA2DuRBiPpcfhqJ
+kmC9uFQvrsge8CC8Sb1wHCr0Wz34qhPoTff6ZV8wm11Jkb5+tT7PMS5Ft0sEBsxV
+R1JFtLNs0k/YpMb4/OrZFZZSIFCTUVPvHQ1/5BwumVnolBC4LORCaSk1xUOydU9h
+bZd4qzIpFteGLGGRT6nEWC1YejLAvcFHVJiKs1F2LwKCAQEAzgnwA8bCLvgIt5rx
+gLod2I7NkFRhPIHLm92VRf0HSHEe1Jo0Q7Yk5F56j00NjmgDItwLpg/hpfZ/wOLY
+nTFrz4kj0636+jESprcxXn4WQAV+GTjXVqDpZ1fW9EEwEriYLoNbV/kzOIwPPD9G
++iJATrZJRb7dEMdhGy/qaB0fCxKmdDoBZKSSxjAUfzfbpv+GX4IbS5ykx07+81q1
+0crtjgQHdoLdCUN1ve4qtIEt4nHaBfPWq7jy0ycXwlH6jE74wajsCq4xrPy1bKXH
+TcHg+PrNRXF/wDoQYboVKL0ST0r0IixxqjAGIhLRy0KN1/CypBlmj8od12oSW1AZ
+DxW6sQKCAQEAtIMW8M5MVO/2dam8XFMySMBvncl5PjuqEIFnFjwIaaFAZEtpnIPR
+nCeFKtpIb+aL7TQP1hNbWPIOYfm6CUUH6dRRHeAEZvRjZS+KNlxxNkkFtM3itVA2
+JCd0YjFakxbrL4FfsRgEoPtnBGexPiDflvIOOqAA2btXGD3/lNofSXbDJHbTqMsX
+KQw9YSfYon2t5UtH+bmTyiKGXi/B+KXJxpnuZ7SEmY9DrHF7jcxUj0+jBKbfJf70
+DEcxVRW3rx2jw6kSA+t/enM9ZDqxGVfzOeit0UpPa9uEyAoJeQAxH20rMq+VMyub
+fRxgWOjsMtHFbKGqgPjG3uEU2vi4B4CLGQKCAQEA2Mr5f2AXPR8jca1+Id+CxZpU
+bgMML7gW31L4lGX9Teo9z+zSdN7sIwqe42Zla1N9wda8p5ribnJxwRdxcPL8bid5
+LLlls4xXD/jQCQCFL90X59Tm6VD6tm1VyCjL44nRwAqP4vJObSB5rTqJYtkfVmnp
+KERF5P0i5yv4Oox0ZOsThou9jtyl1dS50Td0Urhp4LhPdmpDPUq25K1sDDfnGFm6
+IcMPkVznRPUoKQCG9DSQcQqttkSV9Po+qfLa3aHtdndfe88Gd9uom8bsAMTZAfSZ
+D4YhqBHSLWrxvtQ8GxkaPITJv7hocwssdFRUj5/UJKJBgUXPBXEXh+fxlDaGQQ==
+-----END RSA PRIVATE KEY-----
diff --git a/target/product/telephony.mk b/target/product/telephony_system.mk
similarity index 79%
rename from target/product/telephony.mk
rename to target/product/telephony_system.mk
index 38a8caa..3175c8a 100644
--- a/target/product/telephony.mk
+++ b/target/product/telephony_system.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2007 The Android Open Source Project
+# Copyright (C) 2018 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.
@@ -14,8 +14,8 @@
 # limitations under the License.
 #
 
-# This is the list of product-level settings that are specific
-# to products that have telephony hardware.
+# This is the list of modules that are specific to products that have telephony
+# hardware, and install on the system partition.
 
 PRODUCT_PACKAGES := \
     CarrierConfig \
@@ -24,6 +24,5 @@
     CallLogBackup \
     CellBroadcastReceiver \
     EmergencyInfo \
-    rild
 
 PRODUCT_COPY_FILES := \
diff --git a/target/product/telephony.mk b/target/product/telephony_vendor.mk
similarity index 67%
copy from target/product/telephony.mk
copy to target/product/telephony_vendor.mk
index 38a8caa..bddd383 100644
--- a/target/product/telephony.mk
+++ b/target/product/telephony_vendor.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2007 The Android Open Source Project
+# Copyright (C) 2018 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.
@@ -14,16 +14,10 @@
 # limitations under the License.
 #
 
-# This is the list of product-level settings that are specific
-# to products that have telephony hardware.
+# This is the list of modules that are specific to products that have telephony
+# hardware, and install outside the system partition.
 
 PRODUCT_PACKAGES := \
-    CarrierConfig \
-    CarrierDefaultApp \
-    Dialer \
-    CallLogBackup \
-    CellBroadcastReceiver \
-    EmergencyInfo \
-    rild
+    rild \
 
 PRODUCT_COPY_FILES := \
diff --git a/target/product/treble_common.mk b/target/product/treble_common.mk
index 6b0ef2f..d3cce76 100644
--- a/target/product/treble_common.mk
+++ b/target/product/treble_common.mk
@@ -21,7 +21,8 @@
 
 # Generic system image inherits from AOSP with telephony
 $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_vendor.mk)
 
 # Enable dynamic partition size
 PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
@@ -54,5 +55,5 @@
 PRODUCT_PACKAGES += \
     ld.config.vndk_lite.txt
 
-# Support addtional O-MR1 vendor interface
-PRODUCT_EXTRA_VNDK_VERSIONS := 27
+# Support addtional O-MR1 and P vendor interface
+PRODUCT_EXTRA_VNDK_VERSIONS := 27 28
diff --git a/target/product/vndk/current.txt b/target/product/vndk/current.txt
index d70fde6d..b95060f 100644
--- a/target/product/vndk/current.txt
+++ b/target/product/vndk/current.txt
@@ -29,6 +29,7 @@
 VNDK-SP: libbacktrace.so
 VNDK-SP: libbase.so
 VNDK-SP: libbcinfo.so
+VNDK-SP: libbinderthreadstate.so
 VNDK-SP: libblas.so
 VNDK-SP: libc++.so
 VNDK-SP: libcompiler_rt.so
@@ -50,6 +51,7 @@
 VNDK-core: android.frameworks.schedulerservice@1.0.so
 VNDK-core: android.frameworks.sensorservice@1.0.so
 VNDK-core: android.frameworks.vr.composer@1.0.so
+VNDK-core: android.hardware.atrace@1.0.so
 VNDK-core: android.hardware.audio.common-util.so
 VNDK-core: android.hardware.audio.common@2.0.so
 VNDK-core: android.hardware.audio.common@2.0-util.so
@@ -97,7 +99,7 @@
 VNDK-core: android.hardware.graphics.bufferqueue@1.0.so
 VNDK-core: android.hardware.graphics.composer@2.1.so
 VNDK-core: android.hardware.graphics.composer@2.2.so
-VNDK-core: android.hardware.health.filesystem@1.0.so
+VNDK-core: android.hardware.health.storage@1.0.so
 VNDK-core: android.hardware.health@1.0.so
 VNDK-core: android.hardware.health@2.0.so
 VNDK-core: android.hardware.ir@1.0.so
@@ -110,6 +112,7 @@
 VNDK-core: android.hardware.memtrack@1.0.so
 VNDK-core: android.hardware.neuralnetworks@1.0.so
 VNDK-core: android.hardware.neuralnetworks@1.1.so
+VNDK-core: android.hardware.neuralnetworks@1.2.so
 VNDK-core: android.hardware.nfc@1.0.so
 VNDK-core: android.hardware.nfc@1.1.so
 VNDK-core: android.hardware.oemlock@1.0.so
@@ -249,6 +252,7 @@
 VNDK-core: libyuv.so
 VNDK-core: libziparchive.so
 VNDK-private: libbacktrace.so
+VNDK-private: libbinderthreadstate.so
 VNDK-private: libblas.so
 VNDK-private: libcompiler_rt.so
 VNDK-private: libft2.so
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 9e8b698..d7d1bc8 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -72,9 +72,6 @@
 OPTIONS.replace_verity_private_key = False
 OPTIONS.is_signing = False
 
-# Partitions that should have their care_map added to META/care_map.txt.
-PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'product_services',
-                            'odm')
 # Use a fixed timestamp (01/01/2009 00:00:00 UTC) for files when packaging
 # images. (b/24377993, b/80600931)
 FIXED_FILE_TIMESTAMP = int((
@@ -111,16 +108,16 @@
     (which, care_map_ranges): care_map_ranges is the raw string of the care_map
     RangeSet.
   """
-  assert which in PARTITIONS_WITH_CARE_MAP
+  assert which in common.PARTITIONS_WITH_CARE_MAP
 
   simg = sparse_img.SparseImage(imgname)
   care_map_ranges = simg.care_map
-  key = which + "_adjusted_partition_size"
-  adjusted_blocks = OPTIONS.info_dict.get(key)
-  if adjusted_blocks:
-    assert adjusted_blocks > 0, "blocks should be positive for " + which
-    care_map_ranges = care_map_ranges.intersect(rangelib.RangeSet(
-        "0-%d" % (adjusted_blocks,)))
+  key = which + "_image_blocks"
+  image_blocks = OPTIONS.info_dict.get(key)
+  if image_blocks:
+    assert image_blocks > 0, "blocks for {} must be positive".format(which)
+    care_map_ranges = care_map_ranges.intersect(
+        rangelib.RangeSet("0-{}".format(image_blocks)))
 
   return [which, care_map_ranges.to_string_raw()]
 
@@ -311,26 +308,25 @@
   hash_seed = "hash_seed-" + uuid_seed
   image_props["hash_seed"] = str(uuid.uuid5(uuid.NAMESPACE_URL, hash_seed))
 
-  succ = build_image.BuildImage(os.path.join(input_dir, what.upper()),
-                                image_props, output_file.name)
-  assert succ, "build " + what + ".img image failed"
+  build_image.BuildImage(
+      os.path.join(input_dir, what.upper()), image_props, output_file.name)
 
   output_file.Write()
   if block_list:
     block_list.Write()
 
-  # Set the 'adjusted_partition_size' that excludes the verity blocks of the
-  # given image. When avb is enabled, this size is the max image size returned
-  # by the avb tool.
+  # Set the '_image_blocks' that excludes the verity metadata blocks of the
+  # given image. When AVB is enabled, this size is the max image size returned
+  # by the AVB tool.
   is_verity_partition = "verity_block_device" in image_props
   verity_supported = (image_props.get("verity") == "true" or
                       image_props.get("avb_enable") == "true")
   is_avb_enable = image_props.get("avb_hashtree_enable") == "true"
   if verity_supported and (is_verity_partition or is_avb_enable):
-    adjusted_blocks_value = image_props.get("partition_size")
-    if adjusted_blocks_value:
-      adjusted_blocks_key = what + "_adjusted_partition_size"
-      info_dict[adjusted_blocks_key] = int(adjusted_blocks_value)/4096 - 1
+    image_size = image_props.get("image_size")
+    if image_size:
+      image_blocks_key = what + "_image_blocks"
+      info_dict[image_blocks_key] = int(image_size) / 4096 - 1
 
 
 def AddUserdata(output_zip):
@@ -364,8 +360,7 @@
   fstab = OPTIONS.info_dict["fstab"]
   if fstab:
     image_props["fs_type"] = fstab["/data"].fs_type
-  succ = build_image.BuildImage(user_dir, image_props, img.name)
-  assert succ, "build userdata.img image failed"
+  build_image.BuildImage(user_dir, image_props, img.name)
 
   common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict)
   img.Write()
@@ -393,32 +388,46 @@
     cmd.extend(["--include_descriptors_from_image", image])
 
 
-def AddVBMeta(output_zip, partitions):
-  """Creates a VBMeta image and store it in output_zip.
+def AddVBMeta(output_zip, partitions, name, needed_partitions):
+  """Creates a VBMeta image and stores it in output_zip.
+
+  It generates the requested VBMeta image. The requested image could be for
+  top-level or chained VBMeta image, which is determined based on the name.
 
   Args:
     output_zip: The output zip file, which needs to be already open.
     partitions: A dict that's keyed by partition names with image paths as
         values. Only valid partition names are accepted, as listed in
         common.AVB_PARTITIONS.
+    name: Name of the VBMeta partition, e.g. 'vbmeta', 'vbmeta_mainline'.
+    needed_partitions: Partitions whose descriptors should be included into the
+        generated VBMeta image.
+
+  Raises:
+    AssertionError: On invalid input args.
   """
-  img = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "vbmeta.img")
+  assert needed_partitions, "Needed partitions must be specified"
+
+  img = OutputFile(
+      output_zip, OPTIONS.input_tmp, "IMAGES", "{}.img".format(name))
   if os.path.exists(img.input_name):
-    print("vbmeta.img already exists; not rebuilding...")
+    print("{}.img already exists; not rebuilding...".format(name))
     return img.input_name
 
   avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
   cmd = [avbtool, "make_vbmeta_image", "--output", img.name]
-  common.AppendAVBSigningArgs(cmd, "vbmeta")
+  common.AppendAVBSigningArgs(cmd, name)
 
   for partition, path in partitions.items():
+    if partition not in needed_partitions:
+      continue
     assert partition in common.AVB_PARTITIONS, \
         'Unknown partition: {}'.format(partition)
     assert os.path.exists(path), \
         'Failed to find {} for {}'.format(path, partition)
     AppendVBMetaArgsForPartition(cmd, partition, path)
 
-  args = OPTIONS.info_dict.get("avb_vbmeta_args")
+  args = OPTIONS.info_dict.get("avb_{}_args".format(name))
   if args and args.strip():
     split_args = shlex.split(args)
     for index, arg in enumerate(split_args[:-1]):
@@ -439,7 +448,7 @@
             split_args[index + 1] = alt_path
             found = True
             break
-        assert found, 'failed to find %s' % (image_path,)
+        assert found, 'Failed to find {}'.format(image_path)
     cmd.extend(split_args)
 
   p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
@@ -503,8 +512,7 @@
   fstab = OPTIONS.info_dict["fstab"]
   if fstab:
     image_props["fs_type"] = fstab["/cache"].fs_type
-  succ = build_image.BuildImage(user_dir, image_props, img.name)
-  assert succ, "build cache.img image failed"
+  build_image.BuildImage(user_dir, image_props, img.name)
 
   common.CheckSize(img.name, "cache.img", OPTIONS.info_dict)
   img.Write()
@@ -542,19 +550,19 @@
     assert available, "Failed to find " + img_name
 
 
-def AddCareMapTxtForAbOta(output_zip, ab_partitions, image_paths):
-  """Generates and adds care_map.txt for system and vendor partitions.
+def AddCareMapForAbOta(output_zip, ab_partitions, image_paths):
+  """Generates and adds care_map.pb for a/b partition that has care_map.
 
   Args:
     output_zip: The output zip file (needs to be already open), or None to
-        write care_map.txt to OPTIONS.input_tmp/.
+        write care_map.pb to OPTIONS.input_tmp/.
     ab_partitions: The list of A/B partitions.
     image_paths: A map from the partition name to the image path.
   """
   care_map_list = []
   for partition in ab_partitions:
     partition = partition.strip()
-    if partition not in PARTITIONS_WITH_CARE_MAP:
+    if partition not in common.PARTITIONS_WITH_CARE_MAP:
       continue
 
     verity_block_device = "{}_verity_block_device".format(partition)
@@ -565,6 +573,21 @@
       assert os.path.exists(image_path)
       care_map_list += GetCareMap(partition, image_path)
 
+      # adds fingerprint field to the care_map
+      build_props = OPTIONS.info_dict.get(partition + ".build.prop", {})
+      prop_name_list = ["ro.{}.build.fingerprint".format(partition),
+                        "ro.{}.build.thumbprint".format(partition)]
+
+      present_props = [x for x in prop_name_list if x in build_props]
+      if not present_props:
+        print("Warning: fingerprint is not present for partition {}".
+              format(partition))
+        property_id, fingerprint = "unknown", "unknown"
+      else:
+        property_id = present_props[0]
+        fingerprint = build_props[property_id]
+      care_map_list += [property_id, fingerprint]
+
   if not care_map_list:
     return
 
@@ -575,16 +598,16 @@
   with open(temp_care_map_text, 'w') as text_file:
     text_file.write('\n'.join(care_map_list))
 
-  temp_care_map = common.MakeTempFile(prefix="caremap-", suffix=".txt")
-  care_map_gen_cmd = (["care_map_generator", temp_care_map_text, temp_care_map])
+  temp_care_map = common.MakeTempFile(prefix="caremap-", suffix=".pb")
+  care_map_gen_cmd = ["care_map_generator", temp_care_map_text, temp_care_map]
   p = common.Run(care_map_gen_cmd, stdout=subprocess.PIPE,
                  stderr=subprocess.STDOUT)
   output, _ = p.communicate()
-  assert p.returncode == 0, "Failed to generate the care_map proto message."
   if OPTIONS.verbose:
     print(output.rstrip())
+  assert p.returncode == 0, "Failed to generate the care_map proto message."
 
-  care_map_path = "META/care_map.txt"
+  care_map_path = "META/care_map.pb"
   if output_zip and care_map_path not in output_zip.namelist():
     common.ZipWrite(output_zip, temp_care_map, arcname=care_map_path)
   else:
@@ -644,7 +667,7 @@
 def ReplaceUpdatedFiles(zip_filename, files_list):
   """Updates all the ZIP entries listed in files_list.
 
-  For now the list includes META/care_map.txt, and the related files under
+  For now the list includes META/care_map.pb, and the related files under
   SYSTEM/ after rebuilding recovery.
   """
   common.ZipDelete(zip_filename, files_list)
@@ -693,8 +716,8 @@
                 os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
                                             "vendor.img")))
   has_odm = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "ODM")) or
-                 os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
-                                             "odm.img")))
+             os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
+                                         "odm.img")))
   has_product = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "PRODUCT")) or
                  os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
                                              "product.img")))
@@ -806,8 +829,33 @@
     partitions['dtbo'] = AddDtbo(output_zip)
 
   if OPTIONS.info_dict.get("avb_enable") == "true":
+    # vbmeta_partitions includes the partitions that should be included into
+    # top-level vbmeta.img, which are the ones that are not included in any
+    # chained VBMeta image plus the chained VBMeta images themselves.
+    vbmeta_partitions = common.AVB_PARTITIONS[:]
+
+    vbmeta_mainline = OPTIONS.info_dict.get("avb_vbmeta_mainline", "").strip()
+    if vbmeta_mainline:
+      banner("vbmeta_mainline")
+      AddVBMeta(
+          output_zip, partitions, "vbmeta_mainline", vbmeta_mainline.split())
+      vbmeta_partitions = [
+          item for item in vbmeta_partitions
+          if item not in vbmeta_mainline.split()]
+      vbmeta_partitions.append("vbmeta_mainline")
+
+    vbmeta_vendor = OPTIONS.info_dict.get("avb_vbmeta_vendor", "").strip()
+    if vbmeta_vendor:
+      banner("vbmeta_vendor")
+      AddVBMeta(
+          output_zip, partitions, "vbmeta_vendor", vbmeta_vendor.split())
+      vbmeta_partitions = [
+          item for item in vbmeta_partitions
+          if item not in vbmeta_vendor.split()]
+      vbmeta_partitions.append("vbmeta_vendor")
+
     banner("vbmeta")
-    AddVBMeta(output_zip, partitions)
+    AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions)
 
   if OPTIONS.info_dict.get("super_size"):
     banner("super_empty")
@@ -824,9 +872,9 @@
     # ready under IMAGES/ or RADIO/.
     CheckAbOtaImages(output_zip, ab_partitions)
 
-    # Generate care_map.txt for system and vendor partitions (if present), then
-    # write this file to target_files package.
-    AddCareMapTxtForAbOta(output_zip, ab_partitions, partitions)
+    # Generate care_map.pb for ab_partitions, then write this file to
+    # target_files package.
+    AddCareMapForAbOta(output_zip, ab_partitions, partitions)
 
   # Radio images that need to be packed into IMAGES/, and product-img.zip.
   pack_radioimages_txt = os.path.join(
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index c7d93d3..aeb4379 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -32,7 +32,6 @@
 import common
 from rangelib import RangeSet
 
-
 __all__ = ["EmptyImage", "DataImage", "BlockImageDiff"]
 
 
@@ -649,6 +648,14 @@
 
     self.touched_src_sha1 = self.src.RangeSha1(self.touched_src_ranges)
 
+    if self.tgt.hashtree_info:
+      out.append("compute_hash_tree {} {} {} {} {}\n".format(
+          self.tgt.hashtree_info.hashtree_range.to_string_raw(),
+          self.tgt.hashtree_info.filesystem_range.to_string_raw(),
+          self.tgt.hashtree_info.hash_algorithm,
+          self.tgt.hashtree_info.salt,
+          self.tgt.hashtree_info.root_hash))
+
     # Zero out extended blocks as a workaround for bug 20881595.
     if self.tgt.extended:
       assert (WriteSplitTransfers(out, "zero", self.tgt.extended) ==
@@ -988,6 +995,12 @@
           assert touched[i] == 0
           touched[i] = 1
 
+    if self.tgt.hashtree_info:
+      for s, e in self.tgt.hashtree_info.hashtree_range:
+        for i in range(s, e):
+          assert touched[i] == 0
+          touched[i] = 1
+
     # Check that we've written every target block.
     for s, e in self.tgt.care_map:
       for i in range(s, e):
@@ -1533,6 +1546,9 @@
         AddTransfer(tgt_fn, None, tgt_ranges, empty, "new", self.transfers)
         continue
 
+      elif tgt_fn == "__HASHTREE":
+        continue
+
       elif tgt_fn in self.src.file_map:
         # Look for an exact pathname match in the source.
         AddTransfer(tgt_fn, tgt_fn, tgt_ranges, self.src.file_map[tgt_fn],
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 1904085..f1594d7 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -45,6 +45,13 @@
 BYTES_IN_MB = 1024 * 1024
 
 
+class BuildImageError(Exception):
+  """An Exception raised during image building."""
+
+  def __init__(self, message):
+    Exception.__init__(self, message)
+
+
 def RunCommand(cmd, verbose=None, env=None):
   """Echo and run the given command.
 
@@ -76,58 +83,55 @@
   cmd = ["fec", "-s", str(partition_size)]
   output, exit_code = RunCommand(cmd, False)
   if exit_code != 0:
-    return False, 0
-  return True, int(output)
+    raise BuildImageError("Failed to GetVerityFECSize:\n{}".format(output))
+  return int(output)
 
 
 def GetVerityTreeSize(partition_size):
   cmd = ["build_verity_tree", "-s", str(partition_size)]
   output, exit_code = RunCommand(cmd, False)
   if exit_code != 0:
-    return False, 0
-  return True, int(output)
+    raise BuildImageError("Failed to GetVerityTreeSize:\n{}".format(output))
+  return int(output)
 
 
 def GetVerityMetadataSize(partition_size):
   cmd = ["build_verity_metadata.py", "size", str(partition_size)]
   output, exit_code = RunCommand(cmd, False)
   if exit_code != 0:
-    return False, 0
-  return True, int(output)
+    raise BuildImageError("Failed to GetVerityMetadataSize:\n{}".format(output))
+  return int(output)
 
 
 def GetVeritySize(partition_size, fec_supported):
-  success, verity_tree_size = GetVerityTreeSize(partition_size)
-  if not success:
-    return 0
-  success, verity_metadata_size = GetVerityMetadataSize(partition_size)
-  if not success:
-    return 0
+  verity_tree_size = GetVerityTreeSize(partition_size)
+  verity_metadata_size = GetVerityMetadataSize(partition_size)
   verity_size = verity_tree_size + verity_metadata_size
   if fec_supported:
-    success, fec_size = GetVerityFECSize(partition_size + verity_size)
-    if not success:
-      return 0
+    fec_size = GetVerityFECSize(partition_size + verity_size)
     return verity_size + fec_size
   return verity_size
 
 
 def GetDiskUsage(path):
-  """Return number of bytes that "path" occupies on host.
+  """Returns the number of bytes that "path" occupies on host.
 
   Args:
     path: The directory or file to calculate size on
+
   Returns:
-    True and the number of bytes if successful,
-    False and 0 otherwise.
+    The number of bytes.
+
+  Raises:
+    BuildImageError: On error.
   """
   env = {"POSIXLY_CORRECT": "1"}
   cmd = ["du", "-s", path]
   output, exit_code = RunCommand(cmd, verbose=False, env=env)
   if exit_code != 0:
-    return False, 0
+    raise BuildImageError("Failed to get disk usage:\n{}".format(output))
   # POSIX du returns number of blocks with block size 512
-  return True, int(output.split()[0]) * 512
+  return int(output.split()[0]) * 512
 
 
 def GetSimgSize(image_file):
@@ -149,20 +153,85 @@
     avbtool: String with path to avbtool.
     footer_type: 'hash' or 'hashtree' for generating footer.
     partition_size: The size of the partition in question.
-    additional_args: Additional arguments to pass to 'avbtool
-      add_hashtree_image'.
+    additional_args: Additional arguments to pass to "avbtool add_hash_footer"
+        or "avbtool add_hashtree_footer".
+
   Returns:
-    The maximum image size or 0 if an error occurred.
+    The maximum image size.
+
+  Raises:
+    BuildImageError: On error or getting invalid image size.
   """
   cmd = [avbtool, "add_%s_footer" % footer_type,
-         "--partition_size", partition_size, "--calc_max_image_size"]
+         "--partition_size", str(partition_size), "--calc_max_image_size"]
   cmd.extend(shlex.split(additional_args))
 
-  (output, exit_code) = RunCommand(cmd)
+  output, exit_code = RunCommand(cmd)
   if exit_code != 0:
-    return 0
-  else:
-    return int(output)
+    raise BuildImageError(
+        "Failed to calculate max image size:\n{}".format(output))
+  image_size = int(output)
+  if image_size <= 0:
+    raise BuildImageError(
+        "Invalid max image size: {}".format(output))
+  return image_size
+
+
+def AVBCalcMinPartitionSize(image_size, size_calculator):
+  """Calculates min partition size for a given image size.
+
+  Args:
+    image_size: The size of the image in question.
+    size_calculator: The function to calculate max image size
+        for a given partition size.
+
+  Returns:
+    The minimum partition size required to accommodate the image size.
+  """
+  # Use image size as partition size to approximate final partition size.
+  image_ratio = size_calculator(image_size) / float(image_size)
+
+  # Prepare a binary search for the optimal partition size.
+  lo = int(image_size / image_ratio) // BLOCK_SIZE * BLOCK_SIZE - BLOCK_SIZE
+
+  # Ensure lo is small enough: max_image_size should <= image_size.
+  delta = BLOCK_SIZE
+  max_image_size = size_calculator(lo)
+  while max_image_size > image_size:
+    image_ratio = max_image_size / float(lo)
+    lo = int(image_size / image_ratio) // BLOCK_SIZE * BLOCK_SIZE - delta
+    delta *= 2
+    max_image_size = size_calculator(lo)
+
+  hi = lo + BLOCK_SIZE
+
+  # Ensure hi is large enough: max_image_size should >= image_size.
+  delta = BLOCK_SIZE
+  max_image_size = size_calculator(hi)
+  while max_image_size < image_size:
+    image_ratio = max_image_size / float(hi)
+    hi = int(image_size / image_ratio) // BLOCK_SIZE * BLOCK_SIZE + delta
+    delta *= 2
+    max_image_size = size_calculator(hi)
+
+  partition_size = hi
+
+  # Start to binary search.
+  while lo < hi:
+    mid = ((lo + hi) // (2 * BLOCK_SIZE)) * BLOCK_SIZE
+    max_image_size = size_calculator(mid)
+    if max_image_size >= image_size:  # if mid can accommodate image_size
+      if mid < partition_size:  # if a smaller partition size is found
+        partition_size = mid
+      hi = mid
+    else:
+      lo = mid + BLOCK_SIZE
+
+  if OPTIONS.verbose:
+    print("AVBCalcMinPartitionSize({}): partition_size: {}.".format(
+        image_size, partition_size))
+
+  return partition_size
 
 
 def AVBAddFooter(image_path, avbtool, footer_type, partition_size,
@@ -179,11 +248,11 @@
     key_path: Path to key to use or None.
     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'.
+    additional_args: Additional arguments to pass to "avbtool add_hash_footer"
+        or "avbtool add_hashtree_footer".
 
-  Returns:
-    True if the operation succeeded.
+  Raises:
+    BuildImageError: On error.
   """
   cmd = [avbtool, "add_%s_footer" % footer_type,
          "--partition_size", partition_size,
@@ -199,9 +268,8 @@
 
   output, exit_code = RunCommand(cmd)
   if exit_code != 0:
-    print("Failed to add AVB footer! Error: %s" % output)
-    return False
-  return True
+    raise BuildImageError(
+        "Failed to add AVB footer:\n{}".format(output))
 
 
 def AdjustPartitionSizeForVerity(partition_size, fec_supported):
@@ -258,9 +326,8 @@
          verity_path, verity_fec_path]
   output, exit_code = RunCommand(cmd)
   if exit_code != 0:
-    print("Could not build FEC data! Error: %s" % output)
-    return False
-  return True
+    raise BuildImageError(
+        "Failed to build FEC data:\n{}".format(output))
 
 
 def BuildVerityTree(sparse_image_path, verity_image_path, prop_dict):
@@ -268,12 +335,11 @@
          verity_image_path]
   output, exit_code = RunCommand(cmd)
   if exit_code != 0:
-    print("Could not build verity tree! Error: %s" % output)
-    return False
+    raise BuildImageError(
+        "Failed to build verity tree:\n{}".format(output))
   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,
@@ -287,9 +353,8 @@
     cmd.append("--verity_disable")
   output, exit_code = RunCommand(cmd)
   if exit_code != 0:
-    print("Could not build verity metadata! Error: %s" % output)
-    return False
-  return True
+    raise BuildImageError(
+        "Failed to build verity metadata:\n{}".format(output))
 
 
 def Append2Simg(sparse_image_path, unsparse_image_path, error_message):
@@ -298,49 +363,45 @@
   Args:
     sparse_image_path: the path to the (sparse) image
     unsparse_image_path: the path to the (unsparse) image
-  Returns:
-    True on success, False on failure.
+
+  Raises:
+    BuildImageError: On error.
   """
   cmd = ["append2simg", sparse_image_path, unsparse_image_path]
   output, exit_code = RunCommand(cmd)
   if exit_code != 0:
-    print("%s: %s" % (error_message, output))
-    return False
-  return True
+    raise BuildImageError("{}:\n{}".format(error_message, output))
 
 
 def Append(target, file_to_append, error_message):
-  """Appends file_to_append to target."""
+  """Appends file_to_append to target.
+
+  Raises:
+    BuildImageError: On error.
+  """
   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
+    raise BuildImageError(error_message)
 
 
 def BuildVerifiedImage(data_image_path, verity_image_path,
                        verity_metadata_path, verity_fec_path,
                        padding_size, fec_supported):
-  if not Append(verity_image_path, verity_metadata_path,
-                "Could not append verity metadata!"):
-    return False
+  Append(
+      verity_image_path, verity_metadata_path,
+      "Could not append verity metadata!")
 
   if fec_supported:
-    # build FEC for the entire partition, including metadata
-    if not BuildVerityFEC(data_image_path, verity_image_path,
-                          verity_fec_path, padding_size):
-      return False
+    # Build FEC for the entire partition, including metadata.
+    BuildVerityFEC(
+        data_image_path, verity_image_path, verity_fec_path, padding_size)
+    Append(verity_image_path, verity_fec_path, "Could not append FEC!")
 
-    if not Append(verity_image_path, verity_fec_path, "Could not append FEC!"):
-      return False
-
-  if not Append2Simg(data_image_path, verity_image_path,
-                     "Could not append verity data!"):
-    return False
-  return True
+  Append2Simg(
+      data_image_path, verity_image_path, "Could not append verity data!")
 
 
 def UnsparseImage(sparse_image_path, replace=True):
@@ -351,15 +412,15 @@
     if replace:
       os.unlink(unsparse_image_path)
     else:
-      return True, unsparse_image_path
+      return unsparse_image_path
   inflate_command = ["simg2img", sparse_image_path, unsparse_image_path]
-  (inflate_output, exit_code) = RunCommand(inflate_command)
+  inflate_output, exit_code = RunCommand(inflate_command)
   if exit_code != 0:
-    print("Error: '%s' failed with exit code %d:\n%s" % (
-        inflate_command, exit_code, inflate_output))
     os.remove(unsparse_image_path)
-    return False, None
-  return True, unsparse_image_path
+    raise BuildImageError(
+        "Error: '{}' failed with exit code {}:\n{}".format(
+            inflate_command, exit_code, inflate_output))
+  return unsparse_image_path
 
 
 def MakeVerityEnabledImage(out_file, fec_supported, prop_dict):
@@ -369,11 +430,13 @@
     out_file: the location to write the verifiable image at
     prop_dict: a dictionary of properties required for image creation and
                verification
-  Returns:
-    True on success, False otherwise.
+
+  Raises:
+    AssertionError: On invalid partition sizes.
+    BuildImageError: On other errors.
   """
   # get properties
-  image_size = int(prop_dict["partition_size"])
+  image_size = int(prop_dict["image_size"])
   block_dev = prop_dict["verity_block_device"]
   signer_key = prop_dict["verity_key"] + ".pk8"
   if OPTIONS.verity_signer_path is not None:
@@ -382,50 +445,44 @@
     signer_path = prop_dict["verity_signer_cmd"]
   signer_args = OPTIONS.verity_signer_args
 
-  # make a tempdir
   tempdir_name = common.MakeTempDir(suffix="_verity_images")
 
-  # get partial image paths
+  # Get partial image paths.
   verity_image_path = os.path.join(tempdir_name, "verity.img")
   verity_metadata_path = os.path.join(tempdir_name, "verity_metadata.img")
   verity_fec_path = os.path.join(tempdir_name, "verity_fec.img")
 
-  # build the verity tree and get the root hash and salt
-  if not BuildVerityTree(out_file, verity_image_path, prop_dict):
-    return False
+  # Build the verity tree and get the root hash and salt.
+  BuildVerityTree(out_file, verity_image_path, prop_dict)
 
-  # build the metadata blocks
+  # Build the metadata blocks.
   root_hash = prop_dict["verity_root_hash"]
   salt = prop_dict["verity_salt"]
   verity_disable = "verity_disable" in prop_dict
-  if not BuildVerityMetadata(image_size, verity_metadata_path, root_hash, salt,
-                             block_dev, signer_path, signer_key, signer_args,
-                             verity_disable):
-    return False
+  BuildVerityMetadata(
+      image_size, verity_metadata_path, root_hash, salt, block_dev, signer_path,
+      signer_key, signer_args, verity_disable)
 
-  # build the full verified image
-  target_size = int(prop_dict["original_partition_size"])
+  # Build the full verified image.
+  partition_size = int(prop_dict["partition_size"])
   verity_size = int(prop_dict["verity_size"])
 
-  padding_size = target_size - image_size - verity_size
+  padding_size = partition_size - image_size - verity_size
   assert padding_size >= 0
 
-  if not BuildVerifiedImage(out_file,
-                            verity_image_path,
-                            verity_metadata_path,
-                            verity_fec_path,
-                            padding_size,
-                            fec_supported):
-    return False
-
-  return True
+  BuildVerifiedImage(
+      out_file, verity_image_path, verity_metadata_path, verity_fec_path,
+      padding_size, fec_supported)
 
 
 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)
-  return base_fs_file if exit_code == 0 else None
+  output, exit_code = RunCommand(convert_command)
+  if exit_code != 0:
+    raise BuildImageError(
+        "Failed to call blk_alloc_to_base_fs:\n{}".format(output))
+  return base_fs_file
 
 
 def SetUpInDirAndFsConfig(origin_in, prop_dict):
@@ -489,11 +546,9 @@
     ext4fs_output: The output string from mke2fs command.
     prop_dict: The property dict.
 
-  Returns:
-    The check result.
-
   Raises:
     AssertionError: On invalid input.
+    BuildImageError: On check failure.
   """
   assert ext4fs_output is not None
   assert prop_dict.get('fs_type', '').startswith('ext4')
@@ -511,12 +566,11 @@
   adjusted_blocks = total_blocks - headroom_blocks
   if used_blocks > adjusted_blocks:
     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,
-              adjusted_blocks))
-    return False
-  return True
+    raise BuildImageError(
+        "Error: Not enough room on {} (total: {} blocks, used: {} blocks, "
+        "headroom: {} blocks, available: {} blocks)".format(
+            mount_point, total_blocks, used_blocks, headroom_blocks,
+            adjusted_blocks))
 
 
 def BuildImage(in_dir, prop_dict, out_file, target_out=None):
@@ -532,8 +586,8 @@
         under system/core/libcutils) reads device specific FS config files from
         there.
 
-  Returns:
-    True iff the image is built successfully.
+  Raises:
+    BuildImageError: On build image failures.
   """
   in_dir, fs_config = SetUpInDirAndFsConfig(in_dir, prop_dict)
 
@@ -549,52 +603,54 @@
   verity_supported = prop_dict.get("verity") == "true"
   verity_fec_supported = prop_dict.get("verity_fec") == "true"
 
+  avb_footer_type = None
+  if prop_dict.get("avb_hash_enable") == "true":
+    avb_footer_type = "hash"
+  elif prop_dict.get("avb_hashtree_enable") == "true":
+    avb_footer_type = "hashtree"
+
+  if avb_footer_type:
+    avbtool = prop_dict.get("avb_avbtool")
+    avb_signing_args = prop_dict.get(
+        "avb_add_" + avb_footer_type + "_footer_args")
+
   if (prop_dict.get("use_dynamic_partition_size") == "true" and
       "partition_size" not in prop_dict):
-    # if partition_size is not defined, use output of `du' + reserved_size
-    success, size = GetDiskUsage(in_dir)
-    if not success:
-      return False
+    # If partition_size is not defined, use output of `du' + reserved_size.
+    size = GetDiskUsage(in_dir)
     if OPTIONS.verbose:
       print("The tree size of %s is %d MB." % (in_dir, size // BYTES_IN_MB))
     size += int(prop_dict.get("partition_reserved_size", 0))
     # Round this up to a multiple of 4K so that avbtool works
     size = common.RoundUpTo4K(size)
+    # Adjust partition_size to add more space for AVB footer, to prevent
+    # it from consuming partition_reserved_size.
+    if avb_footer_type:
+      size = AVBCalcMinPartitionSize(
+          size,
+          lambda x: AVBCalcMaxImageSize(
+              avbtool, avb_footer_type, x, avb_signing_args))
     prop_dict["partition_size"] = str(size)
     if OPTIONS.verbose:
       print("Allocating %d MB for %s." % (size // BYTES_IN_MB, out_file))
 
-  # Adjust the partition size to make room for the hashes if this is to be
-  # verified.
+  prop_dict["image_size"] = prop_dict["partition_size"]
+
+  # Adjust the image size to make room for the hashes if this is to be verified.
   if verity_supported and is_verity_partition:
     partition_size = int(prop_dict.get("partition_size"))
-    (adjusted_size, verity_size) = AdjustPartitionSizeForVerity(
+    image_size, verity_size = AdjustPartitionSizeForVerity(
         partition_size, verity_fec_supported)
-    if not adjusted_size:
-      return False
-    prop_dict["partition_size"] = str(adjusted_size)
-    prop_dict["original_partition_size"] = str(partition_size)
+    prop_dict["image_size"] = str(image_size)
     prop_dict["verity_size"] = str(verity_size)
 
-  # Adjust partition size for AVB hash footer or AVB hashtree footer.
-  avb_footer_type = ''
-  if prop_dict.get("avb_hash_enable") == "true":
-    avb_footer_type = 'hash'
-  elif prop_dict.get("avb_hashtree_enable") == "true":
-    avb_footer_type = 'hashtree'
-
+  # Adjust the image size for AVB hash footer or AVB hashtree footer.
   if avb_footer_type:
-    avbtool = prop_dict["avb_avbtool"]
     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)
-    if max_image_size <= 0:
-      print("AVBCalcMaxImageSize is <= 0: %d" % max_image_size)
-      return False
-    prop_dict["partition_size"] = str(max_image_size)
-    prop_dict["original_partition_size"] = partition_size
+    max_image_size = AVBCalcMaxImageSize(
+        avbtool, avb_footer_type, partition_size, avb_signing_args)
+    prop_dict["image_size"] = str(max_image_size)
 
   if fs_type.startswith("ext"):
     build_command = [prop_dict["ext_mkuserimg"]]
@@ -603,7 +659,7 @@
       run_e2fsck = True
     build_command.extend([in_dir, out_file, fs_type,
                           prop_dict["mount_point"]])
-    build_command.append(prop_dict["partition_size"])
+    build_command.append(prop_dict["image_size"])
     if "journal_size" in prop_dict:
       build_command.extend(["-j", prop_dict["journal_size"]])
     if "timestamp" in prop_dict:
@@ -616,8 +672,6 @@
       build_command.extend(["-B", prop_dict["block_list"]])
     if "base_fs_file" in prop_dict:
       base_fs_file = ConvertBlockMapToBaseFs(prop_dict["base_fs_file"])
-      if base_fs_file is None:
-        return False
       build_command.extend(["-d", base_fs_file])
     build_command.extend(["-L", prop_dict["mount_point"]])
     if "extfs_inode_count" in prop_dict:
@@ -662,7 +716,7 @@
       build_command.extend(["-a"])
   elif fs_type.startswith("f2fs"):
     build_command = ["mkf2fsuserimg.sh"]
-    build_command.extend([out_file, prop_dict["partition_size"]])
+    build_command.extend([out_file, prop_dict["image_size"]])
     if fs_config:
       build_command.extend(["-C", fs_config])
     build_command.extend(["-f", in_dir])
@@ -675,92 +729,81 @@
       build_command.extend(["-T", str(prop_dict["timestamp"])])
     build_command.extend(["-L", prop_dict["mount_point"]])
   else:
-    print("Error: unknown filesystem type '%s'" % (fs_type))
-    return False
+    raise BuildImageError(
+        "Error: unknown filesystem type: {}".format(fs_type))
 
-  (mkfs_output, exit_code) = RunCommand(build_command)
+  mkfs_output, exit_code = RunCommand(build_command)
   if exit_code != 0:
-    print("Error: '%s' failed with exit code %d:\n%s" % (
-        build_command, exit_code, mkfs_output))
-    success, du = GetDiskUsage(in_dir)
-    du_str = ("%d bytes (%d MB)" % (du, du // BYTES_IN_MB)
-             ) if success else "unknown"
+    try:
+      du = GetDiskUsage(in_dir)
+      du_str = "{} bytes ({} MB)".format(du, du // BYTES_IN_MB)
+    except BuildImageError as e:
+      print(e, file=sys.stderr)
+      du_str = "unknown"
     print(
         "Out of space? The tree size of {} is {}, with reserved space of {} "
         "bytes ({} MB).".format(
             in_dir, du_str,
             int(prop_dict.get("partition_reserved_size", 0)),
             int(prop_dict.get("partition_reserved_size", 0)) // BYTES_IN_MB))
-    if "original_partition_size" in prop_dict:
-      print(
-          "The max size for filsystem files is {} bytes ({} MB), out of a "
-          "total image size of {} bytes ({} MB).".format(
-              int(prop_dict["partition_size"]),
-              int(prop_dict["partition_size"]) // BYTES_IN_MB,
-              int(prop_dict["original_partition_size"]),
-              int(prop_dict["original_partition_size"]) // BYTES_IN_MB))
-    else:
-      print("The max image size is {} bytes ({} MB).".format(
-          int(prop_dict["partition_size"]),
-          int(prop_dict["partition_size"]) // BYTES_IN_MB))
-    return False
+    print(
+        "The max image size for filsystem files is {} bytes ({} MB), out of a "
+        "total partition size of {} bytes ({} MB).".format(
+            int(prop_dict["image_size"]),
+            int(prop_dict["image_size"]) // BYTES_IN_MB,
+            int(prop_dict["partition_size"]),
+            int(prop_dict["partition_size"]) // BYTES_IN_MB))
+
+    raise BuildImageError(
+        "Error: '{}' failed with exit code {}:\n{}".format(
+            build_command, exit_code, mkfs_output))
 
   # Check if there's enough headroom space available for ext4 image.
   if "partition_headroom" in prop_dict and fs_type.startswith("ext4"):
-    if not CheckHeadroom(mkfs_output, prop_dict):
-      return False
+    CheckHeadroom(mkfs_output, prop_dict)
 
   if not fs_spans_partition:
     mount_point = prop_dict.get("mount_point")
-    partition_size = int(prop_dict.get("partition_size"))
-    image_size = GetSimgSize(out_file)
-    if image_size > partition_size:
-      print("Error: %s image size of %d is larger than partition size of "
-            "%d" % (mount_point, image_size, partition_size))
-      return False
+    image_size = int(prop_dict["image_size"])
+    sparse_image_size = GetSimgSize(out_file)
+    if sparse_image_size > image_size:
+      raise BuildImageError(
+          "Error: {} image size of {} is larger than partition size of "
+          "{}".format(mount_point, sparse_image_size, image_size))
     if verity_supported and is_verity_partition:
-      ZeroPadSimg(out_file, partition_size - image_size)
+      ZeroPadSimg(out_file, image_size - sparse_image_size)
 
   # 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
+    MakeVerityEnabledImage(out_file, verity_fec_supported, prop_dict)
 
   # Add AVB HASH or HASHTREE footer (metadata).
   if avb_footer_type:
-    avbtool = prop_dict["avb_avbtool"]
-    original_partition_size = prop_dict["original_partition_size"]
+    partition_size = prop_dict["partition_size"]
     partition_name = prop_dict["partition_name"]
     # key_path and algorithm are only available when chain partition is used.
     key_path = prop_dict.get("avb_key_path")
     algorithm = prop_dict.get("avb_algorithm")
     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):
-      return False
+    AVBAddFooter(
+        out_file, avbtool, avb_footer_type, partition_size, partition_name,
+        key_path, algorithm, salt, avb_signing_args)
 
   if run_e2fsck and prop_dict.get("skip_fsck") != "true":
-    success, unsparse_image = UnsparseImage(out_file, replace=False)
-    if not success:
-      return False
+    unsparse_image = UnsparseImage(out_file, replace=False)
 
     # Run e2fsck on the inflated image file
     e2fsck_command = ["e2fsck", "-f", "-n", unsparse_image]
     # TODO(b/112062612): work around e2fsck failure with SANITIZE_HOST=address
     env4e2fsck = {"ASAN_OPTIONS": "detect_odr_violation=0"}
-    (e2fsck_output, exit_code) = RunCommand(e2fsck_command, env=env4e2fsck)
+    e2fsck_output, exit_code = RunCommand(e2fsck_command, env=env4e2fsck)
 
     os.remove(unsparse_image)
 
     if exit_code != 0:
-      print("Error: '%s' failed with exit code %d:\n%s" % (
-          e2fsck_command, exit_code, e2fsck_output))
-      return False
-
-  return True
+      raise BuildImageError(
+          "Error: '{}' failed with exit code {}:\n{}".format(
+              e2fsck_command, exit_code, e2fsck_output))
 
 
 def ImagePropFromGlobalDict(glob_dict, mount_point):
@@ -988,23 +1031,18 @@
       return True
     return False
 
-  if "original_partition_size" in image_prop:
-    size_property = "original_partition_size"
-  else:
-    size_property = "partition_size"
-
   if mount_point == "system":
-    copy_prop(size_property, "system_size")
+    copy_prop("partition_size", "system_size")
   elif mount_point == "system_other":
-    copy_prop(size_property, "system_size")
+    copy_prop("partition_size", "system_size")
   elif mount_point == "vendor":
-    copy_prop(size_property, "vendor_size")
+    copy_prop("partition_size", "vendor_size")
   elif mount_point == "odm":
-    copy_prop(size_property, "odm_size")
+    copy_prop("partition_size", "odm_size")
   elif mount_point == "product":
-    copy_prop(size_property, "product_size")
+    copy_prop("partition_size", "product_size")
   elif mount_point == "product_services":
-    copy_prop(size_property, "product_services_size")
+    copy_prop("partition_size", "product_services_size")
   return d
 
 
@@ -1056,10 +1094,12 @@
 
     image_properties = ImagePropFromGlobalDict(glob_dict, mount_point)
 
-  if not BuildImage(in_dir, image_properties, out_file, target_out):
-    print("error: failed to build %s from %s" % (out_file, in_dir),
+  try:
+    BuildImage(in_dir, image_properties, out_file, target_out)
+  except:
+    print("Error: Failed to build {} from {}".format(out_file, in_dir),
           file=sys.stderr)
-    sys.exit(1)
+    raise
 
   if prop_file_out:
     glob_dict_out = GlobalDictFromImageProp(image_properties, mount_point)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 8d51df6..4e2346c 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -82,6 +82,11 @@
                   'product_services', 'dtbo', 'odm')
 
 
+# Partitions that should have their care_map added to META/care_map.pb
+PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'product_services',
+                            'odm')
+
+
 class ErrorCode(object):
   """Define error_codes for failures that happen during the actual
   update package installation.
@@ -290,8 +295,12 @@
   else:
     d["fstab"] = None
 
-  d["build.prop"] = LoadBuildProp(read_helper, 'SYSTEM/build.prop')
-  d["vendor.build.prop"] = LoadBuildProp(read_helper, 'VENDOR/build.prop')
+  # Tries to load the build props for all partitions with care_map, including
+  # system and vendor.
+  for partition in PARTITIONS_WITH_CARE_MAP:
+    d["{}.build.prop".format(partition)] = LoadBuildProp(
+        read_helper, "{}/build.prop".format(partition.upper()))
+  d["build.prop"] = d["system.build.prop"]
 
   # Set up the salt (based on fingerprint or thumbprint) that will be used when
   # adding AVB footer.
@@ -408,7 +417,7 @@
     cmd.extend(["--key", key_path, "--algorithm", algorithm])
   avb_salt = OPTIONS.info_dict.get("avb_salt")
   # make_vbmeta_image doesn't like "--salt" (and it's not needed).
-  if avb_salt and partition != "vbmeta":
+  if avb_salt and not partition.startswith("vbmeta"):
     cmd.extend(["--salt", avb_salt])
 
 
@@ -692,7 +701,8 @@
   return tmp
 
 
-def GetSparseImage(which, tmpdir, input_zip, allow_shared_blocks):
+def GetSparseImage(which, tmpdir, input_zip, allow_shared_blocks,
+                   hashtree_info_generator=None):
   """Returns a SparseImage object suitable for passing to BlockImageDiff.
 
   This function loads the specified sparse image from the given path, and
@@ -705,7 +715,8 @@
     tmpdir: The directory that contains the prebuilt image and block map file.
     input_zip: The target-files ZIP archive.
     allow_shared_blocks: Whether having shared blocks is allowed.
-
+    hashtree_info_generator: If present, generates the hashtree_info for this
+        sparse image.
   Returns:
     A SparseImage object, with file_map info loaded.
   """
@@ -723,8 +734,9 @@
   # unconditionally. Note that they are still part of care_map. (Bug: 20939131)
   clobbered_blocks = "0"
 
-  image = sparse_img.SparseImage(path, mappath, clobbered_blocks,
-                                 allow_shared_blocks=allow_shared_blocks)
+  image = sparse_img.SparseImage(
+      path, mappath, clobbered_blocks, allow_shared_blocks=allow_shared_blocks,
+      hashtree_info_generator=hashtree_info_generator)
 
   # block.map may contain less blocks, because mke2fs may skip allocating blocks
   # if they contain all zeros. We can't reconstruct such a file from its block
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index eaba4df..755eda9 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -176,6 +176,7 @@
 
 import common
 import edify_generator
+import verity_utils
 
 if sys.hexversion < 0x02070000:
   print("Python 2.7 or newer is required.", file=sys.stderr)
@@ -1167,7 +1168,8 @@
         'payload_properties.txt',
     )
     self.optional = (
-        # care_map.txt is available only if dm-verity is enabled.
+        # care_map is available only if dm-verity is enabled.
+        'care_map.pb',
         'care_map.txt',
         # compatibility.zip is available only if target supports Treble.
         'compatibility.zip',
@@ -1410,8 +1412,12 @@
                          target_info.get('ext4_share_dup_blocks') == "true")
   system_src = common.GetSparseImage("system", OPTIONS.source_tmp, source_zip,
                                      allow_shared_blocks)
+
+  hashtree_info_generator = verity_utils.CreateHashtreeInfoGenerator(
+      "system", 4096, target_info)
   system_tgt = common.GetSparseImage("system", OPTIONS.target_tmp, target_zip,
-                                     allow_shared_blocks)
+                                     allow_shared_blocks,
+                                     hashtree_info_generator)
 
   blockimgdiff_version = max(
       int(i) for i in target_info.get("blockimgdiff_versions", "1").split(","))
@@ -1438,8 +1444,11 @@
       raise RuntimeError("can't generate incremental that adds /vendor")
     vendor_src = common.GetSparseImage("vendor", OPTIONS.source_tmp, source_zip,
                                        allow_shared_blocks)
-    vendor_tgt = common.GetSparseImage("vendor", OPTIONS.target_tmp, target_zip,
-                                       allow_shared_blocks)
+    hashtree_info_generator = verity_utils.CreateHashtreeInfoGenerator(
+        "vendor", 4096, target_info)
+    vendor_tgt = common.GetSparseImage(
+        "vendor", OPTIONS.target_tmp, target_zip, allow_shared_blocks,
+        hashtree_info_generator)
 
     # Check first block of vendor partition for remount R/W only if
     # disk type is ext4
@@ -1786,13 +1795,16 @@
   target_zip = zipfile.ZipFile(target_file, "r")
   if (target_info.get("verity") == "true" or
       target_info.get("avb_enable") == "true"):
-    care_map_path = "META/care_map.txt"
-    namelist = target_zip.namelist()
-    if care_map_path in namelist:
-      care_map_data = target_zip.read(care_map_path)
-      # In order to support streaming, care_map.txt needs to be packed as
+    care_map_list = [x for x in ["care_map.pb", "care_map.txt"] if
+                     "META/" + x in target_zip.namelist()]
+
+    # Adds care_map if either the protobuf format or the plain text one exists.
+    if care_map_list:
+      care_map_name = care_map_list[0]
+      care_map_data = target_zip.read("META/" + care_map_name)
+      # In order to support streaming, care_map needs to be packed as
       # ZIP_STORED.
-      common.ZipWriteStr(output_zip, "care_map.txt", care_map_data,
+      common.ZipWriteStr(output_zip, care_map_name, care_map_data,
                          compress_type=zipfile.ZIP_STORED)
     else:
       print("Warning: cannot find care map file in target_file package")
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index cb0c268..d35e9e8 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -395,7 +395,7 @@
       pass
 
     # Skip the care_map as we will regenerate the system/vendor images.
-    elif filename == "META/care_map.txt":
+    elif filename == "META/care_map.pb" or filename == "META/care_map.txt":
       pass
 
     # A non-APK file; copy it verbatim.
@@ -597,8 +597,7 @@
   if p.returncode != 0:
     raise common.ExternalError("failed to run dumpkeys")
 
-  if (misc_info.get("system_root_image") == "true" and
-      misc_info.get("recovery_as_boot") == "true"):
+  if misc_info.get("recovery_as_boot") == "true":
     recovery_keys_location = "BOOT/RAMDISK/res/keys"
   else:
     recovery_keys_location = "RECOVERY/RAMDISK/res/keys"
diff --git a/tools/releasetools/sparse_img.py b/tools/releasetools/sparse_img.py
index 083da7a..ca53ae1 100644
--- a/tools/releasetools/sparse_img.py
+++ b/tools/releasetools/sparse_img.py
@@ -33,7 +33,8 @@
   """
 
   def __init__(self, simg_fn, file_map_fn=None, clobbered_blocks=None,
-               mode="rb", build_map=True, allow_shared_blocks=False):
+               mode="rb", build_map=True, allow_shared_blocks=False,
+               hashtree_info_generator=None):
     self.simg_f = f = open(simg_fn, mode)
 
     header_bin = f.read(28)
@@ -64,6 +65,8 @@
           % (total_blks, blk_sz, total_chunks))
 
     if not build_map:
+      assert not hashtree_info_generator, \
+        "Cannot generate the hashtree info without building the offset map."
       return
 
     pos = 0   # in blocks
@@ -102,8 +105,18 @@
         if data_sz != 0:
           raise ValueError("Don't care chunk input size is non-zero (%u)" %
                            (data_sz))
-        else:
-          pos += chunk_sz
+        # Fills the don't care data ranges with zeros.
+        # TODO(xunchang) pass the care_map to hashtree info generator.
+        if hashtree_info_generator:
+          fill_data = '\x00' * 4
+          # In order to compute verity hashtree on device, we need to write
+          # zeros explicitly to the don't care ranges. Because these ranges may
+          # contain non-zero data from the previous build.
+          care_data.append(pos)
+          care_data.append(pos + chunk_sz)
+          offset_map.append((pos, chunk_sz, None, fill_data))
+
+        pos += chunk_sz
 
       elif chunk_type == 0xCAC4:
         raise ValueError("CRC32 chunks are not supported")
@@ -128,6 +141,10 @@
     extended = extended.intersect(all_blocks).subtract(self.care_map)
     self.extended = extended
 
+    self.hashtree_info = None
+    if hashtree_info_generator:
+      self.hashtree_info = hashtree_info_generator.Generate(self)
+
     if file_map_fn:
       self.LoadFileBlockMap(file_map_fn, self.clobbered_blocks,
                             allow_shared_blocks)
@@ -246,6 +263,8 @@
         remaining = remaining.subtract(ranges)
 
     remaining = remaining.subtract(clobbered_blocks)
+    if self.hashtree_info:
+      remaining = remaining.subtract(self.hashtree_info.hashtree_range)
 
     # For all the remaining blocks in the care_map (ie, those that
     # aren't part of the data for any file nor part of the clobbered_blocks),
@@ -308,6 +327,8 @@
         out["__NONZERO-%d" % i] = rangelib.RangeSet(data=blocks)
     if clobbered_blocks:
       out["__COPY"] = clobbered_blocks
+    if self.hashtree_info:
+      out["__HASHTREE"] = self.hashtree_info.hashtree_range
 
   def ResetFileMap(self):
     """Throw away the file map and treat the entire image as
diff --git a/tools/releasetools/test_add_img_to_target_files.py b/tools/releasetools/test_add_img_to_target_files.py
index 834e989..a73746e 100644
--- a/tools/releasetools/test_add_img_to_target_files.py
+++ b/tools/releasetools/test_add_img_to_target_files.py
@@ -23,7 +23,7 @@
 import common
 import test_utils
 from add_img_to_target_files import (
-    AddCareMapTxtForAbOta, AddPackRadioImages, AppendVBMetaArgsForPartition,
+    AddCareMapForAbOta, AddPackRadioImages, AppendVBMetaArgsForPartition,
     CheckAbOtaImages, GetCareMap)
 from rangelib import RangeSet
 
@@ -40,13 +40,13 @@
     common.Cleanup()
 
   def _verifyCareMap(self, expected, file_name):
-    """Parses the care_map proto; and checks the content in plain text."""
+    """Parses the care_map.pb; and checks the content in plain text."""
     text_file = common.MakeTempFile(prefix="caremap-", suffix=".txt")
 
     # Calls an external binary to convert the proto message.
     cmd = ["care_map_generator", "--parse_proto", file_name, text_file]
     p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-    output, _ = p.communicate()
+    p.communicate()
     self.assertEqual(0, p.returncode)
 
     with open(text_file, 'r') as verify_fp:
@@ -139,11 +139,18 @@
                       images + ['baz'])
 
   @staticmethod
-  def _test_AddCareMapTxtForAbOta():
-    """Helper function to set up the test for test_AddCareMapTxtForAbOta()."""
+  def _test_AddCareMapForAbOta():
+    """Helper function to set up the test for test_AddCareMapForAbOta()."""
     OPTIONS.info_dict = {
-        'system_verity_block_device' : '/dev/block/system',
-        'vendor_verity_block_device' : '/dev/block/vendor',
+        'system_verity_block_device': '/dev/block/system',
+        'vendor_verity_block_device': '/dev/block/vendor',
+        'system.build.prop': {
+            'ro.system.build.fingerprint':
+                'google/sailfish/12345:user/dev-keys',
+        },
+        'vendor.build.prop': {
+            'ro.vendor.build.fingerprint': 'google/sailfish/678:user/dev-keys',
+        }
     }
 
     # Prepare the META/ folder.
@@ -164,101 +171,172 @@
     }
     return image_paths
 
-  def test_AddCareMapTxtForAbOta(self):
-    image_paths = self._test_AddCareMapTxtForAbOta()
+  def test_AddCareMapForAbOta(self):
+    image_paths = self._test_AddCareMapForAbOta()
 
-    AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths)
+    AddCareMapForAbOta(None, ['system', 'vendor'], image_paths)
 
-    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
-    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), 'vendor',
-                RangeSet("0-9").to_string_raw()]
+    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
+                "ro.system.build.fingerprint",
+                "google/sailfish/12345:user/dev-keys",
+                'vendor', RangeSet("0-9").to_string_raw(),
+                "ro.vendor.build.fingerprint",
+                "google/sailfish/678:user/dev-keys"]
 
     self._verifyCareMap(expected, care_map_file)
 
-  def test_AddCareMapTxtForAbOta_withNonCareMapPartitions(self):
+  def test_AddCareMapForAbOta_withNonCareMapPartitions(self):
     """Partitions without care_map should be ignored."""
-    image_paths = self._test_AddCareMapTxtForAbOta()
+    image_paths = self._test_AddCareMapForAbOta()
 
-    AddCareMapTxtForAbOta(
+    AddCareMapForAbOta(
         None, ['boot', 'system', 'vendor', 'vbmeta'], image_paths)
 
-    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
-    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), 'vendor',
-                RangeSet("0-9").to_string_raw()]
+    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
+                "ro.system.build.fingerprint",
+                "google/sailfish/12345:user/dev-keys",
+                'vendor', RangeSet("0-9").to_string_raw(),
+                "ro.vendor.build.fingerprint",
+                "google/sailfish/678:user/dev-keys"]
 
     self._verifyCareMap(expected, care_map_file)
 
-  def test_AddCareMapTxtForAbOta_withAvb(self):
+  def test_AddCareMapForAbOta_withAvb(self):
     """Tests the case for device using AVB."""
-    image_paths = self._test_AddCareMapTxtForAbOta()
+    image_paths = self._test_AddCareMapForAbOta()
     OPTIONS.info_dict = {
         'avb_system_hashtree_enable' : 'true',
         'avb_vendor_hashtree_enable' : 'true',
+        'system.build.prop': {
+            'ro.system.build.fingerprint':
+                'google/sailfish/12345:user/dev-keys',
+        },
+        'vendor.build.prop': {
+            'ro.vendor.build.fingerprint': 'google/sailfish/678:user/dev-keys',
+        }
     }
 
-    AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths)
+    AddCareMapForAbOta(None, ['system', 'vendor'], image_paths)
 
-    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
-    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), 'vendor',
-                RangeSet("0-9").to_string_raw()]
+    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
+                "ro.system.build.fingerprint",
+                "google/sailfish/12345:user/dev-keys",
+                'vendor', RangeSet("0-9").to_string_raw(),
+                "ro.vendor.build.fingerprint",
+                "google/sailfish/678:user/dev-keys"]
 
     self._verifyCareMap(expected, care_map_file)
 
-  def test_AddCareMapTxtForAbOta_verityNotEnabled(self):
-    """No care_map.txt should be generated if verity not enabled."""
-    image_paths = self._test_AddCareMapTxtForAbOta()
-    OPTIONS.info_dict = {}
-    AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths)
+  def test_AddCareMapForAbOta_noFingerprint(self):
+    """Tests the case for partitions without fingerprint."""
+    image_paths = self._test_AddCareMapForAbOta()
+    OPTIONS.info_dict = {
+        'system_verity_block_device': '/dev/block/system',
+        'vendor_verity_block_device': '/dev/block/vendor',
+    }
 
-    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
+    AddCareMapForAbOta(None, ['system', 'vendor'], image_paths)
+
+    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), "unknown",
+                "unknown", 'vendor', RangeSet("0-9").to_string_raw(), "unknown",
+                "unknown"]
+
+    self._verifyCareMap(expected, care_map_file)
+
+  def test_AddCareMapForAbOta_withThumbprint(self):
+    """Tests the case for partitions with thumbprint."""
+    image_paths = self._test_AddCareMapForAbOta()
+    OPTIONS.info_dict = {
+        'system_verity_block_device': '/dev/block/system',
+        'vendor_verity_block_device': '/dev/block/vendor',
+        'system.build.prop': {
+            'ro.system.build.thumbprint': 'google/sailfish/123:user/dev-keys',
+        },
+        'vendor.build.prop' : {
+            'ro.vendor.build.thumbprint': 'google/sailfish/456:user/dev-keys',
+        }
+    }
+
+    AddCareMapForAbOta(None, ['system', 'vendor'], image_paths)
+
+    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
+                "ro.system.build.thumbprint",
+                "google/sailfish/123:user/dev-keys",
+                'vendor', RangeSet("0-9").to_string_raw(),
+                "ro.vendor.build.thumbprint",
+                "google/sailfish/456:user/dev-keys"]
+
+    self._verifyCareMap(expected, care_map_file)
+
+  def test_AddCareMapForAbOta_verityNotEnabled(self):
+    """No care_map.pb should be generated if verity not enabled."""
+    image_paths = self._test_AddCareMapForAbOta()
+    OPTIONS.info_dict = {}
+    AddCareMapForAbOta(None, ['system', 'vendor'], image_paths)
+
+    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
     self.assertFalse(os.path.exists(care_map_file))
 
-  def test_AddCareMapTxtForAbOta_missingImageFile(self):
+  def test_AddCareMapForAbOta_missingImageFile(self):
     """Missing image file should be considered fatal."""
-    image_paths = self._test_AddCareMapTxtForAbOta()
+    image_paths = self._test_AddCareMapForAbOta()
     image_paths['vendor'] = ''
-    self.assertRaises(AssertionError, AddCareMapTxtForAbOta, None,
+    self.assertRaises(AssertionError, AddCareMapForAbOta, None,
                       ['system', 'vendor'], image_paths)
 
-  def test_AddCareMapTxtForAbOta_zipOutput(self):
+  def test_AddCareMapForAbOta_zipOutput(self):
     """Tests the case with ZIP output."""
-    image_paths = self._test_AddCareMapTxtForAbOta()
+    image_paths = self._test_AddCareMapForAbOta()
 
     output_file = common.MakeTempFile(suffix='.zip')
     with zipfile.ZipFile(output_file, 'w') as output_zip:
-      AddCareMapTxtForAbOta(output_zip, ['system', 'vendor'], image_paths)
+      AddCareMapForAbOta(output_zip, ['system', 'vendor'], image_paths)
 
-    care_map_name = "META/care_map.txt"
+    care_map_name = "META/care_map.pb"
     temp_dir = common.MakeTempDir()
     with zipfile.ZipFile(output_file, 'r') as verify_zip:
       self.assertTrue(care_map_name in verify_zip.namelist())
       verify_zip.extract(care_map_name, path=temp_dir)
 
-    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), 'vendor',
-                RangeSet("0-9").to_string_raw()]
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
+                "ro.system.build.fingerprint",
+                "google/sailfish/12345:user/dev-keys",
+                'vendor', RangeSet("0-9").to_string_raw(),
+                "ro.vendor.build.fingerprint",
+                "google/sailfish/678:user/dev-keys"]
     self._verifyCareMap(expected, os.path.join(temp_dir, care_map_name))
 
-  def test_AddCareMapTxtForAbOta_zipOutput_careMapEntryExists(self):
+  def test_AddCareMapForAbOta_zipOutput_careMapEntryExists(self):
     """Tests the case with ZIP output which already has care_map entry."""
-    image_paths = self._test_AddCareMapTxtForAbOta()
+    image_paths = self._test_AddCareMapForAbOta()
 
     output_file = common.MakeTempFile(suffix='.zip')
     with zipfile.ZipFile(output_file, 'w') as output_zip:
-      # Create an existing META/care_map.txt entry.
-      common.ZipWriteStr(output_zip, 'META/care_map.txt', 'dummy care_map.txt')
+      # Create an existing META/care_map.pb entry.
+      common.ZipWriteStr(output_zip, 'META/care_map.pb',
+                         'dummy care_map.pb')
 
-      # Request to add META/care_map.txt again.
-      AddCareMapTxtForAbOta(output_zip, ['system', 'vendor'], image_paths)
+      # Request to add META/care_map.pb again.
+      AddCareMapForAbOta(output_zip, ['system', 'vendor'], image_paths)
 
     # The one under OPTIONS.input_tmp must have been replaced.
-    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
-    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), 'vendor',
-                RangeSet("0-9").to_string_raw()]
+    care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.pb')
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(),
+                "ro.system.build.fingerprint",
+                "google/sailfish/12345:user/dev-keys",
+                'vendor', RangeSet("0-9").to_string_raw(),
+                "ro.vendor.build.fingerprint",
+                "google/sailfish/678:user/dev-keys"]
 
     self._verifyCareMap(expected, care_map_file)
 
     # The existing entry should be scheduled to be replaced.
-    self.assertIn('META/care_map.txt', OPTIONS.replace_updated_files_list)
+    self.assertIn('META/care_map.pb', OPTIONS.replace_updated_files_list)
 
   def test_AppendVBMetaArgsForPartition(self):
     OPTIONS.info_dict = {}
@@ -291,7 +369,7 @@
         (0xCAC3, 4),
         (0xCAC1, 6)])
     OPTIONS.info_dict = {
-        'system_adjusted_partition_size' : 12,
+        'system_image_blocks' : 12,
     }
     name, care_map = GetCareMap('system', sparse_image)
     self.assertEqual('system', name)
@@ -306,6 +384,6 @@
         (0xCAC3, 4),
         (0xCAC1, 6)])
     OPTIONS.info_dict = {
-        'system_adjusted_partition_size' : -12,
+        'system_image_blocks' : -12,
     }
     self.assertRaises(AssertionError, GetCareMap, 'system', sparse_image)
diff --git a/tools/releasetools/test_build_image.py b/tools/releasetools/test_build_image.py
index 40a7c85..94c31ee 100644
--- a/tools/releasetools/test_build_image.py
+++ b/tools/releasetools/test_build_image.py
@@ -15,11 +15,15 @@
 #
 
 import filecmp
+import math
 import os.path
+import random
 import unittest
 
 import common
-from build_image import CheckHeadroom, RunCommand, SetUpInDirAndFsConfig
+from build_image import (
+    AVBCalcMinPartitionSize, BLOCK_SIZE, BuildImageError, CheckHeadroom,
+    RunCommand, SetUpInDirAndFsConfig)
 
 
 class BuildImageTest(unittest.TestCase):
@@ -28,6 +32,13 @@
   EXT4FS_OUTPUT = (
       "Created filesystem with 2777/129024 inodes and 515099/516099 blocks")
 
+  def setUp(self):
+    # To test AVBCalcMinPartitionSize(), by using 200MB to 2GB image size.
+    #   -  51200 = 200MB * 1024 * 1024 / 4096
+    #   - 524288 = 2GB * 1024 * 1024 * 1024 / 4096
+    self._image_sizes = [BLOCK_SIZE * random.randint(51200, 524288) + offset
+                         for offset in range(BLOCK_SIZE)]
+
   def tearDown(self):
     common.Cleanup()
 
@@ -38,7 +49,7 @@
         'partition_headroom' : '4096000',
         'mount_point' : 'system',
     }
-    self.assertTrue(CheckHeadroom(self.EXT4FS_OUTPUT, prop_dict))
+    CheckHeadroom(self.EXT4FS_OUTPUT, prop_dict)
 
   def test_CheckHeadroom_InsufficientHeadroom(self):
     # Required headroom: 1001 blocks.
@@ -47,7 +58,8 @@
         'partition_headroom' : '4100096',
         'mount_point' : 'system',
     }
-    self.assertFalse(CheckHeadroom(self.EXT4FS_OUTPUT, prop_dict))
+    self.assertRaises(
+        BuildImageError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict)
 
   def test_CheckHeadroom_WrongFsType(self):
     prop_dict = {
@@ -87,14 +99,14 @@
         'partition_headroom' : '40960',
         'mount_point' : 'system',
     }
-    self.assertTrue(CheckHeadroom(ext4fs_output, prop_dict))
+    CheckHeadroom(ext4fs_output, prop_dict)
 
     prop_dict = {
         'fs_type' : 'ext4',
         'partition_headroom' : '413696',
         'mount_point' : 'system',
     }
-    self.assertFalse(CheckHeadroom(ext4fs_output, prop_dict))
+    self.assertRaises(BuildImageError, CheckHeadroom, ext4fs_output, prop_dict)
 
   def test_SetUpInDirAndFsConfig_SystemRootImageTrue_NonSystem(self):
     prop_dict = {
@@ -176,3 +188,51 @@
     self.assertIn('fs-config-system\n', fs_config_data)
     self.assertIn('fs-config-root\n', fs_config_data)
     self.assertEqual('/', prop_dict['mount_point'])
+
+  def test_AVBCalcMinPartitionSize_LinearFooterSize(self):
+    """Tests with footer size which is linear to partition size."""
+    for image_size in self._image_sizes:
+      for ratio in 0.95, 0.56, 0.22:
+        expected_size = common.RoundUpTo4K(int(math.ceil(image_size / ratio)))
+        self.assertEqual(
+            expected_size,
+            AVBCalcMinPartitionSize(image_size, lambda x: int(x * ratio)))
+
+  def test_AVBCalcMinPartitionSize_SlowerGrowthFooterSize(self):
+    """Tests with footer size which grows slower than partition size."""
+
+    def _SizeCalculator(partition_size):
+      """Footer size is the power of 0.95 of partition size."""
+      # Minus footer size to return max image size.
+      return partition_size - int(math.pow(partition_size, 0.95))
+
+    for image_size in self._image_sizes:
+      min_partition_size = AVBCalcMinPartitionSize(image_size, _SizeCalculator)
+      # Checks min_partition_size can accommodate image_size.
+      self.assertGreaterEqual(
+          _SizeCalculator(min_partition_size),
+          image_size)
+      # Checks min_partition_size (round to BLOCK_SIZE) is the minimum.
+      self.assertLess(
+          _SizeCalculator(min_partition_size - BLOCK_SIZE),
+          image_size)
+
+  def test_AVBCalcMinPartitionSize_FasterGrowthFooterSize(self):
+    """Tests with footer size which grows faster than partition size."""
+
+    def _SizeCalculator(partition_size):
+      """Max image size is the power of 0.95 of partition size."""
+      # Max image size grows less than partition size, which means
+      # footer size grows faster than partition size.
+      return int(math.pow(partition_size, 0.95))
+
+    for image_size in self._image_sizes:
+      min_partition_size = AVBCalcMinPartitionSize(image_size, _SizeCalculator)
+      # Checks min_partition_size can accommodate image_size.
+      self.assertGreaterEqual(
+          _SizeCalculator(min_partition_size),
+          image_size)
+      # Checks min_partition_size (round to BLOCK_SIZE) is the minimum.
+      self.assertLess(
+          _SizeCalculator(min_partition_size - BLOCK_SIZE),
+          image_size)
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index 8416af7..1d8a786 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -889,6 +889,7 @@
         property_files.required)
     self.assertEqual(
         (
+            'care_map.pb',
             'care_map.txt',
             'compatibility.zip',
         ),
@@ -984,6 +985,7 @@
         property_files.required)
     self.assertEqual(
         (
+            'care_map.pb',
             'care_map.txt',
             'compatibility.zip',
         ),
diff --git a/tools/releasetools/test_validate_target_files.py b/tools/releasetools/test_validate_target_files.py
index 3ba89a1..0aaf069 100644
--- a/tools/releasetools/test_validate_target_files.py
+++ b/tools/releasetools/test_validate_target_files.py
@@ -116,13 +116,13 @@
   def _generate_system_image(self, output_file):
     verity_fec = True
     partition_size = 1024 * 1024
-    adjusted_size, verity_size = build_image.AdjustPartitionSizeForVerity(
+    image_size, verity_size = build_image.AdjustPartitionSizeForVerity(
         partition_size, verity_fec)
 
     # Use an empty root directory.
     system_root = common.MakeTempDir()
     cmd = ['mkuserimg_mke2fs', '-s', system_root, output_file, 'ext4',
-           '/system', str(adjusted_size), '-j', '0']
+           '/system', str(image_size), '-j', '0']
     proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
     stdoutdata, _ = proc.communicate()
     self.assertEqual(
@@ -132,15 +132,14 @@
 
     # Append the verity metadata.
     prop_dict = {
-        'original_partition_size' : str(partition_size),
-        'partition_size' : str(adjusted_size),
+        'partition_size' : str(partition_size),
+        'image_size' : str(image_size),
         'verity_block_device' : '/dev/block/system',
         'verity_key' : os.path.join(self.testdata_dir, 'testkey'),
         'verity_signer_cmd' : 'verity_signer',
         'verity_size' : str(verity_size),
     }
-    self.assertTrue(
-        build_image.MakeVerityEnabledImage(output_file, verity_fec, prop_dict))
+    build_image.MakeVerityEnabledImage(output_file, verity_fec, prop_dict)
 
   def test_ValidateVerifiedBootImages_systemImage(self):
     input_tmp = common.MakeTempDir()
diff --git a/tools/releasetools/test_verity_utils.py b/tools/releasetools/test_verity_utils.py
new file mode 100644
index 0000000..580612f
--- /dev/null
+++ b/tools/releasetools/test_verity_utils.py
@@ -0,0 +1,168 @@
+#
+# Copyright (C) 2018 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 verity_utils.py."""
+
+from __future__ import print_function
+
+import os
+import os.path
+import unittest
+
+import build_image
+import common
+import sparse_img
+import test_utils
+import verity_utils
+from rangelib import RangeSet
+
+
+class VerityUtilsTest(unittest.TestCase):
+  def setUp(self):
+    self.testdata_dir = test_utils.get_testdata_dir()
+
+    self.partition_size = 1024 * 1024
+    self.prop_dict = {
+        'verity': 'true',
+        'verity_fec': 'true',
+        'system_verity_block_device': '/dev/block/system',
+        'system_size': self.partition_size
+    }
+
+    self.hash_algorithm = "sha256"
+    self.fixed_salt = \
+        "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
+    self.expected_root_hash = \
+        "0b7c4565e87b1026e11fbab91c0bc29e185c847a5b44d40e6e86e461e8adf80d"
+
+  def tearDown(self):
+    common.Cleanup()
+
+  def _create_simg(self, raw_data):
+    output_file = common.MakeTempFile()
+    raw_image = common.MakeTempFile()
+    with open(raw_image, 'wb') as f:
+      f.write(raw_data)
+
+    cmd = ["img2simg", raw_image, output_file, '4096']
+    p = common.Run(cmd)
+    p.communicate()
+    self.assertEqual(0, p.returncode)
+
+    return output_file
+
+  def _generate_image(self):
+    partition_size = 1024 * 1024
+    adjusted_size, verity_size = build_image.AdjustPartitionSizeForVerity(
+        partition_size, True)
+
+    raw_image = ""
+    for i in range(adjusted_size):
+      raw_image += str(i % 10)
+
+    output_file = self._create_simg(raw_image)
+
+    # Append the verity metadata.
+    prop_dict = {
+        'partition_size': str(partition_size),
+        'image_size': str(adjusted_size),
+        'verity_block_device': '/dev/block/system',
+        'verity_key': os.path.join(self.testdata_dir, 'testkey'),
+        'verity_signer_cmd': 'verity_signer',
+        'verity_size': str(verity_size),
+    }
+    build_image.MakeVerityEnabledImage(output_file, True, prop_dict)
+
+    return output_file
+
+  def test_VerifiedBootVersion1HashtreeInfoGenerator_create(self):
+    image_file = sparse_img.SparseImage(self._generate_image())
+
+    generator = verity_utils.CreateHashtreeInfoGenerator(
+        'system', image_file, self.prop_dict)
+    self.assertEqual(
+        verity_utils.VerifiedBootVersion1HashtreeInfoGenerator, type(generator))
+    self.assertEqual(self.partition_size, generator.partition_size)
+    self.assertTrue(generator.fec_supported)
+
+  def test_VerifiedBootVersion1HashtreeInfoGenerator_decomposeImage(self):
+    image_file = sparse_img.SparseImage(self._generate_image())
+
+    generator = verity_utils.VerifiedBootVersion1HashtreeInfoGenerator(
+        self.partition_size, 4096, True)
+    generator.DecomposeSparseImage(image_file)
+    self.assertEqual(991232, generator.filesystem_size)
+    self.assertEqual(12288, generator.hashtree_size)
+    self.assertEqual(32768, generator.metadata_size)
+
+  def test_VerifiedBootVersion1HashtreeInfoGenerator_parseHashtreeMetadata(
+      self):
+    image_file = sparse_img.SparseImage(self._generate_image())
+    generator = verity_utils.VerifiedBootVersion1HashtreeInfoGenerator(
+        self.partition_size, 4096, True)
+    generator.DecomposeSparseImage(image_file)
+
+    generator._ParseHashtreeMetadata()
+
+    self.assertEqual(
+        self.hash_algorithm, generator.hashtree_info.hash_algorithm)
+    self.assertEqual(self.fixed_salt, generator.hashtree_info.salt)
+    self.assertEqual(self.expected_root_hash, generator.hashtree_info.root_hash)
+
+  def test_VerifiedBootVersion1HashtreeInfoGenerator_validateHashtree_smoke(
+      self):
+    generator = verity_utils.VerifiedBootVersion1HashtreeInfoGenerator(
+        self.partition_size, 4096, True)
+    generator.image = sparse_img.SparseImage(self._generate_image())
+
+    generator.hashtree_info = info = verity_utils.HashtreeInfo()
+    info.filesystem_range = RangeSet(data=[0, 991232 / 4096])
+    info.hashtree_range = RangeSet(
+        data=[991232 / 4096, (991232 + 12288) / 4096])
+    info.hash_algorithm = self.hash_algorithm
+    info.salt = self.fixed_salt
+    info.root_hash = self.expected_root_hash
+
+    self.assertTrue(generator.ValidateHashtree())
+
+  def test_VerifiedBootVersion1HashtreeInfoGenerator_validateHashtree_failure(
+      self):
+    generator = verity_utils.VerifiedBootVersion1HashtreeInfoGenerator(
+        self.partition_size, 4096, True)
+    generator.image = sparse_img.SparseImage(self._generate_image())
+
+    generator.hashtree_info = info = verity_utils.HashtreeInfo()
+    info.filesystem_range = RangeSet(data=[0, 991232 / 4096])
+    info.hashtree_range = RangeSet(
+        data=[991232 / 4096, (991232 + 12288) / 4096])
+    info.hash_algorithm = self.hash_algorithm
+    info.salt = self.fixed_salt
+    info.root_hash = "a" + self.expected_root_hash[1:]
+
+    self.assertFalse(generator.ValidateHashtree())
+
+  def test_VerifiedBootVersion1HashtreeInfoGenerator_generate(self):
+    image_file = sparse_img.SparseImage(self._generate_image())
+    generator = verity_utils.CreateHashtreeInfoGenerator(
+        'system', 4096, self.prop_dict)
+    info = generator.Generate(image_file)
+
+    self.assertEqual(RangeSet(data=[0, 991232 / 4096]), info.filesystem_range)
+    self.assertEqual(RangeSet(data=[991232 / 4096, (991232 + 12288) / 4096]),
+                     info.hashtree_range)
+    self.assertEqual(self.hash_algorithm, info.hash_algorithm)
+    self.assertEqual(self.fixed_salt, info.salt)
+    self.assertEqual(self.expected_root_hash, info.root_hash)
diff --git a/tools/releasetools/verity_utils.py b/tools/releasetools/verity_utils.py
new file mode 100644
index 0000000..0e605b1
--- /dev/null
+++ b/tools/releasetools/verity_utils.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 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.
+
+from __future__ import print_function
+
+import struct
+
+import common
+from build_image import (AdjustPartitionSizeForVerity, GetVerityTreeSize,
+                         GetVerityMetadataSize, BuildVerityTree)
+from rangelib import RangeSet
+
+
+class HashtreeInfoGenerationError(Exception):
+  """An Exception raised during hashtree info generation."""
+
+  def __init__(self, message):
+    Exception.__init__(self, message)
+
+
+class HashtreeInfo(object):
+  def __init__(self):
+    self.hashtree_range = None
+    self.filesystem_range = None
+    self.hash_algorithm = None
+    self.salt = None
+    self.root_hash = None
+
+
+def CreateHashtreeInfoGenerator(partition_name, block_size, info_dict):
+  generator = None
+  if (info_dict.get("verity") == "true" and
+      info_dict.get("{}_verity_block_device".format(partition_name))):
+    partition_size = info_dict["{}_size".format(partition_name)]
+    fec_supported = info_dict.get("verity_fec") == "true"
+    generator = VerifiedBootVersion1HashtreeInfoGenerator(
+        partition_size, block_size, fec_supported)
+
+  return generator
+
+
+class HashtreeInfoGenerator(object):
+  def Generate(self, image):
+    raise NotImplementedError
+
+  def DecomposeSparseImage(self, image):
+    raise NotImplementedError
+
+  def ValidateHashtree(self):
+    raise NotImplementedError
+
+
+class VerifiedBootVersion2HashtreeInfoGenerator(HashtreeInfoGenerator):
+  pass
+
+
+class VerifiedBootVersion1HashtreeInfoGenerator(HashtreeInfoGenerator):
+  """A class that parses the metadata of hashtree for a given partition."""
+
+  def __init__(self, partition_size, block_size, fec_supported):
+    """Initialize VerityTreeInfo with the sparse image and input property.
+
+    Arguments:
+      partition_size: The whole size in bytes of a partition, including the
+        filesystem size, padding size, and verity size.
+      block_size: Expected size in bytes of each block for the sparse image.
+      fec_supported: True if the verity section contains fec data.
+    """
+
+    self.block_size = block_size
+    self.partition_size = partition_size
+    self.fec_supported = fec_supported
+
+    self.image = None
+    self.filesystem_size = None
+    self.hashtree_size = None
+    self.metadata_size = None
+
+    self.hashtree_info = HashtreeInfo()
+
+  def DecomposeSparseImage(self, image):
+    """Calculate the verity size based on the size of the input image.
+
+    Since we already know the structure of a verity enabled image to be:
+    [filesystem, verity_hashtree, verity_metadata, fec_data]. We can then
+    calculate the size and offset of each section.
+    """
+
+    self.image = image
+    assert self.block_size == image.blocksize
+    assert self.partition_size == image.total_blocks * self.block_size, \
+        "partition size {} doesn't match with the calculated image size." \
+        " total_blocks: {}".format(self.partition_size, image.total_blocks)
+
+    adjusted_size, _ = AdjustPartitionSizeForVerity(
+        self.partition_size, self.fec_supported)
+    assert adjusted_size % self.block_size == 0
+
+    verity_tree_size = GetVerityTreeSize(adjusted_size)
+    assert verity_tree_size % self.block_size == 0
+
+    metadata_size = GetVerityMetadataSize(adjusted_size)
+    assert metadata_size % self.block_size == 0
+
+    self.filesystem_size = adjusted_size
+    self.hashtree_size = verity_tree_size
+    self.metadata_size = metadata_size
+
+    self.hashtree_info.filesystem_range = RangeSet(
+        data=[0, adjusted_size / self.block_size])
+    self.hashtree_info.hashtree_range = RangeSet(
+        data=[adjusted_size / self.block_size,
+              (adjusted_size + verity_tree_size) / self.block_size])
+
+  def _ParseHashtreeMetadata(self):
+    """Parses the hash_algorithm, root_hash, salt from the metadata block."""
+
+    metadata_start = self.filesystem_size + self.hashtree_size
+    metadata_range = RangeSet(
+        data=[metadata_start / self.block_size,
+              (metadata_start + self.metadata_size) / self.block_size])
+    meta_data = ''.join(self.image.ReadRangeSet(metadata_range))
+
+    # More info about the metadata structure available in:
+    # system/extras/verity/build_verity_metadata.py
+    META_HEADER_SIZE = 268
+    header_bin = meta_data[0:META_HEADER_SIZE]
+    header = struct.unpack("II256sI", header_bin)
+
+    # header: magic_number, version, signature, table_len
+    assert header[0] == 0xb001b001, header[0]
+    table_len = header[3]
+    verity_table = meta_data[META_HEADER_SIZE: META_HEADER_SIZE + table_len]
+    table_entries = verity_table.rstrip().split()
+
+    # Expected verity table format: "1 block_device block_device block_size
+    # block_size data_blocks data_blocks hash_algorithm root_hash salt"
+    assert len(table_entries) == 10, "Unexpected verity table size {}".format(
+        len(table_entries))
+    assert (int(table_entries[3]) == self.block_size and
+            int(table_entries[4]) == self.block_size)
+    assert (int(table_entries[5]) * self.block_size == self.filesystem_size and
+            int(table_entries[6]) * self.block_size == self.filesystem_size)
+
+    self.hashtree_info.hash_algorithm = table_entries[7]
+    self.hashtree_info.root_hash = table_entries[8]
+    self.hashtree_info.salt = table_entries[9]
+
+  def ValidateHashtree(self):
+    """Checks that we can reconstruct the verity hash tree."""
+
+    # Writes the file system section to a temp file; and calls the executable
+    # build_verity_tree to construct the hash tree.
+    adjusted_partition = common.MakeTempFile(prefix="adjusted_partition")
+    with open(adjusted_partition, "wb") as fd:
+      self.image.WriteRangeDataToFd(self.hashtree_info.filesystem_range, fd)
+
+    generated_verity_tree = common.MakeTempFile(prefix="verity")
+    prop_dict = {}
+    BuildVerityTree(adjusted_partition, generated_verity_tree, prop_dict)
+
+    assert prop_dict["verity_salt"] == self.hashtree_info.salt
+    if prop_dict["verity_root_hash"] != self.hashtree_info.root_hash:
+      print("Calculated verty root hash {} doesn't match the one in metadata"
+            " {}".format(prop_dict["verity_root_hash"],
+                         self.hashtree_info.root_hash))
+      return False
+
+    # Reads the generated hash tree and checks if it has the exact same bytes
+    # as the one in the sparse image.
+    with open(generated_verity_tree, "rb") as fd:
+      return fd.read() == ''.join(self.image.ReadRangeSet(
+          self.hashtree_info.hashtree_range))
+
+  def Generate(self, image):
+    """Parses and validates the hashtree info in a sparse image.
+
+    Returns:
+      hashtree_info: The information needed to reconstruct the hashtree.
+    Raises:
+      HashtreeInfoGenerationError: If we fail to generate the exact bytes of
+          the hashtree.
+    """
+
+    self.DecomposeSparseImage(image)
+    self._ParseHashtreeMetadata()
+
+    if not self.ValidateHashtree():
+      raise HashtreeInfoGenerationError("Failed to reconstruct the verity tree")
+
+    return self.hashtree_info
diff --git a/tools/signapk/Android.bp b/tools/signapk/Android.bp
index ee4cfab..e95205d 100644
--- a/tools/signapk/Android.bp
+++ b/tools/signapk/Android.bp
@@ -24,7 +24,7 @@
         "apksig",
         "bouncycastle-unbundled",
         "bouncycastle-bcpkix-unbundled",
-        "conscrypt",
+        "conscrypt-nojarjar",
     ],
 
     required: ["libconscrypt_openjdk_jni"],