Merge "Add aftl inclusion proof"
diff --git a/core/Makefile b/core/Makefile
index f61a385..bda0b23 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -861,10 +861,17 @@
 # -----------------------------------------------------------------
 # Cert-to-package mapping.  Used by the post-build signing tools.
 # Use a macro to add newline to each echo command
+# $1 package name
+# $2 certificate
+# $3 private key
+# $4 compressed
+# $5 partition tag
+# $6 output file
 define _apkcerts_write_line
-$(hide) echo -n 'name="$(1).apk" certificate="$2" private_key="$3"' >> $5
-$(if $(4), $(hide) echo -n ' compressed="$4"' >> $5)
-$(hide) echo '' >> $5
+$(hide) echo -n 'name="$(1).apk" certificate="$2" private_key="$3"' >> $6
+$(if $(4), $(hide) echo -n ' compressed="$4"' >> $6)
+$(if $(5), $(hide) echo -n ' partition="$5"' >> $6)
+$(hide) echo '' >> $6
 
 endef
 
@@ -884,8 +891,8 @@
 	@rm -f $@
 	$(foreach p,$(sort $(PACKAGES)),\
 	  $(if $(PACKAGES.$(p).EXTERNAL_KEY),\
-	    $(call _apkcerts_write_line,$(p),"EXTERNAL","",$(PACKAGES.$(p).COMPRESSED),$@),\
-	    $(call _apkcerts_write_line,$(p),$(PACKAGES.$(p).CERTIFICATE),$(PACKAGES.$(p).PRIVATE_KEY),$(PACKAGES.$(p).COMPRESSED),$@)))
+	    $(call _apkcerts_write_line,$(p),"EXTERNAL","",$(PACKAGES.$(p).COMPRESSED),$(PACKAGES.$(p).PARTITION),$@),\
+	    $(call _apkcerts_write_line,$(p),$(PACKAGES.$(p).CERTIFICATE),$(PACKAGES.$(p).PRIVATE_KEY),$(PACKAGES.$(p).COMPRESSED),$(PACKAGES.$(p).PARTITION),$@)))
 	# In case value of PACKAGES is empty.
 	$(hide) touch $@
 
@@ -1032,7 +1039,12 @@
   INSTALLED_2NDBOOTLOADER_TARGET :=
 endif # TARGET_NO_BOOTLOADER
 ifneq ($(strip $(TARGET_NO_KERNEL)),true)
-  INSTALLED_KERNEL_TARGET := $(PRODUCT_OUT)/kernel
+  ifneq ($(strip $(BOARD_KERNEL_BINARIES)),)
+    INSTALLED_KERNEL_TARGET := $(foreach k,$(BOARD_KERNEL_BINARIES), \
+      $(PRODUCT_OUT)/$(k))
+  else
+    INSTALLED_KERNEL_TARGET := $(PRODUCT_OUT)/kernel
+  endif
 else
   INSTALLED_KERNEL_TARGET :=
 endif
@@ -1104,7 +1116,12 @@
 
 # This is defined here since we may be building recovery as boot
 # below and only want to define this once
-BUILT_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
+ifneq ($(strip $(BOARD_KERNEL_BINARIES)),)
+  BUILT_BOOTIMAGE_TARGET := $(foreach k,$(subst kernel,boot,$(BOARD_KERNEL_BINARIES)), $(PRODUCT_OUT)/$(k).img)
+else
+  BUILT_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
+endif
+
 
 ifneq ($(strip $(TARGET_NO_KERNEL)),true)
 INTERNAL_BOOTIMAGE_ARGS := \
@@ -2113,7 +2130,7 @@
 else # INSTALLED_VENDOR_BOOTIMAGE_TARGET not defined
   INTERNAL_RECOVERYIMAGE_ARGS := \
       $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
-      --kernel $(recovery_kernel) --ramdisk $(recovery_ramdisk)
+      --ramdisk $(recovery_ramdisk)
 # Assumes this has already been stripped
 ifdef INTERNAL_KERNEL_CMDLINE
   INTERNAL_RECOVERYIMAGE_ARGS += --cmdline "$(INTERNAL_KERNEL_CMDLINE)"
@@ -2139,38 +2156,53 @@
 endif
 endif # INSTALLED_VENDOR_BOOTIMAGE_TARGET not defined
 
+$(recovery_ramdisk): $(MKBOOTFS) $(MINIGZIP) \
+	    $(INTERNAL_ROOT_FILES) \
+	    $(INSTALLED_RAMDISK_TARGET) \
+	    $(INTERNAL_RECOVERYIMAGE_FILES) \
+	    $(recovery_sepolicy) \
+	    $(INSTALLED_2NDBOOTLOADER_TARGET) \
+	    $(INSTALLED_RECOVERY_BUILD_PROP_TARGET) \
+	    $(recovery_resource_deps) \
+	    $(recovery_fstab)
+	# Making recovery image
+	mkdir -p $(TARGET_RECOVERY_OUT)
+	mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/sdcard $(TARGET_RECOVERY_ROOT_OUT)/tmp
+	# Copying baseline ramdisk...
+	# Use rsync because "cp -Rf" fails to overwrite broken symlinks on Mac.
+	rsync -a --exclude=sdcard $(IGNORE_RECOVERY_SEPOLICY) $(IGNORE_CACHE_LINK) $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
+	# Modifying ramdisk contents...
+	$(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),, \
+	  ln -sf /system/bin/init $(TARGET_RECOVERY_ROOT_OUT)/init)
+	# Removes $(TARGET_RECOVERY_ROOT_OUT)/init*.rc EXCEPT init.recovery*.rc.
+	find $(TARGET_RECOVERY_ROOT_OUT) -maxdepth 1 -name 'init*.rc' -type f -not -name "init.recovery.*.rc" | xargs rm -f
+	cp $(TARGET_ROOT_OUT)/init.recovery.*.rc $(TARGET_RECOVERY_ROOT_OUT)/ 2> /dev/null || true # Ignore error when the src file doesn't exist.
+	mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/res
+	rm -rf $(TARGET_RECOVERY_ROOT_OUT)/res/*
+	cp -rf $(recovery_resources_common)/* $(TARGET_RECOVERY_ROOT_OUT)/res
+	$(foreach recovery_text_file,$(generated_recovery_text_files), \
+	  cp -rf $(recovery_text_file) $(TARGET_RECOVERY_ROOT_OUT)/res/images/ &&) true
+	cp -f $(recovery_font) $(TARGET_RECOVERY_ROOT_OUT)/res/images/font.png
+	$(foreach item,$(TARGET_PRIVATE_RES_DIRS), \
+	  cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/$(newline))
+	$(foreach item,$(recovery_fstab), \
+	  cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/system/etc/recovery.fstab)
+	$(if $(strip $(recovery_wipe)), \
+	  cp -f $(recovery_wipe) $(TARGET_RECOVERY_ROOT_OUT)/system/etc/recovery.wipe)
+	ln -sf prop.default $(TARGET_RECOVERY_ROOT_OUT)/default.prop
+	$(BOARD_RECOVERY_IMAGE_PREPARE)
+	$(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
+
 # $(1): output file
+# $(2): kernel file
 define build-recoveryimage-target
-  # Making recovery image
-  $(hide) mkdir -p $(TARGET_RECOVERY_OUT)
-  $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/sdcard $(TARGET_RECOVERY_ROOT_OUT)/tmp
-  # Copying baseline ramdisk...
-  # Use rsync because "cp -Rf" fails to overwrite broken symlinks on Mac.
-  $(hide) rsync -a --exclude=sdcard $(IGNORE_RECOVERY_SEPOLICY) $(IGNORE_CACHE_LINK) $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
-  # Modifying ramdisk contents...
-  $(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),, \
-    $(hide) ln -sf /system/bin/init $(TARGET_RECOVERY_ROOT_OUT)/init)
-  # Removes $(TARGET_RECOVERY_ROOT_OUT)/init*.rc EXCEPT init.recovery*.rc.
-  $(hide) find $(TARGET_RECOVERY_ROOT_OUT) -maxdepth 1 -name 'init*.rc' -type f -not -name "init.recovery.*.rc" | xargs rm -f
-  $(hide) cp $(TARGET_ROOT_OUT)/init.recovery.*.rc $(TARGET_RECOVERY_ROOT_OUT)/ 2> /dev/null || true # Ignore error when the src file doesn't exist.
-  $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/res
-  $(hide) rm -rf $(TARGET_RECOVERY_ROOT_OUT)/res/*
-  $(hide) cp -rf $(recovery_resources_common)/* $(TARGET_RECOVERY_ROOT_OUT)/res
-  $(hide) $(foreach recovery_text_file,$(generated_recovery_text_files), \
-    cp -rf $(recovery_text_file) $(TARGET_RECOVERY_ROOT_OUT)/res/images/ &&) true
-  $(hide) cp -f $(recovery_font) $(TARGET_RECOVERY_ROOT_OUT)/res/images/font.png
-  $(hide) $(foreach item,$(TARGET_PRIVATE_RES_DIRS), \
-    cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/$(newline))
-  $(hide) $(foreach item,$(recovery_fstab), \
-    cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/system/etc/recovery.fstab)
-  $(if $(strip $(recovery_wipe)), \
-    $(hide) cp -f $(recovery_wipe) $(TARGET_RECOVERY_ROOT_OUT)/system/etc/recovery.wipe)
-  $(hide) ln -sf prop.default $(TARGET_RECOVERY_ROOT_OUT)/default.prop
-  $(BOARD_RECOVERY_IMAGE_PREPARE)
-  $(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
   $(if $(filter true,$(PRODUCT_SUPPORTS_VBOOT)), \
-    $(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1).unsigned, \
-    $(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1))
+    $(MKBOOTIMG) --kernel $(2) $(MKBOOTIMG_KERNEL_ARG) $(INTERNAL_RECOVERYIMAGE_ARGS) \
+                 $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) \
+                 --output $(1).unsigned, \
+    $(MKBOOTIMG) --kernel $(2) $(MKBOOTIMG_KERNEL_ARG) $(INTERNAL_RECOVERYIMAGE_ARGS) \
+                 $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) \
+                 --output $(1))
   $(if $(filter true,$(PRODUCT_SUPPORTS_BOOT_SIGNER)),\
     $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
       $(BOOT_SIGNER) /boot $(1) $(PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCT_VERITY_SIGNING_KEY).x509.pem $(1),\
@@ -2180,12 +2212,12 @@
   $(if $(filter true,$(PRODUCT_SUPPORTS_VBOOT)), \
     $(VBOOT_SIGNER) $(FUTILITY) $(1).unsigned $(PRODUCT_VBOOT_SIGNING_KEY).vbpubk $(PRODUCT_VBOOT_SIGNING_KEY).vbprivk $(PRODUCT_VBOOT_SIGNING_SUBKEY).vbprivk $(1).keyblock $(1))
   $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)), \
-    $(hide) $(call assert-max-image-size,$(1),$(call get-hash-image-max-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))), \
-    $(hide) $(call assert-max-image-size,$(1),$(call get-hash-image-max-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))))
+    $(call assert-max-image-size,$(1),$(call get-hash-image-max-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))), \
+    $(call assert-max-image-size,$(1),$(call get-hash-image-max-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))))
   $(if $(filter true,$(BOARD_AVB_ENABLE)), \
     $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)), \
-      $(hide) $(AVBTOOL) add_hash_footer --image $(1) --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) --partition_name boot $(INTERNAL_AVB_BOOT_SIGNING_ARGS) $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS),\
-      $(hide) $(AVBTOOL) add_hash_footer --image $(1) --partition_size $(BOARD_RECOVERYIMAGE_PARTITION_SIZE) --partition_name recovery $(INTERNAL_AVB_RECOVERY_SIGNING_ARGS) $(BOARD_AVB_RECOVERY_ADD_HASH_FOOTER_ARGS)))
+      $(AVBTOOL) add_hash_footer --image $(1) --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) --partition_name boot $(INTERNAL_AVB_BOOT_SIGNING_ARGS) $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS),\
+      $(AVBTOOL) add_hash_footer --image $(1) --partition_size $(BOARD_RECOVERYIMAGE_PARTITION_SIZE) --partition_name recovery $(INTERNAL_AVB_RECOVERY_SIGNING_ARGS) $(BOARD_AVB_RECOVERY_ADD_HASH_FOOTER_ARGS)))
 endef
 
 ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
@@ -2212,18 +2244,10 @@
 $(INSTALLED_BOOTIMAGE_TARGET): $(INSTALLED_DTBIMAGE_TARGET)
 endif
 
-$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
-	    $(INTERNAL_ROOT_FILES) \
-	    $(INSTALLED_RAMDISK_TARGET) \
-	    $(INTERNAL_RECOVERYIMAGE_FILES) \
-	    $(recovery_sepolicy) $(recovery_kernel) \
-	    $(INSTALLED_2NDBOOTLOADER_TARGET) \
-	    $(INSTALLED_RECOVERY_BUILD_PROP_TARGET) \
-	    $(recovery_resource_deps) \
-	    $(recovery_fstab)
+$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(recovery_ramdisk) \
+	    $(recovery_kernel)
 	$(call pretty,"Target boot image from recovery: $@")
-	$(call build-recoveryimage-target, $@)
-$(INSTALLED_BOOTIMAGE_TARGET): .KATI_IMPLICIT_OUTPUTS += $(recovery_ramdisk)
+	$(call build-recoveryimage-target, $@, $(PRODUCT_OUT)/$(subst .img,,$(subst boot,kernel,$(notdir $@))))
 endif # BOARD_USES_RECOVERY_AS_BOOT
 
 ifdef BOARD_INCLUDE_RECOVERY_DTBO
@@ -2240,17 +2264,9 @@
 $(INSTALLED_RECOVERYIMAGE_TARGET): $(INSTALLED_DTBIMAGE_TARGET)
 endif
 
-$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
-	    $(INTERNAL_ROOT_FILES) \
-	    $(INSTALLED_RAMDISK_TARGET) \
-	    $(INSTALLED_BOOTIMAGE_TARGET) \
-	    $(INTERNAL_RECOVERYIMAGE_FILES) \
-	    $(recovery_sepolicy) $(recovery_kernel) \
-	    $(INSTALLED_2NDBOOTLOADER_TARGET) \
-	    $(INSTALLED_RECOVERY_BUILD_PROP_TARGET) \
-	    $(recovery_resource_deps) \
-	    $(recovery_fstab)
-	$(call build-recoveryimage-target, $@)
+$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTIMG) $(recovery_ramdisk) \
+	    $(recovery_kernel)
+	$(call build-recoveryimage-target, $@, $(recovery_kernel))
 
 ifdef RECOVERY_RESOURCE_ZIP
 $(RECOVERY_RESOURCE_ZIP): $(INSTALLED_RECOVERYIMAGE_TARGET) | $(ZIPTIME)
@@ -2361,8 +2377,12 @@
 # Note: it's intentional to skip signing for boot-debug.img, because it
 # can only be used if the device is unlocked with verification error.
 ifneq ($(strip $(TARGET_NO_KERNEL)),true)
-
-INSTALLED_DEBUG_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot-debug.img
+ifneq ($(strip $(BOARD_KERNEL_BINARIES)),)
+  INSTALLED_DEBUG_BOOTIMAGE_TARGET := $(foreach k,$(subst kernel,boot-debug,$(BOARD_KERNEL_BINARIES)), \
+         $(PRODUCT_OUT)/$(k).img)
+else
+  INSTALLED_DEBUG_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot-debug.img
+endif
 
 # Replace ramdisk.img in $(MKBOOTIMG) ARGS with ramdisk-debug.img to build boot-debug.img
 ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
@@ -2392,17 +2412,22 @@
 $(call assert-max-image-size,$(1),$(BOARD_BOOTIMAGE_PARTITION_SIZE))
 endef
 
+# $(1): output file
+define build-debug-bootimage-target
+  $(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-debug,kernel,$(notdir $(1)))) \
+    $(INTERNAL_DEBUG_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $1
+  $(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$1))
+endef
+
 # Depends on original boot.img and ramdisk-debug.img, to build the new boot-debug.img
 $(INSTALLED_DEBUG_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_DEBUG_RAMDISK_TARGET)
 	$(call pretty,"Target boot debug image: $@")
-	$(MKBOOTIMG) $(INTERNAL_DEBUG_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
-	$(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$@))
+	$(call build-debug-bootimage-target, $@)
 
 .PHONY: bootimage_debug-nodeps
 bootimage_debug-nodeps: $(MKBOOTIMG)
 	echo "make $@: ignoring dependencies"
-	$(MKBOOTIMG) $(INTERNAL_DEBUG_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_DEBUG_BOOTIMAGE_TARGET)
-	$(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$(INSTALLED_DEBUG_BOOTIMAGE_TARGET)))
+	$(foreach b,$(INSTALLED_DEBUG_BOOTIMAGE_TARGET),$(call build-debug-bootimage-target,$b))
 
 endif # TARGET_NO_KERNEL
 
@@ -3722,8 +3747,12 @@
 check_vintf_has_vendor := true
 check_vintf_vendor_log := $(intermediates)/check_vintf_vendor_log
 check_vintf_all_deps += $(check_vintf_vendor_log)
+# Check vendor SKU=(empty) case when:
+# - DEVICE_MANIFEST_FILE is not empty; OR
+# - DEVICE_MANIFEST_FILE is empty AND DEVICE_MANIFEST_SKUS is empty (only vendor manifest fragments are used)
 $(check_vintf_vendor_log): PRIVATE_VENDOR_SKUS := \
-  $(if $(DEVICE_MANIFEST_FILE),EMPTY_VENDOR_SKU_PLACEHOLDER) \
+  $(if $(DEVICE_MANIFEST_FILE),EMPTY_VENDOR_SKU_PLACEHOLDER,\
+    $(if $(DEVICE_MANIFEST_SKUS),,EMPTY_VENDOR_SKU_PLACEHOLDER)) \
   $(DEVICE_MANIFEST_SKUS)
 $(check_vintf_vendor_log): $(HOST_OUT_EXECUTABLES)/checkvintf $(check_vintf_vendor_deps)
 	$(foreach vendor_sku,$(PRIVATE_VENDOR_SKUS), \
@@ -3823,11 +3852,19 @@
 
 $(check_vintf_compatible_log): PRIVATE_CHECK_VINTF_ARGS := $(check_vintf_compatible_args)
 $(check_vintf_compatible_log): PRIVATE_CHECK_VINTF_DEPS := $(check_vintf_compatible_deps)
+# Check ODM SKU=(empty) case when:
+# - ODM_MANIFEST_FILES is not empty; OR
+# - ODM_MANIFEST_FILES is empty AND ODM_MANIFEST_SKUS is empty (only ODM manifest fragments are used)
 $(check_vintf_compatible_log): PRIVATE_ODM_SKUS := \
-  $(if $(ODM_MANIFEST_FILES),EMPTY_ODM_SKU_PLACEHOLDER) \
+  $(if $(ODM_MANIFEST_FILES),EMPTY_ODM_SKU_PLACEHOLDER,\
+    $(if $(ODM_MANIFEST_SKUS),,EMPTY_ODM_SKU_PLACEHOLDER)) \
   $(ODM_MANIFEST_SKUS)
+# Check vendor SKU=(empty) case when:
+# - DEVICE_MANIFEST_FILE is not empty; OR
+# - DEVICE_MANIFEST_FILE is empty AND DEVICE_MANIFEST_SKUS is empty (only vendor manifest fragments are used)
 $(check_vintf_compatible_log): PRIVATE_VENDOR_SKUS := \
-  $(if $(DEVICE_MANIFEST_FILE),EMPTY_VENDOR_SKU_PLACEHOLDER) \
+  $(if $(DEVICE_MANIFEST_FILE),EMPTY_VENDOR_SKU_PLACEHOLDER,\
+    $(if $(DEVICE_MANIFEST_SKUS),,EMPTY_VENDOR_SKU_PLACEHOLDER)) \
   $(DEVICE_MANIFEST_SKUS)
 $(check_vintf_compatible_log): $(HOST_OUT_EXECUTABLES)/checkvintf $(check_vintf_compatible_deps)
 	@echo -n -e 'Deps: \n  ' > $@
@@ -4455,7 +4492,7 @@
 	$(hide) $(call package_files-copy-root, \
 	    $(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/$(PRIVATE_RECOVERY_OUT)/RAMDISK)
 ifdef INSTALLED_KERNEL_TARGET
-	cp $(INSTALLED_KERNEL_TARGET) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/kernel
+	cp $(INSTALLED_KERNEL_TARGET) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/
 endif
 ifdef INSTALLED_VENDOR_BOOTIMAGE_TARGET
 	echo "$(GENERIC_KERNEL_CMDLINE)" > $(zip_root)/$(PRIVATE_RECOVERY_OUT)/cmdline
@@ -4876,6 +4913,19 @@
 	$(hide) find $(TARGET_OUT_COVERAGE) | sort >$(PRIVATE_LIST_FILE)
 	$(hide) $(SOONG_ZIP) -d -o $@ -C $(TARGET_OUT_COVERAGE) -l $(PRIVATE_LIST_FILE)
 
+#------------------------------------------------------------------
+# Export the LLVM profile data tool and dependencies for Clang coverage processing
+#
+ifeq (true,$(CLANG_COVERAGE))
+  LLVM_PROFDATA := $(LLVM_PREBUILTS_BASE)/linux-x86/$(LLVM_PREBUILTS_VERSION)/bin/llvm-profdata
+  LIBCXX := $(LLVM_PREBUILTS_BASE)/linux-x86/$(LLVM_PREBUILTS_VERSION)/lib64/libc++.so.1
+  PROFDATA_ZIP := $(PRODUCT_OUT)/llvm-profdata.zip
+  $(PROFDATA_ZIP): $(SOONG_ZIP)
+	$(hide) $(SOONG_ZIP) -d -o $@ -C $(LLVM_PREBUILTS_BASE)/linux-x86/$(LLVM_PREBUILTS_VERSION) -f $(LLVM_PROFDATA) -f $(LIBCXX)
+
+  $(call dist-for-goals,droidcore,$(PROFDATA_ZIP))
+endif
+
 # -----------------------------------------------------------------
 # A zip of the Android Apps. Not keeping full path so that we don't
 # include product names when distributing
diff --git a/core/app_prebuilt_internal.mk b/core/app_prebuilt_internal.mk
index ce554c9..05d9001 100644
--- a/core/app_prebuilt_internal.mk
+++ b/core/app_prebuilt_internal.mk
@@ -167,6 +167,9 @@
 
 include $(BUILD_SYSTEM)/app_certificate_validate.mk
 
+# Set a actual_partition_tag (calculated in base_rules.mk) for the package.
+PACKAGES.$(LOCAL_MODULE).PARTITION := $(actual_partition_tag)
+
 # Disable dex-preopt of prebuilts to save space, if requested.
 ifndef LOCAL_DEX_PREOPT
 ifeq ($(DONT_DEXPREOPT_PREBUILTS),true)
diff --git a/core/base_rules.mk b/core/base_rules.mk
index cce6ec1..f78e509 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -208,23 +208,39 @@
 my_module_relative_path := $(strip $(LOCAL_MODULE_RELATIVE_PATH))
 ifdef LOCAL_IS_HOST_MODULE
   partition_tag :=
+  actual_partition_tag :=
 else
 ifeq (true,$(strip $(LOCAL_VENDOR_MODULE)))
   partition_tag := _VENDOR
+  # A vendor module could be on the vendor partition at "vendor" or the system
+  # partition at "system/vendor".
+  actual_partition_tag := $(if $(filter true,$(BOARD_USES_VENDORIMAGE)),vendor,system)
 else ifeq (true,$(strip $(LOCAL_OEM_MODULE)))
   partition_tag := _OEM
+  actual_partition_tag := oem
 else ifeq (true,$(strip $(LOCAL_ODM_MODULE)))
   partition_tag := _ODM
+  # An ODM module could be on the odm partition at "odm", the vendor partition
+  # at "vendor/odm", or the system partition at "system/vendor/odm".
+  actual_partition_tag := $(if $(filter true,$(BOARD_USES_ODMIMAGE)),odm,$(if $(filter true,$(BOARD_USES_VENDORIMAGE)),vendor,system))
 else ifeq (true,$(strip $(LOCAL_PRODUCT_MODULE)))
   partition_tag := _PRODUCT
+  # A product module could be on the product partition at "product" or the
+  # system partition at "system/product".
+  actual_partition_tag := $(if $(filter true,$(BOARD_USES_PRODUCTIMAGE)),product,system)
 else ifeq (true,$(strip $(LOCAL_SYSTEM_EXT_MODULE)))
   partition_tag := _SYSTEM_EXT
+  # A system_ext-specific module could be on the system_ext partition at
+  # "system_ext" or the system partition at "system/system_ext".
+  actual_partition_tag := $(if $(filter true,$(BOARD_USES_SYSTEM_EXTIMAGE)),system_ext,system)
 else ifeq (NATIVE_TESTS,$(LOCAL_MODULE_CLASS))
   partition_tag := _DATA
+  actual_partition_tag := data
 else
   # The definition of should-install-to-system will be different depending
   # on which goal (e.g., sdk or just droid) is being built.
   partition_tag := $(if $(call should-install-to-system,$(my_module_tags)),,_DATA)
+  actual_partition_tag := $(if $(partition_tag),data,system)
 endif
 endif
 # For test modules that lack a suite tag, set null-suite as the default.
@@ -705,13 +721,19 @@
 
 ifeq ($(use_testcase_folder),true)
 ifneq ($(my_test_data_file_pairs),)
+# Filter out existng installed test data paths when collecting test data files to be installed and
+# indexed as they cause build rule conflicts. Instead put them in a separate list which is only
+# used for indexing.
 $(foreach pair, $(my_test_data_file_pairs), \
   $(eval parts := $(subst :,$(space),$(pair))) \
   $(eval src_path := $(word 1,$(parts))) \
   $(eval file := $(word 2,$(parts))) \
   $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
     $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite),$(arch_dir)), \
-      $(call filter-copy-pair,$(src_path),$(call append-path,$(dir),$(file)),$(my_installed_test_data))))))
+      $(call filter-copy-pair,$(src_path),$(call append-path,$(dir),$(file)),$(my_installed_test_data)))) \
+    $(eval my_compat_dist_test_data_$(suite) += \
+      $(foreach dir, $(call compatibility_suite_dirs,$(suite),$(arch_dir)), \
+        $(filter $(my_installed_test_data),$(call append-path,$(dir),$(file)))))))
 endif
 else
 ifneq ($(my_test_data_file_pairs),)
@@ -732,7 +754,8 @@
 
 $(call create-suite-dependencies)
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-  $(eval my_compat_dist_config_$(suite) := ))
+  $(eval my_compat_dist_config_$(suite) := ) \
+  $(eval my_compat_dist_test_data_$(suite) := ))
 
 endif  # LOCAL_COMPATIBILITY_SUITE
 
diff --git a/core/definitions.mk b/core/definitions.mk
index fb11ab6..3499da9 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2897,7 +2897,8 @@
   $(if $(filter $(suite),$(ALL_COMPATIBILITY_SUITES)),,$(eval ALL_COMPATIBILITY_SUITES += $(suite))) \
   $(eval COMPATIBILITY.$(suite).FILES := \
     $$(COMPATIBILITY.$(suite).FILES) $$(foreach f,$$(my_compat_dist_$(suite)),$$(call word-colon,2,$$(f))) \
-      $$(foreach f,$$(my_compat_dist_config_$(suite)),$$(call word-colon,2,$$(f)))) \
+      $$(foreach f,$$(my_compat_dist_config_$(suite)),$$(call word-colon,2,$$(f))) \
+      $$(my_compat_dist_test_data_$(suite))) \
   $(eval COMPATIBILITY.$(suite).MODULES := \
     $$(COMPATIBILITY.$(suite).MODULES) $$(my_register_name))) \
 $(eval $(my_all_targets) : $(call copy-many-files, \
diff --git a/core/envsetup.mk b/core/envsetup.mk
index e38329d..ac3d5cf 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -259,8 +259,6 @@
 # Jars present in the ART apex. These should match exactly the list of
 # Java libraries in the ART apex build rule.
 ART_APEX_JARS := core-oj core-libart core-icu4j okhttp bouncycastle apache-xml
-TARGET_CORE_JARS := $(ART_APEX_JARS) conscrypt
-HOST_CORE_JARS := $(addsuffix -hostdex,$(TARGET_CORE_JARS))
 #################################################################
 
 # Read the product specs so we can get TARGET_DEVICE and other
diff --git a/core/main.mk b/core/main.mk
index 277ef7d..5fb3810 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -310,7 +310,7 @@
 endif
 ifndef is_sdk_build
   # To speedup startup of non-preopted builds, don't verify or compile the boot image.
-  ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.image-dex2oat-filter=verify-at-runtime
+  ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.image-dex2oat-filter=extract
 endif
 endif
 
diff --git a/core/ninja_config.mk b/core/ninja_config.mk
index c2d2a5b..3f2e5de 100644
--- a/core/ninja_config.mk
+++ b/core/ninja_config.mk
@@ -46,7 +46,7 @@
 	user \
 	userdataimage \
 	userdebug \
-	vts \
+	vts10 \
 	win_sdk \
 	winsdk-tools
 
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 7bbaeb6..c6c2cf5 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -100,19 +100,19 @@
 # Determine whether auto-RRO is enabled for this package.
 enforce_rro_enabled :=
 ifneq (,$(filter *, $(PRODUCT_ENFORCE_RRO_TARGETS)))
-  # * means all system APKs, so enable conditionally based on module path.
+  # * means all system and system_ext APKs, so enable conditionally based on module path.
+  # Note that modules in PRODUCT_ENFORCE_RRO_EXEMPTED_TARGETS are excluded even if it is '*'
 
   # Note that base_rules.mk has not yet been included, so it's likely that only
   # one of LOCAL_MODULE_PATH and the LOCAL_X_MODULE flags has been set.
   ifeq (,$(LOCAL_MODULE_PATH))
-    non_system_module := $(filter true,\
+    non_rro_target_module := $(filter true,\
         $(LOCAL_ODM_MODULE) \
         $(LOCAL_OEM_MODULE) \
         $(LOCAL_PRODUCT_MODULE) \
-        $(LOCAL_SYSTEM_EXT_MODULE) \
         $(LOCAL_PROPRIETARY_MODULE) \
         $(LOCAL_VENDOR_MODULE))
-    enforce_rro_enabled := $(if $(non_system_module),,true)
+    enforce_rro_enabled := $(if $(non_rro_target_module),,true)
   else ifneq ($(filter $(TARGET_OUT)/%,$(LOCAL_MODULE_PATH)),)
     enforce_rro_enabled := true
   endif
@@ -120,6 +120,12 @@
   enforce_rro_enabled := true
 endif
 
+# TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency.
+ifneq (,$(filter $(LOCAL_PACKAGE_NAME), $(PRODUCT_ENFORCE_RRO_EXEMPTED_TARGETS)))
+  enforce_rro_enabled :=
+endif
+
+
 product_package_overlays := $(strip \
     $(wildcard $(foreach dir, $(PRODUCT_PACKAGE_OVERLAYS), \
       $(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))))
@@ -465,6 +471,9 @@
 $(LOCAL_BUILT_MODULE): $(additional_certificates)
 $(LOCAL_BUILT_MODULE): PRIVATE_ADDITIONAL_CERTIFICATES := $(additional_certificates)
 
+# Set a actual_partition_tag (calculated in base_rules.mk) for the package.
+PACKAGES.$(LOCAL_PACKAGE_NAME).PARTITION := $(actual_partition_tag)
+
 # Verify LOCAL_USES_LIBRARIES/LOCAL_OPTIONAL_USES_LIBRARIES
 # If LOCAL_ENFORCE_USES_LIBRARIES is not set, default to true if either of LOCAL_USES_LIBRARIES or
 # LOCAL_OPTIONAL_USES_LIBRARIES are specified.
diff --git a/core/product.mk b/core/product.mk
index 25a9c44..b497abb 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -193,6 +193,9 @@
 # Package list to apply enforcing RRO.
 _product_list_vars += PRODUCT_ENFORCE_RRO_TARGETS
 
+# Packages to skip auto-generating RROs for when PRODUCT_ENFORCE_RRO_TARGETS is set to *.
+_product_list_vars += PRODUCT_ENFORCE_RRO_EXEMPTED_TARGETS
+
 _product_list_vars += PRODUCT_SDK_ATREE_FILES
 _product_list_vars += PRODUCT_SDK_ADDON_NAME
 _product_list_vars += PRODUCT_SDK_ADDON_COPY_FILES
@@ -213,6 +216,12 @@
 
 # A list of module names of BOOTCLASSPATH (jar files)
 _product_list_vars += PRODUCT_BOOT_JARS
+
+# A list of extra BOOTCLASSPATH jars (to be appended after common jars).
+# Products that include device-specific makefiles before AOSP makefiles should use this
+# instead of PRODUCT_BOOT_JARS, so that device-specific jars go after common jars.
+_product_list_vars += PRODUCT_BOOT_JARS_EXTRA
+
 _product_list_vars += PRODUCT_SUPPORTS_BOOT_SIGNER
 _product_list_vars += PRODUCT_SUPPORTS_VBOOT
 _product_list_vars += PRODUCT_SUPPORTS_VERITY
diff --git a/core/product_config.mk b/core/product_config.mk
index c4361d0..aabd472 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -228,6 +228,9 @@
 PRODUCT_AAPT_CONFIG_SP := $(PRODUCT_AAPT_CONFIG)
 PRODUCT_AAPT_CONFIG := $(subst $(space),$(comma),$(PRODUCT_AAPT_CONFIG))
 
+# Extra boot jars must be appended at the end after common boot jars.
+PRODUCT_BOOT_JARS += $(PRODUCT_BOOT_JARS_EXTRA)
+
 ifndef PRODUCT_SYSTEM_NAME
   PRODUCT_SYSTEM_NAME := $(PRODUCT_NAME)
 endif
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index 0a5ba9d..6dc396c 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -157,6 +157,9 @@
 include $(BUILD_SYSTEM)/app_certificate_validate.mk
 PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
 
+# Set a actual_partition_tag (calculated in base_rules.mk) for the package.
+PACKAGES.$(LOCAL_MODULE).PARTITION := $(actual_partition_tag)
+
 ifdef LOCAL_SOONG_BUNDLE
   ALL_MODULES.$(LOCAL_MODULE).BUNDLE := $(LOCAL_SOONG_BUNDLE)
 endif
@@ -202,4 +205,11 @@
   )
 endif
 
+ifdef LOCAL_PREBUILT_COVERAGE_ARCHIVE
+  my_coverage_dir := $(TARGET_OUT_COVERAGE)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
+  my_coverage_copy_pairs := $(foreach f,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(f):$(my_coverage_dir)/$(notdir  $(f)))
+  my_coverage_files := $(call copy-many-files,$(my_coverage_copy_pairs))
+  $(LOCAL_INSTALLED_MODULE): $(my_coverage_files)
+endif
+
 SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
diff --git a/core/soong_config.mk b/core/soong_config.mk
index abe1923..c91639c 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -81,6 +81,7 @@
 $(call add_json_list, DeviceResourceOverlays,            $(DEVICE_PACKAGE_OVERLAYS))
 $(call add_json_list, ProductResourceOverlays,           $(PRODUCT_PACKAGE_OVERLAYS))
 $(call add_json_list, EnforceRROTargets,                 $(PRODUCT_ENFORCE_RRO_TARGETS))
+$(call add_json_list, EnforceRROExemptedTargets,         $(PRODUCT_ENFORCE_RRO_EXEMPTED_TARGETS))
 $(call add_json_list, EnforceRROExcludedOverlays,        $(PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS))
 
 $(call add_json_str,  AAPTCharacteristics,               $(TARGET_AAPT_CHARACTERISTICS))
@@ -116,6 +117,8 @@
 $(call add_json_list, CoveragePaths,                     $(COVERAGE_PATHS))
 $(call add_json_list, CoverageExcludePaths,              $(COVERAGE_EXCLUDE_PATHS))
 
+$(call add_json_bool, SamplingPGO,                       $(filter true,$(SAMPLING_PGO)))
+
 $(call add_json_bool, ArtUseReadBarrier,                 $(call invert_bool,$(filter false,$(PRODUCT_ART_USE_READ_BARRIER))))
 $(call add_json_bool, Binder32bit,                       $(BINDER32BIT))
 $(call add_json_str,  BtConfigIncludeDir,                $(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR))
diff --git a/core/tasks/device-tests.mk b/core/tasks/device-tests.mk
index f071c7c..73fad7c 100644
--- a/core/tasks/device-tests.mk
+++ b/core/tasks/device-tests.mk
@@ -21,30 +21,38 @@
 # Create an artifact to include all test config files in device-tests.
 device-tests-configs-zip := $(PRODUCT_OUT)/device-tests_configs.zip
 my_host_shared_lib_for_device_tests := $(call copy-many-files,$(COMPATIBILITY.device-tests.HOST_SHARED_LIBRARY.FILES))
-$(device-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(device-tests-list-zip) $(device-tests-configs-zip)
+device_tests_host_shared_libs_zip := $(PRODUCT_OUT)/device-tests_host-shared-libs.zip
+
+$(device-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(device-tests-list-zip) $(device-tests-configs-zip) $(device_tests_host_shared_libs_zip)
 $(device-tests-zip) : PRIVATE_device_tests_list := $(PRODUCT_OUT)/device-tests_list
 $(device-tests-zip) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_device_tests)
+$(device-tests-zip) : PRIVATE_device_host_shared_libs_zip := $(device_tests_host_shared_libs_zip)
 $(device-tests-zip) : $(COMPATIBILITY.device-tests.FILES) $(my_host_shared_lib_for_device_tests) $(SOONG_ZIP)
+	rm -f $@-shared-libs.list
 	echo $(sort $(COMPATIBILITY.device-tests.FILES)) | tr " " "\n" > $@.list
 	grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true
 	grep -e .*\\.config$$ $@-host.list > $@-host-test-configs.list || true
 	$(hide) for shared_lib in $(PRIVATE_HOST_SHARED_LIBS); do \
 	  echo $$shared_lib >> $@-host.list; \
+	  echo $$shared_lib >> $@-shared-libs.list; \
 	done
+	grep $(HOST_OUT_TESTCASES) $@-shared-libs.list > $@-host-shared-libs.list || true
 	grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
 	grep -e .*\\.config$$ $@-target.list > $@-target-test-configs.list || true
 	$(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list -P target -C $(PRODUCT_OUT) -l $@-target.list
 	$(hide) $(SOONG_ZIP) -d -o $(device-tests-configs-zip) \
 	  -P host -C $(HOST_OUT) -l $@-host-test-configs.list \
 	  -P target -C $(PRODUCT_OUT) -l $@-target-test-configs.list
+	$(SOONG_ZIP) -d -o $(PRIVATE_device_host_shared_libs_zip) \
+	  -P host -C $(HOST_OUT) -l $@-host-shared-libs.list
 	rm -f $(PRIVATE_device_tests_list)
 	$(hide) grep -e .*\\.config$$ $@-host.list | sed s%$(HOST_OUT)%host%g > $(PRIVATE_device_tests_list)
 	$(hide) grep -e .*\\.config$$ $@-target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_device_tests_list)
 	$(hide) $(SOONG_ZIP) -d -o $(device-tests-list-zip) -C $(dir $@) -f $(PRIVATE_device_tests_list)
 	rm -f $@.list $@-host.list $@-target.list $@-host-test-configs.list $@-target-test-configs.list \
-	  $(PRIVATE_device_tests_list)
+	  $@-shared-libs.list $@-host-shared-libs.list $(PRIVATE_device_tests_list)
 
 device-tests: $(device-tests-zip)
-$(call dist-for-goals, device-tests, $(device-tests-zip) $(device-tests-list-zip) $(device-tests-configs-zip))
+$(call dist-for-goals, device-tests, $(device-tests-zip) $(device-tests-list-zip) $(device-tests-configs-zip) $(device_tests_host_shared_libs_zip))
 
 tests: device-tests
diff --git a/core/tasks/general-tests.mk b/core/tasks/general-tests.mk
index 53ebddc..1cf7ef8 100644
--- a/core/tasks/general-tests.mk
+++ b/core/tasks/general-tests.mk
@@ -14,12 +14,12 @@
 
 .PHONY: general-tests
 
-# TODO(b/149249068): Remove vts-tradefed.jar after all VTS tests are converted
+# TODO(b/149249068): Remove vts10-tradefed.jar after all VTS tests are converted
 general_tests_tools := \
     $(HOST_OUT_JAVA_LIBRARIES)/cts-tradefed.jar \
     $(HOST_OUT_JAVA_LIBRARIES)/compatibility-host-util.jar \
     $(HOST_OUT_JAVA_LIBRARIES)/vts-core-tradefed.jar \
-    $(HOST_OUT_JAVA_LIBRARIES)/vts-tradefed.jar
+    $(HOST_OUT_JAVA_LIBRARIES)/vts10-tradefed.jar
 
 intermediates_dir := $(call intermediates-dir-for,PACKAGING,general-tests)
 general_tests_zip := $(PRODUCT_OUT)/general-tests.zip
diff --git a/target/board/Android.mk b/target/board/Android.mk
index ffc9baf..9edc85c 100644
--- a/target/board/Android.mk
+++ b/target/board/Android.mk
@@ -72,9 +72,9 @@
 GEN := $$(local-generated-sources-dir)/manifest_$(1).xml
 $$(GEN): PRIVATE_SRC_FILES := $$(my_fragment_files)
 $$(GEN): $$(my_fragment_files) $$(HOST_OUT_EXECUTABLES)/assemble_vintf
-	BOARD_SEPOLICY_VERS=$(BOARD_SEPOLICY_VERS) \
-	PRODUCT_ENFORCE_VINTF_MANIFEST=$(PRODUCT_ENFORCE_VINTF_MANIFEST) \
-	PRODUCT_SHIPPING_API_LEVEL=$(PRODUCT_SHIPPING_API_LEVEL) \
+	BOARD_SEPOLICY_VERS=$$(BOARD_SEPOLICY_VERS) \
+	PRODUCT_ENFORCE_VINTF_MANIFEST=$$(PRODUCT_ENFORCE_VINTF_MANIFEST) \
+	PRODUCT_SHIPPING_API_LEVEL=$$(PRODUCT_SHIPPING_API_LEVEL) \
 	$$(HOST_OUT_EXECUTABLES)/assemble_vintf -o $$@ \
 		-i $$(call normalize-path-list,$$(PRIVATE_SRC_FILES))
 
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 8f30e6d..a5264e4 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 vts,$(MAKECMDGOALS)),)
+ifneq ($(TARGET_BUILD_APPS)$(filter cts sdk vts10,$(MAKECMDGOALS)),)
 # DO NOT USE
 # DO NOT USE
 #
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 9748ef3..434cbfc 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -64,7 +64,6 @@
     com.android.tzdata \
     ContactsProvider \
     content \
-    crash_dump \
     debuggerd\
     device_config \
     dmctl \
@@ -312,8 +311,8 @@
     tz_version_host \
     tz_version_host_tzdata_apex \
 
-ifeq ($(TARGET_CORE_JARS),)
-$(error TARGET_CORE_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
+ifeq ($(ART_APEX_JARS),)
+$(error ART_APEX_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
 endif
 
 # The order matters for runtime class lookup performance.
diff --git a/target/product/base_system_ext.mk b/target/product/base_system_ext.mk
index 6847bfa..b67549a 100644
--- a/target/product/base_system_ext.mk
+++ b/target/product/base_system_ext.mk
@@ -17,4 +17,5 @@
 # Base modules and settings for the system_ext partition.
 PRODUCT_PACKAGES += \
     group_system_ext \
+    system_ext_manifest.xml \
     passwd_system_ext \
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index ccbc907..a8b75e0 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -125,6 +125,9 @@
 
 PRODUCT_ENFORCE_RRO_TARGETS := *
 
+# TODO(b/150820813) Settings depends on static overlay, remove this after eliminating the dependency.
+PRODUCT_ENFORCE_RRO_EXEMPTED_TARGETS := Settings
+
 PRODUCT_NAME := mainline_system
 PRODUCT_BRAND := generic
 
diff --git a/target/product/media_system.mk b/target/product/media_system.mk
index 5749ed5..a83e609 100644
--- a/target/product/media_system.mk
+++ b/target/product/media_system.mk
@@ -50,10 +50,10 @@
 
 # The order here is the same order they end up on the classpath, so it matters.
 PRODUCT_SYSTEM_SERVER_JARS := \
+    com.android.location.provider \
     services \
     ethernet-service \
     wifi-service \
-    com.android.location.provider \
 
 # system server jars which are updated via apex modules.
 # The values should be of the format <apex name>:<jar name>
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index b8cb2ff..5184016 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -16,10 +16,6 @@
 
 # Provides a functioning ART environment without Android frameworks
 
-ifeq ($(TARGET_CORE_JARS),)
-$(error TARGET_CORE_JARS is empty; cannot update PRODUCT_PACKAGES variable)
-endif
-
 # Additional mixins to the boot classpath.
 PRODUCT_PACKAGES += \
     android.test.base \
@@ -33,8 +29,7 @@
 
 # ART APEX module.
 # Note that this package includes the minimal boot classpath JARs (listed in
-# TARGET_CORE_JARS), which should no longer be added directly to
-# PRODUCT_PACKAGES.
+# ART_APEX_JARS), which should no longer be added directly to PRODUCT_PACKAGES.
 PRODUCT_PACKAGES += com.android.art
 PRODUCT_HOST_PACKAGES += com.android.art
 
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 90a6485..f29ec90 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -188,6 +188,7 @@
         "imgdiff",
         "minigzip",
         "mkbootfs",
+        "signapk",
     ],
 }
 
diff --git a/tools/releasetools/apex_utils.py b/tools/releasetools/apex_utils.py
index 4fac6f3..ae9b793 100644
--- a/tools/releasetools/apex_utils.py
+++ b/tools/releasetools/apex_utils.py
@@ -27,6 +27,8 @@
 
 OPTIONS = common.OPTIONS
 
+APEX_PAYLOAD_IMAGE = 'apex_payload.img'
+
 
 class ApexInfoError(Exception):
   """An Exception raised during Apex Information command."""
@@ -50,15 +52,11 @@
     self.key_passwords = key_passwords
     self.codename_to_api_level_map = codename_to_api_level_map
 
-  def ProcessApexFile(self, apk_keys, payload_key, payload_public_key,
-                      signing_args=None):
+  def ProcessApexFile(self, apk_keys, payload_key, signing_args=None):
     """Scans and signs the apk files and repack the apex
 
     Args:
       apk_keys: A dict that holds the signing keys for apk files.
-      payload_key: The path to the apex payload signing key.
-      payload_public_key: The path to the public key corresponding to the
-       payload signing key.
 
     Returns:
       The repacked apex file containing the signed apk files.
@@ -89,8 +87,7 @@
       logger.info('No apk file has been signed in %s', self.apex_path)
       return self.apex_path
 
-    return self.RepackApexPayload(payload_dir, payload_key, payload_public_key,
-                                  signing_args)
+    return self.RepackApexPayload(payload_dir, payload_key, signing_args)
 
   def ExtractApexPayloadAndSignApks(self, apk_entries, apk_keys):
     """Extracts the payload image and signs the containing apk files."""
@@ -118,27 +115,15 @@
       has_signed_apk = True
     return payload_dir, has_signed_apk
 
-  def RepackApexPayload(self, payload_dir, payload_key, payload_public_key,
-                        signing_args=None):
+  def RepackApexPayload(self, payload_dir, payload_key, signing_args=None):
     """Rebuilds the apex file with the updated payload directory."""
     apex_dir = common.MakeTempDir()
     # Extract the apex file and reuse its meta files as repack parameters.
     common.UnzipToDir(self.apex_path, apex_dir)
-
-    android_jar_path = common.OPTIONS.android_jar_path
-    if not android_jar_path:
-      android_jar_path = os.path.join(os.environ.get('ANDROID_BUILD_TOP', ''),
-                                      'prebuilts', 'sdk', 'current', 'public',
-                                      'android.jar')
-      logger.warning('android_jar_path not found in options, falling back to'
-                     ' use %s', android_jar_path)
-
     arguments_dict = {
         'manifest': os.path.join(apex_dir, 'apex_manifest.pb'),
         'build_info': os.path.join(apex_dir, 'apex_build_info.pb'),
-        'android_jar_path': android_jar_path,
         'key': payload_key,
-        'pubkey': payload_public_key,
     }
     for filename in arguments_dict.values():
       assert os.path.exists(filename), 'file {} not found'.format(filename)
@@ -151,29 +136,36 @@
       elif os.path.isdir(path):
         shutil.rmtree(path)
 
-    repacked_apex = common.MakeTempFile(suffix='.apex')
-    repack_cmd = ['apexer', '--force', '--include_build_info',
-                  '--do_not_check_keyname', '--apexer_tool_path',
-                  os.getenv('PATH')]
+    # TODO(xunchang) the signing process can be improved by using
+    # '--unsigned_payload_only'. But we need to parse the vbmeta earlier for
+    # the signing arguments, e.g. algorithm, salt, etc.
+    payload_img = os.path.join(apex_dir, APEX_PAYLOAD_IMAGE)
+    generate_image_cmd = ['apexer', '--force', '--payload_only',
+                          '--do_not_check_keyname', '--apexer_tool_path',
+                          os.getenv('PATH')]
     for key, val in arguments_dict.items():
-      repack_cmd.extend(['--' + key, val])
+      generate_image_cmd.extend(['--' + key, val])
+
     # Add quote to the signing_args as we will pass
     # --signing_args "--signing_helper_with_files=%path" to apexer
     if signing_args:
-      repack_cmd.extend(['--signing_args', '"{}"'.format(signing_args)])
+      generate_image_cmd.extend(['--signing_args', '"{}"'.format(signing_args)])
+
     # optional arguments for apex repacking
     manifest_json = os.path.join(apex_dir, 'apex_manifest.json')
     if os.path.exists(manifest_json):
-      repack_cmd.extend(['--manifest_json', manifest_json])
-    assets_dir = os.path.join(apex_dir, 'assets')
-    if os.path.isdir(assets_dir):
-      repack_cmd.extend(['--assets_dir', assets_dir])
-    repack_cmd.extend([payload_dir, repacked_apex])
+      generate_image_cmd.extend(['--manifest_json', manifest_json])
+    generate_image_cmd.extend([payload_dir, payload_img])
     if OPTIONS.verbose:
-      repack_cmd.append('-v')
-    common.RunAndCheckOutput(repack_cmd)
+      generate_image_cmd.append('-v')
+    common.RunAndCheckOutput(generate_image_cmd)
 
-    return repacked_apex
+    # Add the payload image back to the apex file.
+    common.ZipDelete(self.apex_path, APEX_PAYLOAD_IMAGE)
+    with zipfile.ZipFile(self.apex_path, 'a') as output_apex:
+      common.ZipWrite(output_apex, payload_img, APEX_PAYLOAD_IMAGE,
+                      compress_type=zipfile.ZIP_STORED)
+    return self.apex_path
 
 
 def SignApexPayload(avbtool, payload_file, payload_key_path, payload_key_name,
@@ -311,16 +303,13 @@
   with open(apex_file, 'wb') as apex_fp:
     apex_fp.write(apex_data)
 
-  APEX_PAYLOAD_IMAGE = 'apex_payload.img'
   APEX_PUBKEY = 'apex_pubkey'
 
   # 1. Extract the apex payload image and sign the containing apk files. Repack
   # the apex file after signing.
-  payload_public_key = common.ExtractAvbPublicKey(avbtool, payload_key)
   apk_signer = ApexApkSigner(apex_file, container_pw,
                              codename_to_api_level_map)
-  apex_file = apk_signer.ProcessApexFile(apk_keys, payload_key,
-                                         payload_public_key, signing_args)
+  apex_file = apk_signer.ProcessApexFile(apk_keys, payload_key, signing_args)
 
   # 2a. Extract and sign the APEX_PAYLOAD_IMAGE entry with the given
   # payload_key.
@@ -341,7 +330,7 @@
       signing_args)
 
   # 2b. Update the embedded payload public key.
-
+  payload_public_key = common.ExtractAvbPublicKey(avbtool, payload_key)
   common.ZipDelete(apex_file, APEX_PAYLOAD_IMAGE)
   if APEX_PUBKEY in zip_items:
     common.ZipDelete(apex_file, APEX_PUBKEY)
diff --git a/tools/releasetools/check_target_files_vintf.py b/tools/releasetools/check_target_files_vintf.py
index 24c6dcb..b3d491f 100755
--- a/tools/releasetools/check_target_files_vintf.py
+++ b/tools/releasetools/check_target_files_vintf.py
@@ -68,11 +68,12 @@
 
 def GetArgsForSkus(info_dict):
   odm_skus = info_dict.get('vintf_odm_manifest_skus', '').strip().split()
-  if info_dict.get('vintf_include_empty_odm_sku', '') == "true":
+  if info_dict.get('vintf_include_empty_odm_sku', '') == "true" or not odm_skus:
     odm_skus += ['']
 
   vendor_skus = info_dict.get('vintf_vendor_manifest_skus', '').strip().split()
-  if info_dict.get('vintf_include_empty_vendor_sku', '') == "true":
+  if info_dict.get('vintf_include_empty_vendor_sku', '') == "true" or \
+      not vendor_skus:
     vendor_skus += ['']
 
   return [['--property', 'ro.boot.product.hardware.sku=' + odm_sku,
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 29aefed..3bbf9d8 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1783,7 +1783,8 @@
       continue
     m = re.match(
         r'^name="(?P<NAME>.*)"\s+certificate="(?P<CERT>.*)"\s+'
-        r'private_key="(?P<PRIVKEY>.*?)"(\s+compressed="(?P<COMPRESSED>.*)")?$',
+        r'private_key="(?P<PRIVKEY>.*?)"(\s+compressed="(?P<COMPRESSED>.*)")?'
+        r'(\s+partition="(?P<PARTITION>.*)")?$',
         line)
     if not m:
       continue
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index eb68bc3..8e97509 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -79,6 +79,7 @@
 import fnmatch
 import logging
 import os
+import re
 import shutil
 import subprocess
 import sys
@@ -109,6 +110,27 @@
 OPTIONS.rebuild_recovery = False
 OPTIONS.keep_tmp = False
 
+# In an item list (framework or vendor), we may see entries that select whole
+# partitions. Such an entry might look like this 'SYSTEM/*' (e.g., for the
+# system partition). The following regex matches this and extracts the
+# partition name.
+
+PARTITION_ITEM_PATTERN = re.compile(r'^([A-Z_]+)/\*$')
+
+# In apexkeys.txt or apkcerts.txt, we may find partition tags on the various
+# entries in the file. We use these partition tags to filter the entries in
+# those files from the two different target files packages to produce a merged
+# apexkeys.txt or apkcerts.txt file. A partition tag (e.g., for the product
+# partition) looks like this: 'partition="_PRODUCT"' or 'partition="product".
+# We use the group syntax grab the value of the tag.
+
+PARTITION_TAG_PATTERN = re.compile(r'partition="(.*)"')
+
+# The sorting algorithm for apexkeys.txt and apkcerts.txt does not include the
+# ".apex" or ".apk" suffix, so we use the following pattern to extract a key.
+
+MODULE_KEY_PATTERN = re.compile(r'name="(.+)\.(apex|apk)"')
+
 # DEFAULT_FRAMEWORK_ITEM_LIST is a list of items to extract from the partial
 # framework target files package as is, meaning these items will land in the
 # output target files package exactly as they appear in the input partial
@@ -484,9 +506,40 @@
       path=output_dynamic_partitions_info_txt)
 
 
+def item_list_to_partition_set(item_list):
+  """Converts a target files item list to a partition set.
+
+  The item list contains items that might look like 'SYSTEM/*' or 'VENDOR/*' or
+  'OTA/android-info.txt'. Items that end in '/*' are assumed to match entire
+  directories where 'SYSTEM' or 'VENDOR' is a directory name that identifies the
+  contents of a partition of the same name. Other items in the list, such as the
+  'OTA' example contain metadata. This function iterates such a list, returning
+  a set that contains the partition entries.
+
+  Args:
+    item_list: A list of items in a target files package.
+  Returns:
+    A set of partitions extracted from the list of items.
+  """
+
+  partition_set = set()
+
+  for item in item_list:
+    match = PARTITION_ITEM_PATTERN.search(item.strip())
+    partition_tag = match.group(1).lower() if match else None
+
+    if partition_tag:
+      partition_set.add(partition_tag)
+
+  return partition_set
+
+
 def process_apex_keys_apk_certs_common(framework_target_files_dir,
                                        vendor_target_files_dir,
-                                       output_target_files_dir, file_name):
+                                       output_target_files_dir,
+                                       framework_partition_set,
+                                       vendor_partition_set, file_name):
+
   """Performs special processing for META/apexkeys.txt or META/apkcerts.txt.
 
   This function merges the contents of the META/apexkeys.txt or
@@ -502,6 +555,10 @@
       items extracted from the vendor target files package.
     output_target_files_dir: The name of a directory that will be used to create
       the output target files package after all the special cases are processed.
+    framework_partition_set: Partitions that are considered framework
+      partitions. Used to filter apexkeys.txt and apkcerts.txt.
+    vendor_partition_set: Partitions that are considered vendor partitions. Used
+      to filter apexkeys.txt and apkcerts.txt.
     file_name: The name of the file to merge. One of apkcerts.txt or
       apexkeys.txt.
   """
@@ -512,21 +569,44 @@
     with open(file_path) as f:
       for line in f:
         if line.strip():
-          temp[line.split()[0]] = line.strip()
+          name = line.split()[0]
+          match = MODULE_KEY_PATTERN.search(name)
+          temp[match.group(1)] = line.strip()
     return temp
 
   framework_dict = read_helper(framework_target_files_dir)
   vendor_dict = read_helper(vendor_target_files_dir)
+  merged_dict = {}
 
-  for key in framework_dict:
-    if key in vendor_dict and vendor_dict[key] != framework_dict[key]:
-      raise ValueError('Conflicting entries found in %s:\n %s and\n %s' %
-                       (file_name, framework_dict[key], vendor_dict[key]))
-    vendor_dict[key] = framework_dict[key]
+  def filter_into_merged_dict(item_dict, partition_set):
+    for key, value in item_dict.items():
+      match = PARTITION_TAG_PATTERN.search(value)
+
+      if match is None:
+        raise ValueError('Entry missing partition tag: %s' % value)
+
+      partition_tag = match.group(1)
+
+      if partition_tag in partition_set:
+        if key in merged_dict:
+          raise ValueError('Duplicate key %s' % key)
+
+        merged_dict[key] = value
+
+  filter_into_merged_dict(framework_dict, framework_partition_set)
+  filter_into_merged_dict(vendor_dict, vendor_partition_set)
 
   output_file = os.path.join(output_target_files_dir, 'META', file_name)
 
-  write_sorted_data(data=vendor_dict.values(), path=output_file)
+  # The following code is similar to write_sorted_data, but different enough
+  # that we couldn't use that function. We need the output to be sorted by the
+  # basename of the apex/apk (without the ".apex" or ".apk" suffix). This
+  # allows the sort to be consistent with the framework/vendor input data and
+  # eases comparison of input data with merged data.
+  with open(output_file, 'w') as output:
+    for key in sorted(merged_dict.keys()):
+      out_str = merged_dict[key] + '\n'
+      output.write(out_str)
 
 
 def copy_file_contexts(framework_target_files_dir, vendor_target_files_dir,
@@ -559,7 +639,9 @@
 def process_special_cases(framework_target_files_temp_dir,
                           vendor_target_files_temp_dir,
                           output_target_files_temp_dir,
-                          framework_misc_info_keys):
+                          framework_misc_info_keys,
+                          framework_partition_set,
+                          vendor_partition_set):
   """Performs special-case processing for certain target files items.
 
   Certain files in the output target files package require special-case
@@ -576,6 +658,10 @@
     framework_misc_info_keys: A list of keys to obtain from the framework
       instance of META/misc_info.txt. The remaining keys from the vendor
       instance.
+    framework_partition_set: Partitions that are considered framework
+      partitions. Used to filter apexkeys.txt and apkcerts.txt.
+    vendor_partition_set: Partitions that are considered vendor partitions. Used
+      to filter apexkeys.txt and apkcerts.txt.
   """
 
   if 'ab_update' in framework_misc_info_keys:
@@ -604,12 +690,16 @@
       framework_target_files_dir=framework_target_files_temp_dir,
       vendor_target_files_dir=vendor_target_files_temp_dir,
       output_target_files_dir=output_target_files_temp_dir,
+      framework_partition_set=framework_partition_set,
+      vendor_partition_set=vendor_partition_set,
       file_name='apkcerts.txt')
 
   process_apex_keys_apk_certs_common(
       framework_target_files_dir=framework_target_files_temp_dir,
       vendor_target_files_dir=vendor_target_files_temp_dir,
       output_target_files_dir=output_target_files_temp_dir,
+      framework_partition_set=framework_partition_set,
+      vendor_partition_set=vendor_partition_set,
       file_name='apexkeys.txt')
 
 
@@ -716,7 +806,9 @@
       framework_target_files_temp_dir=framework_target_files_temp_dir,
       vendor_target_files_temp_dir=vendor_target_files_temp_dir,
       output_target_files_temp_dir=output_target_files_temp_dir,
-      framework_misc_info_keys=framework_misc_info_keys)
+      framework_misc_info_keys=framework_misc_info_keys,
+      framework_partition_set=item_list_to_partition_set(framework_item_list),
+      vendor_partition_set=item_list_to_partition_set(vendor_item_list))
 
   return output_target_files_temp_dir
 
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 2126d11..92a46a2 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -318,7 +318,7 @@
     common.RunAndCheckOutput(cmd)
     with open(out_signature_size_file) as f:
       signature_size = f.read().rstrip()
-    logger.info("% outputs the maximum signature size: %", cmd[0],
+    logger.info("%s outputs the maximum signature size: %s", cmd[0],
                 signature_size)
     return int(signature_size)
 
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 5b7c2ac..783d63c 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -1082,7 +1082,8 @@
         r'public_key="(?P<PAYLOAD_PUBLIC_KEY>.*)"\s+'
         r'private_key="(?P<PAYLOAD_PRIVATE_KEY>.*)"\s+'
         r'container_certificate="(?P<CONTAINER_CERT>.*)"\s+'
-        r'container_private_key="(?P<CONTAINER_PRIVATE_KEY>.*)"$',
+        r'container_private_key="(?P<CONTAINER_PRIVATE_KEY>.*)"\s+'
+        r'partition="(?P<PARTITION>.*)"$',
         line)
     if not matches:
       continue
diff --git a/tools/releasetools/test_apex_utils.py b/tools/releasetools/test_apex_utils.py
index 07284ad..e19bc90 100644
--- a/tools/releasetools/test_apex_utils.py
+++ b/tools/releasetools/test_apex_utils.py
@@ -14,8 +14,10 @@
 # limitations under the License.
 #
 
+import re
 import os
 import os.path
+import shutil
 import zipfile
 
 import apex_utils
@@ -32,6 +34,7 @@
     self.testdata_dir = test_utils.get_testdata_dir()
     # The default payload signing key.
     self.payload_key = os.path.join(self.testdata_dir, 'testkey.key')
+    self.apex_with_apk = os.path.join(self.testdata_dir, 'has_apk.apex')
 
     common.OPTIONS.search_path = test_utils.get_search_path()
 
@@ -134,35 +137,43 @@
   def test_ApexApkSigner_noApkPresent(self):
     apex_path = os.path.join(self.testdata_dir, 'foo.apex')
     signer = apex_utils.ApexApkSigner(apex_path, None, None)
-    processed_apex = signer.ProcessApexFile({}, self.payload_key,
-                                            None)
+    processed_apex = signer.ProcessApexFile({}, self.payload_key)
     self.assertEqual(apex_path, processed_apex)
 
   @test_utils.SkipIfExternalToolsUnavailable()
   def test_ApexApkSigner_apkKeyNotPresent(self):
-    apex_path = os.path.join(self.testdata_dir, 'has_apk.apex')
+    apex_path = common.MakeTempFile(suffix='.apex')
+    shutil.copy(self.apex_with_apk, apex_path)
     signer = apex_utils.ApexApkSigner(apex_path, None, None)
-    self.assertRaises(apex_utils.ApexSigningError, signer.ProcessApexFile, {},
-                      self.payload_key, None)
+    self.assertRaises(apex_utils.ApexSigningError, signer.ProcessApexFile,
+                      {}, self.payload_key)
 
   @test_utils.SkipIfExternalToolsUnavailable()
   def test_ApexApkSigner_signApk(self):
-    apex_path = os.path.join(self.testdata_dir, 'has_apk.apex')
+    apex_path = common.MakeTempFile(suffix='.apex')
+    shutil.copy(self.apex_with_apk, apex_path)
     signer = apex_utils.ApexApkSigner(apex_path, None, None)
     apk_keys = {'wifi-service-resources.apk': os.path.join(
         self.testdata_dir, 'testkey')}
 
     self.payload_key = os.path.join(self.testdata_dir, 'testkey_RSA4096.key')
-    payload_pubkey = common.ExtractAvbPublicKey('avbtool',
-                                                self.payload_key)
-    signer.ProcessApexFile(apk_keys, self.payload_key, payload_pubkey)
+    apex_file = signer.ProcessApexFile(apk_keys, self.payload_key)
+    package_name_extract_cmd = ['aapt', 'dump', 'badging', apex_file]
+    output = common.RunAndCheckOutput(package_name_extract_cmd)
+    for line in output.splitlines():
+      # Sample output from aapt: "package: name='com.google.android.wifi'
+      # versionCode='1' versionName='' platformBuildVersionName='R'
+      # compileSdkVersion='29' compileSdkVersionCodename='R'"
+      match = re.search(r"^package:.* name='([\w|\.]+)'", line, re.IGNORECASE)
+      if match:
+        package_name = match.group(1)
+    self.assertEquals('com.google.android.wifi', package_name)
 
   @test_utils.SkipIfExternalToolsUnavailable()
   def test_ApexApkSigner_noAssetDir(self):
-    apex_path = os.path.join(self.testdata_dir, 'has_apk.apex')
     no_asset = common.MakeTempFile(suffix='.apex')
     with zipfile.ZipFile(no_asset, 'w') as output_zip:
-      with zipfile.ZipFile(apex_path, 'r') as input_zip:
+      with zipfile.ZipFile(self.apex_with_apk, 'r') as input_zip:
         name_list = input_zip.namelist()
         for name in name_list:
           if not name.startswith('assets'):
@@ -173,23 +184,4 @@
         self.testdata_dir, 'testkey')}
 
     self.payload_key = os.path.join(self.testdata_dir, 'testkey_RSA4096.key')
-    payload_pubkey = common.ExtractAvbPublicKey('avbtool',
-                                                self.payload_key)
-    signer.ProcessApexFile(apk_keys, self.payload_key, payload_pubkey)
-
-  @test_utils.SkipIfExternalToolsUnavailable()
-  def test_ApexApkSigner_withSignerHelper(self):
-    apex_path = os.path.join(self.testdata_dir, 'has_apk.apex')
-    signer = apex_utils.ApexApkSigner(apex_path, None, None)
-    apk_keys = {'wifi-service-resources.apk': os.path.join(
-        self.testdata_dir, 'testkey')}
-
-    self.payload_key = os.path.join(self.testdata_dir, 'testkey_RSA4096.key')
-    payload_pubkey = common.ExtractAvbPublicKey('avbtool', self.payload_key)
-
-    signing_helper = os.path.join(self.testdata_dir, 'signing_helper.sh')
-    os.chmod(signing_helper, 0o700)
-    payload_signer_args = '--signing_helper_with_files={}'.format(
-        signing_helper)
-    signer.ProcessApexFile(apk_keys, self.payload_key, payload_pubkey,
-                           payload_signer_args)
+    signer.ProcessApexFile(apk_keys, self.payload_key)
diff --git a/tools/releasetools/test_merge_target_files.py b/tools/releasetools/test_merge_target_files.py
index 1abe83c..ff8593b 100644
--- a/tools/releasetools/test_merge_target_files.py
+++ b/tools/releasetools/test_merge_target_files.py
@@ -22,6 +22,7 @@
                                 DEFAULT_FRAMEWORK_ITEM_LIST,
                                 DEFAULT_VENDOR_ITEM_LIST,
                                 DEFAULT_FRAMEWORK_MISC_INFO_KEYS, copy_items,
+                                item_list_to_partition_set,
                                 process_apex_keys_apk_certs_common)
 
 
@@ -142,6 +143,8 @@
         os.path.join(vendor_dir, 'META', 'apexkeys.txt'))
 
     process_apex_keys_apk_certs_common(framework_dir, vendor_dir, output_dir,
+                                       set(['product', 'system', 'system_ext']),
+                                       set(['odm', 'vendor']),
                                        'apexkeys.txt')
 
     merged_entries = []
@@ -175,4 +178,54 @@
         os.path.join(conflict_dir, 'META', 'apexkeys.txt'))
 
     self.assertRaises(ValueError, process_apex_keys_apk_certs_common,
-                      framework_dir, conflict_dir, output_dir, 'apexkeys.txt')
+                      framework_dir, conflict_dir, output_dir,
+                      set(['product', 'system', 'system_ext']),
+                      set(['odm', 'vendor']),
+                      'apexkeys.txt')
+
+  def test_process_apex_keys_apk_certs_HandlesApkCertsSyntax(self):
+    output_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(output_dir, 'META'))
+
+    framework_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(framework_dir, 'META'))
+    os.symlink(
+        os.path.join(self.testdata_dir, 'apkcerts_framework.txt'),
+        os.path.join(framework_dir, 'META', 'apkcerts.txt'))
+
+    vendor_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(vendor_dir, 'META'))
+    os.symlink(
+        os.path.join(self.testdata_dir, 'apkcerts_vendor.txt'),
+        os.path.join(vendor_dir, 'META', 'apkcerts.txt'))
+
+    process_apex_keys_apk_certs_common(framework_dir, vendor_dir, output_dir,
+                                       set(['product', 'system', 'system_ext']),
+                                       set(['odm', 'vendor']),
+                                       'apkcerts.txt')
+
+    merged_entries = []
+    merged_path = os.path.join(self.testdata_dir, 'apkcerts_merge.txt')
+
+    with open(merged_path) as f:
+      merged_entries = f.read().split('\n')
+
+    output_entries = []
+    output_path = os.path.join(output_dir, 'META', 'apkcerts.txt')
+
+    with open(output_path) as f:
+      output_entries = f.read().split('\n')
+
+    return self.assertEqual(merged_entries, output_entries)
+
+  def test_item_list_to_partition_set(self):
+    item_list = [
+        'META/apexkeys.txt',
+        'META/apkcerts.txt',
+        'META/filesystem_config.txt',
+        'PRODUCT/*',
+        'SYSTEM/*',
+        'SYSTEM_EXT/*',
+    ]
+    partition_set = item_list_to_partition_set(item_list)
+    self.assertEqual(set(['product', 'system', 'system_ext']), partition_set)
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 2b84413..2dacd50 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -36,8 +36,8 @@
 </policy>"""
 
   # pylint: disable=line-too-long
-  APEX_KEYS_TXT = """name="apex.apexd_test.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem" container_certificate="build/make/target/product/security/testkey.x509.pem" container_private_key="build/make/target/product/security/testkey.pk8"
-name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" container_certificate="build/make/target/product/security/testkey.x509.pem" container_private_key="build/make/target/product/security/testkey.pk8"
+  APEX_KEYS_TXT = """name="apex.apexd_test.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem" container_certificate="build/make/target/product/security/testkey.x509.pem" container_private_key="build/make/target/product/security/testkey.pk8" partition="system"
+name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" container_certificate="build/make/target/product/security/testkey.x509.pem" container_private_key="build/make/target/product/security/testkey.pk8" partition="system"
 """
 
   def setUp(self):
@@ -484,7 +484,8 @@
         'public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" '
         'private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" '
         'container_certificate="build/make/target/product/security/testkey.x509.pem" '
-        'container_private_key="build/make/target/product/security/testkey2.pk8"')
+        'container_private_key="build/make/target/product/security/testkey2.pk8" '
+        'partition="system"')
     target_files = common.MakeTempFile(suffix='.zip')
     with zipfile.ZipFile(target_files, 'w') as target_files_zip:
       target_files_zip.writestr('META/apexkeys.txt', apex_keys)
diff --git a/tools/releasetools/testdata/apexkeys_framework.txt b/tools/releasetools/testdata/apexkeys_framework.txt
index 2346668..b9caf9e 100644
--- a/tools/releasetools/testdata/apexkeys_framework.txt
+++ b/tools/releasetools/testdata/apexkeys_framework.txt
@@ -1,2 +1,7 @@
-name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.debug.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"
-name="com.android.conscrypt.apex" public_key="external/conscrypt/apex/com.android.conscrypt.avbpubkey" private_key="external/conscrypt/apex/com.android.conscrypt.pem" container_certificate="external/conscrypt/apex/com.android.conscrypt.x509.pem" container_private_key="external/conscrypt/apex/com.android.conscrypt.pk8"
+name="com.android.conscrypt.apex" public_key="external/conscrypt/apex/com.android.conscrypt.avbpubkey" private_key="external/conscrypt/apex/com.android.conscrypt.pem" container_certificate="external/conscrypt/apex/com.android.conscrypt.x509.pem" container_private_key="external/conscrypt/apex/com.android.conscrypt.pk8" partition="system"
+name="com.android.dummy_product.apex" public_key="selected" private_key="selected" container_certificate="selected" container_private_key="selected" partition="product"
+name="com.android.runtime.apex" public_key="bionic/apex/com.android.runtime.avbpubkey" private_key="bionic/apex/com.android.runtime.pem" container_certificate="bionic/apex/com.android.runtime.x509.pem" container_private_key="bionic/apex/com.android.runtime.pk8" partition="system"
+name="com.android.vndk.current.on_vendor.apex" public_key="not_selected" private_key="not_selected" container_certificate="not_selected" container_private_key="not_selected" partition="vendor"
+name="com.android.vndk.v27.apex" public_key="packages/modules/vndk/apex/com.android.vndk.v27.pubkey" private_key="packages/modules/vndk/apex/com.android.vndk.v27.pem" container_certificate="packages/modules/vndk/apex/com.android.vndk.v27.x509.pem" container_private_key="packages/modules/vndk/apex/com.android.vndk.v27.pk8" partition="system_ext"
+name="com.android.vndk.v28.apex" public_key="packages/modules/vndk/apex/com.android.vndk.v28.pubkey" private_key="packages/modules/vndk/apex/com.android.vndk.v28.pem" container_certificate="packages/modules/vndk/apex/com.android.vndk.v28.x509.pem" container_private_key="packages/modules/vndk/apex/com.android.vndk.v28.pk8" partition="system_ext"
+name="com.android.vndk.v29.apex" public_key="packages/modules/vndk/apex/com.android.vndk.v29.pubkey" private_key="packages/modules/vndk/apex/com.android.vndk.v29.pem" container_certificate="packages/modules/vndk/apex/com.android.vndk.v29.x509.pem" container_private_key="packages/modules/vndk/apex/com.android.vndk.v29.pk8" partition="system_ext"
diff --git a/tools/releasetools/testdata/apexkeys_framework_conflict.txt b/tools/releasetools/testdata/apexkeys_framework_conflict.txt
index caa21c2..9a055f4 100644
--- a/tools/releasetools/testdata/apexkeys_framework_conflict.txt
+++ b/tools/releasetools/testdata/apexkeys_framework_conflict.txt
@@ -1 +1 @@
-name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.release.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"
+name="com.android.conscrypt.apex" public_key="external/conscrypt/apex/com.android.conscrypt.avbpubkey" private_key="external/conscrypt/apex/com.android.conscrypt.pem" container_certificate="external/conscrypt/apex/com.android.conscrypt.x509.pem" container_private_key="external/conscrypt/apex/com.android.conscrypt.pk8" partition="vendor"
diff --git a/tools/releasetools/testdata/apexkeys_merge.txt b/tools/releasetools/testdata/apexkeys_merge.txt
index 48e789f..a9355d7 100644
--- a/tools/releasetools/testdata/apexkeys_merge.txt
+++ b/tools/releasetools/testdata/apexkeys_merge.txt
@@ -1,4 +1,7 @@
-name="com.android.conscrypt.apex" public_key="external/conscrypt/apex/com.android.conscrypt.avbpubkey" private_key="external/conscrypt/apex/com.android.conscrypt.pem" container_certificate="external/conscrypt/apex/com.android.conscrypt.x509.pem" container_private_key="external/conscrypt/apex/com.android.conscrypt.pk8"
-name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.debug.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"
-name="com.android.runtime.release.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.release.x509.pem" container_private_key="art/build/apex/com.android.runtime.release.pk8"
-name="com.android.support.apexer.apex" public_key="system/apex/apexer/etc/com.android.support.apexer.avbpubkey" private_key="system/apex/apexer/etc/com.android.support.apexer.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
+name="com.android.conscrypt.apex" public_key="external/conscrypt/apex/com.android.conscrypt.avbpubkey" private_key="external/conscrypt/apex/com.android.conscrypt.pem" container_certificate="external/conscrypt/apex/com.android.conscrypt.x509.pem" container_private_key="external/conscrypt/apex/com.android.conscrypt.pk8" partition="system"
+name="com.android.dummy_product.apex" public_key="selected" private_key="selected" container_certificate="selected" container_private_key="selected" partition="product"
+name="com.android.runtime.apex" public_key="bionic/apex/com.android.runtime.avbpubkey" private_key="bionic/apex/com.android.runtime.pem" container_certificate="bionic/apex/com.android.runtime.x509.pem" container_private_key="bionic/apex/com.android.runtime.pk8" partition="system"
+name="com.android.vndk.current.on_vendor.apex" public_key="packages/modules/vndk/apex/com.android.vndk.current.pubkey" private_key="packages/modules/vndk/apex/com.android.vndk.current.pem" container_certificate="packages/modules/vndk/apex/com.android.vndk.current.x509.pem" container_private_key="packages/modules/vndk/apex/com.android.vndk.current.pk8" partition="vendor"
+name="com.android.vndk.v27.apex" public_key="packages/modules/vndk/apex/com.android.vndk.v27.pubkey" private_key="packages/modules/vndk/apex/com.android.vndk.v27.pem" container_certificate="packages/modules/vndk/apex/com.android.vndk.v27.x509.pem" container_private_key="packages/modules/vndk/apex/com.android.vndk.v27.pk8" partition="system_ext"
+name="com.android.vndk.v28.apex" public_key="packages/modules/vndk/apex/com.android.vndk.v28.pubkey" private_key="packages/modules/vndk/apex/com.android.vndk.v28.pem" container_certificate="packages/modules/vndk/apex/com.android.vndk.v28.x509.pem" container_private_key="packages/modules/vndk/apex/com.android.vndk.v28.pk8" partition="system_ext"
+name="com.android.vndk.v29.apex" public_key="packages/modules/vndk/apex/com.android.vndk.v29.pubkey" private_key="packages/modules/vndk/apex/com.android.vndk.v29.pem" container_certificate="packages/modules/vndk/apex/com.android.vndk.v29.x509.pem" container_private_key="packages/modules/vndk/apex/com.android.vndk.v29.pk8" partition="system_ext"
diff --git a/tools/releasetools/testdata/apexkeys_vendor.txt b/tools/releasetools/testdata/apexkeys_vendor.txt
index b751227..7dd3964 100644
--- a/tools/releasetools/testdata/apexkeys_vendor.txt
+++ b/tools/releasetools/testdata/apexkeys_vendor.txt
@@ -1,3 +1,7 @@
-name="com.android.runtime.release.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.release.x509.pem" container_private_key="art/build/apex/com.android.runtime.release.pk8"
-name="com.android.support.apexer.apex" public_key="system/apex/apexer/etc/com.android.support.apexer.avbpubkey" private_key="system/apex/apexer/etc/com.android.support.apexer.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
-name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.debug.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"
+name="com.android.conscrypt.apex" public_key="not_selected" private_key="not_selected" container_certificate="not_selected" container_private_key="not_selected" partition="system"
+name="com.android.dummy_product.apex" public_key="not_selected" private_key="not_selected" container_certificate="not_selected" container_private_key="not_selected" partition="product"
+name="com.android.runtime.apex" public_key="not_selected" private_key="not_selected" container_certificate="not_selected" container_private_key="not_selected" partition="system"
+name="com.android.vndk.current.on_vendor.apex" public_key="packages/modules/vndk/apex/com.android.vndk.current.pubkey" private_key="packages/modules/vndk/apex/com.android.vndk.current.pem" container_certificate="packages/modules/vndk/apex/com.android.vndk.current.x509.pem" container_private_key="packages/modules/vndk/apex/com.android.vndk.current.pk8" partition="vendor"
+name="com.android.vndk.v27.apex" public_key="not_selected" private_key="not_selected" container_certificate="not_selected" container_private_key="not_selected" partition="system_ext"
+name="com.android.vndk.v28.apex" public_key="not_selected" private_key="not_selected" container_certificate="not_selected" container_private_key="not_selected" partition="system_ext"
+name="com.android.vndk.v29.apex" public_key="not_selected" private_key="not_selected" container_certificate="not_selected" container_private_key="not_selected" partition="system_ext"
diff --git a/tools/releasetools/testdata/apkcerts_framework.txt b/tools/releasetools/testdata/apkcerts_framework.txt
new file mode 100644
index 0000000..a75f55c
--- /dev/null
+++ b/tools/releasetools/testdata/apkcerts_framework.txt
@@ -0,0 +1,6 @@
+name="TestSystem1.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="system"
+name="TestSystem2.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="system"
+name="TestVendor.apk" certificate="not_selected" private_key="not_selected" partition="vendor"
+name="TestOdm.apk" certificate="not_selected" private_key="not_selected" partition="odm"
+name="TestProduct.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="product"
+name="TestSystemExt.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="system_ext"
diff --git a/tools/releasetools/testdata/apkcerts_merge.txt b/tools/releasetools/testdata/apkcerts_merge.txt
new file mode 100644
index 0000000..0425e96
--- /dev/null
+++ b/tools/releasetools/testdata/apkcerts_merge.txt
@@ -0,0 +1,6 @@
+name="TestOdm.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="odm"
+name="TestProduct.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="product"
+name="TestSystem1.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="system"
+name="TestSystem2.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="system"
+name="TestSystemExt.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="system_ext"
+name="TestVendor.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="vendor"
diff --git a/tools/releasetools/testdata/apkcerts_vendor.txt b/tools/releasetools/testdata/apkcerts_vendor.txt
new file mode 100644
index 0000000..13d5255
--- /dev/null
+++ b/tools/releasetools/testdata/apkcerts_vendor.txt
@@ -0,0 +1,6 @@
+name="TestSystem1.apk" certificate="not_selected" private_key="not_selected" partition="system"
+name="TestSystem2.apk" certificate="not_selected" private_key="not_selected" partition="system"
+name="TestVendor.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="vendor"
+name="TestOdm.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="odm"
+name="TestProduct.apk" certificate="not_selected" private_key="not_selected" partition="product"
+name="TestSystemExt.apk" certificate="not_selected" private_key="not_selected" partition="system_ext"