Merge "Do not call sort when setting ALL_DEPS.MODULES."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 37c423d..398a006 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -493,6 +493,16 @@
 
 $(call add-clean-step, find $(PRODUCT_OUT) -type f -name "vr_hwc*" -print0 | xargs -0 rm -f)
 
+$(call add-clean-step, rm -rf $(SOONG_OUT_DIR)/.intermediates/system/vold)
+
+# Remove product-services related files / images
+$(call add-clean-step, find $(PRODUCT_OUT) -type f -name "*product-services*" -print0 | xargs -0 rm -rf)
+$(call add-clean-step, find $(PRODUCT_OUT) -type d -name "*product-services*" -print0 | xargs -0 rm -rf)
+$(call add-clean-step, find $(PRODUCT_OUT) -type l -name "*product-services*" -print0 | xargs -0 rm -rf)
+
+# Remove obsolete recovery etc files
+$(call add-clean-step, rm -rf $(TARGET_RECOVERY_ROOT_OUT)/etc)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/OWNERS b/OWNERS
index 1e9b763..b9fee4e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -2,10 +2,7 @@
 dwillemsen@google.com
 nanzhang@google.com
 
-per-file * = ccross@android.com
-per-file * = dwillemsen@google.com
-per-file * = nanzhang@google.com
+per-file * = ccross@android.com,dwillemsen@google.com,nanzhang@google.com
 
 # for version updates
-per-file version_defaults.mk = aseaton@google.com
-per-file version_defaults.mk = elisapascual@google.com
+per-file version_defaults.mk = aseaton@google.com,elisapascual@google.com
diff --git a/core/Makefile b/core/Makefile
index 1bd5127..73e93fc 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -149,6 +149,29 @@
 
 # -----------------------------------------------------------------
 # prop.default
+
+BUILDINFO_SH := build/make/tools/buildinfo.sh
+BUILDINFO_COMMON_SH := build/make/tools/buildinfo_common.sh
+# Generates a set of common build system properties to a file.
+# $(1): Partition name
+# $(2): Output file name
+define generate-common-build-props
+	BUILD_FINGERPRINT="$(BUILD_FINGERPRINT_FROM_FILE)" \
+	BUILD_ID="$(BUILD_ID)" \
+	BUILD_NUMBER="$(BUILD_NUMBER_FROM_FILE)" \
+	BUILD_VERSION_TAGS="$(BUILD_VERSION_TAGS)" \
+	DATE="$(DATE_FROM_FILE)" \
+	PLATFORM_SDK_VERSION="$(PLATFORM_SDK_VERSION)" \
+	PLATFORM_VERSION="$(PLATFORM_VERSION)" \
+	PRODUCT_BRAND="$(PRODUCT_BRAND)" \
+	PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
+	PRODUCT_MODEL="$(PRODUCT_MODEL)" \
+	PRODUCT_NAME="$(TARGET_PRODUCT)" \
+	TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
+	TARGET_DEVICE="$(TARGET_DEVICE)" \
+	bash $(BUILDINFO_COMMON_SH) "$(1)" >> $(2)
+endef
+
 ifdef property_overrides_split_enabled
 INSTALLED_DEFAULT_PROP_TARGET := $(TARGET_OUT)/etc/prop.default
 INSTALLED_DEFAULT_PROP_OLD_TARGET := $(TARGET_ROOT_OUT)/default.prop
@@ -171,7 +194,7 @@
 
 intermediate_system_build_prop := $(call intermediates-dir-for,ETC,system_build_prop)/build.prop
 
-$(INSTALLED_DEFAULT_PROP_TARGET): $(intermediate_system_build_prop)
+$(INSTALLED_DEFAULT_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(intermediate_system_build_prop)
 	@echo Target buildinfo: $@
 	@mkdir -p $(dir $@)
 	@rm -f $@
@@ -183,9 +206,7 @@
 	$(hide) echo "#" >> $@; \
 	        echo "# BOOTIMAGE_BUILD_PROPERTIES" >> $@; \
 	        echo "#" >> $@;
-	$(hide) echo ro.bootimage.build.date=`$(DATE_FROM_FILE)`>>$@
-	$(hide) echo ro.bootimage.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
-	$(hide) echo ro.bootimage.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
+	$(hide) $(call generate-common-build-props,bootimage,$@)
 	$(hide) build/make/tools/post_process_props.py $@
 ifdef property_overrides_split_enabled
 	$(hide) mkdir -p $(TARGET_ROOT_OUT)
@@ -308,9 +329,6 @@
 $(strip $(subst _,-, $(firstword $(1))))
 endef
 
-BUILDINFO_SH := build/make/tools/buildinfo.sh
-DEVICE_BUILDINFO_SH := build/make/tools/device_buildinfo.sh
-
 # TARGET_BUILD_FLAVOR and ro.build.flavor are used only by the test
 # harness to distinguish builds. Only add _asan for a sanitized build
 # if it isn't already a part of the flavor (via a dedicated lunch
@@ -327,7 +345,7 @@
 else
 system_prop_file := $(wildcard $(TARGET_DEVICE_DIR)/system.prop)
 endif
-$(intermediate_system_build_prop): $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file) $(INSTALLED_ANDROID_INFO_TXT_TARGET)
+$(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)
 	@echo Target buildinfo: $@
 	@mkdir -p $(dir $@)
 	$(hide) echo > $@
@@ -338,6 +356,7 @@
 	$(hide) $(foreach prop,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_OEM_PROPERTIES), \
 		echo "import /oem/oem.prop $(prop)" >> $@;)
 endif
+	$(hide) $(call generate-common-build-props,system,$@)
 	$(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
 			TARGET_BUILD_FLAVOR="$(TARGET_BUILD_FLAVOR)" \
 			TARGET_DEVICE="$(TARGET_DEVICE)" \
@@ -419,32 +438,18 @@
     $(FINAL_VENDOR_BUILD_PROPERTIES),=)
 endif  # property_overrides_split_enabled
 
-$(INSTALLED_VENDOR_BUILD_PROP_TARGET): $(DEVICE_BUILDINFO_SH) $(intermediate_system_build_prop)
+$(INSTALLED_VENDOR_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(intermediate_system_build_prop)
 	@echo Target vendor buildinfo: $@
 	@mkdir -p $(dir $@)
 	$(hide) echo > $@
 	$(hide) grep 'ro.product.first_api_level' $(intermediate_system_build_prop) >> $@ || true
-	$(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_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)" \
-			PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
-			TARGET_BOOTLOADER_BOARD_NAME="$(TARGET_BOOTLOADER_BOARD_NAME)" \
-			TARGET_BOARD_PLATFORM="$(TARGET_BOARD_PLATFORM)" \
-	        bash $(DEVICE_BUILDINFO_SH) "vendor" >> $@
+	$(hide) echo ro.product.board="$(TARGET_BOOTLOADER_BOARD_NAME)">>$@
+	$(hide) echo ro.board.platform="$(TARGET_BOARD_PLATFORM)">>$@
+	$(hide) $(call generate-common-build-props,vendor,$@)
 ifdef property_overrides_split_enabled
 	$(hide) echo "#" >> $@; \
 	        echo "# ADDITIONAL VENDOR BUILD PROPERTIES" >> $@; \
@@ -464,14 +469,12 @@
 FINAL_PRODUCT_PROPERTIES := $(call uniq-pairs-by-first-component, \
     $(FINAL_PRODUCT_PROPERTIES),=)
 
-$(INSTALLED_PRODUCT_BUILD_PROP_TARGET):
+$(INSTALLED_PRODUCT_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH)
 	@echo Target product buildinfo: $@
 	@mkdir -p $(dir $@)
 	$(hide) echo > $@
 ifdef BOARD_USES_PRODUCTIMAGE
-	$(hide) echo ro.product.build.date=`$(DATE_FROM_FILE)`>>$@
-	$(hide) echo ro.product.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
-	$(hide) echo ro.product.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
+	$(hide) $(call generate-common-build-props,product,$@)
 endif  # BOARD_USES_PRODUCTIMAGE
 	$(hide) echo "#" >> $@; \
 	        echo "# ADDITIONAL PRODUCT PROPERTIES" >> $@; \
@@ -490,24 +493,14 @@
 FINAL_ODM_BUILD_PROPERTIES := $(call uniq-pairs-by-first-component, \
     $(FINAL_ODM_BUILD_PROPERTIES),=)
 
-$(INSTALLED_ODM_BUILD_PROP_TARGET): $(DEVICE_BUILDINFO_SH)
+$(INSTALLED_ODM_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH)
 	@echo Target odm buildinfo: $@
 	@mkdir -p $(dir $@)
 	$(hide) echo > $@
-	$(hide) echo ro.odm.build.date=`$(DATE_FROM_FILE)`>>$@
-	$(hide) echo ro.odm.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
-	$(hide) echo ro.odm.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
 	$(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)">>$@
-	$(hide) TARGET_DEVICE="$(TARGET_DEVICE)" \
-			PRODUCT_NAME="$(TARGET_PRODUCT)" \
-			PRODUCT_BRAND="$(PRODUCT_BRAND)" \
-			PRODUCT_MODEL="$(PRODUCT_MODEL)" \
-			PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
-			TARGET_BOOTLOADER_BOARD_NAME="$(TARGET_BOOTLOADER_BOARD_NAME)" \
-			TARGET_BOARD_PLATFORM="$(TARGET_BOARD_PLATFORM)" \
-	        bash $(DEVICE_BUILDINFO_SH) "odm" >> $@
+	$(hide) $(call generate-common-build-props,odm,$@)
 	$(hide) echo "#" >> $@; \
 	        echo "# ADDITIONAL ODM BUILD PROPERTIES" >> $@; \
 	        echo "#" >> $@;
@@ -516,7 +509,7 @@
 	$(hide) build/make/tools/post_process_props.py $@
 
 # -----------------------------------------------------------------
-# product-services build.prop
+# product_services build.prop
 INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET := $(TARGET_OUT_PRODUCT_SERVICES)/build.prop
 ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET)
 
@@ -525,14 +518,12 @@
 FINAL_PRODUCT_SERVICES_PROPERTIES := $(call uniq-pairs-by-first-component, \
     $(FINAL_PRODUCT_SERVICES_PROPERTIES),=)
 
-$(INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET):
-	@echo Target product-services buildinfo: $@
+$(INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH)
+	@echo Target product_services buildinfo: $@
 	@mkdir -p $(dir $@)
 	$(hide) echo > $@
 ifdef BOARD_USES_PRODUCT_SERVICESIMAGE
-	$(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)">>$@
+	$(hide) $(call generate-common-build-props,product_services,$@)
 endif  # BOARD_USES_PRODUCT_SERVICESIMAGE
 	$(hide) echo "#" >> $@; \
 	        echo "# ADDITIONAL PRODUCT_SERVICES PROPERTIES" >> $@; \
@@ -754,15 +745,15 @@
 endif
 
 # -----------------------------------------------------------------
-# the ramdisk
-INTERNAL_RAMDISK_FILES := $(filter $(TARGET_ROOT_OUT)/%, \
+# the root dir
+INTERNAL_ROOT_FILES := $(filter $(TARGET_ROOT_OUT)/%, \
 	$(ALL_GENERATED_SOURCES) \
 	$(ALL_DEFAULT_INSTALLED_MODULES))
 
 INSTALLED_FILES_FILE_ROOT := $(PRODUCT_OUT)/installed-files-root.txt
 INSTALLED_FILES_JSON_ROOT := $(INSTALLED_FILES_FILE_ROOT:.txt=.json)
 $(INSTALLED_FILES_FILE_ROOT): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_ROOT)
-$(INSTALLED_FILES_FILE_ROOT) : $(INTERNAL_RAMDISK_FILES) $(FILESLIST)
+$(INSTALLED_FILES_FILE_ROOT) : $(INTERNAL_ROOT_FILES) $(FILESLIST)
 	@echo Installed file list: $@
 	@mkdir -p $(dir $@)
 	@rm -f $@
@@ -771,18 +762,35 @@
 
 $(call dist-for-goals, sdk win_sdk sdk_addon, $(INSTALLED_FILES_FILE_ROOT))
 
+# -----------------------------------------------------------------
+# the ramdisk
+INTERNAL_RAMDISK_FILES := $(filter $(TARGET_RAMDISK_OUT)/%, \
+	$(ALL_GENERATED_SOURCES) \
+	$(ALL_DEFAULT_INSTALLED_MODULES))
+
+INSTALLED_FILES_FILE_RAMDISK := $(PRODUCT_OUT)/installed-files-ramdisk.txt
+INSTALLED_FILES_JSON_RAMDISK := $(INSTALLED_FILES_FILE_RAMDISK:.txt=.json)
+$(INSTALLED_FILES_FILE_RAMDISK): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_RAMDISK)
+$(INSTALLED_FILES_FILE_RAMDISK) : $(INTERNAL_RAMDISK_FILES) $(FILESLIST)
+	@echo Installed file list: $@
+	@mkdir -p $(dir $@)
+	@rm -f $@
+	$(hide) $(FILESLIST) $(TARGET_RAMDISK_OUT) > $(@:.txt=.json)
+	$(hide) build/make/tools/fileslist_util.py -c $(@:.txt=.json) > $@
+
+$(call dist-for-goals, sdk win_sdk sdk_addon, $(INSTALLED_FILES_FILE_RAMDISK))
 BUILT_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk.img
 
 # We just build this directly to the install location.
 INSTALLED_RAMDISK_TARGET := $(BUILT_RAMDISK_TARGET)
-$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) $(INSTALLED_FILES_FILE_ROOT) | $(MINIGZIP)
+$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) $(INSTALLED_FILES_FILE_RAMDISK) | $(MINIGZIP)
 	$(call pretty,"Target ram disk: $@")
-	$(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_ROOT_OUT) | $(MINIGZIP) > $@
+	$(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_RAMDISK_OUT) | $(MINIGZIP) > $@
 
 .PHONY: ramdisk-nodeps
 ramdisk-nodeps: $(MKBOOTFS) | $(MINIGZIP)
 	@echo "make $@: ignoring dependencies"
-	$(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_ROOT_OUT) | $(MINIGZIP) > $(INSTALLED_RAMDISK_TARGET)
+	$(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_RAMDISK_OUT) | $(MINIGZIP) > $(INSTALLED_RAMDISK_TARGET)
 
 INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
 
@@ -958,10 +966,11 @@
 $(2) : $(3)
 $(3) : $(6) $(BUILD_SYSTEM)/Makefile build/make/tools/generate-notice-files.py
 	build/make/tools/generate-notice-files.py --text-output $(2) \
-		$(if $(filter $(1),xml_excluded_vendor_product),-e vendor$(comma)product --xml-output, \
+		$(if $(filter $(1),xml_excluded_extra_partitions),-e vendor$(comma)product$(comma)product_services --xml-output, \
 		  $(if $(filter $(1),xml_vendor),-i vendor --xml-output, \
 		    $(if $(filter $(1),xml_product),-i product --xml-output, \
-		      --html-output))) $(3) \
+		      $(if $(filter $(1),xml_product_services),-i product_services --xml-output, \
+		        --html-output)))) $(3) \
 		-t $$(PRIVATE_MESSAGE) -s $$(PRIVATE_DIR)/src
 notice_files: $(2) $(3)
 endef
@@ -992,6 +1001,11 @@
 target_product_notice_file_xml := $(TARGET_OUT_INTERMEDIATES)/NOTICE_PRODUCT.xml
 target_product_notice_file_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE_PRODUCT.xml.gz
 installed_product_notice_xml_gz := $(TARGET_OUT_PRODUCT)/etc/NOTICE.xml.gz
+
+target_product_services_notice_file_txt := $(TARGET_OUT_INTERMEDIATES)/NOTICE_PRODUCT_SERVICES.txt
+target_product_services_notice_file_xml := $(TARGET_OUT_INTERMEDIATES)/NOTICE_PRODUCT_SERVICES.xml
+target_product_services_notice_file_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE_PRODUCT_SERVICES.xml.gz
+installed_product_services_notice_xml_gz := $(TARGET_OUT_PRODUCT_SERVICES)/etc/NOTICE.xml.gz
 endif
 
 ifndef TARGET_BUILD_APPS
@@ -1000,7 +1014,7 @@
 pdk_fusion_notice_files := $(filter $(TARGET_OUT_NOTICE_FILES)/%, $(ALL_PDK_FUSION_FILES))
 
 ifdef target_vendor_notice_file_xml_gz
-$(eval $(call combine-notice-files, xml_excluded_vendor_product, \
+$(eval $(call combine-notice-files, xml_excluded_extra_partitions, \
 			$(target_notice_file_txt), \
 			$(target_notice_file_html_or_xml), \
 			"Notices for files contained in the filesystem images in this directory:", \
@@ -1020,6 +1034,14 @@
 			$(TARGET_OUT_NOTICE_FILES), \
 			$(target_notice_file_html_or_xml)))
 endif
+ifdef target_product_services_notice_file_txt
+$(eval $(call combine-notice-files, xml_product_services, \
+			$(target_product_services_notice_file_txt), \
+			$(target_product_services_notice_file_xml), \
+			"Notices for files contained in the product_services filesystem image in this directory:", \
+			$(TARGET_OUT_NOTICE_FILES), \
+			$(target_notice_file_html_or_xml)))
+endif
 else
 $(eval $(call combine-notice-files, html, \
 			$(target_notice_file_txt), \
@@ -1063,6 +1085,14 @@
 	$(copy-file-to-target)
 endif
 
+ifdef target_product_services_notice_file_xml_gz
+# Install the product html file at /product_services/etc/NOTICE.xml.gz.
+$(target_product_services_notice_file_xml_gz): $(target_product_services_notice_file_xml) | $(MINIGZIP)
+	$(hide) $(MINIGZIP) -9 < $< > $@
+$(installed_product_services_notice_xml_gz): $(target_product_services_notice_file_xml_gz)
+	$(copy-file-to-target)
+endif
+
 # if we've been run my mm, mmm, etc, don't reinstall this every time
 ifeq ($(ONE_SHOT_MAKEFILE),)
   ALL_DEFAULT_INSTALLED_MODULES += $(installed_notice_html_or_xml_gz)
@@ -1072,6 +1102,9 @@
   ifdef target_product_notice_file_xml_gz
     ALL_DEFAULT_INSTALLED_MODULES += $(installed_product_notice_xml_gz)
   endif
+  ifdef target_product_services_notice_file_xml_gz
+    ALL_DEFAULT_INSTALLED_MODULES += $(installed_product_services_notice_xml_gz)
+  endif
 endif
 endif  # TARGET_BUILD_APPS
 
@@ -1117,8 +1150,10 @@
 	$(hide) mkdir -p $(dir $@)
 	$(hide) openssl x509 -pubkey -noout -in $< > $@
 
-ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_RECOVERY_ROOT_OUT)/etc/update_engine/update-payload-key.pub.pem
-$(TARGET_RECOVERY_ROOT_OUT)/etc/update_engine/update-payload-key.pub.pem: $(TARGET_OUT_ETC)/update_engine/update-payload-key.pub.pem
+ALL_DEFAULT_INSTALLED_MODULES += \
+    $(TARGET_RECOVERY_ROOT_OUT)/system/etc/update_engine/update-payload-key.pub.pem
+$(TARGET_RECOVERY_ROOT_OUT)/system/etc/update_engine/update-payload-key.pub.pem: \
+		$(TARGET_OUT_ETC)/update_engine/update-payload-key.pub.pem
 	$(hide) cp -f $< $@
 endif
 endif
@@ -1353,8 +1388,8 @@
 $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
     $(hide) echo "recovery_as_boot=true" >> $(1))
 $(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
-    $(hide) echo "system_root_image=true" >> $(1)
-    $(hide) echo "root_dir=$(TARGET_ROOT_OUT)" >> $(1))
+    $(hide) echo "system_root_image=true" >> $(1))
+$(hide) echo "root_dir=$(TARGET_ROOT_OUT)" >> $(1)
 $(if $(PRODUCT_USE_DYNAMIC_PARTITION_SIZE),$(hide) echo "use_dynamic_partition_size=true" >> $(1))
 $(if $(3),$(hide) $(foreach kv,$(3),echo "$(kv)" >> $(1);))
 endef
@@ -1605,10 +1640,12 @@
 define build-recoveryimage-target
   # Making recovery image
   $(hide) mkdir -p $(TARGET_RECOVERY_OUT)
-  $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc $(TARGET_RECOVERY_ROOT_OUT)/sdcard $(TARGET_RECOVERY_ROOT_OUT)/tmp
+  $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/sdcard $(TARGET_RECOVERY_ROOT_OUT)/tmp
   # Copying baseline ramdisk...
   # Use rsync because "cp -Rf" fails to overwrite broken symlinks on Mac.
-  $(hide) rsync -a --exclude=etc --exclude=sdcard $(IGNORE_RECOVERY_SEPOLICY) $(IGNORE_CACHE_LINK) $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
+  $(hide) rsync -a --exclude=sdcard $(IGNORE_RECOVERY_SEPOLICY) $(IGNORE_CACHE_LINK) $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
+  $(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),, \
+    $(hide) rsync -a $(TARGET_RAMDISK_OUT)/* $(TARGET_RECOVERY_ROOT_OUT)/)
   # Modifying ramdisk contents...
   $(if $(BOARD_RECOVERY_KERNEL_MODULES), \
     $(call build-image-kernel-modules,$(BOARD_RECOVERY_KERNEL_MODULES),$(TARGET_RECOVERY_ROOT_OUT),,$(call intermediates-dir-for,PACKAGING,depmod_recovery)))
@@ -1623,9 +1660,9 @@
   $(hide) $(foreach item,$(TARGET_PRIVATE_RES_DIRS), \
     cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/$(newline))
   $(hide) $(foreach item,$(recovery_fstab), \
-    cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.fstab)
+    cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/system/etc/recovery.fstab)
   $(if $(strip $(recovery_wipe)), \
-    $(hide) cp -f $(recovery_wipe) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.wipe)
+    $(hide) cp -f $(recovery_wipe) $(TARGET_RECOVERY_ROOT_OUT)/system/etc/recovery.wipe)
   $(hide) cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys
   $(hide) ln -sf prop.default $(TARGET_RECOVERY_ROOT_OUT)/default.prop
   $(BOARD_RECOVERY_IMAGE_PREPARE)
@@ -1660,7 +1697,12 @@
 ifeq (true,$(BOARD_AVB_ENABLE))
 $(INSTALLED_BOOTIMAGE_TARGET) : $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH)
 endif
+ifdef BOARD_INCLUDE_RECOVERY_DTBO
+$(INSTALLED_BOOTIMAGE_TARGET): $(BOARD_PREBUILT_DTBOIMAGE)
+endif
+
 $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
+		$(INTERNAL_ROOT_FILES) \
 		$(INSTALLED_RAMDISK_TARGET) \
 		$(INTERNAL_RECOVERYIMAGE_FILES) \
 		$(recovery_initrc) $(recovery_sepolicy) $(recovery_kernel) \
@@ -1671,11 +1713,16 @@
 		$(RECOVERY_INSTALL_OTA_KEYS) \
 		$(BOARD_RECOVERY_KERNEL_MODULES) \
 		$(DEPMOD)
-		$(call pretty,"Target boot image from recovery: $@")
-		$(call build-recoveryimage-target, $@)
+	$(call pretty,"Target boot image from recovery: $@")
+	$(call build-recoveryimage-target, $@)
+endif # BOARD_USES_RECOVERY_AS_BOOT
+
+ifdef BOARD_INCLUDE_RECOVERY_DTBO
+$(INSTALLED_RECOVERYIMAGE_TARGET): $(BOARD_PREBUILT_DTBOIMAGE)
 endif
 
 $(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
+		$(INTERNAL_ROOT_FILES) \
 		$(INSTALLED_RAMDISK_TARGET) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
 		$(INTERNAL_RECOVERYIMAGE_FILES) \
@@ -1687,7 +1734,7 @@
 		$(RECOVERY_INSTALL_OTA_KEYS) \
 		$(BOARD_RECOVERY_KERNEL_MODULES) \
 		$(DEPMOD)
-		$(call build-recoveryimage-target, $@)
+	$(call build-recoveryimage-target, $@)
 
 ifdef RECOVERY_RESOURCE_ZIP
 $(RECOVERY_RESOURCE_ZIP): $(INSTALLED_RECOVERYIMAGE_TARGET) | $(ZIPTIME)
@@ -1735,17 +1782,13 @@
 
 # ASAN libraries in the system image - add dependency.
 ASAN_IN_SYSTEM_INSTALLED := $(TARGET_OUT)/asan.tar.bz2
-ifneq (,$(SANITIZE_TARGET))
+ifneq (,$(filter address, $(SANITIZE_TARGET)))
   ifeq (true,$(SANITIZE_TARGET_SYSTEM))
     FULL_SYSTEMIMAGE_DEPS += $(ASAN_IN_SYSTEM_INSTALLED)
   endif
 endif
 
-# When building a system root image, also add the ramdisk image as a dependency
-# to ensure all files in it are built before it is created.
-ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
-  FULL_SYSTEMIMAGE_DEPS += $(INTERNAL_RAMDISK_FILES) $(INSTALLED_FILES_FILE_ROOT)
-endif
+FULL_SYSTEMIMAGE_DEPS += $(INTERNAL_ROOT_FILES) $(INSTALLED_FILES_FILE_ROOT)
 
 # -----------------------------------------------------------------
 # Final System VINTF manifest including fragments. This is not assembled
@@ -1821,18 +1864,18 @@
 endef
 endif
 
-# Create symlink /system/product-services to /product-services if necessary.
+# Create symlink /system/product_services to /product_services if necessary.
 ifdef BOARD_USES_PRODUCT_SERVICESIMAGE
-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; \
+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; \
   exit 1; \
 fi
-$(hide) ln -sf /product-services $(TARGET_OUT)/product-services
+$(hide) ln -sf /product_services $(TARGET_OUT)/product_services
 endef
 else
-define create-system-product-services-symlink
+define create-system-product_services-symlink
 endef
 endif
 
@@ -1856,7 +1899,7 @@
   @echo "Target system fs image: $(1)"
   $(call create-system-vendor-symlink)
   $(call create-system-product-symlink)
-  $(call create-system-product-services-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)
@@ -1872,9 +1915,13 @@
 $(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(BUILD_IMAGE_SRCS)
 	$(call build-systemimage-target,$@)
 
-INSTALLED_SYSTEMIMAGE := $(PRODUCT_OUT)/system.img
+INSTALLED_SYSTEMIMAGE_TARGET := $(PRODUCT_OUT)/system.img
 SYSTEMIMAGE_SOURCE_DIR := $(TARGET_OUT)
 
+# INSTALLED_SYSTEMIMAGE_TARGET used to be named INSTALLED_SYSTEMIMAGE. Create an alias for backward
+# compatibility, in case device-specific Makefiles still refer to the old name.
+INSTALLED_SYSTEMIMAGE := $(INSTALLED_SYSTEMIMAGE_TARGET)
+
 # The system partition needs room for the recovery image as well.  We
 # now store the recovery image as a binary patch using the boot image
 # as the source (since they are very similar).  Generate the patch so
@@ -1904,21 +1951,21 @@
 endif # INSTALLED_RECOVERYIMAGE_TARGET
 endif # INSTALLED_BOOTIMAGE_TARGET
 
-$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH)
+$(INSTALLED_SYSTEMIMAGE_TARGET): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH)
 	@echo "Install system fs image: $@"
 	$(copy-file-to-target)
 	$(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),\
 		$(call read-image-prop-dictionary,\
 			$(systemimage_intermediates)/generated_system_image_info.txt,system_size))
 
-systemimage: $(INSTALLED_SYSTEMIMAGE)
+systemimage: $(INSTALLED_SYSTEMIMAGE_TARGET)
 
 .PHONY: systemimage-nodeps snod
 systemimage-nodeps snod: $(filter-out systemimage-nodeps snod,$(MAKECMDGOALS)) \
 	            | $(INTERNAL_USERIMAGES_DEPS)
 	@echo "make $@: ignoring dependencies"
-	$(call build-systemimage-target,$(INSTALLED_SYSTEMIMAGE))
-	$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMIMAGE),\
+	$(call build-systemimage-target,$(INSTALLED_SYSTEMIMAGE_TARGET))
+	$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMIMAGE_TARGET),\
 		$(call read-image-prop-dictionary,\
 			$(systemimage_intermediates)/generated_system_image_info.txt,system_size))
 
@@ -1937,7 +1984,7 @@
   $(call pretty,"Target system fs tarball: $(INSTALLED_SYSTEMTARBALL_TARGET)")
   $(call create-system-vendor-symlink)
   $(call create-system-product-symlink)
-  $(call create-system-product-services-symlink)
+  $(call create-system-product_services-symlink)
   $(MKTARBALL) $(FS_GET_STATS) \
     $(PRODUCT_OUT) system $(PRIVATE_SYSTEM_TAR) \
     $(INSTALLED_SYSTEMTARBALL_TARGET) $(TARGET_OUT)
@@ -2436,7 +2483,7 @@
 endif
 
 # -----------------------------------------------------------------
-# product-services partition image
+# product_services partition image
 ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
 INTERNAL_PRODUCT_SERVICESIMAGE_FILES := \
     $(filter $(TARGET_OUT_PRODUCT_SERVICES)/%,\
@@ -2447,7 +2494,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-product-services.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)
@@ -2459,9 +2506,9 @@
 
 product_servicesimage_intermediates := \
     $(call intermediates-dir-for,PACKAGING,product_services)
-BUILT_PRODUCT_SERVICESIMAGE_TARGET := $(PRODUCT_OUT)/product-services.img
-define build-product-servicesimage-target
-  $(call pretty,"Target product-services fs image: $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)")
+BUILT_PRODUCT_SERVICESIMAGE_TARGET := $(PRODUCT_OUT)/product_services.img
+define build-product_servicesimage-target
+  $(call pretty,"Target product_services fs image: $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)")
   @mkdir -p $(TARGET_OUT_PRODUCT_SERVICES)
   @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)
@@ -2477,16 +2524,16 @@
 # 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-product-servicesimage-target)
+	$(build-product_servicesimage-target)
 
 .PHONY: productservicesimage-nodeps psnod
 productservicesimage-nodeps psnod: | $(INTERNAL_USERIMAGES_DEPS)
-	$(build-product-servicesimage-target)
+	$(build-product_servicesimage-target)
 
 sync: $(INTERNAL_PRODUCT_SERVICESIMAGE_FILES)
 
 else ifdef BOARD_PREBUILT_PRODUCT_SERVICESIMAGE
-INSTALLED_PRODUCT_SERVICESIMAGE_TARGET := $(PRODUCT_OUT)/product-services.img
+INSTALLED_PRODUCT_SERVICESIMAGE_TARGET := $(PRODUCT_OUT)/product_services.img
 $(eval $(call copy-one-file,$(BOARD_PREBUILT_PRODUCT_SERVICESIMAGE),$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)))
 endif
 
@@ -2564,7 +2611,15 @@
 	cp $(BOARD_PREBUILT_DTBOIMAGE) $@
 endif
 
-endif
+endif # BOARD_PREBUILT_DTBOIMAGE
+
+# Returns a list of image targets corresponding to the given list of partitions. For example, it
+# returns "$(INSTALLED_PRODUCTIMAGE_TARGET)" for "product", or "$(INSTALLED_SYSTEMIMAGE_TARGET)
+# $(INSTALLED_VENDORIMAGE_TARGET)" for "system vendor".
+# (1): list of partitions like "system", "vendor" or "system product product_services".
+define images-for-partitions
+$(strip $(foreach item,$(1),$(INSTALLED_$(call to-upper,$(item))IMAGE_TARGET)))
+endef
 
 # -----------------------------------------------------------------
 # vbmeta image
@@ -2581,8 +2636,9 @@
 BOARD_AVB_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
 endif
 
-INTERNAL_AVB_SIGNING_ARGS := \
-    --algorithm $(BOARD_AVB_ALGORITHM) --key $(BOARD_AVB_KEY_PATH)
+ifndef BOARD_BOOTIMAGE_PARTITION_SIZE
+$(error BOARD_BOOTIMAGE_PARTITION_SIZE must be set for BOARD_AVB_ENABLE)
+endif
 
 BOOT_FOOTER_ARGS := BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS
 DTBO_FOOTER_ARGS := BOARD_AVB_DTBO_ADD_HASH_FOOTER_ARGS
@@ -2593,11 +2649,11 @@
 PRODUCT_SERVICES_FOOTER_ARGS := BOARD_AVB_PRODUCT_SERVICES_ADD_HASHTREE_FOOTER_ARGS
 ODM_FOOTER_ARGS := BOARD_AVB_ODM_ADD_HASHTREE_FOOTER_ARGS
 
-# Check and set required build variables for a chain partition.
-# $(1): the partition to enable AVB chain, e.g., BOOT or SYSTEM.
-define check-and-set-avb-chain-args
-$(eval PART := $(1))
-$(eval part=$(call to-lower,$(PART)))
+# Helper function that checks and sets required build variables for an AVB chained partition.
+# $(1): the partition to enable AVB chain, e.g., boot or system.
+define _check-and-set-avb-chain-args
+$(eval part := $(1))
+$(eval PART=$(call to-upper,$(part)))
 
 $(eval _key_path := BOARD_AVB_$(PART)_KEY_PATH)
 $(eval _signing_algorithm := BOARD_AVB_$(PART)_ALGORITHM)
@@ -2621,68 +2677,46 @@
 $(eval $($(_footer_args)) += --rollback_index $($(_rollback_index)))
 endef
 
+# Checks and sets the required build variables for an AVB partition. The partition will be
+# configured as a chained partition, if BOARD_AVB_<partition>_KEY_PATH is defined. Otherwise the
+# image descriptor will be included into vbmeta.img.
+# $(1): Partition name, e.g. boot or system.
+define check-and-set-avb-args
+$(if $(BOARD_AVB_$(call to-upper,$(1))_KEY_PATH),\
+    $(call _check-and-set-avb-chain-args,$(1)),\
+    $(eval INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
+        --include_descriptors_from_image $(call images-for-partitions,$(1))))
+endef
+
 ifdef INSTALLED_BOOTIMAGE_TARGET
-ifdef BOARD_AVB_BOOT_KEY_PATH
-$(eval $(call check-and-set-avb-chain-args,BOOT))
-else
-INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
-    --include_descriptors_from_image $(INSTALLED_BOOTIMAGE_TARGET)
-endif
+$(eval $(call check-and-set-avb-args,boot))
 endif
 
-ifdef BOARD_AVB_SYSTEM_KEY_PATH
-$(eval $(call check-and-set-avb-chain-args,SYSTEM))
-else
-INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
-    --include_descriptors_from_image $(INSTALLED_SYSTEMIMAGE)
-endif
+$(eval $(call check-and-set-avb-args,system))
 
 ifdef INSTALLED_VENDORIMAGE_TARGET
-ifdef BOARD_AVB_VENDOR_KEY_PATH
-$(eval $(call check-and-set-avb-chain-args,VENDOR))
-else
-INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
-    --include_descriptors_from_image $(INSTALLED_VENDORIMAGE_TARGET)
-endif
+$(eval $(call check-and-set-avb-args,vendor))
 endif
 
 ifdef INSTALLED_PRODUCTIMAGE_TARGET
-ifdef BOARD_AVB_PRODUCT_KEY_PATH
-$(eval $(call check-and-set-avb-chain-args,PRODUCT))
-else
-INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
-    --include_descriptors_from_image $(INSTALLED_PRODUCTIMAGE_TARGET)
+$(eval $(call check-and-set-avb-args,product))
 endif
+
+ifdef INSTALLED_PRODUCT_SERVICESIMAGE_TARGET
+$(eval $(call check-and-set-avb-args,product_services))
 endif
 
 ifdef INSTALLED_ODMIMAGE_TARGET
-ifdef BOARD_AVB_ODM_KEY_PATH
-$(eval $(call check-and-set-avb-chain-args,ODM))
-else
-INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
-    --include_descriptors_from_image $(INSTALLED_ODMIMAGE_TARGET)
-endif
+$(eval $(call check-and-set-avb-args,odm))
 endif
 
 ifdef INSTALLED_DTBOIMAGE_TARGET
-ifdef BOARD_AVB_DTBO_KEY_PATH
-$(eval $(call check-and-set-avb-chain-args,DTBO))
-else
-INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
-    --include_descriptors_from_image $(INSTALLED_DTBOIMAGE_TARGET)
-endif
+$(eval $(call check-and-set-avb-args,dtbo))
 endif
 
 ifdef INSTALLED_RECOVERYIMAGE_TARGET
-ifdef BOARD_AVB_RECOVERY_KEY_PATH
-$(eval $(call check-and-set-avb-chain-args,RECOVERY))
-else
-INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
-    --include_descriptors_from_image $(INSTALLED_RECOVERYIMAGE_TARGET)
+$(eval $(call check-and-set-avb-args,recovery))
 endif
-endif
-
-BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --padding_size 4096
 
 # Add kernel cmdline descriptor for kernel to mount system.img as root with
 # dm-verity. This works when system.img is either chained or not-chained:
@@ -2694,6 +2728,8 @@
 BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS += --setup_as_rootfs_from_kernel
 endif
 
+BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --padding_size 4096
+
 ifdef BOARD_AVB_ROLLBACK_INDEX
 BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --rollback_index $(BOARD_AVB_ROLLBACK_INDEX)
 endif
@@ -2702,10 +2738,6 @@
 BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --set_hashtree_disabled_flag
 endif
 
-ifndef BOARD_BOOTIMAGE_PARTITION_SIZE
-  $(error BOARD_BOOTIMAGE_PARTITION_SIZE must be set for BOARD_AVB_ENABLE)
-endif
-
 # $(1): the directory to extract public keys to
 define extract-avb-chain-public-keys
   $(if $(BOARD_AVB_BOOT_KEY_PATH),\
@@ -2722,7 +2754,7 @@
       --output $(1)/product.avbpubkey)
   $(if $(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH),\
     $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH) \
-      --output $(1)/product-services.avbpubkey)
+      --output $(1)/product_services.avbpubkey)
   $(if $(BOARD_AVB_ODM_KEY_PATH),\
     $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_ODM_KEY_PATH) \
       --output $(1)/odm.avbpubkey)
@@ -2740,17 +2772,20 @@
   $(call extract-avb-chain-public-keys, $(AVB_CHAIN_KEY_DIR))
   $(hide) $(AVBTOOL) make_vbmeta_image \
     $(INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS) \
-    $(INTERNAL_AVB_SIGNING_ARGS) \
+    $(PRIVATE_AVB_VBMETA_SIGNING_ARGS) \
     $(BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS) \
     --output $@
   $(hide) rm -rf $(AVB_CHAIN_KEY_DIR)
 endef
 
 INSTALLED_VBMETAIMAGE_TARGET := $(BUILT_VBMETAIMAGE_TARGET)
+$(INSTALLED_VBMETAIMAGE_TARGET): PRIVATE_AVB_VBMETA_SIGNING_ARGS := \
+    --algorithm $(BOARD_AVB_ALGORITHM) --key $(BOARD_AVB_KEY_PATH)
+
 $(INSTALLED_VBMETAIMAGE_TARGET): \
 		$(AVBTOOL) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
-		$(INSTALLED_SYSTEMIMAGE) \
+		$(INSTALLED_SYSTEMIMAGE_TARGET) \
 		$(INSTALLED_VENDORIMAGE_TARGET) \
 		$(INSTALLED_PRODUCTIMAGE_TARGET) \
 		$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) \
@@ -2778,18 +2813,6 @@
 # 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))
@@ -2801,32 +2824,48 @@
 ifdef BOARD_SUPER_PARTITION_SIZE
 
 INSTALLED_SUPERIMAGE_TARGET := $(PRODUCT_OUT)/super.img
-$(INSTALLED_SUPERIMAGE_TARGET): $(call image-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
+INSTALLED_SUPERIMAGE_EMPTY_TARGET := $(PRODUCT_OUT)/super_empty.img
+
+$(INSTALLED_SUPERIMAGE_TARGET): $(call images-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
+$(INSTALLED_SUPERIMAGE_TARGET) $(INSTALLED_SUPERIMAGE_EMPTY_TARGET): PRIVATE_PARTITION_SUFFIX=_a
 endif # AB_OTA_UPDATER
 
+$(INSTALLED_SUPERIMAGE_TARGET) $(INSTALLED_SUPERIMAGE_EMPTY_TARGET): $(HOST_OUT_EXECUTABLES)/lpmake
 
-$(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)))
+# $(1): output image path
+# $(2): slot A suffix (_a or empty)
+# $(3): include images or not (true or empty)
+define build-superimage-target
+  $(HOST_OUT_EXECUTABLES)/lpmake \
+    $(if $(3), --sparse) \
+    --metadata-size 65536 \
+    --metadata-slots $(if $(2),2,1) \
+    --device-size $(BOARD_SUPER_PARTITION_SIZE) \
+    --output $(1) \
+    $(foreach name,$(BOARD_SUPER_PARTITION_PARTITION_LIST), \
+      --partition $(name)$(2):$$($(UUIDGEN) $(name)$(2)):readonly:$(if $(3),$(call read-size-of-partitions,$(name)),0) \
+      $(if $(3), --image $(name)$(2)=$(call images-for-partitions,$(name))) \
+      $(if $(2), --partition $(name)_b:$$($(UUIDGEN) $(name)_b):readonly:0) \
+    )
+endef
+
+$(INSTALLED_SUPERIMAGE_TARGET):
+	$(call pretty,"Target super fs image: $@")
+	$(call build-superimage-target,$@,$(PRIVATE_PARTITION_SUFFIX),true)
 
 $(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_TARGET))
 
+$(INSTALLED_SUPERIMAGE_EMPTY_TARGET):
+	$(call pretty,"Target empty super fs image: $@")
+	$(call build-superimage-target,$@,$(PRIVATE_PARTITION_SUFFIX))
+
+$(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_EMPTY_TARGET))
+
 endif # BOARD_SUPER_PARTITION_SIZE
 endif # PRODUCT_BUILD_SUPER_PARTITION
 
@@ -2845,7 +2884,7 @@
 .PHONY: check_android_partition_sizes
 
 # Add image dependencies so that generated_*_image_info.txt are written before checking.
-check_android_partition_sizes: $(call image-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
+check_android_partition_sizes: $(call images-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
 
 check_android_partition_sizes:
 	partition_size_list="$(call read-size-of-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))"; \
@@ -3117,6 +3156,7 @@
 		$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
 		$(INSTALLED_KERNEL_TARGET) \
 		$(INSTALLED_2NDBOOTLOADER_TARGET) \
+		$(BOARD_PREBUILT_DTBOIMAGE) \
 		$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH) \
 		$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH) \
 		$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH) \
@@ -3137,7 +3177,7 @@
 	@echo "Package target files: $@"
 	$(call create-system-vendor-symlink)
 	$(call create-system-product-symlink)
-	$(call create-system-product-services-symlink)
+	$(call create-system-product_services-symlink)
 	$(call create-vendor-odm-symlink)
 	$(hide) rm -rf $@ $@.list $(zip_root)
 	$(hide) mkdir -p $(dir $@) $(zip_root)
@@ -3153,7 +3193,7 @@
 	$(hide) cp $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/second
 endif
 ifdef BOARD_INCLUDE_RECOVERY_DTBO
-	$(hide) cp $(INSTALLED_DTBOIMAGE_TARGET) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/recovery_dtbo
+	$(hide) cp $(BOARD_PREBUILT_DTBOIMAGE) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/recovery_dtbo
 endif
 ifdef INTERNAL_KERNEL_CMDLINE
 	$(hide) echo "$(INTERNAL_KERNEL_CMDLINE)" > $(zip_root)/$(PRIVATE_RECOVERY_OUT)/cmdline
@@ -3167,13 +3207,12 @@
 endif # INSTALLED_RECOVERYIMAGE_TARGET defined or BOARD_USES_RECOVERY_AS_BOOT is true
 	@# Components of the boot image
 	$(hide) mkdir -p $(zip_root)/BOOT
-ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
 	$(hide) mkdir -p $(zip_root)/ROOT
 	$(hide) $(call package_files-copy-root, \
 		$(TARGET_ROOT_OUT),$(zip_root)/ROOT)
-else
+ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
 	$(hide) $(call package_files-copy-root, \
-		$(TARGET_ROOT_OUT),$(zip_root)/BOOT/RAMDISK)
+		$(TARGET_RAMDISK_OUT),$(zip_root)/BOOT/RAMDISK)
 endif
 	@# If we are using recovery as boot, this is already done when processing recovery.
 ifneq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
@@ -3213,7 +3252,7 @@
 		$(TARGET_OUT_PRODUCT),$(zip_root)/PRODUCT)
 endif
 ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
-	@# Contents of the product-services image
+	@# Contents of the product_services image
 	$(hide) $(call package_files-copy-root, \
 		$(TARGET_OUT_PRODUCT_SERVICES),$(zip_root)/PRODUCT_SERVICES)
 endif
@@ -3419,15 +3458,15 @@
 	$(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/product_services_filesystem_config.txt
+	$(hide) $(call fs_config,$(zip_root)/PRODUCT_SERVICES,product_services/) > $(zip_root)/META/product_services_filesystem_config.txt
 endif
 ifdef BOARD_ODMIMAGE_FILE_SYSTEM_TYPE
 	$(hide) $(call fs_config,$(zip_root)/ODM,odm/) > $(zip_root)/META/odm_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
-	@# normal boot. BOOT/RAMDISK exists only if additionally using BOARD_USES_RECOVERY_AS_BOOT.
+	@# ROOT always contains the files for the root under normal boot.
 	$(hide) $(call fs_config,$(zip_root)/ROOT,) > $(zip_root)/META/root_filesystem_config.txt
+ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+	@# BOOT/RAMDISK exists only if additionally using BOARD_USES_RECOVERY_AS_BOOT.
 ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
 	$(hide) $(call fs_config,$(zip_root)/BOOT/RAMDISK,) > $(zip_root)/META/boot_filesystem_config.txt
 endif
@@ -3535,7 +3574,7 @@
 APPCOMPAT_ZIP := $(PRODUCT_OUT)/appcompat.zip
 # For apps_only build we'll establish the dependency later in build/make/core/main.mk.
 ifndef TARGET_BUILD_APPS
-$(APPCOMPAT_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+$(APPCOMPAT_ZIP): $(INSTALLED_SYSTEMIMAGE_TARGET) \
 		$(INSTALLED_RAMDISK_TARGET) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
 		$(INSTALLED_USERDATAIMAGE_TARGET) \
@@ -3565,7 +3604,7 @@
 SYMBOLS_ZIP := $(PRODUCT_OUT)/$(name).zip
 # For apps_only build we'll establish the dependency later in build/make/core/main.mk.
 ifndef TARGET_BUILD_APPS
-$(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+$(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE_TARGET) \
 		$(INSTALLED_RAMDISK_TARGET) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
 		$(INSTALLED_USERDATAIMAGE_TARGET) \
@@ -3592,7 +3631,7 @@
 name := $(name)-coverage-$(FILE_NAME_TAG)
 COVERAGE_ZIP := $(PRODUCT_OUT)/$(name).zip
 ifndef TARGET_BUILD_APPS
-$(COVERAGE_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+$(COVERAGE_ZIP): $(INSTALLED_SYSTEMIMAGE_TARGET) \
 		$(INSTALLED_RAMDISK_TARGET) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
 		$(INSTALLED_USERDATAIMAGE_TARGET) \
@@ -3620,7 +3659,7 @@
 name := $(name)-apps-$(FILE_NAME_TAG)
 
 APPS_ZIP := $(PRODUCT_OUT)/$(name).zip
-$(APPS_ZIP): $(INSTALLED_SYSTEMIMAGE)
+$(APPS_ZIP): $(INSTALLED_SYSTEMIMAGE_TARGET)
 	@echo "Package apps: $@"
 	$(hide) rm -rf $@
 	$(hide) mkdir -p $(dir $@)
@@ -3684,7 +3723,7 @@
 INSTALLED_QEMU_SYSTEMIMAGE := $(PRODUCT_OUT)/system-qemu.img
 MK_QEMU_IMAGE_SH := device/generic/goldfish/tools/mk_qemu_image.sh
 SGDISK_HOST := $(HOST_OUT_EXECUTABLES)/sgdisk
-$(INSTALLED_QEMU_SYSTEMIMAGE): $(INSTALLED_SYSTEMIMAGE) $(MK_QEMU_IMAGE_SH) $(SGDISK_HOST) $(SIMG2IMG)
+$(INSTALLED_QEMU_SYSTEMIMAGE): $(INSTALLED_SYSTEMIMAGE_TARGET) $(MK_QEMU_IMAGE_SH) $(SGDISK_HOST) $(SIMG2IMG)
 	@echo Create system-qemu.img
 	(export SGDISK=$(SGDISK_HOST) SIMG2IMG=$(SIMG2IMG); $(MK_QEMU_IMAGE_SH) ${PRODUCT_OUT}/system.img)
 
@@ -3709,10 +3748,10 @@
 droidcore: $(INSTALLED_QEMU_PRODUCTIMAGE)
 endif
 ifeq ($(BOARD_USES_PRODUCT_SERVICESIMAGE),true)
-INSTALLED_QEMU_PRODUCT_SERVICESIMAGE := $(PRODUCT_OUT)/product-services-qemu.img
+INSTALLED_QEMU_PRODUCT_SERVICESIMAGE := $(PRODUCT_OUT)/product_services-qemu.img
 $(INSTALLED_QEMU_PRODUCT_SERVICESIMAGE): $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) $(MK_QEMU_IMAGE_SH) $(SGDISK_HOST) $(SIMG2IMG)
-	@echo Create product-services-qemu.img
-	(export SGDISK=$(SGDISK_HOST) SIMG2IMG=$(SIMG2IMG); $(MK_QEMU_IMAGE_SH) ${PRODUCT_OUT}/product-services.img)
+	@echo Create product_services-qemu.img
+	(export SGDISK=$(SGDISK_HOST) SIMG2IMG=$(SIMG2IMG); $(MK_QEMU_IMAGE_SH) ${PRODUCT_OUT}/product_services.img)
 
 productservicesimage: $(INSTALLED_QEMU_PRODUCT_SERVICESIMAGE)
 droidcore: $(INSTALLED_QEMU_PRODUCT_SERVICESIMAGE)
@@ -3734,8 +3773,8 @@
         $(HOST_OUT_EXECUTABLES)/emulator$(HOST_EXECUTABLE_SUFFIX) \
         prebuilts/qemu-kernel/$(TARGET_ARCH)/kernel-qemu \
         $(INSTALLED_RAMDISK_TARGET) \
-		$(INSTALLED_SYSTEMIMAGE) \
-		$(INSTALLED_USERDATAIMAGE_TARGET)
+        $(INSTALLED_SYSTEMIMAGE_TARGET) \
+        $(INSTALLED_USERDATAIMAGE_TARGET)
 
 name := $(TARGET_PRODUCT)-emulator-$(FILE_NAME_TAG)
 
@@ -3823,7 +3862,7 @@
 	$(SYMBOLS_ZIP) \
 	$(COVERAGE_ZIP) \
 	$(APPCOMPAT_ZIP) \
-	$(INSTALLED_SYSTEMIMAGE) \
+	$(INSTALLED_SYSTEMIMAGE_TARGET) \
 	$(INSTALLED_QEMU_SYSTEMIMAGE) \
 	$(INSTALLED_QEMU_VENDORIMAGE) \
 	$(INSTALLED_USERDATAIMAGE_TARGET) \
diff --git a/core/OWNERS b/core/OWNERS
index 4045061..570ede8 100644
--- a/core/OWNERS
+++ b/core/OWNERS
@@ -1,8 +1 @@
-per-file * = ccross@android.com
-per-file * = dwillemsen@google.com
-per-file * = nanzhang@google.com
-
-per-file dex_preopt*.mk = ngeoffray@google.com
-per-file dex_preopt*.mk = calin@google.com
-per-file dex_preopt*.mk = mathewi@google.com
-per-file dex_preopt*.mk = dbrazdil@google.com
+per-file dex_preopt*.mk = ngeoffray@google.com,calin@google.com,mathewi@google.com,dbrazdil@google.com
diff --git a/core/apidiff.mk b/core/apidiff.mk
index 23da624..8887ea4 100644
--- a/core/apidiff.mk
+++ b/core/apidiff.mk
@@ -64,8 +64,8 @@
     _module_name :=
   endif
 else
-  LOCAL_JAVA_LIBRARIES := core-oj core-libart ext framework $(LOCAL_JAVA_LIBRARIES)
-  $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, core-oj):$(call java-lib-files, core-libart)
+  LOCAL_JAVA_LIBRARIES := core-oj core-libart core-simple ext framework $(LOCAL_JAVA_LIBRARIES)
+  $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, core-oj):$(call java-lib-files, core-libart):$(call java-lib-files, core-simple)
 endif  # LOCAL_SDK_VERSION
 LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
 
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 3125a76..fce7a1f 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -573,6 +573,42 @@
   $(eval my_compat_dist_config_$(suite) := ))
 
 
+# Auto-generate build config.
+ifneq (,$(LOCAL_FULL_TEST_CONFIG))
+  test_config := $(LOCAL_FULL_TEST_CONFIG)
+else ifneq (,$(LOCAL_TEST_CONFIG))
+  test_config := $(LOCAL_PATH)/$(LOCAL_TEST_CONFIG)
+else
+  test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
+endif
+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
+is_instrumentation_test :=
+
 # Make sure we only add the files once for multilib modules.
 ifdef $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
   # Sync the auto_test_config value for multilib modules.
@@ -589,41 +625,6 @@
       $(eval n := $(or $(word 2,$(p)),$(notdir $(word 1, $(p))))) \
       $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
         $(s):$(dir)/$(n)))))
-  ifneq (,$(LOCAL_FULL_TEST_CONFIG))
-    test_config := $(LOCAL_FULL_TEST_CONFIG)
-  else ifneq (,$(LOCAL_TEST_CONFIG))
-    test_config := $(LOCAL_PATH)/$(LOCAL_TEST_CONFIG)
-  else
-    test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
-  endif
-  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
-
-  is_instrumentation_test :=
 
   ifneq (,$(test_config))
     $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
@@ -631,8 +632,6 @@
         $(test_config):$(dir)/$(LOCAL_MODULE).config)))
   endif
 
-  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)), \
@@ -647,19 +646,17 @@
   endif
 endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
 
-# HACK: pretend a soong LOCAL_FULL_TEST_CONFIG is autogenerated by copying it to
-# the location autogenerated test configs use and setting the flag in
+# HACK: pretend a soong LOCAL_FULL_TEST_CONFIG is autogenerated by setting the flag in
 # module-info.json
-ifdef LOCAL_FULL_TEST_CONFIG
+# TODO: (b/113029686) Add explicit flag from Soong to determine if a test was
+# autogenerated.
+ifneq (,$(filter $(SOONG_OUT_DIR)%,$(LOCAL_FULL_TEST_CONFIG)))
   ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-    my_test_config_file := $(dir $(LOCAL_BUILT_MODULE))$(LOCAL_MODULE).config
-    $(eval $(call copy-one-file,$(LOCAL_FULL_TEST_CONFIG),$(my_test_config_file)))
-    $(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_test_config_file))
     ALL_MODULES.$(my_register_name).auto_test_config := true
-    my_test_config_file :=
   endif
 endif
 
+
 ifneq ($(my_test_data_file_pairs),)
 $(foreach pair, $(my_test_data_file_pairs), \
   $(eval parts := $(subst :,$(space),$(pair))) \
@@ -771,6 +768,8 @@
 ALL_MODULES.$(my_register_name).FOR_HOST_CROSS := $(my_host_cross)
 ALL_MODULES.$(my_register_name).MODULE_NAME := $(LOCAL_MODULE)
 ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES := $(LOCAL_COMPATIBILITY_SUITE)
+ALL_MODULES.$(my_register_name).TEST_CONFIG := $(test_config)
+test_config :=
 
 INSTALLABLE_FILES.$(LOCAL_INSTALLED_MODULE).MODULE := $(my_register_name)
 
diff --git a/core/binary.mk b/core/binary.mk
index 777279b..c454e4a 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1320,6 +1320,24 @@
     $(my_static_libraries))
 endif
 
+ifneq ($(LOCAL_USE_VNDK),)
+  my_soong_hwasan_static_libraries := $(SOONG_HWASAN_VENDOR_STATIC_LIBRARIES)
+else
+  my_soong_hwasan_static_libraries = $(SOONG_HWASAN_STATIC_LIBRARIES)
+endif
+
+define use_soong_hwasan_static_libraries
+  $(foreach l,$(1),$(if $(filter $(l),$(my_soong_hwasan_static_libraries)),\
+      $(l).hwasan,$(l)))
+endef
+
+ifneq ($(filter hwaddress,$(my_sanitize)),)
+  my_whole_static_libraries := $(call use_soong_hwasan_static_libraries,\
+    $(my_whole_static_libraries))
+  my_static_libraries := $(call use_soong_hwasan_static_libraries,\
+    $(my_static_libraries))
+endif
+
 ###########################################################
 ## When compiling against the VNDK, use LL-NDK libraries
 ###########################################################
@@ -1432,6 +1450,11 @@
         my_warn_types :=
         my_allowed_types := native:vendor native:vndk
     endif
+else ifneq ($(filter $(TARGET_RECOVERY_OUT)/%,$(LOCAL_MODULE_PATH)),)
+my_link_type := native:recovery
+my_warn_types :=
+# TODO(b/113303515) remove native:platform and my_allowed_ndk_types
+my_allowed_types := native:recovery native:platform $(my_allowed_ndk_types)
 else
 my_link_type := native:platform
 my_warn_types := $(my_warn_ndk_types)
@@ -1719,7 +1742,7 @@
     # Disable clang-tidy if clang is disabled.
     my_tidy_enabled := false
   else
-    tidy_only: $(cpp_objects) $(c_objects)
+    tidy_only: $(cpp_objects) $(c_objects) $(gen_c_objects) $(gen_cpp_objects)
     # Set up global default checks
     my_tidy_checks := $(WITH_TIDY_CHECKS)
     ifeq ($(my_tidy_checks),)
@@ -1758,6 +1781,15 @@
 
 my_tidy_checks := $(subst $(space),,$(my_tidy_checks))
 
+# Add dependency of clang-tidy and clang-tidy.sh
+ifneq ($(my_tidy_checks),)
+  my_clang_tidy_programs := $(PATH_TO_CLANG_TIDY) $(PATH_TO_CLANG_TIDY_SHELL)
+  $(cpp_objects): $(intermediates)/%.o: $(my_clang_tidy_programs)
+  $(c_objects): $(intermediates)/%.o: $(my_clang_tidy_programs)
+  $(gen_cpp_objects): $(intermediates)/%.o: $(my_clang_tidy_programs)
+  $(gen_c_objects): $(intermediates)/%.o: $(my_clang_tidy_programs)
+endif
+
 # Move -l* entries from ldflags to ldlibs, and everything else to ldflags
 my_ldlib_flags := $(my_ldflags) $(my_ldlibs)
 my_ldlibs := $(filter -l%,$(my_ldlib_flags))
diff --git a/core/combo/HOST_darwin-x86.mk b/core/combo/HOST_darwin-x86.mk
deleted file mode 100644
index 9a55cb5..0000000
--- a/core/combo/HOST_darwin-x86.mk
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Copyright (C) 2006 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.
-#
-
-# Configuration for Darwin (Mac OS X) on x86.
-# Included by combo/select.mk
-
-define $(combo_var_prefix)transform-shared-lib-to-toc
-$(call _gen_toc_command_for_macho,$(1),$(2))
-endef
-
-$(combo_2nd_arch_prefix)HOST_GLOBAL_ARFLAGS := cqs
-
-############################################################
-## Macros after this line are shared by the 64-bit config.
-
-HOST_CUSTOM_LD_COMMAND := true
-
-define transform-host-o-to-shared-lib-inner
-$(hide) $(PRIVATE_CXX) \
-        -dynamiclib -single_module -read_only_relocs suppress \
-        $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
-            $(PRIVATE_HOST_GLOBAL_LDFLAGS) \
-        ) \
-        $(PRIVATE_ALL_OBJECTS) \
-        $(addprefix -force_load , $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-        $(PRIVATE_ALL_SHARED_LIBRARIES) \
-        $(PRIVATE_ALL_STATIC_LIBRARIES) \
-        $(PRIVATE_LDLIBS) \
-        -o $@ \
-        -install_name @rpath/$(notdir $@) \
-        -Wl,-rpath,@loader_path/../$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES)) \
-        -Wl,-rpath,@loader_path/$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES)) \
-        $(PRIVATE_LDFLAGS)
-endef
-
-define transform-host-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) \
-        $(foreach path,$(PRIVATE_RPATHS), \
-          -Wl,-rpath,@loader_path/$(path)) \
-        -o $@ \
-        -Wl,-headerpad_max_install_names \
-        $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
-           $(PRIVATE_HOST_GLOBAL_LDFLAGS) \
-        ) \
-        $(PRIVATE_ALL_SHARED_LIBRARIES) \
-        $(PRIVATE_ALL_OBJECTS) \
-        $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
-        $(PRIVATE_ALL_STATIC_LIBRARIES) \
-        $(PRIVATE_LDFLAGS) \
-        $(PRIVATE_LDLIBS)
-endef
-
-# $(1): The file to check
-define get-file-size
-stat -f "%z" $(1)
-endef
diff --git a/core/combo/HOST_darwin-x86_64.mk b/core/combo/HOST_darwin-x86_64.mk
index 6cca167..07f8d9f 100644
--- a/core/combo/HOST_darwin-x86_64.mk
+++ b/core/combo/HOST_darwin-x86_64.mk
@@ -23,7 +23,44 @@
 
 HOST_GLOBAL_ARFLAGS := cqs
 
-# We Reuse the following functions with the same name from HOST_darwin-x86.mk:
-# transform-host-o-to-shared-lib-inner
-# transform-host-o-to-executable-inner
-# get-file-size
+HOST_CUSTOM_LD_COMMAND := true
+
+define transform-host-o-to-shared-lib-inner
+$(hide) $(PRIVATE_CXX) \
+        -dynamiclib -single_module -read_only_relocs suppress \
+        $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+            $(PRIVATE_HOST_GLOBAL_LDFLAGS) \
+        ) \
+        $(PRIVATE_ALL_OBJECTS) \
+        $(addprefix -force_load , $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+        $(PRIVATE_ALL_SHARED_LIBRARIES) \
+        $(PRIVATE_ALL_STATIC_LIBRARIES) \
+        $(PRIVATE_LDLIBS) \
+        -o $@ \
+        -install_name @rpath/$(notdir $@) \
+        -Wl,-rpath,@loader_path/../$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES)) \
+        -Wl,-rpath,@loader_path/$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES)) \
+        $(PRIVATE_LDFLAGS)
+endef
+
+define transform-host-o-to-executable-inner
+$(hide) $(PRIVATE_CXX) \
+        $(foreach path,$(PRIVATE_RPATHS), \
+          -Wl,-rpath,@loader_path/$(path)) \
+        -o $@ \
+        -Wl,-headerpad_max_install_names \
+        $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
+           $(PRIVATE_HOST_GLOBAL_LDFLAGS) \
+        ) \
+        $(PRIVATE_ALL_SHARED_LIBRARIES) \
+        $(PRIVATE_ALL_OBJECTS) \
+        $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
+        $(PRIVATE_ALL_STATIC_LIBRARIES) \
+        $(PRIVATE_LDFLAGS) \
+        $(PRIVATE_LDLIBS)
+endef
+
+# $(1): The file to check
+define get-file-size
+stat -f "%z" $(1)
+endef
diff --git a/core/config.mk b/core/config.mk
index 4226f2f..f3be496 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -855,11 +855,6 @@
         $(error When PRODUCT_SHIPPING_API_LEVEL >= 28, TARGET_USES_64_BIT_BINDER must be true)
       endif
     endif
-    ifeq ($(PRODUCT_FULL_TREBLE),true)
-      ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE), true)
-        $(error When PRODUCT_SHIPPING_API_LEVEL >= 28, BOARD_BUILD_SYSTEM_ROOT_IMAGE must be true)
-      endif
-    endif
   endif
   ifneq ($(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),29),)
     ifneq ($(BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE),)
@@ -1116,6 +1111,7 @@
 
 INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-public-list.txt
 INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-private-list.txt
+INTERNAL_PLATFORM_HIDDENAPI_WHITELIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-whitelist.txt
 INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-light-greylist.txt
 INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-dark-greylist.txt
 INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-blacklist.txt
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index 083da9f..9ef2570 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -174,6 +174,24 @@
   my_sanitize := $(filter-out $(my_nosanitize),$(my_sanitize))
 endif
 
+ifneq ($(filter arm x86 x86_64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
+  my_sanitize := $(filter-out hwaddress,$(my_sanitize))
+endif
+
+ifneq ($(filter hwaddress,$(my_sanitize)),)
+  my_sanitize := $(filter-out address,$(my_sanitize))
+  my_sanitize := $(filter-out thread,$(my_sanitize))
+endif
+
+ifneq ($(filter hwaddress,$(my_sanitize)),)
+  my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)HWADDRESS_SANITIZER_RUNTIME_LIBRARY)
+  ifeq ($(LOCAL_MODULE_CLASS),EXECUTABLES)
+    ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+      my_static_libraries := $(my_static_libraries) $($(LOCAL_2ND_ARCH_VAR_PREFIX)HWADDRESS_SANITIZER_STATIC_LIBRARY)
+    endif
+  endif
+endif
+
 # TSAN is not supported on 32-bit architectures. For non-multilib cases, make
 # its use an error. For multilib cases, don't use it for the 32-bit case.
 ifneq ($(filter thread,$(my_sanitize)),)
@@ -195,7 +213,7 @@
 endif
 
 # Disable Scudo if ASan or TSan is enabled.
-ifneq ($(filter address thread,$(my_sanitize)),)
+ifneq ($(filter address thread hwaddress,$(my_sanitize)),)
   my_sanitize := $(filter-out scudo,$(my_sanitize))
 endif
 
@@ -352,6 +370,11 @@
   endif
 endif
 
+# If local module needs HWASAN, add compiler flags.
+ifneq ($(filter hwaddress,$(my_sanitize)),)
+  my_cflags += $(HWADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
+endif
+
 # Use minimal diagnostics when integer overflow is enabled; never do it for HOST or AUX modules
 ifeq ($(LOCAL_IS_HOST_MODULE)$(LOCAL_IS_AUX_MODULE),)
   # Pre-emptively add UBSAN minimal runtime incase a static library dependency requires it
@@ -364,7 +387,7 @@
   ifneq ($(filter unsigned-integer-overflow signed-integer-overflow integer,$(my_sanitize)),)
     ifeq ($(filter unsigned-integer-overflow signed-integer overflow integer,$(my_sanitize_diag)),)
       ifeq ($(filter cfi,$(my_sanitize_diag)),)
-        ifeq ($(filter address,$(my_sanitize)),)
+        ifeq ($(filter address hwaddress,$(my_sanitize)),)
           my_cflags += -fsanitize-minimal-runtime
           my_cflags += -fno-sanitize-trap=integer
           my_cflags += -fno-sanitize-recover=integer
@@ -387,7 +410,7 @@
     notrap_arg := $(subst $(space),$(comma),$(my_sanitize_diag)),
     my_cflags += -fno-sanitize-trap=$(notrap_arg)
     # Diagnostic requires a runtime library, unless ASan or TSan are also enabled.
-    ifeq ($(filter address thread scudo,$(my_sanitize)),)
+    ifeq ($(filter address thread scudo hwaddress,$(my_sanitize)),)
       # Does not have to be the first DT_NEEDED unlike ASan.
       my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_RUNTIME_LIBRARY)
     endif
diff --git a/core/definitions.mk b/core/definitions.mk
index fbb7da6..3d9c140 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -105,9 +105,6 @@
 # All tests that should be skipped in presubmit check.
 ALL_DISABLED_PRESUBMIT_TESTS :=
 
-# CLANG_TIDY_UNKNOWN_CFLAGS is generated by build/soong.
-sanitize_tidy_cflags = $(filter-out $(CLANG_TIDY_UNKNOWN_CFLAGS),$1)
-
 ###########################################################
 ## Debugging; prints a variable list to stdout
 ###########################################################
@@ -1253,10 +1250,16 @@
 	$(PRIVATE_CPPFLAGS_NO_OVERRIDE)
 endef
 
+# PATH_TO_CLANG_TIDY_SHELL is defined in build/soong
+define call-clang-tidy
+CLANG_TIDY=$(PATH_TO_CLANG_TIDY) \
+  $(PATH_TO_CLANG_TIDY_SHELL) \
+  $(PRIVATE_TIDY_FLAGS) \
+  -checks=$(PRIVATE_TIDY_CHECKS)
+endef
+
 define clang-tidy-cpp
-$(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
-  -checks=$(PRIVATE_TIDY_CHECKS) \
-  $< -- $(call sanitize_tidy_cflags,$(transform-cpp-to-o-compiler-args))
+$(hide) $(call-clang-tidy) $< -- $(transform-cpp-to-o-compiler-args)
 endef
 
 ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
@@ -1302,9 +1305,7 @@
 endef
 
 define clang-tidy-c
-$(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
-  -checks=$(PRIVATE_TIDY_CHECKS) \
-  $< -- $(call sanitize_tidy_cflags,$(transform-c-to-o-compiler-args))
+$(hide) $(call-clang-tidy) $< -- $(transform-c-to-o-compiler-args)
 endef
 
 ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
@@ -1372,9 +1373,7 @@
 endef
 
 define clang-tidy-host-cpp
-$(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
-  -checks=$(PRIVATE_TIDY_CHECKS) \
-  $< -- $(call sanitize_tidy_cflags,$(transform-host-cpp-to-o-compiler-args))
+$(hide) $(call-clang-tidy) $< -- $(transform-host-cpp-to-o-compiler-args)
 endef
 
 ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
@@ -1424,9 +1423,7 @@
 endef
 
 define clang-tidy-host-c
-$(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
-  -checks=$(PRIVATE_TIDY_CHECKS) \
-  $< -- $(call sanitize_tidy_cflags,$(transform-host-c-to-o-compiler-args))
+$(hide) $(call-clang-tidy) $< -- $(transform-host-c-to-o-compiler-args)
 endef
 
 ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
@@ -1949,13 +1946,13 @@
 	-Wl,--whole-archive \
 	$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
 	-Wl,--no-whole-archive \
-	$(filter-out %libcompiler_rt.a,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)))) \
+	$(filter-out %libcompiler_rt.hwasan.a %libc_nomalloc.hwasan.a %libc.hwasan.a %libcompiler_rt.a %libc_nomalloc.a %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	-Wl,--start-group \
-	$(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(filter %libc_nomalloc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(filter %libc.a %libc.hwasan.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(filter %libc_nomalloc.a %libc_nomalloc.hwasan.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_TARGET_COVERAGE_LIB)) \
 	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(filter %libcompiler_rt.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(filter %libcompiler_rt.a %libcompiler_rt.hwasan.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(PRIVATE_TARGET_LIBGCC) \
 	-Wl,--end-group \
 	$(PRIVATE_TARGET_CRTEND_O)
@@ -2877,12 +2874,18 @@
 define hiddenapi-generate-greylist-txt
 ifneq (,$(wildcard frameworks/base))
 # Only generate this target if we're in a tree with frameworks/base present.
-$(2): $(1) $(CLASS2GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
-	$(CLASS2GREYLIST) --public-api-list $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) $(1) > $(2)
+$(3): .KATI_IMPLICIT_OUTPUTS := $(2)
+$(3): $(1) $(CLASS2GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
+	$(CLASS2GREYLIST) --public-api-list $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) $(1) \
+	    --write-whitelist $(2) --write-greylist $(3)
 
-$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): $(2)
+$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): $(2)
+$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): \
+    PRIVATE_WHITELIST_INPUTS := $$(PRIVATE_WHITELIST_INPUTS) $(2)
+
+$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): $(3)
 $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): \
-    PRIVATE_GREYLIST_INPUTS := $$(PRIVATE_GREYLIST_INPUTS) $(2)
+    PRIVATE_GREYLIST_INPUTS := $$(PRIVATE_GREYLIST_INPUTS) $(3)
 endif
 endef
 
@@ -2915,12 +2918,14 @@
 ###########################################################
 define transform-jar-to-dex-r8
 @echo R8: $@
+$(hide) rm -f $(PRIVATE_PROGUARD_DICTIONARY)
 $(hide) $(R8_COMPAT_PROGUARD) -injars '$<' \
     --min-api $(PRIVATE_MIN_SDK_VERSION) \
     --force-proguard-compatibility --output $(subst classes.dex,,$@) \
     $(PRIVATE_PROGUARD_FLAGS) \
     $(addprefix -injars , $(PRIVATE_EXTRA_INPUT_JAR)) \
     $(PRIVATE_DX_FLAGS)
+$(hide) touch $(PRIVATE_PROGUARD_DICTIONARY)
 endef
 
 ###########################################################
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index a7caac1..8299988 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -21,7 +21,13 @@
 
 # The default filter for which files go into the system_other image (if it is
 # being used). To bundle everything one should set this to '%'
-SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/% product/app/% product/priv-app/%
+SYSTEM_OTHER_ODEX_FILTER ?= \
+    app/% \
+    priv-app/% \
+    product_services/app/% \
+    product_services/priv-app/% \
+    product/app/% \
+    product/priv-app/% \
 
 # Method returning whether the install path $(1) should be for system_other.
 # Under SANITIZE_LITE, we do not want system_other. Just put things under /data/asan.
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index ce060f2..504cc57 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -77,8 +77,7 @@
 $(dir $(2))$(1)/$(notdir $(2))
 endef
 
-# note we use core-libart.jar in place of core.jar for ART.
-LIBART_TARGET_BOOT_JARS := $(patsubst core, core-libart,$(DEXPREOPT_BOOT_JARS_MODULES))
+LIBART_TARGET_BOOT_JARS := $(DEXPREOPT_BOOT_JARS_MODULES)
 LIBART_TARGET_BOOT_DEX_LOCATIONS := $(foreach jar,$(LIBART_TARGET_BOOT_JARS),/$(DEXPREOPT_BOOT_JAR_DIR)/$(jar).jar)
 LIBART_TARGET_BOOT_DEX_FILES := $(foreach jar,$(LIBART_TARGET_BOOT_JARS),$(call intermediates-dir-for,JAVA_LIBRARIES,$(jar),,COMMON)/javalib.jar)
 
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 8750203..4396dd2 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -147,6 +147,11 @@
 endif
 endif
 
+ifeq ($(HOST_OS),darwin)
+  # Mac no longer supports 32-bit executables
+  HOST_2ND_ARCH :=
+endif
+
 BUILD_ARCH := $(HOST_ARCH)
 BUILD_2ND_ARCH := $(HOST_2ND_ARCH)
 
@@ -180,7 +185,8 @@
 TARGET_COPY_OUT_OEM := oem
 TARGET_COPY_OUT_ODM := odm
 TARGET_COPY_OUT_PRODUCT := product
-TARGET_COPY_OUT_PRODUCT_SERVICES := product-services
+TARGET_COPY_OUT_PRODUCT_SERVICES := product_services
+TARGET_COPY_OUT_RAMDISK := ramdisk
 TARGET_COPY_OUT_ROOT := root
 TARGET_COPY_OUT_RECOVERY := recovery
 
@@ -213,9 +219,9 @@
 
 ###########################################
 # Define TARGET_COPY_OUT_PRODUCT_SERVICES to a placeholder, for at this point
-# we don't know if the device wants to build a separate product-services.img
+# we don't know if the device wants to build a separate product_services.img
 # or just build product stuff into system.img.
-# A device can set up TARGET_COPY_OUT_PRODUCT_SERVICES to "product-services" in its
+# A device can set up TARGET_COPY_OUT_PRODUCT_SERVICES to "product_services" in its
 # BoardConfig.mk.
 # We'll substitute with the real value after loading BoardConfig.mk.
 _product_services_path_placeholder := ||PRODUCT_SERVICES-PATH-PH||
@@ -236,7 +242,7 @@
 #################################################################
 # Set up minimal BOOTCLASSPATH list of jars to build/execute
 # java code with dalvikvm/art.
-TARGET_CORE_JARS := core-oj core-libart conscrypt okhttp bouncycastle apache-xml
+TARGET_CORE_JARS := core-oj core-libart core-simple conscrypt okhttp bouncycastle apache-xml
 ifeq ($(EMMA_INSTRUMENT),true)
   ifneq ($(EMMA_INSTRUMENT_STATIC),true)
     # For instrumented build, if Jacoco is not being included statically
@@ -320,6 +326,12 @@
 CHANGES_URL :=
 
 ###########################################
+# Now we can substitute with the real value of TARGET_COPY_OUT_RAMDISK
+ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+TARGET_COPY_OUT_RAMDISK := $(TARGET_COPY_OUT_ROOT)
+endif
+
+###########################################
 # Now we can substitute with the real value of TARGET_COPY_OUT_VENDOR
 ifeq ($(TARGET_COPY_OUT_VENDOR),$(_vendor_path_placeholder))
 TARGET_COPY_OUT_VENDOR := system/vendor
@@ -366,11 +378,11 @@
 ###########################################
 # Now we can substitute with the real value of TARGET_COPY_OUT_PRODUCT_SERVICES
 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)'.)
+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 $(_product_services_path_placeholder),$(TARGET_COPY_OUT_PRODUCT_SERVICES),$(PRODUCT_SERVICES_COPY_FILES))
+PRODUCT_COPY_FILES := $(subst $(_product_services_path_placeholder),$(TARGET_COPY_OUT_PRODUCT_SERVICES),$(PRODUCT_COPY_FILES))
 
 BOARD_USES_PRODUCT_SERVICESIMAGE :=
 ifdef BOARD_PREBUILT_PRODUCT_SERVICESIMAGE
@@ -379,10 +391,10 @@
 ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
 BOARD_USES_PRODUCT_SERVICESIMAGE := true
 endif
-ifeq ($(TARGET_COPY_OUT_PRODUCT_SERVICES),product-services)
+ifeq ($(TARGET_COPY_OUT_PRODUCT_SERVICES),product_services)
 BOARD_USES_PRODUCT_SERVICESIMAGE := true
 else ifdef BOARD_USES_PRODUCT_SERVICESIMAGE
-$(error TARGET_COPY_OUT_PRODUCT_SERVICES must be set to 'product-services' to use a product-services image)
+$(error TARGET_COPY_OUT_PRODUCT_SERVICES must be set to 'product_services' to use a product_services image)
 endif
 
 ###########################################
@@ -974,11 +986,11 @@
 
 TARGET_OUT_PRODUCT_SERVICES := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_PRODUCT_SERVICES)
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
-target_out_product_services_shared_libraries_base := $(PRODUCT_SERVICES_OUT)/$(TARGET_COPY_OUT_ASAN)/product-services
+target_out_product_services_shared_libraries_base := $(PRODUCT_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_product_services_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_product_services_app_base := $(TARGET_OUT_PRODUCT_SERVICES)
 endif
@@ -1026,6 +1038,9 @@
   TARGET_ROOT_OUT_BIN_UNSTRIPPED \
   TARGET_OUT_COVERAGE
 
+TARGET_RAMDISK_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_RAMDISK)
+TARGET_RAMDISK_OUT_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)
+
 TARGET_ROOT_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ROOT)
 TARGET_ROOT_OUT_BIN := $(TARGET_ROOT_OUT)/bin
 TARGET_ROOT_OUT_SBIN := $(TARGET_ROOT_OUT)/sbin
diff --git a/core/install_jni_libs.mk b/core/install_jni_libs.mk
index b7d83dc..01f7f10 100644
--- a/core/install_jni_libs.mk
+++ b/core/install_jni_libs.mk
@@ -18,10 +18,20 @@
 ifneq ($(filter tests samples, $(LOCAL_MODULE_TAGS)),)
 my_embed_jni := true
 endif
-ifeq ($(filter $(TARGET_OUT)/% $(TARGET_OUT_VENDOR)/% $(TARGET_OUT_OEM)/%, $(my_module_path)),)
-# If this app isn't to be installed to system partitions.
-my_embed_jni := true
+
+# If the APK is not installed in one of the following partitions, force its libraries
+# to be embedded inside the APK instead of installed to /<partition>/lib[64]/.
+supported_partition_patterns := \
+    $(TARGET_OUT)/% \
+    $(TARGET_OUT_VENDOR)/% \
+    $(TARGET_OUT_OEM)/% \
+    $(TARGET_OUT_PRODUCT)/% \
+    $(TARGET_OUT_PRODUCT_SERVICES)/% \
+
+ifeq ($(filter $(supported_partition_patterns),$(my_module_path)),)
+    my_embed_jni := true
 endif
+
 # If we're installing this APP as a compressed module, we include all JNI libraries
 # in the compressed artifact, rather than as separate files on the partition in question.
 ifdef LOCAL_COMPRESSED_MODULE
diff --git a/core/java.mk b/core/java.mk
index d428eb2..e5f1f4a 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -74,8 +74,8 @@
 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
-
+hiddenapi_whitelist_txt := $(intermediates.COMMON)/hiddenapi/whitelist.txt
+hiddenapi_greylist_txt := $(intermediates.COMMON)/hiddenapi/greylist.txt
 
 ifeq ($(LOCAL_MODULE_CLASS)$(LOCAL_SRC_FILES)$(LOCAL_STATIC_JAVA_LIBRARIES)$(LOCAL_SOURCE_FILES_ALL_GENERATED),APPS)
 # If this is an apk without any Java code (e.g. framework-res), we should skip compiling Java.
@@ -489,6 +489,7 @@
 ifdef LOCAL_PROGUARD_ENABLED
   $(built_dex_intermediate): PRIVATE_EXTRA_INPUT_JAR := $(extra_input_jar)
   $(built_dex_intermediate): PRIVATE_PROGUARD_FLAGS := $(legacy_proguard_flags) $(common_proguard_flags) $(LOCAL_PROGUARD_FLAGS)
+  $(built_dex_intermediate): PRIVATE_PROGUARD_DICTIONARY := $(proguard_dictionary)
   $(built_dex_intermediate) : $(full_classes_pre_proguard_jar) $(extra_input_jar) $(my_proguard_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) $(legacy_proguard_lib_deps) $(R8_COMPAT_PROGUARD)
 	$(transform-jar-to-dex-r8)
 else # !LOCAL_PROGUARD_ENABLED
@@ -502,8 +503,8 @@
   # 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_pre_proguard_jar),$(greylist_txt)))
-  LOCAL_INTERMEDIATE_TARGETS += $(greylist_txt)
+  $(eval $(call hiddenapi-generate-greylist-txt, $(full_classes_pre_proguard_jar),$(hiddenapi_whitelist_txt),$(hiddenapi_greylist_txt)))
+  LOCAL_INTERMEDIATE_TARGETS += $(hiddenapi_whitelist_txt) $(hiddenapi_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
diff --git a/core/java_common.mk b/core/java_common.mk
index 9c4fa89..e1ec30b 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -6,6 +6,10 @@
 my_soong_problems += dotdot_srcs
 endif
 
+ifneq (,$(LOCAL_JNI_SHARED_LIBRARIES))
+my_soong_problems += jni_libs
+endif
+
 ###########################################################
 ## Java version
 ###########################################################
diff --git a/core/main.mk b/core/main.mk
index 5eebe1e..fd62a98 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -406,7 +406,6 @@
 # Typical build; include any Android.mk files we can find.
 #
 
-FULL_BUILD := true
 
 # Before we go and include all of the module makefiles, mark the PRODUCT_*
 # and ADDITIONAL*PROPERTIES values readonly so that they won't be modified.
@@ -423,6 +422,7 @@
 endif
 
 subdir_makefiles_inc := .
+FULL_BUILD :=
 
 ifneq ($(ONE_SHOT_MAKEFILE),)
 # We've probably been invoked by the "mm" shell function
@@ -434,7 +434,6 @@
 # so that the modules will be installed in the same place they
 # would have been with a normal make.
 CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS)))
-FULL_BUILD :=
 
 # A helper goal printing out install paths
 define register_module_install_path
@@ -463,6 +462,7 @@
 else # ONE_SHOT_MAKEFILE
 
 ifneq ($(dont_bother),true)
+FULL_BUILD := true
 #
 # Include all of the makefiles in the system
 #
@@ -922,7 +922,9 @@
 define resolve-product-relative-paths
   $(subst $(_vendor_path_placeholder),$(TARGET_COPY_OUT_VENDOR),\
     $(subst $(_product_path_placeholder),$(TARGET_COPY_OUT_PRODUCT),\
-      $(foreach p,$(1),$(call append-path,$(PRODUCT_OUT),$(p)$(2)))))
+      $(subst $(_product_services_path_placeholder),$(TARGET_COPY_OUT_PRODUCT_SERVICES),\
+        $(subst $(_odm_path_placeholder),$(TARGET_COPY_OUT_ODM),\
+          $(foreach p,$(1),$(call append-path,$(PRODUCT_OUT),$(p)$(2)))))))
 endef
 
 # Lists most of the files a particular product installs, including:
@@ -1211,6 +1213,9 @@
 .PHONY: superimage
 superimage: $(INSTALLED_SUPERIMAGE_TARGET)
 
+.PHONY: superimage_empty
+superimage_empty: $(INSTALLED_SUPERIMAGE_EMPTY_TARGET)
+
 .PHONY: bootimage
 bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
 
@@ -1233,6 +1238,7 @@
     $(INSTALLED_BPTIMAGE_TARGET) \
     $(INSTALLED_VENDORIMAGE_TARGET) \
     $(INSTALLED_ODMIMAGE_TARGET) \
+    $(INSTALLED_SUPERIMAGE_EMPTY_TARGET) \
     $(INSTALLED_PRODUCTIMAGE_TARGET) \
     $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
     $(INSTALLED_FILES_FILE) \
@@ -1247,6 +1253,10 @@
     $(INSTALLED_FILES_JSON_PRODUCT_SERVICES) \
     $(INSTALLED_FILES_FILE_SYSTEMOTHER) \
     $(INSTALLED_FILES_JSON_SYSTEMOTHER) \
+    $(INSTALLED_FILES_FILE_RAMDISK) \
+    $(INSTALLED_FILES_JSON_RAMDISK) \
+    $(INSTALLED_FILES_FILE_ROOT) \
+    $(INSTALLED_FILES_JSON_ROOT) \
     $(INSTALLED_FILES_FILE_RECOVERY) \
     $(INSTALLED_FILES_JSON_RECOVERY) \
     soong_docs
@@ -1346,15 +1356,20 @@
   endif
   endif
 
-  ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+  $(call dist-for-goals, droidcore, \
+    $(INSTALLED_FILES_FILE_ROOT) \
+    $(INSTALLED_FILES_JSON_ROOT) \
+  )
+
+  ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
     $(call dist-for-goals, droidcore, \
-      $(INSTALLED_FILES_FILE_ROOT) \
-      $(INSTALLED_FILES_JSON_ROOT) \
+      $(INSTALLED_FILES_FILE_RAMDISK) \
+      $(INSTALLED_FILES_JSON_RAMDISK) \
     )
   endif
 
   ifeq ($(EMMA_INSTRUMENT),true)
-    $(JACOCO_REPORT_CLASSES_ALL) : $(INSTALLED_SYSTEMIMAGE)
+    $(JACOCO_REPORT_CLASSES_ALL) : $(INSTALLED_SYSTEMIMAGE_TARGET)
     $(call dist-for-goals, dist_files, $(JACOCO_REPORT_CLASSES_ALL))
 
     # Put XML formatted API files in the dist dir.
@@ -1435,6 +1450,11 @@
 	@echo "$(call module-names-for-tag-list,$(ALL_MODULE_TAGS))" | \
 	      tr -s ' ' '\n' | sort -u | $(COLUMN)
 
+.PHONY: dump-products
+dump-products:
+	$(dump-products)
+	@echo Successfully dumped products
+
 .PHONY: nothing
 nothing:
 	@echo Successfully read the makefiles.
diff --git a/core/package_internal.mk b/core/package_internal.mk
index acb128c..0208288 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -592,7 +592,7 @@
 endif
 endif
 
-# Run veridex on product, product-services and vendor modules.
+# Run veridex on product, product_services and vendor modules.
 # We skip it for unbundled app builds where we cannot build veridex.
 module_run_appcompat :=
 ifeq (true,$(filter true, \
diff --git a/core/pdk_config.mk b/core/pdk_config.mk
index 57afa3f..4c582e3 100644
--- a/core/pdk_config.mk
+++ b/core/pdk_config.mk
@@ -22,6 +22,7 @@
   target/common/obj/JAVA_LIBRARIES/conscrypt_intermediates \
   target/common/obj/JAVA_LIBRARIES/core-oj_intermediates \
   target/common/obj/JAVA_LIBRARIES/core-libart_intermediates \
+  target/common/obj/JAVA_LIBRARIES/core-simple_intermediates \
   target/common/obj/JAVA_LIBRARIES/legacy-test_intermediates \
   target/common/obj/JAVA_LIBRARIES/legacy-android-test_intermediates \
   target/common/obj/JAVA_LIBRARIES/ext_intermediates \
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index d07aad8..78da421 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -95,7 +95,7 @@
   prebuilt_module_is_dex_javalib :=
 endif
 
-# Run veridex on product, product-services and vendor modules.
+# Run veridex on product, product_services and vendor modules.
 # We skip it for unbundled app builds where we cannot build veridex.
 module_run_appcompat :=
 ifeq (true,$(filter true, \
@@ -188,6 +188,8 @@
     else
         my_link_type := native:vendor
     endif
+else ifneq ($(filter $(TARGET_RECOVERY_OUT)/%,$(LOCAL_MODULE_PATH)),)
+my_link_type := native:recovery
 else
 my_link_type := native:platform
 endif
diff --git a/core/product_config.mk b/core/product_config.mk
index c5d182a..7cbea91 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -243,11 +243,6 @@
 # Sanity check
 $(check-all-products)
 
-ifneq ($(filter dump-products, $(MAKECMDGOALS)),)
-$(dump-products)
-$(error done)
-endif
-
 # Convert a short name like "sooner" into the path to the product
 # file defining that product.
 #
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index fcd3baf..241a2f4 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -104,3 +104,5 @@
       $(LOCAL_EXPORT_PACKAGE_RESOURCES), \
       $(LOCAL_SOONG_RRO_DIRS))
 endif
+
+SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 210ee5f..311e3d4 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -19,7 +19,8 @@
 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
+hiddenapi_whitelist_txt := $(intermediates.COMMON)/hiddenapi/whitelist.txt
+hiddenapi_greylist_txt := $(intermediates.COMMON)/hiddenapi/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)))
@@ -77,7 +78,7 @@
         # 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-generate-greylist-txt,$(full_classes_jar),$(hiddenapi_whitelist_txt),$(hiddenapi_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)))
@@ -161,3 +162,5 @@
 	$(if $(PRIVATE_EXPORTED_SDK_LIBS),\
 		$(hide) echo $(PRIVATE_EXPORTED_SDK_LIBS) | tr ' ' '\n' > $@,\
 		$(hide) touch $@)
+
+SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
diff --git a/core/tasks/general-tests.mk b/core/tasks/general-tests.mk
index c7f1dc9..9619bbe 100644
--- a/core/tasks/general-tests.mk
+++ b/core/tasks/general-tests.mk
@@ -14,22 +14,38 @@
 
 .PHONY: general-tests
 
-general-tests-zip := $(PRODUCT_OUT)/general-tests.zip
+general_tests_tools := \
+    $(HOST_OUT_JAVA_LIBRARIES)/cts-tradefed.jar \
+    $(HOST_OUT_JAVA_LIBRARIES)/compatibility-host-util.jar \
+
+intermediates_dir := $(call intermediates-dir-for,PACKAGING,general-tests)
+general_tests_zip := $(PRODUCT_OUT)/general-tests.zip
 # Create an artifact to include a list of test config files in general-tests.
-general-tests-list-zip := $(PRODUCT_OUT)/general-tests_list.zip
-$(general-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(general-tests-list-zip)
-$(general-tests-zip) : PRIVATE_general_tests_list := $(PRODUCT_OUT)/general-tests_list
+general_tests_list_zip := $(PRODUCT_OUT)/general-tests_list.zip
+$(general_tests_zip) : PRIVATE_general_tests_list_zip := $(general_tests_list_zip)
+$(general_tests_zip) : .KATI_IMPLICIT_OUTPUTS := $(general_tests_list_zip)
+$(general_tests_zip) : PRIVATE_TOOLS := $(general_tests_tools)
+$(general_tests_zip) : PRIVATE_INTERMEDIATES_DIR := $(intermediates_dir)
+$(general_tests_zip) : $(COMPATIBILITY.general-tests.FILES) $(general_tests_tools) $(SOONG_ZIP)
+	rm -rf $(PRIVATE_INTERMEDIATES_DIR)
+	rm -f $@ $(PRIVATE_general_tests_list_zip)
+	mkdir -p $(PRIVATE_INTERMEDIATES_DIR) $(PRIVATE_INTERMEDIATES_DIR)/tools
+	echo $(sort $(COMPATIBILITY.general-tests.FILES)) | tr " " "\n" > $(PRIVATE_INTERMEDIATES_DIR)/list
+	grep $(HOST_OUT_TESTCASES) $(PRIVATE_INTERMEDIATES_DIR)/list > $(PRIVATE_INTERMEDIATES_DIR)/host.list || true
+	grep $(TARGET_OUT_TESTCASES) $(PRIVATE_INTERMEDIATES_DIR)/list > $(PRIVATE_INTERMEDIATES_DIR)/target.list || true
+	cp -fp $(PRIVATE_TOOLS) $(PRIVATE_INTERMEDIATES_DIR)/tools/
+	$(SOONG_ZIP) -d -o $@ \
+	  -P host -C $(PRIVATE_INTERMEDIATES_DIR) -D $(PRIVATE_INTERMEDIATES_DIR)/tools \
+	  -P host -C $(HOST_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/host.list \
+	  -P target -C $(PRODUCT_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/target.list
+	grep -e .*.config$$ $(PRIVATE_INTERMEDIATES_DIR)/host.list | sed s%$(HOST_OUT)%host%g > $(PRIVATE_INTERMEDIATES_DIR)/general-tests_list
+	grep -e .*.config$$ $(PRIVATE_INTERMEDIATES_DIR)/target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_INTERMEDIATES_DIR)/general-tests_list
+	$(SOONG_ZIP) -d -o $(PRIVATE_general_tests_list_zip) -C $(PRIVATE_INTERMEDIATES_DIR) -f $(PRIVATE_INTERMEDIATES_DIR)/general-tests_list
 
-$(general-tests-zip) : $(COMPATIBILITY.general-tests.FILES) $(SOONG_ZIP)
-	echo $(sort $(COMPATIBILITY.general-tests.FILES)) | tr " " "\n" > $@.list
-	grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true
-	grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
-	$(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list -P target -C $(PRODUCT_OUT) -l $@-target.list
-	rm -f $(PRIVATE_general_tests_list)
-	$(hide) grep -e .*.config$$ $@-host.list | sed s%$(HOST_OUT)%host%g > $(PRIVATE_general_tests_list)
-	$(hide) grep -e .*.config$$ $@-target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_general_tests_list)
-	$(hide) $(SOONG_ZIP) -d -o $(general-tests-list-zip) -C $(dir $@) -f $(PRIVATE_general_tests_list)
-	rm -f $@.list $@-host.list $@-target.list $(PRIVATE_general_tests_list)
+general-tests: $(general_tests_zip)
+$(call dist-for-goals, general-tests, $(general_tests_zip) $(general_tests_list_zip))
 
-general-tests: $(general-tests-zip)
-$(call dist-for-goals, general-tests, $(general-tests-zip) $(general-tests-list-zip))
+intermediates_dir :=
+general_tests_tools :=
+general_tests_zip :=
+general_tests_list_zip :=
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index 38149d7..37e4831 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -14,6 +14,7 @@
 			'"compatibility_suites": [$(foreach w,$(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES)),"$(w)", )], ' \
 			'"auto_test_config": [$(ALL_MODULES.$(m).auto_test_config)], ' \
 			'"module_name": ["$(ALL_MODULES.$(m).MODULE_NAME)"], ' \
+			'"test_config": [$(if $(ALL_MODULES.$(m).TEST_CONFIG),"$(ALL_MODULES.$(m).TEST_CONFIG)")], ' \
 			'},\n' \
 	 ) | sed -e 's/, *\]/]/g' -e 's/, *\}/ }/g' -e '$$s/,$$//' >> $@
 	$(hide) echo '}' >> $@
diff --git a/help.sh b/help.sh
index 3ecdbc2..be07344 100755
--- a/help.sh
+++ b/help.sh
@@ -40,7 +40,7 @@
                             Stands for "Vendor, NO Dependencies"
     pnod                    Quickly rebuild the product image from built packages
                             Stands for "Product, NO Dependencies"
-    psnod                   Quickly rebuild the product-services image from built packages
+    psnod                   Quickly rebuild the product_services image from built packages
                             Stands for "ProductServices, NO Dependencies"
     onod                    Quickly rebuild the odm image from built packages
                             Stands for "ODM, NO Dependencies"
diff --git a/target/board/generic/device.mk b/target/board/generic/device.mk
index 82c6657..a75bd07 100644
--- a/target/board/generic/device.mk
+++ b/target/board/generic/device.mk
@@ -25,14 +25,6 @@
     device/generic/goldfish/camera/media_codecs.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs.xml \
     hardware/libhardware_legacy/audio/audio_policy.conf:system/etc/audio_policy.conf
 
-# minimal configuration for audio policy.
-PRODUCT_COPY_FILES += \
-    frameworks/av/services/audiopolicy/config/audio_policy_configuration_generic.xml:system/etc/audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration.xml:system/etc/primary_audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:system/etc/r_submix_audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:system/etc/audio_policy_volumes.xml \
-    frameworks/av/services/audiopolicy/config/default_volume_tables.xml:system/etc/default_volume_tables.xml \
-
 # NFC:
 #   Provide default libnfc-nci.conf file for devices that does not have one in
 #   vendor/etc because aosp system image (of aosp_$arch products) is going to
diff --git a/target/board/generic_arm64/device.mk b/target/board/generic_arm64/device.mk
index c0fbdcd..8bd6a8b 100644
--- a/target/board/generic_arm64/device.mk
+++ b/target/board/generic_arm64/device.mk
@@ -24,14 +24,6 @@
     frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_video.xml \
     device/generic/goldfish/camera/media_codecs.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs.xml
 
-# minimal configuration for audio policy.
-PRODUCT_COPY_FILES += \
-    frameworks/av/services/audiopolicy/config/audio_policy_configuration_generic.xml:system/etc/audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration.xml:system/etc/primary_audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:system/etc/r_submix_audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:system/etc/audio_policy_volumes.xml \
-    frameworks/av/services/audiopolicy/config/default_volume_tables.xml:system/etc/default_volume_tables.xml \
-
 # NFC:
 #   Provide default libnfc-nci.conf file for devices that does not have one in
 #   vendor/etc because aosp system image (of aosp_$arch products) is going to
diff --git a/target/board/generic_x86/device.mk b/target/board/generic_x86/device.mk
index ecf8697..fa2d472 100644
--- a/target/board/generic_x86/device.mk
+++ b/target/board/generic_x86/device.mk
@@ -24,14 +24,6 @@
     frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
     device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml
 
-# minimal configuration for audio policy.
-PRODUCT_COPY_FILES += \
-    frameworks/av/services/audiopolicy/config/audio_policy_configuration_generic.xml:system/etc/audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration.xml:system/etc/primary_audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:system/etc/r_submix_audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:system/etc/audio_policy_volumes.xml \
-    frameworks/av/services/audiopolicy/config/default_volume_tables.xml:system/etc/default_volume_tables.xml \
-
 # NFC:
 #   Provide default libnfc-nci.conf file for devices that does not have one in
 #   vendor/etc because aosp system image (of aosp_$arch products) is going to
diff --git a/target/board/generic_x86_64/device.mk b/target/board/generic_x86_64/device.mk
index ecf8697..fa2d472 100755
--- a/target/board/generic_x86_64/device.mk
+++ b/target/board/generic_x86_64/device.mk
@@ -24,14 +24,6 @@
     frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
     device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml
 
-# minimal configuration for audio policy.
-PRODUCT_COPY_FILES += \
-    frameworks/av/services/audiopolicy/config/audio_policy_configuration_generic.xml:system/etc/audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration.xml:system/etc/primary_audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:system/etc/r_submix_audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:system/etc/audio_policy_volumes.xml \
-    frameworks/av/services/audiopolicy/config/default_volume_tables.xml:system/etc/default_volume_tables.xml \
-
 # NFC:
 #   Provide default libnfc-nci.conf file for devices that does not have one in
 #   vendor/etc because aosp system image (of aosp_$arch products) is going to
diff --git a/target/product/aosp_arm.mk b/target/product/aosp_arm.mk
index dc49498..f0752a8 100644
--- a/target/product/aosp_arm.mk
+++ b/target/product/aosp_arm.mk
@@ -21,16 +21,7 @@
 # - VNDK enforcement
 # - compatible property override enabled
 
-PRODUCT_PROPERTY_OVERRIDES += \
-	vendor.rild.libpath=/vendor/lib/libreference-ril.so
-
-# Note: the following lines need to stay at the beginning so that it can
-# take priority  and override the rules it inherit from other mk files
-# see copy file rules in core/Makefile
-PRODUCT_COPY_FILES += \
-    development/sys-img/advancedFeatures.ini.arm:advancedFeatures.ini \
-    prebuilts/qemu-kernel/arm64/3.18/kernel-qemu2:kernel-ranchu-64 \
-    device/generic/goldfish/fstab.ranchu.arm:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.ranchu
+-include device/generic/goldfish/arm32-vendor.mk
 
 include $(SRC_TARGET_DIR)/product/full.mk
 
diff --git a/target/product/aosp_arm64.mk b/target/product/aosp_arm64.mk
index 0d9e055..ab23111 100644
--- a/target/product/aosp_arm64.mk
+++ b/target/product/aosp_arm64.mk
@@ -21,21 +21,12 @@
 # - VNDK enforcement
 # - compatible property override enabled
 
-PRODUCT_PROPERTY_OVERRIDES += \
-	vendor.rild.libpath=/vendor/lib64/libreference-ril.so
-
 # This is a build configuration for a full-featured build of the
 # Open-Source part of the tree. It's geared toward a US-centric
 # build quite specifically for the emulator, and might not be
 # entirely appropriate to inherit from for on-device configurations.
 
-# Note: the following lines need to stay at the beginning so that it can
-# take priority  and override the rules it inherit from other mk files
-# see copy file rules in core/Makefile
-PRODUCT_COPY_FILES += \
-    development/sys-img/advancedFeatures.ini.arm:advancedFeatures.ini \
-    prebuilts/qemu-kernel/arm64/3.18/kernel-qemu2:kernel-ranchu \
-    device/generic/goldfish/fstab.ranchu.arm:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.ranchu
+-include device/generic/goldfish/arm64-vendor.mk
 
 # Copy different zygote settings for vendor.img to select by setting property
 # ro.zygote=zygote64_32 or ro.zygote=zygote32_64:
diff --git a/target/product/aosp_x86.mk b/target/product/aosp_x86.mk
index abaab5d..9d1b14b 100644
--- a/target/product/aosp_x86.mk
+++ b/target/product/aosp_x86.mk
@@ -21,17 +21,7 @@
 # - VNDK enforcement
 # - compatible property override enabled
 
-PRODUCT_PROPERTY_OVERRIDES += \
-	vendor.rild.libpath=/vendor/lib/libreference-ril.so
-
-# This is a build configuration for a full-featured build of the
-# Open-Source part of the tree. It's geared toward a US-centric
-# build quite specifically for the emulator, and might not be
-# entirely appropriate to inherit from for on-device configurations.
-PRODUCT_COPY_FILES += \
-    development/sys-img/advancedFeatures.ini:advancedFeatures.ini \
-    device/generic/goldfish/data/etc/encryptionkey.img:encryptionkey.img \
-    prebuilts/qemu-kernel/x86_64/4.9/kernel-qemu2:kernel-ranchu-64
+-include device/generic/goldfish/x86-vendor.mk
 
 include $(SRC_TARGET_DIR)/product/full_x86.mk
 
diff --git a/target/product/aosp_x86_64.mk b/target/product/aosp_x86_64.mk
index 2168740..b38c417 100644
--- a/target/product/aosp_x86_64.mk
+++ b/target/product/aosp_x86_64.mk
@@ -21,18 +21,12 @@
 # - VNDK enforcement
 # - compatible property override enabled
 
-PRODUCT_PROPERTY_OVERRIDES += \
-	vendor.rild.libpath=/vendor/lib64/libreference-ril.so
-
 # This is a build configuration for a full-featured build of the
 # Open-Source part of the tree. It's geared toward a US-centric
 # build quite specifically for the emulator, and might not be
 # entirely appropriate to inherit from for on-device configurations.
 
-PRODUCT_COPY_FILES += \
-    development/sys-img/advancedFeatures.ini:advancedFeatures.ini \
-    device/generic/goldfish/data/etc/encryptionkey.img:encryptionkey.img \
-    prebuilts/qemu-kernel/x86_64/4.9/kernel-qemu2:kernel-ranchu
+-include device/generic/goldfish/x86_64-vendor.mk
 
 # Copy different zygote settings for vendor.img to select by setting property
 # ro.zygote=zygote64_32 or ro.zygote=zygote32_64:
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index c2ea1de..832e509 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -27,6 +27,7 @@
     android.test.base \
     android.test.mock \
     android.test.runner \
+    apexd \
     applypatch \
     appops \
     app_process \
@@ -256,11 +257,6 @@
     framework_manifest.xml \
     framework_compatibility_matrix.xml \
 
-ifeq ($(PRODUCT_USE_FASTBOOTD), true)
-PRODUCT_PACKAGES += \
-    fastbootd
-endif
-
 ifeq ($(TARGET_CORE_JARS),)
 $(error TARGET_CORE_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
 endif
diff --git a/target/product/base_vendor.mk b/target/product/base_vendor.mk
index 28a04d6..1b25f27 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -25,12 +25,6 @@
     shell_and_utilities_recovery \
     watchdogd.recovery \
 
-ifeq ($(PRODUCT_USE_FASTBOOTD), true)
-PRODUCT_PACKAGES += \
-    android.hardware.boot@1.0-impl.recovery \
-    bootctrl.default.recovery
-endif
-
 # Base modules and settings for the vendor partition.
 PRODUCT_PACKAGES += \
     android.hardware.cas@1.0-service \
diff --git a/target/product/emulator.mk b/target/product/emulator.mk
index 78d8e92..f6e1011 100644
--- a/target/product/emulator.mk
+++ b/target/product/emulator.mk
@@ -18,151 +18,22 @@
 # emulator-related modules to PRODUCT_PACKAGES.
 #
 
-# Host modules
-PRODUCT_PACKAGES += \
-
-
 # Device modules
 PRODUCT_PACKAGES += \
-    egl.cfg \
-    gralloc.goldfish \
-    gralloc.goldfish.default \
-    gralloc.ranchu \
-    libGLESv1_CM_emulation \
-    lib_renderControl_enc \
-    libEGL_emulation \
     libGLES_android \
-    libGLESv2_enc \
-    libOpenglSystemCommon \
-    libGLESv2_emulation \
-    libGLESv1_enc \
-    libEGL_swiftshader \
-    libGLESv1_CM_swiftshader \
-    libGLESv2_swiftshader \
-    qemu-props \
-    camera.goldfish \
-    camera.goldfish.jpeg \
-    camera.ranchu \
-    camera.ranchu.jpeg \
-    gatekeeper.ranchu \
-    lights.goldfish \
-    gps.goldfish \
-    gps.ranchu \
-    fingerprint.goldfish \
-    sensors.goldfish \
-    audio.primary.goldfish \
-    audio.primary.goldfish_legacy \
-    android.hardware.audio@2.0-service \
-    android.hardware.wifi@1.0-service \
-    vibrator.goldfish \
-    power.goldfish \
-    power.ranchu \
-    fingerprint.ranchu \
-    android.hardware.biometrics.fingerprint@2.1-service \
-    sensors.ranchu \
-    android.hardware.graphics.composer@2.1-impl \
-    android.hardware.graphics.composer@2.1-service \
-    android.hardware.graphics.allocator@2.0-service \
-    android.hardware.graphics.allocator@2.0-impl \
-    android.hardware.graphics.mapper@2.0-impl \
-    hwcomposer.goldfish \
-    hwcomposer.ranchu \
-    sh_vendor \
     vintf \
-    toybox_vendor \
     CarrierConfig \
-    audio.primary.goldfish \
-    audio.r_submix.default \
-    local_time.default \
-    SdkSetup
-
-PRODUCT_PACKAGES += \
-    android.hardware.audio@2.0-impl \
-    android.hardware.audio.effect@2.0-impl \
-    android.hardware.broadcastradio@1.1-service \
-    android.hardware.broadcastradio@1.0-impl \
-    android.hardware.soundtrigger@2.0-impl
-
-PRODUCT_PACKAGES += \
-    android.hardware.keymaster@3.0-impl \
-    android.hardware.keymaster@3.0-service
-
-PRODUCT_PACKAGES += \
-    android.hardware.keymaster@4.0-strongbox-service
-
-PRODUCT_PACKAGES += \
-    android.hardware.gnss@1.0-service \
-    android.hardware.gnss@1.0-impl
-
-PRODUCT_PACKAGES += \
-    android.hardware.sensors@1.0-impl \
-    android.hardware.sensors@1.0-service
-
-PRODUCT_PACKAGES += \
-    android.hardware.drm@1.0-service \
-    android.hardware.drm@1.0-impl
-
-PRODUCT_PACKAGES += \
-    android.hardware.power@1.0-service \
-    android.hardware.power@1.0-impl
-
-PRODUCT_PACKAGES += \
-    camera.device@1.0-impl \
-    android.hardware.camera.provider@2.4-service \
-    android.hardware.camera.provider@2.4-impl \
-
-PRODUCT_PACKAGES += \
-    android.hardware.gatekeeper@1.0-impl \
-    android.hardware.gatekeeper@1.0-service
 
 # need this for gles libraries to load properly
 # after moving to /vendor/lib/
 PRODUCT_PACKAGES += \
     vndk-sp
 
-# WiFi
+# WiFi: system side
 PRODUCT_PACKAGES += \
-	createns \
-	dhcpclient \
-	dhcpserver \
-	execns \
-	hostapd \
 	ip \
-	ipv6proxy \
 	iw \
 	wificond \
-	wpa_supplicant \
-
-PRODUCT_COPY_FILES += \
-    device/generic/goldfish/data/etc/apns-conf.xml:data/misc/apns/apns-conf.xml \
-    device/generic/goldfish/init.ranchu-core.sh:$(TARGET_COPY_OUT_VENDOR)/bin/init.ranchu-core.sh \
-    device/generic/goldfish/init.ranchu-net.sh:$(TARGET_COPY_OUT_VENDOR)/bin/init.ranchu-net.sh \
-    device/generic/goldfish/wifi/init.wifi.sh:$(TARGET_COPY_OUT_VENDOR)/bin/init.wifi.sh \
-    device/generic/goldfish/init.ranchu.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.ranchu.rc \
-    device/generic/goldfish/fstab.ranchu:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.ranchu \
-    device/generic/goldfish/ueventd.ranchu.rc:$(TARGET_COPY_OUT_VENDOR)/ueventd.rc \
-    device/generic/goldfish/input/goldfish_rotary.idc:$(TARGET_COPY_OUT_VENDOR)/usr/idc/goldfish_rotary.idc \
-    device/generic/goldfish/manifest.xml:$(TARGET_COPY_OUT_VENDOR)/manifest.xml \
-    device/generic/goldfish/data/etc/permissions/privapp-permissions-goldfish.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/privapp-permissions-goldfish.xml \
-    device/generic/goldfish/data/etc/config.ini:config.ini \
-    device/generic/goldfish/wifi/simulated_hostapd.conf:$(TARGET_COPY_OUT_VENDOR)/etc/simulated_hostapd.conf \
-    device/generic/goldfish/wifi/wpa_supplicant.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/wpa_supplicant.conf \
-    device/generic/goldfish/wifi/WifiConfigStore.xml:data/misc/wifi/WifiConfigStore.xml \
-    frameworks/native/data/etc/android.hardware.wifi.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.xml \
-    device/generic/goldfish/data/etc/handheld_core_hardware.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/handheld_core_hardware.xml \
-    device/generic/goldfish/camera/media_profiles.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_profiles_V1_0.xml \
-    frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_audio.xml \
-    frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_telephony.xml \
-    device/generic/goldfish/camera/media_codecs_google_video.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_video.xml \
-    device/generic/goldfish/camera/media_codecs.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs.xml \
-    device/generic/goldfish/camera/media_codecs_performance.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_performance.xml \
-    frameworks/native/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.touchscreen.multitouch.jazzhand.xml \
-    frameworks/native/data/etc/android.hardware.camera.autofocus.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.autofocus.xml \
-    frameworks/native/data/etc/android.hardware.camera.full.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.full.xml \
-    frameworks/native/data/etc/android.hardware.fingerprint.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.fingerprint.xml \
-    frameworks/native/data/etc/android.software.autofill.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.autofill.xml \
-    frameworks/av/media/libeffects/data/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    device/generic/goldfish/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
 
 
 PRODUCT_PACKAGE_OVERLAYS := device/generic/goldfish/overlay
@@ -171,6 +42,9 @@
 
 PRODUCT_FULL_TREBLE_OVERRIDE := true
 
+# goldfish vendor partition configurations
+$(call inherit-product-if-exists, device/generic/goldfish/vendor.mk)
+
 #watchdog tiggers reboot because location service is not
 #responding, disble it for now.
 #still keep it on internal master as it is still working
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index 274b2c8..3581c4a 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -18,6 +18,11 @@
 # device with no telephony.
 $(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk)
 
+# OTA support.
+PRODUCT_PACKAGES += \
+    update_engine \
+    update_verifier \
+
 # Enable dynamic partition size
 PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
 
@@ -25,35 +30,7 @@
 PRODUCT_BRAND := generic
 PRODUCT_SHIPPING_API_LEVEL := 28
 
-_base_mk_whitelist := \
-  recovery/root/etc/mke2fs.conf \
-
-ifeq ($(PRODUCT_USE_FASTBOOTD), true)
-  _base_mk_whitelist += \
-    recovery/root/system/bin/fastbootd \
-    recovery/root/system/lib64/android.hardware.boot@1.0.so \
-    recovery/root/system/lib64/hw/bootctrl.default.so \
-    recovery/root/system/lib64/libadbd.so \
-    recovery/root/system/lib64/libadbd_services.so \
-    recovery/root/system/lib64/libasyncio.so \
-    recovery/root/system/lib64/libbootloader_message.so \
-    recovery/root/system/lib64/libcrypto_utils.so \
-    recovery/root/system/lib64/libext2_uuid.so \
-    recovery/root/system/lib64/libext4_utils.so \
-    recovery/root/system/lib64/libfec.so \
-    recovery/root/system/lib64/libfec_rs.so \
-    recovery/root/system/lib64/libfs_mgr.so \
-    recovery/root/system/lib64/libhidlbase.so \
-    recovery/root/system/lib64/libhidltransport.so \
-    recovery/root/system/lib64/libhwbinder.so \
-    recovery/root/system/lib64/libkeyutils.so \
-    recovery/root/system/lib64/liblogwrap.so \
-    recovery/root/system/lib64/liblp.so \
-    recovery/root/system/lib64/libmdnssd.so \
-    recovery/root/system/lib64/libsparse.so \
-    recovery/root/system/lib64/libsquashfs_utils.so \
-    recovery/root/system/lib64/libutils.so
-endif
+_base_mk_whitelist :=
 
 _my_whitelist := $(_base_mk_whitelist)
 
diff --git a/target/product/treble_common.mk b/target/product/treble_common.mk
index a217390..6b0ef2f 100644
--- a/target/product/treble_common.mk
+++ b/target/product/treble_common.mk
@@ -34,15 +34,6 @@
 PRODUCT_PACKAGES += \
     messaging
 
-# The following policy XML files are used as fallback for
-# vendors/devices not using XML to configure audio policy.
-PRODUCT_COPY_FILES += \
-    frameworks/av/services/audiopolicy/config/audio_policy_configuration_generic.xml:system/etc/audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration.xml:system/etc/primary_audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:system/etc/r_submix_audio_policy_configuration.xml \
-    frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:system/etc/audio_policy_volumes.xml \
-    frameworks/av/services/audiopolicy/config/default_volume_tables.xml:system/etc/default_volume_tables.xml \
-
 # Telephony:
 #   Provide a default APN configuration
 PRODUCT_COPY_FILES += \
diff --git a/tools/OWNERS b/tools/OWNERS
index 7a23adc..7d666f1 100644
--- a/tools/OWNERS
+++ b/tools/OWNERS
@@ -1,2 +1 @@
-per-file warn.py = chh@google.com
-per-file checkowners.py = chh@google.com
+per-file warn.py,checkowners.py = chh@google.com
diff --git a/tools/device_buildinfo.sh b/tools/buildinfo_common.sh
similarity index 64%
rename from tools/device_buildinfo.sh
rename to tools/buildinfo_common.sh
index 0782565..f7f798c 100755
--- a/tools/device_buildinfo.sh
+++ b/tools/buildinfo_common.sh
@@ -3,32 +3,27 @@
 partition="$1"
 
 if [ "$#" -ne 1 ]; then
-  echo "Usage: $0 <vendor|odm>" 1>&2
+  echo "Usage: $0 <partition>" 1>&2
   exit 1
 fi
 
-if [ "$partition" != "vendor" ] && [ "$partition" != "odm" ]; then
-  echo "Unknown partition name: $partition" 1>&2
-  exit 1
-fi
+echo "# begin common build properties"
+echo "# autogenerated by $0"
 
-echo "# begin build properties"
-echo "# autogenerated by device_buildinfo.sh"
-
+echo "ro.${partition}.build.date=`$DATE`"
+echo "ro.${partition}.build.date.utc=`$DATE +%s`"
+echo "ro.${partition}.build.fingerprint=$BUILD_FINGERPRINT"
 echo "ro.${partition}.build.id=$BUILD_ID"
-echo "ro.${partition}.build.version.incremental=$BUILD_NUMBER"
-echo "ro.${partition}.build.version.sdk=$PLATFORM_SDK_VERSION"
-echo "ro.${partition}.build.version.release=$PLATFORM_VERSION"
-echo "ro.${partition}.build.type=$TARGET_BUILD_TYPE"
 echo "ro.${partition}.build.tags=$BUILD_VERSION_TAGS"
+echo "ro.${partition}.build.type=$TARGET_BUILD_TYPE"
+echo "ro.${partition}.build.version.incremental=$BUILD_NUMBER"
+echo "ro.${partition}.build.version.release=$PLATFORM_VERSION"
+echo "ro.${partition}.build.version.sdk=$PLATFORM_SDK_VERSION"
 
-echo "ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"
-echo "ro.board.platform=$TARGET_BOARD_PLATFORM"
-
+echo "ro.product.${partition}.brand=$PRODUCT_BRAND"
+echo "ro.product.${partition}.device=$TARGET_DEVICE"
 echo "ro.product.${partition}.manufacturer=$PRODUCT_MANUFACTURER"
 echo "ro.product.${partition}.model=$PRODUCT_MODEL"
-echo "ro.product.${partition}.brand=$PRODUCT_BRAND"
 echo "ro.product.${partition}.name=$PRODUCT_NAME"
-echo "ro.product.${partition}.device=$TARGET_DEVICE"
 
-echo "# end build properties"
+echo "# end common build properties"
diff --git a/tools/checkowners.py b/tools/checkowners.py
index 54198a7..8568ccf 100755
--- a/tools/checkowners.py
+++ b/tools/checkowners.py
@@ -35,22 +35,31 @@
     echo('Checking email address: ' + address)
     result = urllib2.urlopen(request).read()
     checked_addresses[address] = result.find('"_account_id":') >= 0
+    if checked_addresses[address]:
+      echo('Found email address: ' + address)
   return checked_addresses[address]
 
 
+def check_address(fname, num, address):
+  if find_address(address):
+    return 0
+  print '%s:%d: ERROR: unknown email address: %s' % (fname, num, address)
+  return 1
+
+
 def main():
   # One regular expression to check all valid lines.
   noparent = 'set +noparent'
   email = '([^@ ]+@[^ @]+|\\*)'
-  directive = '(%s|%s)' % (email, noparent)
+  emails = '(%s( *, *%s)*)' % (email, email)
+  directive = '(%s|%s)' % (emails, noparent)
   glob = '[a-zA-Z0-9_\\.\\-\\*\\?]+'
-  perfile = 'per-file +' + glob + ' *= *' + directive
+  globs = '(%s( *, *%s)*)' % (glob, glob)
+  perfile = 'per-file +' + globs + ' *= *' + directive
   pats = '(|%s|%s|%s)$' % (noparent, email, perfile)
   patterns = re.compile(pats)
-
-  # One pattern to capture email address.
-  email_address = '.*(@| |=|^)([^@ =]+@[^ @]+)'
-  address_pattern = re.compile(email_address)
+  address_pattern = re.compile('([^@ ]+@[^ @]+)')
+  perfile_pattern = re.compile('per-file +.*=(.*)')
 
   error = 0
   for fname in args.owners:
@@ -60,17 +69,16 @@
       num += 1
       stripped_line = re.sub('#.*$', '', line).strip()
       if not patterns.match(stripped_line):
-        error = 1
-        print('%s:%d: ERROR: unknown line [%s]'
-              % (fname, num, line.strip()))
-      elif args.check_address and address_pattern.match(stripped_line):
-        address = address_pattern.match(stripped_line).group(2)
-        if find_address(address):
-          echo('Found email address: ' + address)
-        else:
-          error = 1
-          print('%s:%d: ERROR: unknown email address: %s'
-                % (fname, num, address))
+        error += 1
+        print '%s:%d: ERROR: unknown line [%s]' % (fname, num, line.strip())
+      elif args.check_address:
+        if perfile_pattern.match(stripped_line):
+          for addr in perfile_pattern.match(stripped_line).group(1).split(','):
+            a = addr.strip()
+            if a and a != '*':
+              error += check_address(fname, num, addr.strip())
+        elif address_pattern.match(stripped_line):
+          error += check_address(fname, num, stripped_line)
   sys.exit(error)
 
 if __name__ == '__main__':
diff --git a/tools/generate-notice-files.py b/tools/generate-notice-files.py
index b754174..49011b2 100755
--- a/tools/generate-notice-files.py
+++ b/tools/generate-notice-files.py
@@ -238,12 +238,14 @@
             if len(included_subdirs) > 0:
                 matched = False
                 for subdir in included_subdirs:
-                    if root.startswith(input_dir + '/' + subdir):
+                    if (root == (input_dir + '/' + subdir) or
+                        root.startswith(input_dir + '/' + subdir + '/')):
                         matched = True
                         break
             elif len(excluded_subdirs) > 0:
                 for subdir in excluded_subdirs:
-                    if root.startswith(input_dir + '/' + subdir):
+                    if (root == (input_dir + '/' + subdir) or
+                        root.startswith(input_dir + '/' + subdir + '/')):
                         matched = False
                         break
             if matched and file.endswith(".txt"):
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 22e7f4b..e47c038 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -73,12 +73,13 @@
 OPTIONS.is_signing = False
 
 # Partitions that should have their care_map added to META/care_map.txt.
-PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'product-services',
+PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'product_services',
                             'odm')
 # Use a fixed timestamp (01/01/2009 00:00:00 UTC) for files when packaging
 # images. (b/24377993, b/80600931)
-FIXED_FILE_TIMESTAMP = (datetime.datetime(2009, 1, 1, 0, 0, 0, 0, None)
-                        - datetime.datetime.utcfromtimestamp(0)).total_seconds()
+FIXED_FILE_TIMESTAMP = int((
+    datetime.datetime(2009, 1, 1, 0, 0, 0, 0, None) -
+    datetime.datetime.utcfromtimestamp(0)).total_seconds())
 
 
 class OutputFile(object):
@@ -98,6 +99,7 @@
     if self._output_zip:
       common.ZipWrite(self._output_zip, self.name, self._zip_name)
 
+
 def GetCareMap(which, imgname):
   """Returns the care_map string for the given partition.
 
@@ -200,19 +202,19 @@
 
 
 def AddProductServices(output_zip):
-  """Turn the contents of PRODUCT_SERVICES into a product-services image and
+  """Turn the contents of PRODUCT_SERVICES into a product_services image and
   store it in output_zip."""
 
   img = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES",
-                   "product-services.img")
+                   "product_services.img")
   if os.path.exists(img.input_name):
-    print("product-services.img already exists; no need to rebuild...")
+    print("product_services.img already exists; no need to rebuild...")
     return img.input_name
 
   block_list = OutputFile(
-      output_zip, OPTIONS.input_tmp, "IMAGES", "product-services.map")
+      output_zip, OPTIONS.input_tmp, "IMAGES", "product_services.map")
   CreateImage(
-      OPTIONS.input_tmp, OPTIONS.info_dict, "product-services", img,
+      OPTIONS.input_tmp, OPTIONS.info_dict, "product_services", img,
       block_list=block_list)
   return img.name
 
@@ -666,10 +668,10 @@
 
   has_recovery = OPTIONS.info_dict.get("no_recovery") != "true"
 
-  # {vendor,odm,product,product-services}.img are unlike system.img or
+  # {vendor,odm,product,product_services}.img are unlike system.img or
   # system_other.img. Because it could be built from source, or dropped into
   # target_files.zip as a prebuilt blob. We consider either of them as
-  # {vendor,product,product-services}.img being available, which could be
+  # {vendor,product,product_services}.img being available, which could be
   # used when generating vbmeta.img for AVB.
   has_vendor = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR")) or
                 os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
@@ -684,7 +686,7 @@
                                                      "PRODUCT_SERVICES")) or
                           os.path.exists(os.path.join(OPTIONS.input_tmp,
                                                       "IMAGES",
-                                                      "product-services.img")))
+                                                      "product_services.img")))
   has_system_other = os.path.isdir(os.path.join(OPTIONS.input_tmp,
                                                 "SYSTEM_OTHER"))
 
@@ -762,8 +764,8 @@
     partitions['product'] = AddProduct(output_zip)
 
   if has_product_services:
-    banner("product-services")
-    partitions['product-services'] = AddProductServices(output_zip)
+    banner("product_services")
+    partitions['product_services'] = AddProductServices(output_zip)
 
   if has_odm:
     banner("odm")
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 86ba1a6..3e159a6 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -428,9 +428,8 @@
 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.
+  When building system.img for all targets, 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.
@@ -441,8 +440,12 @@
     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"):
+
+  if prop_dict["mount_point"] == "system_other":
+    prop_dict["mount_point"] = "system"
+    return origin_in, fs_config
+
+  if prop_dict["mount_point"] != "system":
     return origin_in, fs_config
 
   # Construct a staging directory of the root file system.
@@ -516,9 +519,6 @@
 def BuildImage(in_dir, prop_dict, out_file, target_out=None):
   """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 to input directory.
     prop_dict: A property dict that contains info like partition size. Values
@@ -838,7 +838,6 @@
   elif mount_point == "system_other":
     # We inherit the selinux policies of /system since we contain some of its
     # files.
-    d["mount_point"] = "system"
     copy_prop("avb_system_hashtree_enable", "avb_hashtree_enable")
     copy_prop("avb_system_add_hashtree_footer_args",
               "avb_add_hashtree_footer_args")
@@ -909,7 +908,7 @@
     if not copy_prop("product_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
     copy_prop("product_reserved_size", "partition_reserved_size")
-  elif mount_point == "product-services":
+  elif mount_point == "product_services":
     copy_prop("avb_product_services_hashtree_enable", "avb_hashtree_enable")
     copy_prop("avb_product_services_add_hashtree_footer_args",
               "avb_add_hashtree_footer_args")
@@ -1000,7 +999,7 @@
     copy_prop(size_property, "odm_size")
   elif mount_point == "product":
     copy_prop(size_property, "product_size")
-  elif mount_point == "product-services":
+  elif mount_point == "product_services":
     copy_prop(size_property, "product_services_size")
   return d
 
@@ -1045,8 +1044,8 @@
       mount_point = "oem"
     elif image_filename == "product.img":
       mount_point = "product"
-    elif image_filename == "product-services.img":
-      mount_point = "product-services"
+    elif image_filename == "product_services.img":
+      mount_point = "product_services"
     else:
       print("error: unknown image file name ", image_filename, file=sys.stderr)
       sys.exit(1)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index bf380bc..227d701 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -79,7 +79,7 @@
 
 # The partitions allowed to be signed by AVB (Android verified boot 2.0).
 AVB_PARTITIONS = ('boot', 'recovery', 'system', 'vendor', 'product',
-                  'product-services', 'dtbo', 'odm')
+                  'product_services', 'dtbo', 'odm')
 
 
 class ErrorCode(object):
@@ -181,26 +181,18 @@
   if input_dir is not None:
     # We carry a copy of file_contexts.bin under META/. If not available,
     # search BOOT/RAMDISK/. Note that sometimes we may need a different file
-    # to build images than the one running on device, such as when enabling
-    # system_root_image. In that case, we must have the one for image
-    # generation copied to META/.
+    # to build images than the one running on device, in that case, we must
+    # have the one for image generation copied to META/.
     fc_basename = os.path.basename(d.get("selinux_fc", "file_contexts"))
     fc_config = os.path.join(input_dir, "META", fc_basename)
-    if d.get("system_root_image") == "true":
-      assert os.path.exists(fc_config)
-    if not os.path.exists(fc_config):
-      fc_config = os.path.join(input_dir, "BOOT", "RAMDISK", fc_basename)
-      if not os.path.exists(fc_config):
-        fc_config = None
+    assert os.path.exists(fc_config)
 
-    if fc_config:
-      d["selinux_fc"] = fc_config
+    d["selinux_fc"] = fc_config
 
-    # Similarly we need to redirect "root_dir" and "root_fs_config".
-    if d.get("system_root_image") == "true":
-      d["root_dir"] = os.path.join(input_dir, "ROOT")
-      d["root_fs_config"] = os.path.join(
-          input_dir, "META", "root_filesystem_config.txt")
+    # Similarly we need to redirect "root_dir", and "root_fs_config".
+    d["root_dir"] = os.path.join(input_dir, "ROOT")
+    d["root_fs_config"] = os.path.join(
+        input_dir, "META", "root_filesystem_config.txt")
 
     # Redirect {system,vendor}_base_fs_file.
     if "system_base_fs_file" in d:
@@ -237,15 +229,35 @@
   makeint("boot_size")
   makeint("fstab_version")
 
+  # We changed recovery.fstab path in Q, from ../RAMDISK/etc/recovery.fstab to
+  # ../RAMDISK/system/etc/recovery.fstab. LoadInfoDict() has to handle both
+  # cases, since it may load the info_dict from an old build (e.g. when
+  # generating incremental OTAs from that build).
   system_root_image = d.get("system_root_image") == "true"
   if d.get("no_recovery") != "true":
-    recovery_fstab_path = "RECOVERY/RAMDISK/etc/recovery.fstab"
+    recovery_fstab_path = "RECOVERY/RAMDISK/system/etc/recovery.fstab"
+    if isinstance(input_file, zipfile.ZipFile):
+      if recovery_fstab_path not in input_file.namelist():
+        recovery_fstab_path = "RECOVERY/RAMDISK/etc/recovery.fstab"
+    else:
+      path = os.path.join(input_file, *recovery_fstab_path.split("/"))
+      if not os.path.exists(path):
+        recovery_fstab_path = "RECOVERY/RAMDISK/etc/recovery.fstab"
     d["fstab"] = LoadRecoveryFSTab(
         read_helper, d["fstab_version"], recovery_fstab_path, system_root_image)
+
   elif d.get("recovery_as_boot") == "true":
-    recovery_fstab_path = "BOOT/RAMDISK/etc/recovery.fstab"
+    recovery_fstab_path = "BOOT/RAMDISK/system/etc/recovery.fstab"
+    if isinstance(input_file, zipfile.ZipFile):
+      if recovery_fstab_path not in input_file.namelist():
+        recovery_fstab_path = "BOOT/RAMDISK/etc/recovery.fstab"
+    else:
+      path = os.path.join(input_file, *recovery_fstab_path.split("/"))
+      if not os.path.exists(path):
+        recovery_fstab_path = "BOOT/RAMDISK/etc/recovery.fstab"
     d["fstab"] = LoadRecoveryFSTab(
         read_helper, d["fstab_version"], recovery_fstab_path, system_root_image)
+
   else:
     d["fstab"] = None
 
@@ -693,15 +705,14 @@
     if not entry.startswith('/'):
       continue
 
-    # "/system/framework/am.jar" => "SYSTEM/framework/am.jar". Note that when
-    # using system_root_image, the filename listed in system.map may contain an
-    # additional leading slash (i.e. "//system/framework/am.jar"). Using lstrip
-    # to get consistent results.
+    # "/system/framework/am.jar" => "SYSTEM/framework/am.jar". Note that the
+    # filename listed in system.map may contain an additional leading slash
+    # (i.e. "//system/framework/am.jar"). Using lstrip to get consistent
+    # results.
     arcname = string.replace(entry, which, which.upper(), 1).lstrip('/')
 
-    # Special handling another case with system_root_image, where files not
-    # under /system (e.g. "/sbin/charger") are packed under ROOT/ in a
-    # target_files.zip.
+    # Special handling another case, where files not under /system
+    # (e.g. "/sbin/charger") are packed under ROOT/ in a target_files.zip.
     if which == 'system' and not arcname.startswith('SYSTEM'):
       arcname = 'ROOT/' + arcname
 
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 47e61da..9ad3f6b 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -1096,7 +1096,9 @@
     def ComputeEntryOffsetSize(name):
       """Computes the zip entry offset and size."""
       info = zip_file.getinfo(name)
-      offset = info.header_offset + len(info.FileHeader())
+      offset = info.header_offset
+      offset += zipfile.sizeFileHeader
+      offset += len(info.extra) + len(info.filename)
       size = info.file_size
       return '%s:%d:%d' % (os.path.basename(name), offset, size)
 
@@ -1220,7 +1222,9 @@
     payload, till the end of 'medatada_signature_message'.
     """
     payload_info = input_zip.getinfo('payload.bin')
-    payload_offset = payload_info.header_offset + len(payload_info.FileHeader())
+    payload_offset = payload_info.header_offset
+    payload_offset += zipfile.sizeFileHeader
+    payload_offset += len(payload_info.extra) + len(payload_info.filename)
     payload_size = payload_info.file_size
 
     with input_zip.open('payload.bin', 'r') as payload_fp:
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 393c33d..cb0c268 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -370,13 +370,14 @@
       OPTIONS.rebuild_recovery = True
 
     # Don't copy OTA keys if we're replacing them.
-    elif (OPTIONS.replace_ota_keys and
-          filename in (
-              "BOOT/RAMDISK/res/keys",
-              "BOOT/RAMDISK/etc/update_engine/update-payload-key.pub.pem",
-              "RECOVERY/RAMDISK/res/keys",
-              "SYSTEM/etc/security/otacerts.zip",
-              "SYSTEM/etc/update_engine/update-payload-key.pub.pem")):
+    elif (
+        OPTIONS.replace_ota_keys and
+        filename in (
+            "BOOT/RAMDISK/res/keys",
+            "BOOT/RAMDISK/system/etc/update_engine/update-payload-key.pub.pem",
+            "RECOVERY/RAMDISK/res/keys",
+            "SYSTEM/etc/security/otacerts.zip",
+            "SYSTEM/etc/update_engine/update-payload-key.pub.pem")):
       pass
 
     # Skip META/misc_info.txt since we will write back the new values later.
@@ -596,8 +597,8 @@
   if p.returncode != 0:
     raise common.ExternalError("failed to run dumpkeys")
 
-  # system_root_image puts the recovery keys at BOOT/RAMDISK.
-  if misc_info.get("system_root_image") == "true":
+  if (misc_info.get("system_root_image") == "true" and
+      misc_info.get("recovery_as_boot") == "true"):
     recovery_keys_location = "BOOT/RAMDISK/res/keys"
   else:
     recovery_keys_location = "RECOVERY/RAMDISK/res/keys"
@@ -635,7 +636,7 @@
         pubkey)
     common.ZipWriteStr(
         output_tf_zip,
-        "BOOT/RAMDISK/etc/update_engine/update-payload-key.pub.pem",
+        "BOOT/RAMDISK/system/etc/update_engine/update-payload-key.pub.pem",
         pubkey)
 
   return new_recovery_keys
diff --git a/tools/releasetools/test_build_image.py b/tools/releasetools/test_build_image.py
index 19b5e08..c91d00d 100644
--- a/tools/releasetools/test_build_image.py
+++ b/tools/releasetools/test_build_image.py
@@ -96,16 +96,6 @@
     }
     self.assertFalse(CheckHeadroom(ext4fs_output, prop_dict))
 
-  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',
@@ -124,7 +114,7 @@
       fs_config_fp.write('fs-config-{}\n'.format(partition))
     return fs_config
 
-  def test_SetUpInDirAndFsConfig_SystemRootImageTrue(self):
+  def test_SetUpInDirAndFsConfig(self):
     root_dir = common.MakeTempDir()
     with open(os.path.join(root_dir, 'init'), 'w') as init_fp:
       init_fp.write('init')
@@ -140,7 +130,6 @@
         '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)
 
@@ -154,7 +143,7 @@
     self.assertTrue(filecmp.cmp(fs_config_system, fs_config))
     self.assertEqual('/', prop_dict['mount_point'])
 
-  def test_SetUpInDirAndFsConfig_SystemRootImageTrue_WithRootFsConfig(self):
+  def test_SetUpInDirAndFsConfig_WithRootFsConfig(self):
     root_dir = common.MakeTempDir()
     with open(os.path.join(root_dir, 'init'), 'w') as init_fp:
       init_fp.write('init')
@@ -172,7 +161,6 @@
         '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)
 
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 2a28db4..f56f368 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -14,6 +14,7 @@
 # limitations under the License.
 #
 
+import copy
 import os
 import subprocess
 import tempfile
@@ -783,6 +784,120 @@
     self.assertRaises(
         AssertionError, common.GetAvbChainedPartitionArg, 'system', info_dict)
 
+  INFO_DICT_DEFAULT = {
+      'recovery_api_version': 3,
+      'fstab_version': 2,
+      'system_root_image': 'true',
+      'no_recovery' : 'true',
+      'recovery_as_boot': 'true',
+  }
+
+  @staticmethod
+  def _test_LoadInfoDict_createTargetFiles(info_dict, fstab_path):
+    target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
+    with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+      info_values = ''.join(
+          ['{}={}\n'.format(k, v) for k, v in sorted(info_dict.iteritems())])
+      common.ZipWriteStr(target_files_zip, 'META/misc_info.txt', info_values)
+
+      FSTAB_TEMPLATE = "/dev/block/system {} ext4 ro,barrier=1 defaults"
+      if info_dict.get('system_root_image') == 'true':
+        fstab_values = FSTAB_TEMPLATE.format('/')
+      else:
+        fstab_values = FSTAB_TEMPLATE.format('/system')
+      common.ZipWriteStr(target_files_zip, fstab_path, fstab_values)
+    return target_files
+
+  def test_LoadInfoDict(self):
+    target_files = self._test_LoadInfoDict_createTargetFiles(
+        self.INFO_DICT_DEFAULT,
+        'BOOT/RAMDISK/system/etc/recovery.fstab')
+    with zipfile.ZipFile(target_files, 'r') as target_files_zip:
+      loaded_dict = common.LoadInfoDict(target_files_zip)
+      self.assertEqual(3, loaded_dict['recovery_api_version'])
+      self.assertEqual(2, loaded_dict['fstab_version'])
+      self.assertIn('/', loaded_dict['fstab'])
+      self.assertIn('/system', loaded_dict['fstab'])
+
+  def test_LoadInfoDict_legacyRecoveryFstabPath(self):
+    target_files = self._test_LoadInfoDict_createTargetFiles(
+        self.INFO_DICT_DEFAULT,
+        'BOOT/RAMDISK/etc/recovery.fstab')
+    with zipfile.ZipFile(target_files, 'r') as target_files_zip:
+      loaded_dict = common.LoadInfoDict(target_files_zip)
+      self.assertEqual(3, loaded_dict['recovery_api_version'])
+      self.assertEqual(2, loaded_dict['fstab_version'])
+      self.assertIn('/', loaded_dict['fstab'])
+      self.assertIn('/system', loaded_dict['fstab'])
+
+  def test_LoadInfoDict_dirInput(self):
+    target_files = self._test_LoadInfoDict_createTargetFiles(
+        self.INFO_DICT_DEFAULT,
+        'BOOT/RAMDISK/system/etc/recovery.fstab')
+    unzipped = common.UnzipTemp(target_files)
+    loaded_dict = common.LoadInfoDict(unzipped)
+    self.assertEqual(3, loaded_dict['recovery_api_version'])
+    self.assertEqual(2, loaded_dict['fstab_version'])
+    self.assertIn('/', loaded_dict['fstab'])
+    self.assertIn('/system', loaded_dict['fstab'])
+
+  def test_LoadInfoDict_dirInput_legacyRecoveryFstabPath(self):
+    target_files = self._test_LoadInfoDict_createTargetFiles(
+        self.INFO_DICT_DEFAULT,
+        'BOOT/RAMDISK/system/etc/recovery.fstab')
+    unzipped = common.UnzipTemp(target_files)
+    loaded_dict = common.LoadInfoDict(unzipped)
+    self.assertEqual(3, loaded_dict['recovery_api_version'])
+    self.assertEqual(2, loaded_dict['fstab_version'])
+    self.assertIn('/', loaded_dict['fstab'])
+    self.assertIn('/system', loaded_dict['fstab'])
+
+  def test_LoadInfoDict_systemRootImageFalse(self):
+    # Devices not using system-as-root nor recovery-as-boot. Non-A/B devices
+    # launched prior to P will likely have this config.
+    info_dict = copy.copy(self.INFO_DICT_DEFAULT)
+    del info_dict['no_recovery']
+    del info_dict['system_root_image']
+    del info_dict['recovery_as_boot']
+    target_files = self._test_LoadInfoDict_createTargetFiles(
+        info_dict,
+        'RECOVERY/RAMDISK/system/etc/recovery.fstab')
+    with zipfile.ZipFile(target_files, 'r') as target_files_zip:
+      loaded_dict = common.LoadInfoDict(target_files_zip)
+      self.assertEqual(3, loaded_dict['recovery_api_version'])
+      self.assertEqual(2, loaded_dict['fstab_version'])
+      self.assertNotIn('/', loaded_dict['fstab'])
+      self.assertIn('/system', loaded_dict['fstab'])
+
+  def test_LoadInfoDict_recoveryAsBootFalse(self):
+    # Devices using system-as-root, but with standalone recovery image. Non-A/B
+    # devices launched since P will likely have this config.
+    info_dict = copy.copy(self.INFO_DICT_DEFAULT)
+    del info_dict['no_recovery']
+    del info_dict['recovery_as_boot']
+    target_files = self._test_LoadInfoDict_createTargetFiles(
+        info_dict,
+        'RECOVERY/RAMDISK/system/etc/recovery.fstab')
+    with zipfile.ZipFile(target_files, 'r') as target_files_zip:
+      loaded_dict = common.LoadInfoDict(target_files_zip)
+      self.assertEqual(3, loaded_dict['recovery_api_version'])
+      self.assertEqual(2, loaded_dict['fstab_version'])
+      self.assertIn('/', loaded_dict['fstab'])
+      self.assertIn('/system', loaded_dict['fstab'])
+
+  def test_LoadInfoDict_noRecoveryTrue(self):
+    # Device doesn't have a recovery partition at all.
+    info_dict = copy.copy(self.INFO_DICT_DEFAULT)
+    del info_dict['recovery_as_boot']
+    target_files = self._test_LoadInfoDict_createTargetFiles(
+        info_dict,
+        'RECOVERY/RAMDISK/system/etc/recovery.fstab')
+    with zipfile.ZipFile(target_files, 'r') as target_files_zip:
+      loaded_dict = common.LoadInfoDict(target_files_zip)
+      self.assertEqual(3, loaded_dict['recovery_api_version'])
+      self.assertEqual(2, loaded_dict['fstab_version'])
+      self.assertIsNone(loaded_dict['fstab'])
+
 
 class InstallRecoveryScriptFormatTest(unittest.TestCase):
   """Checks the format of install-recovery.sh.