Merge "Build GSIs (aosp_$arch products) in sparse format"
diff --git a/core/Makefile b/core/Makefile
index 0d86992..bd493a6 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -417,10 +417,17 @@
 	$(hide) echo ro.vendor.build.date=`$(DATE_FROM_FILE)`>>$@
 	$(hide) echo ro.vendor.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
 	$(hide) echo ro.vendor.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
+	$(hide) echo ro.vendor.build.security_patch="$(VENDOR_SECURITY_PATCH)">>$@
 	$(hide) echo ro.vendor.product.cpu.abilist="$(TARGET_CPU_ABI_LIST)">>$@
 	$(hide) echo ro.vendor.product.cpu.abilist32="$(TARGET_CPU_ABI_LIST_32_BIT)">>$@
 	$(hide) echo ro.vendor.product.cpu.abilist64="$(TARGET_CPU_ABI_LIST_64_BIT)">>$@
-	$(hide) TARGET_DEVICE="$(TARGET_DEVICE)" \
+	$(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
+			BUILD_ID="$(BUILD_ID)" \
+			BUILD_NUMBER="$(BUILD_NUMBER_FROM_FILE)" \
+			PLATFORM_VERSION="$(PLATFORM_VERSION)" \
+			PLATFORM_SDK_VERSION="$(PLATFORM_SDK_VERSION)" \
+			BUILD_VERSION_TAGS="$(BUILD_VERSION_TAGS)" \
+			TARGET_DEVICE="$(TARGET_DEVICE)" \
 			PRODUCT_NAME="$(TARGET_PRODUCT)" \
 			PRODUCT_BRAND="$(PRODUCT_BRAND)" \
 			PRODUCT_MODEL="$(PRODUCT_MODEL)" \
@@ -443,7 +450,7 @@
 ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_PRODUCT_BUILD_PROP_TARGET)
 
 FINAL_PRODUCT_PROPERTIES += \
-    $(call collapse-pairs, $(PRODUCT_PRODUCT_PROPERTIES))
+    $(call collapse-pairs, $(PRODUCT_PRODUCT_PROPERTIES) $(ADDITIONAL_PRODUCT_PROPERTIES))
 FINAL_PRODUCT_PROPERTIES := $(call uniq-pairs-by-first-component, \
     $(FINAL_PRODUCT_PROPERTIES),=)
 
@@ -480,9 +487,9 @@
 	@mkdir -p $(dir $@)
 	$(hide) echo > $@
 ifdef BOARD_USES_PRODUCT_SERVICESIMAGE
-	$(hide) echo ro.productservices.build.date=`$(DATE_FROM_FILE)`>>$@
-	$(hide) echo ro.productservices.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
-	$(hide) echo ro.productservices.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
+	$(hide) echo ro.product_services.build.date=`$(DATE_FROM_FILE)`>>$@
+	$(hide) echo ro.product_services.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
+	$(hide) echo ro.product_services.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
 endif  # BOARD_USES_PRODUCT_SERVICESIMAGE
 	$(hide) echo "#" >> $@; \
 	        echo "# ADDITIONAL PRODUCT_SERVICES PROPERTIES" >> $@; \
@@ -1162,7 +1169,7 @@
 endif # USE_LOGICAL_PARTITIONS
 
 # $(1): the path of the output dictionary file
-# $(2): a subset of "system vendor cache userdata product productservices oem"
+# $(2): a subset of "system vendor cache userdata product product_services oem"
 # $(3): additional "key=value" pairs to append to the dictionary file.
 define generate-image-prop-dictionary
 $(if $(filter $(2),system),\
@@ -1213,17 +1220,17 @@
     $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH),$(hide) echo "product_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH)" >> $(1))
     $(if $(BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "product_reserved_size=$(BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
 )
-$(if $(filter $(2),productservices),\
-    $(if $(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "productservices_fs_type=$(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
-    $(if $(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_INODE_COUNT),$(hide) echo "productservices_extfs_inode_count=$(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_INODE_COUNT)" >> $(1))
-    $(if $(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_RSV_PCT),$(hide) echo "productservices_extfs_rsv_pct=$(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_RSV_PCT)" >> $(1))
-    $(if $(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE),$(hide) echo "productservices_size=$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE)" >> $(1))
-    $(if $(BOARD_PRODUCT_SERVICESIMAGE_JOURNAL_SIZE),$(hide) echo "productservices_journal_size=$(BOARD_PRODUCT_SERVICESIMAGE_JOURNAL_SIZE)" >> $(1))
-    $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "productservices_squashfs_compressor=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
-    $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "productservices_squashfs_compressor_opt=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
-    $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "productservices_squashfs_block_size=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
-    $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "productservices_squashfs_disable_4k_align=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
-    $(if $(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "productservices_reserved_size=$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
+$(if $(filter $(2),product_services),\
+    $(if $(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "product_services_fs_type=$(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
+    $(if $(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_INODE_COUNT),$(hide) echo "product_services_extfs_inode_count=$(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_INODE_COUNT)" >> $(1))
+    $(if $(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_RSV_PCT),$(hide) echo "product_services_extfs_rsv_pct=$(BOARD_PRODUCT_SERVICESIMAGE_EXTFS_RSV_PCT)" >> $(1))
+    $(if $(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE),$(hide) echo "product_services_size=$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE)" >> $(1))
+    $(if $(BOARD_PRODUCT_SERVICESIMAGE_JOURNAL_SIZE),$(hide) echo "product_services_journal_size=$(BOARD_PRODUCT_SERVICESIMAGE_JOURNAL_SIZE)" >> $(1))
+    $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "product_services_squashfs_compressor=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
+    $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "product_services_squashfs_compressor_opt=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
+    $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "product_services_squashfs_block_size=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
+    $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "product_services_squashfs_disable_4k_align=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
+    $(if $(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "product_services_reserved_size=$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
 )
 $(if $(filter $(2),oem),\
     $(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
@@ -1248,7 +1255,7 @@
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION),$(hide) echo "system_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION),$(hide) echo "vendor_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_VERITY_PARTITION),$(hide) echo "product_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_VERITY_PARTITION)" >> $(1))
-$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_VERITY_PARTITION),$(hide) echo "productservices_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_VERITY_PARTITION)" >> $(1))
+$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_VERITY_PARTITION),$(hide) echo "product_services_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_VERITY_PARTITION)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_key=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_subkey=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY)" >> $(1))
@@ -1278,9 +1285,9 @@
         $(hide) echo "avb_product_rollback_index_location=$(BOARD_AVB_PRODUCT_ROLLBACK_INDEX_LOCATION)" >> $(1)))
 $(if $(BOARD_AVB_ENABLE),\
     $(if $(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH),\
-        $(hide) echo "avb_productservices_key_path=$(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH)" >> $(1)
-        $(hide) echo "avb_productservices_algorithm=$(BOARD_AVB_PRODUCT_SERVICES_ALGORITHM)" >> $(1)
-        $(hide) echo "avb_productservices_rollback_index_location=$(BOARD_AVB_PRODUCT_SERVICES_ROLLBACK_INDEX_LOCATION)" >> $(1)))
+        $(hide) echo "avb_product_services_key_path=$(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH)" >> $(1)
+        $(hide) echo "avb_product_services_algorithm=$(BOARD_AVB_PRODUCT_SERVICES_ALGORITHM)" >> $(1)
+        $(hide) echo "avb_product_services_rollback_index_location=$(BOARD_AVB_PRODUCT_SERVICES_ROLLBACK_INDEX_LOCATION)" >> $(1)))
 $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
     $(hide) echo "recovery_as_boot=true" >> $(1))
 $(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
@@ -1293,7 +1300,7 @@
 # $(1): the path of the output dictionary file
 # $(2): additional "key=value" pairs to append to the dictionary file.
 define generate-userimage-prop-dictionary
-$(call generate-image-prop-dictionary,$(1),system vendor cache userdata product productservices oem,$(2))
+$(call generate-image-prop-dictionary,$(1),system vendor cache userdata product product_services oem,$(2))
 endef
 
 # $(1): the path of the input dictionary file, where each line has the format key=value
@@ -1698,7 +1705,7 @@
 
 # Create symlink /system/product-services to /product-services if necessary.
 ifdef BOARD_USES_PRODUCT_SERVICESIMAGE
-define create-system-productservices-symlink
+define create-system-product-services-symlink
 $(hide) if [ -d $(TARGET_OUT)/product-services ] && [ ! -h $(TARGET_OUT)/product-services ]; then \
   echo 'Non-symlink $(TARGET_OUT)/product-services detected!' 1>&2; \
   echo 'You cannot install files to $(TARGET_OUT)/product-services while building a separate product-services.img!' 1>&2; \
@@ -1707,7 +1714,7 @@
 $(hide) ln -sf /product-services $(TARGET_OUT)/product-services
 endef
 else
-define create-system-productservices-symlink
+define create-system-product-services-symlink
 endef
 endif
 
@@ -1716,7 +1723,7 @@
   @echo "Target system fs image: $(1)"
   $(call create-system-vendor-symlink)
   $(call create-system-product-symlink)
-  $(call create-system-productservices-symlink)
+  $(call create-system-product-services-symlink)
   @mkdir -p $(dir $(1)) $(systemimage_intermediates) && rm -rf $(systemimage_intermediates)/system_image_info.txt
   $(call generate-image-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt,system, \
       skip_fsck=true)
@@ -1796,7 +1803,7 @@
   $(call pretty,"Target system fs tarball: $(INSTALLED_SYSTEMTARBALL_TARGET)")
   $(call create-system-vendor-symlink)
   $(call create-system-product-symlink)
-  $(call create-system-productservices-symlink)
+  $(call create-system-product-services-symlink)
   $(MKTARBALL) $(FS_GET_STATS) \
     $(PRODUCT_OUT) system $(PRIVATE_SYSTEM_TAR) \
     $(INSTALLED_SYSTEMTARBALL_TARGET) $(TARGET_OUT)
@@ -2301,7 +2308,7 @@
 # platform.zip depends on $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES).
 $(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES)
 
-INSTALLED_FILES_FILE_PRODUCT_SERVICES := $(PRODUCT_OUT)/installed-files-productservices.txt
+INSTALLED_FILES_FILE_PRODUCT_SERVICES := $(PRODUCT_OUT)/installed-files-product-services.txt
 INSTALLED_FILES_JSON_PRODUCT_SERVICES := $(INSTALLED_FILES_FILE_PRODUCT_SERVICES:.txt=.json)
 $(INSTALLED_FILES_FILE_PRODUCT_SERVICES): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_PRODUCT_SERVICES)
 $(INSTALLED_FILES_FILE_PRODUCT_SERVICES) : $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES) $(FILESLIST)
@@ -2311,31 +2318,31 @@
 	$(hide) $(FILESLIST) $(TARGET_OUT_PRODUCT_SERVICES) > $(@:.txt=.json)
 	$(hide) build/tools/fileslist_util.py -c $(@:.txt=.json) > $@
 
-productservicesimage_intermediates := \
-    $(call intermediates-dir-for,PACKAGING,productservices)
+product_servicesimage_intermediates := \
+    $(call intermediates-dir-for,PACKAGING,product_services)
 BUILT_PRODUCT_SERVICESIMAGE_TARGET := $(PRODUCT_OUT)/product-services.img
-define build-productservicesimage-target
+define build-product-servicesimage-target
   $(call pretty,"Target product-services fs image: $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)")
   @mkdir -p $(TARGET_OUT_PRODUCT_SERVICES)
-  @mkdir -p $(productservicesimage_intermediates) && rm -rf $(productservicesimage_intermediates)/productservices_image_info.txt
-  $(call generate-userimage-prop-dictionary, $(productservicesimage_intermediates)/productservices_image_info.txt, skip_fsck=true)
+  @mkdir -p $(product_servicesimage_intermediates) && rm -rf $(product_servicesimage_intermediates)/product_services_image_info.txt
+  $(call generate-image-prop-dictionary, $(product_servicesimage_intermediates)/product_services_image_info.txt,product_services, skip_fsck=true)
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       ./build/tools/releasetools/build_image.py \
-      $(TARGET_OUT_PRODUCT_SERVICES) $(productservicesimage_intermediates)/productservices_image_info.txt $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) $(TARGET_OUT) \
-      $(productservicesimage_intermediates)/generated_productservices_image_info.txt
+      $(TARGET_OUT_PRODUCT_SERVICES) $(product_servicesimage_intermediates)/product_services_image_info.txt $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) $(TARGET_OUT) \
+      $(product_servicesimage_intermediates)/generated_product_services_image_info.txt
   $(hide) $(call assert-max-image-size,$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET),\
       $(call read-image-prop-dictionary,\
-          $(productservicesimage_intermediates)/generated_productservices_image_info.txt,productservices_size))
+          $(product_servicesimage_intermediates)/generated_product_services_image_info.txt,product_services_size))
 endef
 
 # We just build this directly to the install location.
 INSTALLED_PRODUCT_SERVICESIMAGE_TARGET := $(BUILT_PRODUCT_SERVICESIMAGE_TARGET)
 $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES) $(INSTALLED_FILES_FILE_PRODUCT_SERVICES) $(BUILD_IMAGE_SRCS)
-	$(build-productservicesimage-target)
+	$(build-product-servicesimage-target)
 
 .PHONY: productservicesimage-nodeps psnod
 productservicesimage-nodeps psnod: | $(INTERNAL_USERIMAGES_DEPS)
-	$(build-productservicesimage-target)
+	$(build-product-servicesimage-target)
 
 sync: $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES)
 
@@ -2557,6 +2564,62 @@
 endif # BOARD_AVB_ENABLE
 
 # -----------------------------------------------------------------
+# super partition image
+
+# (1): list of items like "system", "vendor", "product", "product_services"
+# return: map each item to the corresponding image target.
+# system => $(BUILT_SYSTEMIMAGE), vendor => $(INSTALLED_VENDORIMAGE_TARGET), etc.
+define image-for-partitions
+$(foreach item,$(1),$(or $(strip $(foreach mapping,
+            system:$(BUILT_SYSTEMIMAGE)
+            product_services:$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET),
+        $(if $(filter $(call word-colon,1,$(mapping)),$(item)),
+            $(patsubst $(call word-colon,1,$(mapping)),$(call word-colon,2,$(mapping)),$(item))))),
+    $(INSTALLED_$(call to-upper,$(item)IMAGE_TARGET))))
+endef
+
+# (1): list of items like "system", "vendor", "product", "product_services"
+# return: map each item into a command ( wrapped in $$() ) that reads the size
+define read-size-of-partitions
+$(foreach p,$(1),$(call read-image-prop-dictionary,$($(p)image_intermediates)/generated_$(p)_image_info.txt,$(p)_size))
+endef
+
+ifeq (true,$(USE_LOGICAL_PARTITIONS))
+
+# BOARD_SUPER_PARTITION_SIZE must be defined to build super image.
+ifdef BOARD_SUPER_PARTITION_SIZE
+
+INSTALLED_SUPERIMAGE_TARGET := $(PRODUCT_OUT)/super.img
+$(INSTALLED_SUPERIMAGE_TARGET): $(call image-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
+
+# For A/B devices, super partition always contains sub-partitions in the _a slot, because this
+# image should only be used for bootstrapping / initializing the device. When flashing the image,
+# bootloader fastboot should always mark _a slot as bootable.
+ifeq ($(AB_OTA_UPDATER),true)
+$(INSTALLED_SUPERIMAGE_TARGET): PRIVATE_PARTITION_SUFFIX=_a
+$(INSTALLED_SUPERIMAGE_TARGET): PRIVATE_METADATA_SLOTS=2
+else
+$(INSTALLED_SUPERIMAGE_TARGET): PRIVATE_METADATA_SLOTS=1
+endif # AB_OTA_UPDATER
+
+
+$(INSTALLED_SUPERIMAGE_TARGET): $(HOST_OUT_EXECUTABLES)/lpmake
+	$< \
+		--sparse \
+		--metadata-size 65536 \
+		--metadata-slots $(PRIVATE_METADATA_SLOTS) \
+		--device-size $(BOARD_SUPER_PARTITION_SIZE) \
+		--output $@ \
+		$(foreach name,$(BOARD_SUPER_PARTITION_PARTITION_LIST), \
+			--partition $(name)$(PRIVATE_PARTITION_SUFFIX):$$($(UUIDGEN) $(name)$(PRIVATE_PARTITION_SUFFIX)):readonly:$(call read-size-of-partitions,$(name)) \
+			--image $(name)$(PRIVATE_PARTITION_SUFFIX)=$(call image-for-partitions,$(name)))
+
+$(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_TARGET))
+
+endif # BOARD_SUPER_PARTITION_SIZE
+endif # USE_LOGICAL_PARTITIONS
+
+# -----------------------------------------------------------------
 # Check image sizes <= size of super partition
 
 ifeq (,$(TARGET_BUILD_APPS))
@@ -2570,30 +2633,11 @@
 
 .PHONY: check_android_partition_sizes
 
-# BOARD_SUPER_PARTITION_PARTITION_LIST: a list of the following tokens
-valid_super_partition_list := system vendor product productservices
-ifneq (,$(filter-out $(valid_super_partition_list),$(BOARD_SUPER_PARTITION_PARTITION_LIST)))
-$(error BOARD_SUPER_PARTITION_PARTITION_LIST contains invalid partition name. \
-        Valid names are $(valid_super_partition_list).)
-endif
-valid_super_partition_list :=
-
 # Add image dependencies so that generated_*_image_info.txt are written before checking.
-ifneq (,$(filter system,$(BOARD_SUPER_PARTITION_PARTITION_LIST)))
-check_android_partition_sizes: $(BUILT_SYSTEMIMAGE)
-endif
-ifneq (,$(filter vendor,$(BOARD_SUPER_PARTITION_PARTITION_LIST)))
-check_android_partition_sizes: $(INSTALLED_VENDORIMAGE_TARGET)
-endif
-ifneq (,$(filter product,$(BOARD_SUPER_PARTITION_PARTITION_LIST)))
-check_android_partition_sizes: $(INSTALLED_PRODUCTIMAGE_TARGET)
-endif
-ifneq (,$(filter productservices,$(BOARD_SUPER_PARTITION_PARTITION_LIST)))
-check_android_partition_sizes: $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)
-endif
+check_android_partition_sizes: $(call image-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
 
 check_android_partition_sizes:
-	partition_size_list="$(foreach p,$(BOARD_SUPER_PARTITION_PARTITION_LIST),$(call read-image-prop-dictionary,$($(p)image_intermediates)/generated_$(p)_image_info.txt,$(p)_size))"; \
+	partition_size_list="$(call read-size-of-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))"; \
 	sum_sizes_expr=$$(sed -e 's/ /+/g' <<< "$${partition_size_list}"); \
 	if [ $$(( $${sum_sizes_expr} )) -gt $(BOARD_SUPER_PARTITION_SIZE) ]; then \
 		echo 'The sum of sizes of all logical partitions is larger than BOARD_SUPER_PARTITION_SIZE.'; \
@@ -2878,7 +2922,7 @@
 	@echo "Package target files: $@"
 	$(call create-system-vendor-symlink)
 	$(call create-system-product-symlink)
-	$(call create-system-productservices-symlink)
+	$(call create-system-product-services-symlink)
 	$(hide) rm -rf $@ $@.list $(zip_root)
 	$(hide) mkdir -p $(dir $@) $(zip_root)
 ifneq (,$(INSTALLED_RECOVERYIMAGE_TARGET)$(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)))
@@ -3146,7 +3190,7 @@
 	$(hide) $(call fs_config,$(zip_root)/PRODUCT,product/) > $(zip_root)/META/product_filesystem_config.txt
 endif
 ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
-	$(hide) $(call fs_config,$(zip_root)/PRODUCT_SERVICES,product-services/) > $(zip_root)/META/productservices_filesystem_config.txt
+	$(hide) $(call fs_config,$(zip_root)/PRODUCT_SERVICES,product-services/) > $(zip_root)/META/product_services_filesystem_config.txt
 endif
 ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
 	@# When using BOARD_BUILD_SYSTEM_ROOT_IMAGE, ROOT always contains the files for the root under
@@ -3499,6 +3543,7 @@
 	$(ALL_DEFAULT_INSTALLED_MODULES) \
 	$(INSTALLED_RAMDISK_TARGET) \
 	$(ALL_DOCS) \
+	$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/metalava-api-stubs-docs_annotations.zip \
 	$(ALL_SDK_FILES)
 endif
 
diff --git a/core/android_manifest.mk b/core/android_manifest.mk
index 517379a..13da10c 100644
--- a/core/android_manifest.mk
+++ b/core/android_manifest.mk
@@ -38,28 +38,36 @@
   $(full_android_manifest): PRIVATE_MIN_SDK_VERSION := $(DEFAULT_APP_TARGET_SDK)
 endif
 
-# Set up rules to merge library manifest files
-my_exported_sdk_libs_file := $(call local-intermediates-dir,COMMON)/exported-sdk-libs
-$(full_android_manifest): PRIVATE_EXPORTED_SDK_LIBS_FILE := $(my_exported_sdk_libs_file)
-$(full_android_manifest): $(my_exported_sdk_libs_file)
-$(full_android_manifest): $(MANIFEST_FIXER)
-
 ifneq (,$(strip $(my_full_libs_manifest_files)))
+  # Set up rules to merge library manifest files
+  fixed_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml.fixed
 
-$(full_android_manifest): PRIVATE_LIBS_MANIFESTS := $(my_full_libs_manifest_files)
-$(full_android_manifest): $(ANDROID_MANIFEST_MERGER_DEPS)
-$(full_android_manifest) : $(main_android_manifest) $(my_full_libs_manifest_files)
+  $(full_android_manifest): PRIVATE_LIBS_MANIFESTS := $(my_full_libs_manifest_files)
+  $(full_android_manifest): $(ANDROID_MANIFEST_MERGER_DEPS)
+  $(full_android_manifest) : $(fixed_android_manifest) $(my_full_libs_manifest_files)
 	@echo "Merge android manifest files: $@ <-- $< $(PRIVATE_LIBS_MANIFESTS)"
 	@mkdir -p $(dir $@)
-	$(call fix-manifest,$<,$@.tmp,$(PRIVATE_MIN_SDK_VERSION),$(PRIVATE_EXPORTED_SDK_LIBS_FILE))
-	$(hide) $(ANDROID_MANIFEST_MERGER) --main $@.tmp \
+	$(hide) $(ANDROID_MANIFEST_MERGER) --main $< \
 	    --libs $(call normalize-path-list,$(PRIVATE_LIBS_MANIFESTS)) \
 	    --out $@
-	rm $@.tmp
-
 else
-$(full_android_manifest): $(main_android_manifest)
-	@echo "Fix manifest: $@"
-	$(call fix-manifest,$<,$@,$(PRIVATE_MIN_SDK_VERSION),$(PRIVATE_EXPORTED_SDK_LIBS_FILE))
-
+  fixed_android_manifest := $(full_android_manifest)
 endif
+
+my_exported_sdk_libs_file := $(call local-intermediates-dir,COMMON)/exported-sdk-libs
+$(fixed_android_manifest): PRIVATE_EXPORTED_SDK_LIBS_FILE := $(my_exported_sdk_libs_file)
+$(fixed_android_manifest): $(my_exported_sdk_libs_file)
+
+$(fixed_android_manifest): PRIVATE_MANIFEST_FIXER_FLAGS :=
+ifneq ($(LOCAL_MODULE_CLASS),APPS)
+$(fixed_android_manifest): PRIVATE_MANIFEST_FIXER_FLAGS := --library
+endif
+$(fixed_android_manifest): $(MANIFEST_FIXER)
+$(fixed_android_manifest): $(main_android_manifest)
+	@echo "Fix manifest: $@"
+	$(MANIFEST_FIXER) \
+	  --minSdkVersion $(PRIVATE_MIN_SDK_VERSION) \
+	  $(PRIVATE_MANIFEST_FIXER_FLAGS) \
+	  $(if (PRIVATE_EXPORTED_SDK_LIBS_FILE),\
+	    $$(cat $(PRIVATE_EXPORTED_SDK_LIBS_FILE) | sort -u | sed -e 's/^/\ --uses-library\ /' | tr '\n' ' ')) \
+	  $< $@
diff --git a/core/autogen_test_config.mk b/core/autogen_test_config.mk
index 5feec2b..bf87c9d 100644
--- a/core/autogen_test_config.mk
+++ b/core/autogen_test_config.mk
@@ -29,9 +29,10 @@
 autogen_test_config_template := $(NATIVE_TEST_CONFIG_TEMPLATE)
 endif
 # Auto generating test config file for native test
+$(autogen_test_config_file): PRIVATE_MODULE_NAME := $(LOCAL_MODULE)
 $(autogen_test_config_file) : $(autogen_test_config_template)
 	@echo "Auto generating test config $(notdir $@)"
-	$(hide) sed 's&{MODULE}&$(PRIVATE_MODULE)&g' $< > $@
+	$(hide) sed 's&{MODULE}&$(PRIVATE_MODULE_NAME)&g' $< > $@
 my_auto_generate_config := true
 else
 # Auto generating test config file for instrumentation test
@@ -52,6 +53,7 @@
   LOCAL_INTERMEDIATE_TARGETS += $(autogen_test_config_file)
   $(LOCAL_BUILT_MODULE): $(autogen_test_config_file)
   ALL_MODULES.$(my_register_name).auto_test_config := true
+  $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_autogen := true
 else
   autogen_test_config_file :=
 endif
diff --git a/core/base_rules.mk b/core/base_rules.mk
index b4cb55b..770a16c 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -356,6 +356,7 @@
 ## make clean- targets
 ###########################################################
 cleantarget := clean-$(my_register_name)
+.PHONY: $(cleantarget)
 $(cleantarget) : PRIVATE_MODULE := $(my_register_name)
 $(cleantarget) : PRIVATE_CLEAN_FILES := \
     $(LOCAL_BUILT_MODULE) \
@@ -565,69 +566,74 @@
     $(LOCAL_BUILT_MODULE):$(dir)/$(my_installed_module_stem))) \
   $(eval my_compat_dist_config_$(suite) := ))
 
+
 # Make sure we only add the files once for multilib modules.
-ifndef $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
-$(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files := true
-
-# LOCAL_COMPATIBILITY_SUPPORT_FILES is a list of <src>[:<dest>].
-$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-  $(eval my_compat_dist_$(suite) += $(foreach f, $(LOCAL_COMPATIBILITY_SUPPORT_FILES), \
-    $(eval p := $(subst :,$(space),$(f))) \
-    $(eval s := $(word 1,$(p))) \
-    $(eval n := $(or $(word 2,$(p)),$(notdir $(word 1, $(p))))) \
-    $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
-      $(s):$(dir)/$(n)))))
-
-test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
-ifeq (,$(test_config))
-  ifneq (true,$(is_native))
-    is_instrumentation_test := true
-    ifeq (true, $(LOCAL_IS_HOST_MODULE))
-      is_instrumentation_test := false
-    endif
-    # If LOCAL_MODULE_CLASS is not APPS, it's certainly not an instrumentation
-    # test. However, some packages for test data also have LOCAL_MODULE_CLASS
-    # set to APPS. These will require flag LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG
-    # to disable auto-generating test config file.
-    ifneq (APPS, $(LOCAL_MODULE_CLASS))
-      is_instrumentation_test := false
-    endif
+ifdef $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
+  # Sync the auto_test_config value for multilib modules.
+  ifdef $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_autogen
+    ALL_MODULES.$(my_register_name).auto_test_config := true
   endif
-  # CTS modules can be used for test data, so test config files must be
-  # explicitly created using AndroidTest.xml
-  ifeq (,$(filter cts, $(LOCAL_COMPATIBILITY_SUITE)))
-    ifneq (true, $(LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG))
-      ifeq (true, $(filter true,$(is_native) $(is_instrumentation_test)))
-        include $(BUILD_SYSTEM)/autogen_test_config.mk
-        test_config := $(autogen_test_config_file)
-        autogen_test_config_file :=
+else
+  $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files := true
+  # LOCAL_COMPATIBILITY_SUPPORT_FILES is a list of <src>[:<dest>].
+  $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+    $(eval my_compat_dist_$(suite) += $(foreach f, $(LOCAL_COMPATIBILITY_SUPPORT_FILES), \
+      $(eval p := $(subst :,$(space),$(f))) \
+      $(eval s := $(word 1,$(p))) \
+      $(eval n := $(or $(word 2,$(p)),$(notdir $(word 1, $(p))))) \
+      $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+        $(s):$(dir)/$(n)))))
+
+  test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
+  ifeq (,$(test_config))
+    ifneq (true,$(is_native))
+      is_instrumentation_test := true
+      ifeq (true, $(LOCAL_IS_HOST_MODULE))
+        is_instrumentation_test := false
+      endif
+      # If LOCAL_MODULE_CLASS is not APPS, it's certainly not an instrumentation
+      # test. However, some packages for test data also have LOCAL_MODULE_CLASS
+      # set to APPS. These will require flag LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG
+      # to disable auto-generating test config file.
+      ifneq (APPS, $(LOCAL_MODULE_CLASS))
+        is_instrumentation_test := false
+      endif
+    endif
+    # CTS modules can be used for test data, so test config files must be
+    # explicitly created using AndroidTest.xml
+    ifeq (,$(filter cts, $(LOCAL_COMPATIBILITY_SUITE)))
+      ifneq (true, $(LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG))
+        ifeq (true, $(filter true,$(is_native) $(is_instrumentation_test)))
+          include $(BUILD_SYSTEM)/autogen_test_config.mk
+          test_config := $(autogen_test_config_file)
+          autogen_test_config_file :=
+        endif
       endif
     endif
   endif
-endif
 
-is_instrumentation_test :=
+  is_instrumentation_test :=
 
-ifneq (,$(test_config))
-$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-  $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
-    $(test_config):$(dir)/$(LOCAL_MODULE).config)))
-endif
+  ifneq (,$(test_config))
+    $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+      $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+        $(test_config):$(dir)/$(LOCAL_MODULE).config)))
+  endif
 
-test_config :=
+  test_config :=
 
-ifneq (,$(wildcard $(LOCAL_PATH)/DynamicConfig.xml))
-$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-  $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
-    $(LOCAL_PATH)/DynamicConfig.xml:$(dir)/$(LOCAL_MODULE).dynamic)))
-endif
+  ifneq (,$(wildcard $(LOCAL_PATH)/DynamicConfig.xml))
+    $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+      $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+        $(LOCAL_PATH)/DynamicConfig.xml:$(dir)/$(LOCAL_MODULE).dynamic)))
+  endif
 
-ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config))
-$(foreach extra_config, $(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config), \
-  $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-    $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
-      $(extra_config):$(dir)/$(notdir $(extra_config))))))
-endif
+  ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config))
+  $(foreach extra_config, $(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config), \
+    $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+      $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+        $(extra_config):$(dir)/$(notdir $(extra_config))))))
+  endif
 endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
 
 ifneq ($(my_test_data_file_pairs),)
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 75587bb..e7116a5 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -253,6 +253,7 @@
 LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=
 LOCAL_DROIDDOC_STUBS_SRCJAR :=
 LOCAL_DROIDDOC_DOC_ZIP :=
+LOCAL_DROIDDOC_ANNOTATIONS_ZIP :=
 # '',true
 LOCAL_SOURCE_FILES_ALL_GENERATED:=
 LOCAL_SRC_FILES:=
diff --git a/core/config.mk b/core/config.mk
index 5ebbd9c..0a23ef9 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -701,6 +701,7 @@
 DATA_BINDING_COMPILER := $(HOST_OUT_JAVA_LIBRARIES)/databinding-compiler.jar
 FAT16COPY := build/make/tools/fat16copy.py
 CHECK_LINK_TYPE := build/make/tools/check_link_type.py
+UUIDGEN := build/make/tools/uuidgen.py
 
 PROGUARD := external/proguard/bin/proguard.sh
 JAVATAGS := build/make/tools/java-event-log-tags.py
@@ -719,6 +720,7 @@
 DEXDUMP := $(HOST_OUT_EXECUTABLES)/dexdump2$(BUILD_EXECUTABLE_SUFFIX)
 PROFMAN := $(HOST_OUT_EXECUTABLES)/profman
 HIDDENAPI := $(HOST_OUT_EXECUTABLES)/hiddenapi
+CLASS2GREYLIST := $(HOST_OUT_EXECUTABLES)/class2greylist
 
 FINDBUGS_DIR := external/owasp/sanitizer/tools/findbugs/bin
 FINDBUGS := $(FINDBUGS_DIR)/findbugs
@@ -909,6 +911,20 @@
     PLATFORM_SEPOLICY_VERSION \
     TOT_SEPOLICY_VERSION \
 
+# If true, kernel configuration requirements are present in OTA package (and will be enforced
+# during OTA). Otherwise, kernel configuration requirements are enforced in VTS.
+# Devices that checks the running kernel (instead of the kernel in OTA package) should not
+# set this variable to prevent OTA failures.
+ifndef PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
+  PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS :=
+  ifdef PRODUCT_SHIPPING_API_LEVEL
+    ifeq (true,$(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),29))
+      PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS := true
+    endif
+  endif
+endif
+.KATI_READONLY := PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
+
 ifndef USE_LOGICAL_PARTITIONS
   USE_LOGICAL_PARTITIONS := $(PRODUCT_USE_LOGICAL_PARTITIONS)
 endif
@@ -945,6 +961,17 @@
 endif
 endif
 
+ifdef BOARD_SUPER_PARTITION_PARTITION_LIST
+# BOARD_SUPER_PARTITION_PARTITION_LIST: a list of the following tokens
+valid_super_partition_list := system vendor product product_services
+ifneq (,$(filter-out $(valid_super_partition_list),$(BOARD_SUPER_PARTITION_PARTITION_LIST)))
+$(error BOARD_SUPER_PARTITION_PARTITION_LIST contains invalid partition name \
+		($(filter-out $(valid_super_partition_list),$(BOARD_SUPER_PARTITION_PARTITION_LIST))). \
+        Valid names are $(valid_super_partition_list))
+endif
+valid_super_partition_list :=
+endif # BOARD_SUPER_PARTITION_PARTITION_LIST
+
 endif # USE_LOGICAL_PARTITIONS
 
 # ###############################################################
diff --git a/core/definitions.mk b/core/definitions.mk
index 7108e09..3512598 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -742,18 +742,6 @@
 $(foreach lib,$(1),$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/exported-sdk-libs)
 endef
 
-# Fix manifest
-# $(1): input manifest path
-# $(2): output manifest path
-# $(3): min sdk version
-# $(4): (optional) exported-sdk-libs file
-define fix-manifest
-$(MANIFEST_FIXER) \
---minSdkVersion $(3) \
-$(if $(4),$$(cat $(4) | sort -u | sed -e 's/^/\ --uses-library\ /' | tr '\n' ' ')) \
-$(1) $(2)
-endef
-
 ###########################################################
 ## Returns true if $(1) and $(2) are equal.  Returns
 ## the empty string if they are not equal.
@@ -808,8 +796,8 @@
 
 define collapse-pairs
 $(eval _cpSEP := $(strip $(if $(2),$(2),=)))\
-$(subst $(space)$(_cpSEP)$(space),$(_cpSEP),$(strip \
-    $(subst $(_cpSEP), $(_cpSEP) ,$(1))))
+$(strip $(subst $(space)$(_cpSEP)$(space),$(_cpSEP),$(strip \
+    $(subst $(_cpSEP), $(_cpSEP) ,$(1)))$(space)))
 endef
 
 ###########################################################
@@ -2866,6 +2854,16 @@
     PRIVATE_DEX_INPUTS := $$(PRIVATE_DEX_INPUTS) $(1)
 endef
 
+# Generate a greylist.txt from a classes.jar
+define hiddenapi-generate-greylist-txt
+$(2): $(1) $(CLASS2GREYLIST)
+	$(CLASS2GREYLIST) $(1) > $(2)
+
+$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): $(2)
+$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): \
+    PRIVATE_GREYLIST_INPUTS := $$(PRIVATE_GREYLIST_INPUTS) $(2)
+endef
+
 # File names for intermediate dex files of `hiddenapi-copy-soong-jar`.
 hiddenapi-soong-input-dex = $(dir $(1))/hiddenapi/dex-input/classes.dex
 hiddenapi-soong-output-dex = $(dir $(1))/hiddenapi/dex-output/classes.dex
diff --git a/core/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index 977f852..5a68738 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -100,7 +100,9 @@
 		$(PRIVATE_BOOT_IMAGE_FLAGS) \
 		$(addprefix --dex-file=,$(LIBART_TARGET_BOOT_DEX_FILES)) \
 		$(addprefix --dex-location=,$(LIBART_TARGET_BOOT_DEX_LOCATIONS)) \
+		--generate-debug-info --generate-build-id \
 		--oat-symbols=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED) \
+		--strip \
 		--oat-file=$(patsubst %.art,%.oat,$@) \
 		--oat-location=$(patsubst %.art,%.oat,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_BOOT_IMAGE_FILENAME)) \
 		--image=$@ --base=$(LIBART_IMG_TARGET_BASE_ADDRESS) \
@@ -109,7 +111,6 @@
 		--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
 		--android-root=$(PRODUCT_OUT)/system \
 		--runtime-arg -Xnorelocate --compile-pic \
-		--no-generate-debug-info --generate-build-id \
 		--multi-image --no-inline-from=core-oj.jar \
 		--abort-on-hard-verifier-error \
 		--abort-on-soft-verifier-error \
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index deaee56..5425e31 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -287,6 +287,7 @@
 	$(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_DOCS_DIR) && zip -rqX $$F * )
 
 $(LOCAL_MODULE)-docs.zip : $(out_zip)
+.PHONY: $(LOCAL_MODULE)-docs.zip
 
 $(call dist-for-goals,docs,$(out_zip))
 
diff --git a/core/envsetup.mk b/core/envsetup.mk
index d8469da..c7c3f92 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -218,8 +218,8 @@
 # A device can set up TARGET_COPY_OUT_PRODUCT_SERVICES to "product-services" in its
 # BoardConfig.mk.
 # We'll substitute with the real value after loading BoardConfig.mk.
-_productservices_path_placeholder := ||PRODUCTSERVICES-PATH-PH||
-TARGET_COPY_OUT_PRODUCT_SERVICES := $(_productservices_path_placeholder)
+_product_services_path_placeholder := ||PRODUCT-SERVICES-PATH-PH||
+TARGET_COPY_OUT_PRODUCT_SERVICES := $(_product_services_path_placeholder)
 ###########################################
 
 #################################################################
@@ -355,12 +355,12 @@
 
 ###########################################
 # Now we can substitute with the real value of TARGET_COPY_OUT_PRODUCT_SERVICES
-ifeq ($(TARGET_COPY_OUT_PRODUCT_SERVICES),$(_productservices_path_placeholder))
+ifeq ($(TARGET_COPY_OUT_PRODUCT_SERVICES),$(_product_services_path_placeholder))
 TARGET_COPY_OUT_PRODUCT_SERVICES := system/product-services
 else ifeq ($(filter product-services system/product-services,$(TARGET_COPY_OUT_PRODUCT_SERVICES)),)
 $(error TARGET_COPY_OUT_PRODUCT_SERVICES must be either 'product-services' or 'system/product-services', seeing '$(TARGET_COPY_OUT_PRODUCT_SERVICES)'.)
 endif
-PRODUCT_SERVICES_COPY_FILES := $(subst $(_productservices_path_placeholder),$(TARGET_COPY_OUT_PRODUCT_SERVICES),$(PRODUCT_SERVICES_COPY_FILES))
+PRODUCT_SERVICES_COPY_FILES := $(subst $(_product_services_path_placeholder),$(TARGET_COPY_OUT_PRODUCT_SERVICES),$(PRODUCT_SERVICES_COPY_FILES))
 
 BOARD_USES_PRODUCT_SERVICESIMAGE :=
 ifdef BOARD_PREBUILT_PRODUCT_SERVICESIMAGE
@@ -916,33 +916,33 @@
 
 TARGET_OUT_PRODUCT_SERVICES := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_PRODUCT_SERVICES)
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
-target_out_productservices_shared_libraries_base := $(PRODUCT_SERVICES_OUT)/$(TARGET_COPY_OUT_ASAN)/product-services
+target_out_product_services_shared_libraries_base := $(PRODUCT_SERVICES_OUT)/$(TARGET_COPY_OUT_ASAN)/product-services
 ifeq ($(SANITIZE_LITE),true)
 # When using SANITIZE_LITE, APKs must not be packaged with sanitized libraries, as they will not
 # work with unsanitized app_process. For simplicity, generate APKs into /data/asan/.
-target_out_productservices_app_base := $(PRODUCT_SERVICES_OUT)/$(TARGET_COPY_OUT_ASAN)/product-services
+target_out_product_services_app_base := $(PRODUCT_SERVICES_OUT)/$(TARGET_COPY_OUT_ASAN)/product-services
 else
-target_out_productservices_app_base := $(TARGET_OUT_PRODUCT_SERVICES)
+target_out_product_services_app_base := $(TARGET_OUT_PRODUCT_SERVICES)
 endif
 else
-target_out_productservices_shared_libraries_base := $(TARGET_OUT_PRODUCT_SERVICES)
-target_out_productservices_app_base := $(TARGET_OUT_PRODUCT_SERVICES)
+target_out_product_services_shared_libraries_base := $(TARGET_OUT_PRODUCT_SERVICES)
+target_out_product_services_app_base := $(TARGET_OUT_PRODUCT_SERVICES)
 endif
 
 ifeq ($(TARGET_IS_64_BIT),true)
-TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_productservices_shared_libraries_base)/lib64
+TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_product_services_shared_libraries_base)/lib64
 else
-TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_productservices_shared_libraries_base)/lib
+TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_product_services_shared_libraries_base)/lib
 endif
 TARGET_OUT_PRODUCT_SERVICES_JAVA_LIBRARIES:= $(TARGET_OUT_PRODUCT_SERVICES)/framework
-TARGET_OUT_PRODUCT_SERVICES_APPS := $(target_out_productservices_app_base)/app
-TARGET_OUT_PRODUCT_SERVICES_APPS_PRIVILEGED := $(target_out_productservices_app_base)/priv-app
+TARGET_OUT_PRODUCT_SERVICES_APPS := $(target_out_product_services_app_base)/app
+TARGET_OUT_PRODUCT_SERVICES_APPS_PRIVILEGED := $(target_out_product_services_app_base)/priv-app
 TARGET_OUT_PRODUCT_SERVICES_ETC := $(TARGET_OUT_PRODUCT_SERVICES)/etc
 
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_productservices_shared_libraries_base)/lib/$(TARGET_2ND_ARCH)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_product_services_shared_libraries_base)/lib/$(TARGET_2ND_ARCH)
 else
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_productservices_shared_libraries_base)/lib
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SERVICES_SHARED_LIBRARIES := $(target_out_product_services_shared_libraries_base)/lib
 endif
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SERVICES_APPS := $(TARGET_OUT_PRODUCT_SERVICES_APPS)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SERVICES_APPS_PRIVILEGED := $(TARGET_OUT_PRODUCT_SERVICES_APPS_PRIVILEGED)
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index db24542..2aed61e 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -93,6 +93,7 @@
 
 javac-check : $(full_classes_compiled_jar)
 javac-check-$(LOCAL_MODULE) : $(full_classes_compiled_jar)
+.PHONY: javac-check-$(LOCAL_MODULE)
 
 $(full_classes_combined_jar): $(full_classes_compiled_jar) \
                               $(jar_manifest_file) \
diff --git a/core/java.mk b/core/java.mk
index 78b492d..0d898e7 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -79,6 +79,7 @@
 built_dex_hiddenapi := $(intermediates.COMMON)/dex-hiddenapi/classes.dex
 full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
 java_source_list_file := $(intermediates.COMMON)/java-source-list
+greylist_txt := $(intermediates.COMMON)/greylist.txt
 
 
 ifeq ($(LOCAL_MODULE_CLASS)$(LOCAL_SRC_FILES)$(LOCAL_STATIC_JAVA_LIBRARIES)$(LOCAL_SOURCE_FILES_ALL_GENERATED),APPS)
@@ -308,6 +309,7 @@
 
 javac-check : $(full_classes_compiled_jar)
 javac-check-$(LOCAL_MODULE) : $(full_classes_compiled_jar)
+.PHONY: javac-check-$(LOCAL_MODULE)
 
 $(full_classes_combined_jar): PRIVATE_DONT_DELETE_JAR_META_INF := $(LOCAL_DONT_DELETE_JAR_META_INF)
 $(full_classes_combined_jar): $(full_classes_compiled_jar) \
@@ -457,14 +459,15 @@
     -applymapping $(link_instr_intermediates_dir.COMMON)/proguard_dictionary \
     -verbose \
     $(legacy_proguard_flags)
+legacy_proguard_lib_deps += \
+  $(link_instr_classes_jar) \
+  $(link_instr_intermediates_dir.COMMON)/proguard_options \
+  $(link_instr_intermediates_dir.COMMON)/proguard_dictionary \
 
 # Sometimes (test + main app) uses different keep rules from the main app -
 # apply the main app's dictionary anyway.
 legacy_proguard_flags += -ignorewarnings
 
-# Make sure we run Proguard on the main app first
-$(full_classes_proguard_jar) : $(link_instr_intermediates_dir.COMMON)/proguard.classes.jar
-
 endif # no obfuscation
 endif # LOCAL_INSTRUMENTATION_FOR
 
@@ -544,6 +547,13 @@
 endif
 
 ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),) # is_boot_jar
+  # Derive API greylist from the classes jar.
+  # We use full_classes_proguard_jar here, as that is what is converted to dex
+  # later on. The difference is academic currently, as we don't proguard any
+  # bootclasspath code at the moment. If we were to do that, we should add keep
+  # rules for all members with the @UnsupportedAppUsage annotation.
+  $(eval $(call hiddenapi-generate-greylist-txt,$(full_classes_proguard_jar),$(greylist_txt)))
+  LOCAL_INTERMEDIATE_TARGETS += $(greylist_txt)
   $(eval $(call hiddenapi-copy-dex-files,$(built_dex_intermediate),$(built_dex_hiddenapi)))
   built_dex_copy_from := $(built_dex_hiddenapi)
 else # !is_boot_jar
@@ -576,6 +586,7 @@
 findbugs_html := $(PRODUCT_OUT)/findbugs/$(LOCAL_MODULE).html
 $(findbugs_html) : PRIVATE_XML_FILE := $(findbugs_xml)
 $(LOCAL_MODULE)-findbugs : $(findbugs_html)
+.PHONY: $(LOCAL_MODULE)-findbugs
 $(findbugs_html) : $(findbugs_xml)
 	@mkdir -p $(dir $@)
 	@echo ConvertXmlToText: $@
diff --git a/core/main.mk b/core/main.mk
index 76a1f3f..ae9781b 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -146,6 +146,15 @@
 
 #
 # -----------------------------------------------------------------
+# Validate ADDITIONAL_PRODUCT_PROPERTIES.
+ifneq ($(ADDITIONAL_PRODUCT_PROPERTIES),)
+$(error ADDITIONAL_PRODUCT_PROPERTIES must not be set before here: $(ADDITIONAL_PRODUCT_PROPERTIES))
+endif
+
+ADDITIONAL_PRODUCT_PROPERTIES :=
+
+#
+# -----------------------------------------------------------------
 # Add the product-defined properties to the build properties.
 ifdef PRODUCT_SHIPPING_API_LEVEL
 ADDITIONAL_BUILD_PROPERTIES += \
@@ -231,7 +240,7 @@
 ADDITIONAL_DEFAULT_PROPERTIES += ro.actionable_compatible_property.enabled=${PRODUCT_COMPATIBLE_PROPERTY}
 endif
 
-ADDITIONAL_BUILD_PROPERTIES += ro.boot.logical_partitions=${USE_LOGICAL_PARTITIONS}
+ADDITIONAL_PRODUCT_PROPERTIES += ro.boot.logical_partitions=${USE_LOGICAL_PARTITIONS}
 
 # -----------------------------------------------------------------
 ###
@@ -402,6 +411,8 @@
 .KATI_READONLY := ADDITIONAL_DEFAULT_PROPERTIES
 ADDITIONAL_BUILD_PROPERTIES := $(strip $(ADDITIONAL_BUILD_PROPERTIES))
 .KATI_READONLY := ADDITIONAL_BUILD_PROPERTIES
+ADDITIONAL_PRODUCT_PROPERTIES := $(strip $(ADDITIONAL_PRODUCT_PROPERTIES))
+.KATI_READONLY := ADDITIONAL_PRODUCT_PROPERTIES
 
 ifneq ($(PRODUCT_ENFORCE_RRO_TARGETS),)
 ENFORCE_RRO_SOURCES :=
@@ -977,6 +988,39 @@
 
 ifdef FULL_BUILD
   product_FILES := $(call product-installed-files, $(INTERNAL_PRODUCT))
+
+  # Verify the artifact path requirements made by included products.
+  all_offending_files :=
+  $(foreach makefile,$(ARTIFACT_PATH_REQUIREMENT_PRODUCTS),\
+    $(eval requirements := $(PRODUCTS.$(makefile).ARTIFACT_PATH_REQUIREMENTS)) \
+    $(eval ### Verify that the product only produces files inside its path requirements.) \
+    $(eval whitelist := $(PRODUCTS.$(makefile).ARTIFACT_PATH_WHITELIST)) \
+    $(eval path_patterns := $(call resolve-product-relative-paths,$(requirements),%)) \
+    $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \
+    $(eval files := $(call product-installed-files, $(makefile))) \
+    $(eval files := $(filter-out $(TARGET_OUT_FAKE)/% $(HOST_OUT)/%,$(files))) \
+    $(eval # RROs become REQUIRED by the source module, but are always placed on the vendor partition.) \
+    $(eval files := $(filter-out %__auto_generated_rro.apk,$(files))) \
+    $(eval offending_files := $(filter-out $(path_patterns) $(whitelist_patterns),$(files))) \
+    $(call maybe-print-list-and-error,$(offending_files),$(makefile) produces files outside its artifact path requirement.) \
+    $(eval unused_whitelist := $(filter-out $(files),$(whitelist_patterns))) \
+    $(call maybe-print-list-and-error,$(unused_whitelist),$(makefile) includes redundant whitelist entries in its artifact path requirement.) \
+    $(eval ### Optionally verify that nothing else produces files inside this artifact path requirement.) \
+    $(eval extra_files := $(filter-out $(files) $(HOST_OUT)/%,$(product_FILES))) \
+    $(eval files_in_requirement := $(filter $(path_patterns),$(extra_files))) \
+    $(eval all_offending_files += $(files_in_requirement)) \
+    $(eval whitelist := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST)) \
+    $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \
+    $(eval offending_files := $(filter-out $(whitelist_patterns),$(files_in_requirement))) \
+    $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS),\
+      $(call maybe-print-list-and-error,$(offending_files),$(INTERNAL_PRODUCT) produces files inside $(makefile)s artifact path requirement.) \
+      $(eval unused_whitelist := $(filter-out $(extra_files),$(whitelist_patterns))) \
+      $(call maybe-print-list-and-error,$(unused_whitelist),$(INTERNAL_PRODUCT) includes redundant artifact path requirement whitelist entries.) \
+    ) \
+  )
+$(PRODUCT_OUT)/offending_artifacts.txt:
+	rm -f $@
+	$(foreach f,$(sort $(all_offending_files)),echo $(f) >> $@;)
 else
   # We're not doing a full build, and are probably only including
   # a subset of the module makefiles.  Don't try to build any modules
@@ -985,38 +1029,6 @@
   product_FILES :=
 endif
 
-# Verify the artifact path requirements made by included products.
-$(foreach makefile,$(ARTIFACT_PATH_REQUIREMENT_PRODUCTS),\
-  $(eval requirements := $(PRODUCTS.$(makefile).ARTIFACT_PATH_REQUIREMENTS)) \
-  $(eval ### Verify that the product only produces files inside its path requirements.) \
-  $(eval whitelist := $(PRODUCTS.$(makefile).ARTIFACT_PATH_WHITELIST)) \
-  $(eval path_patterns := $(call resolve-product-relative-paths,$(requirements),%)) \
-  $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \
-  $(eval files := $(call product-installed-files, $(makefile))) \
-  $(eval files := $(filter-out $(TARGET_OUT_FAKE)/% $(HOST_OUT)/%,$(files))) \
-  $(eval # RROs become REQUIRED by the source module, but are always placed on the vendor partition.) \
-  $(eval files := $(filter-out %__auto_generated_rro.apk,$(files))) \
-  $(eval offending_files := $(filter-out $(path_patterns) $(whitelist_patterns),$(files))) \
-  $(call maybe-print-list-and-error,$(offending_files),$(makefile) produces files outside its artifact path requirement.) \
-  $(eval unused_whitelist := $(filter-out $(files),$(whitelist_patterns))) \
-  $(call maybe-print-list-and-error,$(unused_whitelist),$(makefile) includes redundant whitelist entries in its artifact path requirement.) \
-  $(eval ### Optionally verify that nothing else produces files inside this artifact path requirement.) \
-  $(eval extra_files := $(filter-out $(files) $(HOST_OUT)/%,$(product_FILES))) \
-  $(eval files_in_requirement := $(filter $(path_patterns),$(extra_files))) \
-  $(eval all_offending_files += $(files_in_requirement)) \
-  $(eval whitelist := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST)) \
-  $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \
-  $(eval offending_files := $(filter-out $(whitelist_patterns),$(files_in_requirement))) \
-  $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS),\
-    $(call maybe-print-list-and-error,$(offending_files),$(INTERNAL_PRODUCT) produces files inside $(makefile)s artifact path requirement.) \
-    $(eval unused_whitelist := $(filter-out $(extra_files),$(whitelist_patterns))) \
-    $(call maybe-print-list-and-error,$(unused_whitelist),$(INTERNAL_PRODUCT) includes redundant artifact path requirement whitelist entries.) \
-  ) \
-)
-$(PRODUCT_OUT)/offending_artifacts.txt:
-	rm -f $@
-	$(foreach f,$(sort $(all_offending_files)),echo $(f) >> $@;)
-
 ifeq (0,1)
   $(info product_FILES for $(TARGET_DEVICE) ($(INTERNAL_PRODUCT)):)
   $(foreach p,$(product_FILES),$(info :   $(p)))
@@ -1189,6 +1201,9 @@
 .PHONY: systemotherimage
 systemotherimage: $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)
 
+.PHONY: superimage
+superimage: $(INSTALLED_SUPERIMAGE_TARGET)
+
 .PHONY: bootimage
 bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
 
@@ -1361,7 +1376,8 @@
 # umbrella targets to assit engineers in verifying builds
 .PHONY: java native target host java-host java-target native-host native-target \
         java-host-tests java-target-tests native-host-tests native-target-tests \
-        java-tests native-tests host-tests target-tests tests java-dex
+        java-tests native-tests host-tests target-tests tests java-dex \
+        native-host-cross
 # some synonyms
 .PHONY: host-java target-java host-native target-native \
         target-java-tests target-native-tests
diff --git a/core/native_test_config_template.xml b/core/native_test_config_template.xml
index a960529..a88d57c 100644
--- a/core/native_test_config_template.xml
+++ b/core/native_test_config_template.xml
@@ -15,6 +15,8 @@
 -->
 <!-- This test config file is auto-generated. -->
 <configuration description="Runs {MODULE}.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
diff --git a/core/product-graph.mk b/core/product-graph.mk
index 51985df..696aabf 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -145,3 +145,4 @@
 	dot -Tsvg -Nshape=box -o $@ $<
 
 product-graph: $(products_pdf) $(products_svg)
+.PHONY: product-graph
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index ef71107..44b4f5c 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -19,6 +19,7 @@
 full_classes_pre_proguard_jar := $(intermediates.COMMON)/classes-pre-proguard.jar
 full_classes_header_jar := $(intermediates.COMMON)/classes-header.jar
 common_javalib.jar := $(intermediates.COMMON)/javalib.jar
+greylist_txt := $(intermediates.COMMON)/greylist.txt
 
 $(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(full_classes_jar)))
 $(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(full_classes_pre_proguard_jar)))
@@ -33,6 +34,10 @@
 $(call dist-for-goals,docs,$(OUT_DOCS)/$(LOCAL_MODULE)-docs.zip)
 endif
 
+ifdef LOCAL_DROIDDOC_ANNOTATIONS_ZIP
+$(eval $(call copy-one-file,$(LOCAL_DROIDDOC_ANNOTATIONS_ZIP),$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(LOCAL_MODULE)_annotations.zip))
+endif
+
 ifdef LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
   $(eval $(call copy-one-file,$(LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR),\
     $(intermediates.COMMON)/jacoco-report-classes.jar))
@@ -82,6 +87,11 @@
   ifneq ($(LOCAL_UNINSTALLABLE_MODULE),true)
     ifndef LOCAL_IS_HOST_MODULE
       ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),)  # is_boot_jar
+        # Derive greylist from classes.jar.
+        # We use full_classes_jar here, which is the post-proguard jar (on the basis that we also
+        # have a full_classes_pre_proguard_jar). This is consistent with the equivalent code in
+        # java.mk.
+        $(eval $(call hiddenapi-generate-greylist-txt,$(full_classes_jar),$(greylist_txt)))
         $(eval $(call hiddenapi-copy-soong-jar,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
       else # !is_boot_jar
         $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
@@ -131,6 +141,7 @@
 
 javac-check : $(full_classes_jar)
 javac-check-$(LOCAL_MODULE) : $(full_classes_jar)
+.PHONY: javac-check-$(LOCAL_MODULE)
 
 ifndef LOCAL_IS_HOST_MODULE
 ifeq ($(LOCAL_SDK_VERSION),system_current)
diff --git a/core/tasks/tools/compatibility.mk b/core/tasks/tools/compatibility.mk
index 6117414..34ac1d0 100644
--- a/core/tasks/tools/compatibility.mk
+++ b/core/tasks/tools/compatibility.mk
@@ -48,6 +48,7 @@
 $(compatibility_zip): $(test_artifacts) $(test_tools) $(test_suite_prebuilt_tools) $(test_suite_dynamic_config) $(SOONG_ZIP) | $(ADB) $(ACP)
 # Make dir structure
 	$(hide) mkdir -p $(PRIVATE_OUT_DIR)/tools $(PRIVATE_OUT_DIR)/testcases
+	$(hide) echo $(BUILD_NUMBER_FROM_FILE) > $(PRIVATE_OUT_DIR)/tools/version.txt
 # Copy tools
 	$(hide) $(ACP) -fp $(PRIVATE_TOOLS) $(PRIVATE_OUT_DIR)/tools
 	$(if $(PRIVATE_DYNAMIC_CONFIG),$(hide) $(ACP) -fp $(PRIVATE_DYNAMIC_CONFIG) $(PRIVATE_OUT_DIR)/testcases/$(PRIVATE_SUITE_NAME).dynamic)
diff --git a/core/tasks/vndk.mk b/core/tasks/vndk.mk
index 1bde7a6..9420638 100644
--- a/core/tasks/vndk.mk
+++ b/core/tasks/vndk.mk
@@ -23,19 +23,6 @@
 # BOARD_VNDK_RUNTIME_DISABLE must not be set to 'true'.
 ifneq ($(BOARD_VNDK_RUNTIME_DISABLE),true)
 
-# Returns arch-specific libclang_rt.ubsan* library name.
-# Because VNDK_CORE_LIBRARIES includes all arch variants for libclang_rt.ubsan*
-# libs, the arch-specific libs are selected separately.
-#
-# Args:
-#   $(1): if not empty, evaluates for TARGET_2ND_ARCH
-define clang-ubsan-vndk-core
-$(strip \
-  $(eval prefix := $(if $(1),2ND_,)) \
-  $(addsuffix .vendor,$($(addprefix $(prefix),UBSAN_RUNTIME_LIBRARY))) \
-)
-endef
-
 # Returns list of src:dest paths of the intermediate objs
 #
 # Args:
@@ -70,20 +57,7 @@
     $(if $(notice),$(notice):$(subst .vendor,,$(lib)).so.txt)))
 endef
 
-# If in the future libclang_rt.ubsan* is removed from the VNDK-core list,
-# need to update the related logic in this file.
-ifeq (,$(filter libclang_rt.ubsan%,$(VNDK_CORE_LIBRARIES)))
-  $(warning libclang_rt.ubsan* is no longer a VNDK-core library. Please update this file.)
-  vndk_core_libs := $(addsuffix .vendor,$(VNDK_CORE_LIBRARIES))
-else
-  vndk_core_libs := $(addsuffix .vendor,$(filter-out libclang_rt.ubsan%,$(VNDK_CORE_LIBRARIES)))
-
-  vndk_core_libs += $(call clang-ubsan-vndk-core)
-  ifdef TARGET_2ND_ARCH
-    vndk_core_libs += $(call clang-ubsan-vndk-core,true)
-  endif
-endif
-
+vndk_core_libs := $(addsuffix .vendor,$(VNDK_CORE_LIBRARIES))
 vndk_sp_libs := $(addsuffix .vendor,$(VNDK_SAMEPROCESS_LIBRARIES))
 vndk_private_libs := $(addsuffix .vendor,$(VNDK_PRIVATE_LIBRARIES))
 
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 235883a..f7324bd 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -373,22 +373,9 @@
   # Check if chain partition is used.
   key_path = OPTIONS.info_dict.get("avb_" + partition + "_key_path")
   if key_path:
-    # extract public key in AVB format to be included in vbmeta.img
-    avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
-    pubkey_path = common.MakeTempFile(prefix="avb-", suffix=".pubkey")
-    proc = common.Run(
-        [avbtool, "extract_public_key", "--key", key_path, "--output",
-         pubkey_path],
-        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-    stdoutdata, _ = proc.communicate()
-    assert proc.returncode == 0, \
-        "Failed to extract pubkey for {}:\n{}".format(
-            partition, stdoutdata)
-
-    rollback_index_location = OPTIONS.info_dict[
-        "avb_" + partition + "_rollback_index_location"]
-    cmd.extend(["--chain_partition", "%s:%s:%s" % (
-        partition, rollback_index_location, pubkey_path)])
+    chained_partition_arg = common.GetAvbChainedPartitionArg(
+        partition, OPTIONS.info_dict)
+    cmd.extend(["--chain_partition", chained_partition_arg])
   else:
     cmd.extend(["--include_descriptors_from_image", image])
 
@@ -666,11 +653,11 @@
   has_product = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "PRODUCT")) or
                  os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
                                              "product.img")))
-  has_productservices = (os.path.isdir(os.path.join(OPTIONS.input_tmp,
-                                                    "PRODUCTSERVICES")) or
-                         os.path.exists(os.path.join(OPTIONS.input_tmp,
-                                                     "IMAGES",
-                                                     "product-services.img")))
+  has_product_services = (os.path.isdir(os.path.join(OPTIONS.input_tmp,
+                                                     "PRODUCT_SERVICES")) or
+                          os.path.exists(os.path.join(OPTIONS.input_tmp,
+                                                      "IMAGES",
+                                                      "product-services.img")))
   has_system_other = os.path.isdir(os.path.join(OPTIONS.input_tmp,
                                                 "SYSTEM_OTHER"))
 
@@ -747,7 +734,7 @@
     banner("product")
     partitions['product'] = AddProduct(output_zip)
 
-  if has_productservices:
+  if has_product_services:
     banner("product-services")
     partitions['product-services'] = AddProductServices(output_zip)
 
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index fc3eb2c..6eee583 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -425,6 +425,52 @@
   return base_fs_file if exit_code == 0 else None
 
 
+def SetUpInDirAndFsConfig(origin_in, prop_dict):
+  """Returns the in_dir and fs_config that should be used for image building.
+
+  If the target uses system_root_image and it's building system.img, it creates
+  and returns a staged dir that combines the contents of /system (i.e. in the
+  given in_dir) and root.
+
+  Args:
+    origin_in: Path to the input directory.
+    prop_dict: A property dict that contains info like partition size. Values
+        may be updated.
+
+  Returns:
+    A tuple of in_dir and fs_config that should be used to build the image.
+  """
+  fs_config = prop_dict.get("fs_config")
+  if (prop_dict.get("system_root_image") != "true" or
+      prop_dict["mount_point"] != "system"):
+    return origin_in, fs_config
+
+  # Construct a staging directory of the root file system.
+  in_dir = common.MakeTempDir()
+  root_dir = prop_dict.get("root_dir")
+  if root_dir:
+    shutil.rmtree(in_dir)
+    shutil.copytree(root_dir, in_dir, symlinks=True)
+  in_dir_system = os.path.join(in_dir, "system")
+  shutil.rmtree(in_dir_system, ignore_errors=True)
+  shutil.copytree(origin_in, in_dir_system, symlinks=True)
+
+  # Change the mount point to "/".
+  prop_dict["mount_point"] = "/"
+  if fs_config:
+    # We need to merge the fs_config files of system and root.
+    merged_fs_config = common.MakeTempFile(
+        prefix="merged_fs_config", suffix=".txt")
+    with open(merged_fs_config, "w") as fw:
+      if "root_fs_config" in prop_dict:
+        with open(prop_dict["root_fs_config"]) as fr:
+          fw.writelines(fr.readlines())
+      with open(fs_config) as fr:
+        fw.writelines(fr.readlines())
+    fs_config = merged_fs_config
+  return in_dir, fs_config
+
+
 def CheckHeadroom(ext4fs_output, prop_dict):
   """Checks if there's enough headroom space available.
 
@@ -468,40 +514,25 @@
 
 
 def BuildImage(in_dir, prop_dict, out_file, target_out=None):
-  """Build an image to out_file from in_dir with property prop_dict.
-  After the function call, values in prop_dict is updated with
-  computed values.
+  """Builds an image for the files under in_dir and writes it to out_file.
+
+  When using system_root_image, it will additionally look for the files under
+  root (specified by 'root_dir') and builds an image that contains both sources.
 
   Args:
-    in_dir: path of input directory.
-    prop_dict: property dictionary.
-    out_file: path of the output image file.
-    target_out: path of the product out directory to read device specific FS
-        config files.
+    in_dir: Path to input directory.
+    prop_dict: A property dict that contains info like partition size. Values
+        will be updated with computed values.
+    out_file: The output image file.
+    target_out: Path to the TARGET_OUT directory as in Makefile. It actually
+        points to the /system directory under PRODUCT_OUT. fs_config (the one
+        under system/core/libcutils) reads device specific FS config files from
+        there.
 
   Returns:
     True iff the image is built successfully.
   """
-  # system_root_image=true: build a system.img that combines the contents of
-  # /system and root, which should be mounted at the root of the file system.
-  origin_in = in_dir
-  fs_config = prop_dict.get("fs_config")
-  if (prop_dict.get("system_root_image") == "true" and
-      prop_dict["mount_point"] == "system"):
-    in_dir = common.MakeTempDir()
-    # Change the mount point to "/".
-    prop_dict["mount_point"] = "/"
-    if fs_config:
-      # We need to merge the fs_config files of system and root.
-      merged_fs_config = common.MakeTempFile(prefix="merged_fs_config",
-                                             suffix=".txt")
-      with open(merged_fs_config, "w") as fw:
-        if "root_fs_config" in prop_dict:
-          with open(prop_dict["root_fs_config"]) as fr:
-            fw.writelines(fr.readlines())
-        with open(fs_config) as fr:
-          fw.writelines(fr.readlines())
-      fs_config = merged_fs_config
+  in_dir, fs_config = SetUpInDirAndFsConfig(in_dir, prop_dict)
 
   build_command = []
   fs_type = prop_dict.get("fs_type", "")
@@ -518,11 +549,11 @@
   if (prop_dict.get("use_logical_partitions") == "true" and
       "partition_size" not in prop_dict):
     # if partition_size is not defined, use output of `du' + reserved_size
-    success, size = GetDiskUsage(origin_in)
+    success, size = GetDiskUsage(in_dir)
     if not success:
       return False
     if OPTIONS.verbose:
-      print("The tree size of %s is %d MB." % (origin_in, size // BYTES_IN_MB))
+      print("The tree size of %s is %d MB." % (in_dir, size // BYTES_IN_MB))
     size += int(prop_dict.get("partition_reserved_size", 0))
     # Round this up to a multiple of 4K so that avbtool works
     size = common.RoundUpTo4K(size)
@@ -643,31 +674,31 @@
     print("Error: unknown filesystem type '%s'" % (fs_type))
     return False
 
-  if in_dir != origin_in:
-    # Construct a staging directory of the root file system.
-    root_dir = prop_dict.get("root_dir")
-    if root_dir:
-      shutil.rmtree(in_dir)
-      shutil.copytree(root_dir, in_dir, symlinks=True)
-    staging_system = os.path.join(in_dir, "system")
-    shutil.rmtree(staging_system, ignore_errors=True)
-    shutil.copytree(origin_in, staging_system, symlinks=True)
-
   (mkfs_output, exit_code) = RunCommand(build_command)
   if exit_code != 0:
     print("Error: '%s' failed with exit code %d:\n%s" % (
         build_command, exit_code, mkfs_output))
-    success, du = GetDiskUsage(origin_in)
+    success, du = GetDiskUsage(in_dir)
     du_str = ("%d bytes (%d MB)" % (du, du // BYTES_IN_MB)
              ) if success else "unknown"
-    print("Out of space? The tree size of %s is %s." % (
-        origin_in, du_str))
-    print("The max is %d bytes (%d MB)." % (
-        int(prop_dict["partition_size"]),
-        int(prop_dict["partition_size"]) // BYTES_IN_MB))
-    print("Reserved space is %d bytes (%d MB)." % (
-        int(prop_dict.get("partition_reserved_size", 0)),
-        int(prop_dict.get("partition_reserved_size", 0)) // BYTES_IN_MB))
+    print(
+        "Out of space? The tree size of {} is {}, with reserved space of {} "
+        "bytes ({} MB).".format(
+            in_dir, du_str,
+            int(prop_dict.get("partition_reserved_size", 0)),
+            int(prop_dict.get("partition_reserved_size", 0)) // BYTES_IN_MB))
+    if "original_partition_size" in prop_dict:
+      print(
+          "The max size for filsystem files is {} bytes ({} MB), out of a "
+          "total image size of {} bytes ({} MB).".format(
+              int(prop_dict["partition_size"]),
+              int(prop_dict["partition_size"]) // BYTES_IN_MB,
+              int(prop_dict["original_partition_size"]),
+              int(prop_dict["original_partition_size"]) // BYTES_IN_MB))
+    else:
+      print("The max image size is {} bytes ({} MB).".format(
+          int(prop_dict["partition_size"]),
+          int(prop_dict["partition_size"]) // BYTES_IN_MB))
     return False
 
   # Check if there's enough headroom space available for ext4 image.
@@ -877,27 +908,27 @@
       d["extfs_rsv_pct"] = "0"
     copy_prop("product_reserved_size", "partition_reserved_size")
   elif mount_point == "product-services":
-    copy_prop("avb_productservices_hashtree_enable", "avb_hashtree_enable")
-    copy_prop("avb_productservices_add_hashtree_footer_args",
+    copy_prop("avb_product_services_hashtree_enable", "avb_hashtree_enable")
+    copy_prop("avb_product_services_add_hashtree_footer_args",
               "avb_add_hashtree_footer_args")
-    copy_prop("avb_productservices_key_path", "avb_key_path")
-    copy_prop("avb_productservices_algorithm", "avb_algorithm")
-    copy_prop("productservices_fs_type", "fs_type")
-    copy_prop("productservices_size", "partition_size")
-    if not copy_prop("productservices_journal_size", "journal_size"):
+    copy_prop("avb_product_services_key_path", "avb_key_path")
+    copy_prop("avb_product_services_algorithm", "avb_algorithm")
+    copy_prop("product_services_fs_type", "fs_type")
+    copy_prop("product_services_size", "partition_size")
+    if not copy_prop("product_services_journal_size", "journal_size"):
       d["journal_size"] = "0"
-    copy_prop("productservices_verity_block_device", "verity_block_device")
-    copy_prop("productservices_squashfs_compressor", "squashfs_compressor")
-    copy_prop("productservices_squashfs_compressor_opt",
+    copy_prop("product_services_verity_block_device", "verity_block_device")
+    copy_prop("product_services_squashfs_compressor", "squashfs_compressor")
+    copy_prop("product_services_squashfs_compressor_opt",
               "squashfs_compressor_opt")
-    copy_prop("productservices_squashfs_block_size", "squashfs_block_size")
-    copy_prop("productservices_squashfs_disable_4k_align",
+    copy_prop("product_services_squashfs_block_size", "squashfs_block_size")
+    copy_prop("product_services_squashfs_disable_4k_align",
               "squashfs_disable_4k_align")
-    copy_prop("productservices_base_fs_file", "base_fs_file")
-    copy_prop("productservices_extfs_inode_count", "extfs_inode_count")
-    if not copy_prop("productservices_extfs_rsv_pct", "extfs_rsv_pct"):
+    copy_prop("product_services_base_fs_file", "base_fs_file")
+    copy_prop("product_services_extfs_inode_count", "extfs_inode_count")
+    if not copy_prop("product_services_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
-    copy_prop("productservices_reserved_size", "partition_reserved_size")
+    copy_prop("product_services_reserved_size", "partition_reserved_size")
   elif mount_point == "oem":
     copy_prop("fs_type", "fs_type")
     copy_prop("oem_size", "partition_size")
@@ -931,16 +962,22 @@
       d[dest_p] = image_prop[src_p]
       return True
     return False
+
+  if "original_partition_size" in image_prop:
+    size_property = "original_partition_size"
+  else:
+    size_property = "partition_size"
+
   if mount_point == "system":
-    copy_prop("partition_size", "system_size")
+    copy_prop(size_property, "system_size")
   elif mount_point == "system_other":
-    copy_prop("partition_size", "system_size")
+    copy_prop(size_property, "system_size")
   elif mount_point == "vendor":
-    copy_prop("partition_size", "vendor_size")
+    copy_prop(size_property, "vendor_size")
   elif mount_point == "product":
-    copy_prop("partition_size", "product_size")
+    copy_prop(size_property, "product_size")
   elif mount_point == "product-services":
-    copy_prop("partition_size", "productservices_size")
+    copy_prop(size_property, "product_services_size")
   return d
 
 
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 5b5e6ed..c10e57c 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -371,6 +371,40 @@
     cmd.extend(["--salt", avb_salt])
 
 
+def GetAvbChainedPartitionArg(partition, info_dict, key=None):
+  """Constructs and returns the arg to build or verify a chained partition.
+
+  Args:
+    partition: The partition name.
+    info_dict: The info dict to look up the key info and rollback index
+        location.
+    key: The key to be used for building or verifying the partition. Defaults to
+        the key listed in info_dict.
+
+  Returns:
+    A string of form "partition:rollback_index_location:key" that can be used to
+    build or verify vbmeta image.
+
+  Raises:
+    AssertionError: When it fails to extract the public key with avbtool.
+  """
+  if key is None:
+    key = info_dict["avb_" + partition + "_key_path"]
+  avbtool = os.getenv('AVBTOOL') or info_dict["avb_avbtool"]
+  pubkey_path = MakeTempFile(prefix="avb-", suffix=".pubkey")
+  proc = Run(
+      [avbtool, "extract_public_key", "--key", key, "--output", pubkey_path],
+      stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+  stdoutdata, _ = proc.communicate()
+  assert proc.returncode == 0, \
+      "Failed to extract pubkey for {}:\n{}".format(
+          partition, stdoutdata)
+
+  rollback_index_location = info_dict[
+      "avb_" + partition + "_rollback_index_location"]
+  return "{}:{}:{}".format(partition, rollback_index_location, pubkey_path)
+
+
 def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None,
                         has_ramdisk=False, two_step_image=False):
   """Build a bootable image from the specified sourcedir.
diff --git a/tools/releasetools/test_build_image.py b/tools/releasetools/test_build_image.py
index 161faff..19b5e08 100644
--- a/tools/releasetools/test_build_image.py
+++ b/tools/releasetools/test_build_image.py
@@ -14,10 +14,12 @@
 # limitations under the License.
 #
 
+import filecmp
+import os.path
 import unittest
 
 import common
-from build_image import CheckHeadroom, RunCommand
+from build_image import CheckHeadroom, RunCommand, SetUpInDirAndFsConfig
 
 
 class BuildImageTest(unittest.TestCase):
@@ -26,6 +28,9 @@
   EXT4FS_OUTPUT = (
       "Created filesystem with 2777/129024 inodes and 515099/516099 blocks")
 
+  def tearDown(self):
+    common.Cleanup()
+
   def test_CheckHeadroom_SizeUnderLimit(self):
     # Required headroom: 1000 blocks.
     prop_dict = {
@@ -91,4 +96,95 @@
     }
     self.assertFalse(CheckHeadroom(ext4fs_output, prop_dict))
 
-    common.Cleanup()
+  def test_SetUpInDirAndFsConfig_SystemRootImageFalse(self):
+    prop_dict = {
+        'fs_config': 'fs-config',
+        'mount_point': 'system',
+    }
+    in_dir, fs_config = SetUpInDirAndFsConfig('/path/to/in_dir', prop_dict)
+    self.assertEqual('/path/to/in_dir', in_dir)
+    self.assertEqual('fs-config', fs_config)
+    self.assertEqual('system', prop_dict['mount_point'])
+
+  def test_SetUpInDirAndFsConfig_SystemRootImageTrue_NonSystem(self):
+    prop_dict = {
+        'fs_config': 'fs-config',
+        'mount_point': 'vendor',
+        'system_root_image': 'true',
+    }
+    in_dir, fs_config = SetUpInDirAndFsConfig('/path/to/in_dir', prop_dict)
+    self.assertEqual('/path/to/in_dir', in_dir)
+    self.assertEqual('fs-config', fs_config)
+    self.assertEqual('vendor', prop_dict['mount_point'])
+
+  @staticmethod
+  def _gen_fs_config(partition):
+    fs_config = common.MakeTempFile(suffix='.txt')
+    with open(fs_config, 'w') as fs_config_fp:
+      fs_config_fp.write('fs-config-{}\n'.format(partition))
+    return fs_config
+
+  def test_SetUpInDirAndFsConfig_SystemRootImageTrue(self):
+    root_dir = common.MakeTempDir()
+    with open(os.path.join(root_dir, 'init'), 'w') as init_fp:
+      init_fp.write('init')
+
+    origin_in = common.MakeTempDir()
+    with open(os.path.join(origin_in, 'file'), 'w') as in_fp:
+      in_fp.write('system-file')
+    os.symlink('../etc', os.path.join(origin_in, 'symlink'))
+
+    fs_config_system = self._gen_fs_config('system')
+
+    prop_dict = {
+        'fs_config': fs_config_system,
+        'mount_point': 'system',
+        'root_dir': root_dir,
+        'system_root_image': 'true',
+    }
+    in_dir, fs_config = SetUpInDirAndFsConfig(origin_in, prop_dict)
+
+    self.assertTrue(filecmp.cmp(
+        os.path.join(in_dir, 'init'), os.path.join(root_dir, 'init')))
+    self.assertTrue(filecmp.cmp(
+        os.path.join(in_dir, 'system', 'file'),
+        os.path.join(origin_in, 'file')))
+    self.assertTrue(os.path.islink(os.path.join(in_dir, 'system', 'symlink')))
+
+    self.assertTrue(filecmp.cmp(fs_config_system, fs_config))
+    self.assertEqual('/', prop_dict['mount_point'])
+
+  def test_SetUpInDirAndFsConfig_SystemRootImageTrue_WithRootFsConfig(self):
+    root_dir = common.MakeTempDir()
+    with open(os.path.join(root_dir, 'init'), 'w') as init_fp:
+      init_fp.write('init')
+
+    origin_in = common.MakeTempDir()
+    with open(os.path.join(origin_in, 'file'), 'w') as in_fp:
+      in_fp.write('system-file')
+    os.symlink('../etc', os.path.join(origin_in, 'symlink'))
+
+    fs_config_system = self._gen_fs_config('system')
+    fs_config_root = self._gen_fs_config('root')
+
+    prop_dict = {
+        'fs_config': fs_config_system,
+        'mount_point': 'system',
+        'root_dir': root_dir,
+        'root_fs_config': fs_config_root,
+        'system_root_image': 'true',
+    }
+    in_dir, fs_config = SetUpInDirAndFsConfig(origin_in, prop_dict)
+
+    self.assertTrue(filecmp.cmp(
+        os.path.join(in_dir, 'init'), os.path.join(root_dir, 'init')))
+    self.assertTrue(filecmp.cmp(
+        os.path.join(in_dir, 'system', 'file'),
+        os.path.join(origin_in, 'file')))
+    self.assertTrue(os.path.islink(os.path.join(in_dir, 'system', 'symlink')))
+
+    with open(fs_config) as fs_config_fp:
+      fs_config_data = fs_config_fp.readlines()
+    self.assertIn('fs-config-system\n', fs_config_data)
+    self.assertIn('fs-config-root\n', fs_config_data)
+    self.assertEqual('/', prop_dict['mount_point'])
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 1c75d19..2a28db4 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -524,6 +524,9 @@
 
 class CommonUtilsTest(unittest.TestCase):
 
+  def setUp(self):
+    self.testdata_dir = test_utils.get_testdata_dir()
+
   def tearDown(self):
     common.Cleanup()
 
@@ -730,6 +733,56 @@
           AssertionError, common.GetSparseImage, 'system', tempdir, input_zip,
           False)
 
+  def test_GetAvbChainedPartitionArg(self):
+    pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem')
+    info_dict = {
+        'avb_avbtool': 'avbtool',
+        'avb_system_key_path': pubkey,
+        'avb_system_rollback_index_location': 2,
+    }
+    args = common.GetAvbChainedPartitionArg('system', info_dict).split(':')
+    self.assertEqual(3, len(args))
+    self.assertEqual('system', args[0])
+    self.assertEqual('2', args[1])
+    self.assertTrue(os.path.exists(args[2]))
+
+  def test_GetAvbChainedPartitionArg_withPrivateKey(self):
+    key = os.path.join(self.testdata_dir, 'testkey.key')
+    info_dict = {
+        'avb_avbtool': 'avbtool',
+        'avb_product_key_path': key,
+        'avb_product_rollback_index_location': 2,
+    }
+    args = common.GetAvbChainedPartitionArg('product', info_dict).split(':')
+    self.assertEqual(3, len(args))
+    self.assertEqual('product', args[0])
+    self.assertEqual('2', args[1])
+    self.assertTrue(os.path.exists(args[2]))
+
+  def test_GetAvbChainedPartitionArg_withSpecifiedKey(self):
+    info_dict = {
+        'avb_avbtool': 'avbtool',
+        'avb_system_key_path': 'does-not-exist',
+        'avb_system_rollback_index_location': 2,
+    }
+    pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem')
+    args = common.GetAvbChainedPartitionArg(
+        'system', info_dict, pubkey).split(':')
+    self.assertEqual(3, len(args))
+    self.assertEqual('system', args[0])
+    self.assertEqual('2', args[1])
+    self.assertTrue(os.path.exists(args[2]))
+
+  def test_GetAvbChainedPartitionArg_invalidKey(self):
+    pubkey = os.path.join(self.testdata_dir, 'testkey_with_passwd.x509.pem')
+    info_dict = {
+        'avb_avbtool': 'avbtool',
+        'avb_system_key_path': pubkey,
+        'avb_system_rollback_index_location': 2,
+    }
+    self.assertRaises(
+        AssertionError, common.GetAvbChainedPartitionArg, 'system', info_dict)
+
 
 class InstallRecoveryScriptFormatTest(unittest.TestCase):
   """Checks the format of install-recovery.sh.
diff --git a/tools/releasetools/testdata/testkey.key b/tools/releasetools/testdata/testkey.key
new file mode 100644
index 0000000..3a84607
--- /dev/null
+++ b/tools/releasetools/testdata/testkey.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+O/I7YvBaCZA3
+KrvP7ErTh6DS3cAvjLY2GkAA7NWcXIICsVwWMtMZAMO+Rtk/o3XY7r53Amg8ue2e
+b0D5Wc8gUVEeDQdRZJscz5CTwmC/b/YBWQBSPknWv23hf7ZYjR5HMk/XlmOfrylA
+oaZzJyKvLSBu+Zi9cvZlSZObnoOYR8JQJEhjYgYn8JwycV4i1VTQvEqxXkyW3kE7
+RW/8JXgRqI4vDIKehm5SFi2jt0eU7/ju/8f3OGQkLng4DV2QPfwQ+A7kad+EYVI1
+dBGYkNNesWB3o75A7jJQ1fyVg/XQzOKZSki1lrTm3rw0AOrBiXdPudbO+4L2vgip
+kPI9/bVNAgMBAAECggEABGjBSY0Wgw+7rvunlL8mUNbQ7HJFVRTO2FwtZZgXr2MZ
+hFR2DPGqoOa6ortjp6zzO071TS7aGaY5krWDbQQe3+Hinm6w37sUOUu6TyJvOaCv
+tAJLFpzo+zg+pL5gDJdgv0e0QAv1TSszKpNUl1Ct5h+Go+vXFXUHrvtQl4fKBwqA
+efxcd3R4z3p/3Cl2ZYIRz9I7UXUZZYwJE7bDNDz3aFZ1jUoELGmhe1O5w0hJY1q6
+PxuOM9bL60yDn0vu0eiCjaPlHeHyGe9pQ1aQLEuwQz9zpWC01dWPVkLmny7HDygC
+VBsdg8MNlzJQ1WV2en11BH72IqZ59U8pD0xEB7a4BQKBgQDxenfXyYZw4AKcaJlP
+ncJmsx/wcgEvWNxiI4etArXES4VIyP2OlSw+q9JbOOpaSk8TJP5PNfUkgTbC4B2y
+gh/AobJP5b7Wn5LrsHc3GY6CzF1i8T4xXQRxnaKWE86SOmZQlEmyCnpyCmfFVuaR
+E8p8CPW/gQLhpxSlQdGZ0bYLiwKBgQDJrJRDdyaI/Isusog/OwKHVGBU6CmRa5tM
+gx+GIlxheqhuDqnBkr0h1kL20Zi80JeG7vKWr+dwfqkEarfdTe+juwlIuQ3MEuXL
+AbsKNuaU1naOqOLm9rjZgRtR7oNLVH5AbkKMaJz1zM6YiMl54FEDX7ZVY8b6q1Kz
+YXT3sGi9hwKBgBsNa0ujagpPLjuzhCllNRgoTRW0z+kr/VSJQnPhb9eT1lS3H6DP
+mWtT+Hb7w1VmKcGtTUg2dUYnq6jdTrZm2YPNGZrV1DFbIyyAUnq7xDlnB7dD64HA
+N/U6gbJqeaPsIvY4BqGJhvorrEBxYdcy7mZC4rUXkOkSvL9exkqDMe/NAoGARaHU
+v0aQg5PO6pyx9kMFqHw1lptiXtdsk4pihAmxI+cZ6IYfjrp/mwNDs7zCo87RwsEV
++Xlay7iv2tqOCVczerDFj9p1LRUJSoKadfhmvNUfsjoVvfFJ+a9eI3fa1VOjE9P+
+HkSwjR3d50Sza+VLk4Kkje8ZcMtejpkDrdG3GFkCgYBXHqciwlFn5nMPFRe8v426
+6YBiUtzCQCZxDtMeeZYCJslFfjrqPXNUcU/flxWwaikjFsLJEtl7aT3Hpdi5I7T8
+yCYkUWqAAh7twEYTOeG6v/tEa/PmsBjZXPD2zkCp76EQmv3gbvsH4F/nA55gT/GR
+2in6XS/4rHBvjn5gF6MFyg==
+-----END PRIVATE KEY-----
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index 4e40b86..09f800f 100755
--- a/tools/releasetools/validate_target_files.py
+++ b/tools/releasetools/validate_target_files.py
@@ -315,9 +315,19 @@
     key = options['verity_key']
     if key is None:
       key = info_dict['avb_vbmeta_key_path']
+
     # avbtool verifies all the images that have descriptors listed in vbmeta.
     image = os.path.join(input_tmp, 'IMAGES', 'vbmeta.img')
     cmd = ['avbtool', 'verify_image', '--image', image, '--key', key]
+
+    # Append the args for chained partitions if any.
+    for partition in common.AVB_PARTITIONS:
+      key_name = 'avb_' + partition + '_key_path'
+      if info_dict.get(key_name) is not None:
+        chained_partition_arg = common.GetAvbChainedPartitionArg(
+            partition, info_dict, options[key_name])
+        cmd.extend(["--expected_chain_partition", chained_partition_arg])
+
     proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
     stdoutdata, _ = proc.communicate()
     assert proc.returncode == 0, \
@@ -339,8 +349,13 @@
   parser.add_argument(
       '--verity_key',
       help='the verity public key to verify the bootable images (Verified '
-           'Boot 1.0), or the vbmeta image (Verified Boot 2.0), where '
+           'Boot 1.0), or the vbmeta image (Verified Boot 2.0, aka AVB), where '
            'applicable')
+  for partition in common.AVB_PARTITIONS:
+    parser.add_argument(
+        '--avb_' + partition + '_key_path',
+        help='the public or private key in PEM format to verify AVB chained '
+             'partition of {}'.format(partition))
   parser.add_argument(
       '--verity_key_mincrypt',
       help='the verity public key in mincrypt format to verify the system '
diff --git a/tools/uuidgen.py b/tools/uuidgen.py
new file mode 100755
index 0000000..d3091a7
--- /dev/null
+++ b/tools/uuidgen.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import print_function
+import sys
+import uuid
+
+def uuidgen(name):
+    return uuid.uuid5(uuid.uuid5(uuid.NAMESPACE_URL, "android.com"), name)
+
+if __name__ == "__main__":
+    if len(sys.argv) < 2:
+        print("Usage: uuidgen.py <name>")
+        sys.exit(1)
+    name = sys.argv[1]
+    print(uuidgen(name))
diff --git a/tools/vendor_buildinfo.sh b/tools/vendor_buildinfo.sh
index c12f7cb..6590049 100755
--- a/tools/vendor_buildinfo.sh
+++ b/tools/vendor_buildinfo.sh
@@ -3,6 +3,13 @@
 echo "# begin build properties"
 echo "# autogenerated by vendor_buildinfo.sh"
 
+echo "ro.vendor.build.id=$BUILD_ID"
+echo "ro.vendor.build.version.incremental=$BUILD_NUMBER"
+echo "ro.vendor.build.version.sdk=$PLATFORM_SDK_VERSION"
+echo "ro.vendor.build.version.release=$PLATFORM_VERSION"
+echo "ro.vendor.build.type=$TARGET_BUILD_TYPE"
+echo "ro.vendor.build.tags=$BUILD_VERSION_TAGS"
+
 echo "ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"
 echo "ro.board.platform=$TARGET_BOARD_PLATFORM"