Merge "Print a user-friendly message when `lunch` cannot use the default product."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 673856c..97dc31f 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -713,6 +713,15 @@
 $(call add-clean-step, find $(SOONG_OUT_DIR)/.intermediates -type d -name "android_*_recovery*" -print0 | xargs -0 rm -rf)
 $(call add-clean-step, find $(SOONG_OUT_DIR)/.intermediates -type d -name "android_*_vendor*" -print0 | xargs -0 rm -rf)
 
+# Clean up VTS-Core and VTS10 related artifacts.
+$(call add-clean-step, rm -rf $(HOST_OUT)/vts-core/*)
+$(call add-clean-step, rm -rf $(HOST_OUT)/framework/vts-core-tradefed.jar)
+$(call add-clean-step, rm -rf $(HOST_OUT)/vts10/*)
+$(call add-clean-step, rm -rf $(HOST_OUT)/framework/vts10-tradefed.jar)
+# Clean up VTS again as VTS-Core will be renamed to VTS
+$(call add-clean-step, rm -rf $(HOST_OUT)/vts/*)
+$(call add-clean-step, rm -rf $(HOST_OUT)/framework/vts-tradefed.jar)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index 03d4b03..c25a8a7 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -418,7 +418,7 @@
 $(intermediate_system_build_prop): $(BUILDINFO_SH) $(BUILDINFO_COMMON_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(API_FINGERPRINT) $(POST_PROCESS_PROPS)
 	@echo Target buildinfo: $@
 	@mkdir -p $(dir $@)
-	$(hide) touch $@
+	$(hide) rm -f $@ && touch $@
 ifneq ($(PRODUCT_OEM_PROPERTIES),)
 	$(hide) echo "#" >> $@; \
 	        echo "# PRODUCT_OEM_PROPERTIES" >> $@; \
@@ -517,7 +517,7 @@
 $(INSTALLED_VENDOR_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) $(intermediate_system_build_prop) $(vendor_prop_files)
 	@echo Target vendor buildinfo: $@
 	@mkdir -p $(dir $@)
-	$(hide) touch $@
+	$(hide) rm -f $@ && touch $@
 ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
 	$(hide) echo ro.boot.dynamic_partitions=true >> $@
 endif
@@ -584,7 +584,7 @@
 $(INSTALLED_PRODUCT_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) $(product_prop_files)
 	@echo Target product buildinfo: $@
 	@mkdir -p $(dir $@)
-	$(hide) touch $@
+	$(hide) rm -f $@ && touch $@
 ifdef BOARD_USES_PRODUCTIMAGE
 	$(hide) $(call generate-common-build-props,product,$@)
 endif  # BOARD_USES_PRODUCTIMAGE
@@ -625,7 +625,7 @@
 $(INSTALLED_ODM_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) $(odm_prop_files)
 	@echo Target odm buildinfo: $@
 	@mkdir -p $(dir $@)
-	$(hide) touch $@
+	$(hide) rm -f $@ && touch $@
 	$(hide) echo ro.odm.product.cpu.abilist="$(TARGET_CPU_ABI_LIST)">>$@
 	$(hide) echo ro.odm.product.cpu.abilist32="$(TARGET_CPU_ABI_LIST_32_BIT)">>$@
 	$(hide) echo ro.odm.product.cpu.abilist64="$(TARGET_CPU_ABI_LIST_64_BIT)">>$@
@@ -666,7 +666,7 @@
 $(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) $(system_ext_prop_files)
 	@echo Target system_ext buildinfo: $@
 	@mkdir -p $(dir $@)
-	$(hide) touch $@
+	$(hide) rm -f $@ && touch $@
 	$(hide) $(call generate-common-build-props,system_ext,$@)
 	$(hide) $(foreach file,$(system_ext_prop_files), \
 	    if [ -f "$(file)" ]; then \
@@ -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 $@
 
@@ -2550,7 +2557,12 @@
 # can only be used if the device is unlocked with verification error.
 ifneq ($(strip $(TARGET_NO_KERNEL)),true)
 
-INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot-test-harness.img
+ifneq ($(strip $(BOARD_KERNEL_BINARIES)),)
+  INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET := $(foreach k,$(subst kernel,boot-test-harness,$(BOARD_KERNEL_BINARIES)), \
+    $(PRODUCT_OUT)/$(k).img)
+else
+  INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot-test-harness.img
+endif
 
 # Replace ramdisk-debug.img in $(MKBOOTIMG) ARGS with ramdisk-test-harness.img to build boot-test-harness.img
 INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS := $(subst $(INSTALLED_DEBUG_RAMDISK_TARGET),$(INSTALLED_TEST_HARNESS_RAMDISK_TARGET),$(INTERNAL_DEBUG_BOOTIMAGE_ARGS))
@@ -2563,17 +2575,22 @@
 $(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(AVBTOOL) $(BOARD_AVB_BOOT_TEST_KEY_PATH)
 endif
 
+# $(1): output file
+define build-boot-test-harness-target
+  $(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-test-harness,kernel,$(notdir $(1)))) \
+    $(INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
+  $(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$@))
+endef
+
 # Build the new boot-test-harness.img, based on boot-debug.img and ramdisk-test-harness.img.
 $(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET)
 	$(call pretty,"Target boot test harness image: $@")
-	$(MKBOOTIMG) $(INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
-	$(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$@))
+	$(call build-boot-test-harness-target,$@)
 
 .PHONY: bootimage_test_harness-nodeps
 bootimage_test_harness-nodeps: $(MKBOOTIMG)
 	echo "make $@: ignoring dependencies"
-	$(MKBOOTIMG) $(INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET)
-	$(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET)))
+	$(foreach b,$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET),$(call build-boot-test-harness-target,$b))
 
 endif # TARGET_NO_KERNEL
 endif # BOARD_BUILD_SYSTEM_ROOT_IMAGE is not true
@@ -3991,6 +4008,7 @@
 INTERNAL_OTATOOLS_MODULES := \
   aapt2 \
   add_img_to_target_files \
+  aftltool \
   append2simg \
   avbtool \
   blk_alloc_to_base_fs \
@@ -4905,6 +4923,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
@@ -5155,6 +5186,20 @@
 vendorimage: $(INSTALLED_QEMU_VENDORIMAGE)
 droidcore: $(INSTALLED_QEMU_VENDORIMAGE)
 endif
+
+ifdef INSTALLED_RAMDISK_TARGET
+ifdef INSTALLED_VENDOR_BOOTIMAGE_TARGET
+ifdef INTERNAL_VENDOR_RAMDISK_TARGET
+INSTALLED_QEMU_RAMDISKIMAGE := $(PRODUCT_OUT)/ramdisk-qemu.img
+$(INSTALLED_QEMU_RAMDISKIMAGE): $(INTERNAL_VENDOR_RAMDISK_TARGET) $(INSTALLED_RAMDISK_TARGET)
+	@echo Create ramdisk-qemu.img
+	(cat $(INSTALLED_RAMDISK_TARGET) $(INTERNAL_VENDOR_RAMDISK_TARGET) > $(INSTALLED_QEMU_RAMDISKIMAGE))
+
+droidcore: $(INSTALLED_QEMU_RAMDISKIMAGE)
+endif
+endif
+endif
+
 ifdef INSTALLED_PRODUCTIMAGE_TARGET
 INSTALLED_QEMU_PRODUCTIMAGE := $(PRODUCT_OUT)/product-qemu.img
 $(INSTALLED_QEMU_PRODUCTIMAGE): $(INSTALLED_PRODUCTIMAGE_TARGET) $(MK_QEMU_IMAGE_SH) $(SGDISK_HOST) $(SIMG2IMG)
@@ -5292,6 +5337,7 @@
 	$(APPCOMPAT_ZIP) \
 	$(INSTALLED_SYSTEMIMAGE_TARGET) \
 	$(INSTALLED_QEMU_SYSTEMIMAGE) \
+	$(INSTALLED_QEMU_RAMDISKIMAGE) \
 	$(INSTALLED_QEMU_VENDORIMAGE) \
 	$(QEMU_VERIFIED_BOOT_PARAMS) \
 	$(INSTALLED_USERDATAIMAGE_TARGET) \
diff --git a/core/app_prebuilt_internal.mk b/core/app_prebuilt_internal.mk
index ce554c9..61e13e9 100644
--- a/core/app_prebuilt_internal.mk
+++ b/core/app_prebuilt_internal.mk
@@ -163,10 +163,20 @@
   $(built_module) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
   $(built_module) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
   $(built_module) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
+
+  additional_certificates := $(foreach c,$(LOCAL_ADDITIONAL_CERTIFICATES), $(c).x509.pem $(c).pk8)
+  $(built_module): $(additional_certificates)
+  $(built_module): PRIVATE_ADDITIONAL_CERTIFICATES := $(additional_certificates)
+
+  $(built_module): $(LOCAL_CERTIFICATE_LINEAGE)
+  $(built_module): PRIVATE_CERTIFICATE_LINEAGE := $(LOCAL_CERTIFICATE_LINEAGE)
 endif
 
 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 f70911e..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.
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index e27d91c..3d481df 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -152,6 +152,7 @@
 LOCAL_JETIFIER_ENABLED:=
 LOCAL_JNI_SHARED_LIBRARIES:=
 LOCAL_JNI_SHARED_LIBRARIES_ABI:=
+LOCAL_CERTIFICATE_LINEAGE:=
 LOCAL_LDFLAGS:=
 LOCAL_LDLIBS:=
 LOCAL_LOGTAGS_FILES:=
diff --git a/core/definitions.mk b/core/definitions.mk
index 3499da9..0558a38 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2285,6 +2285,7 @@
 define sign-package-arg
 $(hide) mv $(1) $(1).unsigned
 $(hide) $(JAVA) -Djava.library.path=$$(dirname $(SIGNAPK_JNI_LIBRARY_PATH)) -jar $(SIGNAPK_JAR) \
+    $(if $(strip $(PRIVATE_CERTIFICATE_LINEAGE)), --lineage $(PRIVATE_CERTIFICATE_LINEAGE)) \
     $(PRIVATE_CERTIFICATE) $(PRIVATE_PRIVATE_KEY) \
     $(PRIVATE_ADDITIONAL_CERTIFICATES) $(1).unsigned $(1).signed
 $(hide) mv $(1).signed $(1)
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 e680df7..59e0701 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -471,6 +471,12 @@
 $(LOCAL_BUILT_MODULE): $(additional_certificates)
 $(LOCAL_BUILT_MODULE): PRIVATE_ADDITIONAL_CERTIFICATES := $(additional_certificates)
 
+$(LOCAL_BUILT_MODULE): $(LOCAL_CERTIFICATE_LINEAGE)
+$(LOCAL_BUILT_MODULE): PRIVATE_CERTIFICATE_LINEAGE := $(LOCAL_CERTIFICATE_LINEAGE)
+
+# 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/rbe.mk b/core/rbe.mk
index 7886e1a..019ac04 100644
--- a/core/rbe.mk
+++ b/core/rbe.mk
@@ -46,8 +46,12 @@
     d8_exec_strategy := "local"
   endif
 
+  platform := "container-image=docker://gcr.io/androidbuild-re-dockerimage/android-build-remoteexec-image@sha256:582efb38f0c229ea39952fff9e132ccbe183e14869b39888010dacf56b360d62"
+  cxx_platform := $(platform)",Pool=default"
+  java_r8_d8_platform := $(platform)",Pool=java16"
+
   RBE_WRAPPER := $(rbe_dir)/rewrapper
-  RBE_CXX := --labels=type=compile,lang=cpp,compiler=clang --env_var_whitelist=PWD --exec_strategy=$(cxx_rbe_exec_strategy)
+  RBE_CXX := --labels=type=compile,lang=cpp,compiler=clang --env_var_whitelist=PWD --exec_strategy=$(cxx_rbe_exec_strategy) --platform="$(cxx_platform)"
 
   # Append rewrapper to existing *_WRAPPER variables so it's possible to
   # use both ccache and rewrapper.
@@ -55,16 +59,17 @@
   CXX_WRAPPER := $(strip $(CXX_WRAPPER) $(RBE_WRAPPER) $(RBE_CXX))
 
   ifdef RBE_JAVAC
-    JAVAC_WRAPPER := $(strip $(JAVAC_WRAPPER) $(RBE_WRAPPER) --labels=type=compile,lang=java,compiler=javac,shallow=true --exec_strategy=$(javac_exec_strategy))
+    JAVAC_WRAPPER := $(strip $(JAVAC_WRAPPER) $(RBE_WRAPPER) --labels=type=compile,lang=java,compiler=javac --exec_strategy=$(javac_exec_strategy) --platform="$(java_r8_d8_platform)")
   endif
 
   ifdef RBE_R8
-    R8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=r8,shallow=true --exec_strategy=$(r8_exec_strategy))
+    R8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=r8 --exec_strategy=$(r8_exec_strategy) --platform="$(java_r8_d8_platform)" --inputs=out/soong/host/linux-x86/framework/r8-compat-proguard.jar,build/make/core/proguard_basic_keeps.flags --toolchain_inputs=prebuilts/jdk/jdk11/linux-x86/bin/java)
   endif
 
   ifdef RBE_D8
-    D8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=d8,shallow=true --exec_strategy=$(d8_exec_strategy))
+    D8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=d8 --exec_strategy=$(d8_exec_strategy) --platform="$(java_r8_d8_platform)" --inputs=out/soong/host/linux-x86/framework/d8.jar --toolchain_inputs=prebuilts/jdk/jdk11/linux-x86/bin/java)
   endif
 
   rbe_dir :=
 endif
+
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index a001e3a..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
diff --git a/core/tasks/general-tests.mk b/core/tasks/general-tests.mk
index 53ebddc..cb84a5c 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)/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/core/tasks/sdk-addon.mk b/core/tasks/sdk-addon.mk
index 7f777a5..5097f12 100644
--- a/core/tasks/sdk-addon.mk
+++ b/core/tasks/sdk-addon.mk
@@ -66,7 +66,7 @@
 files_to_copy += \
 	$(addon_dir_img):$(INSTALLED_QEMU_SYSTEMIMAGE):images/$(TARGET_CPU_ABI)/system.img \
 	$(addon_dir_img):$(INSTALLED_QEMU_VENDORIMAGE):images/$(TARGET_CPU_ABI)/vendor.img \
-	$(addon_dir_img):$(BUILT_RAMDISK_TARGET):images/$(TARGET_CPU_ABI)/ramdisk.img \
+	$(addon_dir_img):$(INSTALLED_QEMU_RAMDISKIMAGE):images/$(TARGET_CPU_ABI)/ramdisk.img \
 	$(addon_dir_img):$(PRODUCT_OUT)/system/build.prop:images/$(TARGET_CPU_ABI)/build.prop \
 	$(addon_dir_img):device/generic/goldfish/data/etc/userdata.img:images/$(TARGET_CPU_ABI)/userdata.img \
 	$(addon_dir_img):$(target_notice_file_txt):images/$(TARGET_CPU_ABI)/NOTICE.txt \
diff --git a/core/tasks/tools/package-modules.mk b/core/tasks/tools/package-modules.mk
index 55a08f5..6cafa4a 100644
--- a/core/tasks/tools/package-modules.mk
+++ b/core/tasks/tools/package-modules.mk
@@ -16,7 +16,16 @@
 #
 
 my_makefile := $(lastword $(filter-out $(lastword $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
-my_staging_dir := $(call intermediates-dir-for,PACKAGING,$(my_package_name))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(my_package_name)
+LOCAL_MODULE_CLASS := PACKAGING
+LOCAL_MODULE_STEM := $(my_package_name).zip
+LOCAL_UNINSTALLABLE_MODULE := true
+include $(BUILD_SYSTEM)/base_rules.mk
+my_staging_dir := $(intermediates)
+my_package_zip := $(LOCAL_BUILT_MODULE)
+
 my_built_modules := $(foreach p,$(my_copy_pairs),$(call word-colon,1,$(p)))
 my_copy_pairs := $(foreach p,$(my_copy_pairs),$(call word-colon,1,$(p)):$(my_staging_dir)/$(call word-colon,2,$(p)))
 my_pickup_files :=
@@ -80,7 +89,6 @@
   $(error done)
 endif
 
-my_package_zip := $(my_staging_dir)/$(my_package_name).zip
 $(my_package_zip): PRIVATE_COPY_PAIRS := $(my_copy_pairs)
 $(my_package_zip): PRIVATE_PICKUP_FILES := $(my_pickup_files)
 $(my_package_zip) : $(my_built_modules)
diff --git a/core/tasks/vts-core-tests.mk b/core/tasks/vts-core-tests.mk
index f67d722..33da020 100644
--- a/core/tasks/vts-core-tests.mk
+++ b/core/tasks/vts-core-tests.mk
@@ -12,8 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-test_suite_name := vts-core
-test_suite_tradefed := vts-core-tradefed
+test_suite_name := vts
+test_suite_tradefed := vts-tradefed
 test_suite_readme := test/vts/tools/vts-core-tradefed/README
 
 # TODO(b/149249068): Clean up after all VTS tests are converted.
@@ -23,9 +23,14 @@
 
 include $(BUILD_SYSTEM)/tasks/tools/compatibility.mk
 
-.PHONY: vts-core
+.PHONY: vts
 $(compatibility_zip): $(vts_test_artifact_paths)
-vts-core: $(compatibility_zip)
-$(call dist-for-goals, vts-core, $(compatibility_zip))
+vts: $(compatibility_zip)
+$(call dist-for-goals, vts, $(compatibility_zip))
 
-tests: vts-core
+# TODO(b/149249068): Remove vts-core phony target after it's removed from all
+# builders.
+.PHONY: vts-core
+vts-core: vts
+
+tests: vts
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index ab7783f..811bcd8 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -250,7 +250,7 @@
     #  It must be of the form "YYYY-MM-DD" on production devices.
     #  It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
     #  If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
-      PLATFORM_SECURITY_PATCH := 2020-03-05
+      PLATFORM_SECURITY_PATCH := 2020-04-05
 endif
 .KATI_READONLY := PLATFORM_SECURITY_PATCH
 
diff --git a/target/board/BoardConfigEmuCommon.mk b/target/board/BoardConfigEmuCommon.mk
index d11f9d2..a2e5518 100644
--- a/target/board/BoardConfigEmuCommon.mk
+++ b/target/board/BoardConfigEmuCommon.mk
@@ -74,6 +74,13 @@
   BOARD_VENDORIMAGE_PARTITION_SIZE := 146800640
 endif
 
+#vendor boot
+TARGET_NO_VENDOR_BOOT := false
+BOARD_INCLUDE_DTB_IN_BOOTIMG := false
+BOARD_BOOT_HEADER_VERSION := 3
+BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOT_HEADER_VERSION)
+BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE := 0x06000000
+
 # Enable chain partition for system.
 BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
 BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk
index 61aa67c..c89e203 100644
--- a/target/board/BoardConfigGsiCommon.mk
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -33,6 +33,13 @@
 #   updating the last seen rollback index in the tamper-evident storage.
 BOARD_AVB_ROLLBACK_INDEX := 0
 
+# Enable chain partition for system.
+# GSI need to sign on system.img instead of vbmeta.
+BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
+BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
+BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
+BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1
+
 # GSI specific System Properties
 ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
 TARGET_SYSTEM_EXT_PROP := build/make/target/board/gsi_system_ext.prop
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 8f30e6d..8e28b5f 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
 #
@@ -56,7 +56,7 @@
 include build/make/target/board/BoardConfigEmuCommon.mk
 
 TARGET_NO_KERNEL := false
-TARGET_NO_VENDOR_BOOT := true
+TARGET_NO_VENDOR_BOOT := false
 BOARD_USES_RECOVERY_AS_BOOT := true
 
 BOARD_BOOTIMAGE_PARTITION_SIZE := 0x02000000
diff --git a/target/product/aosp_arm64.mk b/target/product/aosp_arm64.mk
index 491397f..3f986d3 100644
--- a/target/product/aosp_arm64.mk
+++ b/target/product/aosp_arm64.mk
@@ -51,8 +51,9 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_product.mk)
 
 #
-# All components inherited here go to vendor image
+# All components inherited here go to vendor or vendor_boot image
 #
+$(call inherit-product-if-exists, device/generic/goldfish/arm64-vendor.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/board/generic_arm64/device.mk)
 
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index d9eb7c3..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 \
diff --git a/target/product/full.mk b/target/product/full.mk
index b356f9d..adb54ab 100644
--- a/target/product/full.mk
+++ b/target/product/full.mk
@@ -19,6 +19,7 @@
 # build quite specifically for the emulator, and might not be
 # entirely appropriate to inherit from for on-device configurations.
 
+$(call inherit-product-if-exists, device/generic/goldfish/arm32-vendor.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/emulator.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/board/generic/device.mk)
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 5184016..84b1252 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -75,6 +75,10 @@
     pm.dexopt.inactive=verify \
     pm.dexopt.shared=speed
 
+# Pass file with the list of updatable boot class path packages to dex2oat.
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
+    dalvik.vm.dex2oat-updatable-bcp-packages-file=/system/etc/updatable-bcp-packages.txt
+
 # Enable resolution of startup const strings.
 PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
     dalvik.vm.dex2oat-resolve-startup-strings=true
diff --git a/target/product/sdk_phone_arm64.mk b/target/product/sdk_phone_arm64.mk
index 9024890..ad72633 100644
--- a/target/product/sdk_phone_arm64.mk
+++ b/target/product/sdk_phone_arm64.mk
@@ -16,7 +16,6 @@
 QEMU_USE_SYSTEM_EXT_PARTITIONS := true
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_arm64.mk)
-$(call inherit-product-if-exists, device/generic/goldfish/arm64-vendor.mk)
 
 # Define the host tools and libs that are parts of the SDK.
 $(call inherit-product, sdk/build/product_sdk.mk)
diff --git a/target/product/userspace_reboot.mk b/target/product/userspace_reboot.mk
index 76ec83d..3f881af 100644
--- a/target/product/userspace_reboot.mk
+++ b/target/product/userspace_reboot.mk
@@ -16,6 +16,4 @@
 
 # Inherit this when the target supports userspace reboot
 
-PRODUCT_PROPERTY_OVERRIDES := ro.init.userspace_reboot.is_supported=true
-
-# TODO(b/135984674): configure userspace reboot related properties
+PRODUCT_PROPERTY_OVERRIDES := init.userspace_reboot.is_supported=true
diff --git a/tools/fs_config/fs_config.c b/tools/fs_config/fs_config.c
index 2952875..2a75add 100644
--- a/tools/fs_config/fs_config.c
+++ b/tools/fs_config/fs_config.c
@@ -26,6 +26,7 @@
 #include <selinux/label.h>
 
 #include "private/android_filesystem_config.h"
+#include "private/fs_config.h"
 
 // This program takes a list of files and directories (indicated by a
 // trailing slash) on the stdin, and prints to stdout each input
diff --git a/tools/fs_get_stats/fs_get_stats.c b/tools/fs_get_stats/fs_get_stats.c
index 159e2aa..64ef0e2 100644
--- a/tools/fs_get_stats/fs_get_stats.c
+++ b/tools/fs_get_stats/fs_get_stats.c
@@ -4,6 +4,7 @@
 #include <unistd.h>
 
 #include <private/android_filesystem_config.h>
+#include <private/fs_config.h>
 
 #define DO_DEBUG 1
 
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index f29ec90..d6f2116 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -238,6 +238,16 @@
             embedded_launcher: false,
         },
     },
+    // TODO (b/140144201) Build imgdiff from releasetools_common
+    required: [
+        "aapt2",
+        "boot_signer",
+        "brotli",
+        "bsdiff",
+        "imgdiff",
+        "minigzip",
+        "mkbootfs",
+    ],
 }
 
 python_binary_host {
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 3276b29..dcf470a 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -77,6 +77,7 @@
     self.boot_signer_args = []
     self.verity_signer_path = None
     self.verity_signer_args = []
+    self.aftl_tool_path = None
     self.aftl_server = None
     self.aftl_key_path = None
     self.aftl_manufacturer_key_path = None
@@ -931,6 +932,39 @@
   return "{}:{}:{}".format(partition, rollback_index_location, pubkey_path)
 
 
+def AddAftlInclusionProof(output_image):
+  """Appends the aftl inclusion proof to the vbmeta image."""
+
+  # Ensure the other AFTL parameters are set as well.
+  assert OPTIONS.aftl_tool_path is not None, 'No aftl tool provided.'
+  assert OPTIONS.aftl_key_path is not None, 'No AFTL key provided.'
+  assert OPTIONS.aftl_manufacturer_key_path is not None, \
+      'No AFTL manufacturer key provided.'
+
+  vbmeta_image = MakeTempFile()
+  os.rename(output_image, vbmeta_image)
+  build_info = BuildInfo(OPTIONS.info_dict)
+  version_incremental = build_info.GetBuildProp("ro.build.version.incremental")
+  aftltool = OPTIONS.aftl_tool_path
+  aftl_cmd = [aftltool, "make_icp_from_vbmeta",
+              "--vbmeta_image_path", vbmeta_image,
+              "--output", output_image,
+              "--version_incremental", version_incremental,
+              "--transparency_log_servers", OPTIONS.aftl_server,
+              "--transparency_log_pub_keys", OPTIONS.aftl_key_path,
+              "--manufacturer_key", OPTIONS.aftl_manufacturer_key_path,
+              "--algorithm", "SHA256_RSA4096",
+              "--padding", "4096"]
+  if OPTIONS.aftl_signer_helper:
+    aftl_cmd.extend(shlex.split(OPTIONS.aftl_signer_helper))
+  RunAndCheckOutput(aftl_cmd)
+
+  verify_cmd = ['aftltool', 'verify_image_icp', '--vbmeta_image_path',
+                output_image, '--transparency_log_pub_keys',
+                OPTIONS.aftl_key_path]
+  RunAndCheckOutput(verify_cmd)
+
+
 def BuildVBMeta(image_path, partitions, name, needed_partitions):
   """Creates a VBMeta image.
 
@@ -973,28 +1007,26 @@
       # zip only). For such cases, we additionally scan other locations (e.g.
       # IMAGES/, RADIO/, etc) before bailing out.
       if arg == '--include_descriptors_from_image':
-        image_path = split_args[index + 1]
-        if os.path.exists(image_path):
+        chained_image = split_args[index + 1]
+        if os.path.exists(chained_image):
           continue
         found = False
         for dir_name in ['IMAGES', 'RADIO', 'PREBUILT_IMAGES']:
           alt_path = os.path.join(
-              OPTIONS.input_tmp, dir_name, os.path.basename(image_path))
+              OPTIONS.input_tmp, dir_name, os.path.basename(chained_image))
           if os.path.exists(alt_path):
             split_args[index + 1] = alt_path
             found = True
             break
-        assert found, 'Failed to find {}'.format(image_path)
+        assert found, 'Failed to find {}'.format(chained_image)
     cmd.extend(split_args)
 
   RunAndCheckOutput(cmd)
 
+  # Generate the AFTL inclusion proof.
   if OPTIONS.aftl_server is not None:
-    # Ensure the other AFTL parameters are set as well.
-    assert OPTIONS.aftl_key_path is not None, 'No AFTL key provided.'
-    assert OPTIONS.aftl_manufacturer_key_path is not None, 'No AFTL manufacturer key provided.'
-    assert OPTIONS.aftl_signer_helper is not None, 'No AFTL signer helper provided.'
-    # AFTL inclusion proof generation code will go here.
+    AddAftlInclusionProof(image_path)
+
 
 def _MakeRamdisk(sourcedir, fs_config_file=None):
   ramdisk_img = tempfile.NamedTemporaryFile()
@@ -1754,7 +1786,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
@@ -1846,9 +1879,9 @@
          "java_path=", "java_args=", "android_jar_path=", "public_key_suffix=",
          "private_key_suffix=", "boot_signer_path=", "boot_signer_args=",
          "verity_signer_path=", "verity_signer_args=", "device_specific=",
-         "extra=", "logfile=", "aftl_server=", "aftl_key_path=",
-         "aftl_manufacturer_key_path=", "aftl_signer_helper="] +
-        list(extra_long_opts))
+         "extra=", "logfile=", "aftl_tool_path=", "aftl_server=",
+         "aftl_key_path=", "aftl_manufacturer_key_path=",
+         "aftl_signer_helper="] + list(extra_long_opts))
   except getopt.GetoptError as err:
     Usage(docstring)
     print("**", str(err), "**")
@@ -1886,6 +1919,8 @@
       OPTIONS.verity_signer_path = a
     elif o in ("--verity_signer_args",):
       OPTIONS.verity_signer_args = shlex.split(a)
+    elif o in ("--aftl_tool_path",):
+      OPTIONS.aftl_tool_path = a
     elif o in ("--aftl_server",):
       OPTIONS.aftl_server = a
     elif o in ("--aftl_key_path",):
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index eb68bc3..d9d3854 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
@@ -94,6 +95,8 @@
 logger = logging.getLogger(__name__)
 
 OPTIONS = common.OPTIONS
+# Always turn on verbose logging.
+OPTIONS.verbose = True
 OPTIONS.framework_target_files = None
 OPTIONS.framework_item_list = None
 OPTIONS.framework_misc_info_keys = None
@@ -109,6 +112,28 @@
 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 will find partition tags on each entry 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"'. We use the group syntax grab the value of
+# the tag. We use non-greedy matching in case there are other fields on the
+# same line.
+
+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 +509,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 +558,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 +572,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 +642,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 +661,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 +693,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 +809,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
 
@@ -1016,9 +1111,6 @@
     common.Usage(__doc__)
     sys.exit(1)
 
-  # Always turn on verbose logging.
-  OPTIONS.verbose = True
-
   if OPTIONS.framework_item_list:
     framework_item_list = common.LoadListFromFile(OPTIONS.framework_item_list)
   else:
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 5b7c2ac..52cd9a8 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>.*?)"'
+        r'(\s+partition="(?P<PARTITION>.*?)")?$',
         line)
     if not matches:
       continue
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index da92163..7058da7 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -710,6 +710,25 @@
       'Compressed4.apk' : 'certs/compressed4',
   }
 
+  # Test parsing with no optional fields, both optional fields, and only the
+  # partition optional field.
+  APKCERTS_TXT4 = (
+      'name="RecoveryLocalizer.apk" certificate="certs/devkey.x509.pem"'
+      ' private_key="certs/devkey.pk8"\n'
+      'name="Settings.apk"'
+      ' certificate="build/make/target/product/security/platform.x509.pem"'
+      ' private_key="build/make/target/product/security/platform.pk8"'
+      ' compressed="gz" partition="system"\n'
+      'name="TV.apk" certificate="PRESIGNED" private_key=""'
+      ' partition="product"\n'
+  )
+
+  APKCERTS_CERTMAP4 = {
+      'RecoveryLocalizer.apk' : 'certs/devkey',
+      'Settings.apk' : 'build/make/target/product/security/platform',
+      'TV.apk' : 'PRESIGNED',
+  }
+
   def setUp(self):
     self.testdata_dir = test_utils.get_testdata_dir()
 
@@ -786,6 +805,14 @@
     with zipfile.ZipFile(target_files, 'r') as input_zip:
       self.assertRaises(ValueError, common.ReadApkCerts, input_zip)
 
+  def test_ReadApkCerts_WithWithoutOptionalFields(self):
+    target_files = self._write_apkcerts_txt(self.APKCERTS_TXT4)
+    with zipfile.ZipFile(target_files, 'r') as input_zip:
+      certmap, ext = common.ReadApkCerts(input_zip)
+
+    self.assertDictEqual(self.APKCERTS_CERTMAP4, certmap)
+    self.assertIsNone(ext)
+
   def test_ExtractPublicKey(self):
     cert = os.path.join(self.testdata_dir, 'testkey.x509.pem')
     pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem')
@@ -1404,6 +1431,47 @@
     self.assertEqual('3', chained_partition_args[1])
     self.assertTrue(os.path.exists(chained_partition_args[2]))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
+  def test_BuildVBMeta_appendAftl(self):
+    testdata_dir = test_utils.get_testdata_dir()
+    common.OPTIONS.info_dict = {
+        'ab_update': 'true',
+        'avb_avbtool': 'avbtool',
+        'build.prop': {
+            'ro.build.version.incremental': '6285659',
+            'ro.product.device': 'coral',
+            'ro.build.fingerprint': 'google/coral/coral:R/RP1A.200311.002/'
+                                    '6285659:userdebug/dev-keys'
+        }
+    }
+    common.OPTIONS.aftl_tool_path = "aftltool"
+    common.OPTIONS.aftl_server = "log.endpoints.aftl-dev.cloud.goog:9000"
+    common.OPTIONS.aftl_key_path = os.path.join(testdata_dir,
+                                                'test_transparency_key.pub')
+    common.OPTIONS.aftl_manufacturer_key_path = os.path.join(
+        testdata_dir, 'test_aftl_rsa4096.pem')
+
+    input_dir = common.MakeTempDir()
+    system_image = common.MakeTempFile()
+    build_image_cmd = ['mkuserimg_mke2fs', input_dir, system_image, 'ext4',
+                       '/system', str(4096 * 100), '-j', '0', '-s']
+    common.RunAndCheckOutput(build_image_cmd)
+
+    add_footer_cmd = ['avbtool', 'add_hashtree_footer',
+                      '--partition_size', str(4096 * 150),
+                      '--partition_name', 'system',
+                      '--image', system_image]
+    common.RunAndCheckOutput(add_footer_cmd)
+
+    vbmeta_image = common.MakeTempFile()
+    common.BuildVBMeta(vbmeta_image, {'system': system_image}, 'vbmeta',
+                       ['system'])
+
+    verify_cmd = ['aftltool', 'verify_image_icp', '--vbmeta_image_path',
+                  vbmeta_image, '--transparency_log_pub_keys',
+                  common.OPTIONS.aftl_key_path]
+    common.RunAndCheckOutput(verify_cmd)
+
 
 class InstallRecoveryScriptFormatTest(test_utils.ReleaseToolsTestCase):
   """Checks the format of install-recovery.sh.
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..308172f 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -35,8 +35,12 @@
   <signer signature="{}"><seinfo value="media"/></signer>
 </policy>"""
 
+  # Note that we test one apex with the partition tag, and another without to
+  # make sure that new OTA tools can process an older target files package that
+  # does not include the partition tag.
+
   # 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"
+  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"
 """
 
@@ -484,7 +488,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"
diff --git a/tools/releasetools/testdata/test_aftl_rsa4096.pem b/tools/releasetools/testdata/test_aftl_rsa4096.pem
new file mode 100644
index 0000000..89f1ef3
--- /dev/null
+++ b/tools/releasetools/testdata/test_aftl_rsa4096.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+vqQgxO2OFsQOJQ/4PRYEKd1neTlZrw==
+-----END PRIVATE KEY-----
diff --git a/tools/releasetools/testdata/test_transparency_key.pub b/tools/releasetools/testdata/test_transparency_key.pub
new file mode 100644
index 0000000..8bfd816
--- /dev/null
+++ b/tools/releasetools/testdata/test_transparency_key.pub
@@ -0,0 +1,15 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4ilqCNsenNA013iCdwgD
+YPxZ853nbHG9lMBp9boXiwRcqT/8bUKHIL7YX5z7s+QoRYVY3rkMKppRabclXzyx
+H59YnPMaU4uv7NqwWzjgaZo7E+vo7IF+KBjV3cJulId5Av0yIYUCsrwd7MpGtWdC
+Q3S+7Vd4zwzCKEhcvliNIhnNlp1U3wNkPCxOyCAsMEn6k8O5ar12ke5TvxDv15db
+rPDeHh8G2OYWoCkWL+lSN35L2kOJqKqVbLKWrrOd96RCYrrtbPCi580OADJRcUlG
+lgcjwmNwmypBWvQMZ6ITj0P0ksHnl1zZz1DE2rXe1goLI1doghb5KxLaezlR8c2C
+E3w/uo9KJgNmNgUVzzqZZ6FE0moyIDNOpP7KtZAL0DvEZj6jqLbB0ccPQElrg52m
+Dv2/A3nYSr0mYBKeskT4+Bg7PGgoC8p7WyLSxMyzJEDYdtrj9OFx6eZaA23oqTQx
+k3Qq5H8RfNBeeSUEeKF7pKH/7gyqZ2bNzBFMA2EBZgBozwRfaeN/HCv3qbaCnwvu
+6caacmAsK+RxiYxSL1QsJqyhCWWGxVyenmxdc1KG/u5ypi7OIioztyzR3t2tAzD3
+Nb+2t8lgHBRxbV24yiPlnvPmB1ZYEctXnlRR9Evpl1o9xA9NnybPHKr9rozN39CZ
+V/USB8K6ao1y5xPZxa8CZksCAwEAAQ==
+-----END PUBLIC KEY-----
+
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index 9809ed4..95ef05f 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -36,6 +36,7 @@
 
 import com.android.apksig.ApkSignerEngine;
 import com.android.apksig.DefaultApkSignerEngine;
+import com.android.apksig.SigningCertificateLineage;
 import com.android.apksig.Hints;
 import com.android.apksig.apk.ApkUtils;
 import com.android.apksig.apk.MinSdkVersionException;
@@ -1042,6 +1043,7 @@
         int alignment = 4;
         Integer minSdkVersionOverride = null;
         boolean signUsingApkSignatureSchemeV2 = true;
+        SigningCertificateLineage certLineage = null;
 
         int argstart = 0;
         while (argstart < args.length && args[argstart].startsWith("-")) {
@@ -1069,6 +1071,15 @@
             } else if ("--disable-v2".equals(args[argstart])) {
                 signUsingApkSignatureSchemeV2 = false;
                 ++argstart;
+            } else if ("--lineage".equals(args[argstart])) {
+                File lineageFile = new File(args[++argstart]);
+                try {
+                    certLineage = SigningCertificateLineage.readFromFile(lineageFile);
+                } catch (Exception e) {
+                    throw new IllegalArgumentException(
+                            "Error reading lineage file: " + e.getMessage());
+                }
+                ++argstart;
             } else {
                 usage();
             }
@@ -1149,6 +1160,7 @@
                                 .setV2SigningEnabled(signUsingApkSignatureSchemeV2)
                                 .setOtherSignersSignaturesPreserved(false)
                                 .setCreatedBy("1.0 (Android SignApk)")
+                                .setSigningCertificateLineage(certLineage)
                                 .build()) {
                     // We don't preserve the input APK's APK Signing Block (which contains v2
                     // signatures)
diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp
index 63fb962..88505b7 100644
--- a/tools/zipalign/ZipFile.cpp
+++ b/tools/zipalign/ZipFile.cpp
@@ -1221,7 +1221,7 @@
     FileReader(FILE* fp) : Reader(), fp_(fp), current_offset_(0) {
     }
 
-    bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const {
+    bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const {
         // Data is usually requested sequentially, so this helps avoid pointless
         // fseeks every time we perform a read. There's an impedence mismatch
         // here because the original API was designed around pread and pwrite.
@@ -1244,7 +1244,7 @@
 
   private:
     FILE* fp_;
-    mutable uint32_t current_offset_;
+    mutable off64_t current_offset_;
 };
 
 // free the memory when you're done