Merge "Add build script to generate TF test XML file with filters"
diff --git a/Changes.md b/Changes.md
new file mode 100644
index 0000000..53ff007
--- /dev/null
+++ b/Changes.md
@@ -0,0 +1,106 @@
+# Build System Changes for Android.mk Writers
+
+## Deprecating / obsoleting envsetup.sh variables in Makefiles
+
+It is not required to source envsetup.sh before running a build. Many scripts,
+including a majority of our automated build systems, do not do so. Make will
+transparently make every environment variable available as a make variable.
+This means that relying on environment variables only set up in envsetup.sh will
+produce different output for local users and scripted users.
+
+Many of these variables also include absolute path names, which we'd like to
+keep out of the generated files, so that you don't need to do a full rebuild if
+you move the source tree.
+
+To fix this, we're marking the variables that are set in envsetup.sh as
+deprecated in the makefiles. This will trigger a warning every time one is read
+(or written) inside Kati. Once all the warnings have been removed for a
+particular variable, we'll switch it to obsolete, and any references will become
+errors.
+
+### envsetup.sh variables with make equivalents
+
+| instead of                                                   | use                  |
+|--------------------------------------------------------------|----------------------|
+| OUT {#OUT}                                                   | OUT_DIR              |
+| ANDROID_HOST_OUT {#ANDROID_HOST_OUT}                         | HOST_OUT             |
+| ANDROID_PRODUCT_OUT {#ANDROID_PRODUCT_OUT}                   | PRODUCT_OUT          |
+| ANDROID_HOST_OUT_TESTCASES {#ANDROID_HOST_OUT_TESTCASES}     | HOST_OUT_TESTCASES   |
+| ANDROID_TARGET_OUT_TESTCASES {#ANDROID_TARGET_OUT_TESTCASES} | TARGET_OUT_TESTCASES |
+
+All of the make variables may be relative paths from the current directory, or
+absolute paths if the output directory was specified as an absolute path. If you
+need an absolute variable, convert it to absolute during a rule, so that it's
+not expanded into the generated ninja file:
+
+``` make
+$(PRODUCT_OUT)/gen.img: my/src/path/gen.sh
+	export PRODUCT_OUT=$$(cd $(PRODUCT_OUT); pwd); cd my/src/path; ./gen.sh -o $${PRODUCT_OUT}/gen.img
+```
+
+### ANDROID_BUILD_TOP  {#ANDROID_BUILD_TOP}
+
+In Android.mk files, you can always assume that the current directory is the
+root of the source tree, so this can just be replaced with '.' (which is what
+$TOP is hardcoded to), or removed entirely. If you need an absolute path, see
+the instructions above.
+
+### Stop using PATH directly  {#PATH}
+
+This isn't only set by envsetup.sh, but it is modified by it. Due to that it's
+rather easy for this to change between different shells, and it's not ideal to
+reread the makefiles every time this changes.
+
+In most cases, you shouldn't need to touch PATH at all. When you need to have a
+rule reference a particular binary that's part of the source tree or outputs,
+it's preferrable to just use the path to the file itself (since you should
+already be adding that as a dependency).
+
+Depending on the rule, passing the file path itself may not be feasible due to
+layers of unchangable scripts/binaries. In that case, be sure to add the
+dependency, but modify the PATH within the rule itself:
+
+``` make
+$(TARGET): myscript my/path/binary
+	PATH=my/path:$$PATH myscript -o $@
+```
+
+### Stop using PYTHONPATH directly  {#PYTHONPATH}
+
+Like PATH, this isn't only set by envsetup.sh, but it is modified by it. Due to
+that it's rather easy for this to change between different shells, and it's not
+ideal to reread the makefiles every time.
+
+The best solution here is to start switching to Soong's python building support,
+which packages the python interpreter, libraries, and script all into one file
+that no longer needs PYTHONPATH. See fontchain_lint for examples of this:
+
+* [external/fonttools/Lib/fontTools/Android.bp] for python_library_host
+* [frameworks/base/Android.bp] for python_binary_host
+* [frameworks/base/data/fonts/Android.mk] to execute the python binary
+
+If you still need to use PYTHONPATH, do so within the rule itself, just like
+path:
+
+``` make
+$(TARGET): myscript.py $(sort $(shell find my/python/lib -name '*.py'))
+	PYTHONPATH=my/python/lib:$$PYTHONPATH myscript.py -o $@
+```
+
+### Other envsetup.sh variables  {#other_envsetup_variables}
+
+* ANDROID_TOOLCHAIN
+* ANDROID_TOOLCHAIN_2ND_ARCH
+* ANDROID_DEV_SCRIPTS
+* ANDROID_EMULATOR_PREBUILTS
+* ANDROID_PRE_BUILD_PATHS
+
+These are all exported from envsetup.sh, but don't have clear equivalents within
+the makefile system. If you need one of them, you'll have to set up your own
+version.
+
+
+[build/soong/Changes.md]: https://android.googlesource.com/platform/build/soong/+/master/Changes.md
+[external/fonttools/Lib/fontTools/Android.bp]: https://android.googlesource.com/platform/external/fonttools/+/master/Lib/fontTools/Android.bp
+[frameworks/base/Android.bp]: https://android.googlesource.com/platform/frameworks/base/+/master/Android.bp
+[frameworks/base/data/fonts/Android.mk]: https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/Android.mk
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..47809a9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+# Android Make Build System
+
+This is the Makefile-based portion of the Android Build System.
+
+For documentation on how to run a build, see [Usage.txt](Usage.txt)
+
+For a list of behavioral changes useful for Android.mk writers see
+[Changes.md](Changes.md)
+
+For an outdated reference on Android.mk files, see
+[build-system.html](/core/build-system.html). Our Android.mk files look similar,
+but are entirely different from the Android.mk files used by the NDK build
+system. When searching for documentation elsewhere, ensure that it is for the
+platform build system -- most are not.
+
+This Makefile-based system is in the process of being replaced with [Soong], a
+new build system written in Go. During the transition, all of these makefiles
+are read by [Kati], and generate a ninja file instead of being executed
+directly. That's combined with a ninja file read by Soong so that the build
+graph of the two systems can be combined and run as one.
+
+[Kati]: https://github.com/google/kati
+[Soong]: https://android.googlesource.com/platform/build/soong/+/master
diff --git a/README.txt b/Usage.txt
similarity index 100%
rename from README.txt
rename to Usage.txt
diff --git a/core/Makefile b/core/Makefile
index 5bc6322..88cb343 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -31,12 +31,13 @@
     $(if $(filter $(unique_product_copy_files_pairs),$(cf)),,\
         $(eval unique_product_copy_files_pairs += $(cf))))
 unique_product_copy_files_destinations :=
+product_copy_files_ignored :=
 $(foreach cf,$(unique_product_copy_files_pairs), \
     $(eval _src := $(call word-colon,1,$(cf))) \
     $(eval _dest := $(call word-colon,2,$(cf))) \
     $(call check-product-copy-files,$(cf)) \
     $(if $(filter $(unique_product_copy_files_destinations),$(_dest)), \
-        $(info PRODUCT_COPY_FILES $(cf) ignored.), \
+        $(eval product_copy_files_ignored += $(cf)), \
         $(eval _fulldest := $(call append-path,$(PRODUCT_OUT),$(_dest))) \
         $(if $(filter %.xml,$(_dest)),\
             $(eval $(call copy-xml-file-checked,$(_src),$(_fulldest))),\
@@ -45,10 +46,31 @@
                 $(eval $(call copy-one-file,$(_src),$(_fulldest))))) \
         $(eval ALL_DEFAULT_INSTALLED_MODULES += $(_fulldest)) \
         $(eval unique_product_copy_files_destinations += $(_dest))))
+
+# Dump a list of overriden (and ignored PRODUCT_COPY_FILES entries)
+$(file >$(PRODUCT_OUT)/product_copy_files_ignored.txt,$(subst $(space),$(newline),$(strip $(product_copy_files_ignored))))
+ifdef dist_goal
+$(file >$(DIST_DIR)/logs/product_copy_files_ignored.txt,$(subst $(space),$(newline),$(strip $(product_copy_files_ignored))))
+endif
+
+product_copy_files_ignored :=
 unique_product_copy_files_pairs :=
 unique_product_copy_files_destinations :=
 
 # -----------------------------------------------------------------
+# Returns the max allowed size for an image suitable for hash verification
+# (e.g., boot.img, recovery.img, etc).
+# The value 69632 derives from MAX_VBMETA_SIZE + MAX_FOOTER_SIZE in $(AVBTOOL).
+# $(1): partition size to flash the image
+define get-hash-image-max-size
+$(if $(1), \
+  $(if $(filter true,$(BOARD_AVB_ENABLE)), \
+    $(eval _hash_meta_size := 69632), \
+    $(eval _hash_meta_size := 0)) \
+  $(1)-$(_hash_meta_size))
+endef
+
+# -----------------------------------------------------------------
 # Define rules to copy headers defined in copy_headers.mk
 # If more than one makefile declared a header, print a warning,
 # then copy the last one defined. This matches the previous make
@@ -508,6 +530,18 @@
 $(call dist-for-goals,droidcore,$(SOONG_TO_CONVERT))
 
 # -----------------------------------------------------------------
+# Modules use -Wno-error, or added default -Wall -Werror
+WALL_WERROR := $(PRODUCT_OUT)/wall_werror.txt
+$(WALL_WERROR):
+	@rm -f $@
+	echo "# Modules using -Wno-error" >> $@
+	for m in $(sort $(SOONG_MODULES_USING_WNO_ERROR) $(MODULES_USING_WNO_ERROR)); do echo $$m >> $@; done
+	echo "# Modules added default -Wall" >> $@
+	for m in $(sort $(SOONG_MODULES_ADDED_WALL) $(MODULES_ADDED_WALL)); do echo $$m >> $@; done
+
+$(call dist-for-goals,droidcore,$(WALL_WERROR))
+
+# -----------------------------------------------------------------
 # The dev key is used to sign this package, and as the key required
 # for future OTA packages installed by this system.  Actual product
 # deliverables will be re-signed by hand.  We expect this file to
@@ -605,6 +639,8 @@
 	@echo "make $@: ignoring dependencies"
 	$(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_ROOT_OUT) | $(MINIGZIP) > $(INSTALLED_RAMDISK_TARGET)
 
+INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
+
 ifneq ($(strip $(TARGET_NO_KERNEL)),true)
 
 # -----------------------------------------------------------------
@@ -643,8 +679,6 @@
     --os_version $(PLATFORM_VERSION) \
     --os_patch_level $(PLATFORM_SECURITY_PATCH)
 
-INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
-
 # BOARD_USES_RECOVERY_AS_BOOT = true must have BOARD_BUILD_SYSTEM_ROOT_IMAGE = true.
 ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
 ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
@@ -662,7 +696,7 @@
 $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH)
 	$(call pretty,"Target boot image: $@")
 	$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
-	$(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE))
+	$(hide) $(call assert-max-image-size,$@,$(call get-hash-image-max-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE)))
 	$(hide) $(AVBTOOL) add_hash_footer \
 	  --image $@ \
 	  --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \
@@ -673,9 +707,9 @@
 bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH)
 	@echo "make $@: ignoring dependencies"
 	$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET)
-	$(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE))
+	$(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(call get-hash-image-max-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE)))
 	$(hide) $(AVBTOOL) add_hash_footer \
-	  --image $@ \
+	  --image $(INSTALLED_BOOTIMAGE_TARGET) \
 	  --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \
 	  --partition_name boot $(INTERNAL_AVB_BOOT_SIGNING_ARGS) \
 	  $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)
@@ -727,6 +761,13 @@
 endif # BOARD_USES_RECOVERY_AS_BOOT
 
 else	# TARGET_NO_KERNEL
+ifdef BOARD_PREBUILT_BOOTIMAGE
+ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+# Remove when b/63676296 is resolved.
+$(error Prebuilt bootimage is only supported for AB targets)
+endif
+$(eval $(call copy-one-file,$(BOARD_PREBUILT_BOOTIMAGE),$(INSTALLED_BOOTIMAGE_TARGET)))
+else
 INTERNAL_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE))
 # HACK: The top-level targets depend on the bootimage.  Not all targets
 # can produce a bootimage, though, and emulator targets need the ramdisk
@@ -735,6 +776,7 @@
 #       kernel-less inputs.
 INSTALLED_BOOTIMAGE_TARGET := $(INSTALLED_RAMDISK_TARGET)
 endif
+endif
 
 # -----------------------------------------------------------------
 # NOTICE files
@@ -1090,9 +1132,10 @@
 recovery_sepolicy := \
     $(TARGET_RECOVERY_ROOT_OUT)/sepolicy \
     $(TARGET_RECOVERY_ROOT_OUT)/plat_file_contexts \
-    $(TARGET_RECOVERY_ROOT_OUT)/nonplat_file_contexts \
+    $(TARGET_RECOVERY_ROOT_OUT)/vendor_file_contexts \
     $(TARGET_RECOVERY_ROOT_OUT)/plat_property_contexts \
-    $(TARGET_RECOVERY_ROOT_OUT)/nonplat_property_contexts
+    $(TARGET_RECOVERY_ROOT_OUT)/vendor_property_contexts
+
 # Passed into rsync from non-recovery root to recovery root, to avoid overwriting recovery-specific
 # SELinux files
 IGNORE_RECOVERY_SEPOLICY := $(patsubst $(TARGET_RECOVERY_OUT)/%,--exclude=/%,$(recovery_sepolicy))
@@ -1167,14 +1210,6 @@
 RECOVERY_RESOURCE_ZIP :=
 endif
 
-ifeq ($(TARGET_PRIVATE_RES_DIRS),)
-  $(info No private recovery resources for TARGET_DEVICE $(TARGET_DEVICE))
-endif
-
-ifeq ($(recovery_fstab),)
-  $(info No recovery.fstab for TARGET_DEVICE $(TARGET_DEVICE))
-endif
-
 INTERNAL_RECOVERYIMAGE_ARGS := \
 	$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
 	--kernel $(recovery_kernel) \
@@ -1213,15 +1248,15 @@
 
 # $(1): output file
 define build-recoveryimage-target
-  @echo ----- Making recovery image ------
+  # 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
-  @echo Copying baseline ramdisk...
+  # 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)
   # Copy adbd from system/bin to recovery/root/sbin
   $(hide) cp -f $(TARGET_OUT_EXECUTABLES)/adbd $(TARGET_RECOVERY_ROOT_OUT)/sbin/adbd
-  @echo Modifying ramdisk contents...
+  # 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)))
   # Removes $(TARGET_RECOVERY_ROOT_OUT)/init*.rc EXCEPT init.recovery*.rc.
@@ -1264,16 +1299,13 @@
   )
   $(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)), \
     $(VBOOT_SIGNER) $(FUTILITY) $(1).unsigned $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbpubk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbprivk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY).vbprivk $(1).keyblock $(1))
-  $(if $(and $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),$(filter true,$(BOARD_AVB_ENABLE))), \
-      $(hide) $(AVBTOOL) add_hash_footer \
-        --image $(1) \
-        --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \
-        --partition_name boot $(INTERNAL_AVB_BOOT_SIGNING_ARGS) \
-        $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS))
   $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)), \
-    $(hide) $(call assert-max-image-size,$(1),$(BOARD_BOOTIMAGE_PARTITION_SIZE)), \
-    $(hide) $(call assert-max-image-size,$(1),$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)))
-  @echo ----- Made recovery image: $(1) --------
+    $(hide) $(call assert-max-image-size,$(1),$(call get-hash-image-max-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))), \
+    $(hide) $(call assert-max-image-size,$(1),$(call get-hash-image-max-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))))
+  $(if $(filter true,$(BOARD_AVB_ENABLE)), \
+    $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)), \
+      $(hide) $(AVBTOOL) add_hash_footer --image $(1) --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) --partition_name boot $(INTERNAL_AVB_BOOT_SIGNING_ARGS) $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS),\
+      $(hide) $(AVBTOOL) add_hash_footer --image $(1) --partition_size $(BOARD_RECOVERYIMAGE_PARTITION_SIZE) --partition_name recovery $(INTERNAL_AVB_RECOVERY_SIGNING_ARGS) $(BOARD_AVB_RECOVERY_ADD_HASH_FOOTER_ARGS)))
 endef
 
 ADBD := $(TARGET_OUT_EXECUTABLES)/adbd
@@ -1927,6 +1959,7 @@
 DTBO_FOOTER_ARGS := BOARD_AVB_DTBO_ADD_HASH_FOOTER_ARGS
 SYSTEM_FOOTER_ARGS := BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS
 VENDOR_FOOTER_ARGS := BOARD_AVB_VENDOR_ADD_HASHTREE_FOOTER_ARGS
+RECOVERY_FOOTER_ARGS := BOARD_AVB_RECOVERY_ADD_HASH_FOOTER_ARGS
 
 # Check and set required build variables for a chain partition.
 # $(1): the partition to enable AVB chain, e.g., BOOT or SYSTEM.
@@ -1988,6 +2021,15 @@
 endif
 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)
+endif
+endif
+
 BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --padding_size 4096
 
 # Add kernel cmdline descriptor for kernel to mount system.img as root with
@@ -2026,6 +2068,9 @@
   $(if $(BOARD_AVB_DTBO_KEY_PATH),\
     $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_DTBO_KEY_PATH) \
       --output $(1)/dtbo.avbpubkey)
+  $(if $(BOARD_AVB_RECOVERY_KEY_PATH),\
+    $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_RECOVERY_KEY_PATH) \
+      --output $(1)/recovery.avbpubkey)
 endef
 
 define build-vbmetaimage-target
@@ -2041,7 +2086,14 @@
 endef
 
 INSTALLED_VBMETAIMAGE_TARGET := $(BUILT_VBMETAIMAGE_TARGET)
-$(INSTALLED_VBMETAIMAGE_TARGET): $(AVBTOOL) $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_SYSTEMIMAGE) $(INSTALLED_VENDORIMAGE_TARGET) $(INSTALLED_DTBOIMAGE_TARGET) $(BOARD_AVB_KEY_PATH)
+$(INSTALLED_VBMETAIMAGE_TARGET): \
+		$(AVBTOOL) \
+		$(INSTALLED_BOOTIMAGE_TARGET) \
+		$(INSTALLED_SYSTEMIMAGE) \
+		$(INSTALLED_VENDORIMAGE_TARGET) \
+		$(INSTALLED_DTBOIMAGE_TARGET) \
+		$(INSTALLED_RECOVERYIMAGE_TARGET) \
+		$(BOARD_AVB_KEY_PATH)
 	$(build-vbmetaimage-target)
 
 .PHONY: vbmetaimage-nodeps
@@ -2171,7 +2223,7 @@
   $(shell find system/update_engine/scripts -name \*.pyc -prune -o -type f -print | sort) \
   $(shell find build/target/product/security -type f -name \*.x509.pem -o -name \*.pk8 -o \
       -name verity_key | sort) \
-  $(shell find device vendor -type f -name \*.pk8 -o -name verifiedboot\* -o \
+  $(shell find device $(wildcard vendor) -type f -name \*.pk8 -o -name verifiedboot\* -o \
       -name \*.x509.pem -o -name oem\*.prop | sort)
 
 OTATOOLS_RELEASETOOLS := \
@@ -2293,6 +2345,7 @@
 		$(INSTALLED_USERDATAIMAGE_TARGET) \
 		$(INSTALLED_CACHEIMAGE_TARGET) \
 		$(INSTALLED_VENDORIMAGE_TARGET) \
+		$(INSTALLED_VBMETAIMAGE_TARGET) \
 		$(INSTALLED_DTBOIMAGE_TARGET) \
 		$(INTERNAL_SYSTEMOTHERIMAGE_FILES) \
 		$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
@@ -2408,9 +2461,6 @@
 ifdef BOARD_BOOTIMAGE_PARTITION_SIZE
 	$(hide) echo "boot_size=$(BOARD_BOOTIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
 endif
-ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),)
-	$(hide) echo "recovery_as_boot=$(BOARD_USES_RECOVERY_AS_BOOT)" >> $(zip_root)/META/misc_info.txt
-endif
 ifeq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
 	$(hide) echo "no_recovery=true" >> $(zip_root)/META/misc_info.txt
 endif
@@ -2465,6 +2515,12 @@
 	$(hide) echo "avb_boot_algorithm=$(BOARD_AVB_BOOT_ALGORITHM)" >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "avb_boot_rollback_index_location=$(BOARD_AVB_BOOT_ROLLBACK_INDEX_LOCATION)" >> $(zip_root)/META/misc_info.txt
 endif # BOARD_AVB_BOOT_KEY_PATH
+	$(hide) echo "avb_recovery_add_hash_footer_args=$(BOARD_AVB_RECOVERY_ADD_HASH_FOOTER_ARGS)" >> $(zip_root)/META/misc_info.txt
+ifdef BOARD_AVB_RECOVERY_KEY_PATH
+	$(hide) echo "avb_recovery_key_path=$(BOARD_AVB_RECOVERY_KEY_PATH)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "avb_recovery_algorithm=$(BOARD_AVB_RECOVERY_ALGORITHM)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "avb_recovery_rollback_index_location=$(BOARD_AVB_RECOVERY_ROLLBACK_INDEX_LOCATION)" >> $(zip_root)/META/misc_info.txt
+endif # BOARD_AVB_RECOVERY_KEY_PATH
 endif # BOARD_AVB_ENABLE
 ifdef BOARD_BPT_INPUT_FILES
 	$(hide) echo "board_bpt_enable=true" >> $(zip_root)/META/misc_info.txt
@@ -2513,10 +2569,22 @@
 	@# If breakpad symbols have been generated, add them to the zip.
 	$(hide) $(ACP) -r $(TARGET_OUT_BREAKPAD) $(zip_root)/BREAKPAD
 endif
+# BOARD_BUILD_DISABLED_VBMETAIMAGE is used to build a special vbmeta.img
+# that disables AVB verification. The content is fixed and we can just copy
+# it to $(zip_root)/IMAGES without passing some info into misc_info.txt for
+# regeneration.
+ifeq (true,$(BOARD_BUILD_DISABLED_VBMETAIMAGE))
+	$(hide) mkdir -p $(zip_root)/IMAGES
+	$(hide) cp $(INSTALLED_VBMETAIMAGE_TARGET) $(zip_root)/IMAGES/
+endif
 ifdef BOARD_PREBUILT_VENDORIMAGE
 	$(hide) mkdir -p $(zip_root)/IMAGES
 	$(hide) cp $(INSTALLED_VENDORIMAGE_TARGET) $(zip_root)/IMAGES/
 endif
+ifdef BOARD_PREBUILT_BOOTIMAGE
+	$(hide) mkdir -p $(zip_root)/IMAGES
+	$(hide) cp $(INSTALLED_BOOTIMAGE_TARGET) $(zip_root)/IMAGES/
+endif
 ifdef BOARD_PREBUILT_DTBOIMAGE
 	$(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
 	$(hide) cp $(INSTALLED_DTBOIMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
@@ -2553,8 +2621,6 @@
 ifdef INSTALLED_SYSTEMOTHERIMAGE_TARGET
 	$(hide) $(call fs_config,$(zip_root)/SYSTEM_OTHER,system/) > $(zip_root)/META/system_other_filesystem_config.txt
 endif
-
-ifeq ($(PRODUCT_FULL_TREBLE),true)
 	@# Metadata for compatibility verification.
 	$(hide) cp $(BUILT_SYSTEM_MANIFEST) $(zip_root)/META/system_manifest.xml
 	$(hide) cp $(BUILT_SYSTEM_COMPATIBILITY_MATRIX) $(zip_root)/META/system_matrix.xml
@@ -2564,7 +2630,6 @@
 ifdef BUILT_VENDOR_MATRIX
 	$(hide) cp $(BUILT_VENDOR_MATRIX) $(zip_root)/META/vendor_matrix.xml
 endif
-endif
 
 	$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
 	    ./build/tools/releasetools/add_img_to_target_files -a -v -p $(HOST_OUT) $(zip_root)
diff --git a/core/aapt2.mk b/core/aapt2.mk
index 8bb2d4b..c582e30 100644
--- a/core/aapt2.mk
+++ b/core/aapt2.mk
@@ -108,3 +108,13 @@
 
 	cp $@ $(PRIVATE_RESOURCE_EXPORT_PACKAGE)
 endif
+
+# Clear inputs only used in this file, so that they're not re-used during the next build
+my_res_resources :=
+my_overlay_resources :=
+my_compiled_res_base_dir :=
+my_asset_dirs :=
+my_full_asset_paths :=
+my_apk_split_configs :=
+my_generated_res_dirs :=
+my_generated_res_dirs_deps :=
diff --git a/core/base_rules.mk b/core/base_rules.mk
index b501fbd..7ce3f0f 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -65,6 +65,16 @@
   my_host_cross :=
 endif
 
+_path := $(LOCAL_MODULE_PATH) $(LOCAL_MODULE_PATH_32) $(LOCAL_MODULE_PATH_64)
+ifneq ($(filter $(TARGET_OUT_VENDOR)%,$(_path)),)
+LOCAL_VENDOR_MODULE := true
+else ifneq ($(filter $(TARGET_OUT_OEM)/%,$(_path)),)
+LOCAL_OEM_MODULE := true
+else ifneq ($(filter $(TARGET_OUT_ODM)/%,$(_path)),)
+LOCAL_ODM_MODULE := true
+endif
+_path :=
+
 ifndef LOCAL_PROPRIETARY_MODULE
   LOCAL_PROPRIETARY_MODULE := $(LOCAL_VENDOR_MODULE)
 endif
@@ -76,6 +86,7 @@
 endif
 
 include $(BUILD_SYSTEM)/local_vndk.mk
+include $(BUILD_SYSTEM)/local_vsdk.mk
 
 my_module_tags := $(LOCAL_MODULE_TAGS)
 ifeq ($(my_host_cross),true)
@@ -601,6 +612,7 @@
 ALL_MODULES.$(my_register_name).FOR_2ND_ARCH := true
 endif
 ALL_MODULES.$(my_register_name).FOR_HOST_CROSS := $(my_host_cross)
+ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES := $(LOCAL_COMPATIBILITY_SUITE)
 
 INSTALLABLE_FILES.$(LOCAL_INSTALLED_MODULE).MODULE := $(my_register_name)
 
@@ -656,7 +668,7 @@
 
 
 ifdef j_or_n
-$(j_or_n) $(h_or_t) $(j_or_n)-$(h_or_t) : $(my_checked_module)
+$(j_or_n) $(h_or_t) $(j_or_n)-$(h_or_hc_or_t) : $(my_checked_module)
 ifneq (,$(filter $(my_module_tags),tests))
 $(j_or_n)-$(h_or_t)-tests $(j_or_n)-tests $(h_or_t)-tests : $(my_checked_module)
 endif
diff --git a/core/binary.mk b/core/binary.mk
index bd1e601..6b65b6c 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -387,9 +387,9 @@
 # clang is enabled by default for host builds
 # enable it unless we've specifically disabled clang above
 ifdef LOCAL_IS_HOST_MODULE
-    ifeq ($($(my_prefix)OS),windows)
+    ifneq ($($(my_prefix)CLANG_SUPPORTED),true)
         ifeq ($(my_clang),true)
-            $(error $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Clang is not yet supported for windows binaries)
+            $(call pretty-error,Clang is not yet supported for $($(my_prefix)OS) binaries)
         endif
         my_clang := false
     else
@@ -806,7 +806,7 @@
 ifneq (,$(LOCAL_SDK_VERSION))
 # Set target-api for LOCAL_SDK_VERSIONs other than current.
 ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
-renderscript_target_api := $(LOCAL_SDK_VERSION)
+renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
 endif
 endif  # LOCAL_SDK_VERSION is set
 endif  # LOCAL_RENDERSCRIPT_TARGET_API is set
@@ -1330,6 +1330,22 @@
 asm_objects += $(asm_objects_asm)
 endif
 
+###################################################################
+## When compiling a CFI enabled target, use the .cfi variant of any
+## static dependencies (where they exist).
+##################################################################
+define use_soong_cfi_static_libraries
+  $(foreach l,$(1),$(if $(filter $(l),$(SOONG_CFI_STATIC_LIBRARIES)),\
+      $(l).cfi,$(l)))
+endef
+
+ifneq ($(filter cfi,$(my_sanitize)),)
+  my_whole_static_libraries := $(call use_soong_cfi_static_libraries,\
+    $(my_whole_static_libraries))
+  my_static_libraries := $(call use_soong_cfi_static_libraries,\
+    $(my_static_libraries))
+endif
+
 ###########################################################
 ## When compiling against the VNDK, use LL-NDK libraries
 ###########################################################
@@ -1664,13 +1680,30 @@
     my_cflags += -DANDROID_STRICT
 endif
 
-# Add -Werror if LOCAL_PATH is in the WARNING_DISALLOWED project list,
-# or not in the WARNING_ALLOWED project list.
-ifneq (,$(strip $(call find_warning_disallowed_projects,$(LOCAL_PATH))))
-  my_cflags_no_override += -Werror
-else
-  ifeq (,$(strip $(call find_warning_allowed_projects,$(LOCAL_PATH))))
-    my_cflags_no_override += -Werror
+# Check if -Werror or -Wno-error is used in C compiler flags.
+# Modules defined in $(SOONG_ANDROID_MK) are checked in soong's cc.go.
+ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+  # Header libraries do not need cflags.
+  ifneq (HEADER_LIBRARIES,$(LOCAL_MODULE_CLASS))
+    # Prebuilt modules do not need cflags.
+    ifeq (,$(LOCAL_PREBUILT_MODULE_FILE))
+      my_all_cflags := $(my_cflags) $(my_cppflags) $(my_cflags_no_override)
+      # Issue warning if -Wno-error is used.
+      ifneq (,$(filter -Wno-error,$(my_all_cflags)))
+        $(eval MODULES_USING_WNO_ERROR := $(MODULES_USING_WNO_ERROR) $(LOCAL_MODULE_MAKEFILE):$(LOCAL_MODULE))
+      else
+        # Issue warning if -Werror is not used. Add it.
+        ifeq (,$(filter -Werror,$(my_all_cflags)))
+          # Add -Wall -Werror unless the project is in the WARNING_ALLOWED project list.
+          ifeq (,$(strip $(call find_warning_allowed_projects,$(LOCAL_PATH))))
+            my_cflags := -Wall -Werror $(my_cflags)
+          else
+            $(eval MODULES_ADDED_WALL := $(MODULES_ADDED_WALL) $(LOCAL_MODULE_MAKEFILE):$(LOCAL_MODULE))
+            my_cflags := -Wall $(my_cflags)
+          endif
+        endif
+      endif
+    endif
   endif
 endif
 
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 7863c7d..4dbaf94 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -4,6 +4,7 @@
 
 # '',true
 LOCAL_32_BIT_ONLY:=
+LOCAL_AAPT2_ONLY:=
 LOCAL_AAPT_FLAGS:=
 LOCAL_AAPT_INCLUDE_ALL_RESOURCES:=
 LOCAL_ADDITIONAL_CERTIFICATES:=
@@ -225,10 +226,16 @@
 LOCAL_SDK_VERSION:=
 LOCAL_SHARED_ANDROID_LIBRARIES:=
 LOCAL_SHARED_LIBRARIES:=
+LOCAL_SOONG_HEADER_JAR :=
+LOCAL_SOONG_DEX_JAR :=
+LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=
+LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=
+LOCAL_SOONG_RRO_DIRS :=
 # '',true
 LOCAL_SOURCE_FILES_ALL_GENERATED:=
 LOCAL_SRC_FILES:=
 LOCAL_SRC_FILES_EXCLUDE:=
+LOCAL_SRCJARS:=
 LOCAL_STATIC_ANDROID_LIBRARIES:=
 LOCAL_STATIC_JAVA_AAR_LIBRARIES:=
 LOCAL_STATIC_JAVA_LIBRARIES:=
diff --git a/core/config.mk b/core/config.mk
index cbafd50..a8b9af2 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -59,7 +59,24 @@
 .DELETE_ON_ERROR:
 
 # Mark variables deprecated/obsolete
-$(KATI_deprecated_var PATH,Do not use PATH directly)
+CHANGES_URL := https://android.googlesource.com/platform/build/+/master/Changes.md
+$(KATI_deprecated_var PATH,Do not use PATH directly. See $(CHANGES_URL)#PATH)
+$(KATI_obsolete_var PYTHONPATH,Do not use PYTHONPATH directly. See $(CHANGES_URL)#PYTHONPATH)
+$(KATI_obsolete_var OUT,Use OUT_DIR instead. See $(CHANGES_URL)#OUT)
+$(KATI_obsolete_var ANDROID_HOST_OUT,Use HOST_OUT instead. See $(CHANGES_URL)#ANDROID_HOST_OUT)
+$(KATI_deprecated_var ANDROID_PRODUCT_OUT,Use PRODUCT_OUT instead. See $(CHANGES_URL)#ANDROID_PRODUCT_OUT)
+$(KATI_obsolete_var ANDROID_HOST_OUT_TESTCASES,Use HOST_OUT_TESTCASES instead. See $(CHANGES_URL)#ANDROID_HOST_OUT_TESTCASES)
+$(KATI_obsolete_var ANDROID_TARGET_OUT_TESTCASES,Use TARGET_OUT_TESTCASES instead. See $(CHANGES_URL)#ANDROID_TARGET_OUT_TESTCASES)
+$(KATI_deprecated_var ANDROID_BUILD_TOP,Use '.' instead. See $(CHANGES_URL)#ANDROID_BUILD_TOP)
+$(KATI_obsolete_var \
+  ANDROID_TOOLCHAIN \
+  ANDROID_TOOLCHAIN_2ND_ARCH \
+  ANDROID_DEV_SCRIPTS \
+  ANDROID_EMULATOR_PREBUILTS \
+  ANDROID_PRE_BUILD_PATHS \
+  ,See $(CHANGES_URL)#other_envsetup_variables)
+
+CHANGES_URL :=
 
 # Used to force goals to build.  Only use for conditionally defined goals.
 .PHONY: FORCE
@@ -67,6 +84,9 @@
 
 ORIGINAL_MAKECMDGOALS := $(MAKECMDGOALS)
 
+dist_goal := $(strip $(filter dist,$(MAKECMDGOALS)))
+MAKECMDGOALS := $(strip $(filter-out dist,$(MAKECMDGOALS)))
+
 # Tell python not to spam the source tree with .pyc files.  This
 # only has an effect on python 2.6 and above.
 export PYTHONDONTWRITEBYTECODE := 1
@@ -524,6 +544,11 @@
   USE_D8 := true
 endif
 
+# Default R8 behavior when USE_R8 is not specified.
+ifndef USE_R8
+  USE_R8 := false
+endif
+
 #
 # Tools that are prebuilts for TARGET_BUILD_APPS
 #
@@ -538,17 +563,17 @@
   ZIPALIGN := $(HOST_OUT_EXECUTABLES)/zipalign
 
 else # TARGET_BUILD_APPS || TARGET_BUILD_PDK
-  AIDL := $(prebuilt_sdk_tools_bin)/aidl
+  AIDL := $(prebuilt_build_tools_bin)/aidl
   AAPT := $(prebuilt_sdk_tools_bin)/aapt
   AAPT2 := $(prebuilt_sdk_tools_bin)/aapt2
   DESUGAR := $(prebuilt_build_tools_jars)/desugar.jar
   MAINDEXCLASSES := $(prebuilt_sdk_tools)/mainDexClasses
   SIGNAPK_JAR := $(prebuilt_sdk_tools)/lib/signapk$(COMMON_JAVA_PACKAGE_SUFFIX)
   SIGNAPK_JNI_LIBRARY_PATH := $(prebuilt_sdk_tools)/$(HOST_OS)/lib64
-  ZIPALIGN := $(prebuilt_sdk_tools_bin)/zipalign
+  ZIPALIGN := $(prebuilt_build_tools_bin)/zipalign
 endif # TARGET_BUILD_APPS || TARGET_BUILD_PDK
 
-R8_COMPAT_PROGUARD_JAR := prebuilts/r8/compatproguard-master.jar
+R8_COMPAT_PROGUARD := $(HOST_OUT_EXECUTABLES)/r8-compat-proguard
 
 ifeq (,$(TARGET_BUILD_APPS))
   # Use RenderScript prebuilts for unbundled builds but not PDK builds
@@ -660,21 +685,34 @@
 
 FINDBUGS_DIR := external/owasp/sanitizer/tools/findbugs/bin
 FINDBUGS := $(FINDBUGS_DIR)/findbugs
-JACOCO_CLI_JAR := $(HOST_OUT_JAVA_LIBRARIES)/jacoco-cli$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 # Tool to merge AndroidManifest.xmls
 ANDROID_MANIFEST_MERGER := $(JAVA) -classpath prebuilts/devtools/tools/lib/manifest-merger.jar com.android.manifmerger.Main merge
 
 COLUMN:= column
 
-# Path to tools.jar, or empty if EXPERIMENTAL_USE_OPENJDK9 is set
+ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
+USE_OPENJDK9 :=
+TARGET_OPENJDK9 :=
+else ifeq ($(EXPERIMENTAL_USE_OPENJDK9),false)
+USE_OPENJDK9 :=
+TARGET_OPENJDK9 :=
+else ifeq ($(EXPERIMENTAL_USE_OPENJDK9),1.8)
+USE_OPENJDK9 := true
+TARGET_OPENJDK9 :=
+else ifeq ($(EXPERIMENTAL_USE_OPENJDK9),true)
+USE_OPENJDK9 := true
+TARGET_OPENJDK9 := true
+endif
+
+# Path to tools.jar, or empty if USE_OPENJDK9 is unset
 HOST_JDK_TOOLS_JAR :=
 # TODO: Remove HOST_JDK_TOOLS_JAR and all references to it once OpenJDK 8
-# toolchains are no longer supported (i.e. when what is now
-# EXPERIMENTAL_USE_OPENJDK9 becomes the standard). http://b/38418220
-ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
+# toolchains are no longer supported (i.e. when USE_OPENJDK9 is enforced).
+# http://b/38418220
+ifndef USE_OPENJDK9
 HOST_JDK_TOOLS_JAR := $(ANDROID_JAVA_TOOLCHAIN)/../lib/tools.jar
-endif # ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
+endif # ifndef USE_OPENJDK9
 
 # It's called md5 on Mac OS and md5sum on Linux
 ifeq ($(HOST_OS),darwin)
@@ -711,13 +749,15 @@
 # PRODUCT_FULL_TREBLE
 $(foreach req,$(requirements),$(eval \
     $(req) := $(if $($(req)_OVERRIDE),$($(req)_OVERRIDE),$(PRODUCT_FULL_TREBLE))))
-# If the requirement is false for any reason, then it's not PRODUCT_FULL_TREBLE
-$(foreach req,$(requirements),$(eval \
-    PRODUCT_FULL_TREBLE := $(if $(filter false,$($(req))),false,$(PRODUCT_FULL_TREBLE))))
+
+PRODUCT_FULL_TREBLE_OVERRIDE ?=
+$(foreach req,$(requirements),$(eval $(req)_OVERRIDE ?=))
 
 .KATI_READONLY := \
+    PRODUCT_FULL_TREBLE_OVERRIDE \
+    $(foreach req,$(requirements),$(req)_OVERRIDE) \
     $(requirements) \
-    PRODUCT_FULL_TREBLE
+    PRODUCT_FULL_TREBLE \
 
 requirements :=
 
@@ -842,6 +882,11 @@
     $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/android.jar,%, \
     $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/android.jar)))
 
+TARGET_AVAILABLE_SDK_VERSIONS := $(addprefix system_,$(call numerically_sort,\
+    $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/android_system.jar,%, \
+    $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/android_system.jar)))) \
+    $(TARGET_AVAILABLE_SDK_VERSIONS)
+
 # We don't have prebuilt test_current SDK yet.
 TARGET_AVAILABLE_SDK_VERSIONS := test_current $(TARGET_AVAILABLE_SDK_VERSIONS)
 
@@ -884,38 +929,7 @@
 APPS_DEFAULT_VERSION_NAME := $(PLATFORM_VERSION)
 endif
 
-# Projects clean of compiler warnings should be compiled with -Werror.
-# If most modules in a directory such as external/ have warnings,
-# the directory should be in ANDROID_WARNING_ALLOWED_PROJECTS list.
-# When some of its subdirectories are cleaned up, the subdirectories
-# can be added into ANDROID_WARNING_DISALLOWED_PROJECTS list, e.g.
-# external/fio/.
-ANDROID_WARNING_DISALLOWED_PROJECTS := \
-    art/% \
-    bionic/% \
-    external/fio/% \
-    hardware/interfaces/% \
-
-define find_warning_disallowed_projects
-    $(filter $(ANDROID_WARNING_DISALLOWED_PROJECTS),$(1)/)
-endef
-
-# Projects with compiler warnings are compiled without -Werror.
-ANDROID_WARNING_ALLOWED_PROJECTS := \
-    bootable/% \
-    cts/% \
-    dalvik/% \
-    development/% \
-    device/% \
-    external/% \
-    frameworks/% \
-    hardware/% \
-    packages/% \
-    system/% \
-    test/vts/% \
-    tools/adt/idea/android/ultimate/get_modification_time/jni/% \
-    vendor/% \
-
+# ANDROID_WARNING_ALLOWED_PROJECTS is generated by build/soong.
 define find_warning_allowed_projects
     $(filter $(ANDROID_WARNING_ALLOWED_PROJECTS),$(1)/)
 endef
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index 8bd9248..9415143 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -132,6 +132,12 @@
   my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
 endif
 
+# Disable CFI for host targets
+ifdef LOCAL_IS_HOST_MODULE
+  my_sanitize := $(filter-out cfi,$(my_sanitize))
+  my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
+endif
+
 # Support for local sanitize blacklist paths.
 ifneq ($(my_sanitize)$(my_global_sanitize),)
   ifneq ($(LOCAL_SANITIZE_BLACKLIST),)
diff --git a/core/definitions.mk b/core/definitions.mk
index 23d8648..18a31c9 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2381,7 +2381,7 @@
 @rm -rf $(dir $@)/desugar_dumped_classes
 @mkdir $(dir $@)/desugar_dumped_classes
 $(hide) $(JAVA) \
-    $(if $(EXPERIMENTAL_USE_OPENJDK9),--add-opens java.base/java.lang.invoke=ALL-UNNAMED,) \
+    $(if $(USE_OPENJDK9),--add-opens java.base/java.lang.invoke=ALL-UNNAMED,) \
     -Djdk.internal.lambda.dumpProxyClasses=$(abspath $(dir $@))/desugar_dumped_classes \
     -jar $(DESUGAR) \
     $(addprefix --bootclasspath_entry ,$(PRIVATE_BOOTCLASSPATH)) \
@@ -2569,9 +2569,9 @@
 define uncompress-dexs
 $(hide) if (zipinfo $@ '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then \
   rm -rf $(dir $@)uncompresseddexs && mkdir $(dir $@)uncompresseddexs; \
-  unzip $@ '*.dex' -d $(dir $@)uncompresseddexs && \
-  zip -d $@ '*.dex' && \
-  ( cd $(dir $@)uncompresseddexs && find . -type f | sort | zip -D -X -0 ../$(notdir $@) -@ ) && \
+  unzip -q $@ '*.dex' -d $(dir $@)uncompresseddexs && \
+  zip -qd $@ '*.dex' && \
+  ( cd $(dir $@)uncompresseddexs && find . -type f | sort | zip -qD -X -0 ../$(notdir $@) -@ ) && \
   rm -rf $(dir $@)uncompresseddexs; \
   fi
 endef
@@ -2581,9 +2581,9 @@
 define uncompress-shared-libs
 $(hide) if (zipinfo $@ $(PRIVATE_EMBEDDED_JNI_LIBS) 2>/dev/null | grep -v ' stor ' >/dev/null) ; then \
   rm -rf $(dir $@)uncompressedlibs && mkdir $(dir $@)uncompressedlibs; \
-  unzip $@ $(PRIVATE_EMBEDDED_JNI_LIBS) -d $(dir $@)uncompressedlibs && \
-  zip -d $@ 'lib/*.so' && \
-  ( cd $(dir $@)uncompressedlibs && find lib -type f | sort | zip -D -X -0 ../$(notdir $@) -@ ) && \
+  unzip -q $@ $(PRIVATE_EMBEDDED_JNI_LIBS) -d $(dir $@)uncompressedlibs && \
+  zip -qd $@ 'lib/*.so' && \
+  ( cd $(dir $@)uncompressedlibs && find lib -type f | sort | zip -qD -X -0 ../$(notdir $@) -@ ) && \
   rm -rf $(dir $@)uncompressedlibs; \
   fi
 endef
@@ -2774,7 +2774,7 @@
 ###########################################################
 ## Commands to call Proguard
 ###########################################################
-ifeq ($(EXPERIMENTAL_USE_OPENJDK9),true)
+ifdef TARGET_OPENJDK9
 define transform-jar-to-proguard
 @echo Skipping Proguard: $<$(PRIVATE_PROGUARD_INJAR_FILTERS) $@
 $(hide) cp '$<' $@
@@ -2795,7 +2795,7 @@
 ###########################################################
 define transform-jar-to-dex-r8
 @echo R8: $@
-$(hide) $(JAVA) -jar $(R8_COMPAT_PROGUARD_JAR) -injars '$<$(PRIVATE_PROGUARD_INJAR_FILTERS)' \
+$(hide) $(R8_COMPAT_PROGUARD) -injars '$<$(PRIVATE_PROGUARD_INJAR_FILTERS)' \
     --min-api $(PRIVATE_MIN_SDK_VERSION) \
     --force-proguard-compatibility --output $(subst classes.dex,,$@) \
     $(PRIVATE_PROGUARD_FLAGS) \
@@ -3283,6 +3283,30 @@
 # run test
 $(strip $(call test-validate-paths-are-subdirs))
 
+###########################################################
+## Validate jacoco class filters and convert them to
+## file arguments
+## Jacoco class filters are comma-separated lists of class
+## files (android.app.Application), and may have '*' as the
+## last character to match all classes in a package
+## including subpackages.
+define jacoco-class-filter-to-file-args
+$(strip $(call jacoco-validate-file-args,\
+  $(subst $(comma),$(space),\
+    $(subst .,/,\
+      $(strip $(1))))))
+endef
+
+define jacoco-validate-file-args
+$(strip $(1)\
+  $(call validate-paths-are-subdirs,$(1))
+  $(foreach arg,$(1),\
+    $(if $(findstring ?,$(arg)),$(call pretty-error,\
+      '?' filters are not supported in LOCAL_JACK_COVERAGE_INCLUDE_FILTER or LOCAL_JACK_COVERAGE_EXCLUDE_FILTER))\
+    $(if $(findstring *,$(patsubst %*,%,$(arg))),$(call pretty-error,\
+      '*' is only supported at the end of a filter in LOCAL_JACK_COVERAGE_INCLUDE_FILTER or LOCAL_JACK_COVERAGE_EXCLUDE_FILTER))\
+  ))
+endef
 
 ###########################################################
 ## Other includes
@@ -3364,3 +3388,22 @@
   $(eval ALL_MODULES.$(enforce_rro_source_module).REQUIRED += $(enforce_rro_module)) \
 )
 endef
+
+###########################################################
+## Find system_$(VER) in LOCAL_SDK_VERSION
+##
+## $(1): LOCAL_SDK_VERSION
+###########################################################
+define has-system-sdk-version
+$(filter system_%,$(1))
+endef
+
+###########################################################
+## Get numerical version in LOCAL_SDK_VERSION
+##
+## $(1): LOCAL_SDK_VERSION
+###########################################################
+define get-numeric-sdk-version
+$(filter-out current,\
+  $(if $(call has-system-sdk-version,$(1)),$(patsubst system_%,%,$(1)),$(1)))
+endef
diff --git a/core/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index 302cc8b..8b71198 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -97,6 +97,8 @@
 		--runtime-arg -Xnorelocate --compile-pic \
 		--no-generate-debug-info --generate-build-id \
 		--multi-image --no-inline-from=core-oj.jar \
+		--abort-on-hard-verifier-error \
+		--abort-on-soft-verifier-error \
 		$(PRODUCT_DEX_PREOPT_BOOT_FLAGS) $(GLOBAL_DEXPREOPT_FLAGS) $(ART_BOOT_IMAGE_EXTRA_ARGS)
 
 endif
diff --git a/core/distdir.mk b/core/distdir.mk
index 89c5966..c074186 100644
--- a/core/distdir.mk
+++ b/core/distdir.mk
@@ -17,9 +17,6 @@
 # When specifying "dist", the user has asked that we copy the important
 # files from this build into DIST_DIR.
 
-dist_goal := $(strip $(filter dist,$(MAKECMDGOALS)))
-MAKECMDGOALS := $(strip $(filter-out dist,$(MAKECMDGOALS)))
-
 ifdef dist_goal
 
 # $(1): source file
diff --git a/core/dpi_specific_apk.mk b/core/dpi_specific_apk.mk
index ac5c4a9..e29cde7 100644
--- a/core/dpi_specific_apk.mk
+++ b/core/dpi_specific_apk.mk
@@ -19,7 +19,7 @@
 $(built_dpi_apk): PRIVATE_AAPT_INCLUDES := $(all_library_res_package_exports)
 $(built_dpi_apk): PRIVATE_RESOURCE_LIST := $(all_res_assets)
 ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
-$(built_dpi_apk): PRIVATE_DEFAULT_APP_TARGET_SDK := $(LOCAL_SDK_VERSION)
+$(built_dpi_apk): PRIVATE_DEFAULT_APP_TARGET_SDK := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
 else
 $(built_dpi_apk): PRIVATE_DEFAULT_APP_TARGET_SDK := $(DEFAULT_APP_TARGET_SDK)
 endif
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index 45b8af0..176a01d 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -72,8 +72,18 @@
     LOCAL_JAVA_LIBRARIES := android_test_stubs_current $(LOCAL_JAVA_LIBRARIES)
     $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, android_test_stubs_current)
   else
-    LOCAL_JAVA_LIBRARIES := sdk_v$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES)
-    $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, sdk_v$(LOCAL_SDK_VERSION))
+    ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
+      ifeq (,$(TARGET_BUILD_APPS))
+        LOCAL_JAVA_LIBRARIES := system_sdk_v$(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION)) $(LOCAL_JAVA_LIBRARIES)
+        $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, system_sdk_v$(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION)))
+      else
+        LOCAL_JAVA_LIBRARIES := sdk_v$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES)
+        $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, sdk_v$(LOCAL_SDK_VERSION))
+      endif
+    else
+      LOCAL_JAVA_LIBRARIES := sdk_v$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES)
+      $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, sdk_v$(LOCAL_SDK_VERSION))
+    endif
   endif
 else
   LOCAL_JAVA_LIBRARIES := core-oj core-libart ext framework $(LOCAL_JAVA_LIBRARIES)
@@ -91,8 +101,12 @@
 $(full_target): PRIVATE_SOURCE_PATH := $(call normalize-path-list,$(LOCAL_DROIDDOC_SOURCE_PATH))
 $(full_target): PRIVATE_JAVA_FILES := $(filter %.java,$(full_src_files))
 $(full_target): PRIVATE_JAVA_FILES += $(addprefix $($(my_prefix)OUT_COMMON_INTERMEDIATES)/, $(filter %.java,$(LOCAL_INTERMEDIATE_SOURCES)))
+$(full_target): PRIVATE_JAVA_FILES += $(filter %.java,$(LOCAL_GENERATED_SOURCES))
+$(full_target): PRIVATE_SRCJARS := $(LOCAL_SRCJARS)
 $(full_target): PRIVATE_SOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/src
+$(full_target): PRIVATE_SRCJAR_INTERMEDIATES_DIR := $(intermediates.COMMON)/srcjars
 $(full_target): PRIVATE_SRC_LIST_FILE := $(intermediates.COMMON)/droiddoc-src-list
+$(full_target): PRIVATE_SRCJAR_LIST_FILE := $(intermediates.COMMON)/droiddoc-srcjar-list
 
 ifneq ($(strip $(LOCAL_ADDITIONAL_JAVA_DIR)),)
 $(full_target): PRIVATE_ADDITIONAL_JAVA_DIR := $(LOCAL_ADDITIONAL_JAVA_DIR)
@@ -169,21 +183,26 @@
 # keep -bootclasspath here since it works in combination with -source 1.8.
 $(full_target): \
         $(full_src_files) \
+        $(LOCAL_GENERATED_SOURCES) \
         $(droiddoc_templates) \
         $(droiddoc) \
         $(html_dir_files) \
         $(full_java_libs) \
+        $(EXTRACT_SRCJARS) \
+        $(LOCAL_SRCJARS) \
         $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	@echo Docs droiddoc: $(PRIVATE_OUT_DIR)
 	$(hide) mkdir -p $(dir $@)
-	$(addprefix $(hide) rm -rf ,$(PRIVATE_STUB_OUT_DIR))
+	$(hide) rm -rf $(PRIVATE_STUB_OUT_DIR) $(PRIVATE_SRCJAR_INTERMEDIATES_DIR)
 	$(call prepare-doc-source-list,$(PRIVATE_SRC_LIST_FILE),$(PRIVATE_JAVA_FILES), \
 			$(PRIVATE_SOURCE_INTERMEDIATES_DIR) $(PRIVATE_ADDITIONAL_JAVA_DIR))
+	$(EXTRACT_SRCJARS) $(PRIVATE_SRCJAR_INTERMEDIATES_DIR) $(PRIVATE_SRCJAR_LIST_FILE) $(PRIVATE_SRCJARS)
 	$(hide) ( \
 		$(JAVADOC) \
                 -encoding UTF-8 \
                 -source 1.8 \
                 \@$(PRIVATE_SRC_LIST_FILE) \
+                \@$(PRIVATE_SRCJAR_LIST_FILE) \
                 -J-Xmx1600m \
                 -J-XX:-OmitStackTraceInFastThrow \
                 -XDignore.symbol.file \
@@ -213,7 +232,7 @@
 ##
 ##
 
-ifneq ($(EXPERIMENTAL_USE_OPENJDK9),)
+ifdef USE_OPENJDK9
 # For OpenJDK 9 we use --patch-module to define the core libraries code.
 # TODO(tobiast): Reorganize this when adding proper support for OpenJDK 9
 # modules. Here we treat all code in core libraries as being in java.base
@@ -223,17 +242,19 @@
 # For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
 $(full_target): PRIVATE_BOOTCLASSPATH_ARG := $(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH))
 endif
-
-$(full_target): $(full_src_files) $(full_java_libs)
+$(full_target): $(full_src_files) $(LOCAL_GENERATED_SOURCES) $(full_java_libs) $(EXTRACT_SRCJARS) $(LOCAL_SRCJARS) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	@echo Docs javadoc: $(PRIVATE_OUT_DIR)
 	@mkdir -p $(dir $@)
+	rm -rf $(PRIVATE_SRCJAR_INTERMEDIATES_DIR)
 	$(call prepare-doc-source-list,$(PRIVATE_SRC_LIST_FILE),$(PRIVATE_JAVA_FILES), \
 			$(PRIVATE_SOURCE_INTERMEDIATES_DIR) $(PRIVATE_ADDITIONAL_JAVA_DIR))
+	$(EXTRACT_SRCJARS) $(PRIVATE_SRCJAR_INTERMEDIATES_DIR) $(PRIVATE_SRCJAR_LIST_FILE) $(PRIVATE_SRCJARS)
 	$(hide) ( \
 		$(JAVADOC) \
                 -encoding UTF-8 \
                 $(PRIVATE_DROIDDOC_OPTIONS) \
                 \@$(PRIVATE_SRC_LIST_FILE) \
+                \@$(PRIVATE_SRCJAR_LIST_FILE) \
                 -J-Xmx1024m \
                 -XDignore.symbol.file \
                 -Xdoclint:none \
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 509e7f6..e220fae 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -285,9 +285,14 @@
 endif
 
 # Check BOARD_VNDK_VERSION
+define check_vndk_version
+  $(eval vndk_path := prebuilts/vndk/v$(1)) \
+  $(if $(wildcard $(vndk_path)/Android.bp),,$(error VNDK version $(1) not found))
+endef
+
 ifdef BOARD_VNDK_VERSION
   ifneq ($(BOARD_VNDK_VERSION),current)
-    $(error BOARD_VNDK_VERSION: Only "current" is implemented)
+    $(call check_vndk_version,$(BOARD_VNDK_VERSION))
   endif
 
   TARGET_VENDOR_TEST_SUFFIX := /vendor
@@ -295,6 +300,10 @@
   TARGET_VENDOR_TEST_SUFFIX :=
 endif
 
+ifdef PRODUCT_EXTRA_VNDK_VERSIONS
+  $(foreach v,$(PRODUCT_EXTRA_VNDK_VERSIONS),$(call check_vndk_version,$(v)))
+endif
+
 # ---------------------------------------------------------------
 # Set up configuration for target machine.
 # The following must be set:
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index a522f0b..1b3f967 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -186,8 +186,8 @@
 endif # !LOCAL_IS_STATIC_JAVA_LIBRARY
 
 ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
-  my_default_app_target_sdk := $(LOCAL_SDK_VERSION)
-  my_sdk_version := $(LOCAL_SDK_VERSION)
+  my_default_app_target_sdk := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
+  my_sdk_version := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
 else
   my_default_app_target_sdk := $(DEFAULT_APP_TARGET_SDK)
   my_sdk_version := $(PLATFORM_SDK_VERSION)
diff --git a/core/install_jni_libs.mk b/core/install_jni_libs.mk
index 6b550c1..625a8a2 100644
--- a/core/install_jni_libs.mk
+++ b/core/install_jni_libs.mk
@@ -18,19 +18,9 @@
 ifneq ($(filter tests samples, $(LOCAL_MODULE_TAGS)),)
 my_embed_jni := true
 endif
-ifeq ($(PRODUCT_FULL_TREBLE),true)
-  ifeq ($(filter $(TARGET_OUT)/%, $(my_module_path)),)
-    # If this app isn't to be installed to the system partition, and the device
-    # is fully treble-ized then jni libs are embedded, Otherwise, access to the
-    # directory where the lib is installed to (usually /vendor/lib) needs to be
-    # allowed for system processes, which is a Treble violation.
-    my_embed_jni := true
-  endif
-else
-  ifeq ($(filter $(TARGET_OUT)/% $(TARGET_OUT_VENDOR)/% $(TARGET_OUT_OEM)/%, $(my_module_path)),)
-    # If this app isn't to be installed to system, vendor, or oem partitions.
-    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
 endif
 
 jni_shared_libraries :=
diff --git a/core/jacoco.mk b/core/jacoco.mk
index 9e6fd07..f51790d 100644
--- a/core/jacoco.mk
+++ b/core/jacoco.mk
@@ -19,41 +19,22 @@
 # (at the time of authorship, it is included by java.mk and
 # java_host_library.mk)
 
-my_include_filter :=
-my_exclude_filter :=
+# determine Jacoco include/exclude filters even when coverage is not enabled
+# to get syntax checking on LOCAL_JACK_COVERAGE_(INCLUDE|EXCLUDE)_FILTER
+# copy filters from Jack but also skip some known java packages
+my_include_filter := $(strip $(LOCAL_JACK_COVERAGE_INCLUDE_FILTER))
+my_exclude_filter := $(strip $(DEFAULT_JACOCO_EXCLUDE_FILTER),$(LOCAL_JACK_COVERAGE_EXCLUDE_FILTER))
+
+my_include_args := $(call jacoco-class-filter-to-file-args, $(my_include_filter))
+my_exclude_args := $(call jacoco-class-filter-to-file-args, $(my_exclude_filter))
+
+# single-quote each arg of the include args so the '*' gets evaluated by zip
+# don't quote the exclude args they need to be evaluated by bash for rm -rf
+my_include_args := $(foreach arg,$(my_include_args),'$(arg)')
 
 ifeq ($(LOCAL_EMMA_INSTRUMENT),true)
-  # determine Jacoco include/exclude filters
-  DEFAULT_JACOCO_EXCLUDE_FILTER := org/junit/*,org/jacoco/*,org/mockito/*
-  # copy filters from Jack but also skip some known java packages
-  my_include_filter := $(strip $(LOCAL_JACK_COVERAGE_INCLUDE_FILTER))
-  my_exclude_filter := $(strip $(DEFAULT_JACOCO_EXCLUDE_FILTER),$(LOCAL_JACK_COVERAGE_EXCLUDE_FILTER))
-
-  # replace '.' with '/' and ',' with ' ', and quote each arg
-  ifneq ($(strip $(my_include_filter)),)
-    my_include_args := $(strip $(my_include_filter))
-
-    my_include_args := $(subst .,/,$(my_include_args))
-    my_include_args := '$(subst $(comma),' ',$(my_include_args))'
-  else
-    my_include_args :=
-  endif
-
-  # replace '.' with '/' and ',' with ' '
-  ifneq ($(strip $(my_exclude_filter)),)
-    my_exclude_args := $(my_exclude_filter)
-
-    my_exclude_args := $(subst .,/,$(my_exclude_args))
-    my_exclude_args := $(subst $(comma)$(comma),$(comma),$(my_exclude_args))
-    my_exclude_args := $(subst $(comma), ,$(my_exclude_args))
-  else
-    my_exclude_args :=
-  endif
-
   my_files := $(intermediates.COMMON)/jacoco
 
-  $(call validate-paths-are-subdirs,$(my_exclude_args))
-
   # make a task that unzips the classes that we want to instrument from the
   # input jar
   my_unzipped_path := $(my_files)/work/classes-to-instrument/classes
diff --git a/core/java.mk b/core/java.mk
index 71bed38..817f81a 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -135,7 +135,7 @@
   ifneq (,$(LOCAL_SDK_VERSION))
     # Set target-api for LOCAL_SDK_VERSIONs other than current.
     ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
-      renderscript_target_api := $(LOCAL_SDK_VERSION)
+      renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
     endif
   endif  # LOCAL_SDK_VERSION is set
 endif  # LOCAL_RENDERSCRIPT_TARGET_API is set
@@ -555,7 +555,9 @@
 
 $(eval $(call copy-one-file,$(full_classes_jarjar_jar),$(full_classes_jar)))
 
-ifeq ($(EXPERIMENTAL_USE_OPENJDK9),true)
+# Temporarily enable --multi-dex until proguard supports v53 class files
+# ( http://b/67673860 ) or we move away from proguard altogether.
+ifdef TARGET_OPENJDK9
 LOCAL_DX_FLAGS := $(filter-out --multi-dex,$(LOCAL_DX_FLAGS)) --multi-dex
 endif
 
@@ -752,7 +754,7 @@
 $(built_dex_intermediate): PRIVATE_PROGUARD_INJAR_FILTERS := $(proguard_injar_filters)
 $(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) : $(full_classes_proguard_jar) $(extra_input_jar) $(my_support_library_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) $(legacy_proguard_lib_deps) $(R8_COMPAT_PROGUARD_JAR)
+$(built_dex_intermediate) : $(full_classes_proguard_jar) $(extra_input_jar) $(my_support_library_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) $(legacy_proguard_lib_deps) $(R8_COMPAT_PROGUARD)
 	$(transform-jar-to-dex-r8)
 endif # USE_R8
 endif # LOCAL_PROGUARD_ENABLED
@@ -799,8 +801,8 @@
 endif  # full_classes_jar is defined
 
 ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
-  my_default_app_target_sdk := $(LOCAL_SDK_VERSION)
-  my_sdk_version := $(LOCAL_SDK_VERSION)
+  my_default_app_target_sdk := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
+  my_sdk_version := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
 else
   my_default_app_target_sdk := $(DEFAULT_APP_TARGET_SDK)
   my_sdk_version := $(PLATFORM_SDK_VERSION)
diff --git a/core/java_common.mk b/core/java_common.mk
index 37de700..a90c779 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -23,8 +23,7 @@
     # TODO(ccross): allow 1.9 for current and unbundled once we have SDK system modules
     LOCAL_JAVA_LANGUAGE_VERSION := 1.8
   else
-    # DEFAULT_JAVA_LANGUAGE_VERSION is 1.8 unless EXPERIMENTAL_USE_OPENJDK9=true
-    # in which case it is 1.9
+    # DEFAULT_JAVA_LANGUAGE_VERSION is 1.8, unless TARGET_OPENJDK9 in which case it is 1.9
     LOCAL_JAVA_LANGUAGE_VERSION := $(DEFAULT_JAVA_LANGUAGE_VERSION)
   endif
 endif
@@ -230,8 +229,16 @@
     else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),test_current)
       full_java_bootclasspath_libs := $(call java-lib-header-files,android_test_stubs_current)
     else
-      full_java_bootclasspath_libs := $(call java-lib-header-files,sdk_v$(LOCAL_SDK_VERSION))
-    endif # current, system_current, or test_current
+      ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
+        ifeq (,$(TARGET_BUILD_APPS))
+          full_java_bootclasspath_libs := $(call java-lib-header-files,system_sdk_v$(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION)))
+        else
+          full_java_bootclasspath_libs := $(call java-lib-header-files,sdk_v$(LOCAL_SDK_VERSION))
+        endif
+      else
+        full_java_bootclasspath_libs := $(call java-lib-header-files,sdk_v$(LOCAL_SDK_VERSION))
+      endif
+    endif # current, system_current, system_${VER} or test_current
   endif # LOCAL_SDK_VERSION
 
   ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
@@ -405,6 +412,10 @@
 my_link_type := java:system
 my_warn_types := java:platform
 my_allowed_types := java:sdk java:system
+else ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
+my_link_type := java:system
+my_warn_types := java:platform
+my_allowed_types := java:sdk java:system
 else ifneq ($(LOCAL_SDK_VERSION),)
 my_link_type := java:sdk
 my_warn_types := java:system java:platform
@@ -415,7 +426,14 @@
 my_allowed_types := java:sdk java:system java:platform
 endif
 
-my_link_deps := $(addprefix JAVA_LIBRARIES:,$(LOCAL_STATIC_JAVA_LIBRARIES))
+ifdef LOCAL_AAPT2_ONLY
+my_link_type += aapt2_only
+endif
+ifdef LOCAL_USE_AAPT2
+my_allowed_types += aapt2_only
+endif
+
+my_link_deps := $(addprefix JAVA_LIBRARIES:,$(LOCAL_STATIC_JAVA_LIBRARIES) $(LOCAL_JAVA_LIBRARIES))
 my_link_deps += $(addprefix APPS:,$(apk_libraries))
 
 my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
diff --git a/core/local_vndk.mk b/core/local_vndk.mk
index 640aac7..3677d40 100644
--- a/core/local_vndk.mk
+++ b/core/local_vndk.mk
@@ -5,10 +5,8 @@
 ifndef LOCAL_SDK_VERSION
   ifneq (,$(filter true,$(LOCAL_VENDOR_MODULE) $(LOCAL_ODM_MODULE) $(LOCAL_OEM_MODULE) $(LOCAL_PROPRIETARY_MODULE)))
     LOCAL_USE_VNDK:=true
-  else
-    ifneq (,$(filter $(TARGET_OUT_VENDOR)%,$(LOCAL_MODULE_PATH) $(LOCAL_MODULE_PATH_32) $(LOCAL_MODULE_PATH_64)))
-      LOCAL_USE_VNDK:=true
-    endif
+    # Note: no need to check LOCAL_MODULE_PATH* since LOCAL_[VENDOR|ODM|OEM]_MODULE is already
+    # set correctly before this is included.
   endif
 endif
 endif
diff --git a/core/local_vsdk.mk b/core/local_vsdk.mk
new file mode 100644
index 0000000..f798d47
--- /dev/null
+++ b/core/local_vsdk.mk
@@ -0,0 +1,19 @@
+
+ifdef BOARD_VSDK_VERSION
+# Set LOCAL_SDK_VERSION to system_current, If LOCAL_SDK_VERSION is not defined and LOCAL_VENDOR_MODULE is true
+  _is_vendor_app :=
+  ifneq (,$(filter true,$(LOCAL_VENDOR_MODULE) $(LOCAL_ODM_MODULE) $(LOCAL_OEM_MODULE) $(LOCAL_PROPRIETARY_MODULE)))
+    _is_vendor_app := true
+  else
+    ifneq (,$(filter $(TARGET_OUT_VENDOR)%,$(LOCAL_MODULE_PATH) $(LOCAL_MODULE_PATH_32) $(LOCAL_MODULE_PATH_64)))
+      _is_vendor_app := true
+    endif
+  endif
+  ifneq (,$(filter JAVA_LIBRARIES APPS,$(LOCAL_MODULE_CLASS)))
+    ifndef LOCAL_SDK_VERSION
+      ifeq ($(_is_vendor_app),true)
+        LOCAL_SDK_VERSION := system_current
+      endif
+    endif
+  endif
+endif
diff --git a/core/main.mk b/core/main.mk
index 6f7366d..ea907fc 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -97,11 +97,21 @@
 # (must be defined before including definitions.make)
 INTERNAL_MODIFIER_TARGETS := all
 
-# EMMA_INSTRUMENT_STATIC merges the static emma library to each emma-enabled module.
+# EMMA_INSTRUMENT_STATIC merges the static jacoco library to each
+# jacoco-enabled module.
 ifeq (true,$(EMMA_INSTRUMENT_STATIC))
 EMMA_INSTRUMENT := true
 endif
 
+ifeq (true,$(EMMA_INSTRUMENT))
+# Adding the jacoco library can cause the inclusion of
+# some typically banned classes
+# So if the user didn't specify SKIP_BOOT_JARS_CHECK, enable it here
+ifndef SKIP_BOOT_JARS_CHECK
+SKIP_BOOT_JARS_CHECK := true
+endif
+endif
+
 #
 # -----------------------------------------------------------------
 # Validate ADDITIONAL_DEFAULT_PROPERTIES.
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 9bf173f..2a84b4f 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -146,6 +146,10 @@
 need_compile_asset := true
 endif
 
+ifdef LOCAL_AAPT2_ONLY
+LOCAL_USE_AAPT2 := true
+endif
+
 my_res_package :=
 ifdef LOCAL_USE_AAPT2
 # In aapt2 the last takes precedence.
@@ -361,7 +365,7 @@
 ifneq (,$(LOCAL_SDK_VERSION))
 # Set target-api for LOCAL_SDK_VERSIONs other than current.
 ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
-renderscript_target_api := $(LOCAL_SDK_VERSION)
+renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
 endif
 endif  # LOCAL_SDK_VERSION is set
 endif  # LOCAL_RENDERSCRIPT_TARGET_API is set
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 48e410b..f4b143c 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -216,7 +216,7 @@
     else
       my_coverage_path := $(TARGET_OUT_COVERAGE)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
     endif
-    my_coverage_path := $(my_coverage_path)/$(basename $(my_installed_module_stem)).gcnodir
+    my_coverage_path := $(my_coverage_path)/$(patsubst %.so,%,$(my_installed_module_stem)).gcnodir
     $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(my_coverage_path)))
     $(LOCAL_BUILT_MODULE): $(my_coverage_path)
   endif
@@ -500,6 +500,8 @@
 
 ifeq ($(LOCAL_SDK_VERSION),system_current)
 my_link_type := java:system
+else ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
+my_link_type := java:system
 else ifneq ($(LOCAL_SDK_VERSION),)
 my_link_type := java:sdk
 else
@@ -547,6 +549,10 @@
 $(common_javalib_jar) : $(common_classes_jar)
 	$(transform-prebuilt-to-target)
 
+ifdef LOCAL_AAPT2_ONLY
+LOCAL_USE_AAPT2 := true
+endif
+
 ifdef LOCAL_USE_AAPT2
 ifneq ($(my_src_aar),)
 LOCAL_SDK_RES_VERSION:=$(strip $(LOCAL_SDK_RES_VERSION))
diff --git a/core/product.mk b/core/product.mk
index c01a856..f15f6b3 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -102,6 +102,7 @@
     PRODUCT_SDK_ADDON_COPY_MODULES \
     PRODUCT_SDK_ADDON_DOC_MODULES \
     PRODUCT_SDK_ADDON_SYS_IMG_SOURCE_PROP \
+    PRODUCT_SOONG_NAMESPACES \
     PRODUCT_DEFAULT_WIFI_CHANNELS \
     PRODUCT_DEFAULT_DEV_CERTIFICATE \
     PRODUCT_RESTRICT_VENDOR_FILES \
diff --git a/core/product_config.mk b/core/product_config.mk
index 4e2d5ae..5b0e257 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -480,3 +480,7 @@
 # Whether any paths should have CFI enabled for components
 PRODUCT_CFI_INCLUDE_PATHS := \
     $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_CFI_INCLUDE_PATHS))
+
+# which Soong namespaces to export to Make
+PRODUCT_SOONG_NAMESPACES :=
+    $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SOONG_NAMESPACES))
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
new file mode 100644
index 0000000..0b8fa4d
--- /dev/null
+++ b/core/soong_app_prebuilt.mk
@@ -0,0 +1,74 @@
+# App prebuilt coming from Soong.
+# Extra inputs:
+# LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE
+
+ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+  $(call pretty-error,soong_app_prebuilt.mk may only be used from Soong)
+endif
+
+LOCAL_MODULE_SUFFIX := .apk
+LOCAL_BUILT_MODULE_STEM := package.apk
+
+#######################################
+include $(BUILD_SYSTEM)/base_rules.mk
+#######################################
+
+ifdef LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
+  $(eval $(call copy-one-file,$(LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR),\
+    $(intermediates.COMMON)/jacoco-report-classes.jar))
+endif
+
+$(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_BUILT_MODULE)))
+
+ifdef LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE
+resource_export_package := $(intermediates.COMMON)/package-export.apk
+resource_export_stamp := $(intermediates.COMMON)/src/R.stamp
+
+$(resource_export_package): PRIVATE_STAMP := $(resource_export_stamp)
+$(resource_export_package): .KATI_IMPLICIT_OUTPUTS := $(resource_export_stamp)
+$(resource_export_package): $(LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE)
+	@echo "Copy: $$@"
+	$(copy-file-to-target)
+	touch $(PRIVATE_STAMP)
+
+endif # LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE
+
+java-dex: $(LOCAL_SOONG_DEX_JAR)
+
+ifdef LOCAL_DEX_PREOPT
+# defines built_odex along with rule to install odex
+include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
+
+$(built_odex): $(LOCAL_SOONG_DEX_JAR)
+	$(call dexpreopt-one-file,$<,$@)
+endif
+
+ifndef LOCAL_IS_HOST_MODULE
+ifeq ($(LOCAL_SDK_VERSION),system_current)
+my_link_type := java:system
+my_warn_types := java:platform
+my_allowed_types := java:sdk java:system
+else ifneq ($(LOCAL_SDK_VERSION),)
+my_link_type := java:sdk
+my_warn_types := java:system java:platform
+my_allowed_types := java:sdk
+else
+my_link_type := java:platform
+my_warn_types :=
+my_allowed_types := java:sdk java:system java:platform
+endif
+
+my_link_deps :=
+my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+my_common := COMMON
+include $(BUILD_SYSTEM)/link_type.mk
+endif # !LOCAL_IS_HOST_MODULE
+
+ifdef LOCAL_SOONG_RRO_DIRS
+  $(call append_enforce_rro_sources, \
+      $(my_register_name), \
+      false, \
+      $(LOCAL_FULL_MANIFEST_FILE), \
+      $(LOCAL_EXPORT_PACKAGE_RESOURCES), \
+      $(LOCAL_SOONG_RRO_DIRS))
+endif
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 5ebd123..f1f1e09 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -81,6 +81,8 @@
 $(call add_json_str,  AAPTPreferredConfig,               $(PRODUCT_AAPT_PREF_CONFIG))
 $(call add_json_list, AAPTPrebuiltDPI,                   $(PRODUCT_AAPT_PREBUILT_DPI))
 
+$(call add_json_str,  DefaultAppCertificate,             $(PRODUCT_DEFAULT_DEV_CERTIFICATE))
+
 $(call add_json_str,  AppsDefaultVersionName,            $(APPS_DEFAULT_VERSION_NAME))
 
 $(call add_json_list, SanitizeHost,                      $(SANITIZE_HOST))
@@ -110,6 +112,7 @@
 $(call add_json_bool, DevicePrefer32BitExecutables,      $(filter true,$(TARGET_PREFER_32_BIT_EXECUTABLES)))
 $(call add_json_val,  DeviceUsesClang,                   $(if $(USE_CLANG_PLATFORM_BUILD),$(USE_CLANG_PLATFORM_BUILD),false))
 $(call add_json_str,  DeviceVndkVersion,                 $(BOARD_VNDK_VERSION))
+$(call add_json_list, ExtraVndkVersions,                 $(PRODUCT_EXTRA_VNDK_VERSIONS))
 $(call add_json_bool, Malloc_not_svelte,                 $(call invert_bool,$(filter true,$(MALLOC_SVELTE))))
 $(call add_json_str,  Override_rs_driver,                $(OVERRIDE_RS_DRIVER))
 $(call add_json_bool, Treble,                            $(filter true,$(PRODUCT_FULL_TREBLE)))
@@ -119,6 +122,10 @@
 
 $(call add_json_bool, UseGoma,                           $(filter-out false,$(USE_GOMA)))
 
+$(call add_json_str,  DistDir,                           $(if $(dist_goal), $(DIST_DIR)))
+
+$(call add_json_list, NamespacesToExport,                $(PRODUCT_SOONG_NAMESPACES))
+
 _contents := $(subst $(comma)$(newline)__SV_END,$(newline)}$(newline),$(_contents)__SV_END)
 
 $(file >$(SOONG_VARIABLES).tmp,$(_contents))
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 53ad50d..e7f5fa5 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -2,6 +2,7 @@
 # Extra inputs:
 # LOCAL_SOONG_HEADER_JAR
 # LOCAL_SOONG_DEX_JAR
+# LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
 
 ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
   $(call pretty-error,soong_java_prebuilt.mk may only be used from Soong)
@@ -15,16 +16,17 @@
 #######################################
 
 full_classes_jar := $(intermediates.COMMON)/classes.jar
+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
 
-LOCAL_FULL_CLASSES_PRE_JACOCO_JAR := $(LOCAL_PREBUILT_MODULE_FILE)
+$(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)))
 
-#######################################
-include $(BUILD_SYSTEM)/jacoco.mk
-#######################################
-
-$(eval $(call copy-one-file,$(LOCAL_FULL_CLASSES_JACOCO_JAR),$(full_classes_jar)))
+ifdef LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
+  $(eval $(call copy-one-file,$(LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR),\
+    $(intermediates.COMMON)/jacoco-report-classes.jar))
+endif
 
 ifneq ($(TURBINE_DISABLED),false)
 ifdef LOCAL_SOONG_HEADER_JAR
@@ -79,6 +81,10 @@
 my_link_type := java:system
 my_warn_types := java:platform
 my_allowed_types := java:sdk java:system
+else ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
+my_link_type := java:system
+my_warn_types := java:platform
+my_allowed_types := java:sdk java:system
 else ifneq ($(LOCAL_SDK_VERSION),)
 my_link_type := java:sdk
 my_warn_types := java:system java:platform
@@ -94,7 +100,3 @@
 my_common := COMMON
 include $(BUILD_SYSTEM)/link_type.mk
 endif # !LOCAL_IS_HOST_MODULE
-
-# Built in equivalent to include $(CLEAR_VARS)
-LOCAL_SOONG_HEADER_JAR :=
-LOCAL_SOONG_DEX_JAR :=
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 69cf955..6645af5 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -28,6 +28,10 @@
 
 my_res_package :=
 
+ifdef LOCAL_AAPT2_ONLY
+LOCAL_USE_AAPT2 := true
+endif
+
 # Hack to build static Java library with Android resource
 # See bug 5714516
 all_resources :=
@@ -146,7 +150,7 @@
 ifneq (,$(LOCAL_SDK_VERSION))
 # Set target-api for LOCAL_SDK_VERSIONs other than current.
 ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
-renderscript_target_api := $(LOCAL_SDK_VERSION)
+renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
 endif
 endif  # LOCAL_SDK_VERSION is set
 endif  # LOCAL_RENDERSCRIPT_TARGET_API is set
diff --git a/core/tasks/collect_gpl_sources.mk b/core/tasks/collect_gpl_sources.mk
index 30ba62b..70f0afe 100644
--- a/core/tasks/collect_gpl_sources.mk
+++ b/core/tasks/collect_gpl_sources.mk
@@ -12,20 +12,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-gpl_source_tgz := $(call intermediates-dir-for,PACKAGING,gpl_source,HOST,COMMON)/gpl_source.tgz
+ifdef dist_goal
+
+# The rule below doesn't have dependenices on the files that it copies,
+# so manually generate directly into the DIST_DIR directory that is always
+# wiped between dist builds.
+gpl_source_tgz := $(DIST_DIR)/gpl_source.tgz
 
 # FORCE since we can't know whether any of the sources changed
 $(gpl_source_tgz): PRIVATE_PATHS := $(sort $(patsubst %/, %, $(dir $(ALL_GPL_MODULE_LICENSE_FILES))))
-$(gpl_source_tgz) : $(ALL_GPL_MODULE_LICENSE_FILES) FORCE
+$(gpl_source_tgz) : $(ALL_GPL_MODULE_LICENSE_FILES)
 	@echo Package gpl sources: $@
-	@rm -rf $(dir $@) && mkdir -p $(dir $@)
 	$(hide) tar cfz $@ --exclude ".git*" $(PRIVATE_PATHS)
 
-
-.PHONY: gpl_source_tgz
-gpl_source_tgz : $(gpl_source_tgz)
-
 # Dist the tgz only if we are doing a full build
 ifeq (,$(TARGET_BUILD_APPS))
-$(call dist-for-goals, droidcore, $(gpl_source_tgz))
+droidcore: $(gpl_source_tgz)
 endif
+
+endif # dist_goal
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index e9b2ac7..f6d688c 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -11,6 +11,7 @@
 			'"path": [$(foreach w,$(sort $(ALL_MODULES.$(m).PATH)),"$(w)", )], ' \
 			'"tags": [$(foreach w,$(sort $(ALL_MODULES.$(m).TAGS)),"$(w)", )], ' \
 			'"installed": [$(foreach w,$(sort $(ALL_MODULES.$(m).INSTALLED)),"$(w)", )], ' \
+			'"compatibility_suites": [$(foreach w,$(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES)),"$(w)", )], ' \
 			'},\n' \
 	 ) | sed -e 's/, *\]/]/g' -e 's/, *\}/ }/g' -e '$$s/,$$//' >> $@
 	$(hide) echo '}' >> $@
diff --git a/core/tasks/vndk.mk b/core/tasks/vndk.mk
new file mode 100644
index 0000000..962fae1
--- /dev/null
+++ b/core/tasks/vndk.mk
@@ -0,0 +1,207 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+current_makefile := $(lastword $(MAKEFILE_LIST))
+
+# BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
+ifeq ($(BOARD_VNDK_VERSION),current)
+
+# Returns arch-specific libclang_rt.ubsan* library name.
+# Because VNDK_CORE_LIBRARIES includes all arch variants for libclang_rt.ubsan*
+# libs, the arch-specific libs are selected separately.
+#
+# Args:
+#   $(1): if not empty, evaluates for TARGET_2ND_ARCH
+define clang-ubsan-vndk-core
+$(strip \
+  $(eval prefix := $(if $(1),2ND_,)) \
+  $(addsuffix .vendor,$($(addprefix $(prefix),UBSAN_RUNTIME_LIBRARY))) \
+)
+endef
+
+# Returns list of file paths of the intermediate objs
+#
+# Args:
+#   $(1): list of obj names (e.g., libfoo.vendor, ld.config.txt, ...)
+#   $(2): target class (e.g., SHARED_LIBRARIES, STATIC_LIBRARIES, ETC)
+#   $(3): if not empty, evaluates for TARGET_2ND_ARCH
+define paths-of-intermediates
+$(strip \
+  $(foreach obj,$(1), \
+    $(eval file_name := $(if $(filter SHARED_LIBRARIES,$(2)),$(patsubst %.so,%,$(obj)).so,$(obj))) \
+    $(eval dir := $(call intermediates-dir-for,$(2),$(obj),,,$(3))) \
+    $(call append-path,$(dir),$(file_name)) \
+  ) \
+)
+endef
+
+# If in the future libclang_rt.ubsan* is removed from the VNDK-core list,
+# need to update the related logic in this file.
+ifeq (,$(filter libclang_rt.ubsan%,$(VNDK_CORE_LIBRARIES)))
+  $(warning libclang_rt.ubsan* is no longer a VNDK-core library. Please update this file.)
+  vndk_core_libs := $(addsuffix .vendor,$(VNDK_CORE_LIBRARIES))
+else
+  vndk_core_libs := $(addsuffix .vendor,$(filter-out libclang_rt.ubsan%,$(VNDK_CORE_LIBRARIES)))
+
+  # for TARGET_ARCH
+  vndk_core_libs += $(call clang-ubsan-vndk-core)
+
+  # TODO(b/69834489): Package additional arch variants
+  # ifdef TARGET_2ND_ARCH
+  #   vndk_core_libs += $(call clang-ubsan-vndk-core,true)
+  # endif
+endif
+
+vndk_sp_libs := $(addsuffix .vendor,$(VNDK_SAMEPROCESS_LIBRARIES))
+vndk_private_libs := $(addsuffix .vendor,$(VNDK_PRIVATE_LIBRARIES))
+
+vndk_snapshot_libs := \
+  $(vndk_core_libs) \
+  $(vndk_sp_libs)
+
+vndk_prebuilt_txts := \
+  ld.config.txt \
+  vndksp.libraries.txt \
+  llndk.libraries.txt
+
+vndk_snapshot_top := $(call intermediates-dir-for,PACKAGING,vndk-snapshot)
+vndk_snapshot_out := $(vndk_snapshot_top)/vndk-snapshot
+vndk_snapshot_configs_out := $(vndk_snapshot_top)/configs
+
+#######################################
+# vndkcore.libraries.txt
+vndkcore.libraries.txt := $(vndk_snapshot_configs_out)/vndkcore.libraries.txt
+$(vndkcore.libraries.txt): $(vndk_core_libs)
+	@echo 'Generating: $@'
+	@rm -f $@
+	@mkdir -p $(dir $@)
+	$(hide) echo -n > $@
+	$(hide) $(foreach lib,$^,echo $(patsubst %.vendor,%,$(lib)).so >> $@;)
+
+
+#######################################
+# vndkprivate.libraries.txt
+vndkprivate.libraries.txt := $(vndk_snapshot_configs_out)/vndkprivate.libraries.txt
+$(vndkprivate.libraries.txt): $(vndk_private_libs)
+	@echo 'Generating: $@'
+	@rm -f $@
+	@mkdir -p $(dir $@)
+	$(hide) echo -n > $@
+	$(hide) $(foreach lib,$^,echo $(patsubst %.vendor,%,$(lib)).so >> $@;)
+
+
+vndk_snapshot_configs := \
+  $(vndkcore.libraries.txt) \
+  $(vndkprivate.libraries.txt)
+
+#######################################
+# vndk_snapshot_zip
+vndk_snapshot_arch := $(vndk_snapshot_out)/arch-$(TARGET_ARCH)-$(TARGET_ARCH_VARIANT)
+vndk_snapshot_zip := $(PRODUCT_OUT)/android-vndk-$(TARGET_ARCH).zip
+
+$(vndk_snapshot_zip): PRIVATE_VNDK_SNAPSHOT_OUT := $(vndk_snapshot_out)
+
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT := $(vndk_snapshot_arch)/shared/vndk-core
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES := \
+  $(call paths-of-intermediates,$(vndk_core_libs),SHARED_LIBRARIES)
+
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT := $(vndk_snapshot_arch)/shared/vndk-sp
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES := \
+  $(call paths-of-intermediates,$(vndk_sp_libs),SHARED_LIBRARIES)
+
+$(vndk_snapshot_zip): PRIVATE_CONFIGS_OUT := $(vndk_snapshot_arch)/configs
+$(vndk_snapshot_zip): PRIVATE_CONFIGS_INTERMEDIATES := \
+  $(call paths-of-intermediates,$(vndk_prebuilt_txts),ETC) \
+  $(vndk_snapshot_configs)
+
+# TODO(b/69834489): Package additional arch variants
+# ifdef TARGET_2ND_ARCH
+# vndk_snapshot_arch_2ND := $(vndk_snapshot_out)/arch-$(TARGET_2ND_ARCH)-$(TARGET_2ND_ARCH_VARIANT)
+# $(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT_2ND := $(vndk_snapshot_arch_2ND)/shared/vndk-core
+# $(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES_2ND := \
+#   $(call paths-of-intermediates,$(vndk_core_libs),SHARED_LIBRARIES,true)
+# $(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT_2ND := $(vndk_snapshot_arch_2ND)/shared/vndk-sp
+# $(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES_2ND := \
+#   $(call paths-of-intermediates,$(vndk_sp_libs),SHARED_LIBRARIES,true)
+# endif
+
+# Args
+#   $(1): destination directory
+#   $(2): list of files to copy
+$(vndk_snapshot_zip): private-copy-vndk-intermediates = \
+  $(if $(2),$(strip \
+    @mkdir -p $(1); \
+    $(foreach file,$(2), \
+      if [ -e $(file) ]; then \
+        cp -p $(file) $(call append-path,$(1),$(subst .vendor,,$(notdir $(file)))); \
+      fi; \
+    ) \
+  ))
+
+vndk_snapshot_dependencies := \
+  $(vndk_snapshot_libs) \
+  $(vndk_prebuilt_txts) \
+  $(vndk_snapshot_configs)
+
+$(vndk_snapshot_zip): $(vndk_snapshot_dependencies) $(SOONG_ZIP)
+	@echo 'Generating VNDK snapshot: $@'
+	@rm -f $@
+	@rm -rf $(PRIVATE_VNDK_SNAPSHOT_OUT)
+	@mkdir -p $(PRIVATE_VNDK_SNAPSHOT_OUT)
+	$(call private-copy-vndk-intermediates, \
+		$(PRIVATE_VNDK_CORE_OUT),$(PRIVATE_VNDK_CORE_INTERMEDIATES))
+	$(call private-copy-vndk-intermediates, \
+		$(PRIVATE_VNDK_SP_OUT),$(PRIVATE_VNDK_SP_INTERMEDIATES))
+	$(call private-copy-vndk-intermediates, \
+		$(PRIVATE_CONFIGS_OUT),$(PRIVATE_CONFIGS_INTERMEDIATES))
+# TODO(b/69834489): Package additional arch variants
+# ifdef TARGET_2ND_ARCH
+# 	$(call private-copy-vndk-intermediates, \
+# 		$(PRIVATE_VNDK_CORE_OUT_2ND),$(PRIVATE_VNDK_CORE_INTERMEDIATES_2ND))
+# 	$(call private-copy-vndk-intermediates, \
+# 		$(PRIVATE_VNDK_SP_OUT_2ND),$(PRIVATE_VNDK_SP_INTERMEDIATES_2ND))
+# endif
+	$(hide) $(SOONG_ZIP) -o $@ -C $(PRIVATE_VNDK_SNAPSHOT_OUT) -D $(PRIVATE_VNDK_SNAPSHOT_OUT)
+
+.PHONY: vndk
+vndk: $(vndk_snapshot_zip)
+
+$(call dist-for-goals, vndk, $(vndk_snapshot_zip))
+
+# clear global vars
+clang-ubsan-vndk-core :=
+paths-of-intermediates :=
+vndk_core_libs :=
+vndk_sp_libs :=
+vndk_snapshot_libs :=
+vndk_prebuilt_txts :=
+vndk_snapshot_configs :=
+vndk_snapshot_top :=
+vndk_snapshot_out :=
+vndk_snapshot_configs_out :=
+vndk_snapshot_arch :=
+vndk_snapshot_dependencies :=
+# TODO(b/69834489): Package additional arch variants
+# ifdef TARGET_2ND_ARCH
+# vndk_snapshot_arch_2ND :=
+# endif
+
+else # BOARD_VNDK_VERSION is NOT set to 'current'
+
+.PHONY: vndk
+vndk:
+	$(call echo-error,$(current_makefile),CANNOT generate VNDK snapshot. BOARD_VNDK_VERSION must be set to 'current'.)
+	exit 1
+
+endif # BOARD_VNDK_VERSION
diff --git a/help.sh b/help.sh
index c031dcc..3f39c77 100755
--- a/help.sh
+++ b/help.sh
@@ -15,7 +15,7 @@
 m -j [<goals>]              # Execute the configured build.
 
 Usage of "m" imitates usage of the program "make".
-See '"${SCRIPT_DIR}"'/README.txt for more info about build usage and concepts.
+See '"${SCRIPT_DIR}"'/Usage.txt for more info about build usage and concepts.
 
 Common goals are:
 
diff --git a/navbar.md b/navbar.md
new file mode 100644
index 0000000..e218a78
--- /dev/null
+++ b/navbar.md
@@ -0,0 +1,4 @@
+* [Home](/README.md)
+* [Usage](/Usage.txt)
+* [Changes](/Changes.md)
+* [Outdated Reference](/core/build-system.html)
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index 331f082..8d93f75 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -57,11 +57,13 @@
 # when finalizing them.
 BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
 BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
 DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
 
 BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy
 BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
+
+# Enable A/B update
+TARGET_NO_RECOVERY := true
+BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic/sepolicy/bootanim.te b/target/board/generic/sepolicy/bootanim.te
index 4be1c8a..b23e1ca 100644
--- a/target/board/generic/sepolicy/bootanim.te
+++ b/target/board/generic/sepolicy/bootanim.te
@@ -2,4 +2,8 @@
 allow bootanim ashmem_device:chr_file execute;
 #TODO: This can safely be ignored until b/62954877 is fixed
 dontaudit bootanim system_data_file:dir read;
+
+allow bootanim vendor_file:file { execute getattr open read };
+allow bootanim graphics_device:chr_file { read ioctl open };
+
 set_prop(bootanim, qemu_prop)
diff --git a/target/board/generic/sepolicy/file_contexts b/target/board/generic/sepolicy/file_contexts
index f550f4d..c046434 100644
--- a/target/board/generic/sepolicy/file_contexts
+++ b/target/board/generic/sepolicy/file_contexts
@@ -23,6 +23,7 @@
 /vendor/bin/hw/android\.hardware\.drm@1\.0-service\.widevine          u:object_r:hal_drm_widevine_exec:s0
 
 /vendor/lib(64)?/hw/gralloc\.ranchu\.so   u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/hw/gralloc\.goldfish\.default\.so   u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libEGL_emulation\.so          u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libGLESv1_CM_emulation\.so    u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libGLESv2_emulation\.so       u:object_r:same_process_hal_file:s0
diff --git a/target/board/generic/sepolicy/goldfish_setup.te b/target/board/generic/sepolicy/goldfish_setup.te
index bcd49bd..eb913e9 100644
--- a/target/board/generic/sepolicy/goldfish_setup.te
+++ b/target/board/generic/sepolicy/goldfish_setup.te
@@ -4,6 +4,7 @@
 
 init_daemon_domain(goldfish_setup)
 
+set_prop(goldfish_setup, debug_prop);
 allow goldfish_setup self:capability { net_admin net_raw };
 allow goldfish_setup self:udp_socket { create ioctl };
 allow goldfish_setup vendor_toolbox_exec:file execute_no_trans;
diff --git a/target/board/generic/sepolicy/hal_graphics_allocator_default.te b/target/board/generic/sepolicy/hal_graphics_allocator_default.te
new file mode 100644
index 0000000..0c8e27d
--- /dev/null
+++ b/target/board/generic/sepolicy/hal_graphics_allocator_default.te
@@ -0,0 +1,2 @@
+allow hal_graphics_allocator_default graphics_device:dir search;
+allow hal_graphics_allocator_default graphics_device:chr_file { ioctl open read write };
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 9beb9a3..9d2ccbd 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -88,11 +88,13 @@
 # when finalizing them.
 BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
 BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
 DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
 
 BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
 BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy
+
+# Enable A/B update
+TARGET_NO_RECOVERY := true
+BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic_mips/BoardConfig.mk b/target/board/generic_mips/BoardConfig.mk
index fb66d21..523408b 100644
--- a/target/board/generic_mips/BoardConfig.mk
+++ b/target/board/generic_mips/BoardConfig.mk
@@ -65,10 +65,12 @@
 # when finalizing them.
 BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
 BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
 DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
 
 BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy
+
+# Enable A/B update
+TARGET_NO_RECOVERY := true
+BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic_mips64/BoardConfig.mk b/target/board/generic_mips64/BoardConfig.mk
index 67bb51f..2052d7b 100644
--- a/target/board/generic_mips64/BoardConfig.mk
+++ b/target/board/generic_mips64/BoardConfig.mk
@@ -80,8 +80,6 @@
 # when finalizing them.
 BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
 BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
 DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
@@ -89,3 +87,7 @@
 BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy
 
 DEX_PREOPT_DEFAULT := nostripping
+
+# Enable A/B update
+TARGET_NO_RECOVERY := true
+BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic_x86/BoardConfig.mk b/target/board/generic_x86/BoardConfig.mk
index 000a9a3..0b39af1 100644
--- a/target/board/generic_x86/BoardConfig.mk
+++ b/target/board/generic_x86/BoardConfig.mk
@@ -48,8 +48,6 @@
 # when finalizing them.
 BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
 BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
 DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
@@ -57,3 +55,7 @@
 BOARD_SEPOLICY_DIRS += \
         build/target/board/generic/sepolicy \
         build/target/board/generic_x86/sepolicy
+
+# Enable A/B update
+TARGET_NO_RECOVERY := true
+BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index 883dd2e..3a4bde6 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -50,8 +50,6 @@
 # when finalizing them.
 BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
 BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
 BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
@@ -60,3 +58,7 @@
 BOARD_SEPOLICY_DIRS += \
         build/target/board/generic/sepolicy \
         build/target/board/generic_x86/sepolicy
+
+# Enable A/B update
+TARGET_NO_RECOVERY := true
+BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/product/core_minimal.mk b/target/product/core_minimal.mk
index fc9da87..05e3b45 100644
--- a/target/product/core_minimal.mk
+++ b/target/product/core_minimal.mk
@@ -155,9 +155,13 @@
 
 # On userdebug builds, collect more tombstones by default.
 ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
     tombstoned.max_tombstone_count=50
 endif
 
+PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+    ro.logd.size.stats=64K \
+    log.tag.stats_log=I
+
 $(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/base.mk)
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
index 4e1adc8..9e684f7 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -105,7 +105,7 @@
 
 # Ensure that this property is always defined so that bionic_systrace.cpp
 # can rely on it being initially set by init.
-PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
     debug.atrace.tags.enableflags=0
 
 PRODUCT_COPY_FILES += \
diff --git a/target/product/emulator.mk b/target/product/emulator.mk
index 58245cb..cc946ca 100644
--- a/target/product/emulator.mk
+++ b/target/product/emulator.mk
@@ -26,6 +26,7 @@
 PRODUCT_PACKAGES += \
     egl.cfg \
     gralloc.goldfish \
+    gralloc.goldfish.default \
     gralloc.ranchu \
     libGLESv1_CM_emulation \
     lib_renderControl_enc \
@@ -35,6 +36,9 @@
     libOpenglSystemCommon \
     libGLESv2_emulation \
     libGLESv1_enc \
+    libEGL_swiftshader \
+    libGLESv1_CM_swiftshader \
+    libGLESv2_swiftshader \
     qemu-props \
     camera.goldfish \
     camera.goldfish.jpeg \
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 42c8ea8..6e7038e 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -89,5 +89,5 @@
     pm.dexopt.shared=speed
 
 # Enable minidebuginfo generation unless overridden.
-PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
     dalvik.vm.dex2oat-minidebuginfo=true
diff --git a/target/product/vndk/Android.mk b/target/product/vndk/Android.mk
index e7f07e7..d2d9562 100644
--- a/target/product/vndk/Android.mk
+++ b/target/product/vndk/Android.mk
@@ -96,11 +96,26 @@
 	@chmod a+x $@
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := vndk_package
+LOCAL_MODULE := vndk_current
 LOCAL_REQUIRED_MODULES := \
     $(addsuffix .vendor,$(VNDK_CORE_LIBRARIES)) \
     $(addsuffix .vendor,$(VNDK_SAMEPROCESS_LIBRARIES)) \
-    $(LLNDK_LIBRARIES)
+    $(LLNDK_LIBRARIES) \
+    llndk.libraries.txt \
+    vndksp.libraries.txt
 
 include $(BUILD_PHONY_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := vndk_package
+ifeq (current,$(BOARD_VNDK_VERSION))
+LOCAL_REQUIRED_MODULES := \
+    vndk_current
+else
+LOCAL_REQUIRED_MODULES := \
+    vndk_v$(BOARD_VNDK_VERSION)
+endif
+LOCAL_REQUIRED_MODULES += \
+    $(foreach vndk_ver,$(PRODUCT_EXTRA_VNDK_VERSIONS),vndk_v$(vndk_ver))
+include $(BUILD_PHONY_PACKAGE)
 endif # BOARD_VNDK_VERSION is set
diff --git a/tools/generate-notice-files.py b/tools/generate-notice-files.py
index adbf7c2..b754174 100755
--- a/tools/generate-notice-files.py
+++ b/tools/generate-notice-files.py
@@ -253,15 +253,12 @@
 
     filesets = [sorted(files_with_same_hash[md5]) for md5 in sorted(files_with_same_hash.keys())]
 
-    print "Combining NOTICE files into text"
     combine_notice_files_text(filesets, input_dir, txt_output_file, file_title)
 
     if html_output_file is not None:
-        print "Combining NOTICE files into HTML"
         combine_notice_files_html(filesets, input_dir, html_output_file)
 
     if xml_output_file is not None:
-        print "Combining NOTICE files into XML"
         combine_notice_files_xml(files_with_same_hash, input_dir, xml_output_file)
 
 if __name__ == "__main__":
diff --git a/tools/java-event-log-tags.py b/tools/java-event-log-tags.py
index f364751..37cd712 100755
--- a/tools/java-event-log-tags.py
+++ b/tools/java-event-log-tags.py
@@ -51,30 +51,37 @@
     print >> sys.stderr, "unhandled option %s" % (o,)
     sys.exit(1)
 
-if len(args) != 2:
-  print "need exactly two input files, not %d" % (len(args),)
+if len(args) != 1 and len(args) != 2:
+  print "need one or two input files, not %d" % (len(args),)
   print __doc__
   sys.exit(1)
 
 fn = args[0]
 tagfile = event_log_tags.TagFile(fn)
 
-# Load the merged tag file (which should have numbers assigned for all
-# tags.  Use the numbers from the merged file to fill in any missing
-# numbers from the input file.
-merged_fn = args[1]
-merged_tagfile = event_log_tags.TagFile(merged_fn)
-merged_by_name = dict([(t.tagname, t) for t in merged_tagfile.tags])
-for t in tagfile.tags:
-  if t.tagnum is None:
-    if t.tagname in merged_by_name:
-      t.tagnum = merged_by_name[t.tagname].tagnum
-    else:
-      # We're building something that's not being included in the
-      # product, so its tags don't appear in the merged file.  Assign
-      # them all an arbitrary number so we can emit the java and
-      # compile the (unused) package.
-      t.tagnum = 999999
+if len(args) > 1:
+  # Load the merged tag file (which should have numbers assigned for all
+  # tags.  Use the numbers from the merged file to fill in any missing
+  # numbers from the input file.
+  merged_fn = args[1]
+  merged_tagfile = event_log_tags.TagFile(merged_fn)
+  merged_by_name = dict([(t.tagname, t) for t in merged_tagfile.tags])
+  for t in tagfile.tags:
+    if t.tagnum is None:
+      if t.tagname in merged_by_name:
+        t.tagnum = merged_by_name[t.tagname].tagnum
+      else:
+        # We're building something that's not being included in the
+        # product, so its tags don't appear in the merged file.  Assign
+        # them all an arbitrary number so we can emit the java and
+        # compile the (unused) package.
+        t.tagnum = 999999
+else:
+  # Not using the merged tag file, so all tags must have manually assigned
+  # numbers
+  for t in tagfile.tags:
+    if t.tagnum is None:
+      tagfilef.AddError("tag \"%s\" has no number" % (tagname,), tag.linenum)
 
 if "java_package" not in tagfile.options:
   tagfile.AddError("java_package option not specified", linenum=0)
diff --git a/tools/libhost/Android.bp b/tools/libhost/Android.bp
index e5a5ecf..4c9100f 100644
--- a/tools/libhost/Android.bp
+++ b/tools/libhost/Android.bp
@@ -10,6 +10,7 @@
     name: "libhost",
     target: {
         windows: {
+            cflags: ["-Wno-unused-parameter"],
             enabled: true,
         },
     },
diff --git a/tools/libhost/CopyFile.c b/tools/libhost/CopyFile.c
index bd65f1e..f9bda86 100644
--- a/tools/libhost/CopyFile.c
+++ b/tools/libhost/CopyFile.c
@@ -352,7 +352,12 @@
  * need to trash it so we can create one.
  */
 #if defined(_WIN32)
-extern int copySymlink(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options) __attribute__((error("no symlinks on Windows")));
+extern int copySymlink(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options)
+#ifdef __clang__
+  __attribute__((unavailable("no symlinks on Windows")));
+#else
+  __attribute__((error("no symlinks on Windows")));
+#endif
 #else
 static int copySymlink(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options)
 {
@@ -574,8 +579,10 @@
         } else {
             retVal = copyDirectory(src, dst, &srcStat, options);
         }
+#if !defined(_WIN32)
     } else if (S_ISLNK(srcStat.st_mode)) {
         retVal = copySymlink(src, dst, &srcStat, options);
+#endif
     } else if (S_ISREG(srcStat.st_mode)) {
         retVal = copyRegular(src, dst, &srcStat, options);
     } else {
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index d31a297..e295760 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -45,18 +45,13 @@
 
 from __future__ import print_function
 
-import sys
-
-if sys.hexversion < 0x02070000:
-  print("Python 2.7 or newer is required.", file=sys.stderr)
-  sys.exit(1)
-
 import datetime
 import hashlib
 import os
 import shlex
 import shutil
 import subprocess
+import sys
 import tempfile
 import uuid
 import zipfile
@@ -66,6 +61,10 @@
 import rangelib
 import sparse_img
 
+if sys.hexversion < 0x02070000:
+  print("Python 2.7 or newer is required.", file=sys.stderr)
+  sys.exit(1)
+
 OPTIONS = common.OPTIONS
 
 OPTIONS.add_missing = False
@@ -346,10 +345,20 @@
     cmd.extend(["--include_descriptors_from_image", img_path])
 
 
-def AddVBMeta(output_zip, boot_img_path, system_img_path, vendor_img_path,
-              dtbo_img_path, prefix="IMAGES/"):
-  """Create a VBMeta image and store it in output_zip."""
+def AddVBMeta(output_zip, partitions, prefix="IMAGES/"):
+  """Creates a VBMeta image and store it in output_zip.
+
+  Args:
+    output_zip: The output zip file, which needs to be already open.
+    partitions: A dict that's keyed by partition names with image paths as
+        values. Only valid partition names are accepted, which include 'boot',
+        'recovery', 'system', 'vendor', 'dtbo'.
+  """
   img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "vbmeta.img")
+  if os.path.exists(img.input_name):
+    print("vbmeta.img already exists in %s; not rebuilding..." % (prefix,))
+    return img.input_name
+
   avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
   cmd = [avbtool, "make_vbmeta_image", "--output", img.name]
   common.AppendAVBSigningArgs(cmd, "vbmeta")
@@ -357,10 +366,12 @@
   public_key_dir = tempfile.mkdtemp(prefix="avbpubkey-")
   OPTIONS.tempfiles.append(public_key_dir)
 
-  AppendVBMetaArgsForPartition(cmd, "boot", boot_img_path, public_key_dir)
-  AppendVBMetaArgsForPartition(cmd, "system", system_img_path, public_key_dir)
-  AppendVBMetaArgsForPartition(cmd, "vendor", vendor_img_path, public_key_dir)
-  AppendVBMetaArgsForPartition(cmd, "dtbo", dtbo_img_path, public_key_dir)
+  for partition, path in partitions.items():
+    assert partition in common.AVB_PARTITIONS, 'Unknown partition: %s' % (
+        partition,)
+    assert os.path.exists(path), 'Failed to find %s for partition %s' % (
+        path, partition)
+    AppendVBMetaArgsForPartition(cmd, partition, path, public_key_dir)
 
   args = OPTIONS.info_dict.get("avb_vbmeta_args")
   if args and args.strip():
@@ -376,9 +387,9 @@
         if os.path.exists(image_path):
           continue
         found = False
-        for dir in ['IMAGES', 'RADIO', 'VENDOR_IMAGES', 'PREBUILT_IMAGES']:
+        for dir_name in ['IMAGES', 'RADIO', 'VENDOR_IMAGES', 'PREBUILT_IMAGES']:
           alt_path = os.path.join(
-              OPTIONS.input_tmp, dir, os.path.basename(image_path))
+              OPTIONS.input_tmp, dir_name, os.path.basename(image_path))
           if os.path.exists(alt_path):
             split_args[index + 1] = alt_path
             found = True
@@ -477,6 +488,17 @@
 
 
 def AddImagesToTargetFiles(filename):
+  """Creates and adds images (boot/recovery/system/...) to a target_files.zip.
+
+  It works with either a zip file (zip mode), or a directory that contains the
+  files to be packed into a target_files.zip (dir mode). The latter is used when
+  being called from build/make/core/Makefile.
+
+  The images will be created under IMAGES/ in the input target_files.zip.
+
+  Args:
+      filename: the target_files.zip, or the zip root directory.
+  """
   if os.path.isdir(filename):
     OPTIONS.input_tmp = os.path.abspath(filename)
     input_zip = None
@@ -508,10 +530,13 @@
   else:
     OPTIONS.info_dict = common.LoadInfoDict(filename, filename)
     output_zip = None
-    images_dir = os.path.join(OPTIONS.input_tmp, "IMAGES")
-    if not os.path.isdir(images_dir):
-      os.makedirs(images_dir)
-    images_dir = None
+
+  # Always make input_tmp/IMAGES available, since we may stage boot / recovery
+  # images there even under zip mode. The directory will be cleaned up as part
+  # of OPTIONS.input_tmp.
+  images_dir = os.path.join(OPTIONS.input_tmp, "IMAGES")
+  if not os.path.isdir(images_dir):
+    os.makedirs(images_dir)
 
   has_recovery = (OPTIONS.info_dict.get("no_recovery") != "true")
 
@@ -526,67 +551,63 @@
     if fp:
       OPTIONS.info_dict["avb_salt"] = hashlib.sha256(fp).hexdigest()
 
+  # A map between partition names and their paths, which could be used when
+  # generating AVB vbmeta image.
+  partitions = dict()
+
   def banner(s):
     print("\n\n++++ " + s + " ++++\n\n")
 
-  prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
-  boot_image = None
-  if os.path.exists(prebuilt_path):
-    banner("boot")
-    print("boot.img already exists in IMAGES/, no need to rebuild...")
-    if OPTIONS.rebuild_recovery:
-      boot_image = common.GetBootableImage(
-          "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
-  else:
-    banner("boot")
-    boot_image = common.GetBootableImage(
-        "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
-    if boot_image:
+  banner("boot")
+  # common.GetBootableImage() returns the image directly if present.
+  boot_image = common.GetBootableImage(
+      "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
+  # boot.img may be unavailable in some targets (e.g. aosp_arm64).
+  if boot_image:
+    partitions['boot'] = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
+    if not os.path.exists(partitions['boot']):
+      boot_image.WriteToDir(OPTIONS.input_tmp)
       if output_zip:
         boot_image.AddToZip(output_zip)
-      else:
-        boot_image.WriteToDir(OPTIONS.input_tmp)
 
   recovery_image = None
   if has_recovery:
     banner("recovery")
-    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "recovery.img")
-    if os.path.exists(prebuilt_path):
-      print("recovery.img already exists in IMAGES/, no need to rebuild...")
-      if OPTIONS.rebuild_recovery:
-        recovery_image = common.GetBootableImage(
-            "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp,
-            "RECOVERY")
-    else:
-      recovery_image = common.GetBootableImage(
-          "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
-      if recovery_image:
-        if output_zip:
-          recovery_image.AddToZip(output_zip)
-        else:
-          recovery_image.WriteToDir(OPTIONS.input_tmp)
+    recovery_image = common.GetBootableImage(
+        "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
+    assert recovery_image, "Failed to create recovery.img."
+    partitions['recovery'] = os.path.join(
+        OPTIONS.input_tmp, "IMAGES", "recovery.img")
+    if not os.path.exists(partitions['recovery']):
+      recovery_image.WriteToDir(OPTIONS.input_tmp)
+      if output_zip:
+        recovery_image.AddToZip(output_zip)
 
       banner("recovery (two-step image)")
       # The special recovery.img for two-step package use.
       recovery_two_step_image = common.GetBootableImage(
           "IMAGES/recovery-two-step.img", "recovery-two-step.img",
           OPTIONS.input_tmp, "RECOVERY", two_step_image=True)
-      if recovery_two_step_image:
+      assert recovery_two_step_image, "Failed to create recovery-two-step.img."
+      recovery_two_step_image_path = os.path.join(
+          OPTIONS.input_tmp, "IMAGES", "recovery-two-step.img")
+      if not os.path.exists(recovery_two_step_image_path):
+        recovery_two_step_image.WriteToDir(OPTIONS.input_tmp)
         if output_zip:
           recovery_two_step_image.AddToZip(output_zip)
-        else:
-          recovery_two_step_image.WriteToDir(OPTIONS.input_tmp)
 
   banner("system")
-  system_img_path = AddSystem(
+  partitions['system'] = system_img_path = AddSystem(
       output_zip, recovery_img=recovery_image, boot_img=boot_image)
-  vendor_img_path = None
+
   if has_vendor:
     banner("vendor")
-    vendor_img_path = AddVendor(output_zip)
+    partitions['vendor'] = vendor_img_path = AddVendor(output_zip)
+
   if has_system_other:
     banner("system_other")
     AddSystemOther(output_zip)
+
   if not OPTIONS.is_signing:
     banner("userdata")
     AddUserdata(output_zip)
@@ -597,16 +618,13 @@
     banner("partition-table")
     AddPartitionTable(output_zip)
 
-  dtbo_img_path = None
   if OPTIONS.info_dict.get("has_dtbo") == "true":
     banner("dtbo")
-    dtbo_img_path = AddDtbo(output_zip)
+    partitions['dtbo'] = AddDtbo(output_zip)
 
   if OPTIONS.info_dict.get("avb_enable") == "true":
     banner("vbmeta")
-    boot_contents = boot_image.WriteToTemp()
-    AddVBMeta(output_zip, boot_contents.name, system_img_path,
-              vendor_img_path, dtbo_img_path)
+    AddVBMeta(output_zip, partitions)
 
   # For devices using A/B update, copy over images from RADIO/ and/or
   # VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed
@@ -638,8 +656,6 @@
         continue
 
       img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
-      img_vendor_dir = os.path.join(
-        OPTIONS.input_tmp, "VENDOR_IMAGES")
       if os.path.exists(img_radio_path):
         if output_zip:
           common.ZipWrite(output_zip, img_radio_path,
@@ -647,11 +663,12 @@
         else:
           shutil.copy(img_radio_path, prebuilt_path)
       else:
+        img_vendor_dir = os.path.join(OPTIONS.input_tmp, "VENDOR_IMAGES")
         for root, _, files in os.walk(img_vendor_dir):
           if img_name in files:
             if output_zip:
               common.ZipWrite(output_zip, os.path.join(root, img_name),
-                os.path.join("IMAGES", img_name))
+                              os.path.join("IMAGES", img_name))
             else:
               shutil.copy(os.path.join(root, img_name), prebuilt_path)
             break
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index c184c42..8f06b95 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -16,6 +16,7 @@
 
 import array
 import common
+import copy
 import functools
 import heapq
 import itertools
@@ -204,6 +205,18 @@
     self.id = len(by_id)
     by_id.append(self)
 
+    self._patch = None
+
+  @property
+  def patch(self):
+    return self._patch
+
+  @patch.setter
+  def patch(self, patch):
+    if patch:
+      assert self.style == "diff"
+    self._patch = patch
+
   def NetStashChange(self):
     return (sum(sr.size() for (_, sr) in self.stash_before) -
             sum(sr.size() for (_, sr) in self.use_stash))
@@ -213,6 +226,7 @@
     self.use_stash = []
     self.style = "new"
     self.src_ranges = RangeSet()
+    self.patch = None
 
   def __str__(self):
     return (str(self.id) + ": <" + str(self.src_ranges) + " " + self.style +
@@ -675,6 +689,7 @@
             # These are identical; we don't need to generate a patch,
             # just issue copy commands on the device.
             xf.style = "move"
+            xf.patch = None
             tgt_size = xf.tgt_ranges.size() * self.tgt.blocksize
             if xf.src_ranges != xf.tgt_ranges:
               print("%10d %10d (%6.2f%%) %7s %s %s (from %s)" % (
@@ -683,24 +698,33 @@
                       xf.tgt_name + " (from " + xf.src_name + ")"),
                   str(xf.tgt_ranges), str(xf.src_ranges)))
           else:
-            # For files in zip format (eg, APKs, JARs, etc.) we would
-            # like to use imgdiff -z if possible (because it usually
-            # produces significantly smaller patches than bsdiff).
-            # This is permissible if:
-            #
-            #  - imgdiff is not disabled, and
-            #  - the source and target files are monotonic (ie, the
-            #    data is stored with blocks in increasing order), and
-            #  - we haven't removed any blocks from the source set.
-            #
-            # If these conditions are satisfied then appending all the
-            # blocks in the set together in order will produce a valid
-            # zip file (plus possibly extra zeros in the last block),
-            # which is what imgdiff needs to operate.  (imgdiff is
-            # fine with extra zeros at the end of the file.)
-            imgdiff = (not self.disable_imgdiff and xf.intact and
-                       xf.tgt_name.split(".")[-1].lower()
-                       in ("apk", "jar", "zip"))
+            if xf.patch:
+              # We have already generated the patch with imgdiff. Check if the
+              # transfer is intact.
+              assert not self.disable_imgdiff
+              imgdiff = True
+              if not xf.intact:
+                imgdiff = False
+                xf.patch = None
+            else:
+              # For files in zip format (eg, APKs, JARs, etc.) we would
+              # like to use imgdiff -z if possible (because it usually
+              # produces significantly smaller patches than bsdiff).
+              # This is permissible if:
+              #
+              #  - imgdiff is not disabled, and
+              #  - the source and target files are monotonic (ie, the
+              #    data is stored with blocks in increasing order), and
+              #  - we haven't removed any blocks from the source set.
+              #
+              # If these conditions are satisfied then appending all the
+              # blocks in the set together in order will produce a valid
+              # zip file (plus possibly extra zeros in the last block),
+              # which is what imgdiff needs to operate.  (imgdiff is
+              # fine with extra zeros at the end of the file.)
+              imgdiff = (not self.disable_imgdiff and xf.intact and
+                         xf.tgt_name.split(".")[-1].lower()
+                         in ("apk", "jar", "zip"))
             xf.style = "imgdiff" if imgdiff else "bsdiff"
             diff_queue.append((index, imgdiff, patch_num))
             patch_num += 1
@@ -738,48 +762,51 @@
             xf_index, imgdiff, patch_index = diff_queue.pop()
 
           xf = self.transfers[xf_index]
-          src_ranges = xf.src_ranges
-          tgt_ranges = xf.tgt_ranges
+          patch = xf.patch
+          if not patch:
+            src_ranges = xf.src_ranges
+            tgt_ranges = xf.tgt_ranges
 
-          # Needs lock since WriteRangeDataToFd() is stateful (calling seek).
-          with lock:
-            src_file = common.MakeTempFile(prefix="src-")
-            with open(src_file, "wb") as fd:
-              self.src.WriteRangeDataToFd(src_ranges, fd)
-
-            tgt_file = common.MakeTempFile(prefix="tgt-")
-            with open(tgt_file, "wb") as fd:
-              self.tgt.WriteRangeDataToFd(tgt_ranges, fd)
-
-          message = []
-          try:
-            patch = compute_patch(src_file, tgt_file, imgdiff)
-          except ValueError as e:
-            message.append(
-                "Failed to generate %s for %s: tgt=%s, src=%s:\n%s" % (
-                "imgdiff" if imgdiff else "bsdiff",
-                xf.tgt_name if xf.tgt_name == xf.src_name else
-                    xf.tgt_name + " (from " + xf.src_name + ")",
-                xf.tgt_ranges, xf.src_ranges, e.message))
-            # TODO(b/68016761): Better handle the holes in mke2fs created images.
-            if imgdiff:
-              try:
-                patch = compute_patch(src_file, tgt_file, imgdiff=False)
-                message.append(
-                    "Fell back and generated with bsdiff instead for %s" % (
-                    xf.tgt_name,))
-                xf.style = "bsdiff"
-                with lock:
-                  warning_messages.extend(message)
-                del message[:]
-              except ValueError as e:
-                message.append(
-                    "Also failed to generate with bsdiff for %s:\n%s" % (
-                    xf.tgt_name, e.message))
-
-          if message:
+            # Needs lock since WriteRangeDataToFd() is stateful (calling seek).
             with lock:
-              error_messages.extend(message)
+              src_file = common.MakeTempFile(prefix="src-")
+              with open(src_file, "wb") as fd:
+                self.src.WriteRangeDataToFd(src_ranges, fd)
+
+              tgt_file = common.MakeTempFile(prefix="tgt-")
+              with open(tgt_file, "wb") as fd:
+                self.tgt.WriteRangeDataToFd(tgt_ranges, fd)
+
+            message = []
+            try:
+              patch = compute_patch(src_file, tgt_file, imgdiff)
+            except ValueError as e:
+              message.append(
+                  "Failed to generate %s for %s: tgt=%s, src=%s:\n%s" % (
+                  "imgdiff" if imgdiff else "bsdiff",
+                  xf.tgt_name if xf.tgt_name == xf.src_name else
+                      xf.tgt_name + " (from " + xf.src_name + ")",
+                  xf.tgt_ranges, xf.src_ranges, e.message))
+              # TODO(b/68016761): Better handle the holes in mke2fs created
+              # images.
+              if imgdiff:
+                try:
+                  patch = compute_patch(src_file, tgt_file, imgdiff=False)
+                  message.append(
+                      "Fell back and generated with bsdiff instead for %s" % (
+                      xf.tgt_name,))
+                  xf.style = "bsdiff"
+                  with lock:
+                    warning_messages.extend(message)
+                  del message[:]
+                except ValueError as e:
+                  message.append(
+                      "Also failed to generate with bsdiff for %s:\n%s" % (
+                      xf.tgt_name, e.message))
+
+            if message:
+              with lock:
+                error_messages.extend(message)
 
           with lock:
             patches[patch_index] = (xf_index, patch)
@@ -1151,8 +1178,8 @@
   def FindTransfers(self):
     """Parse the file_map to generate all the transfers."""
 
-    def AddSplitTransfers(tgt_name, src_name, tgt_ranges, src_ranges,
-                          style, by_id):
+    def AddSplitTransfersWithFixedSizeChunks(tgt_name, src_name, tgt_ranges,
+                                             src_ranges, style, by_id):
       """Add one or multiple Transfer()s by splitting large files.
 
       For BBOTA v3, we need to stash source blocks for resumable feature.
@@ -1167,21 +1194,7 @@
       Compared to the fixed 1024-block limit, it reduces the overall package
       size by 30% for volantis, and 20% for angler and bullhead."""
 
-      # Possibly split large files into smaller chunks.
       pieces = 0
-      cache_size = common.OPTIONS.cache_size
-      split_threshold = 0.125
-      max_blocks_per_transfer = int(cache_size * split_threshold /
-                                    self.tgt.blocksize)
-
-      # Change nothing for small files.
-      if (tgt_ranges.size() <= max_blocks_per_transfer and
-          src_ranges.size() <= max_blocks_per_transfer):
-        Transfer(tgt_name, src_name, tgt_ranges, src_ranges,
-                 self.tgt.RangeSha1(tgt_ranges), self.src.RangeSha1(src_ranges),
-                 style, by_id)
-        return
-
       while (tgt_ranges.size() > max_blocks_per_transfer and
              src_ranges.size() > max_blocks_per_transfer):
         tgt_split_name = "%s-%d" % (tgt_name, pieces)
@@ -1207,6 +1220,37 @@
                  self.tgt.RangeSha1(tgt_ranges), self.src.RangeSha1(src_ranges),
                  style, by_id)
 
+    def AddSplitTransfers(tgt_name, src_name, tgt_ranges, src_ranges, style,
+                          by_id):
+      """Find all the zip files and split the others with a fixed chunk size.
+
+      This function will construct a list of zip archives, which will later be
+      split by imgdiff to reduce the final patch size. For the other files,
+      we will plainly split them based on a fixed chunk size with the potential
+      patch size penalty.
+      """
+
+      assert style == "diff"
+
+      # Change nothing for small files.
+      if (tgt_ranges.size() <= max_blocks_per_transfer and
+          src_ranges.size() <= max_blocks_per_transfer):
+        Transfer(tgt_name, src_name, tgt_ranges, src_ranges,
+                 self.tgt.RangeSha1(tgt_ranges), self.src.RangeSha1(src_ranges),
+                 style, by_id)
+        return
+
+      if tgt_name.split(".")[-1].lower() in ("apk", "jar", "zip"):
+        split_enable = (not self.disable_imgdiff and src_ranges.monotonic and
+                        tgt_ranges.monotonic)
+        if split_enable and (self.tgt.RangeSha1(tgt_ranges) !=
+                             self.src.RangeSha1(src_ranges)):
+          large_apks.append((tgt_name, src_name, tgt_ranges, src_ranges))
+          return
+
+      AddSplitTransfersWithFixedSizeChunks(tgt_name, src_name, tgt_ranges,
+                                           src_ranges, style, by_id)
+
     def AddTransfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id,
                     split=False):
       """Wrapper function for adding a Transfer()."""
@@ -1275,8 +1319,145 @@
       AddSplitTransfers(
           tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
 
+    def ParseAndValidateSplitInfo(patch_size, tgt_ranges, src_ranges,
+                                  split_info):
+      """Parse the split_info and return a list of info tuples.
+
+      Args:
+        patch_size: total size of the patch file.
+        tgt_ranges: Ranges of the target file within the original image.
+        src_ranges: Ranges of the source file within the original image.
+        split_info format:
+          imgdiff version#
+          count of pieces
+          <patch_size_1> <tgt_size_1> <src_ranges_1>
+          ...
+          <patch_size_n> <tgt_size_n> <src_ranges_n>
+
+      Returns:
+        [patch_start, patch_len, split_tgt_ranges, split_src_ranges]
+      """
+
+      version = int(split_info[0])
+      assert version == 2
+      count = int(split_info[1])
+      assert len(split_info) - 2 == count
+
+      split_info_list = []
+      patch_start = 0
+      tgt_remain = copy.deepcopy(tgt_ranges)
+      # each line has the format <patch_size>, <tgt_size>, <src_ranges>
+      for line in split_info[2:]:
+        info = line.split()
+        assert len(info) == 3
+        patch_length = int(info[0])
+
+        split_tgt_size = int(info[1])
+        assert split_tgt_size % 4096 == 0
+        assert split_tgt_size / 4096 <= tgt_remain.size()
+        split_tgt_ranges = tgt_remain.first(split_tgt_size / 4096)
+        tgt_remain = tgt_remain.subtract(split_tgt_ranges)
+
+        # Find the split_src_ranges within the image file from its relative
+        # position in file.
+        split_src_indices = RangeSet.parse_raw(info[2])
+        split_src_ranges = RangeSet()
+        for r in split_src_indices:
+          curr_range = src_ranges.first(r[1]).subtract(src_ranges.first(r[0]))
+          assert not split_src_ranges.overlaps(curr_range)
+          split_src_ranges = split_src_ranges.union(curr_range)
+
+        split_info_list.append((patch_start, patch_length,
+                                split_tgt_ranges, split_src_ranges))
+        patch_start += patch_length
+
+      # Check that the sizes of all the split pieces add up to the final file
+      # size for patch and target.
+      assert tgt_remain.size() == 0
+      assert patch_start == patch_size
+      return split_info_list
+
+    def AddSplitTransferForLargeApks():
+      """Create split transfers for large apk files.
+
+      Example: Chrome.apk will be split into
+        src-0: Chrome.apk-0, tgt-0: Chrome.apk-0
+        src-1: Chrome.apk-1, tgt-1: Chrome.apk-1
+        ...
+
+      After the split, the target pieces are continuous and block aligned; and
+      the source pieces are mutually exclusive. During the split, we also
+      generate and save the image patch between src-X & tgt-X. This patch will
+      be valid because the block ranges of src-X & tgt-X will always stay the
+      same afterwards; but there's a chance we don't use the patch if we
+      convert the "diff" command into "new" or "move" later.
+
+      The split will be attempted by calling imgdiff, which expects the input
+      files to be valid zip archives. If imgdiff fails for some reason (i.e.
+      holes in the APK file), we will fall back to split the failed APKs into
+      fixed size chunks.
+      """
+
+      while True:
+        with transfer_lock:
+          if not large_apks:
+            return
+          tgt_name, src_name, tgt_ranges, src_ranges = large_apks.pop(0)
+
+        src_file = common.MakeTempFile(prefix="src-")
+        tgt_file = common.MakeTempFile(prefix="tgt-")
+        with transfer_lock:
+          with open(src_file, "wb") as src_fd:
+            self.src.WriteRangeDataToFd(src_ranges, src_fd)
+          with open(tgt_file, "wb") as tgt_fd:
+            self.tgt.WriteRangeDataToFd(tgt_ranges, tgt_fd)
+
+        patch_file = common.MakeTempFile(prefix="patch-")
+        patch_info_file = common.MakeTempFile(prefix="split_info-")
+        cmd = ["imgdiff", "-z",
+               "--block-limit={}".format(max_blocks_per_transfer),
+               "--split-info=" + patch_info_file,
+               src_file, tgt_file, patch_file]
+        p = common.Run(cmd, stdout=subprocess.PIPE)
+        p.communicate()
+        if p.returncode != 0:
+          print("Failed to create patch between {} and {},"
+                " falling back to bsdiff".format(src_name, tgt_name))
+          with transfer_lock:
+            AddSplitTransfersWithFixedSizeChunks(tgt_name, src_name,
+                                                 tgt_ranges, src_ranges,
+                                                 "diff", self.transfers)
+          continue
+
+        with open(patch_info_file) as patch_info:
+          lines = patch_info.readlines()
+
+        patch_size_total = os.path.getsize(patch_file)
+        split_info_list = ParseAndValidateSplitInfo(patch_size_total,
+                                                    tgt_ranges, src_ranges,
+                                                    lines)
+        for index, (patch_start, patch_length, split_tgt_ranges,
+            split_src_ranges) in enumerate(split_info_list):
+          with open(patch_file) as f:
+            f.seek(patch_start)
+            patch_content = f.read(patch_length)
+
+          split_src_name = "{}-{}".format(src_name, index)
+          split_tgt_name = "{}-{}".format(tgt_name, index)
+          transfer_split = Transfer(split_tgt_name, split_src_name,
+                                    split_tgt_ranges, split_src_ranges,
+                                    self.tgt.RangeSha1(split_tgt_ranges),
+                                    self.src.RangeSha1(split_src_ranges),
+                                    "diff", self.transfers)
+          transfer_split.patch = patch_content
+
     print("Finding transfers...")
 
+    large_apks = []
+    cache_size = common.OPTIONS.cache_size
+    split_threshold = 0.125
+    max_blocks_per_transfer = int(cache_size * split_threshold /
+                                  self.tgt.blocksize)
     empty = RangeSet()
     for tgt_fn, tgt_ranges in self.tgt.file_map.items():
       if tgt_fn == "__ZERO":
@@ -1321,6 +1502,14 @@
 
       AddTransfer(tgt_fn, None, tgt_ranges, empty, "new", self.transfers)
 
+    transfer_lock = threading.Lock()
+    threads = [threading.Thread(target=AddSplitTransferForLargeApks)
+               for _ in range(self.threads)]
+    for th in threads:
+      th.start()
+    while threads:
+      threads.pop().join()
+
   def AbbreviateSourceNames(self):
     for k in self.src.file_map.keys():
       b = os.path.basename(k)
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index a388f8a..e11f5a6 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -195,8 +195,9 @@
     else:
       hi = i
 
-  print("Adjusted partition size for verity, partition_size: {},"
-        " verity_size: {}".format(result, verity_size))
+  if OPTIONS.verbose:
+    print("Adjusted partition size for verity, partition_size: {},"
+          " verity_size: {}".format(result, verity_size))
   AdjustPartitionSizeForVerity.results[key] = (result, verity_size)
   return (result, verity_size)
 
@@ -257,7 +258,7 @@
   return True
 
 def Append(target, file_to_append, error_message):
-  print "appending %s to %s" % (file_to_append, target)
+  # appending file_to_append to target
   with open(target, "a") as out_file:
     with open(file_to_append, "r") as input_file:
       for line in input_file:
@@ -535,9 +536,9 @@
 
   try:
     if fs_type.startswith("ext4"):
-      (ext4fs_output, exit_code) = RunCommand(build_command, True)
+      (ext4fs_output, exit_code) = RunCommand(build_command)
     else:
-      (_, exit_code) = RunCommand(build_command, True)
+      (_, exit_code) = RunCommand(build_command)
   finally:
     if in_dir != origin_in:
       # Clean up temporary directories and files.
diff --git a/tools/releasetools/check_ota_package_signature.py b/tools/releasetools/check_ota_package_signature.py
index 1f8b7bb..8106d06 100755
--- a/tools/releasetools/check_ota_package_signature.py
+++ b/tools/releasetools/check_ota_package_signature.py
@@ -22,7 +22,10 @@
 
 import argparse
 import common
+import os
+import os.path
 import re
+import site
 import subprocess
 import sys
 import tempfile
@@ -32,7 +35,12 @@
 from hashlib import sha256
 
 # 'update_payload' package is under 'system/update_engine/scripts/', which
-# should to be included in PYTHONPATH.
+# should be included in PYTHONPATH. Try to set it up automatically if
+# if ANDROID_BUILD_TOP is available.
+top = os.getenv('ANDROID_BUILD_TOP')
+if top:
+  site.addsitedir(os.path.join(top, 'system', 'update_engine', 'scripts'))
+
 from update_payload.payload import Payload
 from update_payload.update_metadata_pb2 import Signatures
 
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index d16f5eb..639e3b6 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -75,6 +75,11 @@
 # Values for "certificate" in apkcerts that mean special things.
 SPECIAL_CERT_STRINGS = ("PRESIGNED", "EXTERNAL")
 
+
+# The partitions allowed to be signed by AVB (Android verified boot 2.0).
+AVB_PARTITIONS = ('boot', 'recovery', 'system', 'vendor', 'dtbo')
+
+
 class ErrorCode(object):
   """Define error_codes for failures that happen during the actual
   update package installation.
@@ -447,10 +452,12 @@
   else:
     cmd.extend(["--output", img.name])
 
+  # "boot" or "recovery", without extension.
+  partition_name = os.path.basename(sourcedir).lower()
+
   p = Run(cmd, stdout=subprocess.PIPE)
   p.communicate()
-  assert p.returncode == 0, "mkbootimg of %s image failed" % (
-      os.path.basename(sourcedir),)
+  assert p.returncode == 0, "mkbootimg of %s image failed" % (partition_name,)
 
   if (info_dict.get("boot_signer", None) == "true" and
       info_dict.get("verity_key", None)):
@@ -459,7 +466,7 @@
     if two_step_image:
       path = "/boot"
     else:
-      path = "/" + os.path.basename(sourcedir).lower()
+      path = "/" + partition_name
     cmd = [OPTIONS.boot_signer_path]
     cmd.extend(OPTIONS.boot_signer_args)
     cmd.extend([path, img.name,
@@ -471,7 +478,7 @@
 
   # Sign the image if vboot is non-empty.
   elif info_dict.get("vboot", None):
-    path = "/" + os.path.basename(sourcedir).lower()
+    path = "/" + partition_name
     img_keyblock = tempfile.NamedTemporaryFile()
     # We have switched from the prebuilt futility binary to using the tool
     # (futility-host) built from the source. Override the setting in the old
@@ -493,20 +500,21 @@
     img_unsigned.close()
     img_keyblock.close()
 
-  # AVB: if enabled, calculate and add hash to boot.img.
+  # AVB: if enabled, calculate and add hash to boot.img or recovery.img.
   if info_dict.get("avb_enable") == "true":
     avbtool = os.getenv('AVBTOOL') or info_dict["avb_avbtool"]
-    part_size = info_dict["boot_size"]
+    part_size = info_dict[partition_name + "_size"]
     cmd = [avbtool, "add_hash_footer", "--image", img.name,
-           "--partition_size", str(part_size), "--partition_name", "boot"]
-    AppendAVBSigningArgs(cmd, "boot")
-    args = info_dict.get("avb_boot_add_hash_footer_args")
+           "--partition_size", str(part_size), "--partition_name",
+           partition_name]
+    AppendAVBSigningArgs(cmd, partition_name)
+    args = info_dict.get("avb_" + partition_name + "_add_hash_footer_args")
     if args and args.strip():
       cmd.extend(shlex.split(args))
     p = Run(cmd, stdout=subprocess.PIPE)
     p.communicate()
     assert p.returncode == 0, "avbtool add_hash_footer of %s failed" % (
-        os.path.basename(OPTIONS.input_tmp))
+        partition_name,)
 
   img.seek(os.SEEK_SET, 0)
   data = img.read()
@@ -727,10 +735,18 @@
 
 
 def CheckSize(data, target, info_dict):
-  """Check the data string passed against the max size limit, if
-  any, for the given target.  Raise exception if the data is too big.
-  Print a warning if the data is nearing the maximum size."""
+  """Checks the data string passed against the max size limit.
 
+  For non-AVB images, raise exception if the data is too big. Print a warning
+  if the data is nearing the maximum size.
+
+  For AVB images, the actual image size should be identical to the limit.
+
+  Args:
+    data: A string that contains all the data for the partition.
+    target: The partition name. The ".img" suffix is optional.
+    info_dict: The dict to be looked up for relevant info.
+  """
   if target.endswith(".img"):
     target = target[:-4]
   mount_point = "/" + target
@@ -750,14 +766,22 @@
     return
 
   size = len(data)
-  pct = float(size) * 100.0 / limit
-  msg = "%s size (%d) is %.2f%% of limit (%d)" % (target, size, pct, limit)
-  if pct >= 99.0:
-    raise ExternalError(msg)
-  elif pct >= 95.0:
-    print("\n  WARNING: %s\n" % (msg,))
-  elif OPTIONS.verbose:
-    print("  ", msg)
+  # target could be 'userdata' or 'cache'. They should follow the non-AVB image
+  # path.
+  if info_dict.get("avb_enable") == "true" and target in AVB_PARTITIONS:
+    if size != limit:
+      raise ExternalError(
+          "Mismatching image size for %s: expected %d actual %d" % (
+              target, limit, size))
+  else:
+    pct = float(size) * 100.0 / limit
+    msg = "%s size (%d) is %.2f%% of limit (%d)" % (target, size, pct, limit)
+    if pct >= 99.0:
+      raise ExternalError(msg)
+    elif pct >= 95.0:
+      print("\n  WARNING: %s\n" % (msg,))
+    elif OPTIONS.verbose:
+      print("  ", msg)
 
 
 def ReadApkCerts(tf_zip):
diff --git a/tools/releasetools/pylintrc b/tools/releasetools/pylintrc
index 90de1af..7b3405c 100644
--- a/tools/releasetools/pylintrc
+++ b/tools/releasetools/pylintrc
@@ -144,9 +144,6 @@
 
 [BASIC]
 
-# Required attributes for module, separated by a comma
-required-attributes=
-
 # List of builtins function names that should not be used, separated by a comma
 bad-functions=map,filter,input
 
@@ -357,10 +354,6 @@
 
 [CLASSES]
 
-# List of interface methods to ignore, separated by a comma. This is used for
-# instance to not check methods defines in Zope's Interface base class.
-ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
-
 # List of method names used to declare (i.e. assign) instance attributes.
 defining-attr-methods=__init__,__new__,setUp
 
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index e4ef2c1..c30ebff 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -547,6 +547,7 @@
   AVB_FOOTER_ARGS_BY_PARTITION = {
     'boot' : 'avb_boot_add_hash_footer_args',
     'dtbo' : 'avb_dtbo_add_hash_footer_args',
+    'recovery' : 'avb_recovery_add_hash_footer_args',
     'system' : 'avb_system_add_hashtree_footer_args',
     'vendor' : 'avb_vendor_add_hashtree_footer_args',
     'vbmeta' : 'avb_vbmeta_args',
diff --git a/tools/signtos/Android.bp b/tools/signtos/Android.bp
new file mode 100644
index 0000000..b26631f
--- /dev/null
+++ b/tools/signtos/Android.bp
@@ -0,0 +1,27 @@
+//
+// Copyright (C) 2014 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.
+//
+
+// the signtos tool - signs Trusty images
+// ============================================================
+java_library_host {
+    name: "signtos",
+    srcs: ["SignTos.java"],
+    manifest: "SignTos.mf",
+    static_libs: [
+        "bouncycastle",
+        "bouncycastle-bcpkix",
+    ],
+}
diff --git a/tools/signtos/Android.mk b/tools/signtos/Android.mk
deleted file mode 100644
index 3e869b3..0000000
--- a/tools/signtos/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (C) 2014 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.
-#
-LOCAL_PATH := $(call my-dir)
-
-# the signtos tool - signs Trusty images
-# ============================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := signtos
-LOCAL_SRC_FILES := SignTos.java
-LOCAL_JAR_MANIFEST := SignTos.mf
-LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle bouncycastle-bcpkix
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/warn.py b/tools/warn.py
index 44ad368..cc63de4 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -1807,6 +1807,7 @@
      'patterns': [r".*: warning: In file included from .+,"]},
 
     # warnings from clang-tidy
+    group_tidy_warn_pattern('android'),
     group_tidy_warn_pattern('cert'),
     group_tidy_warn_pattern('clang-diagnostic'),
     group_tidy_warn_pattern('cppcoreguidelines'),