Updating Platform Security String to 2018-09-05 Bug: 111501777 am: 6bc223c9af
am: 57c2d9f670

Change-Id: I8ed61f72717a185b342a5a728e8111ad6dd606df
diff --git a/Changes.md b/Changes.md
index 37bbad0..7440220 100644
--- a/Changes.md
+++ b/Changes.md
@@ -1,5 +1,164 @@
 # Build System Changes for Android.mk Writers
 
+### `export` and `unexport` deprecation  {#export_keyword}
+
+The `export` and `unexport` keywords have been deprecated, and will throw
+warnings or errors depending on where they are used.
+
+Early in the make system, during product configuration and BoardConfig.mk
+reading: these will throw a warnings, and will be an error in the future.
+Device specific configuration should not be able to affect common core build
+steps -- we're looking at triggering build steps to be invalidated if the set
+of environment variables they can access changes. If device specific
+configuration is allowed to change those, switching devices with the same
+output directory could become significantly more expensive than it already can
+be.
+
+Later, during Android.mk files, and later tasks: these will throw errors, since
+it is increasingly likely that they are being used incorrectly, attempting to
+change the environment for a single build step, and instead setting it for
+hundreds of thousands.
+
+It is not recommended to just move the environment variable setting outside of
+the build (in vendorsetup.sh, or some other configuration script or wrapper).
+We expect to limit the environment variables that the build respects in the
+future, others will be cleared. (There will be methods to get custom variables
+into the build, just not to every build step)
+
+Instead, write the export commands into the rule command lines themselves:
+
+``` make
+$(intermediates)/generated_output.img:
+	rm -rf $@
+	export MY_ENV_A="$(MY_A)"; make ...
+```
+
+If you want to set many environment variables, and/or use them many times,
+write them out to a script and source the script:
+
+``` make
+envsh := $(intermediates)/env.sh
+$(envsh):
+	rm -rf $@
+	echo 'export MY_ENV_A="$(MY_A)"' >$@
+	echo 'export MY_ENV_B="$(MY_B)"' >>$@
+
+$(intermediates)/generated_output.img: PRIVATE_ENV := $(envsh)
+$(intermediates)/generated_output.img: $(envsh) a/b/c/package.sh
+	rm -rf $@
+	source $(PRIVATE_ENV); make ...
+	source $(PRIVATE_ENV); a/b/c/package.sh ...
+```
+
+## Implicit make rules are obsolete {#implicit_rules}
+
+Implicit rules look something like the following:
+
+``` make
+$(TARGET_OUT_SHARED_LIBRARIES)/%_vendor.so: $(TARGET_OUT_SHARED_LIBRARIES)/%.so
+	...
+
+%.o : %.foo
+	...
+```
+
+These can have wide ranging effects across unrelated modules, so they're now obsolete. Instead, use static pattern rules, which are similar, but explicitly match the specified outputs:
+
+``` make
+libs := $(foreach lib,libfoo libbar,$(TARGET_OUT_SHARED_LIBRARIES)/$(lib)_vendor.so)
+$(libs): %_vendor.so: %.so
+	...
+
+files := $(wildcard $(LOCAL_PATH)/*.foo)
+gen := $(patsubst $(LOCAL_PATH)/%.foo,$(intermediates)/%.o,$(files))
+$(gen): %.o : %.foo
+	...
+```
+
+## Removing '/' from Valid Module Names {#name_slash}
+
+The build system uses module names in path names in many places. Having an
+extra '/' or '../' being inserted can cause problems -- and not just build
+breaks, but stranger invalid behavior.
+
+In every case we've seen, the fix is relatively simple: move the directory into
+`LOCAL_MODULE_RELATIVE_PATH` (or `LOCAL_MODULE_PATH` if you're still using it).
+If this causes multiple modules to be named the same, use unique module names
+and `LOCAL_MODULE_STEM` to change the installed file name:
+
+``` make
+include $(CLEAR_VARS)
+LOCAL_MODULE := ver1/code.bin
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/firmware
+...
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ver2/code.bin
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/firmware
+...
+include $(BUILD_PREBUILT)
+```
+
+Can be rewritten as:
+
+```
+include $(CLEAR_VARS)
+LOCAL_MODULE := ver1_code.bin
+LOCAL_MODULE_STEM := code.bin
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/ver1
+...
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ver2_code.bin
+LOCAL_MODULE_STEM := code.bin
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/ver2
+...
+include $(BUILD_PREBUILT)
+```
+
+You just need to make sure that any other references (`PRODUCT_PACKAGES`,
+`LOCAL_REQUIRED_MODULES`, etc) are converted to the new names.
+
+## Valid Module Names {#name}
+
+We've adopted lexical requirements very similar to [Bazel's
+requirements](https://docs.bazel.build/versions/master/build-ref.html#name) for
+target names. Valid characters are `a-z`, `A-Z`, `0-9`, and the special
+characters `_.+-=,@~`. This currently applies to `LOCAL_PACKAGE_NAME`,
+`LOCAL_MODULE`, and `LOCAL_MODULE_SUFFIX`, and `LOCAL_MODULE_STEM*`.
+
+Many other characters already caused problems if you used them, so we don't
+expect this to have a large effect.
+
+## PATH Tools {#PATH_Tools}
+
+The build has started restricting the external host tools usable inside the
+build. This will help ensure that build results are reproducible across
+different machines, and catch mistakes before they become larger issues.
+
+To start with, this includes replacing the $PATH with our own directory of
+tools, mirroring that of the host PATH.  The only difference so far is the
+removal of the host GCC tools. Anything that is not explicitly in the
+configuration as allowed will continue functioning, but will generate a log
+message. This is expected to become more restrictive over time.
+
+The configuration is located in build/soong/ui/build/paths/config.go, and
+contains all the common tools in use in many builds. Anything not in that list
+will currently print a warning in the `$OUT_DIR/soong.log` file, including the
+command and arguments used, and the process tree in order to help locate the
+usage.
+
+In order to fix any issues brought up by these checks, the best way to fix them
+is to use tools checked into the tree -- either as prebuilts, or building them
+as host tools during the build.
+
+As a temporary measure, you can set `TEMPORARY_DISABLE_PATH_RESTRICTIONS=true`
+in your environment to temporarily turn off the error checks and allow any tool
+to be used (with logging). Beware that GCC didn't work well with the interposer
+used for logging, so this may not help in all cases.
+
 ## Deprecating / obsoleting envsetup.sh variables in Makefiles
 
 It is not required to source envsetup.sh before running a build. Many scripts,
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 7677261..bb3b04f 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -488,6 +488,9 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/Launcher3)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Launcher3_intermediates)
 
+# Remove old merged AndroidManifest.xml location
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS/*_intermediates/AndroidManifest.xml)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/Usage.txt b/Usage.txt
index 004210b..558329b 100644
--- a/Usage.txt
+++ b/Usage.txt
@@ -29,7 +29,7 @@
   An alternative to setting $TARGET_PRODUCT and $TARGET_BUILD_VARIANT,
   which you may see in build servers, is to execute:
 
-    make PRODUCT-<product>-<variant>
+    m PRODUCT-<product>-<variant>
 
 
   A target may be a file path. For example, out/host/linux-x86/bin/adb .
@@ -46,6 +46,17 @@
     files named Android.bp
       these files are defined in Blueprint syntax
 
+  During a build, a few log files are generated in ${OUT} (or ${DIST_DIR}/logs
+    for dist builds):
+
+    verbose.log.gz
+      every command run, along with its outputs. This is similar to the
+      previous `m showcommands` option.
+    error.log
+      list of actions that failed during the build, and their outputs.
+    soong.log
+      verbose debug information from soong_ui
+
   For now, the full (extremely large) compiled list of targets can be found
     (after running the build once), split among these two files:
 
@@ -57,8 +68,6 @@
     tool here.
 
 Targets that adjust an existing build:
-  showcommands              Display the individual commands run to implement
-                            the build
   dist                      Copy into ${DIST_DIR} the portion of the build
                             that must be distributed
 
@@ -71,7 +80,7 @@
   Variables can either be set in the surrounding shell environment or can be
     passed as command-line arguments. For example:
       export I_AM_A_SHELL_VAR=1
-      I_AM_ANOTHER_SHELL_VAR=2 make droid I_AM_A_MAKE_VAR=3
+      I_AM_ANOTHER_SHELL_VAR=2 m droid I_AM_A_MAKE_VAR=3
   Here are some common variables and their meanings:
     TARGET_PRODUCT          The <product> to build # as described above
     TARGET_BUILD_VARIANT    The <variant> to build # as described above
diff --git a/core/Makefile b/core/Makefile
index 0a2f6e3..6e1c4a6 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -36,7 +36,9 @@
             $(eval $(call copy-xml-file-checked,$(_src),$(_fulldest))),\
             $(if $(and $(filter %.jar,$(_dest)),$(filter $(basename $(notdir $(_dest))),$(PRODUCT_LOADED_BY_PRIVILEGED_MODULES))),\
                 $(eval $(call copy-and-uncompress-dexs,$(_src),$(_fulldest))), \
-                $(eval $(call copy-one-file,$(_src),$(_fulldest))))) \
+                $(if $(filter init%rc,$(notdir $(_dest)))$(filter %/etc/init,$(dir $(_dest))),\
+                    $(eval $(call copy-init-script-file-checked,$(_src),$(_fulldest))),\
+                    $(eval $(call copy-one-file,$(_src),$(_fulldest)))))) \
         $(eval ALL_DEFAULT_INSTALLED_MODULES += $(_fulldest)) \
         $(eval unique_product_copy_files_destinations += $(_dest))))
 
@@ -682,11 +684,23 @@
 	$(ALL_GENERATED_SOURCES) \
 	$(ALL_DEFAULT_INSTALLED_MODULES))
 
+INSTALLED_FILES_FILE_ROOT := $(PRODUCT_OUT)/installed-files-root.txt
+INSTALLED_FILES_JSON_ROOT := $(INSTALLED_FILES_FILE_ROOT:.txt=.json)
+$(INSTALLED_FILES_FILE_ROOT): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_ROOT)
+$(INSTALLED_FILES_FILE_ROOT) : $(INTERNAL_RAMDISK_FILES) $(FILESLIST)
+	@echo Installed file list: $@
+	@mkdir -p $(dir $@)
+	@rm -f $@
+	$(hide) $(FILESLIST) $(TARGET_ROOT_OUT) > $(@:.txt=.json)
+	$(hide) build/make/tools/fileslist_util.py -c $(@:.txt=.json) > $@
+
+$(call dist-for-goals, sdk win_sdk sdk_addon, $(INSTALLED_FILES_FILE_ROOT))
+
 BUILT_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk.img
 
 # We just build this directly to the install location.
 INSTALLED_RAMDISK_TARGET := $(BUILT_RAMDISK_TARGET)
-$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) | $(MINIGZIP)
+$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) $(INSTALLED_FILES_FILE_ROOT) | $(MINIGZIP)
 	$(call pretty,"Target ram disk: $@")
 	$(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_ROOT_OUT) | $(MINIGZIP) > $@
 
@@ -849,7 +863,7 @@
 .PHONY: notice_files
 
 # Create the rule to combine the files into text and html/xml forms
-# $(1) - xml_excluded_vendor|xml_vendor|html
+# $(1) - xml_excluded_vendor_product|xml_vendor|xml_product|html
 # $(2) - Plain text output file
 # $(3) - HTML/XML output file
 # $(4) - File title
@@ -874,9 +888,10 @@
 $(2) : $(3)
 $(3) : $(6) $(BUILD_SYSTEM)/Makefile build/make/tools/generate-notice-files.py
 	build/make/tools/generate-notice-files.py --text-output $(2) \
-		$(if $(filter $(1),xml_excluded_vendor),-e vendor --xml-output, \
+		$(if $(filter $(1),xml_excluded_vendor_product),-e vendor$(comma)product --xml-output, \
 		  $(if $(filter $(1),xml_vendor),-i vendor --xml-output, \
-		    --html-output)) $(3) \
+		    $(if $(filter $(1),xml_product),-i product --xml-output, \
+		      --html-output))) $(3) \
 		-t $$(PRIVATE_MESSAGE) -s $$(PRIVATE_DIR)/src
 notice_files: $(2) $(3)
 endef
@@ -902,6 +917,11 @@
 target_vendor_notice_file_xml := $(TARGET_OUT_INTERMEDIATES)/NOTICE_VENDOR.xml
 target_vendor_notice_file_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE_VENDOR.xml.gz
 installed_vendor_notice_xml_gz := $(TARGET_OUT_VENDOR)/etc/NOTICE.xml.gz
+
+target_product_notice_file_txt := $(TARGET_OUT_INTERMEDIATES)/NOTICE_PRODUCT.txt
+target_product_notice_file_xml := $(TARGET_OUT_INTERMEDIATES)/NOTICE_PRODUCT.xml
+target_product_notice_file_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE_PRODUCT.xml.gz
+installed_product_notice_xml_gz := $(TARGET_OUT_PRODUCT)/etc/NOTICE.xml.gz
 endif
 
 ifndef TARGET_BUILD_APPS
@@ -910,7 +930,7 @@
 pdk_fusion_notice_files := $(filter $(TARGET_OUT_NOTICE_FILES)/%, $(ALL_PDK_FUSION_FILES))
 
 ifdef target_vendor_notice_file_xml_gz
-$(eval $(call combine-notice-files, xml_excluded_vendor, \
+$(eval $(call combine-notice-files, xml_excluded_vendor_product, \
 			$(target_notice_file_txt), \
 			$(target_notice_file_html_or_xml), \
 			"Notices for files contained in the filesystem images in this directory:", \
@@ -922,6 +942,14 @@
 			"Notices for files contained in the vendor filesystem image in this directory:", \
 			$(TARGET_OUT_NOTICE_FILES), \
 			$(target_notice_file_html_or_xml)))
+ifdef target_product_notice_file_txt
+$(eval $(call combine-notice-files, xml_product, \
+			$(target_product_notice_file_txt), \
+			$(target_product_notice_file_xml), \
+			"Notices for files contained in the product filesystem image in this directory:", \
+			$(TARGET_OUT_NOTICE_FILES), \
+			$(target_notice_file_html_or_xml)))
+endif
 else
 $(eval $(call combine-notice-files, html, \
 			$(target_notice_file_txt), \
@@ -957,12 +985,23 @@
 	$(copy-file-to-target)
 endif
 
+ifdef target_product_notice_file_xml_gz
+# Install the product html file at /product/etc/NOTICE.xml.gz.
+$(target_product_notice_file_xml_gz): $(target_product_notice_file_xml) | $(MINIGZIP)
+	$(hide) $(MINIGZIP) -9 < $< > $@
+$(installed_product_notice_xml_gz): $(target_product_notice_file_xml_gz)
+	$(copy-file-to-target)
+endif
+
 # if we've been run my mm, mmm, etc, don't reinstall this every time
 ifeq ($(ONE_SHOT_MAKEFILE),)
   ALL_DEFAULT_INSTALLED_MODULES += $(installed_notice_html_or_xml_gz)
   ifdef target_vendor_notice_file_xml_gz
     ALL_DEFAULT_INSTALLED_MODULES += $(installed_vendor_notice_xml_gz)
   endif
+  ifdef target_product_notice_file_xml_gz
+    ALL_DEFAULT_INSTALLED_MODULES += $(installed_product_notice_xml_gz)
+  endif
 endif
 endif  # TARGET_BUILD_APPS
 
@@ -1071,7 +1110,7 @@
 INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS)))
 
 ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY))
-INTERNAL_USERIMAGES_DEPS += $(BUILD_VERITY_TREE) $(APPEND2SIMG) $(VERITY_SIGNER)
+INTERNAL_USERIMAGES_DEPS += $(BUILD_VERITY_METADATA) $(BUILD_VERITY_TREE) $(APPEND2SIMG) $(VERITY_SIGNER)
 ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY_FEC))
 INTERNAL_USERIMAGES_DEPS += $(FEC)
 endif
@@ -1086,55 +1125,81 @@
 INTERNAL_USERIMAGES_DEPS += $(MKE2FS_CONF)
 endif
 
+ifeq (true,$(USE_LOGICAL_PARTITIONS))
+
+ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),true)
+  $(error vboot 1.0 doesn't support logical partition)
+endif
+
+# TODO(b/80195851): Should not define BOARD_AVB_SYSTEM_KEY_PATH without
+# BOARD_AVB_SYSTEM_DETACHED_VBMETA.
+
+endif # USE_LOGICAL_PARTITIONS
+
 # $(1): the path of the output dictionary file
-# $(2): additional "key=value" pairs to append to the dictionary file.
-define generate-userimage-prop-dictionary
+# $(2): a subset of "system vendor cache userdata product oem"
+# $(3): additional "key=value" pairs to append to the dictionary file.
+define generate-image-prop-dictionary
+$(if $(filter $(2),system),\
+    $(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1))
+    $(if $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "system_fs_type=$(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
+    $(if $(BOARD_SYSTEMIMAGE_EXTFS_INODE_COUNT),$(hide) echo "system_extfs_inode_count=$(BOARD_SYSTEMIMAGE_EXTFS_INODE_COUNT)" >> $(1))
+    $(if $(BOARD_SYSTEMIMAGE_EXTFS_RSV_PCT),$(hide) echo "system_extfs_rsv_pct=$(BOARD_SYSTEMIMAGE_EXTFS_RSV_PCT)" >> $(1))
+    $(if $(BOARD_SYSTEMIMAGE_JOURNAL_SIZE),$(hide) echo "system_journal_size=$(BOARD_SYSTEMIMAGE_JOURNAL_SIZE)" >> $(1))
+    $(if $(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "system_squashfs_compressor=$(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
+    $(if $(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "system_squashfs_compressor_opt=$(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
+    $(if $(BOARD_SYSTEMIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "system_squashfs_block_size=$(BOARD_SYSTEMIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
+    $(if $(BOARD_SYSTEMIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "system_squashfs_disable_4k_align=$(BOARD_SYSTEMIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
+    $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH),$(hide) echo "system_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH)" >> $(1))
+    $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_HEADROOM),$(hide) echo "system_headroom=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_HEADROOM)" >> $(1))
+    $(if $(BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "system_reserved_size=$(BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
+)
+$(if $(filter $(2),userdata),\
+    $(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
+    $(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(1))
+)
+$(if $(filter $(2),cache),\
+    $(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
+    $(if $(BOARD_CACHEIMAGE_PARTITION_SIZE),$(hide) echo "cache_size=$(BOARD_CACHEIMAGE_PARTITION_SIZE)" >> $(1))
+)
+$(if $(filter $(2),vendor),\
+    $(if $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "vendor_fs_type=$(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
+    $(if $(BOARD_VENDORIMAGE_EXTFS_INODE_COUNT),$(hide) echo "vendor_extfs_inode_count=$(BOARD_VENDORIMAGE_EXTFS_INODE_COUNT)" >> $(1))
+    $(if $(BOARD_VENDORIMAGE_EXTFS_RSV_PCT),$(hide) echo "vendor_extfs_rsv_pct=$(BOARD_VENDORIMAGE_EXTFS_RSV_PCT)" >> $(1))
+    $(if $(BOARD_VENDORIMAGE_PARTITION_SIZE),$(hide) echo "vendor_size=$(BOARD_VENDORIMAGE_PARTITION_SIZE)" >> $(1))
+    $(if $(BOARD_VENDORIMAGE_JOURNAL_SIZE),$(hide) echo "vendor_journal_size=$(BOARD_VENDORIMAGE_JOURNAL_SIZE)" >> $(1))
+    $(if $(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "vendor_squashfs_compressor=$(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
+    $(if $(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "vendor_squashfs_compressor_opt=$(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
+    $(if $(BOARD_VENDORIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "vendor_squashfs_block_size=$(BOARD_VENDORIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
+    $(if $(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "vendor_squashfs_disable_4k_align=$(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
+    $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH),$(hide) echo "vendor_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH)" >> $(1))
+    $(if $(BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "vendor_reserved_size=$(BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
+)
+$(if $(filter $(2),product),\
+    $(if $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "product_fs_type=$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
+    $(if $(BOARD_PRODUCTIMAGE_EXTFS_INODE_COUNT),$(hide) echo "product_extfs_inode_count=$(BOARD_PRODUCTIMAGE_EXTFS_INODE_COUNT)" >> $(1))
+    $(if $(BOARD_PRODUCTIMAGE_EXTFS_RSV_PCT),$(hide) echo "product_extfs_rsv_pct=$(BOARD_PRODUCTIMAGE_EXTFS_RSV_PCT)" >> $(1))
+    $(if $(BOARD_PRODUCTIMAGE_PARTITION_SIZE),$(hide) echo "product_size=$(BOARD_PRODUCTIMAGE_PARTITION_SIZE)" >> $(1))
+    $(if $(BOARD_PRODUCTIMAGE_JOURNAL_SIZE),$(hide) echo "product_journal_size=$(BOARD_PRODUCTIMAGE_JOURNAL_SIZE)" >> $(1))
+    $(if $(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "product_squashfs_compressor=$(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
+    $(if $(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "product_squashfs_compressor_opt=$(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
+    $(if $(BOARD_PRODUCTIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "product_squashfs_block_size=$(BOARD_PRODUCTIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
+    $(if $(BOARD_PRODUCTIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "product_squashfs_disable_4k_align=$(BOARD_PRODUCTIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
+    $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH),$(hide) echo "product_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH)" >> $(1))
+)
+$(if $(filter $(2),oem),\
+    $(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
+    $(if $(BOARD_OEMIMAGE_JOURNAL_SIZE),$(hide) echo "oem_journal_size=$(BOARD_OEMIMAGE_JOURNAL_SIZE)" >> $(1))
+    $(if $(BOARD_OEMIMAGE_EXTFS_INODE_COUNT),$(hide) echo "oem_extfs_inode_count=$(BOARD_OEMIMAGE_EXTFS_INODE_COUNT)" >> $(1))
+    $(if $(BOARD_OEMIMAGE_EXTFS_RSV_PCT),$(hide) echo "oem_extfs_rsv_pct=$(BOARD_OEMIMAGE_EXTFS_RSV_PCT)" >> $(1))
+)
 $(hide) echo "ext_mkuserimg=$(notdir $(MKEXTUSERIMG))" >> $(1)
 $(if $(INTERNAL_USERIMAGES_EXT_VARIANT),$(hide) echo "fs_type=$(INTERNAL_USERIMAGES_EXT_VARIANT)" >> $(1))
-$(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1))
-$(if $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "system_fs_type=$(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
-$(if $(BOARD_SYSTEMIMAGE_EXTFS_INODE_COUNT),$(hide) echo "system_extfs_inode_count=$(BOARD_SYSTEMIMAGE_EXTFS_INODE_COUNT)" >> $(1))
-$(if $(BOARD_SYSTEMIMAGE_EXTFS_RSV_PCT),$(hide) echo "system_extfs_rsv_pct=$(BOARD_SYSTEMIMAGE_EXTFS_RSV_PCT)" >> $(1))
-$(if $(BOARD_SYSTEMIMAGE_JOURNAL_SIZE),$(hide) echo "system_journal_size=$(BOARD_SYSTEMIMAGE_JOURNAL_SIZE)" >> $(1))
-$(if $(BOARD_EXT4_SHARE_DUP_BLOCKS),$(hide) echo "ext4_share_dup_blocks=$(BOARD_EXT4_SHARE_DUP_BLOCKS)" >> $(1))
-$(if $(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "system_squashfs_compressor=$(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
-$(if $(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "system_squashfs_compressor_opt=$(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
-$(if $(BOARD_SYSTEMIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "system_squashfs_block_size=$(BOARD_SYSTEMIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
-$(if $(BOARD_SYSTEMIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "system_squashfs_disable_4k_align=$(BOARD_SYSTEMIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
-$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH),$(hide) echo "system_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH)" >> $(1))
-$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_HEADROOM),$(hide) echo "system_headroom=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_HEADROOM)" >> $(1))
-$(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
-$(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(1))
-$(if $(BOARD_FLASH_LOGICAL_BLOCK_SIZE), $(hide) echo "flash_logical_block_size=$(BOARD_FLASH_LOGICAL_BLOCK_SIZE)" >> $(1))
-$(if $(BOARD_FLASH_ERASE_BLOCK_SIZE), $(hide) echo "flash_erase_block_size=$(BOARD_FLASH_ERASE_BLOCK_SIZE)" >> $(1))
-$(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
-$(if $(BOARD_CACHEIMAGE_PARTITION_SIZE),$(hide) echo "cache_size=$(BOARD_CACHEIMAGE_PARTITION_SIZE)" >> $(1))
-$(if $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "vendor_fs_type=$(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
-$(if $(BOARD_VENDORIMAGE_EXTFS_INODE_COUNT),$(hide) echo "vendor_extfs_inode_count=$(BOARD_VENDORIMAGE_EXTFS_INODE_COUNT)" >> $(1))
-$(if $(BOARD_VENDORIMAGE_EXTFS_RSV_PCT),$(hide) echo "vendor_extfs_rsv_pct=$(BOARD_VENDORIMAGE_EXTFS_RSV_PCT)" >> $(1))
-$(if $(BOARD_VENDORIMAGE_PARTITION_SIZE),$(hide) echo "vendor_size=$(BOARD_VENDORIMAGE_PARTITION_SIZE)" >> $(1))
-$(if $(BOARD_VENDORIMAGE_JOURNAL_SIZE),$(hide) echo "vendor_journal_size=$(BOARD_VENDORIMAGE_JOURNAL_SIZE)" >> $(1))
-$(if $(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "vendor_squashfs_compressor=$(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
-$(if $(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "vendor_squashfs_compressor_opt=$(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
-$(if $(BOARD_VENDORIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "vendor_squashfs_block_size=$(BOARD_VENDORIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
-$(if $(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "vendor_squashfs_disable_4k_align=$(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
-$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH),$(hide) echo "vendor_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH)" >> $(1))
-$(if $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "product_fs_type=$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
-$(if $(BOARD_PRODUCTIMAGE_EXTFS_INODE_COUNT),$(hide) echo "product_extfs_inode_count=$(BOARD_PRODUCTIMAGE_EXTFS_INODE_COUNT)" >> $(1))
-$(if $(BOARD_PRODUCTIMAGE_EXTFS_RSV_PCT),$(hide) echo "product_extfs_rsv_pct=$(BOARD_PRODUCTIMAGE_EXTFS_RSV_PCT)" >> $(1))
-$(if $(BOARD_PRODUCTIMAGE_PARTITION_SIZE),$(hide) echo "product_size=$(BOARD_PRODUCTIMAGE_PARTITION_SIZE)" >> $(1))
-$(if $(BOARD_PRODUCTIMAGE_JOURNAL_SIZE),$(hide) echo "product_journal_size=$(BOARD_PRODUCTIMAGE_JOURNAL_SIZE)" >> $(1))
-$(if $(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "product_squashfs_compressor=$(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
-$(if $(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "product_squashfs_compressor_opt=$(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
-$(if $(BOARD_PRODUCTIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "product_squashfs_block_size=$(BOARD_PRODUCTIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
-$(if $(BOARD_PRODUCTIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "product_squashfs_disable_4k_align=$(BOARD_PRODUCTIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
-$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH),$(hide) echo "product_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH)" >> $(1))
-$(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
-$(if $(BOARD_OEMIMAGE_JOURNAL_SIZE),$(hide) echo "oem_journal_size=$(BOARD_OEMIMAGE_JOURNAL_SIZE)" >> $(1))
-$(if $(BOARD_OEMIMAGE_EXTFS_INODE_COUNT),$(hide) echo "oem_extfs_inode_count=$(BOARD_OEMIMAGE_EXTFS_INODE_COUNT)" >> $(1))
-$(if $(BOARD_OEMIMAGE_EXTFS_RSV_PCT),$(hide) echo "oem_extfs_rsv_pct=$(BOARD_OEMIMAGE_EXTFS_RSV_PCT)" >> $(1))
 $(if $(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG),$(hide) echo "extfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG)" >> $(1))
 $(if $(INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG),$(hide) echo "squashfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG)" >> $(1))
+$(if $(BOARD_EXT4_SHARE_DUP_BLOCKS),$(hide) echo "ext4_share_dup_blocks=$(BOARD_EXT4_SHARE_DUP_BLOCKS)" >> $(1))
+$(if $(BOARD_FLASH_LOGICAL_BLOCK_SIZE), $(hide) echo "flash_logical_block_size=$(BOARD_FLASH_LOGICAL_BLOCK_SIZE)" >> $(1))
+$(if $(BOARD_FLASH_ERASE_BLOCK_SIZE), $(hide) echo "flash_erase_block_size=$(BOARD_FLASH_ERASE_BLOCK_SIZE)" >> $(1))
 $(hide) echo "selinux_fc=$(SELINUX_FC)" >> $(1)
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER),$(hide) echo "boot_signer=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)" >> $(1))
@@ -1175,9 +1240,22 @@
 $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
     $(hide) echo "recovery_as_boot=true" >> $(1))
 $(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
-    $(hide) echo "system_root_image=true" >> $(1);\
-    echo "ramdisk_dir=$(TARGET_ROOT_OUT)" >> $(1))
-$(if $(2),$(hide) $(foreach kv,$(2),echo "$(kv)" >> $(1);))
+    $(hide) echo "system_root_image=true" >> $(1)
+    $(hide) echo "ramdisk_dir=$(TARGET_ROOT_OUT)" >> $(1))
+$(if $(USE_LOGICAL_PARTITIONS),$(hide) echo "use_logical_partitions=true" >> $(1))
+$(if $(3),$(hide) $(foreach kv,$(3),echo "$(kv)" >> $(1);))
+endef
+
+# $(1): the path of the output dictionary file
+# $(2): additional "key=value" pairs to append to the dictionary file.
+define generate-userimage-prop-dictionary
+$(call generate-image-prop-dictionary,$(1),system vendor cache userdata product oem,$(2))
+endef
+
+# $(1): the path of the input dictionary file, where each line has the format key=value
+# $(2): the key to look up
+define read-image-prop-dictionary
+$$(grep '$(2)=' $(1) | cut -f2- -d'=')
 endef
 
 # $(1): modules list
@@ -1352,8 +1430,6 @@
   # 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
   # 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)))
@@ -1381,10 +1457,6 @@
           >> $(TARGET_RECOVERY_ROOT_OUT)/prop.default
   $(hide) ln -sf prop.default $(TARGET_RECOVERY_ROOT_OUT)/default.prop
   $(BOARD_RECOVERY_IMAGE_PREPARE)
-  $(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)), \
-    $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/system_root; \
-            rm -rf $(TARGET_RECOVERY_ROOT_OUT)/system; \
-            ln -sf /system_root/system $(TARGET_RECOVERY_ROOT_OUT)/system) # Mount the system_root_image to /system_root and symlink /system.
   $(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
   $(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)), \
     $(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1).unsigned, \
@@ -1406,8 +1478,6 @@
       $(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
-
 ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
 ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER))
 $(INSTALLED_BOOTIMAGE_TARGET) : $(BOOT_SIGNER)
@@ -1418,7 +1488,7 @@
 ifeq (true,$(BOARD_AVB_ENABLE))
 $(INSTALLED_BOOTIMAGE_TARGET) : $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH)
 endif
-$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) $(ADBD) \
+$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
 		$(INSTALLED_RAMDISK_TARGET) \
 		$(INTERNAL_RECOVERYIMAGE_FILES) \
 		$(recovery_initrc) $(recovery_sepolicy) $(recovery_kernel) \
@@ -1433,7 +1503,7 @@
 		$(call build-recoveryimage-target, $@)
 endif
 
-$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) $(ADBD) \
+$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
 		$(INSTALLED_RAMDISK_TARGET) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
 		$(INTERNAL_RECOVERYIMAGE_FILES) \
@@ -1499,6 +1569,31 @@
   endif
 endif
 
+# When building a system root image, also add the ramdisk image as a dependency
+# to ensure all files in it are built before it is created.
+ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+  FULL_SYSTEMIMAGE_DEPS += $(INTERNAL_RAMDISK_FILES) $(INSTALLED_FILES_FILE_ROOT)
+endif
+
+# -----------------------------------------------------------------
+# Final System VINTF manifest including fragments. This is not assembled
+# on the device because it depends on everything in a given device
+# image which defines a vintf_fragment.
+
+BUILT_ASSEMBLED_SYSTEM_MANIFEST := $(PRODUCT_OUT)/verified_assembled_system_manifest.xml
+$(BUILT_ASSEMBLED_SYSTEM_MANIFEST): $(HOST_OUT_EXECUTABLES)/assemble_vintf
+$(BUILT_ASSEMBLED_SYSTEM_MANIFEST): $(BUILT_VENDOR_MATRIX)
+$(BUILT_ASSEMBLED_SYSTEM_MANIFEST): $(BUILT_SYSTEM_MANIFEST)
+$(BUILT_ASSEMBLED_SYSTEM_MANIFEST): $(FULL_SYSTEMIMAGE_DEPS)
+	@echo "Verifying system VINTF manifest."
+	PRODUCT_ENFORCE_VINTF_MANIFEST=$(PRODUCT_ENFORCE_VINTF_MANIFEST) \
+	$(HOST_OUT_EXECUTABLES)/assemble_vintf \
+		-c $(BUILT_VENDOR_MATRIX) \
+		-i $(BUILT_SYSTEM_MANIFEST) \
+		$$([ -d $(TARGET_OUT)/etc/vintf/manifest ] && \
+			find $(TARGET_OUT)/etc/vintf/manifest -type f -name "*.xml" | \
+			sed "s/^/-i /" | tr '\n' ' ') -o $@
+
 # -----------------------------------------------------------------
 # installed file list
 # Depending on anything that $(BUILT_SYSTEMIMAGE) depends on.
@@ -1506,6 +1601,8 @@
 # so that we can get the size stat even if the build fails due to too large
 # system image.
 INSTALLED_FILES_FILE := $(PRODUCT_OUT)/installed-files.txt
+INSTALLED_FILES_JSON := $(INSTALLED_FILES_FILE:.txt=.json)
+$(INSTALLED_FILES_FILE): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON)
 $(INSTALLED_FILES_FILE): $(FULL_SYSTEMIMAGE_DEPS) $(FILESLIST)
 	@echo Installed file list: $@
 	@mkdir -p $(dir $@)
@@ -1558,23 +1655,17 @@
   $(call create-system-vendor-symlink)
   $(call create-system-product-symlink)
   @mkdir -p $(dir $(1)) $(systemimage_intermediates) && rm -rf $(systemimage_intermediates)/system_image_info.txt
-  $(call generate-userimage-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt, \
+  $(call generate-image-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt,system, \
       skip_fsck=true)
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       build/make/tools/releasetools/build_image.py \
       $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) $(TARGET_OUT) \
-      || ( echo "Out of space? the tree size of $(TARGET_OUT) is (MB): " 1>&2 ;\
-           du -sm $(TARGET_OUT) 1>&2;\
-           if [ "$(INTERNAL_USERIMAGES_EXT_VARIANT)" == "ext4" ]; then \
-               maxsize=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE); \
-               echo "The max is $$(( maxsize / 1048576 )) MB." 1>&2 ;\
-           else \
-               echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576 )) MB." 1>&2 ;\
-           fi; \
-           mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE) $(DIST_DIR)/installed-files-rescued.txt; \
+      $(systemimage_intermediates)/generated_system_image_info.txt \
+      || ( mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE) $(DIST_DIR)/installed-files-rescued.txt; \
            exit 1 )
 endef
 
+$(BUILT_SYSTEMIMAGE): $(BUILT_ASSEMBLED_SYSTEM_MANIFEST)
 $(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(BUILD_IMAGE_SRCS)
 	$(call build-systemimage-target,$@)
 
@@ -1612,7 +1703,9 @@
 $(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH)
 	@echo "Install system fs image: $@"
 	$(copy-file-to-target)
-	$(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
+	$(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),\
+		$(call read-image-prop-dictionary,\
+			$(systemimage_intermediates)/generated_system_image_info.txt,system_size))
 
 systemimage: $(INSTALLED_SYSTEMIMAGE)
 
@@ -1621,7 +1714,9 @@
 	            | $(INTERNAL_USERIMAGES_DEPS)
 	@echo "make $@: ignoring dependencies"
 	$(call build-systemimage-target,$(INSTALLED_SYSTEMIMAGE))
-	$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMIMAGE),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
+	$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMIMAGE),\
+		$(call read-image-prop-dictionary,\
+			$(systemimage_intermediates)/generated_system_image_info.txt,system_size))
 
 ifneq (,$(filter systemimage-nodeps snod, $(MAKECMDGOALS)))
 ifeq (true,$(WITH_DEXPREOPT))
@@ -1794,7 +1889,7 @@
   $(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
   @mkdir -p $(TARGET_OUT_DATA)
   @mkdir -p $(userdataimage_intermediates) && rm -rf $(userdataimage_intermediates)/userdata_image_info.txt
-  $(call generate-userimage-prop-dictionary, $(userdataimage_intermediates)/userdata_image_info.txt, skip_fsck=true)
+  $(call generate-image-prop-dictionary, $(userdataimage_intermediates)/userdata_image_info.txt,userdata,skip_fsck=true)
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       build/make/tools/releasetools/build_image.py \
       $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt $(INSTALLED_USERDATAIMAGE_TARGET) $(TARGET_OUT)
@@ -1901,7 +1996,7 @@
   $(call pretty,"Target cache fs image: $(INSTALLED_CACHEIMAGE_TARGET)")
   @mkdir -p $(TARGET_OUT_CACHE)
   @mkdir -p $(cacheimage_intermediates) && rm -rf $(cacheimage_intermediates)/cache_image_info.txt
-  $(call generate-userimage-prop-dictionary, $(cacheimage_intermediates)/cache_image_info.txt, skip_fsck=true)
+  $(call generate-image-prop-dictionary, $(cacheimage_intermediates)/cache_image_info.txt,cache,skip_fsck=true)
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       build/make/tools/releasetools/build_image.py \
       $(TARGET_OUT_CACHE) $(cacheimage_intermediates)/cache_image_info.txt $(INSTALLED_CACHEIMAGE_TARGET) $(TARGET_OUT)
@@ -1942,6 +2037,8 @@
     $(PDK_FUSION_SYMLINK_STAMP)
 
 INSTALLED_FILES_FILE_SYSTEMOTHER := $(PRODUCT_OUT)/installed-files-system-other.txt
+INSTALLED_FILES_JSON_SYSTEMOTHER := $(INSTALLED_FILES_FILE_SYSTEMOTHER:.txt=.json)
+$(INSTALLED_FILES_FILE_SYSTEMOTHER): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_SYSTEMOTHER)
 $(INSTALLED_FILES_FILE_SYSTEMOTHER) : $(INTERNAL_SYSTEMOTHERIMAGE_FILES) $(FILESLIST)
 	@echo Installed file list: $@
 	@mkdir -p $(dir $@)
@@ -1958,11 +2055,14 @@
   $(call pretty,"Target system_other fs image: $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)")
   @mkdir -p $(TARGET_OUT_SYSTEM_OTHER)
   @mkdir -p $(systemotherimage_intermediates) && rm -rf $(systemotherimage_intermediates)/system_other_image_info.txt
-  $(call generate-userimage-prop-dictionary, $(systemotherimage_intermediates)/system_other_image_info.txt, skip_fsck=true)
+  $(call generate-image-prop-dictionary, $(systemotherimage_intermediates)/system_other_image_info.txt,system,skip_fsck=true)
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       build/make/tools/releasetools/build_image.py \
-      $(TARGET_OUT_SYSTEM_OTHER) $(systemotherimage_intermediates)/system_other_image_info.txt $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) $(TARGET_OUT)
-  $(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
+      $(TARGET_OUT_SYSTEM_OTHER) $(systemotherimage_intermediates)/system_other_image_info.txt $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) $(TARGET_OUT)\
+      $(systemotherimage_intermediates)/generated_system_other_image_info.txt
+  $(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),\
+    $(call read-image-prop-dictionary,\
+      $(systemotherimage_intermediates)/generated_system_other_image_info.txt,system_size))
 endef
 
 # We just build this directly to the install location.
@@ -1989,10 +2089,38 @@
       $(ALL_PDK_FUSION_FILES)) \
     $(PDK_FUSION_SYMLINK_STAMP)
 
+# Final Vendor VINTF manifest including fragments. This is not assembled
+# on the device because it depends on everything in a given device
+# image which defines a vintf_fragment.
+ifdef BUILT_VENDOR_MANIFEST
+BUILT_ASSEMBLED_VENDOR_MANIFEST := $(PRODUCT_OUT)/verified_assembled_vendor_manifest.xml
+ifeq (true,$(strip $(PRODUCT_ENFORCE_VINTF_MANIFEST)))
+ifdef DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE
+# TODO(b/65028233): turn this on globally
+$(BUILT_ASSEMBLED_VENDOR_MANIFEST): PRIVATE_SYSTEM_ASSEMBLE_VINTF_ENV_VARS := VINTF_ENFORCE_NO_UNUSED_HALS=true
+endif # DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE
+endif # PRODUCT_ENFORCE_VINTF_MANIFEST
+$(BUILT_ASSEMBLED_VENDOR_MANIFEST): $(HOST_OUT_EXECUTABLES)/assemble_vintf
+$(BUILT_ASSEMBLED_VENDOR_MANIFEST): $(BUILT_SYSTEM_MATRIX)
+$(BUILT_ASSEMBLED_VENDOR_MANIFEST): $(BUILT_VENDOR_MANIFEST)
+$(BUILT_ASSEMBLED_VENDOR_MANIFEST): $(INTERNAL_VENDORIMAGE_FILES)
+	@echo "Verifying vendor VINTF manifest."
+	PRODUCT_ENFORCE_VINTF_MANIFEST=$(PRODUCT_ENFORCE_VINTF_MANIFEST) \
+	$(PRIVATE_SYSTEM_ASSEMBLE_VINTF_ENV_VARS) \
+	$(HOST_OUT_EXECUTABLES)/assemble_vintf \
+		-c $(BUILT_SYSTEM_MATRIX) \
+		-i $(BUILT_VENDOR_MANIFEST) \
+		$$([ -d $(TARGET_OUT_VENDOR)/etc/vintf/manifest ] && \
+			find $(TARGET_OUT_VENDOR)/etc/vintf/manifest -type f -name "*.xml" | \
+			sed "s/^/-i /" | tr '\n' ' ') -o $@
+endif # BUILT_VENDOR_MANIFEST
+
 # platform.zip depends on $(INTERNAL_VENDORIMAGE_FILES).
 $(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_VENDORIMAGE_FILES)
 
 INSTALLED_FILES_FILE_VENDOR := $(PRODUCT_OUT)/installed-files-vendor.txt
+INSTALLED_FILES_JSON_VENDOR := $(INSTALLED_FILES_FILE_VENDOR:.txt=.json)
+$(INSTALLED_FILES_FILE_VENDOR): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_VENDOR)
 $(INSTALLED_FILES_FILE_VENDOR) : $(INTERNAL_VENDORIMAGE_FILES) $(FILESLIST)
 	@echo Installed file list: $@
 	@mkdir -p $(dir $@)
@@ -2007,17 +2135,23 @@
   $(call pretty,"Target vendor fs image: $(INSTALLED_VENDORIMAGE_TARGET)")
   @mkdir -p $(TARGET_OUT_VENDOR)
   @mkdir -p $(vendorimage_intermediates) && rm -rf $(vendorimage_intermediates)/vendor_image_info.txt
-  $(call generate-userimage-prop-dictionary, $(vendorimage_intermediates)/vendor_image_info.txt, skip_fsck=true)
+  $(call generate-image-prop-dictionary, $(vendorimage_intermediates)/vendor_image_info.txt,vendor,skip_fsck=true)
   $(if $(BOARD_VENDOR_KERNEL_MODULES), \
     $(call build-image-kernel-modules,$(BOARD_VENDOR_KERNEL_MODULES),$(TARGET_OUT_VENDOR),vendor/,$(call intermediates-dir-for,PACKAGING,depmod_vendor)))
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       build/make/tools/releasetools/build_image.py \
-      $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT)
-  $(hide) $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET),$(BOARD_VENDORIMAGE_PARTITION_SIZE))
+      $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT) \
+      $(vendorimage_intermediates)/generated_vendor_image_info.txt
+  $(hide) $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET),\
+      $(call read-image-prop-dictionary,\
+          $(vendorimage_intermediates)/generated_vendor_image_info.txt,vendor_size))
 endef
 
 # We just build this directly to the install location.
 INSTALLED_VENDORIMAGE_TARGET := $(BUILT_VENDORIMAGE_TARGET)
+ifdef BUILT_VENDOR_MANIFEST
+$(INSTALLED_VENDORIMAGE_TARGET): $(BUILT_ASSEMBLED_VENDOR_MANIFEST)
+endif
 $(INSTALLED_VENDORIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_VENDORIMAGE_FILES) $(INSTALLED_FILES_FILE_VENDOR) $(BUILD_IMAGE_SRCS) $(DEPMOD) $(BOARD_VENDOR_KERNEL_MODULES)
 	$(build-vendorimage-target)
 
@@ -2045,6 +2179,8 @@
 $(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_PRODUCTIMAGE_FILES)
 
 INSTALLED_FILES_FILE_PRODUCT := $(PRODUCT_OUT)/installed-files-product.txt
+INSTALLED_FILES_JSON_PRODUCT := $(INSTALLED_FILES_FILE_PRODUCT:.txt=.json)
+$(INSTALLED_FILES_FILE_PRODUCT): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_PRODUCT)
 $(INSTALLED_FILES_FILE_PRODUCT) : $(INTERNAL_PRODUCTIMAGE_FILES) $(FILESLIST)
 	@echo Installed file list: $@
 	@mkdir -p $(dir $@)
@@ -2059,7 +2195,7 @@
   $(call pretty,"Target product fs image: $(INSTALLED_PRODUCTIMAGE_TARGET)")
   @mkdir -p $(TARGET_OUT_PRODUCT)
   @mkdir -p $(productimage_intermediates) && rm -rf $(productimage_intermediates)/product_image_info.txt
-  $(call generate-userimage-prop-dictionary, $(productimage_intermediates)/product_image_info.txt, skip_fsck=true)
+  $(call generate-image-prop-dictionary, $(productimage_intermediates)/product_image_info.txt,product,skip_fsck=true)
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       ./build/tools/releasetools/build_image.py \
       $(TARGET_OUT_PRODUCT) $(productimage_intermediates)/product_image_info.txt $(INSTALLED_PRODUCTIMAGE_TARGET) $(TARGET_OUT)
@@ -2221,12 +2357,12 @@
 BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --rollback_index $(BOARD_AVB_ROLLBACK_INDEX)
 endif
 
-ifndef BOARD_BOOTIMAGE_PARTITION_SIZE
-  $(error BOARD_BOOTIMAGE_PARTITION_SIZE must be set for BOARD_AVB_ENABLE)
+ifeq (eng,$(filter eng, $(TARGET_BUILD_VARIANT)))
+BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --set_hashtree_disabled_flag
 endif
 
-ifndef BOARD_SYSTEMIMAGE_PARTITION_SIZE
-  $(error BOARD_SYSTEMIMAGE_PARTITION_SIZE must be set for BOARD_AVB_ENABLE)
+ifndef BOARD_BOOTIMAGE_PARTITION_SIZE
+  $(error BOARD_BOOTIMAGE_PARTITION_SIZE must be set for BOARD_AVB_ENABLE)
 endif
 
 # $(1): the directory to extract public keys to
@@ -2348,7 +2484,6 @@
   $(HOST_OUT_EXECUTABLES)/sload_f2fs \
   $(HOST_OUT_EXECUTABLES)/simg2img \
   $(HOST_OUT_EXECUTABLES)/e2fsck \
-  $(HOST_OUT_EXECUTABLES)/build_verity_tree \
   $(HOST_OUT_EXECUTABLES)/generate_verity_key \
   $(HOST_OUT_EXECUTABLES)/verity_signer \
   $(HOST_OUT_EXECUTABLES)/verity_verifier \
@@ -2361,7 +2496,9 @@
   $(HOST_OUT_EXECUTABLES)/delta_generator \
   $(AVBTOOL) \
   $(BLK_ALLOC_TO_BASE_FS) \
-  $(BROTLI)
+  $(BROTLI) \
+  $(BUILD_VERITY_METADATA) \
+  $(BUILD_VERITY_TREE)
 
 ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT))
 OTATOOLS += \
@@ -2407,18 +2544,17 @@
 $(BUILT_OTATOOLS_PACKAGE): zip_root := $(call intermediates-dir-for,PACKAGING,otatools)/otatools
 
 OTATOOLS_DEPS := \
-  system/extras/verity/build_verity_metadata.py \
   system/extras/ext4_utils/mke2fs.conf \
   $(sort $(shell find external/avb/test/data -type f -name "testkey_*.pem" -o \
       -name "atx_metadata.bin")) \
-  $(sort $(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 \
+  $(sort $(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 $(wildcard vendor) -type f -name \*.pk8 -o -name verifiedboot\* -o \
-      -name \*.x509.pem -o -name oem\*.prop))
+  $(sort $(shell find device $(wildcard vendor) -type f -name "*.pk8" -o -name "verifiedboot*" -o \
+      -name "*.x509.pem" -o -name "oem*.prop"))
 
 OTATOOLS_RELEASETOOLS := \
-  $(sort $(shell find build/make/tools/releasetools -name \*.pyc -prune -o -type f))
+  $(sort $(shell find build/make/tools/releasetools -name "*.pyc" -prune -o -type f))
 
 ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT))
 OTATOOLS_DEPS += \
@@ -2506,10 +2642,6 @@
 endif
 
 ifeq ($(AB_OTA_UPDATER),true)
-  ifdef BRILLO_VENDOR_PARTITIONS
-    $(BUILT_TARGET_FILES_PACKAGE): $(foreach p,$(BRILLO_VENDOR_PARTITIONS),\
-                                     $(call word-colon,1,$(p))/$(call word-colon,2,$(p)))
-  endif
   ifdef OSRELEASED_DIRECTORY
     $(BUILT_TARGET_FILES_PACKAGE): $(TARGET_OUT_OEM)/$(OSRELEASED_DIRECTORY)/product_id
     $(BUILT_TARGET_FILES_PACKAGE): $(TARGET_OUT_OEM)/$(OSRELEASED_DIRECTORY)/product_version
@@ -2551,7 +2683,9 @@
 		$(HOST_OUT_EXECUTABLES)/imgdiff \
 		$(HOST_OUT_EXECUTABLES)/bsdiff \
 		$(BUILD_IMAGE_SRCS) \
-		$(BUILT_VENDOR_MANIFEST) \
+		$(BUILT_ASSEMBLED_SYSTEM_MANIFEST) \
+		$(BUILT_ASSEMBLED_VENDOR_MANIFEST) \
+		$(BUILT_SYSTEM_MATRIX) \
 		$(BUILT_VENDOR_MATRIX) \
 		| $(ACP)
 	@echo "Package target files: $@"
@@ -2751,17 +2885,6 @@
 	@# Include the build type in META/misc_info.txt so the server can easily differentiate production builds.
 	$(hide) echo "build_type=$(TARGET_BUILD_VARIANT)" >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "ab_update=true" >> $(zip_root)/META/misc_info.txt
-ifdef BRILLO_VENDOR_PARTITIONS
-	$(hide) mkdir -p $(zip_root)/VENDOR_IMAGES
-	$(hide) for f in $(BRILLO_VENDOR_PARTITIONS); do \
-	  pair1="$$(echo $$f | awk -F':' '{print $$1}')"; \
-	  pair2="$$(echo $$f | awk -F':' '{print $$2}')"; \
-	  src=$${pair1}/$${pair2}; \
-	  dest=$(zip_root)/VENDOR_IMAGES/$${pair2}; \
-	  mkdir -p $$(dirname "$${dest}"); \
-	  cp $${src} $${dest}; \
-	done;
-endif
 ifdef OSRELEASED_DIRECTORY
 	$(hide) cp $(TARGET_OUT_OEM)/$(OSRELEASED_DIRECTORY)/product_id $(zip_root)/META/product_id.txt
 	$(hide) cp $(TARGET_OUT_OEM)/$(OSRELEASED_DIRECTORY)/product_version $(zip_root)/META/product_version.txt
@@ -2838,10 +2961,10 @@
 	$(hide) $(call fs_config,$(zip_root)/SYSTEM_OTHER,system/) > $(zip_root)/META/system_other_filesystem_config.txt
 endif
 	@# 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
-ifdef BUILT_VENDOR_MANIFEST
-	$(hide) cp $(BUILT_VENDOR_MANIFEST) $(zip_root)/META/vendor_manifest.xml
+	$(hide) cp $(BUILT_SYSTEM_MATRIX) $(zip_root)/META/system_matrix.xml
+	$(hide) cp $(BUILT_ASSEMBLED_SYSTEM_MANIFEST) $(zip_root)/META/system_manifest.xml
+ifdef BUILT_ASSEMBLED_VENDOR_MANIFEST
+	$(hide) cp $(BUILT_ASSEMBLED_VENDOR_MANIFEST) $(zip_root)/META/vendor_manifest.xml
 endif
 ifdef BUILT_VENDOR_MATRIX
 	$(hide) cp $(BUILT_VENDOR_MATRIX) $(zip_root)/META/vendor_matrix.xml
@@ -2865,7 +2988,7 @@
 # -----------------------------------------------------------------
 # NDK Sysroot Package
 NDK_SYSROOT_TARGET := $(PRODUCT_OUT)/ndk_sysroot.tar.bz2
-$(NDK_SYSROOT_TARGET): ndk
+$(NDK_SYSROOT_TARGET): $(SOONG_OUT_DIR)/ndk.timestamp
 	@echo Package NDK sysroot...
 	$(hide) tar cjf $@ -C $(SOONG_OUT_DIR) ndk
 
@@ -3208,7 +3331,7 @@
 	if [ $$FAIL ]; then exit 1; fi
 	$(hide) echo $(notdir $(SDK_FONT_DEPS)) | tr " " "\n"  > $(SDK_FONT_TEMP)/fontsInSdk.txt
 	$(hide) ( \
-		ATREE_STRIP="strip -x" \
+		ATREE_STRIP="$(HOST_STRIP) -x" \
 		$(HOST_OUT_EXECUTABLES)/atree \
 		$(addprefix -f ,$(PRIVATE_INPUT_FILES)) \
 			-m $(PRIVATE_DEP_FILE) \
diff --git a/core/aapt2.mk b/core/aapt2.mk
index b3a7c93..fbbf3dd 100644
--- a/core/aapt2.mk
+++ b/core/aapt2.mk
@@ -64,9 +64,11 @@
 $(my_res_resources_flat) $(my_overlay_resources_flat) $(my_resources_flata): \
   PRIVATE_AAPT2_CFLAGS := --pseudo-localize
 
-my_static_library_resources := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES)),\
+# TODO(b/78447299): Forbid LOCAL_STATIC_JAVA_AAR_LIBRARIES in aapt2 and remove
+# support for it.
+my_static_library_resources := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),\
   $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/package-res.apk)
-my_static_library_extra_packages := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES)),\
+my_static_library_extra_packages := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),\
   $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/extra_packages)
 my_shared_library_resources := $(foreach l, $(LOCAL_SHARED_ANDROID_LIBRARIES),\
   $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/package-res.apk)
diff --git a/core/android_manifest.mk b/core/android_manifest.mk
index 7d573d3..517379a 100644
--- a/core/android_manifest.mk
+++ b/core/android_manifest.mk
@@ -6,40 +6,60 @@
   LOCAL_MANIFEST_FILE := AndroidManifest.xml
 endif
 ifdef LOCAL_FULL_MANIFEST_FILE
-  full_android_manifest := $(LOCAL_FULL_MANIFEST_FILE)
+  main_android_manifest := $(LOCAL_FULL_MANIFEST_FILE)
 else
-  full_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
+  main_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
 endif
 
-my_full_libs_manifest_files := $(LOCAL_FULL_LIBS_MANIFEST_FILES)
-my_full_libs_manifest_deps := $(LOCAL_FULL_LIBS_MANIFEST_FILES)
-
-# Set up dependency on aar libraries
 LOCAL_STATIC_JAVA_AAR_LIBRARIES := $(strip $(LOCAL_STATIC_JAVA_AAR_LIBRARIES))
-ifdef LOCAL_STATIC_JAVA_AAR_LIBRARIES
-my_full_libs_manifest_deps += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
-  $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/classes.jar)
-my_full_libs_manifest_files += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
-  $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/AndroidManifest.xml)
+
+my_full_libs_manifest_files :=
+
+ifndef LOCAL_DONT_MERGE_MANIFESTS
+  my_full_libs_manifest_files += $(LOCAL_FULL_LIBS_MANIFEST_FILES)
+
+  my_full_libs_manifest_files += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES) $(LOCAL_STATIC_ANDROID_LIBRARIES),\
+    $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/manifest/AndroidManifest.xml)
+endif
 
 # With aapt2, we'll link in the built resource from the AAR.
-ifndef LOCAL_USE_AAPT2
-LOCAL_RESOURCE_DIR += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
-  $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/res)
-endif  # LOCAL_USE_AAPT2
-endif  # LOCAL_STATIC_JAVA_AAR_LIBRARIES
+ifneq ($(LOCAL_USE_AAPT2),true)
+  LOCAL_RESOURCE_DIR += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
+    $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/res)
+endif
+
+full_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
+
+ifdef LOCAL_MIN_SDK_VERSION
+  $(full_android_manifest): PRIVATE_MIN_SDK_VERSION := $(LOCAL_MIN_SDK_VERSION)
+else ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
+  $(full_android_manifest): PRIVATE_MIN_SDK_VERSION := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
+else
+  $(full_android_manifest): PRIVATE_MIN_SDK_VERSION := $(DEFAULT_APP_TARGET_SDK)
+endif
 
 # Set up rules to merge library manifest files
-ifdef my_full_libs_manifest_files
-main_android_manifest := $(full_android_manifest)
-full_android_manifest := $(intermediates.COMMON)/AndroidManifest.xml
+my_exported_sdk_libs_file := $(call local-intermediates-dir,COMMON)/exported-sdk-libs
+$(full_android_manifest): PRIVATE_EXPORTED_SDK_LIBS_FILE := $(my_exported_sdk_libs_file)
+$(full_android_manifest): $(my_exported_sdk_libs_file)
+$(full_android_manifest): $(MANIFEST_FIXER)
+
+ifneq (,$(strip $(my_full_libs_manifest_files)))
+
 $(full_android_manifest): PRIVATE_LIBS_MANIFESTS := $(my_full_libs_manifest_files)
-$(full_android_manifest): $(ANDROID_MANIFEST_MERGER_CLASSPATH)
-$(full_android_manifest) : $(main_android_manifest) $(my_full_libs_manifest_deps)
+$(full_android_manifest): $(ANDROID_MANIFEST_MERGER_DEPS)
+$(full_android_manifest) : $(main_android_manifest) $(my_full_libs_manifest_files)
 	@echo "Merge android manifest files: $@ <-- $< $(PRIVATE_LIBS_MANIFESTS)"
 	@mkdir -p $(dir $@)
-	$(hide) $(ANDROID_MANIFEST_MERGER) --main $< \
+	$(call fix-manifest,$<,$@.tmp,$(PRIVATE_MIN_SDK_VERSION),$(PRIVATE_EXPORTED_SDK_LIBS_FILE))
+	$(hide) $(ANDROID_MANIFEST_MERGER) --main $@.tmp \
 	    --libs $(call normalize-path-list,$(PRIVATE_LIBS_MANIFESTS)) \
 	    --out $@
+	rm $@.tmp
+
+else
+$(full_android_manifest): $(main_android_manifest)
+	@echo "Fix manifest: $@"
+	$(call fix-manifest,$<,$@,$(PRIVATE_MIN_SDK_VERSION),$(PRIVATE_EXPORTED_SDK_LIBS_FILE))
 
 endif
diff --git a/core/apidiff.mk b/core/apidiff.mk
index 36d75fe..7876c11 100644
--- a/core/apidiff.mk
+++ b/core/apidiff.mk
@@ -57,12 +57,11 @@
     LOCAL_JAVA_LIBRARIES := android_test_stubs_current $(LOCAL_JAVA_LIBRARIES)
     $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, android_test_stubs_current)
   else
-    # core_<ver> is subset of <ver>. Instead of defining a prebuilt lib for core_<ver>,
-    # use the stub for <ver> when building for apps.
-    _version := $(patsubst core_%,%,$(LOCAL_SDK_VERSION))
-    LOCAL_JAVA_LIBRARIES := sdk_v$(_version) $(LOCAL_JAVA_LIBRARIES)
-    $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, sdk_v$(_version))
-    _version :=
+    # TARGET_BUILD_APPS is set. Use the modules defined in prebuilts/sdk/Android.mk.
+    _module_name := $(call resolve-prebuilt-sdk-module,$(LOCAL_SDK_VERSION))
+    LOCAL_JAVA_LIBRARIES := $(_module_name) $(LOCAL_JAVA_LIBRARIES)
+    $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, $(_module_name))
+    _module_name :=
   endif
 else
   LOCAL_JAVA_LIBRARIES := core-oj core-libart ext framework $(LOCAL_JAVA_LIBRARIES)
@@ -125,7 +124,7 @@
 		$(full_java_lib_deps) \
 		$(jdiff) \
 		$(doclava) \
-		$(LOCAL_MODULE)-docs \
+		$(call doc-timestamp-for,$(LOCAL_MODULE)) \
 		$(LOCAL_ADDITIONAL_DEPENDENCIES)
 	@echo Generating API diff: $(PRIVATE_OUT_DIR)
 	@echo   Old API: $(PRIVATE_OLDAPI)
diff --git a/core/autogen_test_config.mk b/core/autogen_test_config.mk
index c359bac..5feec2b 100644
--- a/core/autogen_test_config.mk
+++ b/core/autogen_test_config.mk
@@ -17,39 +17,35 @@
 # This build rule allows TradeFed test config file to be created based on
 # following inputs:
 #   is_native: If the test is a native test.
-#   LOCAL_MANIFEST_FILE: Name of the AndroidManifest file for the test. If it's
-#       not set, default value `AndroidManifest.xml` will be used.
+#   full_android_manifest: Name of the AndroidManifest file for the test.
 # Output:
 #   autogen_test_config_file: Path to the test config file generated.
 
 autogen_test_config_file := $(dir $(LOCAL_BUILT_MODULE))$(LOCAL_MODULE).config
 ifeq (true,$(is_native))
+ifeq ($(LOCAL_NATIVE_BENCHMARK),true)
+autogen_test_config_template := $(NATIVE_BENCHMARK_TEST_CONFIG_TEMPLATE)
+else
+autogen_test_config_template := $(NATIVE_TEST_CONFIG_TEMPLATE)
+endif
 # Auto generating test config file for native test
-$(autogen_test_config_file) : $(NATIVE_TEST_CONFIG_TEMPLATE)
+$(autogen_test_config_file) : $(autogen_test_config_template)
 	@echo "Auto generating test config $(notdir $@)"
-	$(hide) sed 's&{MODULE}&$(PRIVATE_MODULE)&g' $^ > $@
+	$(hide) sed 's&{MODULE}&$(PRIVATE_MODULE)&g' $< > $@
 my_auto_generate_config := true
 else
 # Auto generating test config file for instrumentation test
-ifeq ($(strip $(LOCAL_MANIFEST_FILE)),)
-  LOCAL_MANIFEST_FILE := AndroidManifest.xml
-endif
-ifdef LOCAL_FULL_MANIFEST_FILE
-  my_android_manifest := $(LOCAL_FULL_MANIFEST_FILE)
-else
-  my_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
-endif
-ifneq (,$(wildcard $(my_android_manifest)))
+ifneq (,$(full_android_manifest))
 $(autogen_test_config_file): PRIVATE_AUTOGEN_TEST_CONFIG_SCRIPT := $(AUTOGEN_TEST_CONFIG_SCRIPT)
-$(autogen_test_config_file): PRIVATE_TEST_CONFIG_ANDROID_MANIFEST := $(my_android_manifest)
+$(autogen_test_config_file): PRIVATE_TEST_CONFIG_ANDROID_MANIFEST := $(full_android_manifest)
 $(autogen_test_config_file): PRIVATE_EMPTY_TEST_CONFIG := $(EMPTY_TEST_CONFIG)
 $(autogen_test_config_file): PRIVATE_TEMPLATE := $(INSTRUMENTATION_TEST_CONFIG_TEMPLATE)
-$(autogen_test_config_file) : $(my_android_manifest) $(EMPTY_TEST_CONFIG) $(INSTRUMENTATION_TEST_CONFIG_TEMPLATE) $(AUTOGEN_TEST_CONFIG_SCRIPT)
+$(autogen_test_config_file) : $(full_android_manifest) $(EMPTY_TEST_CONFIG) $(INSTRUMENTATION_TEST_CONFIG_TEMPLATE) $(AUTOGEN_TEST_CONFIG_SCRIPT)
 	@echo "Auto generating test config $(notdir $@)"
 	@rm -f $@
 	$(hide) $(PRIVATE_AUTOGEN_TEST_CONFIG_SCRIPT) $@ $(PRIVATE_TEST_CONFIG_ANDROID_MANIFEST) $(PRIVATE_EMPTY_TEST_CONFIG) $(PRIVATE_TEMPLATE)
 my_auto_generate_config := true
-endif # ifeq (,$(wildcard $(my_android_manifest)))
+endif # ifneq (,$(full_android_manifest))
 endif # ifneq (true,$(is_native))
 
 ifeq (true,$(my_auto_generate_config))
@@ -60,5 +56,4 @@
   autogen_test_config_file :=
 endif
 
-my_android_manifest :=
 my_auto_generate_config :=
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 22e7aef..f59df3f 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -31,6 +31,7 @@
 ifeq ($(LOCAL_MODULE),)
   $(error $(LOCAL_PATH): LOCAL_MODULE is not defined)
 endif
+$(call verify-module-name)
 
 LOCAL_IS_HOST_MODULE := $(strip $(LOCAL_IS_HOST_MODULE))
 LOCAL_IS_AUX_MODULE := $(strip $(LOCAL_IS_AUX_MODULE))
@@ -423,7 +424,7 @@
 # Make sure we only set up the copy rules once, even if another arch variant
 # shares a common LOCAL_INIT_RC.
 my_init_rc_new_pairs := $(filter-out $(ALL_INIT_RC_INSTALLED_PAIRS),$(my_init_rc_pairs))
-my_init_rc_new_installed := $(call copy-many-files,$(my_init_rc_new_pairs))
+my_init_rc_new_installed := $(call copy-many-init-script-files-checked,$(my_init_rc_new_pairs))
 ALL_INIT_RC_INSTALLED_PAIRS += $(my_init_rc_new_pairs)
 
 $(my_all_targets) : $(my_init_rc_installed)
@@ -440,6 +441,30 @@
 endif # !LOCAL_UNINSTALLABLE_MODULE
 
 ###########################################################
+## VINTF manifest fragment goals
+###########################################################
+
+my_vintf_installed:=
+my_vintf_pairs:=
+ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
+ifndef LOCAL_IS_HOST_MODULE
+ifneq ($(strip $(LOCAL_VINTF_FRAGMENTS)),)
+
+my_vintf_pairs := $(foreach xml,$(LOCAL_VINTF_FRAGMENTS),$(LOCAL_PATH)/$(xml):$(TARGET_OUT$(partition_tag)_ETC)/vintf/manifest/$(notdir $(xml)))
+my_vintf_installed := $(foreach xml,$(my_vintf_pairs),$(call word-colon,2,$(xml)))
+
+# Only set up copy rules once, even if another arch variant shares it
+my_vintf_new_pairs := $(filter-out $(ALL_VINTF_MANIFEST_FRAGMENTS_LIST),$(my_vintf_pairs))
+my_vintf_new_installed := $(call copy-many-vintf-manifest-files-checked,$(my_vintf_pairs))
+
+ALL_VINTF_MANIFEST_FRAGMENTS_LIST += $(my_vintf_new_pairs)
+
+$(my_all_targets) : $(my_vintf_installed)
+endif # LOCAL_VINTF_FRAGMENTS
+endif # !LOCAL_IS_HOST_MODULE
+endif # !LOCAL_UNINSTALLABLE_MODULE
+
+###########################################################
 ## CHECK_BUILD goals
 ###########################################################
 my_checked_module :=
@@ -522,10 +547,6 @@
   is_native := true
   multi_arch := true
 endif
-ifeq ($(LOCAL_MODULE_CLASS),NATIVE_BENCHMARK)
-  is_native := true
-  multi_arch := true
-endif
 ifdef LOCAL_MULTILIB
   multi_arch := true
 endif
@@ -537,7 +558,8 @@
 # The module itself.
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
   $(eval my_compat_dist_$(suite) := $(foreach dir, $(call compatibility_suite_dirs,$(suite),$(arch_dir)), \
-    $(LOCAL_BUILT_MODULE):$(dir)/$(my_installed_module_stem))))
+    $(LOCAL_BUILT_MODULE):$(dir)/$(my_installed_module_stem))) \
+  $(eval my_compat_dist_config_$(suite) := ))
 
 # Make sure we only add the files once for multilib modules.
 ifndef $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
@@ -584,7 +606,7 @@
 
 ifneq (,$(test_config))
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-  $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+  $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
     $(test_config):$(dir)/$(LOCAL_MODULE).config)))
 endif
 
@@ -592,14 +614,14 @@
 
 ifneq (,$(wildcard $(LOCAL_PATH)/DynamicConfig.xml))
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-  $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+  $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
     $(LOCAL_PATH)/DynamicConfig.xml:$(dir)/$(LOCAL_MODULE).dynamic)))
 endif
 
 ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config))
 $(foreach extra_config, $(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config), \
   $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-    $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+    $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
       $(extra_config):$(dir)/$(notdir $(extra_config))))))
 endif
 endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
@@ -618,10 +640,19 @@
 is_native :=
 
 $(call create-suite-dependencies)
+$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+  $(eval my_compat_dist_config_$(suite) := ))
 
 endif  # LOCAL_COMPATIBILITY_SUITE
 
 ###########################################################
+## Add test module to ALL_DISABLED_PRESUBMIT_TESTS if LOCAL_PRESUBMIT_DISABLED is set to true.
+###########################################################
+ifeq ($(LOCAL_PRESUBMIT_DISABLED),true)
+  ALL_DISABLED_PRESUBMIT_TESTS += $(LOCAL_MODULE)
+endif  # LOCAL_PRESUBMIT_DISABLED
+
+###########################################################
 ## Register with ALL_MODULES
 ###########################################################
 
@@ -643,11 +674,11 @@
 ALL_MODULES.$(my_register_name).INSTALLED := \
     $(strip $(ALL_MODULES.$(my_register_name).INSTALLED) \
     $(LOCAL_INSTALLED_MODULE) $(my_init_rc_installed) $(my_installed_symlinks) \
-    $(my_installed_test_data))
+    $(my_installed_test_data) $(my_vintf_installed))
 ALL_MODULES.$(my_register_name).BUILT_INSTALLED := \
     $(strip $(ALL_MODULES.$(my_register_name).BUILT_INSTALLED) \
     $(LOCAL_BUILT_MODULE):$(LOCAL_INSTALLED_MODULE) \
-    $(my_init_rc_pairs) $(my_test_data_pairs))
+    $(my_init_rc_pairs) $(my_test_data_pairs) $(my_vintf_pairs))
 endif
 ifdef LOCAL_PICKUP_FILES
 # Files or directories ready to pick up by the build system
@@ -655,11 +686,32 @@
 ALL_MODULES.$(my_register_name).PICKUP_FILES := \
     $(ALL_MODULES.$(my_register_name).PICKUP_FILES) $(LOCAL_PICKUP_FILES)
 endif
+
 my_required_modules := $(LOCAL_REQUIRED_MODULES) \
     $(LOCAL_REQUIRED_MODULES_$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH))
 ifdef LOCAL_IS_HOST_MODULE
 my_required_modules += $(LOCAL_REQUIRED_MODULES_$($(my_prefix)OS))
 endif
+
+###############################################################################
+## When compiling against the VNDK, add the .vendor suffix to required modules.
+###############################################################################
+ifneq ($(LOCAL_USE_VNDK),)
+  ####################################################
+  ## Soong modules may be built twice, once for /system
+  ## and once for /vendor. If we're using the VNDK,
+  ## switch all soong libraries over to the /vendor
+  ## variant.
+  ####################################################
+  ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+    # We don't do this renaming for soong-defined modules since they already
+    # have correct names (with .vendor suffix when necessary) in their
+    # LOCAL_*_LIBRARIES.
+    my_required_modules := $(foreach l,$(my_required_modules),\
+      $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
+  endif
+endif
+
 ALL_MODULES.$(my_register_name).REQUIRED := \
     $(strip $(ALL_MODULES.$(my_register_name).REQUIRED) $(my_required_modules))
 ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED := \
@@ -744,8 +796,10 @@
 $(j_or_n)-$(h_or_t)-tests $(j_or_n)-tests $(h_or_t)-tests : $(my_checked_module)
 endif
 $(LOCAL_MODULE)-$(h_or_hc_or_t) : $(my_all_targets)
+.PHONY: $(LOCAL_MODULE)-$(h_or_hc_or_t)
 ifeq ($(j_or_n),native)
 $(LOCAL_MODULE)-$(h_or_hc_or_t)$(my_32_64_bit_suffix) : $(my_all_targets)
+.PHONY: $(LOCAL_MODULE)-$(h_or_hc_or_t)$(my_32_64_bit_suffix)
 endif
 endif
 
diff --git a/core/binary.mk b/core/binary.mk
index 954df1f..60f78dd 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -7,6 +7,7 @@
 
 #######################################
 include $(BUILD_SYSTEM)/base_rules.mk
+include $(BUILD_SYSTEM)/use_lld_setup.mk
 #######################################
 
 ##################################################
@@ -404,6 +405,13 @@
    my_cpp_std_cppflags := -std=$(my_cpp_std_version)
 endif
 
+# Extra cflags for projects under external/ directory
+ifeq ($(my_clang),true)
+ifneq ($(filter external/%,$(LOCAL_PATH)),)
+    my_cflags += $(CLANG_EXTERNAL_CFLAGS)
+endif
+endif
+
 # arch-specific static libraries go first so that generic ones can depend on them
 my_static_libraries := $(LOCAL_STATIC_LIBRARIES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_STATIC_LIBRARIES_$(my_32_64_bit_suffix)) $(my_static_libraries)
 my_whole_static_libraries := $(LOCAL_WHOLE_STATIC_LIBRARIES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_WHOLE_STATIC_LIBRARIES_$(my_32_64_bit_suffix)) $(my_whole_static_libraries)
@@ -516,7 +524,15 @@
 my_target_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CFLAGS)
 my_target_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CONLYFLAGS) $(my_c_std_conlyflags)
 my_target_global_cppflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CPPFLAGS) $(my_cpp_std_cppflags)
-my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_LDFLAGS)
+ifeq ($(my_use_clang_lld),true)
+  my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_LLDFLAGS)
+  include $(BUILD_SYSTEM)/pack_dyn_relocs_setup.mk
+  ifeq ($(my_pack_module_relocations),false)
+    my_target_global_ldflags += -Wl,--pack-dyn-relocs=none
+  endif
+else
+  my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_LDFLAGS)
+endif # my_use_clang_lld
 else
 my_target_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CFLAGS)
 my_target_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CONLYFLAGS) $(my_c_std_conlyflags)
@@ -542,7 +558,11 @@
 my_host_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CFLAGS)
 my_host_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CONLYFLAGS) $(my_c_std_conlyflags)
 my_host_global_cppflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CPPFLAGS) $(my_cpp_std_cppflags)
-my_host_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_LDFLAGS)
+ifeq ($(my_use_clang_lld),true)
+  my_host_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_LLDFLAGS)
+else
+  my_host_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_LDFLAGS)
+endif # my_use_clang_lld
 else
 my_host_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CFLAGS)
 my_host_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CONLYFLAGS) $(my_c_std_conlyflags)
@@ -795,7 +815,7 @@
 $(RenderScript_file_stamp): PRIVATE_RS_FLAGS := $(renderscript_flags)
 $(RenderScript_file_stamp): PRIVATE_RS_SOURCE_FILES := $(renderscript_sources_fullpath)
 $(RenderScript_file_stamp): PRIVATE_RS_OUTPUT_DIR := $(renderscript_intermediate)
-$(RenderScript_file_stamp): PRIVATE_RS_TARGET_API := $(renderscript_target_api)
+$(RenderScript_file_stamp): PRIVATE_RS_TARGET_API := $(patsubst current,0,$(renderscript_target_api))
 $(RenderScript_file_stamp): PRIVATE_DEP_FILES := $(bc_dep_files)
 $(RenderScript_file_stamp): $(renderscript_sources_fullpath) $(LOCAL_RENDERSCRIPT_CC)
 	$(transform-renderscripts-to-cpp-and-bc)
@@ -1582,10 +1602,15 @@
 # libraries have already been linked into the module at that point.
 # We do, however, care about the NOTICE files for any static
 # libraries that we use. (see notice_files.mk)
-
+#
+# Don't do this in mm, since many of the targets won't exist.
+ifeq ($(ONE_SHOT_MAKEFILE),)
 installed_static_library_notice_file_targets := \
     $(foreach lib,$(my_static_libraries) $(my_whole_static_libraries), \
       NOTICE-$(if $(LOCAL_IS_HOST_MODULE),HOST,TARGET)-STATIC_LIBRARIES-$(lib))
+else
+installed_static_library_notice_file_targets :=
+endif
 
 # Default is -fno-rtti.
 ifeq ($(strip $(LOCAL_RTTI_FLAG)),)
@@ -1715,10 +1740,19 @@
       my_tidy_flags += -quiet -extra-arg-before=-fno-caret-diagnostics
     endif
 
-    # We might be using the static analyzer through clang-tidy.
-    # https://bugs.llvm.org/show_bug.cgi?id=32914
     ifneq ($(my_tidy_checks),)
+      # We might be using the static analyzer through clang-tidy.
+      # https://bugs.llvm.org/show_bug.cgi?id=32914
       my_tidy_flags += -extra-arg-before=-D__clang_analyzer__
+
+      # A recent change in clang-tidy (r328258) enabled destructor inlining,
+      # which appears to cause a number of false positives. Until that's
+      # resolved, this turns off the effects of r328258.
+      # https://bugs.llvm.org/show_bug.cgi?id=37459
+      my_tidy_flags += -extra-arg-before=-Xclang
+      my_tidy_flags += -extra-arg-before=-analyzer-config
+      my_tidy_flags += -extra-arg-before=-Xclang
+      my_tidy_flags += -extra-arg-before=c++-temp-dtor-inlining=false
     endif
   endif
 endif
diff --git a/core/build-system.html b/core/build-system.html
index 3d86e24..3a11a47 100644
--- a/core/build-system.html
+++ b/core/build-system.html
@@ -147,12 +147,6 @@
 .c, .cpp, .h, .java, java libraries, etc., should all work without intervention
 in the Android.mk file.</p>
 
-<h3>Hiding command lines</h3>
-<p>The default of the build system will be to hide the command lines being
-executed for make steps.  It will be possible to override this by specifying
-the showcommands pseudo-target, and possibly by setting an environment
-variable.</p>
-
 <h3>Wildcard source files</h3>
 <p>Wildcarding source file will be discouraged.  It may be useful in some
 scenarios.  The default <code>$(wildcard *)</code> will not work due to the
@@ -326,19 +320,6 @@
 directory inside the current combo directory.  This is especially useful on the
 simulator and emulator, where the persistent data remains present between 
 builds.</li>
-<li><b>showcommands</b> - <code>showcommands</code> is a modifier target
-which causes the build system to show the actual command lines for the build
-steps, instead of the brief descriptions.  Most people don't like seeing the
-actual commands, because they're quite long and hard to read, but if you need
-to for debugging purposes, you can add <code>showcommands</code> to the list
-of targets you build.  For example <code>make showcommands</code> will build
-the default android configuration, and <code>make runtime showcommands</code>
-will build just the runtime, and targets that it depends on, while displaying
-the full command lines.  Please note that there are a couple places where the
-commands aren't shown here.  These are considered bugs, and should be fixed,
-but they're often hard to track down.  Please let
-<a href="mailto:android-build-team">android-build-team</a> know if you find
-any.</li>
 <li><b>LOCAL_MODULE</b> - Anything you specify as a <code>LOCAL_MODULE</code>
 in an Android.mk is made into a pseudotarget.  For example, <code>make
 runtime</code> might be shorthand for <code>make
diff --git a/core/build_id.mk b/core/build_id.mk
index 932e214..bac2f48 100644
--- a/core/build_id.mk
+++ b/core/build_id.mk
@@ -18,4 +18,4 @@
 # (like "CRB01").  It must be a single word, and is
 # capitalized by convention.
 
-export BUILD_ID=PI
+BUILD_ID=PI
diff --git a/core/ccache.mk b/core/ccache.mk
index d67bce6..d10aceb 100644
--- a/core/ccache.mk
+++ b/core/ccache.mk
@@ -14,39 +14,48 @@
 # limitations under the License.
 #
 
+# We no longer provide a ccache prebuilt.
+#
+# Ours was old, and had a number of issues that triggered non-reproducible
+# results and other failures. Newer ccache versions may fix some of those
+# issues, but at the large scale of our build servers, we weren't seeing
+# significant performance gains from using ccache -- you end up needing very
+# good locality and/or very large caches if you're building many different
+# configurations.
+#
+# Local no-change full rebuilds were showing better results, but why not just
+# use incremental builds at that point?
+#
+# So if you still want to use ccache, continue setting USE_CCACHE, but also set
+# the CCACHE_EXEC environment variable to the path to your ccache executable.
+ifneq ($(CCACHE_EXEC),)
 ifneq ($(filter-out false,$(USE_CCACHE)),)
   # The default check uses size and modification time, causing false misses
   # since the mtime depends when the repo was checked out
-  export CCACHE_COMPILERCHECK ?= content
+  CCACHE_COMPILERCHECK ?= content
 
   # See man page, optimizations to get more cache hits
   # implies that __DATE__ and __TIME__ are not critical for functionality.
   # Ignore include file modification time since it will depend on when
   # the repo was checked out
-  export CCACHE_SLOPPINESS := time_macros,include_file_mtime,file_macro
+  CCACHE_SLOPPINESS := time_macros,include_file_mtime,file_macro
 
   # Turn all preprocessor absolute paths into relative paths.
   # Fixes absolute paths in preprocessed source due to use of -g.
   # We don't really use system headers much so the rootdir is
   # fine; ensures these paths are relative for all Android trees
   # on a workstation.
-  export CCACHE_BASEDIR := /
+  CCACHE_BASEDIR := /
 
   # Workaround for ccache with clang.
   # See http://petereisentraut.blogspot.com/2011/09/ccache-and-clang-part-2.html
-  export CCACHE_CPP2 := true
+  CCACHE_CPP2 := true
 
-  CCACHE_HOST_TAG := $(HOST_PREBUILT_TAG)
-  ccache := prebuilts/misc/$(CCACHE_HOST_TAG)/ccache/ccache
-  # Check that the executable is here.
-  ccache := $(strip $(wildcard $(ccache)))
-  ifdef ccache
-    ifndef CC_WRAPPER
-      CC_WRAPPER := $(ccache)
-    endif
-    ifndef CXX_WRAPPER
-      CXX_WRAPPER := $(ccache)
-    endif
-    ccache =
+  ifndef CC_WRAPPER
+    CC_WRAPPER := $(CCACHE_EXEC)
   endif
+  ifndef CXX_WRAPPER
+    CXX_WRAPPER := $(CCACHE_EXEC)
+  endif
+endif
 endif
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index bd86cfb..04439d1 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -63,6 +63,7 @@
 LOCAL_DONT_CHECK_MODULE:=
 # Don't delete the META_INF dir when merging static Java libraries.
 LOCAL_DONT_DELETE_JAR_META_INF:=
+LOCAL_DONT_MERGE_MANIFESTS:=
 LOCAL_DPI_FILE_STEM:=
 LOCAL_DPI_VARIANTS:=
 LOCAL_DROIDDOC_ASSET_DIR:=
@@ -74,11 +75,6 @@
 LOCAL_DROIDDOC_STUB_OUT_DIR:=
 LOCAL_DROIDDOC_TEMPLATE_DIR:=
 LOCAL_DROIDDOC_USE_STANDARD_DOCLET:=
-LOCAL_DROIDDOC_USE_METALAVA:=
-LOCAL_DROIDDOC_METALAVA_PREVIOUS_API:=
-LOCAL_DROIDDOC_METALAVA_ANNOTATIONS_ENABLED:=
-LOCAL_DROIDDOC_METALAVA_MERGE_ANNOTATIONS_DIR:=
-LOCAL_DROIDDOC_METALAVA_DOCS_STUB_OUT_DIR:=
 LOCAL_DX_FLAGS:=
 LOCAL_EMMA_COVERAGE_FILTER:=
 LOCAL_EMMA_INSTRUMENT:=
@@ -90,6 +86,7 @@
 LOCAL_EXPORT_HEADER_LIBRARY_HEADERS:=
 LOCAL_EXPORT_PACKAGE_RESOURCES:=
 LOCAL_EXPORT_PROGUARD_FLAG_FILES:=
+LOCAL_EXPORT_SDK_LIBRARIES:=
 LOCAL_EXPORT_SHARED_LIBRARY_HEADERS:=
 LOCAL_EXPORT_STATIC_LIBRARY_HEADERS:=
 LOCAL_EXTRACT_APK:=
@@ -174,6 +171,7 @@
 LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH:=
 LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN:=
 LOCAL_MULTILIB:=
+LOCAL_NATIVE_BENCHMARK:=
 LOCAL_NDK_STL_VARIANT:=
 LOCAL_NDK_VERSION:=current
 LOCAL_NO_CRT:=
@@ -208,6 +206,7 @@
 LOCAL_PREBUILT_OBJ_FILES:=
 LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES:=
 LOCAL_PREBUILT_STRIP_COMMENTS:=
+LOCAL_PRESUBMIT_DISABLED:=
 LOCAL_PRIVATE_PLATFORM_APIS:=
 LOCAL_PRIVILEGED_MODULE:=
 # '',full,custom,disabled,obfuscation,optimization
@@ -241,6 +240,7 @@
 LOCAL_SANITIZE_DIAG:=
 LOCAL_SANITIZE_RECOVER:=
 LOCAL_SANITIZE_BLACKLIST :=
+LOCAL_SDK_LIBRARIES :=
 LOCAL_SDK_RES_VERSION:=
 LOCAL_SDK_VERSION:=
 LOCAL_SHARED_ANDROID_LIBRARIES:=
@@ -254,7 +254,7 @@
 LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=
 LOCAL_SOONG_RRO_DIRS :=
 LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=
-LOCAL_DROIDDOC_STUBS_JAR :=
+LOCAL_DROIDDOC_STUBS_SRCJAR :=
 LOCAL_DROIDDOC_DOC_ZIP :=
 # '',true
 LOCAL_SOURCE_FILES_ALL_GENERATED:=
@@ -277,9 +277,12 @@
 LOCAL_UNINSTALLABLE_MODULE:=
 LOCAL_UNSTRIPPED_PATH:=
 LOCAL_USE_AAPT2:=$(USE_AAPT2)
+LOCAL_USE_CLANG_LLD:=
+LOCAL_USE_R8:=
 LOCAL_USE_VNDK:=
 LOCAL_USES_LIBRARIES:=
 LOCAL_VENDOR_MODULE:=
+LOCAL_VINTF_FRAGMENTS:=
 LOCAL_VTSC_FLAGS:=
 LOCAL_VTS_INCLUDES:=
 LOCAL_VTS_MODE:=
@@ -472,6 +475,8 @@
 LOCAL_CUSTOM_BUILD_STEP_OUTPUT:=
 LOCAL_IS_AUX_MODULE :=
 
+full_android_manifest :=
+
 # Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to
 # iterate over thousands of entries every time.
 # Leave the current makefile to make sure we don't break anything
diff --git a/core/config.mk b/core/config.mk
index d218408..7e5ba31 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -45,6 +45,9 @@
 backslash := \a
 backslash := $(patsubst %a,%,$(backslash))
 
+# Prevent accidentally changing these variables
+.KATI_READONLY := SHELL empty space comma newline pound backslash
+
 # this turns off the suffix rules built into make
 .SUFFIXES:
 
@@ -58,6 +61,10 @@
 # If a rule fails, delete $@.
 .DELETE_ON_ERROR:
 
+# Mark variables that should be coming as environment variables from soong_ui
+# as readonly
+.KATI_READONLY := OUT_DIR TMPDIR BUILD_DATETIME_FILE
+
 # Mark variables deprecated/obsolete
 CHANGES_URL := https://android.googlesource.com/platform/build/+/master/Changes.md
 $(KATI_obsolete_var PATH,Do not use PATH directly. See $(CHANGES_URL)#PATH)
@@ -78,6 +85,9 @@
 $(KATI_obsolete_var PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE,Set FCM Version in device manifest instead. See $(CHANGES_URL)#PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE)
 $(KATI_obsolete_var USE_CLANG_PLATFORM_BUILD,Clang is the only supported Android compiler. See $(CHANGES_URL)#USE_CLANG_PLATFORM_BUILD)
 
+# This is marked as obsolete in envsetup.mk after reading the BoardConfig.mk
+$(KATI_deprecate_export It is a global setting. See $(CHANGES_URL)#export_keyword)
+
 CHANGES_URL :=
 
 # Used to force goals to build.  Only use for conditionally defined goals.
@@ -92,13 +102,15 @@
 UNAME := $(shell uname -sm)
 
 SRC_TARGET_DIR := $(TOPDIR)build/target
-SRC_API_DIR := $(TOPDIR)prebuilts/sdk/api
-SRC_SYSTEM_API_DIR := $(TOPDIR)prebuilts/sdk/system-api
-SRC_TEST_API_DIR := $(TOPDIR)prebuilts/sdk/test-api
 
 # Some specific paths to tools
 SRC_DROIDDOC_DIR := $(TOPDIR)build/make/tools/droiddoc
 
+# Mark some inputs as readonly
+ifdef TARGET_DEVICE_DIR
+  .KATI_READONLY := TARGET_DEVICE_DIR
+endif
+
 # Set up efficient math functions which are used in make.
 # Here since this file is included by envsetup as well as during build.
 include $(BUILD_SYSTEM)/math.mk
@@ -156,6 +168,7 @@
 BUILD_TARGET_TEST_CONFIG := $(BUILD_SYSTEM)/target_test_config.mk
 
 INSTRUMENTATION_TEST_CONFIG_TEMPLATE := $(BUILD_SYSTEM)/instrumentation_test_config_template.xml
+NATIVE_BENCHMARK_TEST_CONFIG_TEMPLATE := $(BUILD_SYSTEM)/native_benchmark_test_config_template.xml
 NATIVE_TEST_CONFIG_TEMPLATE := $(BUILD_SYSTEM)/native_test_config_template.xml
 EMPTY_TEST_CONFIG := $(BUILD_SYSTEM)/empty_test_config.xml
 
@@ -202,6 +215,14 @@
 endif
 
 # ###############################################################
+# Broken build defaults
+# ###############################################################
+BUILD_BROKEN_ANDROIDMK_EXPORTS :=
+BUILD_BROKEN_DUP_COPY_HEADERS :=
+BUILD_BROKEN_DUP_RULES :=
+BUILD_BROKEN_PHONY_TARGETS :=
+
+# ###############################################################
 # Include sub-configuration files
 # ###############################################################
 
@@ -301,8 +322,8 @@
 
 # Commands to generate .toc file from Darwin dynamic library.
 define _gen_toc_command_for_macho
-$(hide) otool -l $(1) | grep LC_ID_DYLIB -A 5 > $(2)
-$(hide) nm -gP $(1) | cut -f1-2 -d" " | (grep -v U$$ >> $(2) || true)
+$(hide) $(HOST_OTOOL) -l $(1) | grep LC_ID_DYLIB -A 5 > $(2)
+$(hide) $(HOST_NM) -gP $(1) | cut -f1-2 -d" " | (grep -v U$$ >> $(2) || true)
 endef
 
 combo_target := HOST_
@@ -346,10 +367,6 @@
 ifeq ($(CALLED_FROM_SETUP),true)
 include $(BUILD_SYSTEM)/ccache.mk
 include $(BUILD_SYSTEM)/goma.mk
-
-export CC_WRAPPER
-export CXX_WRAPPER
-export JAVAC_WRAPPER
 endif
 
 ifdef TARGET_PREFER_32_BIT
@@ -357,10 +374,18 @@
 TARGET_PREFER_32_BIT_EXECUTABLES := true
 endif
 
-ifeq (,$(TARGET_SUPPORTS_32_BIT_APPS)$(TARGET_SUPPORTS_64_BIT_APPS))
+ifeq (,$(filter true,$(TARGET_SUPPORTS_32_BIT_APPS) $(TARGET_SUPPORTS_64_BIT_APPS)))
   TARGET_SUPPORTS_32_BIT_APPS := true
 endif
 
+# Sanity check to warn about likely cryptic errors later in the build.
+ifeq ($(TARGET_IS_64_BIT),true)
+  ifeq (,$(filter true false,$(TARGET_SUPPORTS_64_BIT_APPS)))
+    $(warning Building a 32-bit-app-only product on a 64-bit device. \
+      If this is intentional, set TARGET_SUPPORTS_64_BIT_APPS := false)
+  endif
+endif
+
 # "ro.product.cpu.abilist32" and "ro.product.cpu.abilist64" are
 # comma separated lists of the 32 and 64 bit ABIs (in order of
 # preference) that the target supports. If TARGET_CPU_ABI_LIST_{32,64}_BIT
@@ -549,8 +574,9 @@
 prebuilt_build_tools := prebuilts/build-tools
 prebuilt_build_tools_wrappers := prebuilts/build-tools/common/bin
 prebuilt_build_tools_jars := prebuilts/build-tools/common/framework
+prebuilt_build_tools_bin_noasan := $(prebuilt_build_tools)/$(HOST_PREBUILT_TAG)/bin
 ifeq ($(filter address,$(SANITIZE_HOST)),)
-prebuilt_build_tools_bin := $(prebuilt_build_tools)/$(HOST_PREBUILT_TAG)/bin
+prebuilt_build_tools_bin := $(prebuilt_build_tools_bin_noasan)
 else
 prebuilt_build_tools_bin := $(prebuilt_build_tools)/$(HOST_PREBUILT_TAG)/asan/bin
 endif
@@ -559,14 +585,14 @@
 
 # Work around for b/68406220
 # This should match the soong version.
-ifndef USE_D8
-  USE_D8 := true
-endif
+USE_D8 := true
+.KATI_READONLY := USE_D8
 
 # Default R8 behavior when USE_R8 is not specified.
 ifndef USE_R8
-  USE_R8 := false
+  USE_R8 := true
 endif
+.KATI_READONLY := USE_R8
 
 #
 # Tools that are prebuilts for TARGET_BUILD_APPS
@@ -575,7 +601,6 @@
   AIDL := $(HOST_OUT_EXECUTABLES)/aidl
   AAPT := $(HOST_OUT_EXECUTABLES)/aapt
   AAPT2 := $(HOST_OUT_EXECUTABLES)/aapt2
-  DESUGAR := $(HOST_OUT_JAVA_LIBRARIES)/desugar.jar
   MAINDEXCLASSES := $(HOST_OUT_EXECUTABLES)/mainDexClasses
   SIGNAPK_JAR := $(HOST_OUT_JAVA_LIBRARIES)/signapk$(COMMON_JAVA_PACKAGE_SUFFIX)
   SIGNAPK_JNI_LIBRARY_PATH := $(HOST_OUT_SHARED_LIBRARIES)
@@ -585,7 +610,6 @@
   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
@@ -608,24 +632,26 @@
 CKATI := $(prebuilt_build_tools_bin)/ckati
 DEPMOD := $(HOST_OUT_EXECUTABLES)/depmod
 FILESLIST := $(SOONG_HOST_OUT_EXECUTABLES)/fileslist
+HOST_INIT_VERIFIER := $(HOST_OUT_EXECUTABLES)/host_init_verifier
 MAKEPARALLEL := $(prebuilt_build_tools_bin)/makeparallel
 SOONG_JAVAC_WRAPPER := $(SOONG_HOST_OUT_EXECUTABLES)/soong_javac_wrapper
 SOONG_ZIP := $(SOONG_HOST_OUT_EXECUTABLES)/soong_zip
 MERGE_ZIPS := $(SOONG_HOST_OUT_EXECUTABLES)/merge_zips
 XMLLINT := $(SOONG_HOST_OUT_EXECUTABLES)/xmllint
+XZ := $(prebuilt_build_tools)/$(HOST_PREBUILT_TAG)/bin/xz
 ZIP2ZIP := $(SOONG_HOST_OUT_EXECUTABLES)/zip2zip
 ZIPTIME := $(prebuilt_build_tools_bin)/ziptime
 
 # ---------------------------------------------------------------
 # Generic tools.
 
-LEX := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/flex/flex-2.5.39
+LEX := $(prebuilt_build_tools_bin_noasan)/flex
 # The default PKGDATADIR built in the prebuilt bison is a relative path
 # prebuilts/build-tools/common/bison.
 # To run bison from elsewhere you need to set up enviromental variable
 # BISON_PKGDATADIR.
 BISON_PKGDATADIR := $(PWD)/prebuilts/build-tools/common/bison
-BISON := prebuilts/build-tools/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/bin/bison
+BISON := $(prebuilt_build_tools_bin_noasan)/bison
 YACC := $(BISON) -d
 BISON_DATA := $(wildcard $(BISON_PKGDATADIR)/* $(BISON_PKGDATADIR)/*/*)
 
@@ -688,6 +714,7 @@
 BUILD_IMAGE_SRCS := $(wildcard build/make/tools/releasetools/*.py)
 APPEND2SIMG := $(HOST_OUT_EXECUTABLES)/append2simg
 VERITY_SIGNER := $(HOST_OUT_EXECUTABLES)/verity_signer
+BUILD_VERITY_METADATA := $(HOST_OUT_EXECUTABLES)/build_verity_metadata.py
 BUILD_VERITY_TREE := $(HOST_OUT_EXECUTABLES)/build_verity_tree
 BOOT_SIGNER := $(HOST_OUT_EXECUTABLES)/boot_signer
 FUTILITY := $(HOST_OUT_EXECUTABLES)/futility-host
@@ -699,41 +726,20 @@
 PROFMAN := $(HOST_OUT_EXECUTABLES)/profman
 HIDDENAPI := $(HOST_OUT_EXECUTABLES)/hiddenapi
 
-# relocation packer
-RELOCATION_PACKER := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/relocation_packer/relocation_packer
-
 FINDBUGS_DIR := external/owasp/sanitizer/tools/findbugs/bin
 FINDBUGS := $(FINDBUGS_DIR)/findbugs
 
 JETIFIER := prebuilts/sdk/tools/jetifier/jetifier-standalone/bin/jetifier-standalone
 
-# Tool to merge AndroidManifest.xmls
-ANDROID_MANIFEST_MERGER_CLASSPATH := \
-    prebuilts/gradle-plugin/com/android/tools/build/manifest-merger/26.0.0-beta2/manifest-merger-26.0.0-beta2.jar \
-    prebuilts/gradle-plugin/com/android/tools/sdk-common/26.0.0-beta2/sdk-common-26.0.0-beta2.jar \
-    prebuilts/gradle-plugin/com/android/tools/common/26.0.0-beta2/common-26.0.0-beta2.jar \
-    prebuilts/misc/common/guava/guava-21.0.jar
-ANDROID_MANIFEST_MERGER := $(JAVA) \
-    -classpath $(subst $(space),:,$(strip $(ANDROID_MANIFEST_MERGER_CLASSPATH))) \
-    com.android.manifmerger.Merger
-
 COLUMN:= column
 
-ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
-ifeq ($(RUN_ERROR_PRONE),true)
-USE_OPENJDK9 :=
-else
 USE_OPENJDK9 := true
-endif
-TARGET_OPENJDK9 :=
-else ifeq ($(EXPERIMENTAL_USE_OPENJDK9),false)
-USE_OPENJDK9 :=
+
+ifeq ($(EXPERIMENTAL_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
 
@@ -748,8 +754,7 @@
 endif
 
 APICHECK_CLASSPATH_ENTRIES := \
-    $(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX) \
-    $(HOST_OUT_JAVA_LIBRARIES)/jsilver$(COMMON_JAVA_PACKAGE_SUFFIX) \
+    $(HOST_OUT_JAVA_LIBRARIES)/apicheck$(COMMON_JAVA_PACKAGE_SUFFIX) \
     $(HOST_JDK_TOOLS_JAR) \
     )
 APICHECK_CLASSPATH := $(subst $(space),:,$(strip $(APICHECK_CLASSPATH_ENTRIES)))
@@ -926,6 +931,30 @@
     PLATFORM_SEPOLICY_VERSION \
     TOT_SEPOLICY_VERSION \
 
+ifndef USE_LOGICAL_PARTITIONS
+  USE_LOGICAL_PARTITIONS := $(PRODUCT_USE_LOGICAL_PARTITIONS)
+endif
+.KATI_READONLY := USE_LOGICAL_PARTITIONS
+
+ifeq ($(USE_LOGICAL_PARTITIONS),true)
+  BOARD_KERNEL_CMDLINE += androidboot.logical_partitions=1
+
+ifneq ($(BOARD_SYSTEMIMAGE_PARTITION_SIZE),)
+ifneq ($(BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE),)
+$(error Should not define BOARD_SYSTEMIMAGE_PARTITION_SIZE and \
+    BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE together)
+endif
+endif
+
+ifneq ($(BOARD_VENDORIMAGE_PARTITION_SIZE),)
+ifneq ($(BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE),)
+$(error Should not define BOARD_VENDORIMAGE_PARTITION_SIZE and \
+    BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE together)
+endif
+endif
+
+endif # USE_LOGICAL_PARTITIONS
+
 # ###############################################################
 # Set up final options.
 # ###############################################################
@@ -977,6 +1006,29 @@
 SUPPORT_LIBRARY_ROOT := frameworks/support
 endif
 
+get-sdk-version = $(if $(findstring _,$(1)),$(subst core_,,$(subst system_,,$(subst test_,,$(1)))),$(1))
+get-sdk-api = $(if $(findstring _,$(1)),$(patsubst %_$(call get-sdk-version,$(1)),%,$(1)),public)
+get-prebuilt-sdk-dir = $(HISTORICAL_SDK_VERSIONS_ROOT)/$(call get-sdk-version,$(1))/$(call get-sdk-api,$(1))
+
+# Resolve LOCAL_SDK_VERSION to prebuilt module name, e.g.:
+# 23 -> sdk_public_23_android
+# system_current -> sdk_system_current_android
+# $(1): An sdk version (LOCAL_SDK_VERSION)
+# $(2): optional library name (default: android)
+define resolve-prebuilt-sdk-module
+$(if $(findstring _,$(1)),\
+  sdk_$(1)_$(or $(2),android),\
+  sdk_public_$(1)_$(or $(2),android))
+endef
+
+# Resolve LOCAL_SDK_VERSION to prebuilt android.jar
+# $(1): LOCAL_SDK_VERSION
+resolve-prebuilt-sdk-jar-path = $(call get-prebuilt-sdk-dir,$(1))/android.jar
+
+# Resolve LOCAL_SDK_VERSION to prebuilt framework.aidl
+# $(1): An sdk version (LOCAL_SDK_VERSION)
+resolve-prebuilt-sdk-aidl-path = $(call get-prebuilt-sdk-dir,$(call get-sdk-version,$(1)))/framework.aidl
+
 # Historical SDK version N is stored in $(HISTORICAL_SDK_VERSIONS_ROOT)/N.
 # The 'current' version is whatever this source tree is.
 #
@@ -993,36 +1045,35 @@
     ( sgrax $(1) | sort -g ) )
 endef
 
-TARGET_AVAILABLE_SDK_VERSIONS := $(call numerically_sort,\
-    $(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 and core_current SDK yet.
-TARGET_AVAILABLE_SDK_VERSIONS := test_current core_current $(TARGET_AVAILABLE_SDK_VERSIONS)
+# This produces a list like "current/core current/public current/system 4/public"
+TARGET_AVAILABLE_SDK_VERSIONS := $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/*/android.jar)
+TARGET_AVAILABLE_SDK_VERSIONS := $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/android.jar,%,$(TARGET_AVAILABLE_SDK_VERSIONS))
+# Strips and reorganizes the "public", "core" and "system" subdirs.
+TARGET_AVAILABLE_SDK_VERSIONS := $(subst /public,,$(TARGET_AVAILABLE_SDK_VERSIONS))
+TARGET_AVAILABLE_SDK_VERSIONS := $(patsubst %/core,core_%,$(TARGET_AVAILABLE_SDK_VERSIONS))
+TARGET_AVAILABLE_SDK_VERSIONS := $(patsubst %/system,system_%,$(TARGET_AVAILABLE_SDK_VERSIONS))
+# No prebuilt for test_current.
+TARGET_AVAILABLE_SDK_VERSIONS += test_current
+TARGET_AVAIALBLE_SDK_VERSIONS := $(call numerically_sort,$(TARGET_AVAILABLE_SDK_VERSIONS))
 
 TARGET_SDK_VERSIONS_WITHOUT_JAVA_18_SUPPORT := $(call numbers_less_than,24,$(TARGET_AVAILABLE_SDK_VERSIONS))
 TARGET_SDK_VERSIONS_WITHOUT_JAVA_19_SUPPORT := $(call numbers_less_than,27,$(TARGET_AVAILABLE_SDK_VERSIONS))
 
-INTERNAL_PLATFORM_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/public_api.txt
-INTERNAL_PLATFORM_DEX_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/public-dex.txt
+ifndef INTERNAL_PLATFORM_PRIVATE_API_FILE
 INTERNAL_PLATFORM_PRIVATE_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/private.txt
+endif
+ifndef INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE
 INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/private-dex.txt
-INTERNAL_PLATFORM_REMOVED_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/removed.txt
-INTERNAL_PLATFORM_REMOVED_DEX_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/removed-dex.txt
-INTERNAL_PLATFORM_SYSTEM_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/system-api.txt
+endif
+ifndef INTERNAL_PLATFORM_SYSTEM_PRIVATE_API_FILE
 INTERNAL_PLATFORM_SYSTEM_PRIVATE_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/system-private.txt
+endif
+ifndef INTERNAL_PLATFORM_SYSTEM_PRIVATE_DEX_API_FILE
 INTERNAL_PLATFORM_SYSTEM_PRIVATE_DEX_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/system-private-dex.txt
-INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/system-removed.txt
-INTERNAL_PLATFORM_SYSTEM_EXACT_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/system-exact.txt
-INTERNAL_PLATFORM_TEST_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/test-api.txt
-INTERNAL_PLATFORM_TEST_REMOVED_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/test-removed.txt
-INTERNAL_PLATFORM_TEST_EXACT_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/test-exact.txt
+endif
 
+INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-public-list.txt
+INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-private-list.txt
 INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-light-greylist.txt
 INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-dark-greylist.txt
 INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-blacklist.txt
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index d570ccd..083da9f 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -12,10 +12,12 @@
 my_global_sanitize_diag :=
 ifeq ($(my_clang),true)
   ifdef LOCAL_IS_HOST_MODULE
-    my_global_sanitize := $(strip $(SANITIZE_HOST))
+    ifneq ($($(my_prefix)OS),windows)
+      my_global_sanitize := $(strip $(SANITIZE_HOST))
 
-    # SANITIZE_HOST=true is a deprecated way to say SANITIZE_HOST=address.
-    my_global_sanitize := $(subst true,address,$(my_global_sanitize))
+      # SANITIZE_HOST=true is a deprecated way to say SANITIZE_HOST=address.
+      my_global_sanitize := $(subst true,address,$(my_global_sanitize))
+    endif
   else
     my_global_sanitize := $(strip $(SANITIZE_TARGET))
     my_global_sanitize_diag := $(strip $(SANITIZE_TARGET_DIAG))
@@ -34,6 +36,16 @@
   endif
 endif
 
+# Global integer sanitization doesn't support static modules.
+ifeq ($(filter SHARED_LIBRARIES EXECUTABLES,$(LOCAL_MODULE_CLASS)),)
+  my_global_sanitize := $(filter-out integer_overflow,$(my_global_sanitize))
+  my_global_sanitize_diag := $(filter-out integer_overflow,$(my_global_sanitize_diag))
+endif
+ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+  my_global_sanitize := $(filter-out integer_overflow,$(my_global_sanitize))
+  my_global_sanitize_diag := $(filter-out integer_overflow,$(my_global_sanitize_diag))
+endif
+
 # Disable global CFI in excluded paths
 ifneq ($(filter cfi, $(my_global_sanitize)),)
   combined_exclude_paths := $(CFI_EXCLUDE_PATHS) \
@@ -134,10 +146,12 @@
   my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
 endif
 
-# Disable CFI for host targets
+# Disable sanitizers which need the UBSan runtime for host targets.
 ifdef LOCAL_IS_HOST_MODULE
   my_sanitize := $(filter-out cfi,$(my_sanitize))
   my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
+  my_sanitize := $(filter-out signed-integer-overflow unsigned-integer-overflow integer_overflow,$(my_sanitize))
+  my_sanitize_diag := $(filter-out signed-integer-overflow unsigned-integer-overflow integer_overflow,$(my_sanitize_diag))
 endif
 
 # Support for local sanitize blacklist paths.
@@ -180,6 +194,15 @@
   endif
 endif
 
+# Disable Scudo if ASan or TSan is enabled.
+ifneq ($(filter address thread,$(my_sanitize)),)
+  my_sanitize := $(filter-out scudo,$(my_sanitize))
+endif
+
+ifneq ($(filter scudo,$(my_sanitize)),)
+  my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)SCUDO_RUNTIME_LIBRARY)
+endif
+
 # Undefined symbols can occur if a non-sanitized library links
 # sanitized static libraries. That's OK, because the executable
 # always depends on the ASan runtime library, which defines these
@@ -214,23 +237,26 @@
 endif
 
 ifneq ($(filter integer_overflow,$(my_sanitize)),)
-  ifneq ($(filter SHARED_LIBRARIES EXECUTABLES,$(LOCAL_MODULE_CLASS)),)
-    ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+  # Respect LOCAL_NOSANITIZE for integer-overflow flags.
+  ifeq ($(filter signed-integer-overflow, $(strip $(LOCAL_NOSANITIZE))),)
+    my_sanitize += signed-integer-overflow
+  endif
+  ifeq ($(filter unsigned-integer-overflow, $(strip $(LOCAL_NOSANITIZE))),)
+    my_sanitize += unsigned-integer-overflow
+  endif
+  my_cflags += $(INTEGER_OVERFLOW_EXTRA_CFLAGS)
 
-      # Respect LOCAL_NOSANITIZE for integer-overflow flags.
-      ifeq ($(filter signed-integer-overflow, $(strip $(LOCAL_NOSANITIZE))),)
-        my_sanitize += signed-integer-overflow
-      endif
-      ifeq ($(filter unsigned-integer-overflow, $(strip $(LOCAL_NOSANITIZE))),)
-        my_sanitize += unsigned-integer-overflow
-      endif
-      my_cflags += $(INTEGER_OVERFLOW_EXTRA_CFLAGS)
-
-      # Check for diagnostics mode (on by default).
-      ifneq ($(filter integer_overflow,$(my_sanitize_diag)),)
+  # Check for diagnostics mode.
+  ifneq ($(filter integer_overflow,$(my_sanitize_diag)),)
+    ifneq ($(filter SHARED_LIBRARIES EXECUTABLES,$(LOCAL_MODULE_CLASS)),)
+      ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
         my_sanitize_diag += signed-integer-overflow
         my_sanitize_diag += unsigned-integer-overflow
+      else
+        $(call pretty-error,Make cannot apply integer overflow diagnostics to static binary.)
       endif
+    else
+      $(call pretty-error,Make cannot apply integer overflow diagnostics to static library.)
     endif
   endif
   my_sanitize := $(filter-out integer_overflow,$(my_sanitize))
@@ -361,7 +387,7 @@
     notrap_arg := $(subst $(space),$(comma),$(my_sanitize_diag)),
     my_cflags += -fno-sanitize-trap=$(notrap_arg)
     # Diagnostic requires a runtime library, unless ASan or TSan are also enabled.
-    ifeq ($(filter address thread,$(my_sanitize)),)
+    ifeq ($(filter address thread scudo,$(my_sanitize)),)
       # Does not have to be the first DT_NEEDED unlike ASan.
       my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_RUNTIME_LIBRARY)
     endif
diff --git a/core/configure_module_stem.mk b/core/configure_module_stem.mk
index 48b7787..30df8ea 100644
--- a/core/configure_module_stem.mk
+++ b/core/configure_module_stem.mk
@@ -1,20 +1,26 @@
 my_multilib_stem := $(LOCAL_MODULE_STEM_$(if $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)IS_64_BIT),64,32))
 ifdef my_multilib_stem
   my_module_stem := $(my_multilib_stem)
+  $(call verify-module-stem,my_multilib_stem)
 else ifdef LOCAL_MODULE_STEM
   my_module_stem := $(LOCAL_MODULE_STEM)
+  $(call verify-module-stem,LOCAL_MODULE_STEM)
 else
   my_module_stem := $(LOCAL_MODULE)
 endif
 
 ifdef LOCAL_BUILT_MODULE_STEM
   my_built_module_stem := $(LOCAL_BUILT_MODULE_STEM)
+  $(call verify-module-stem,LOCAL_BUILT_MODULE_STEM)
 else
   my_built_module_stem := $(my_module_stem)$(LOCAL_MODULE_SUFFIX)
+  $(call verify-module-stem,LOCAL_MODULE_SUFFIX)
 endif
 
 ifdef LOCAL_INSTALLED_MODULE_STEM
   my_installed_module_stem := $(LOCAL_INSTALLED_MODULE_STEM)
+  $(call verify-module-stem,LOCAL_INSTALLED_MODULE_STEM)
 else
   my_installed_module_stem := $(my_module_stem)$(LOCAL_MODULE_SUFFIX)
+  $(call verify-module-stem,LOCAL_MODULE_SUFFIX)
 endif
diff --git a/core/definitions.mk b/core/definitions.mk
index 599ab49..ec71da0 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -99,6 +99,15 @@
 # All installed initrc files
 ALL_INIT_RC_INSTALLED_PAIRS :=
 
+# All installed vintf manifest fragments for a partition at
+ALL_VINTF_MANIFEST_FRAGMENTS_LIST:=
+
+# All tests that should be skipped in presubmit check.
+ALL_DISABLED_PRESUBMIT_TESTS :=
+
+# CLANG_TIDY_UNKNOWN_CFLAGS is generated by build/soong.
+sanitize_tidy_cflags = $(filter-out $(CLANG_TIDY_UNKNOWN_CFLAGS),$1)
+
 ###########################################################
 ## Debugging; prints a variable list to stdout
 ###########################################################
@@ -471,8 +480,8 @@
 ###########################################################
 ## Find test data in a form required by LOCAL_TEST_DATA
 ## $(1): the base dir, relative to the root of the source tree.
-## $(3): the file name pattern to be passed to find as "-name"
-## $(2): a list of subdirs of the base dir
+## $(2): the file name pattern to be passed to find as "-name"
+## $(3): a list of subdirs of the base dir
 ###########################################################
 
 define find-test-data-in-subdirs
@@ -651,7 +660,8 @@
 ###########################################################
 
 define module-stubs-files
-$(foreach module,$(1),$(ALL_MODULES.$(module).STUBS))
+$(foreach module,$(1),$(if $(filter $(module),$(JAVA_SDK_LIBRARIES)),\
+$(call java-lib-files,$(module).stubs),$(ALL_MODULES.$(module).STUBS)))
 endef
 
 ###########################################################
@@ -725,6 +735,25 @@
 endef
 endif
 
+# Get the exported-sdk-libs files which collectively give you the list of exported java sdk
+# lib names that are (transitively) exported from the given set of java libs
+# $(1): library name list
+define exported-sdk-libs-files
+$(foreach lib,$(1),$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/exported-sdk-libs)
+endef
+
+# Fix manifest
+# $(1): input manifest path
+# $(2): output manifest path
+# $(3): min sdk version
+# $(4): (optional) exported-sdk-libs file
+define fix-manifest
+$(MANIFEST_FIXER) \
+--minSdkVersion $(3) \
+$(if $(4),$$(cat $(4) | sort -u | sed -e 's/^/\ --uses-library\ /' | tr '\n' ' ')) \
+$(1) $(2)
+endef
+
 ###########################################################
 ## Returns true if $(1) and $(2) are equal.  Returns
 ## the empty string if they are not equal.
@@ -1095,7 +1124,7 @@
 @mkdir -p $(dir $@)
 @mkdir -p $(PRIVATE_HEADER_OUTPUT_DIR)
 @echo "Generating C++ from AIDL: $(PRIVATE_MODULE) <= $<"
-$(hide) $(AIDL_CPP) -d$(basename $@).aidl.d -ninja $(PRIVATE_AIDL_FLAGS) \
+$(hide) $(AIDL_CPP) -d$(basename $@).aidl.d --ninja $(PRIVATE_AIDL_FLAGS) \
     $< $(PRIVATE_HEADER_OUTPUT_DIR) $@
 endef
 
@@ -1239,7 +1268,7 @@
 define clang-tidy-cpp
 $(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
   -checks=$(PRIVATE_TIDY_CHECKS) \
-  $< -- $(transform-cpp-to-o-compiler-args)
+  $< -- $(call sanitize_tidy_cflags,$(transform-cpp-to-o-compiler-args))
 endef
 
 ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
@@ -1287,7 +1316,7 @@
 define clang-tidy-c
 $(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
   -checks=$(PRIVATE_TIDY_CHECKS) \
-  $< -- $(transform-c-to-o-compiler-args)
+  $< -- $(call sanitize_tidy_cflags,$(transform-c-to-o-compiler-args))
 endef
 
 ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
@@ -1357,7 +1386,7 @@
 define clang-tidy-host-cpp
 $(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
   -checks=$(PRIVATE_TIDY_CHECKS) \
-  $< -- $(transform-host-cpp-to-o-compiler-args)
+  $< -- $(call sanitize_tidy_cflags,$(transform-host-cpp-to-o-compiler-args))
 endef
 
 ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
@@ -1409,7 +1438,7 @@
 define clang-tidy-host-c
 $(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
   -checks=$(PRIVATE_TIDY_CHECKS) \
-  $< -- $(transform-host-c-to-o-compiler-args)
+  $< -- $(call sanitize_tidy_cflags,$(transform-host-c-to-o-compiler-args))
 endef
 
 ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
@@ -1829,14 +1858,15 @@
 ###########################################################
 
 ifneq ($(TARGET_BUILD_VARIANT),user)
-  TARGET_STRIP_EXTRA = && $(PRIVATE_OBJCOPY) --add-gnu-debuglink=$< $@
+  TARGET_STRIP_EXTRA = && $(PRIVATE_OBJCOPY_ADD_SECTION) --add-gnu-debuglink=$< $@
   TARGET_STRIP_KEEP_SYMBOLS_EXTRA = --add-gnu-debuglink=$<
 endif
 
 define transform-to-stripped
 @echo "$($(PRIVATE_PREFIX)DISPLAY) Strip: $(PRIVATE_MODULE) ($@)"
 @mkdir -p $(dir $@)
-$(hide) $(PRIVATE_STRIP) --strip-all $< -o $@ \
+$(hide) $(PRIVATE_STRIP) $(PRIVATE_STRIP_ALL_FLAGS) $< \
+  $(PRIVATE_STRIP_O_FLAG) $@ \
   $(if $(PRIVATE_NO_DEBUGLINK),,$(TARGET_STRIP_EXTRA))
 endef
 
@@ -1844,7 +1874,9 @@
 @echo "$($(PRIVATE_PREFIX)DISPLAY) Strip (mini debug info): $(PRIVATE_MODULE) ($@)"
 @mkdir -p $(dir $@)
 $(hide) rm -f $@ $@.dynsyms $@.funcsyms $@.keep_symbols $@.debug $@.mini_debuginfo.xz
-if $(PRIVATE_STRIP) --strip-all -R .comment $< -o $@; then \
+if $(PRIVATE_STRIP) $(PRIVATE_STRIP_ALL_FLAGS) \
+  --remove-section .comment $< \
+  $(PRIVATE_STRIP_O_FLAG) $@; then  \
   $(PRIVATE_OBJCOPY) --only-keep-debug $< $@.debug && \
   $(PRIVATE_NM) -D $< --format=posix --defined-only | awk '{ print $$1 }' | sort >$@.dynsyms && \
   $(PRIVATE_NM) $< --format=posix --defined-only | awk '{ if ($$2 == "T" || $$2 == "t" || $$2 == "D") print $$1 }' | sort >$@.funcsyms && \
@@ -1854,8 +1886,8 @@
   $(PRIVATE_OBJCOPY) -S --remove-section .gdb_index --remove-section .comment --keep-symbols=$@.keep_symbols $@.mini_debuginfo && \
   $(PRIVATE_OBJCOPY) --rename-section saved_debug_frame=.debug_frame $@.mini_debuginfo && \
   rm -f $@.mini_debuginfo.xz && \
-  xz $@.mini_debuginfo && \
-  $(PRIVATE_OBJCOPY) --add-section .gnu_debugdata=$@.mini_debuginfo.xz $@; \
+  $(XZ) $@.mini_debuginfo && \
+  $(PRIVATE_OBJCOPY_ADD_SECTION) --add-section .gnu_debugdata=$@.mini_debuginfo.xz $@; \
 else \
   cp -f $< $@; \
 fi
@@ -1864,22 +1896,12 @@
 define transform-to-stripped-keep-symbols
 @echo "$($(PRIVATE_PREFIX)DISPLAY) Strip (keep symbols): $(PRIVATE_MODULE) ($@)"
 @mkdir -p $(dir $@)
-$(hide) $(PRIVATE_OBJCOPY) \
-    `$(PRIVATE_READELF) -S $< | awk '/.debug_/ {print "-R " $$2}' | xargs` \
+$(hide) $(PRIVATE_OBJCOPY_ADD_SECTION) \
+    `$(PRIVATE_READELF) -S $< | awk '/.debug_/ {print "--remove-section " $$2}' | xargs` \
     $(TARGET_STRIP_KEEP_SYMBOLS_EXTRA) $< $@
 endef
 
 ###########################################################
-## Commands for packing a target executable or library
-###########################################################
-
-define pack-elf-relocations
-@echo "$($(PRIVATE_PREFIX)DISPLAY) Pack Relocations: $(PRIVATE_MODULE) ($@)"
-$(copy-file-to-target)
-$(hide) $(RELOCATION_PACKER) $@
-endef
-
-###########################################################
 ## Commands for running gcc to link an executable
 ###########################################################
 
@@ -1965,10 +1987,6 @@
 HOST_FPIE_FLAGS :=
 else
 HOST_FPIE_FLAGS := -pie
-# Force the correct entry point to workaround a bug in binutils that manifests with -pie
-ifeq ($(HOST_CROSS_OS),windows)
-HOST_CROSS_FPIE_FLAGS += -Wl,-e_mainCRTStartup
-endif
 endif
 
 ifneq ($(HOST_CUSTOM_LD_COMMAND),true)
@@ -2141,6 +2159,19 @@
 $(EXTRACT_JAR_PACKAGES) -i $(PRIVATE_SRCJAR) -o $(PRIVATE_AAPT_EXTRA_PACKAGES) --prefix '--extra-packages '
 endef
 
+define _create-default-manifest-file
+$(1):
+	rm -f $1
+	(echo '<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="missing.manifest">' && \
+	 echo '    <uses-sdk android:minSdkVersion="$(2)" />' && \
+	 echo '</manifest>' ) > $1
+endef
+
+define create-default-manifest-file
+  $(eval $(call _create-default-manifest-file,$(1),$(2)))
+endef
+
+
 ###########################################################
 xlint_unchecked := -Xlint:unchecked
 
@@ -2295,12 +2326,9 @@
     $(JAVA) -jar $(TURBINE) \
     --output $@.premerged --temp_dir $(dir $@)/classes-turbine \
     --sources \@$(PRIVATE_JAVA_SOURCE_LIST) --source_jars $(PRIVATE_SRCJARS) \
-    --javacopts $(PRIVATE_JAVACFLAGS) $(COMMON_JDK_FLAGS) \
-    $(addprefix --bootclasspath ,$(strip \
-         $(call normalize-path-list,$(PRIVATE_BOOTCLASSPATH)) \
-         $(PRIVATE_EMPTY_BOOTCLASSPATH))) \
-    $(addprefix --classpath ,$(strip \
-        $(call normalize-path-list,$(PRIVATE_ALL_JAVA_HEADER_LIBRARIES)))) \
+    --javacopts $(PRIVATE_JAVACFLAGS) $(COMMON_JDK_FLAGS) -- \
+    $(addprefix --bootclasspath ,$(strip $(PRIVATE_BOOTCLASSPATH))) \
+    $(addprefix --classpath ,$(strip $(PRIVATE_ALL_JAVA_HEADER_LIBRARIES))) \
     || ( rm -rf $(dir $@)/classes-turbine ; exit 41 ) && \
     $(MERGE_ZIPS) -j --ignore-duplicates -stripDir META-INF $@.tmp $@.premerged $(call reverse-list,$(PRIVATE_STATIC_JAVA_HEADER_LIBRARIES)) ; \
 else \
@@ -2358,48 +2386,10 @@
 $(if $(filter $(1),$(PLATFORM_VERSION_CODENAME)),10000,$(1))
 endef
 
-# --add-opens is required because desugar reflects via java.lang.invoke.MethodHandles.Lookup
-define desugar-classes-jar
-@echo Desugar: $@
-@mkdir -p $(dir $@)
-$(hide) rm -f $@ $@.tmp
-@rm -rf $(dir $@)/desugar_dumped_classes
-@mkdir $(dir $@)/desugar_dumped_classes
-$(hide) $(JAVA) \
-    $(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)) \
-    $(addprefix --classpath_entry ,$(PRIVATE_SHARED_JAVA_HEADER_LIBRARIES)) \
-    --min_sdk_version $(call codename-or-sdk-to-sdk,$(PRIVATE_MIN_SDK_VERSION)) \
-    --allow_empty_bootclasspath \
-    $(if $(filter --core-library,$(PRIVATE_DX_FLAGS)),--core_library) \
-    -i $< -o $@.tmp
-    mv $@.tmp $@
-endef
-
 
 define transform-classes.jar-to-dex
 @echo "target Dex: $(PRIVATE_MODULE)"
 @mkdir -p $(dir $@)
-$(hide) rm -f $(dir $@)classes*.dex
-$(hide) $(DX_COMMAND) \
-    --dex --output=$(dir $@) \
-    --min-sdk-version=$(PRIVATE_MIN_SDK_VERSION) \
-    $(if $(NO_OPTIMIZE_DX), \
-        --no-optimize) \
-    $(if $(GENERATE_DEX_DEBUG), \
-	    --debug --verbose \
-	    --dump-to=$(@:.dex=.lst) \
-	    --dump-width=1000) \
-    $(PRIVATE_DX_FLAGS) \
-    $<
-endef
-
-
-define transform-classes-d8.jar-to-dex
-@echo "target Dex: $(PRIVATE_MODULE)"
-@mkdir -p $(dir $@)
 $(hide) rm -f $(dir $@)classes*.dex $(dir $@)d8_input.jar
 $(hide) $(ZIP2ZIP) -j -i $< -o $(dir $@)d8_input.jar "**/*.class"
 $(hide) $(DX_COMMAND) \
@@ -2658,6 +2648,33 @@
     $(_cmf_dest)))
 endef
 
+# Copy the file only if it's a well-formed init script file. For use via $(eval).
+# $(1): source file
+# $(2): destination file
+define copy-init-script-file-checked
+# Host init verifier doesn't exist on darwin.
+ifneq ($(HOST_OS),darwin)
+$(2): $(1) $(HOST_INIT_VERIFIER) $(call intermediates-dir-for,ETC,passwd)/passwd
+	$(hide) $(HOST_INIT_VERIFIER) $$< $(call intermediates-dir-for,ETC,passwd)/passwd
+else
+$(2): $(1)
+endif
+	@echo "Copy init script: $$@"
+	$$(copy-file-to-target)
+endef
+
+# Copies many init script files and check they are well-formed.
+# $(1): The init script files to copy.  Each entry is a ':' separated src:dst pair.
+# Evaluates to the list of the dst files. (ie suitable for a dependency list.)
+define copy-many-init-script-files-checked
+$(foreach f, $(1), $(strip \
+    $(eval _cmf_tuple := $(subst :, ,$(f))) \
+    $(eval _cmf_src := $(word 1,$(_cmf_tuple))) \
+    $(eval _cmf_dest := $(word 2,$(_cmf_tuple))) \
+    $(eval $(call copy-init-script-file-checked,$(_cmf_src),$(_cmf_dest))) \
+    $(_cmf_dest)))
+endef
+
 # Copy the file only if it's a well-formed xml file. For use via $(eval).
 # $(1): source file
 # $(2): destination file, must end with .xml.
@@ -2668,6 +2685,40 @@
 	$$(copy-file-to-target)
 endef
 
+# Copies many xml files and check they are well-formed.
+# $(1): The xml files to copy.  Each entry is a ':' separated src:dst pair.
+# Evaluates to the list of the dst files. (ie suitable for a dependency list.)
+define copy-many-xml-files-checked
+$(foreach f, $(1), $(strip \
+    $(eval _cmf_tuple := $(subst :, ,$(f))) \
+    $(eval _cmf_src := $(word 1,$(_cmf_tuple))) \
+    $(eval _cmf_dest := $(word 2,$(_cmf_tuple))) \
+    $(eval $(call copy-xml-file-checked,$(_cmf_src),$(_cmf_dest))) \
+    $(_cmf_dest)))
+endef
+
+# Copy the file only if it is a well-formed manifest file. For use viea $(eval)
+# $(1): source file
+# $(2): destination file
+define copy-vintf-manifest-checked
+$(2): $(1) $(HOST_OUT_EXECUTABLES)/assemble_vintf
+	@echo "Copy xml: $$@"
+	$(hide) $(HOST_OUT_EXECUTABLES)/assemble_vintf -i $$< >/dev/null  # Don't print the xml file to stdout.
+	$$(copy-file-to-target)
+endef
+
+# Copies many vintf manifest files checked.
+# $(1): The files to copy.  Each entry is a ':' separated src:dst pair
+# Evaluates to the list of the dst files (ie suitable for a dependency list)
+define copy-many-vintf-manifest-files-checked
+$(foreach f, $(1), $(strip \
+    $(eval _cmf_tuple := $(subst :, ,$(f))) \
+    $(eval _cmf_src := $(word 1,$(_cmf_tuple))) \
+    $(eval _cmf_dest := $(word 2,$(_cmf_tuple))) \
+    $(eval $(call copy-vintf-manifest-checked,$(_cmf_src),$(_cmf_dest))) \
+    $(_cmf_dest)))
+endef
+
 # The -t option to acp and the -p option to cp is
 # required for OSX.  OSX has a ridiculous restriction
 # where it's an error for a .a file's modification time
@@ -2785,35 +2836,46 @@
 fi
 endef
 
+# Copy dex files, invoking $(HIDDENAPI) on them in the process.
+# Also make the source dex file an input of the hiddenapi singleton rule in dex_preopt.mk.
 define hiddenapi-copy-dex-files
 $(2): $(1) $(HIDDENAPI) $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
       $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
 	@rm -rf $(dir $(2))
 	@mkdir -p $(dir $(2))
-	find $(dir $(1)) -maxdepth 1 -name "classes*.dex" | sort | \
-		xargs -I{} cp -f {} $(dir $(2))
-	find $(dir $(2)) -name "classes*.dex" | sort | sed 's/^/--dex=/' | \
-		xargs $(HIDDENAPI) --light-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
-		                   --dark-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \
-		                   --blacklist=$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
+	find $(dir $(1)) -maxdepth 1 -name "classes*.dex" | xargs -I{} cp -f {} $(dir $(2))/; \
+	find $(dir $(2)) -maxdepth 1 -name "classes*.dex" | sort | sed 's/^/--dex=/' \
+	| xargs $(HIDDENAPI) encode \
+	    --light-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
+	    --dark-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \
+	    --blacklist=$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
+
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): $(1)
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): \
+    PRIVATE_DEX_INPUTS := $$(PRIVATE_DEX_INPUTS) $(1)
 endef
 
+# File names for intermediate dex files of `hiddenapi-copy-soong-jar`.
+hiddenapi-soong-input-dex = $(dir $(1))/hiddenapi/dex-input/classes.dex
+hiddenapi-soong-output-dex = $(dir $(1))/hiddenapi/dex-output/classes.dex
+
+# Decompress a JAR with dex files, invoke $(HIDDENAPI) on them and compress again.
 define hiddenapi-copy-soong-jar
-$(2): PRIVATE_FOLDER := $(dir $(2))dex-hiddenapi
-$(2): $(1) $(HIDDENAPI) $(SOONG_ZIP) $(MERGE_ZIPS) $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
-      $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
-	@echo "Hidden API: $$@"
-	$$(copy-file-to-target)
-	@rm -rf $${PRIVATE_FOLDER}
-	@mkdir -p $${PRIVATE_FOLDER}
-	unzip -q $(2) 'classes*.dex' -d $${PRIVATE_FOLDER}
-	find $${PRIVATE_FOLDER} -name "classes*.dex" | sort | sed 's/^/--dex=/' | \
-		xargs $(HIDDENAPI) --light-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
-		                   --dark-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \
-		                   --blacklist=$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
-	$(SOONG_ZIP) -o $${PRIVATE_FOLDER}/classes.dex.jar -C $${PRIVATE_FOLDER} -D $${PRIVATE_FOLDER}
-	$(MERGE_ZIPS) -D -zipToNotStrip $${PRIVATE_FOLDER}/classes.dex.jar -stripFile "classes*.dex" \
-		$(2) $${PRIVATE_FOLDER}/classes.dex.jar $(1)
+$(call hiddenapi-soong-input-dex,$(2)): $(1)
+	@rm -rf `dirname $$@`
+	@mkdir -p `dirname $$@`
+	unzip -o -q $(1) 'classes*.dex' -d `dirname $$@`
+	find `dirname $$@` -maxdepth 1 -name 'classes*.dex' | xargs touch
+
+$(call hiddenapi-copy-dex-files,\
+    $(call hiddenapi-soong-input-dex,$(2)),\
+    $(call hiddenapi-soong-output-dex,$(2)))
+
+$(2): OUTPUT_DIR := $(dir $(call hiddenapi-soong-output-dex,$(2)))
+$(2): OUTPUT_JAR := $(dir $(call hiddenapi-soong-output-dex,$(2)))classes.jar
+$(2): $(1) $(call hiddenapi-soong-output-dex,$(2)) | $(SOONG_ZIP) $(MERGE_ZIPS)
+	$(SOONG_ZIP) -o $${OUTPUT_JAR} -C $${OUTPUT_DIR} -D $${OUTPUT_DIR}
+	$(MERGE_ZIPS) -D -zipToNotStrip $${OUTPUT_JAR} -stripFile "classes*.dex" $(2) $${OUTPUT_JAR} $(1)
 endef
 
 ###########################################################
@@ -3089,15 +3151,20 @@
 
 # For each suite:
 # 1. Copy the files to the many suite output directories.
+#    And for test config files, we'll check the .xml is well-formed before copy.
 # 2. Add all the files to each suite's dependent files list.
 # 3. Do the dependency addition to my_all_targets
-# Requires for each suite: my_compat_dist_$(suite) to be defined.
+# Requires for each suite: use my_compat_dist_config_$(suite) to define the test config.
+#    and use my_compat_dist_$(suite) to define the others.
 define create-suite-dependencies
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
   $(eval COMPATIBILITY.$(suite).FILES := \
-    $$(COMPATIBILITY.$(suite).FILES) $$(foreach f,$$(my_compat_dist_$(suite)),$$(call word-colon,2,$$(f))))) \
+    $$(COMPATIBILITY.$(suite).FILES) $$(foreach f,$$(my_compat_dist_$(suite)),$$(call word-colon,2,$$(f))) \
+      $$(foreach f,$$(my_compat_dist_config_$(suite)),$$(call word-colon,2,$$(f))))) \
 $(eval $(my_all_targets) : $(call copy-many-files, \
-  $(sort $(foreach suite,$(LOCAL_COMPATIBILITY_SUITE),$(my_compat_dist_$(suite))))))
+  $(sort $(foreach suite,$(LOCAL_COMPATIBILITY_SUITE),$(my_compat_dist_$(suite))))) \
+  $(call copy-many-xml-files-checked, \
+    $(sort $(foreach suite,$(LOCAL_COMPATIBILITY_SUITE),$(my_compat_dist_config_$(suite))))))
 endef
 
 ###########################################################
@@ -3451,10 +3518,18 @@
   $(if $(call has-system-sdk-version,$(1)),$(patsubst system_%,%,$(1)),$(1)))
 endef
 
-# Convert to lower case without requiring a shell, which isn't cacheable.
+###########################################################
+## Convert to lower case without requiring a shell, which isn't cacheable.
+##
+## $(1): string
+###########################################################
 to-lower=$(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
 
-# Convert to upper case without requiring a shell, which isn't cacheable.
+###########################################################
+## Convert to upper case without requiring a shell, which isn't cacheable.
+##
+## $(1): string
+###########################################################
 to-upper=$(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$1))))))))))))))))))))))))))
 
 # Sanity-check to-lower and to-upper
@@ -3471,3 +3546,40 @@
 
 lower :=
 upper :=
+
+###########################################################
+## Verify module name meets character requirements:
+##   a-z A-Z 0-9
+##   _.+-=,@~
+##
+## This is a subset of bazel's target name restrictions:
+##   https://docs.bazel.build/versions/master/build-ref.html#name
+###########################################################
+define verify-module-name
+$(if $(filter-out $(LOCAL_MODULE),$(subst /,,$(LOCAL_MODULE))), \
+  $(call pretty-warning,Module name contains a /$(comma) use LOCAL_MODULE_STEM and LOCAL_MODULE_RELATIVE_PATH instead)) \
+$(if $(call _invalid-name-chars,$(LOCAL_MODULE)), \
+  $(call pretty-error,Invalid characters in module name: $(call _invalid-name-chars,$(LOCAL_MODULE))))
+endef
+define _invalid-name-chars
+$(subst _,,$(subst .,,$(subst +,,$(subst -,,$(subst =,,$(subst $(comma),,$(subst @,,$(subst ~,,$(subst 0,,$(subst 1,,$(subst 2,,$(subst 3,,$(subst 4,,$(subst 5,,$(subst 6,,$(subst 7,,$(subst 8,,$(subst 9,,$(subst a,,$(subst b,,$(subst c,,$(subst d,,$(subst e,,$(subst f,,$(subst g,,$(subst h,,$(subst i,,$(subst j,,$(subst k,,$(subst l,,$(subst m,,$(subst n,,$(subst o,,$(subst p,,$(subst q,,$(subst r,,$(subst s,,$(subst t,,$(subst u,,$(subst v,,$(subst w,,$(subst x,,$(subst y,,$(subst z,,$(call to-lower,$(1))))))))))))))))))))))))))))))))))))))))))))))
+endef
+.KATI_READONLY := verify-module-name _invalid-name-chars
+
+###########################################################
+## Verify module stem meets character requirements:
+##   a-z A-Z 0-9
+##   _.+-=,@~
+##
+## This is a subset of bazel's target name restrictions:
+##   https://docs.bazel.build/versions/master/build-ref.html#name
+##
+## $(1): The module stem variable to check
+###########################################################
+define verify-module-stem
+$(if $(filter-out $($(1)),$(subst /,,$($(1)))), \
+  $(call pretty-warning,Module stem \($(1)\) contains a /$(comma) use LOCAL_MODULE_RELATIVE_PATH instead)) \
+$(if $(call _invalid-name-chars,$($(1))), \
+  $(call pretty-error,Invalid characters in module stem \($(1)\): $(call _invalid-name-chars,$($(1)))))
+endef
+.KATI_READONLY := verify-module-stem
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index 7298bde..00da02b 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -21,7 +21,7 @@
 
 # The default filter for which files go into the system_other image (if it is
 # being used). To bundle everything one should set this to '%'
-SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%
+SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/% product/app/% product/priv-app/%
 
 # Method returning whether the install path $(1) should be for system_other.
 # Under SANITIZE_LITE, we do not want system_other. Just put things under /data/asan.
@@ -90,6 +90,39 @@
 $(TARGET_2ND_ARCH_VAR_PREFIX)DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT := $($(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME)
 endif  # TARGET_2ND_ARCH
 
+# === hiddenapi rules ===
+
+hiddenapi_stubs_jar = $(call intermediates-dir-for,JAVA_LIBRARIES,$(1),,COMMON)/javalib.jar
+
+# Public API stubs
+HIDDENAPI_STUBS := \
+    $(call hiddenapi_stubs_jar,android_stubs_current) \
+    $(call hiddenapi_stubs_jar,android.test.base.stubs) \
+    $(call hiddenapi_stubs_jar,android.test.mock.stubs) \
+    $(call hiddenapi_stubs_jar,android.test.runner.stubs)
+
+# System API stubs
+HIDDENAPI_STUBS += \
+    $(call hiddenapi_stubs_jar,android_system_stubs_current)
+
+# Test API stubs
+HIDDENAPI_STUBS += \
+    $(call hiddenapi_stubs_jar,android_test_stubs_current)
+
+# Singleton rule which applies $(HIDDENAPI) on all boot class path dex files.
+# Inputs are filled with `hiddenapi-copy-dex-files` rules.
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): \
+    PRIVATE_HIDDENAPI_STUBS := $(HIDDENAPI_STUBS)
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): \
+    .KATI_IMPLICIT_OUTPUTS := $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): $(HIDDENAPI) $(HIDDENAPI_STUBS)
+	for INPUT_DEX in $(PRIVATE_DEX_INPUTS); do \
+		find `dirname $${INPUT_DEX}` -maxdepth 1 -name "classes*.dex"; \
+	done | sort | sed 's/^/--boot-dex=/' | xargs $(HIDDENAPI) list \
+	    $(addprefix --stub-dex=,$(PRIVATE_HIDDENAPI_STUBS)) \
+	    --out-public=$(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) \
+	    --out-private=$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST)
+
 ifeq ($(PRODUCT_DIST_BOOT_AND_SYSTEM_JARS),true)
 boot_profile_jars_zip := $(PRODUCT_OUT)/boot_profile_jars.zip
 all_boot_jars := \
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index 9c4d55d..ce060f2 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -20,10 +20,6 @@
 PRELOADED_CLASSES := $(call word-colon,1,$(firstword \
     $(filter %system/etc/preloaded-classes,$(PRODUCT_COPY_FILES))))
 
-# Use the first compiled-classes file in PRODUCT_COPY_FILES.
-COMPILED_CLASSES := $(call word-colon,1,$(firstword \
-    $(filter %system/etc/compiled-classes,$(PRODUCT_COPY_FILES))))
-
 # Use the first dirty-image-objects file in PRODUCT_COPY_FILES.
 DIRTY_IMAGE_OBJECTS := $(call word-colon,1,$(firstword \
     $(filter %system/etc/dirty-image-objects,$(PRODUCT_COPY_FILES))))
@@ -104,16 +100,27 @@
 my_use_profile_for_boot_image := true
 endif
 endif
+ifeq (,$(strip $(LIBART_TARGET_BOOT_DEX_FILES)))
+my_use_profile_for_boot_image := false
+endif
 
 ifeq (true,$(my_use_profile_for_boot_image))
 
-# Location of text based profile for the boot image.
-my_boot_image_profile_location := $(PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION)
-ifeq (,$(my_boot_image_profile_location))
+boot_image_profiles := $(PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION)
+
+ifeq (,$(boot_image_profiles))
 # If not set, use the default.
-my_boot_image_profile_location := frameworks/base/config/boot-image-profile.txt
+boot_image_profiles := frameworks/base/config/boot-image-profile.txt
 endif
 
+# Location of text based profile for the boot image.
+my_boot_image_profile_location := $(PRODUCT_OUT)/dex_bootjars/boot-image-profile.txt
+
+$(my_boot_image_profile_location): $(boot_image_profiles)
+	@echo 'Generating $@ for profman'
+	@rm -rf $@
+	$(hide) cat $^ > $@
+
 # Code to create the boot image profile, not in dex_preopt_libart_boot.mk since the profile is the same for all archs.
 my_out_boot_image_profile_location := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/boot.prof
 $(my_out_boot_image_profile_location): PRIVATE_PROFILE_INPUT_LOCATION := $(my_boot_image_profile_location)
@@ -169,7 +176,7 @@
 # $(2): the output .odex file
 # In the case where LOCAL_ENFORCE_USES_LIBRARIES is true, PRIVATE_DEX2OAT_CLASS_LOADER_CONTEXT
 # contains the normalized path list of the libraries. This makes it easier to conditionally prepend
-# org.apache.http.legacy.boot based on the SDK level if required.
+# org.apache.http.legacy.impl based on the SDK level if required.
 define dex2oat-one-file
 $(hide) rm -f $(2)
 $(hide) mkdir -p $(dir $(2))
@@ -179,7 +186,8 @@
 stored_class_loader_context_arg="" && \
 uses_library_names="$(PRIVATE_USES_LIBRARY_NAMES)" && \
 optional_uses_library_names="$(PRIVATE_OPTIONAL_USES_LIBRARY_NAMES)" && \
-$(if $(PRIVATE_ENFORCE_USES_LIBRARIES), \
+aapt_binary="$(AAPT)" && \
+$(if $(filter true,$(PRIVATE_ENFORCE_USES_LIBRARIES)), \
 source build/make/core/verify_uses_libraries.sh "$(1)" && \
 source build/make/core/construct_context.sh "$(PRIVATE_CONDITIONAL_USES_LIBRARIES_HOST)" "$(PRIVATE_CONDITIONAL_USES_LIBRARIES_TARGET)" && \
 ,) \
diff --git a/core/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index a5e7e88..977f852 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -33,12 +33,6 @@
 $(my_2nd_arch_prefix)LIBART_TARGET_BOOT_ART_VDEX_INSTALLED_FILES := $(addprefix $(dir $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)),\
     $(LIBART_TARGET_BOOT_ART_VDEX_FILES))
 
-# If we have a compiled-classes file, create a parameter.
-COMPILED_CLASSES_FLAGS :=
-ifneq ($(COMPILED_CLASSES),)
-  COMPILED_CLASSES_FLAGS := --compiled-classes=$(COMPILED_CLASSES)
-endif
-
 # If we have a dirty-image-objects file, create a parameter.
 DIRTY_IMAGE_OBJECTS_FLAGS :=
 ifneq ($(DIRTY_IMAGE_OBJECTS),)
@@ -59,13 +53,12 @@
 	$(hide) $(ACP) -fp $(dir $<)$(notdir $@) $@
 
 ifeq (,$(my_out_boot_image_profile_location))
-my_boot_image_flags := $(COMPILED_CLASSES_FLAGS)
-my_boot_image_flags += --image-classes=$(PRELOADED_CLASSES)
-my_boot_image_flags += $(DIRTY_IMAGE_OBJECTS_FLAGS)
+my_boot_image_flags := --image-classes=$(PRELOADED_CLASSES)
 else
 my_boot_image_flags := --compiler-filter=speed-profile
 my_boot_image_flags += --profile-file=$(my_out_boot_image_profile_location)
 endif
+my_boot_image_flags += $(DIRTY_IMAGE_OBJECTS_FLAGS)
 
 ifneq (addresstrue,$(SANITIZE_TARGET)$(SANITIZE_LITE))
 # Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
@@ -94,7 +87,7 @@
 $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME): PRIVATE_2ND_ARCH_VAR_PREFIX := $(my_2nd_arch_prefix)
 $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME): PRIVATE_IMAGE_LOCATION := $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION)
 # Use dex2oat debug version for better error reporting
-$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) : $(LIBART_TARGET_BOOT_DEX_FILES) $(PRELOADED_CLASSES) $(COMPILED_CLASSES) $(DIRTY_IMAGE_OBJECTS) $(DEX2OAT_DEPENDENCY) $(PATCHOAT_DEPENDENCY) $(my_out_boot_image_profile_location)
+$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) : $(LIBART_TARGET_BOOT_DEX_FILES) $(PRELOADED_CLASSES) $(DIRTY_IMAGE_OBJECTS) $(DEX2OAT_DEPENDENCY) $(PATCHOAT_DEPENDENCY) $(my_out_boot_image_profile_location)
 	@echo "target dex2oat: $@"
 	@mkdir -p $(dir $@)
 	@mkdir -p $(dir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED))
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index ce91759..4e9b7b0 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -193,14 +193,19 @@
 installed_odex += $($(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)
 else  # boot jar
 ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
+
+my_module_multilib := $(LOCAL_MULTILIB)
+# If the module is not an SDK library and it's a system server jar, only preopt the primary arch.
+my_filtered_lib_name := $(patsubst %.impl,%,$(LOCAL_MODULE))
+ifeq (,$(filter $(JAVA_SDK_LIBRARIES),$(my_filtered_lib_name)))
 # For a Java library, by default we build odex for both 1st arch and 2nd arch.
 # But it can be overridden with "LOCAL_MULTILIB := first".
 ifneq (,$(filter $(PRODUCT_SYSTEM_SERVER_JARS),$(LOCAL_MODULE)))
 # For system server jars, we build for only "first".
 my_module_multilib := first
-else
-my_module_multilib := $(LOCAL_MULTILIB)
 endif
+endif
+
 # #################################################
 # Odex for the 1st arch
 my_2nd_arch_prefix :=
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index bcd2002..1a36758 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -15,9 +15,12 @@
 #
 
 $(call record-module-type,DROIDDOC)
-###########################################################
-## Common logic to both droiddoc and javadoc
-###########################################################
+##
+##
+## Common to both droiddoc and javadoc
+##
+##
+
 LOCAL_IS_HOST_MODULE := $(call true-or-empty,$(LOCAL_IS_HOST_MODULE))
 ifeq ($(LOCAL_IS_HOST_MODULE),true)
 my_prefix := HOST_
@@ -51,7 +54,6 @@
 endif
 
 ifeq ($(LOCAL_IS_HOST_MODULE),true)
-
 $(full_target): PRIVATE_BOOTCLASSPATH :=
 full_java_libs := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/,\
   $(addsuffix $(COMMON_JAVA_PACKAGE_SUFFIX),$(LOCAL_JAVA_LIBRARIES)))
@@ -73,12 +75,11 @@
     LOCAL_JAVA_LIBRARIES := core.current.stubs $(LOCAL_JAVA_LIBRARIES)
     $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, core.current.stubs)
   else
-    # core_<ver> is subset of <ver>. Instead of defining a prebuilt lib for core_<ver>,
-    # use the stub for <ver> when building for apps.
-    _version := $(patsubst core_%,%,$(LOCAL_SDK_VERSION))
-    LOCAL_JAVA_LIBRARIES := sdk_v$(_version) $(LOCAL_JAVA_LIBRARIES)
-    $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, sdk_v$(_version))
-    _version :=
+    # TARGET_BUILD_APPS is set. Use the modules defined in prebuilts/sdk/Android.mk.
+    _module_name := $(call resolve-prebuilt-sdk-module,$(LOCAL_SDK_VERSION))
+    LOCAL_JAVA_LIBRARIES := $(_module_name) $(LOCAL_JAVA_LIBRARIES)
+    $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, $(_module_name))
+    _module_name :=
   endif
 else
   ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
@@ -114,7 +115,6 @@
 $(full_target): PRIVATE_OUT_DIR := $(out_dir)
 $(full_target): PRIVATE_DROIDDOC_OPTIONS := $(LOCAL_DROIDDOC_OPTIONS)
 $(full_target): PRIVATE_STUB_OUT_DIR := $(LOCAL_DROIDDOC_STUB_OUT_DIR)
-$(full_target): PRIVATE_METALAVA_DOCS_STUB_OUT_DIR := $(LOCAL_DROIDDOC_METALAVA_DOCS_STUB_OUT_DIR)
 
 # Lists the input files for the doc build into a text file
 # suitable for the @ syntax of javadoc.
@@ -127,10 +127,18 @@
 $(hide) for d in $(3) ; do find $$d -name '*.java' -and -not -name '.*' >> $(1) 2> /dev/null ; done ; true
 endef
 
-###########################################################
-## Logic for droiddoc only
-###########################################################
+ifeq (a,b)
+$(full_target): PRIVATE_PROFILING_OPTIONS := \
+    -J-agentlib:jprofilerti=port=8849 -J-Xbootclasspath/a:/Applications/jprofiler5/bin/agent.jar
+endif
+
+
 ifneq ($(strip $(LOCAL_DROIDDOC_USE_STANDARD_DOCLET)),true)
+##
+##
+## droiddoc only
+##
+##
 
 droiddoc_templates := \
     $(sort $(shell find $(LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR) -type f $(if $(ALLOW_MISSING_DEPENDENCIES),2>/dev/null)))
@@ -141,6 +149,10 @@
   endif
 endif
 
+droiddoc := \
+	$(HOST_JDK_TOOLS_JAR) \
+	$(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX)
+
 $(full_target): PRIVATE_DOCLETPATH := $(HOST_OUT_JAVA_LIBRARIES)/jsilver$(COMMON_JAVA_PACKAGE_SUFFIX):$(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX)
 $(full_target): PRIVATE_CURRENT_BUILD := -hdf page.build $(BUILD_ID)-$(BUILD_NUMBER_FROM_FILE)
 $(full_target): PRIVATE_CURRENT_TIME :=  -hdf page.now "$$($(DATE_FROM_FILE) "+%d %b %Y %k:%M")"
@@ -162,129 +174,18 @@
 $(full_target): PRIVATE_ADDITIONAL_HTML_DIR :=
 endif
 
-# TODO(nanzhang): Remove it if this is not used any more
+# TODO: not clear if this is used any more
 $(full_target): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
 
-ifeq ($(strip $(LOCAL_DROIDDOC_USE_METALAVA)),true)
-ifneq ($(LOCAL_DROIDDOC_METALAVA_PREVIOUS_API),)
-$(full_target): PRIVATE_DROIDDOC_METALAVA_PREVIOUS_API := --previous-api $(LOCAL_DROIDDOC_METALAVA_PREVIOUS_API)
-else
-$(full_target): PRIVATE_DROIDDOC_METALAVA_PREVIOUS_API :=
-endif #!LOCAL_DROIDDOC_METALAVA_PREVIOUS_API
-
-metalava_annotations_deps :=
-ifeq ($(strip $(LOCAL_DROIDDOC_METALAVA_ANNOTATIONS_ENABLED)),true)
-ifeq ($(LOCAL_DROIDDOC_METALAVA_PREVIOUS_API),)
-$(error $(LOCAL_PATH): LOCAL_DROIDDOC_METALAVA_PREVIOUS_API has to be non-empty if metalava annotations was enabled!)
-endif
-ifeq ($(LOCAL_DROIDDOC_METALAVA_MERGE_ANNOTATIONS_DIR),)
-$(error $(LOCAL_PATH): LOCAL_DROIDDOC_METALAVA_MERGE_ANNOTATIONS_DIR has to be non-empty if metalava annotations was enabled!)
-endif
-
-$(full_target): PRIVATE_DROIDDOC_METALAVA_ANNOTATIONS := --include-annotations --migrate-nullness \
-    --extract-annotations $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(LOCAL_MODULE)_annotations.zip \
-    --merge-annotations $(LOCAL_DROIDDOC_METALAVA_MERGE_ANNOTATIONS_DIR) \
-    --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction
-metalava_annotations_deps := $(sort $(shell find $(LOCAL_DROIDDOC_METALAVA_MERGE_ANNOTATIONS_DIR) -type f))
-else
-$(full_target): PRIVATE_DROIDDOC_METALAVA_ANNOTATIONS :=
-endif #LOCAL_DROIDDOC_METALAVA_ANNOTATIONS_ENABLED=true
-
-ifneq (,$(filter --generate-documentation,$(LOCAL_DROIDDOC_OPTIONS)))
-
-pos = $(if $(findstring $1,$2),$(call pos,$1,$(wordlist 2,$(words $2),$2),x $3),$3)
-metalava_args := $(wordlist 1, $(words $(call pos,--generate-documentation,$(LOCAL_DROIDDOC_OPTIONS))), \
-    $(LOCAL_DROIDDOC_OPTIONS))
-remaining_args :=  $(wordlist $(words $(call pos,--generate-documentation,$(LOCAL_DROIDDOC_OPTIONS))), \
-    $(words $(LOCAL_DROIDDOC_OPTIONS)), $(LOCAL_DROIDDOC_OPTIONS))
-doclava_args := $(wordlist 2, $(words $(remaining_args)), $(remaining_args))
-
-$(full_target): \
-        $(full_src_files) $(LOCAL_GENERATED_SOURCES) \
-        $(droiddoc_templates) \
-        $(HOST_JDK_TOOLS_JAR) \
-        $(HOST_OUT_JAVA_LIBRARIES)/jsilver$(COMMON_JAVA_PACKAGE_SUFFIX) \
-        $(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX) \
-        $(HOST_OUT_JAVA_LIBRARIES)/metalava$(COMMON_JAVA_PACKAGE_SUFFIX) \
-        $(html_dir_files) \
-        $(full_java_libs) \
-        $(ZIPSYNC) \
-        $(LOCAL_SRCJARS) \
-        $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-        $(LOCAL_DROIDDOC_METALAVA_PREVIOUS_API) \
-        $(metalava_annotations_deps)
-	@echo metalava based docs: $(PRIVATE_OUT_DIR)
-	$(hide) mkdir -p $(dir $@)
-	$(hide) rm -rf $(PRIVATE_STUB_OUT_DIR)
-	$(hide) rm -rf $(PRIVATE_METALAVA_DOCS_STUB_OUT_DIR)
-	$(call prepare-doc-source-list,$(PRIVATE_SRC_LIST_FILE),$(PRIVATE_JAVA_FILES), \
-			$(PRIVATE_SOURCE_INTERMEDIATES_DIR) $(PRIVATE_ADDITIONAL_JAVA_DIR))
-	$(ZIPSYNC) -d $(PRIVATE_SRCJAR_INTERMEDIATES_DIR) -l $(PRIVATE_SRCJAR_LIST_FILE) -f "*.java" $(PRIVATE_SRCJARS)
-	$(hide) ( \
-		$(JAVA) -jar $(HOST_OUT_JAVA_LIBRARIES)/metalava$(COMMON_JAVA_PACKAGE_SUFFIX) \
-                -encoding UTF-8 -source 1.8 \@$(PRIVATE_SRC_LIST_FILE) \@$(PRIVATE_SRCJAR_LIST_FILE) \
-                $(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH)) \
-                $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
-                --sourcepath $(PRIVATE_SOURCE_PATH) \
-                --no-banner --color --quiet \
-                $(addprefix --stubs ,$(PRIVATE_STUB_OUT_DIR)) \
-                $(addprefix --doc-stubs ,$(PRIVATE_METALAVA_DOCS_STUB_OUT_DIR)) \
-                --write-stubs-source-list $(intermediates.COMMON)/stubs-src-list \
-                $(metalava_args) $(PRIVATE_DROIDDOC_METALAVA_PREVIOUS_API) $(PRIVATE_DROIDDOC_METALAVA_ANNOTATIONS) \
-                $(JAVADOC) -encoding UTF-8 -source 1.8 STUBS_SOURCE_LIST \
-                -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file \
-                -quiet -doclet com.google.doclava.Doclava -docletpath $(PRIVATE_DOCLETPATH) \
-                -templatedir $(PRIVATE_CUSTOM_TEMPLATE_DIR) \
-                $(PRIVATE_DROIDDOC_HTML_DIR) $(PRIVATE_ADDITIONAL_HTML_DIR) \
-                $(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH)) \
-                $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
-                -sourcepath $(PRIVATE_SOURCE_PATH) \
-                -d $(PRIVATE_OUT_DIR) \
-                $(PRIVATE_CURRENT_BUILD) $(PRIVATE_CURRENT_TIME) $(doclava_args) \
-        && touch -f $@ ) || (rm -rf $(PRIVATE_OUT_DIR) $(PRIVATE_SRC_LIST_FILE); exit 45)
-else
-# no docs generation
-$(full_target): \
-        $(full_src_files) $(LOCAL_GENERATED_SOURCES) \
-        $(full_java_libs) \
-        $(HOST_OUT_JAVA_LIBRARIES)/metalava$(COMMON_JAVA_PACKAGE_SUFFIX) \
-        $(ZIPSYNC) \
-        $(LOCAL_SRCJARS) \
-        $(LOCAL_ADDITIONAL_DEPENDENCIES)
-	@echo metalava based stubs: $@
-	$(hide) mkdir -p $(dir $@)
-	$(hide) rm -rf $(PRIVATE_STUB_OUT_DIR)
-	$(call prepare-doc-source-list,$(PRIVATE_SRC_LIST_FILE),$(PRIVATE_JAVA_FILES), \
-			$(PRIVATE_SOURCE_INTERMEDIATES_DIR) $(PRIVATE_ADDITIONAL_JAVA_DIR))
-	$(ZIPSYNC) -d $(PRIVATE_SRCJAR_INTERMEDIATES_DIR) -l $(PRIVATE_SRCJAR_LIST_FILE) -f "*.java" $(PRIVATE_SRCJARS)
-	$(hide) ( \
-		$(JAVA) -jar $(HOST_OUT_JAVA_LIBRARIES)/metalava$(COMMON_JAVA_PACKAGE_SUFFIX) \
-                -encoding UTF-8 -source 1.8 \@$(PRIVATE_SRC_LIST_FILE) \@$(PRIVATE_SRCJAR_LIST_FILE) \
-                $(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH)) \
-                $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
-                --sourcepath $(PRIVATE_SOURCE_PATH) \
-                $(PRIVATE_DROIDDOC_OPTIONS) $(PRIVATE_DROIDDOC_METALAVA_PREVIOUS_API) $(PRIVATE_DROIDDOC_METALAVA_ANNOTATIONS) \
-                --no-banner --color --quiet \
-                $(addprefix --stubs ,$(PRIVATE_STUB_OUT_DIR)) \
-        && touch -f $@ ) || (rm -rf $(PRIVATE_SRC_LIST_FILE); exit 45)
-
-endif # stubs + docs generation
-ifeq ($(strip $(LOCAL_DROIDDOC_METALAVA_ANNOTATIONS_ENABLED)),true)
-$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(LOCAL_MODULE)_annotations.zip: $(full_target)
-endif
-
-else # doclava based droiddoc generation
-
 # TODO(tobiast): Clean this up once we move to -source 1.9.
 # OpenJDK 9 does not have the concept of a "boot classpath" so we should
 # then rename PRIVATE_BOOTCLASSPATH to PRIVATE_MODULE or similar. For now,
 # keep -bootclasspath here since it works in combination with -source 1.8.
 $(full_target): \
-        $(full_src_files) $(LOCAL_GENERATED_SOURCES) \
+        $(full_src_files) \
+        $(LOCAL_GENERATED_SOURCES) \
         $(droiddoc_templates) \
-        $(HOST_JDK_TOOLS_JAR) \
-        $(HOST_OUT_JAVA_LIBRARIES)/jsilver$(COMMON_JAVA_PACKAGE_SUFFIX) \
-        $(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX) \
+        $(droiddoc) \
         $(html_dir_files) \
         $(full_java_libs) \
         $(ZIPSYNC) \
@@ -298,35 +199,44 @@
 	$(ZIPSYNC) -d $(PRIVATE_SRCJAR_INTERMEDIATES_DIR) -l $(PRIVATE_SRCJAR_LIST_FILE) -f "*.java" $(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 \
-                -quiet -doclet com.google.doclava.Doclava -docletpath $(PRIVATE_DOCLETPATH) \
+                -encoding UTF-8 \
+                -source 1.8 \
+                \@$(PRIVATE_SRC_LIST_FILE) \
+                \@$(PRIVATE_SRCJAR_LIST_FILE) \
+                -J-Xmx1600m \
+                -J-XX:-OmitStackTraceInFastThrow \
+                -XDignore.symbol.file \
+                $(PRIVATE_PROFILING_OPTIONS) \
+                -quiet \
+                -doclet com.google.doclava.Doclava \
+                -docletpath $(PRIVATE_DOCLETPATH) \
                 -templatedir $(PRIVATE_CUSTOM_TEMPLATE_DIR) \
-                $(PRIVATE_DROIDDOC_HTML_DIR) $(PRIVATE_ADDITIONAL_HTML_DIR) \
+                $(PRIVATE_DROIDDOC_HTML_DIR) \
+                $(PRIVATE_ADDITIONAL_HTML_DIR) \
                 $(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH)) \
                 $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
-                -sourcepath $(PRIVATE_SOURCE_PATH)$(addprefix :,$(PRIVATE_CLASSPATH)) \
+                -sourcepath $(PRIVATE_SOURCE_PATH) \
                 -d $(PRIVATE_OUT_DIR) \
-                $(PRIVATE_CURRENT_BUILD) $(PRIVATE_CURRENT_TIME) $(PRIVATE_DROIDDOC_OPTIONS) \
+                $(PRIVATE_CURRENT_BUILD) $(PRIVATE_CURRENT_TIME) \
+                $(PRIVATE_DROIDDOC_OPTIONS) \
                 $(addprefix -stubs ,$(PRIVATE_STUB_OUT_DIR)) \
-        && touch -f $@ ) || (rm -rf $(PRIVATE_OUT_DIR) $(PRIVATE_SRC_LIST_FILE); exit 45)
-endif #LOCAL_DROIDDOC_USE_METALAVA
+        && touch -f $@ \
+    ) || (cat $(PRIVATE_SRC_LIST_FILE) $(PRIVATE_SRCJAR_LIST_FILE) && rm -rf $(PRIVATE_OUT_DIR) $(PRIVATE_SRC_LIST_FILE); exit 45)
+
+
 
 else
+##
+##
+## standard doclet only
+##
+##
 
-###########################################################
-## Logic for javadoc only
-###########################################################
-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
 # to work around the OpenJDK 9 module system. http://b/62049770
 $(full_target): PRIVATE_BOOTCLASSPATH_ARG := --patch-module=java.base=$(PRIVATE_BOOTCLASSPATH)
-else
-# 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) $(LOCAL_GENERATED_SOURCES) $(full_java_libs) $(ZIPSYNC) $(LOCAL_SRCJARS) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	@echo Docs javadoc: $(PRIVATE_OUT_DIR)
 	@mkdir -p $(dir $@)
@@ -334,15 +244,31 @@
 			$(PRIVATE_SOURCE_INTERMEDIATES_DIR) $(PRIVATE_ADDITIONAL_JAVA_DIR))
 	$(ZIPSYNC) -d $(PRIVATE_SRCJAR_INTERMEDIATES_DIR) -l $(PRIVATE_SRCJAR_LIST_FILE) -f "*.java" $(PRIVATE_SRCJARS)
 	$(hide) ( \
-		$(JAVADOC) -encoding UTF-8 \@$(PRIVATE_SRC_LIST_FILE) \@$(PRIVATE_SRCJAR_LIST_FILE) \
-                $(PRIVATE_DROIDDOC_OPTIONS) -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none -quiet \
-                $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) $(PRIVATE_BOOTCLASSPATH_ARG) \
+		$(JAVADOC) \
+                -encoding UTF-8 \
+                $(PRIVATE_DROIDDOC_OPTIONS) \
+                \@$(PRIVATE_SRC_LIST_FILE) \
+                \@$(PRIVATE_SRCJAR_LIST_FILE) \
+                -J-Xmx1024m \
+                -XDignore.symbol.file \
+                -Xdoclint:none \
+                $(PRIVATE_PROFILING_OPTIONS) \
+                $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
+                $(PRIVATE_BOOTCLASSPATH_ARG) \
                 -sourcepath $(PRIVATE_SOURCE_PATH) \
                 -d $(PRIVATE_OUT_DIR) \
+                -quiet \
         && touch -f $@ \
     ) || (rm -rf $(PRIVATE_OUT_DIR) $(PRIVATE_SRC_LIST_FILE); exit 45)
 
-endif # !LOCAL_DROIDDOC_USE_STANDARD_DOCLET
+
+endif
+##
+##
+## Common to both droiddoc and javadoc
+##
+##
+
 
 ALL_DOCS += $(full_target)
 
@@ -364,4 +290,4 @@
 
 $(call dist-for-goals,docs,$(out_zip))
 
-endif #!LOCAL_UNINSTALLABLE_MODULE
+endif
diff --git a/core/dynamic_binary.mk b/core/dynamic_binary.mk
index f44b8a8..2f9c8ff 100644
--- a/core/dynamic_binary.mk
+++ b/core/dynamic_binary.mk
@@ -35,49 +35,11 @@
 LOCAL_INTERMEDIATE_TARGETS := $(linked_module)
 
 ###################################
+include $(BUILD_SYSTEM)/use_lld_setup.mk
 include $(BUILD_SYSTEM)/binary.mk
 ###################################
 
 ###########################################################
-## Pack relocation tables
-###########################################################
-relocation_packer_input := $(linked_module)
-relocation_packer_output := $(intermediates)/PACKED/$(my_built_module_stem)
-
-my_pack_module_relocations := false
-ifneq ($(DISABLE_RELOCATION_PACKER),true)
-    my_pack_module_relocations := $(firstword \
-      $(LOCAL_PACK_MODULE_RELOCATIONS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) \
-      $(LOCAL_PACK_MODULE_RELOCATIONS))
-endif
-
-ifeq ($(my_pack_module_relocations),)
-  my_pack_module_relocations := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_PACK_MODULE_RELOCATIONS)
-endif
-
-# Do not pack relocations for executables. Because packing results in
-# non-zero p_vaddr which causes kernel to load executables to lower
-# address (starting at 0x8000) http://b/20665974
-ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
-  my_pack_module_relocations := false
-endif
-
-# TODO (dimitry): Relocation packer is not yet available for darwin
-ifneq ($(HOST_OS),linux)
-  my_pack_module_relocations := false
-endif
-
-ifeq (true,$(my_pack_module_relocations))
-# Pack relocations
-$(relocation_packer_output): $(relocation_packer_input)
-	$(pack-elf-relocations)
-else
-$(relocation_packer_output): $(relocation_packer_input)
-	@echo "target Unpacked: $(PRIVATE_MODULE) ($@)"
-	$(copy-file-to-target)
-endif
-
-###########################################################
 ## Store a copy with symbols for symbolic debugging
 ###########################################################
 ifeq ($(LOCAL_UNSTRIPPED_PATH),)
@@ -85,7 +47,7 @@
 else
 my_unstripped_path := $(LOCAL_UNSTRIPPED_PATH)
 endif
-symbolic_input := $(relocation_packer_output)
+symbolic_input := $(linked_module)
 symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem)
 $(symbolic_output) : $(symbolic_input)
 	@echo "target Symbolic: $(PRIVATE_MODULE) ($@)"
@@ -97,7 +59,7 @@
 
 ifeq ($(BREAKPAD_GENERATE_SYMBOLS),true)
 my_breakpad_path := $(TARGET_OUT_BREAKPAD)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
-breakpad_input := $(relocation_packer_output)
+breakpad_input := $(linked_module)
 breakpad_output := $(my_breakpad_path)/$(my_installed_module_stem).sym
 $(breakpad_output) : $(breakpad_input) | $(BREAKPAD_DUMP_SYMS) $(PRIVATE_READELF)
 	@echo "target breakpad: $(PRIVATE_MODULE) ($@)"
@@ -133,7 +95,25 @@
 endif
 endif
 
-$(strip_output): PRIVATE_STRIP := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP)
+ifeq ($(my_use_clang_lld),true)
+  # b/80093681: GNU strip and objcopy --{add,remove}-section have bug in handling
+  # GNU_RELRO segment of files lnked by clang lld; so they are replaced
+  # by llvm-strip and llvm-objcopy here.
+  $(strip_output): PRIVATE_OBJCOPY_ADD_SECTION := $(LLVM_OBJCOPY)
+  $(strip_output): PRIVATE_STRIP := $(LLVM_STRIP)
+  $(strip_output): PRIVATE_STRIP_O_FLAG :=
+  # GNU strip keeps .ARM.attributes section even with -strip-all,
+  # so here pass -keep=.ARM.attributes to llvm-strip.
+  $(strip_output): PRIVATE_STRIP_ALL_FLAGS := -strip-all -keep=.ARM.attributes
+else
+  $(strip_output): PRIVATE_OBJCOPY_ADD_SECTION := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJCOPY)
+  $(strip_output): PRIVATE_STRIP := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP)
+  $(strip_output): PRIVATE_STRIP_O_FLAG := -o
+  $(strip_output): PRIVATE_STRIP_ALL_FLAGS := --strip-all
+endif
+# PRIVATE_OBJCOPY is not changed to llvm-objcopy yet.
+# It is used even when my_use_clang_lld is true,
+# because some objcopy flags are not supported by llvm-objcopy yet.
 $(strip_output): PRIVATE_OBJCOPY := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJCOPY)
 $(strip_output): PRIVATE_NM := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NM)
 $(strip_output): PRIVATE_READELF := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_READELF)
@@ -145,15 +125,15 @@
 
 ifeq ($(my_strip_module),mini-debug-info)
 # Strip the binary, but keep debug frames and symbol table in a compressed .gnu_debugdata section.
-$(strip_output): $(strip_input) | $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP) $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJCOPY) $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NM)
+$(strip_output): $(strip_input) $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP) $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJCOPY) $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NM) $(XZ)
 	$(transform-to-stripped-keep-mini-debug-info)
 else ifneq ($(filter true no_debuglink,$(my_strip_module)),)
 # Strip the binary
-$(strip_output): $(strip_input) | $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP)
+$(strip_output): $(strip_input) $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP)
 	$(transform-to-stripped)
 else ifeq ($(my_strip_module),keep_symbols)
 # Strip only the debug frames, but leave the symbol table.
-$(strip_output): $(strip_input) | $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP)
+$(strip_output): $(strip_input) $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP)
 	$(transform-to-stripped-keep-symbols)
 
 # A product may be configured to strip everything in some build variants.
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 700189e..2f37767 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -241,17 +241,26 @@
 # or under vendor/*/$(TARGET_DEVICE).  Search in both places, but
 # make sure only one exists.
 # Real boards should always be associated with an OEM vendor.
-board_config_mk := \
-	$(strip $(sort $(wildcard \
-		$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \
-		$(shell test -d device && find -L device -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \
-		$(shell test -d vendor && find -L vendor -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \
-	)))
-ifeq ($(board_config_mk),)
-  $(error No config file found for TARGET_DEVICE $(TARGET_DEVICE))
-endif
-ifneq ($(words $(board_config_mk)),1)
-  $(error Multiple board config files for TARGET_DEVICE $(TARGET_DEVICE): $(board_config_mk))
+ifdef TARGET_DEVICE_DIR
+  ifneq ($(origin TARGET_DEVICE_DIR),command line)
+    $(error TARGET_DEVICE_DIR may not be set manually)
+  endif
+  board_config_mk := $(TARGET_DEVICE_DIR)/BoardConfig.mk
+else
+  board_config_mk := \
+    $(strip $(sort $(wildcard \
+      $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \
+      $(shell test -d device && find -L device -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \
+      $(shell test -d vendor && find -L vendor -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \
+    )))
+  ifeq ($(board_config_mk),)
+    $(error No config file found for TARGET_DEVICE $(TARGET_DEVICE))
+  endif
+  ifneq ($(words $(board_config_mk)),1)
+    $(error Multiple board config files for TARGET_DEVICE $(TARGET_DEVICE): $(board_config_mk))
+  endif
+  TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))
+  .KATI_READONLY := TARGET_DEVICE_DIR
 endif
 include $(board_config_mk)
 ifeq ($(TARGET_ARCH),)
@@ -261,10 +270,34 @@
   $(warning *** Unsupported option MALLOC_IMPL defined by board config: $(board_config_mk).)
   $(error Use `MALLOC_SVELTE := true` to configure jemalloc for low-memory)
 endif
-TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))
 board_config_mk :=
 
 ###########################################
+# Handle BUILD_BROKEN_* settings
+vars := \
+  BUILD_BROKEN_ANDROIDMK_EXPORTS \
+  BUILD_BROKEN_DUP_COPY_HEADERS \
+  BUILD_BROKEN_DUP_RULES \
+  BUILD_BROKEN_PHONY_TARGETS
+
+$(foreach var,$(vars),$(eval $(var) := $$(strip $$($(var)))))
+
+$(foreach var,$(vars), \
+  $(if $(filter-out true false,$($(var))), \
+    $(error Valid values of $(var) are "true", "false", and "". Not "$($(var))")))
+
+.KATI_READONLY := $(vars)
+
+CHANGES_URL := https://android.googlesource.com/platform/build/+/master/Changes.md
+
+# "" is equivalent to true currently.
+ifeq ($(BUILD_BROKEN_ANDROIDMK_EXPORTS),false)
+$(KATI_obsolete_export It is a global setting. See $(CHANGES_URL)#export_keyword)
+endif
+
+CHANGES_URL :=
+
+###########################################
 # Now we can substitute with the real value of TARGET_COPY_OUT_VENDOR
 ifeq ($(TARGET_COPY_OUT_VENDOR),$(_vendor_path_placeholder))
 TARGET_COPY_OUT_VENDOR := system/vendor
@@ -366,28 +399,22 @@
 # ---------------------------------------------------------------
 # figure out the output directories
 
-ifeq (,$(strip $(OUT_DIR)))
-ifeq (,$(strip $(OUT_DIR_COMMON_BASE)))
-OUT_DIR := $(TOPDIR)out
-else
-OUT_DIR := $(OUT_DIR_COMMON_BASE)/$(notdir $(PWD))
-endif
-endif
-
 SOONG_OUT_DIR := $(OUT_DIR)/soong
 
 TARGET_OUT_ROOT := $(OUT_DIR)/target
 
 HOST_OUT_ROOT := $(OUT_DIR)/host
 
+.KATI_READONLY := SOONG_OUT_DIR TARGET_OUT_ROOT HOST_OUT_ROOT
+
 # We want to avoid two host bin directories in multilib build.
 HOST_OUT := $(HOST_OUT_ROOT)/$(HOST_OS)-$(HOST_PREBUILT_ARCH)
 SOONG_HOST_OUT := $(SOONG_OUT_DIR)/host/$(HOST_OS)-$(HOST_PREBUILT_ARCH)
-# TODO: remove
-BUILD_OUT := $(HOST_OUT)
 
 HOST_CROSS_OUT := $(HOST_OUT_ROOT)/windows-$(HOST_PREBUILT_ARCH)
 
+.KATI_READONLY := HOST_OUT SOONG_HOST_OUT HOST_CROSS_OUT
+
 TARGET_PRODUCT_OUT_ROOT := $(TARGET_OUT_ROOT)/product
 
 TARGET_COMMON_OUT_ROOT := $(TARGET_OUT_ROOT)/common
@@ -395,11 +422,17 @@
 
 PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
 
+.KATI_READONLY := TARGET_PRODUCT_OUT_ROOT TARGET_COMMON_OUT_ROOT HOST_COMMON_OUT_ROOT PRODUCT_OUT
+
 OUT_DOCS := $(TARGET_COMMON_OUT_ROOT)/docs
 OUT_NDK_DOCS := $(TARGET_COMMON_OUT_ROOT)/ndk-docs
+.KATI_READONLY := OUT_DOCS OUT_NDK_DOCS
 
-BUILD_OUT_EXECUTABLES := $(BUILD_OUT)/bin
+$(call KATI_obsolete,BUILD_OUT,Use HOST_OUT instead)
+
+BUILD_OUT_EXECUTABLES := $(HOST_OUT)/bin
 SOONG_HOST_OUT_EXECUTABLES := $(SOONG_HOST_OUT)/bin
+.KATI_READONLY := BUILD_OUT_EXECUTABLES SOONG_HOST_OUT_EXECUTABLES
 
 HOST_OUT_EXECUTABLES := $(HOST_OUT)/bin
 HOST_OUT_SHARED_LIBRARIES := $(HOST_OUT)/lib64
@@ -409,18 +442,39 @@
 HOST_OUT_NATIVE_TESTS := $(HOST_OUT)/nativetest64
 HOST_OUT_COVERAGE := $(HOST_OUT)/coverage
 HOST_OUT_TESTCASES := $(HOST_OUT)/testcases
+.KATI_READONLY := \
+  HOST_OUT_EXECUTABLES \
+  HOST_OUT_SHARED_LIBRARIES \
+  HOST_OUT_RENDERSCRIPT_BITCODE \
+  HOST_OUT_JAVA_LIBRARIES \
+  HOST_OUT_SDK_ADDON \
+  HOST_OUT_NATIVE_TESTS \
+  HOST_OUT_COVERAGE \
+  HOST_OUT_TESTCASES
 
 HOST_CROSS_OUT_EXECUTABLES := $(HOST_CROSS_OUT)/bin
 HOST_CROSS_OUT_SHARED_LIBRARIES := $(HOST_CROSS_OUT)/lib
 HOST_CROSS_OUT_NATIVE_TESTS := $(HOST_CROSS_OUT)/nativetest
 HOST_CROSS_OUT_COVERAGE := $(HOST_CROSS_OUT)/coverage
 HOST_CROSS_OUT_TESTCASES := $(HOST_CROSS_OUT)/testcases
+.KATI_READONLY := \
+  HOST_CROSS_OUT_EXECUTABLES \
+  HOST_CROSS_OUT_SHARED_LIBRARIES \
+  HOST_CROSS_OUT_NATIVE_TESTS \
+  HOST_CROSS_OUT_COVERAGE \
+  HOST_CROSS_OUT_TESTCASES
 
 HOST_OUT_INTERMEDIATES := $(HOST_OUT)/obj
 HOST_OUT_INTERMEDIATE_LIBRARIES := $(HOST_OUT_INTERMEDIATES)/lib
 HOST_OUT_NOTICE_FILES := $(HOST_OUT_INTERMEDIATES)/NOTICE_FILES
 HOST_OUT_COMMON_INTERMEDIATES := $(HOST_COMMON_OUT_ROOT)/obj
 HOST_OUT_FAKE := $(HOST_OUT)/fake_packages
+.KATI_READONLY := \
+  HOST_OUT_INTERMEDIATES \
+  HOST_OUT_INTERMEDIATE_LIBRARIES \
+  HOST_OUT_NOTICE_FILES \
+  HOST_OUT_COMMON_INTERMEDIATES \
+  HOST_OUT_FAKE
 
 # Nano environment config
 include $(BUILD_SYSTEM)/aux_config.mk
@@ -428,13 +482,22 @@
 HOST_CROSS_OUT_INTERMEDIATES := $(HOST_CROSS_OUT)/obj
 HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES := $(HOST_CROSS_OUT_INTERMEDIATES)/lib
 HOST_CROSS_OUT_NOTICE_FILES := $(HOST_CROSS_OUT_INTERMEDIATES)/NOTICE_FILES
+.KATI_READONLY := \
+  HOST_CROSS_OUT_INTERMEDIATES \
+  HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES \
+  HOST_CROSS_OUT_NOTICE_FILES
 
 HOST_OUT_GEN := $(HOST_OUT)/gen
 HOST_OUT_COMMON_GEN := $(HOST_COMMON_OUT_ROOT)/gen
+.KATI_READONLY := \
+  HOST_OUT_GEN \
+  HOST_OUT_COMMON_GEN
 
 HOST_CROSS_OUT_GEN := $(HOST_CROSS_OUT)/gen
+.KATI_READONLY := HOST_CROSS_OUT_GEN
 
 HOST_OUT_TEST_CONFIG := $(HOST_OUT)/test_config
+.KATI_READONLY := HOST_OUT_TEST_CONFIG
 
 # Out for HOST_2ND_ARCH
 HOST_2ND_ARCH_VAR_PREFIX := 2ND_
@@ -446,10 +509,21 @@
 $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_JAVA_LIBRARIES := $(HOST_OUT_JAVA_LIBRARIES)
 $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_NATIVE_TESTS := $(HOST_OUT)/nativetest
 $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_TESTCASES := $(HOST_OUT_TESTCASES)
+.KATI_READONLY := \
+  HOST_2ND_ARCH_VAR_PREFIX \
+  HOST_2ND_ARCH_MODULE_SUFFIX \
+  $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATES \
+  $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES \
+  $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES \
+  $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_EXECUTABLES \
+  $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_JAVA_LIBRARIES \
+  $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_NATIVE_TESTS \
+  $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_TESTCASES
 
 # The default host library path.
 # It always points to the path where we build libraries in the default bitness.
 HOST_LIBRARY_PATH := $(HOST_OUT_SHARED_LIBRARIES)
+.KATI_READONLY := HOST_LIBRARY_PATH
 
 # Out for HOST_CROSS_2ND_ARCH
 HOST_CROSS_2ND_ARCH_VAR_PREFIX := 2ND_
@@ -459,6 +533,14 @@
 $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_SHARED_LIBRARIES := $(HOST_CROSS_OUT)/lib64
 $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_EXECUTABLES := $(HOST_CROSS_OUT_EXECUTABLES)
 $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_NATIVE_TESTS := $(HOST_CROSS_OUT)/nativetest64
+.KATI_READONLY := \
+  HOST_CROSS_2ND_ARCH_VAR_PREFIX \
+  HOST_CROSS_2ND_ARCH_MODULE_SUFFIX \
+  $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_INTERMEDIATES \
+  $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES \
+  $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_SHARED_LIBRARIES \
+  $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_EXECUTABLES \
+  $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_NATIVE_TESTS
 
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
   TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj_asan
@@ -467,17 +549,21 @@
 endif
 TARGET_OUT_HEADERS := $(TARGET_OUT_INTERMEDIATES)/include
 TARGET_OUT_INTERMEDIATE_LIBRARIES := $(TARGET_OUT_INTERMEDIATES)/lib
+.KATI_READONLY := TARGET_OUT_INTERMEDIATES TARGET_OUT_HEADERS TARGET_OUT_INTERMEDIATE_LIBRARIES
 
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
   TARGET_OUT_COMMON_INTERMEDIATES := $(TARGET_COMMON_OUT_ROOT)/obj_asan
 else
   TARGET_OUT_COMMON_INTERMEDIATES := $(TARGET_COMMON_OUT_ROOT)/obj
 endif
+.KATI_READONLY := TARGET_OUT_COMMON_INTERMEDIATES
 
 TARGET_OUT_GEN := $(PRODUCT_OUT)/gen
 TARGET_OUT_COMMON_GEN := $(TARGET_COMMON_OUT_ROOT)/gen
+.KATI_READONLY := TARGET_OUT_GEN TARGET_OUT_COMMON_GEN
 
 TARGET_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM)
+.KATI_READONLY := TARGET_OUT
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
 target_out_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/system
 ifeq ($(SANITIZE_LITE),true)
@@ -512,6 +598,21 @@
 TARGET_OUT_FAKE := $(PRODUCT_OUT)/fake_packages
 TARGET_OUT_TESTCASES := $(PRODUCT_OUT)/testcases
 TARGET_OUT_TEST_CONFIG := $(PRODUCT_OUT)/test_config
+.KATI_READONLY := \
+  TARGET_OUT_EXECUTABLES \
+  TARGET_OUT_OPTIONAL_EXECUTABLES \
+  TARGET_OUT_SHARED_LIBRARIES \
+  TARGET_OUT_RENDERSCRIPT_BITCODE \
+  TARGET_OUT_JAVA_LIBRARIES \
+  TARGET_OUT_APPS \
+  TARGET_OUT_APPS_PRIVILEGED \
+  TARGET_OUT_KEYLAYOUT \
+  TARGET_OUT_KEYCHARS \
+  TARGET_OUT_ETC \
+  TARGET_OUT_NOTICE_FILES \
+  TARGET_OUT_FAKE \
+  TARGET_OUT_TESTCASES \
+  TARGET_OUT_TEST_CONFIG
 
 ifeq ($(SANITIZE_LITE),true)
 # When using SANITIZE_LITE, APKs must not be packaged with sanitized libraries, as they will not
@@ -520,6 +621,7 @@
 else
 TARGET_OUT_SYSTEM_OTHER := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM_OTHER)
 endif
+.KATI_READONLY := TARGET_OUT_SYSTEM_OTHER
 
 # Out for TARGET_2ND_ARCH
 TARGET_2ND_ARCH_VAR_PREFIX := $(HOST_2ND_ARCH_VAR_PREFIX)
@@ -529,6 +631,7 @@
 else
 TARGET_2ND_ARCH_MODULE_SUFFIX := $(HOST_2ND_ARCH_MODULE_SUFFIX)
 endif
+.KATI_READONLY := TARGET_2ND_ARCH_VAR_PREFIX TARGET_2ND_ARCH_MODULE_SUFFIX
 
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
   $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj_$(TARGET_2ND_ARCH)_asan
@@ -546,6 +649,15 @@
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_APPS := $(TARGET_OUT_APPS)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_APPS_PRIVILEGED := $(TARGET_OUT_APPS_PRIVILEGED)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_TESTCASES := $(TARGET_OUT_TESTCASES)
+.KATI_READONLY := \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_RENDERSCRIPT_BITCODE \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_EXECUTABLES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_APPS \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_APPS_PRIVILEGED \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_TESTCASES
 
 TARGET_OUT_DATA := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_DATA)
 TARGET_OUT_DATA_EXECUTABLES := $(TARGET_OUT_EXECUTABLES)
@@ -567,6 +679,20 @@
 TARGET_OUT_VENDOR_METRIC_TESTS := $(TARGET_OUT_DATA)/benchmarktest$(TARGET_VENDOR_TEST_SUFFIX)
 endif
 TARGET_OUT_DATA_FAKE := $(TARGET_OUT_DATA)/fake_packages
+.KATI_READONLY := \
+  TARGET_OUT_DATA \
+  TARGET_OUT_DATA_EXECUTABLES \
+  TARGET_OUT_DATA_SHARED_LIBRARIES \
+  TARGET_OUT_DATA_JAVA_LIBRARIES \
+  TARGET_OUT_DATA_APPS \
+  TARGET_OUT_DATA_KEYLAYOUT \
+  TARGET_OUT_DATA_KEYCHARS \
+  TARGET_OUT_DATA_ETC \
+  TARGET_OUT_DATA_NATIVE_TESTS \
+  TARGET_OUT_DATA_METRIC_TESTS \
+  TARGET_OUT_VENDOR_NATIVE_TESTS \
+  TARGET_OUT_VENDOR_METRIC_TESTS \
+  TARGET_OUT_DATA_FAKE
 
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_EXECUTABLES := $(TARGET_OUT_DATA_EXECUTABLES)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_SHARED_LIBRARIES := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES)
@@ -582,10 +708,20 @@
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_NATIVE_TESTS := $(TARGET_OUT_DATA)/nativetest$(TARGET_VENDOR_TEST_SUFFIX)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_METRIC_TESTS := $(TARGET_OUT_DATA)/benchmarktest$(TARGET_VENDOR_TEST_SUFFIX)
 endif
+.KATI_READONLY := \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_EXECUTABLES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_SHARED_LIBRARIES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_APPS \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_METRIC_TESTS \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_NATIVE_TESTS \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_METRIC_TESTS \
 
 TARGET_OUT_CACHE := $(PRODUCT_OUT)/cache
+.KATI_READONLY := TARGET_OUT_CACHE
 
 TARGET_OUT_VENDOR := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR)
+.KATI_READONLY := TARGET_OUT_VENDOR
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
 target_out_vendor_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/vendor
 ifeq ($(SANITIZE_LITE),true)
@@ -612,6 +748,15 @@
 TARGET_OUT_VENDOR_APPS := $(target_out_vendor_app_base)/app
 TARGET_OUT_VENDOR_APPS_PRIVILEGED := $(target_out_vendor_app_base)/priv-app
 TARGET_OUT_VENDOR_ETC := $(TARGET_OUT_VENDOR)/etc
+.KATI_READONLY := \
+  TARGET_OUT_VENDOR_EXECUTABLES \
+  TARGET_OUT_VENDOR_OPTIONAL_EXECUTABLES \
+  TARGET_OUT_VENDOR_SHARED_LIBRARIES \
+  TARGET_OUT_VENDOR_RENDERSCRIPT_BITCODE \
+  TARGET_OUT_VENDOR_JAVA_LIBRARIES \
+  TARGET_OUT_VENDOR_APPS \
+  TARGET_OUT_VENDOR_APPS_PRIVILEGED \
+  TARGET_OUT_VENDOR_ETC
 
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_EXECUTABLES := $(TARGET_OUT_VENDOR_EXECUTABLES)
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
@@ -622,6 +767,12 @@
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_RENDERSCRIPT_BITCODE := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_SHARED_LIBRARIES)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_APPS := $(TARGET_OUT_VENDOR_APPS)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_APPS_PRIVILEGED := $(TARGET_OUT_VENDOR_APPS_PRIVILEGED)
+.KATI_READONLY := \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_EXECUTABLES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_SHARED_LIBRARIES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_RENDERSCRIPT_BITCODE \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_APPS \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_APPS_PRIVILEGED
 
 TARGET_OUT_OEM := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_OEM)
 TARGET_OUT_OEM_EXECUTABLES := $(TARGET_OUT_OEM)/bin
@@ -634,6 +785,12 @@
 # TARGET_OUT_OEM_JAVA_LIBRARIES:= $(TARGET_OUT_OEM)/framework
 TARGET_OUT_OEM_APPS := $(TARGET_OUT_OEM)/app
 TARGET_OUT_OEM_ETC := $(TARGET_OUT_OEM)/etc
+.KATI_READONLY := \
+  TARGET_OUT_OEM \
+  TARGET_OUT_OEM_EXECUTABLES \
+  TARGET_OUT_OEM_SHARED_LIBRARIES \
+  TARGET_OUT_OEM_APPS \
+  TARGET_OUT_OEM_ETC
 
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_EXECUTABLES := $(TARGET_OUT_OEM_EXECUTABLES)
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
@@ -642,6 +799,10 @@
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_SHARED_LIBRARIES := $(TARGET_OUT_OEM)/lib
 endif
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_APPS := $(TARGET_OUT_OEM_APPS)
+.KATI_READONLY := \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_EXECUTABLES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_SHARED_LIBRARIES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_APPS \
 
 TARGET_OUT_ODM := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ODM)
 TARGET_OUT_ODM_EXECUTABLES := $(TARGET_OUT_ODM)/bin
@@ -652,6 +813,12 @@
 endif
 TARGET_OUT_ODM_APPS := $(TARGET_OUT_ODM)/app
 TARGET_OUT_ODM_ETC := $(TARGET_OUT_ODM)/etc
+.KATI_READONLY := \
+  TARGET_OUT_ODM \
+  TARGET_OUT_ODM_EXECUTABLES \
+  TARGET_OUT_ODM_SHARED_LIBRARIES \
+  TARGET_OUT_ODM_APPS \
+  TARGET_OUT_ODM_ETC
 
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_EXECUTABLES := $(TARGET_OUT_ODM_EXECUTABLES)
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
@@ -660,8 +827,14 @@
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES := $(TARGET_OUT_ODM)/lib
 endif
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_APPS := $(TARGET_OUT_ODM_APPS)
+.KATI_READONLY := \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_EXECUTABLES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_APPS
 
 TARGET_OUT_PRODUCT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_PRODUCT)
+TARGET_OUT_PRODUCT_EXECUTABLES := $(TARGET_OUT_PRODUCT)/bin
+.KATI_READONLY := TARGET_OUT_PRODUCT
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
 target_out_product_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/product
 ifeq ($(SANITIZE_LITE),true)
@@ -681,11 +854,19 @@
 else
 TARGET_OUT_PRODUCT_SHARED_LIBRARIES := $(target_out_product_shared_libraries_base)/lib
 endif
-TARGET_OUT_PRODUCT_JAVA_LIBRARIES:= $(TARGET_OUT_PRODUCT)/framework
+TARGET_OUT_PRODUCT_JAVA_LIBRARIES := $(TARGET_OUT_PRODUCT)/framework
 TARGET_OUT_PRODUCT_APPS := $(target_out_product_app_base)/app
 TARGET_OUT_PRODUCT_APPS_PRIVILEGED := $(target_out_product_app_base)/priv-app
 TARGET_OUT_PRODUCT_ETC := $(TARGET_OUT_PRODUCT)/etc
+.KATI_READONLY := \
+  TARGET_OUT_PRODUCT_EXECUTABLES \
+  TARGET_OUT_PRODUCT_SHARED_LIBRARIES \
+  TARGET_OUT_PRODUCT_JAVA_LIBRARIES \
+  TARGET_OUT_PRODUCT_APPS \
+  TARGET_OUT_PRODUCT_APPS_PRIVILEGED \
+  TARGET_OUT_PRODUCT_ETC
 
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_EXECUTABLES := $(TARGET_OUT_PRODUCT_EXECUTABLES)
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SHARED_LIBRARIES := $(target_out_product_shared_libraries_base)/lib/$(TARGET_2ND_ARCH)
 else
@@ -693,8 +874,14 @@
 endif
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_APPS := $(TARGET_OUT_PRODUCT_APPS)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_APPS_PRIVILEGED := $(TARGET_OUT_PRODUCT_APPS_PRIVILEGED)
+.KATI_READONLY := \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_EXECUTABLES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SHARED_LIBRARIES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_APPS \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_APPS_PRIVILEGED
 
 TARGET_OUT_BREAKPAD := $(PRODUCT_OUT)/breakpad
+.KATI_READONLY := TARGET_OUT_BREAKPAD
 
 TARGET_OUT_UNSTRIPPED := $(PRODUCT_OUT)/symbols
 TARGET_OUT_EXECUTABLES_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/system/bin
@@ -704,31 +891,60 @@
 TARGET_ROOT_OUT_SBIN_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/sbin
 TARGET_ROOT_OUT_BIN_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/bin
 TARGET_OUT_COVERAGE := $(PRODUCT_OUT)/coverage
+.KATI_READONLY := \
+  TARGET_OUT_UNSTRIPPED \
+  TARGET_OUT_EXECUTABLES_UNSTRIPPED \
+  TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED \
+  TARGET_OUT_VENDOR_SHARED_LIBRARIES_UNSTRIPPED \
+  TARGET_ROOT_OUT_UNSTRIPPED \
+  TARGET_ROOT_OUT_SBIN_UNSTRIPPED \
+  TARGET_ROOT_OUT_BIN_UNSTRIPPED \
+  TARGET_OUT_COVERAGE
 
 TARGET_ROOT_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ROOT)
 TARGET_ROOT_OUT_BIN := $(TARGET_ROOT_OUT)/bin
 TARGET_ROOT_OUT_SBIN := $(TARGET_ROOT_OUT)/sbin
 TARGET_ROOT_OUT_ETC := $(TARGET_ROOT_OUT)/etc
 TARGET_ROOT_OUT_USR := $(TARGET_ROOT_OUT)/usr
+.KATI_READONLY := \
+  TARGET_ROOT_OUT \
+  TARGET_ROOT_OUT_BIN \
+  TARGET_ROOT_OUT_SBIN \
+  TARGET_ROOT_OUT_ETC \
+  TARGET_ROOT_OUT_USR
 
 TARGET_RECOVERY_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_RECOVERY)
 TARGET_RECOVERY_ROOT_OUT := $(TARGET_RECOVERY_OUT)/root
+.KATI_READONLY := \
+  TARGET_RECOVERY_OUT \
+  TARGET_RECOVERY_ROOT_OUT
 
 TARGET_SYSLOADER_OUT := $(PRODUCT_OUT)/sysloader
 TARGET_SYSLOADER_ROOT_OUT := $(TARGET_SYSLOADER_OUT)/root
 TARGET_SYSLOADER_SYSTEM_OUT := $(TARGET_SYSLOADER_OUT)/root/system
+.KATI_READONLY := \
+  TARGET_SYSLOADER_OUT \
+  TARGET_SYSLOADER_ROOT_OUT \
+  TARGET_SYSLOADER_SYSTEM_OUT
 
 TARGET_INSTALLER_OUT := $(PRODUCT_OUT)/installer
 TARGET_INSTALLER_DATA_OUT := $(TARGET_INSTALLER_OUT)/data
 TARGET_INSTALLER_ROOT_OUT := $(TARGET_INSTALLER_OUT)/root
 TARGET_INSTALLER_SYSTEM_OUT := $(TARGET_INSTALLER_OUT)/root/system
+.KATI_READONLY := \
+  TARGET_INSTALLER_OUT \
+  TARGET_INSTALLER_DATA_OUT \
+  TARGET_INSTALLER_ROOT_OUT \
+  TARGET_INSTALLER_SYSTEM_OUT
 
 COMMON_MODULE_CLASSES := TARGET-NOTICE_FILES HOST-NOTICE_FILES HOST-JAVA_LIBRARIES
 PER_ARCH_MODULE_CLASSES := SHARED_LIBRARIES STATIC_LIBRARIES EXECUTABLES GYP RENDERSCRIPT_BITCODE NATIVE_TESTS HEADER_LIBRARIES
+.KATI_READONLY := COMMON_MODULE_CLASSES PER_ARCH_MODULE_CLASSES
 
 ifeq (,$(strip $(DIST_DIR)))
   DIST_DIR := $(OUT_DIR)/dist
 endif
+.KATI_READONLY := DIST_DIR
 
 ifeq ($(CALLED_FROM_SETUP),true)
 PRINT_BUILD_CONFIG ?= true
diff --git a/core/force_aapt2.mk b/core/force_aapt2.mk
new file mode 100644
index 0000000..ede6fd4
--- /dev/null
+++ b/core/force_aapt2.mk
@@ -0,0 +1,71 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Including this makefile will force AAPT2 on if FORCE_AAPT2==true,
+# rewriting some properties to convert standard AAPT usage to AAPT2.
+
+ifneq ($(FORCE_AAPT2),false)
+  ifeq ($(LOCAL_USE_AAPT2),)
+    # Force AAPT2 on
+    LOCAL_USE_AAPT2 := true
+    # Filter out support library resources
+    LOCAL_RESOURCE_DIR := $(filter-out \
+      prebuilts/sdk/current/% \
+      frameworks/support/%,\
+        $(LOCAL_RESOURCE_DIR))
+    # Filter out unnecessary aapt flags
+    ifneq (,$(filter --extra-packages,$(LOCAL_AAPT_FLAGS)))
+      LOCAL_AAPT_FLAGS := $(subst --extra-packages=,--extra-packages$(space), \
+        $(filter-out \
+          --extra-packages=android.support.% \
+          --extra-packages=androidx.%, \
+            $(subst --extra-packages$(space),--extra-packages=,$(LOCAL_AAPT_FLAGS))))
+        ifeq (,$(filter --extra-packages,$(LOCAL_AAPT_FLAGS)))
+          LOCAL_AAPT_FLAGS := $(filter-out --auto-add-overlay,$(LOCAL_AAPT_FLAGS))
+        endif
+    endif
+
+    # AAPT2 is pickier about missing resources.  Support library may have references to resources
+    # added in current, so always treat LOCAL_SDK_VERSION as LOCAL_SDK_RES_VERSION := current.
+    ifdef LOCAL_SDK_VERSION
+      LOCAL_SDK_RES_VERSION := current
+    endif
+
+    ifeq (,$(strip $(LOCAL_MANIFEST_FILE)$(LOCAL_FULL_MANIFEST_FILE)))
+      ifeq (,$(wildcard $(LOCAL_PATH)/AndroidManifest.xml))
+        # work around missing manifests by creating a default one
+        LOCAL_FULL_MANIFEST_FILE := $(call local-intermediates-dir,COMMON)/DefaultManifest.xml
+        ifdef LOCAL_MIN_SDK_VERSION
+          my_manifest_min_sdk_version := $(LOCAL_MIN_SDK_VERSION)
+        else ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
+          my_manifest_min_sdk_version := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
+        else
+          my_manifest_min_sdk_version := $(DEFAULT_APP_TARGET_SDK)
+        endif
+        $(call create-default-manifest-file,$(LOCAL_FULL_MANIFEST_FILE),$(my_manifest_min_sdk_version))
+        my_manifest_min_sdk_version :=
+      endif
+    endif
+  endif
+endif
+
+ifneq ($(LOCAL_USE_AAPT2),true)
+  ifneq ($(LOCAL_USE_AAPT2),false)
+    ifneq ($(LOCAL_USE_AAPT2),)
+      $(call pretty-error,Invalid value for LOCAL_USE_AAPT2: "$(LOCAL_USE_AAPT2)")
+    endif
+  endif
+endif
diff --git a/core/goma.mk b/core/goma.mk
index 2fb37a7..3787dfd 100644
--- a/core/goma.mk
+++ b/core/goma.mk
@@ -14,9 +14,6 @@
 # limitations under the License.
 #
 
-# Used by the compiler wrapper, but should only be set by gomacc
-unexport GOMACC_PATH
-
 # Notice: this works only with Google's Goma build infrastructure.
 ifneq ($(filter-out false,$(USE_GOMA)),)
   # Goma requires a lot of processes and file descriptors.
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index 1ef0ccb..d35f39d 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -33,7 +33,6 @@
 full_classes_header_jar := $(intermediates.COMMON)/classes-header.jar
 full_classes_compiled_jar := $(intermediates.COMMON)/classes-full-debug.jar
 full_classes_combined_jar := $(intermediates.COMMON)/classes-combined.jar
-full_classes_desugar_jar := $(intermediates.COMMON)/desugar.classes.jar
 full_classes_jarjar_jar := $(intermediates.COMMON)/classes-jarjar.jar
 full_classes_jar := $(intermediates.COMMON)/classes.jar
 built_dex := $(intermediates.COMMON)/classes.dex
@@ -43,7 +42,6 @@
     $(full_classes_turbine_jar) \
     $(full_classes_compiled_jar) \
     $(full_classes_combined_jar) \
-    $(full_classes_desugar_jar) \
     $(full_classes_jarjar_jar) \
     $(full_classes_jar) \
     $(built_dex) \
@@ -158,22 +156,6 @@
 
 $(eval $(call copy-one-file,$(full_classes_jarjar_jar),$(full_classes_jar)))
 
-ifneq ($(USE_D8_DESUGAR),true)
-my_desugaring :=
-ifeq ($(LOCAL_JAVA_LANGUAGE_VERSION),1.8)
-my_desugaring := true
-$(full_classes_desugar_jar): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
-$(full_classes_desugar_jar): $(full_classes_jar) $(full_java_header_libs) $(DESUGAR)
-	$(desugar-classes-jar)
-endif
-else
-my_desugaring :=
-endif
-
-ifndef my_desugaring
-full_classes_desugar_jar := $(full_classes_jar)
-endif
-
 ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
 # No dex; all we want are the .class files with resources.
 $(LOCAL_BUILT_MODULE) : $(java_resource_sources)
@@ -184,12 +166,8 @@
 else # !LOCAL_IS_STATIC_JAVA_LIBRARY
 $(built_dex): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
 $(built_dex): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
-$(built_dex): $(full_classes_desugar_jar) $(DX) $(ZIP2ZIP)
-ifneq ($(USE_D8_DESUGAR),true)
+$(built_dex): $(full_classes_jar) $(DX) $(ZIP2ZIP)
 	$(transform-classes.jar-to-dex)
-else
-	$(transform-classes-d8.jar-to-dex)
-endif
 
 $(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
 $(LOCAL_BUILT_MODULE): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar)
diff --git a/core/host_executable_internal.mk b/core/host_executable_internal.mk
index c4f9f66..e72c419 100644
--- a/core/host_executable_internal.mk
+++ b/core/host_executable_internal.mk
@@ -33,7 +33,7 @@
 
 my_libdir := $(notdir $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_SHARED_LIBRARIES))
 ifeq ($(LOCAL_MODULE_CLASS),NATIVE_TESTS)
-$(LOCAL_BUILT_MODULE): PRIVATE_RPATHS := ../../$(my_libdir)
+$(LOCAL_BUILT_MODULE): PRIVATE_RPATHS := ../../$(my_libdir) ../../../$(my_libdir)
 else
 $(LOCAL_BUILT_MODULE): PRIVATE_RPATHS := ../$(my_libdir) $(my_libdir)
 endif
diff --git a/core/host_java_library_common.mk b/core/host_java_library_common.mk
index 51e2d94..8df4b37 100644
--- a/core/host_java_library_common.mk
+++ b/core/host_java_library_common.mk
@@ -48,8 +48,3 @@
 
 LOCAL_INTERMEDIATE_SOURCE_DIR := $(intermediates.COMMON)/src
 LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
-
-# If error prone is enabled then add LOCAL_ERROR_PRONE_FLAGS to LOCAL_JAVACFLAGS
-ifeq ($(RUN_ERROR_PRONE),true)
-LOCAL_JAVACFLAGS += $(LOCAL_ERROR_PRONE_FLAGS)
-endif
diff --git a/core/java.mk b/core/java.mk
index 9147849..0bcf602 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -15,6 +15,10 @@
 endif # !PDK_JAVA
 endif #PDK
 
+ifndef LOCAL_USE_R8
+LOCAL_USE_R8 := $(USE_R8)
+endif
+
 LOCAL_NO_STANDARD_LIBRARIES:=$(strip $(LOCAL_NO_STANDARD_LIBRARIES))
 LOCAL_SDK_VERSION:=$(strip $(LOCAL_SDK_VERSION))
 
@@ -68,7 +72,6 @@
 full_classes_header_jar := $(intermediates.COMMON)/classes-header.jar
 full_classes_compiled_jar := $(intermediates.COMMON)/classes-full-debug.jar
 full_classes_processed_jar := $(intermediates.COMMON)/classes-processed.jar
-full_classes_desugar_jar := $(intermediates.COMMON)/classes-desugar.jar
 full_classes_jarjar_jar := $(intermediates.COMMON)/classes-jarjar.jar
 full_classes_proguard_jar := $(intermediates.COMMON)/classes-proguard.jar
 full_classes_combined_jar := $(intermediates.COMMON)/classes-combined.jar
@@ -90,7 +93,6 @@
 LOCAL_INTERMEDIATE_TARGETS += \
     $(full_classes_turbine_jar) \
     $(full_classes_compiled_jar) \
-    $(full_classes_desugar_jar) \
     $(full_classes_jarjar_jar) \
     $(full_classes_jar) \
     $(full_classes_combined_jar) \
@@ -116,7 +118,7 @@
   # LOCAL_SDK_VERSION is current and no TARGET_BUILD_APPS
   aidl_preprocess_import := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
 else
-  aidl_preprocess_import := $(HISTORICAL_SDK_VERSIONS_ROOT)/$(LOCAL_SDK_VERSION)/framework.aidl
+  aidl_preprocess_import := $(call resolve-prebuilt-sdk-aidl-path,$(LOCAL_SDK_VERSION))
 endif # not current or system_current
 else
 # build against the platform.
@@ -225,11 +227,6 @@
 # Deps for generated source files must be handled separately,
 # via deps on the target that generates the sources.
 
-# If error prone is enabled then add LOCAL_ERROR_PRONE_FLAGS to LOCAL_JAVACFLAGS
-ifeq ($(RUN_ERROR_PRONE),true)
-LOCAL_JAVACFLAGS += $(LOCAL_ERROR_PRONE_FLAGS)
-endif
-
 # For user / userdebug builds, strip the local variable table and the local variable
 # type table. This has no bearing on stack traces, but will leave less information
 # available via JDWP.
@@ -372,23 +369,7 @@
 LOCAL_DX_FLAGS := $(filter-out --multi-dex,$(LOCAL_DX_FLAGS)) --multi-dex
 endif
 
-ifneq ($(USE_D8_DESUGAR),true)
-my_desugaring :=
-ifndef LOCAL_IS_STATIC_JAVA_LIBRARY
-my_desugaring := true
-$(full_classes_desugar_jar): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
-$(full_classes_desugar_jar): $(LOCAL_FULL_CLASSES_JACOCO_JAR) $(full_java_header_libs) $(DESUGAR)
-	$(desugar-classes-jar)
-endif
-else
-my_desugaring :=
-endif
-
-ifndef my_desugaring
-full_classes_desugar_jar := $(LOCAL_FULL_CLASSES_JACOCO_JAR)
-endif
-
-full_classes_pre_proguard_jar := $(full_classes_desugar_jar)
+full_classes_pre_proguard_jar := $(LOCAL_FULL_CLASSES_JACOCO_JAR)
 
 # Keep a copy of the jar just before proguard processing.
 $(eval $(call copy-one-file,$(full_classes_pre_proguard_jar),$(intermediates.COMMON)/classes-pre-proguard.jar))
@@ -400,9 +381,10 @@
     $(error invalid value for LOCAL_PROGUARD_ENABLED: $(LOCAL_PROGUARD_ENABLED))
 endif
 proguard_dictionary := $(intermediates.COMMON)/proguard_dictionary
+proguard_configuration := $(intermediates.COMMON)/proguard_configuration
 
 # When an app contains references to APIs that are not in the SDK specified by
-# its LOCAL_SDK_VERSION for example added by support library or by runtime 
+# its LOCAL_SDK_VERSION for example added by support library or by runtime
 # classes added by desugar, we artifically raise the "SDK version" "linked" by
 # ProGuard, to
 # - suppress ProGuard warnings of referencing symbols unknown to the lower SDK version.
@@ -412,7 +394,7 @@
 ifdef LOCAL_SDK_VERSION
 ifdef TARGET_BUILD_APPS
 ifeq (,$(filter current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
-  my_proguard_sdk_raise := $(call java-lib-header-files, sdk_vcurrent)
+  my_proguard_sdk_raise := $(call java-lib-header-files, $(call resolve-prebuilt-sdk-module,current))
 endif
 else
   # For platform build, we can't just raise to the "current" SDK,
@@ -435,6 +417,7 @@
   $(filter-out $(my_proguard_sdk_raise),$(full_shared_java_header_libs))
 
 legacy_proguard_flags += -printmapping $(proguard_dictionary)
+legacy_proguard_flags += -printconfiguration $(proguard_configuration)
 
 common_proguard_flags := -forceprocessing
 
@@ -443,7 +426,7 @@
 common_proguard_flags += -dontshrink # don't shrink tests by default
 endif # test package
 ifneq ($(LOCAL_PROGUARD_ENABLED),custom)
-  ifdef LOCAL_USE_AAPT2
+  ifeq ($(LOCAL_USE_AAPT2),true)
     common_proguard_flag_files += $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES),\
         $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/export_proguard_flags)
   endif
@@ -491,9 +474,9 @@
 endif # LOCAL_INSTRUMENTATION_FOR
 
 proguard_flag_files := $(addprefix $(LOCAL_PATH)/, $(LOCAL_PROGUARD_FLAG_FILES))
-ifeq ($(USE_R8),true)
+ifeq ($(LOCAL_USE_R8),true)
 proguard_flag_files += $(addprefix $(LOCAL_PATH)/, $(LOCAL_R8_FLAG_FILES))
-endif # USE_R8
+endif # LOCAL_USE_R8
 LOCAL_PROGUARD_FLAGS += $(addprefix -include , $(proguard_flag_files))
 
 ifdef LOCAL_TEST_MODULE_TO_PROGUARD_WITH
@@ -503,25 +486,25 @@
 endif
 
 ifneq ($(filter obfuscation,$(LOCAL_PROGUARD_ENABLED)),)
-ifneq ($(USE_R8),true)
-  $(full_classes_proguard_jar): .KATI_IMPLICIT_OUTPUTS := $(proguard_dictionary)
+ifneq ($(LOCAL_USE_R8),true)
+  $(full_classes_proguard_jar): .KATI_IMPLICIT_OUTPUTS := $(proguard_dictionary) $(proguard_configuration)
 else
-  $(built_dex_intermediate): .KATI_IMPLICIT_OUTPUTS := $(proguard_dictionary)
+  $(built_dex_intermediate): .KATI_IMPLICIT_OUTPUTS := $(proguard_dictionary) $(proguard_configuration)
 endif
 endif
 
 # If R8 is not enabled run Proguard.
-ifneq ($(USE_R8),true)
+ifneq ($(LOCAL_USE_R8),true)
 # Changes to these dependencies need to be replicated below when using R8
 # instead of Proguard + dx.
 $(full_classes_proguard_jar): PRIVATE_EXTRA_INPUT_JAR := $(extra_input_jar)
 $(full_classes_proguard_jar): PRIVATE_PROGUARD_FLAGS := $(legacy_proguard_flags) $(common_proguard_flags) $(LOCAL_PROGUARD_FLAGS)
 $(full_classes_proguard_jar) : $(full_classes_pre_proguard_jar) $(extra_input_jar) $(my_proguard_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) $(legacy_proguard_lib_deps) | $(PROGUARD)
 	$(call transform-jar-to-proguard)
-else # !USE_R8
+else # !LOCAL_USE_R8
 # Running R8 instead of Proguard, proguarded jar is actually the pre-Proguarded jar.
 full_classes_proguard_jar := $(full_classes_pre_proguard_jar)
-endif # !USE_R8
+endif # !LOCAL_USE_R8
 
 else  # LOCAL_PROGUARD_ENABLED not defined
 proguard_flag_files :=
@@ -533,25 +516,21 @@
 
 my_r8 :=
 ifdef LOCAL_PROGUARD_ENABLED
-ifeq ($(USE_R8),true)
+ifeq ($(LOCAL_USE_R8),true)
 # These are the dependencies for the proguarded jar when running
 # Proguard + dx. They are used for the generated dex when using R8, as
 # R8 does Proguard + dx
 my_r8 := true
 $(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)
+$(built_dex_intermediate) : $(full_classes_proguard_jar) $(extra_input_jar) $(my_proguard_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) $(legacy_proguard_lib_deps) $(R8_COMPAT_PROGUARD)
 	$(transform-jar-to-dex-r8)
-endif # USE_R8
+endif # LOCAL_USE_R8
 endif # LOCAL_PROGUARD_ENABLED
 
 ifndef my_r8
 $(built_dex_intermediate): $(full_classes_proguard_jar) $(DX) $(ZIP2ZIP)
-ifneq ($(USE_D8_DESUGAR),true)
 	$(transform-classes.jar-to-dex)
-else
-	$(transform-classes-d8.jar-to-dex)
-endif
 endif
 
 ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),) # is_boot_jar
diff --git a/core/java_common.mk b/core/java_common.mk
index 2b85dc1..d63c15f 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -193,16 +193,25 @@
 
 annotation_processor_flags :=
 annotation_processor_deps :=
+annotation_processor_jars :=
+
+# If error prone is enabled then add LOCAL_ERROR_PRONE_FLAGS to LOCAL_JAVACFLAGS
+ifeq ($(RUN_ERROR_PRONE),true)
+annotation_processor_jars += $(ERROR_PRONE_JARS)
+LOCAL_JAVACFLAGS += $(ERROR_PRONE_FLAGS)
+LOCAL_JAVACFLAGS += '-Xplugin:ErrorProne $(ERROR_PRONE_CHECKS) $(LOCAL_ERROR_PRONE_FLAGS)'
+endif
 
 ifdef LOCAL_ANNOTATION_PROCESSORS
-  annotation_processor_jars := $(call java-lib-files,$(LOCAL_ANNOTATION_PROCESSORS),true)
-  annotation_processor_flags += -processorpath $(call normalize-path-list,$(annotation_processor_jars))
-  annotation_processor_deps += $(annotation_processor_jars)
+  annotation_processor_jars += $(call java-lib-files,$(LOCAL_ANNOTATION_PROCESSORS),true)
 
   # b/25860419: annotation processors must be explicitly specified for grok
   annotation_processor_flags += $(foreach class,$(LOCAL_ANNOTATION_PROCESSOR_CLASSES),-processor $(class))
+endif
 
-  annotation_processor_jars :=
+ifneq (,$(strip $(annotation_processor_jars)))
+annotation_processor_flags += -processorpath $(call normalize-path-list,$(annotation_processor_jars))
+annotation_processor_deps += $(annotation_processor_jars)
 endif
 
 full_static_java_libs := $(call java-lib-files,$(LOCAL_STATIC_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
@@ -225,11 +234,29 @@
 
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RMTYPEDEFS := $(LOCAL_RMTYPEDEFS)
 
+# Sanity check class path vars.
+disallowed_deps := $(foreach sdk,$(TARGET_AVAILABLE_SDK_VERSIONS),$(call resolve-prebuilt-sdk-module,$(sdk)))
+disallowed_deps += $(foreach sdk,$(TARGET_AVAILABLE_SDK_VERSIONS),\
+  $(foreach sdk_lib,$(JAVA_SDK_LIBRARIES),$(call resolve-prebuilt-sdk-module,$(sdk),$(sdk_lib))))
+bad_deps := $(filter $(disallowed_deps),$(LOCAL_JAVA_LIBRARIES) $(LOCAL_STATIC_JAVA_LIBRARIES))
+ifneq (,$(bad_deps))
+  $(call pretty-error,SDK modules should not be depended on directly. Please use LOCAL_SDK_VERSION for $(bad_deps))
+endif
+
 full_java_bootclasspath_libs :=
 empty_bootclasspath :=
 my_system_modules :=
+exported_sdk_libs_files :=
+my_exported_sdk_libs_file :=
 
 ifndef LOCAL_IS_HOST_MODULE
+  sdk_libs :=
+
+  # When an sdk lib name is listed in LOCAL_JAVA_LIBRARIES, move it to LOCAL_SDK_LIBRARIES, so that
+  # it is correctly redirected to the stubs library.
+  LOCAL_SDK_LIBRARIES += $(filter $(JAVA_SDK_LIBRARIES),$(LOCAL_JAVA_LIBRARIES))
+  LOCAL_JAVA_LIBRARIES := $(filter-out $(JAVA_SDK_LIBRARIES),$(LOCAL_JAVA_LIBRARIES))
+
   ifeq ($(LOCAL_SDK_VERSION),)
     ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
       # No bootclasspath. But we still need "" to prevent javac from using default host bootclasspath.
@@ -243,6 +270,13 @@
       LOCAL_JAVA_LIBRARIES := $(filter-out $(TARGET_DEFAULT_BOOTCLASSPATH_LIBRARIES) $(TARGET_DEFAULT_JAVA_LIBRARIES),$(LOCAL_JAVA_LIBRARIES))
       my_system_modules := $(DEFAULT_SYSTEM_MODULES)
     endif  # LOCAL_NO_STANDARD_LIBRARIES
+
+    ifneq (,$(TARGET_BUILD_APPS))
+      sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(call resolve-prebuilt-sdk-module,system_current,$(lib_name)))
+    else
+      # When SDK libraries are referenced from modules built without SDK, provide the all APIs to them
+      sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(lib_name).impl)
+    endif
   else
     ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
       $(call pretty-error,Must not define both LOCAL_NO_STANDARD_LIBRARIES and LOCAL_SDK_VERSION)
@@ -251,22 +285,30 @@
       $(call pretty-error,Invalid LOCAL_SDK_VERSION '$(LOCAL_SDK_VERSION)' \
              Choices are: $(TARGET_AVAILABLE_SDK_VERSIONS))
     endif
-    ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),current)
-      # LOCAL_SDK_VERSION is current and no TARGET_BUILD_APPS.
-      full_java_bootclasspath_libs := $(call java-lib-header-files,android_stubs_current)
-    else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),system_current)
-      full_java_bootclasspath_libs := $(call java-lib-header-files,android_system_stubs_current)
-    else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),test_current)
-      full_java_bootclasspath_libs := $(call java-lib-header-files,android_test_stubs_current)
-    else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),core_current)
-      full_java_bootclasspath_libs := $(call java-lib-header-files,core.current.stubs)
+
+    ifneq (,$(TARGET_BUILD_APPS)$(filter-out %current,$(LOCAL_SDK_VERSION)))
+      # TARGET_BUILD_APPS mode or numbered SDK. Use prebuilt modules.
+      sdk_module := $(call resolve-prebuilt-sdk-module,$(LOCAL_SDK_VERSION))
+      sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(call resolve-prebuilt-sdk-module,$(LOCAL_SDK_VERSION),$(lib_name)))
     else
-      # core_<ver> is subset of <ver>. Instead of defining a prebuilt lib for core_<ver>,
-      # use the stub for <ver> when building for apps.
-      _version := $(patsubst core_%,%,$(LOCAL_SDK_VERSION))
-      full_java_bootclasspath_libs := $(call java-lib-header-files,sdk_v$(_version))
-      _version :=
-    endif # current, system_current, system_${VER}, test_current or core_current
+      # Note: the lib naming scheme must be kept in sync with build/soong/java/sdk_library.go.
+      sdk_lib_suffix = $(call pretty-error,sdk_lib_suffix was not set correctly)
+      ifeq (current,$(LOCAL_SDK_VERSION))
+        sdk_module := android_stubs_current
+        sdk_lib_suffix := .stubs
+      else ifeq (system_current,$(LOCAL_SDK_VERSION))
+        sdk_module := android_system_stubs_current
+        sdk_lib_suffix := .stubs.system
+      else ifeq (test_current,$(LOCAL_SDK_VERSION))
+        sdk_module := android_test_stubs_current
+        sdk_lib_suffix := .stubs.test
+      else ifeq (core_current,$(LOCAL_SDK_VERSION))
+        sdk_module := core.current.stubs
+        sdk_lib_suffix = $(call pretty-error,LOCAL_SDK_LIBRARIES not supported for LOCAL_SDK_VERSION = core_current)
+      endif
+      sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(lib_name)$(sdk_lib_suffix))
+    endif
+    full_java_bootclasspath_libs := $(call java-lib-header-files,$(sdk_module))
   endif # LOCAL_SDK_VERSION
 
   ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
@@ -292,9 +334,16 @@
       full_java_bootclasspath_libs += $(call java-lib-header-files,core-lambda-stubs)
     endif
   endif
+  full_shared_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES) $(sdk_libs),$(LOCAL_IS_HOST_MODULE))
+  full_shared_java_header_libs := $(call java-lib-header-files,$(LOCAL_JAVA_LIBRARIES) $(sdk_libs),$(LOCAL_IS_HOST_MODULE))
+  sdk_libs :=
 
-  full_shared_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
-  full_shared_java_header_libs := $(call java-lib-header-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+  # Files that contains the names of SDK libraries exported from dependencies. These will be re-exported.
+  # Note: No need to consider LOCAL_*_ANDROID_LIBRARIES and LOCAL_STATIC_JAVA_AAR_LIBRARIES. They are all appended to
+  # LOCAL_*_JAVA_LIBRARIES in java.mk
+  exported_sdk_libs_files := $(call exported-sdk-libs-files,$(LOCAL_JAVA_LIBRARIES) $(LOCAL_STATIC_JAVA_LIBRARIES))
+  # The file that contains the names of all SDK libraries that this module exports and re-exports
+  my_exported_sdk_libs_file := $(call local-intermediates-dir,COMMON)/exported-sdk-libs
 
 else # LOCAL_IS_HOST_MODULE
 
@@ -332,6 +381,22 @@
   endif # USE_CORE_LIB_BOOTCLASSPATH
 endif # !LOCAL_IS_HOST_MODULE
 
+
+# Export the SDK libs. The sdk library names listed in LOCAL_SDK_LIBRARIES are first exported.
+# Then sdk library names exported from dependencies are all re-exported.
+$(my_exported_sdk_libs_file): PRIVATE_EXPORTED_SDK_LIBS_FILES := $(exported_sdk_libs_files)
+$(my_exported_sdk_libs_file): PRIVATE_SDK_LIBS := $(sort $(LOCAL_SDK_LIBRARIES))
+$(my_exported_sdk_libs_file): $(exported_sdk_libs_files)
+	@echo "Export SDK libs $@"
+	$(hide) mkdir -p $(dir $@) && rm -f $@ $@.temp
+	$(if $(PRIVATE_SDK_LIBS),\
+		echo $(PRIVATE_SDK_LIBS) | tr ' ' '\n' > $@.temp,\
+		touch $@.temp)
+	$(if $(PRIVATE_EXPORTED_SDK_LIBS_FILES),\
+		cat $(PRIVATE_EXPORTED_SDK_LIBS_FILES) >> $@.temp)
+	$(hide) cat $@.temp | sort -u > $@
+	$(hide) rm -f $@.temp
+
 ifdef empty_bootclasspath
   ifdef full_java_bootclasspath_libs
     $(call pretty-error,internal error: empty_bootclasspath and full_java_bootclasspath_libs should not both be set)
@@ -451,7 +516,7 @@
 ifdef LOCAL_AAPT2_ONLY
 my_link_type += aapt2_only
 endif
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
 my_allowed_types += aapt2_only
 endif
 
diff --git a/core/java_renderscript.mk b/core/java_renderscript.mk
index 191b3be..d7dd4ed 100644
--- a/core/java_renderscript.mk
+++ b/core/java_renderscript.mk
@@ -75,7 +75,7 @@
 $(rs_generated_src_jar): PRIVATE_RS_FLAGS := $(renderscript_flags)
 $(rs_generated_src_jar): PRIVATE_RS_SOURCE_FILES := $(renderscript_sources_fullpath)
 $(rs_generated_src_jar): PRIVATE_RS_OUTPUT_DIR := $(renderscript_intermediate.COMMON)
-$(rs_generated_src_jar): PRIVATE_RS_TARGET_API := $(renderscript_target_api)
+$(rs_generated_src_jar): PRIVATE_RS_TARGET_API := $(patsubst current,0,$(renderscript_target_api))
 $(rs_generated_src_jar): PRIVATE_DEP_FILES := $(bc_dep_files)
 $(rs_generated_src_jar): PRIVATE_RS_OUTPUT_RES_ZIP := $(rs_generated_res_zip)
 $(rs_generated_src_jar): .KATI_IMPLICIT_OUTPUTS := $(rs_generated_res_zip)
diff --git a/core/main.mk b/core/main.mk
index 1946edb..226afbc 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -26,6 +26,8 @@
 
 else # KATI
 
+$(info [1/1] initializing build system ...)
+
 # Absolute path of the present working direcotry.
 # This overrides the shell variable $PWD, which does not necessarily points to
 # the top of the source tree, for example when "make -C" is used in m/mm/mmm.
@@ -233,6 +235,8 @@
 ADDITIONAL_DEFAULT_PROPERTIES += ro.actionable_compatible_property.enabled=${PRODUCT_COMPATIBLE_PROPERTY}
 endif
 
+ADDITIONAL_BUILD_PROPERTIES += ro.boot.logical_partitions=${USE_LOGICAL_PARTITIONS}
+
 # -----------------------------------------------------------------
 ###
 ### In this section we set up the things that are different
@@ -327,6 +331,15 @@
 endif
 endif
 
+## asan ##
+
+# Install some additional tools on ASAN builds IFF we are also installing debug tools
+ifneq ($(filter address,$(SANITIZE_TARGET)),)
+ifneq (,$(filter debug,$(tags_to_install)))
+  tags_to_install += asan
+endif
+endif
+
 ## sdk ##
 
 ifdef is_sdk_build
@@ -354,10 +367,6 @@
 
 ADDITIONAL_BUILD_PROPERTIES += net.bt.name=Android
 
-# Sets the location that the runtime dumps stack traces to when signalled
-# with SIGQUIT. Stack trace dumping is turned on for all android builds.
-ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.stack-trace-dir=/data/anr
-
 # ------------------------------------------------------------
 # Define a function that, given a list of module tags, returns
 # non-empty if that module should be installed in /system.
@@ -402,6 +411,8 @@
 ENFORCE_RRO_SOURCES :=
 endif
 
+subdir_makefiles_inc := .
+
 ifneq ($(ONE_SHOT_MAKEFILE),)
 # We've probably been invoked by the "mm" shell function
 # with a subdirectory's makefile.
@@ -413,10 +424,6 @@
 # would have been with a normal make.
 CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS)))
 FULL_BUILD :=
-# Stub out the notice targets, which probably aren't defined
-# when using ONE_SHOT_MAKEFILE.
-NOTICE-HOST-%: ;
-NOTICE-TARGET-%: ;
 
 # A helper goal printing out install paths
 define register_module_install_path
@@ -450,7 +457,7 @@
 #
 
 subdir_makefiles := $(SOONG_ANDROID_MK) $(file <$(OUT_DIR)/.module_paths/Android.mk.list)
-subdir_makefiles_total := $(words $(subdir_makefiles))
+subdir_makefiles_total := $(words int $(subdir_makefiles) post finish)
 .KATI_READONLY := subdir_makefiles_total
 
 $(foreach mk,$(subdir_makefiles),$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] including $(mk) ...)$(eval include $(mk)))
@@ -466,6 +473,12 @@
 
 endif # ONE_SHOT_MAKEFILE
 
+ifndef subdir_makefiles_total
+subdir_makefiles_total := $(words init post finish)
+endif
+
+$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] finishing build rules ...)
+
 # -------------------------------------------------------------------
 # All module makefiles have been included at this point.
 # -------------------------------------------------------------------
@@ -886,47 +899,74 @@
 # $(2): The initial module name list.
 # Returns empty string (maybe with some whitespaces).
 define expand-required-modules
-$(eval _erm_new_modules := $(sort $(filter-out $($(1)),\
-  $(foreach m,$(2),$(ALL_MODULES.$(m).REQUIRED)))))\
+$(eval _erm_req := $(foreach m,$(2),$(ALL_MODULES.$(m).REQUIRED))) \
+$(eval _erm_new_modules := $(sort $(filter-out $($(1)),$(_erm_req))))\
 $(if $(_erm_new_modules),$(eval $(1) += $(_erm_new_modules))\
   $(call expand-required-modules,$(1),$(_erm_new_modules)))
 endef
 
-ifdef FULL_BUILD
-  # The base list of modules to build for this product is specified
-  # by the appropriate product definition file, which was included
-  # by product_config.mk.
-  product_MODULES := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES)
-ifdef BOARD_VNDK_VERSION
-  product_MODULES += vndk_package
+# Determines the files a particular product installs.
+# The base list of modules to build for this product is specified
+# by the appropriate product definition file, which was included
+# by product_config.mk.
+# Name resolution for PRODUCT_PACKAGES:
+#   foo:32 resolves to foo_32;
+#   foo:64 resolves to foo;
+#   foo resolves to both foo and foo_32 (if foo_32 is defined).
+#
+# Name resolution for LOCAL_REQUIRED_MODULES:
+#   If a module is built for 2nd arch, its required module resolves to
+#   32-bit variant, if it exits. See the select-bitness-of-required-modules definition.
+# $(1): product makefile
+define product-installed-files
+  $(eval _pif_modules := $(PRODUCTS.$(strip $(1)).PRODUCT_PACKAGES)) \
+  $(if $(BOARD_VNDK_VERSION),$(eval _pif_modules += vndk_package)) \
+  $(eval ### Filter out the overridden packages and executables before doing expansion) \
+  $(eval _pif_overrides := $(foreach p, $(_pif_modules), $(PACKAGES.$(p).OVERRIDES))) \
+  $(eval _pif_overrides += $(foreach m, $(_pif_modules), $(EXECUTABLES.$(m).OVERRIDES))) \
+  $(eval _pif_modules := $(filter-out $(_pif_overrides), $(_pif_modules))) \
+  $(eval ### Resolve the :32 :64 module name) \
+  $(eval _pif_modules_32 := $(patsubst %:32,%,$(filter %:32, $(_pif_modules)))) \
+  $(eval _pif_modules_64 := $(patsubst %:64,%,$(filter %:64, $(_pif_modules)))) \
+  $(eval _pif_modules_rest := $(filter-out %:32 %:64,$(_pif_modules))) \
+  $(eval ### Note for 32-bit product, 32 and 64 will be added as their original module names.) \
+  $(eval _pif_modules := $(call get-32-bit-modules-if-we-can, $(_pif_modules_32))) \
+  $(eval _pif_modules += $(_pif_modules_64)) \
+  $(eval ### For the rest we add both) \
+  $(eval _pif_modules += $(call get-32-bit-modules, $(_pif_modules_rest))) \
+  $(eval _pif_modules += $(_pif_modules_rest)) \
+  $(call expand-required-modules,_pif_modules,$(_pif_modules)) \
+  $(call module-installed-files, $(_pif_modules))
+endef
+
+# Fails the build if the given list is non-empty, and prints it entries (stripping PRODUCT_OUT).
+# $(1): list of files to print
+# $(2): heading to print on failure
+define maybe-print-list-and-error
+$(if $(strip $(1)), \
+  $(warning $(2)) \
+  $(info Offending entries:) \
+  $(foreach e,$(sort $(1)),$(info    $(patsubst $(PRODUCT_OUT)/%,%,$(e)))) \
+  $(error Build failed) \
+)
+endef
+
+ifeq (true|,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_PACKAGES_EXIST)|$(filter true,$(ALLOW_MISSING_DEPENDENCIES)))
+  _whitelist := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_PACKAGES_EXIST_WHITELIST)
+  _modules := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES)
+  # Sanity check all modules in PRODUCT_PACKAGES exist. We check for the
+  # existence if either <module> or the <module>_32 variant.
+  _nonexistant_modules := $(filter-out $(ALL_MODULES),$(_modules))
+  _nonexistant_modules := $(foreach m,$(_nonexistant_modules),\
+    $(if $(call get-32-bit-modules,$(m)),,$(m)))
+  $(call maybe-print-list-and-error,$(filter-out $(_whitelist),$(_nonexistant_modules)),\
+    $(INTERNAL_PRODUCT) includes non-existant modules in PRODUCT_PACKAGES)
+  $(call maybe-print-list-and-error,$(filter-out $(_nonexistant_modules),$(_whitelist)),\
+    $(INTERNAL_PRODUCT) includes redundant whitelist entries for nonexistant PRODUCT_PACKAGES)
 endif
-  # Filter out the overridden packages before doing expansion
-  product_MODULES := $(filter-out $(foreach p, $(product_MODULES), \
-      $(PACKAGES.$(p).OVERRIDES)), $(product_MODULES))
-  # Filter out executables as well
-  product_MODULES := $(filter-out $(foreach m, $(product_MODULES), \
-      $(EXECUTABLES.$(m).OVERRIDES)), $(product_MODULES))
 
-  # Resolve the :32 :64 module name
-  modules_32 := $(patsubst %:32,%,$(filter %:32, $(product_MODULES)))
-  modules_64 := $(patsubst %:64,%,$(filter %:64, $(product_MODULES)))
-  modules_rest := $(filter-out %:32 %:64,$(product_MODULES))
-  # Note for 32-bit product, $(modules_32) and $(modules_64) will be
-  # added as their original module names.
-  product_MODULES := $(call get-32-bit-modules-if-we-can, $(modules_32))
-  product_MODULES += $(modules_64)
-  # For the rest we add both
-  product_MODULES += $(call get-32-bit-modules, $(modules_rest))
-  product_MODULES += $(modules_rest)
-
-  $(call expand-required-modules,product_MODULES,$(product_MODULES))
-
-  product_FILES := $(call module-installed-files, $(product_MODULES))
-  ifeq (0,1)
-    $(info product_FILES for $(TARGET_DEVICE) ($(INTERNAL_PRODUCT)):)
-    $(foreach p,$(product_FILES),$(info :   $(p)))
-    $(error done)
-  endif
+ifdef FULL_BUILD
+  product_FILES := $(call product-installed-files, $(INTERNAL_PRODUCT))
 else
   # We're not doing a full build, and are probably only including
   # a subset of the module makefiles.  Don't try to build any modules
@@ -935,6 +975,49 @@
   product_FILES :=
 endif
 
+# Transforms paths relative to PRODUCT_OUT to absolute paths.
+# $(1): list of relative paths
+# $(2): optional suffix to append to paths
+define resolve-product-relative-paths
+  $(subst $(_vendor_path_placeholder),$(TARGET_COPY_OUT_VENDOR),\
+    $(subst $(_product_path_placeholder),$(TARGET_COPY_OUT_PRODUCT),\
+      $(foreach p,$(1),$(PRODUCT_OUT)/$(p)$(2))))
+endef
+
+# Verify the artifact path requirements made by included products.
+$(foreach makefile,$(ARTIFACT_PATH_REQUIREMENT_PRODUCTS),\
+  $(eval requirements := $(PRODUCTS.$(makefile).ARTIFACT_PATH_REQUIREMENTS)) \
+  $(eval ### Verify that the product only produces files inside its path requirements.) \
+  $(eval whitelist := $(PRODUCTS.$(makefile).ARTIFACT_PATH_WHITELIST)) \
+  $(eval path_patterns := $(call resolve-product-relative-paths,$(requirements),%)) \
+  $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \
+  $(eval files := $(call product-installed-files, $(makefile))) \
+  $(eval files += $(foreach cf,$(PRODUCTS.$(makefile).PRODUCT_COPY_FILES),\
+    $(call append-path,$(PRODUCT_OUT),$(call word-colon,2,$(cf))))) \
+  $(eval files := $(filter-out $(TARGET_OUT_FAKE)/% $(HOST_OUT)/%,$(files))) \
+  $(eval offending_files := $(filter-out $(path_patterns) $(whitelist_patterns),$(files))) \
+  $(call maybe-print-list-and-error,$(offending_files),$(makefile) produces files outside its artifact path requirement.) \
+  $(eval unused_whitelist := $(filter-out $(files),$(whitelist_patterns))) \
+  $(call maybe-print-list-and-error,$(unused_whitelist),$(makefile) includes redundant whitelist entries in its artifact path requirement.) \
+  $(eval ### Optionally verify that nothing else produces files inside this artifact path requirement.) \
+  $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS),\
+    $(eval extra_files := $(filter-out $(files) $(HOST_OUT)/%,$(product_FILES))) \
+    $(eval whitelist := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST)) \
+    $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \
+    $(eval files_in_requirement := $(filter $(path_patterns),$(extra_files))) \
+    $(eval offending_files := $(filter-out $(whitelist_patterns),$(files_in_requirement))) \
+    $(call maybe-print-list-and-error,$(offending_files),$(INTERNAL_PRODUCT) produces files inside $(makefile)s artifact path requirement.) \
+    $(eval unused_whitelist := $(filter-out $(extra_files),$(whitelist_patterns))) \
+    $(call maybe-print-list-and-error,$(unused_whitelist),$(INTERNAL_PRODUCT) includes redundant artifact path requirement whitelist entries.) \
+  ) \
+)
+
+ifeq (0,1)
+  $(info product_FILES for $(TARGET_DEVICE) ($(INTERNAL_PRODUCT)):)
+  $(foreach p,$(product_FILES),$(info :   $(p)))
+  $(error done)
+endif
+
 eng_MODULES := $(sort \
         $(call get-tagged-modules,eng) \
         $(call module-installed-files, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES_ENG)) \
@@ -947,6 +1030,9 @@
         $(call get-tagged-modules,tests) \
         $(call module-installed-files, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES_TESTS)) \
     )
+asan_MODULES := $(sort \
+        $(call module-installed-files, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES_DEBUG_ASAN)) \
+    )
 
 # TODO: Remove the 3 places in the tree that use ALL_DEFAULT_INSTALLED_MODULES
 # and get rid of it from this list.
@@ -1107,21 +1193,25 @@
 # Build files and then package it into the rom formats
 .PHONY: droidcore
 droidcore: files \
-	systemimage \
-	$(INSTALLED_BOOTIMAGE_TARGET) \
-	$(INSTALLED_RECOVERYIMAGE_TARGET) \
-	$(INSTALLED_VBMETAIMAGE_TARGET) \
-	$(INSTALLED_USERDATAIMAGE_TARGET) \
-	$(INSTALLED_CACHEIMAGE_TARGET) \
-	$(INSTALLED_BPTIMAGE_TARGET) \
-	$(INSTALLED_VENDORIMAGE_TARGET) \
-	$(INSTALLED_PRODUCTIMAGE_TARGET) \
-	$(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
-	$(INSTALLED_FILES_FILE) \
-	$(INSTALLED_FILES_FILE_VENDOR) \
-	$(INSTALLED_FILES_FILE_PRODUCT) \
-	$(INSTALLED_FILES_FILE_SYSTEMOTHER) \
-	soong_docs
+    systemimage \
+    $(INSTALLED_BOOTIMAGE_TARGET) \
+    $(INSTALLED_RECOVERYIMAGE_TARGET) \
+    $(INSTALLED_VBMETAIMAGE_TARGET) \
+    $(INSTALLED_USERDATAIMAGE_TARGET) \
+    $(INSTALLED_CACHEIMAGE_TARGET) \
+    $(INSTALLED_BPTIMAGE_TARGET) \
+    $(INSTALLED_VENDORIMAGE_TARGET) \
+    $(INSTALLED_PRODUCTIMAGE_TARGET) \
+    $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
+    $(INSTALLED_FILES_FILE) \
+    $(INSTALLED_FILES_JSON) \
+    $(INSTALLED_FILES_FILE_VENDOR) \
+    $(INSTALLED_FILES_JSON_VENDOR) \
+    $(INSTALLED_FILES_FILE_PRODUCT) \
+    $(INSTALLED_FILES_JSON_PRODUCT) \
+    $(INSTALLED_FILES_FILE_SYSTEMOTHER) \
+    $(INSTALLED_FILES_JSON_SYSTEMOTHER) \
+    soong_docs
 
 # dist_files only for putting your library into the dist directory with a full build.
 .PHONY: dist_files
@@ -1184,9 +1274,13 @@
     $(SYMBOLS_ZIP) \
     $(COVERAGE_ZIP) \
     $(INSTALLED_FILES_FILE) \
+    $(INSTALLED_FILES_JSON) \
     $(INSTALLED_FILES_FILE_VENDOR) \
+    $(INSTALLED_FILES_JSON_VENDOR) \
     $(INSTALLED_FILES_FILE_PRODUCT) \
+    $(INSTALLED_FILES_JSON_PRODUCT) \
     $(INSTALLED_FILES_FILE_SYSTEMOTHER) \
+    $(INSTALLED_FILES_JSON_SYSTEMOTHER) \
     $(INSTALLED_BUILD_PROP_TARGET) \
     $(BUILT_TARGET_FILES_PACKAGE) \
     $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
@@ -1207,14 +1301,51 @@
   endif
   endif
 
+  ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+    $(call dist-for-goals, droidcore, \
+      $(INSTALLED_FILES_FILE_ROOT) \
+      $(INSTALLED_FILES_JSON_ROOT) \
+    )
+  endif
+
   ifeq ($(EMMA_INSTRUMENT),true)
     $(JACOCO_REPORT_CLASSES_ALL) : $(INSTALLED_SYSTEMIMAGE)
     $(call dist-for-goals, dist_files, $(JACOCO_REPORT_CLASSES_ALL))
+
+    # Put XML formatted API files in the dist dir.
+    api_xmls := $(addprefix $(TARGET_OUT_COMMON_INTERMEDIATES)/,api.xml system-api.xml test-api.xml)
+    $(api_xmls): $(TARGET_OUT_COMMON_INTERMEDIATES)/%api.xml : frameworks/base/api/%current.txt $(APICHECK)
+	$(hide) echo "Converting API file to XML: $@"
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(APICHECK_COMMAND) -convert2xml $< $@
+
+    $(call dist-for-goals, dist_files, $(api_xmls))
+    api_xmls :=
   endif
 
 # Building a full system-- the default is to build droidcore
 droid_targets: droidcore dist_files
 
+ifdef USE_LOGICAL_PARTITIONS
+ifdef BOARD_SUPER_PARTITION_SIZE
+ifdef BOARD_SUPER_PARTITION_PARTITION_LIST
+
+droid_targets: check_android_partition_sizes
+
+.PHONY: check_android_partition_sizes
+check_android_partition_sizes: partition_size_list=$(foreach p,$(BOARD_SUPER_PARTITION_PARTITION_LIST),$(BOARD_$(call to-upper,$(p))IMAGE_PARTITION_SIZE))
+check_android_partition_sizes: sum_sizes_expr=$(subst $(space),+,$(partition_size_list))
+check_android_partition_sizes:
+	if [ $$(( $(sum_sizes_expr) )) -gt $(BOARD_SUPER_PARTITION_SIZE) ]; then \
+		echo The sum of sizes of all logical partitions is larger than BOARD_SUPER_PARTITION_SIZE.; \
+		echo $(sum_sizes_expr) == $$(( $(sum_sizes_expr) )) '>' $(BOARD_SUPER_PARTITION_SIZE); \
+		exit 1; \
+	fi
+
+endif # BOARD_SUPER_PARTITION_PARTITION_LIST
+endif # BOARD_SUPER_PARTITION_SIZE
+endif # USE_LOGICAL_PARTITIONS
+
 endif # TARGET_BUILD_APPS
 
 .PHONY: docs
@@ -1288,4 +1419,6 @@
 ndk: $(SOONG_OUT_DIR)/ndk.timestamp
 .PHONY: ndk
 
+$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] writing build rules ...)
+
 endif # KATI
diff --git a/core/math.mk b/core/math.mk
index 44e03ce..ac3151e 100644
--- a/core/math.mk
+++ b/core/math.mk
@@ -15,44 +15,104 @@
 #
 
 ###########################################################
-# Basic math functions for positive integers <= 100
+# Basic math functions for non-negative integers <= 100
 #
 # (SDK versions for example)
 ###########################################################
-__MATH_NUMBERS :=  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 \
-                  21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
-                  41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
-                  61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
-                  81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
+__MATH_POS_NUMBERS :=  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 \
+                      21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
+                      41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
+                      61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
+                      81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
+__MATH_NUMBERS := 0 $(__MATH_POS_NUMBERS)
 
-# Returns true if $(1) is a positive integer <= 100, otherwise returns nothing.
+math-error = $(call pretty-error,$(1))
+math-expect :=
+math-expect-true :=
+math-expect :=
+math-expect-error :=
+
+# Run the math tests with:
+#  make -f ${ANDROID_BUILD_TOP}/build/make/core/math.mk RUN_MATH_TESTS=true
+#  $(get_build_var CKATI) -f ${ANDROID_BUILD_TOP}//build/make/core/math.mk RUN_MATH_TESTS=true
+ifdef RUN_MATH_TESTS
+  MATH_TEST_FAILURE :=
+  MATH_TEST_ERROR :=
+  math-error = $(if $(MATH_TEST_ERROR),,$(eval MATH_TEST_ERROR:=$(1)))
+  define math-expect
+    $(eval got:=$$$1) \
+    $(if $(subst $(got),,$(2))$(subst $(2),,$(got))$(MATH_TEST_ERROR), \
+      $(if $(MATH_TEST_ERROR),$(warning $(MATH_TEST_ERROR)),$(warning $$$1 '$(got)' != '$(2)')) \
+      $(eval MATH_TEST_FAILURE := true)) \
+    $(eval MATH_TEST_ERROR :=) \
+    $(eval got:=)
+  endef
+  math-expect-true = $(call math-expect,$(1),true)
+  math-expect-false = $(call math-expect,$(1),)
+
+  define math-expect-error
+    $(eval got:=$$$1) \
+    $(if $(subst $(MATH_TEST_ERROR),,$(2))$(subst $(2),,$(MATH_TEST_ERROR)), \
+      $(warning '$(MATH_TEST_ERROR)' != '$(2)') \
+      $(eval MATH_TEST_FAILURE := true)) \
+    $(eval MATH_TEST_ERROR :=) \
+    $(eval got:=)
+  endef
+endif
+
+# Returns true if $(1) is a non-negative integer <= 100, otherwise returns nothing.
 define math_is_number
 $(strip \
-  $(if $(1),,$(error Argument missing)) \
-  $(if $(word 2,$(1)),$(error Multiple words in a single argument: $(1))) \
+  $(if $(1),,$(call math-error,Argument missing)) \
+  $(if $(word 2,$(1)),$(call math-error,Multiple words in a single argument: $(1))) \
   $(if $(filter $(1),$(__MATH_NUMBERS)),true))
 endef
 
-#$(warning true == $(call math_is_number,2))
-#$(warning == $(call math_is_number,foo))
-#$(call math_is_number,1 2)
-#$(call math_is_number,no 2)
+define math_is_zero
+$(strip \
+  $(if $(word 2,$(1)),$(call math-error,Multiple words in a single argument: $(1))) \
+  $(if $(filter 0,$(1)),true))
+endef
+
+$(call math-expect-true,(call math_is_number,0))
+$(call math-expect-true,(call math_is_number,2))
+$(call math-expect-false,(call math_is_number,foo))
+$(call math-expect-false,(call math_is_number,-1))
+$(call math-expect-error,(call math_is_number,1 2),Multiple words in a single argument: 1 2)
+$(call math-expect-error,(call math_is_number,no 2),Multiple words in a single argument: no 2)
+
+$(call math-expect-true,(call math_is_zero,0))
+$(call math-expect-false,(call math_is_zero,1))
+$(call math-expect-false,(call math_is_zero,foo))
+$(call math-expect-error,(call math_is_zero,1 2),Multiple words in a single argument: 1 2)
+$(call math-expect-error,(call math_is_zero,no 2),Multiple words in a single argument: no 2)
 
 define _math_check_valid
-$(if $(call math_is_number,$(1)),,$(error Only positive integers <= 100 are supported (not $(1))))
+$(if $(call math_is_number,$(1)),,$(call math-error,Only non-negative integers <= 100 are supported (not $(1))))
 endef
 
+$(call math-expect,(call _math_check_valid,0))
+$(call math-expect,(call _math_check_valid,1))
+$(call math-expect,(call _math_check_valid,100))
+$(call math-expect-error,(call _math_check_valid,-1),Only non-negative integers <= 100 are supported (not -1))
+$(call math-expect-error,(call _math_check_valid,101),Only non-negative integers <= 100 are supported (not 101))
+$(call math-expect-error,(call _math_check_valid,),Argument missing)
+$(call math-expect-error,(call _math_check_valid,1 2),Multiple words in a single argument: 1 2)
+
 # return a list containing integers ranging from [$(1),$(2)]
 define int_range_list
-$(call _math_check_valid,$(1))$(call _math_check_valid,$(2))$(wordlist $(1),$(2),$(__MATH_NUMBERS))
+$(strip \
+  $(call _math_check_valid,$(1))$(call _math_check_valid,$(2)) \
+  $(if $(call math_is_zero,$(1)),0)\
+  $(wordlist $(if $(call math_is_zero,$(1)),1,$(1)),$(2),$(__MATH_POS_NUMBERS)))
 endef
 
-#$(call _math_check_valid,0)
-#$(call _math_check_valid,1)
-#$(call _math_check_valid,100)
-#$(call _math_check_valid,101)
-#$(call _math_check_valid,)
-#$(call _math_check_valid,1 2)
+$(call math-expect,(call int_range_list,0,1),0 1)
+$(call math-expect,(call int_range_list,1,1),1)
+$(call math-expect,(call int_range_list,1,2),1 2)
+$(call math-expect,(call int_range_list,2,1),)
+$(call math-expect-error,(call int_range_list,1,101),Only non-negative integers <= 100 are supported (not 101))
+
 
 # Returns the greater of $1 or $2.
 # If $1 or $2 is not a positive integer <= 100, then an error is generated.
@@ -61,12 +121,14 @@
   $(lastword $(filter $(1) $(2),$(__MATH_NUMBERS))))
 endef
 
-#$(call math_max)
-#$(call math_max,1)
-#$(call math_max,1 2,3)
-#$(warning 1 == $(call math_max,1,1))
-#$(warning 42 == $(call math_max,5,42))
-#$(warning 42 == $(call math_max,42,5))
+$(call math-expect-error,(call math_max),Argument missing)
+$(call math-expect-error,(call math_max,1),Argument missing)
+$(call math-expect-error,(call math_max,1 2,3),Multiple words in a single argument: 1 2)
+$(call math-expect,(call math_max,0,1),1)
+$(call math-expect,(call math_max,1,0),1)
+$(call math-expect,(call math_max,1,1),1)
+$(call math-expect,(call math_max,5,42),42)
+$(call math-expect,(call math_max,42,5),42)
 
 define math_gt_or_eq
 $(if $(filter $(1),$(call math_max,$(1),$(2))),true)
@@ -76,15 +138,23 @@
 $(if $(call math_gt_or_eq,$(1),$(2)),,true)
 endef
 
-#$(warning $(call math_gt_or_eq, 2, 1))
-#$(warning $(call math_gt_or_eq, 1, 1))
-#$(warning $(if $(call math_gt_or_eq, 1, 2),false,true))
+$(call math-expect-true,(call math_gt_or_eq, 2, 1))
+$(call math-expect-true,(call math_gt_or_eq, 1, 1))
+$(call math-expect-false,(call math_gt_or_eq, 1, 2))
 
 # $1 is the variable name to increment
 define inc_and_print
 $(strip $(eval $(1) := $($(1)) .)$(words $($(1))))
 endef
 
+ifdef RUN_MATH_TESTS
+a :=
+$(call math-expect,(call inc_and_print,a),1)
+$(call math-expect,(call inc_and_print,a),2)
+$(call math-expect,(call inc_and_print,a),3)
+$(call math-expect,(call inc_and_print,a),4)
+endif
+
 # Returns the words in $2 that are numbers and are less than $1
 define numbers_less_than
 $(strip \
@@ -94,12 +164,19 @@
         $(n)))))
 endef
 
+$(call math-expect,(call numbers_less_than,0,0 1 2 3),)
+$(call math-expect,(call numbers_less_than,1,0 2 1 3),0)
+$(call math-expect,(call numbers_less_than,2,0 2 1 3),0 1)
+$(call math-expect,(call numbers_less_than,3,0 2 1 3),0 2 1)
+$(call math-expect,(call numbers_less_than,4,0 2 1 3),0 2 1 3)
+$(call math-expect,(call numbers_less_than,3,0 2 1 3 2),0 2 1 2)
+
 _INT_LIMIT_WORDS := $(foreach a,x x,$(foreach b,x x x x x x x x x x x x x x x x,\
   $(foreach c,x x x x x x x x x x x x x x x x,x x x x x x x x x x x x x x x x)))
 
 define _int_encode
 $(if $(filter $(words x $(_INT_LIMIT_WORDS)),$(words $(wordlist 1,$(1),x $(_INT_LIMIT_WORDS)))),\
-  $(call pretty-error,integer greater than $(words $(_INT_LIMIT_WORDS)) is not supported!),\
+  $(call math-error,integer greater than $(words $(_INT_LIMIT_WORDS)) is not supported!),\
     $(wordlist 1,$(1),$(_INT_LIMIT_WORDS)))
 endef
 
@@ -135,18 +212,59 @@
 $(words $(call _int_encode,$(1)) $(call _int_encode,$(2)))
 endef
 
+$(call math-expect,(call int_plus,0,0),0)
+$(call math-expect,(call int_plus,0,1),1)
+$(call math-expect,(call int_plus,1,0),1)
+$(call math-expect,(call int_plus,1,100),101)
+$(call math-expect,(call int_plus,100,100),200)
+
 define int_subtract
-$(if $(call _int_greater-or-equal,$(call _int_encode,$(1)),$(call _int_encode,$(2))),\
+$(strip \
+  $(if $(call _int_greater-or-equal,$(call _int_encode,$(1)),$(call _int_encode,$(2))),\
   $(words $(filter-out xx,$(join $(call _int_encode,$(1)),$(call _int_encode,$(2))))),\
-    $(call pretty-error,$(1) subtract underflow $(2)))
+    $(call math-error,subtract underflow $(1) - $(2))))
 endef
 
+$(call math-expect,(call int_subtract,0,0),0)
+$(call math-expect,(call int_subtract,1,0),1)
+$(call math-expect,(call int_subtract,1,1),0)
+$(call math-expect,(call int_subtract,100,1),99)
+$(call math-expect,(call int_subtract,200,100),100)
+$(call math-expect-error,(call int_subtract,0,1),subtract underflow 0 - 1)
+
 define int_multiply
 $(words $(foreach a,$(call _int_encode,$(1)),$(call _int_encode,$(2))))
 endef
 
+$(call math-expect,(call int_multiply,0,0),0)
+$(call math-expect,(call int_multiply,1,0),0)
+$(call math-expect,(call int_multiply,1,1),1)
+$(call math-expect,(call int_multiply,100,1),100)
+$(call math-expect,(call int_multiply,1,100),100)
+$(call math-expect,(call int_multiply,4,100),400)
+$(call math-expect,(call int_multiply,100,4),400)
+
 define int_divide
-$(if $(filter 0,$(2)),$(call pretty-error,division by zero is not allowed!),$(strip \
+$(if $(filter 0,$(2)),$(call math-error,division by zero is not allowed!),$(strip \
   $(if $(call _int_greater-or-equal,$(call _int_encode,$(1)),$(call _int_encode,$(2))), \
     $(call int_plus,$(call int_divide,$(call int_subtract,$(1),$(2)),$(2)),1),0)))
 endef
+
+$(call math-expect,(call int_divide,1,1),1)
+$(call math-expect,(call int_divide,200,1),200)
+$(call math-expect,(call int_divide,200,3),66)
+$(call math-expect,(call int_divide,1,2),0)
+$(call math-expect-error,(call int_divide,0,0),division by zero is not allowed!)
+$(call math-expect-error,(call int_divide,1,0),division by zero is not allowed!)
+
+ifdef RUN_MATH_TESTS
+  ifdef MATH_TEST_FAILURE
+    math-tests:
+	@echo FAIL
+	@false
+  else
+    math-tests:
+	@echo PASS
+  endif
+  .PHONY: math-tests
+endif
diff --git a/core/native_benchmark_test_config_template.xml b/core/native_benchmark_test_config_template.xml
new file mode 100644
index 0000000..18736bf
--- /dev/null
+++ b/core/native_benchmark_test_config_template.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- This test config file is auto-generated. -->
+<configuration description="Runs {MODULE}.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native-metric" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
+        <option name="native-benchmark-device-path" value="/data/local/tmp" />
+        <option name="benchmark-module-name" value="{MODULE}" />
+    </test>
+</configuration>
diff --git a/core/notice_files.mk b/core/notice_files.mk
index 383d73c..08778c5 100644
--- a/core/notice_files.mk
+++ b/core/notice_files.mk
@@ -14,6 +14,11 @@
   notice_file :=
 endif
 
+ifeq ($(LOCAL_MODULE_CLASS),FAKE)
+  # We ignore NOTICE files for modules of type FAKE.
+  notice_file :=
+endif
+
 # Soong generates stub libraries that don't need NOTICE files
 ifdef LOCAL_NO_NOTICE_FILE
   ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
@@ -35,6 +40,10 @@
 
 ifdef notice_file
 
+ifdef my_register_name
+ALL_MODULES.$(my_register_name).NOTICES := $(ALL_MODULES.$(my_register_name).NOTICES) $(notice_file)
+endif
+
 # This relies on the name of the directory in PRODUCT_OUT matching where
 # it's installed on the target - i.e. system, data, etc.  This does
 # not work for root and isn't exact, but it's probably good enough for
diff --git a/core/pack_dyn_relocs_setup.mk b/core/pack_dyn_relocs_setup.mk
new file mode 100644
index 0000000..c5564b1
--- /dev/null
+++ b/core/pack_dyn_relocs_setup.mk
@@ -0,0 +1,34 @@
+#############################################################
+## Set up my_pack_module_relocations
+## Input variables:
+##   DISABLE_RELOCATION_PACKER,
+##   LOCAL_PACK_MODULE_RELOCATIONS*,
+##   *TARGET_PACK_MODULE_RELOCATIONS,
+##   LOCAL_MODULE_CLASS, HOST_OS
+##   LOCAL_IS_HOST_MODULE
+## Output variables:
+##   my_pack_module_relocations, if false skip relocation_packer
+#############################################################
+
+my_pack_module_relocations := false
+ifneq ($(DISABLE_RELOCATION_PACKER),true)
+  my_pack_module_relocations := $(firstword \
+    $(LOCAL_PACK_MODULE_RELOCATIONS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) \
+    $(LOCAL_PACK_MODULE_RELOCATIONS))
+endif
+
+ifeq ($(my_pack_module_relocations),)
+  my_pack_module_relocations := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_PACK_MODULE_RELOCATIONS)
+endif
+
+# Do not pack relocations for executables. Because packing results in
+# non-zero p_vaddr which causes kernel to load executables to lower
+# address (starting at 0x8000) http://b/20665974
+ifeq ($(filter SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
+  my_pack_module_relocations := false
+endif
+
+ifdef LOCAL_IS_HOST_MODULE
+  # Do not pack relocations on host modules
+  my_pack_module_relocations := false
+endif
diff --git a/core/package.mk b/core/package.mk
index f3713fc..854e009 100644
--- a/core/package.mk
+++ b/core/package.mk
@@ -8,7 +8,9 @@
 include $(BUILD_SYSTEM)/multilib.mk
 
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
-  ifneq ($(TARGET_SUPPORTS_64_BIT_APPS)|$(my_module_multilib),|64)
+  ifeq ($(TARGET_SUPPORTS_64_BIT_APPS),true)
+    my_module_multilib := first
+  else ifneq ($(my_module_multilib),64)
     my_module_multilib := first
   endif
 endif
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 80d386d..637a135 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -87,6 +87,11 @@
   LOCAL_RESOURCE_DIR := $(foreach d,$(LOCAL_RESOURCE_DIR),$(call clean-path,$(d)))
 endif
 
+include $(BUILD_SYSTEM)/force_aapt2.mk
+
+# Process Support Library dependencies.
+include $(BUILD_SYSTEM)/support_libraries.mk
+
 package_resource_overlays := $(strip \
     $(wildcard $(foreach dir, $(PRODUCT_PACKAGE_OVERLAYS), \
       $(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \
@@ -153,13 +158,13 @@
 endif
 
 my_res_package :=
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
 # In aapt2 the last takes precedence.
 my_resource_dirs := $(call reverse-list,$(LOCAL_RESOURCE_DIR))
 my_res_dir :=
 my_overlay_res_dirs :=
 
-ifneq ($(LOCAL_STATIC_ANDROID_LIBRARIES),)
+ifneq ($(strip $(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),)
 # If we are using static android libraries, every source file becomes an overlay.
 # This is to emulate old AAPT behavior which simulated library support.
 my_res_dir :=
@@ -314,9 +319,6 @@
 LOCAL_AAPT_FLAGS += --auto-add-overlay --extra-packages com.android.databinding.library
 endif  # LOCAL_DATA_BINDING
 
-# Process Support Library dependencies.
-include $(BUILD_SYSTEM)/support_libraries.mk
-
 # If the module is a compressed module, we don't pre-opt it because its final
 # installation location will be the data partition.
 ifdef LOCAL_COMPRESSED_MODULE
@@ -357,9 +359,9 @@
 ###############################
 ## AAPT/AAPT2
 
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
   my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res
-  ifneq (,$(renderscript_target_api))
+  ifneq (,$(filter-out current,$(renderscript_target_api)))
     ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
       my_generated_res_zips := $(rs_generated_res_zip)
     endif  # renderscript_target_api < 21
@@ -489,7 +491,7 @@
 else ifneq ($(filter-out current system_current test_current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_RES_VERSION))),)
 # for released sdk versions, the platform resources were built into android.jar.
 framework_res_package_export := \
-    $(HISTORICAL_SDK_VERSIONS_ROOT)/$(LOCAL_SDK_RES_VERSION)/android.jar
+    $(call resolve-prebuilt-sdk-jar-path,$(LOCAL_SDK_RES_VERSION))
 else # LOCAL_SDK_RES_VERSION
 framework_res_package_export := \
     $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk
@@ -509,7 +511,7 @@
 $(LOCAL_INTERMEDIATE_TARGETS): \
     PRIVATE_AAPT_INCLUDES := $(all_library_res_package_exports)
 
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
 $(my_res_package) : $(all_library_res_package_export_deps)
 endif
 
@@ -593,7 +595,7 @@
 $(LOCAL_BUILT_MODULE): PRIVATE_FULL_CLASSES_JAR := $(full_classes_jar)
 $(LOCAL_BUILT_MODULE) : $(jni_shared_libraries)
 $(LOCAL_BUILT_MODULE) : $(JAR_ARGS)
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
 $(LOCAL_BUILT_MODULE): PRIVATE_RES_PACKAGE := $(my_res_package)
 $(LOCAL_BUILT_MODULE) : $(my_res_package) $(AAPT2) | $(ACP)
 else
@@ -604,7 +606,7 @@
 $(LOCAL_BUILT_MODULE) : $(MINIGZIP)
 endif
 	@echo "target Package: $(PRIVATE_MODULE) ($@)"
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
 	$(call copy-file-to-new-target)
 else  # ! LOCAL_USE_AAPT2
 	$(if $(PRIVATE_SOURCE_ARCHIVE),\
@@ -620,7 +622,7 @@
 	$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call add-java-resources-to,$@))
 else  # full_classes_jar
 	$(add-dex-to-package)
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
 	$(call add-jar-resources-to-package,$@,$(PRIVATE_FULL_CLASSES_JAR),$(PRIVATE_RESOURCE_INTERMEDIATES_DIR))
 endif
 endif  # full_classes_jar
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 0efda57..f7394c2 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -6,14 +6,16 @@
 ##
 ###########################################################
 
+include $(BUILD_SYSTEM)/use_lld_setup.mk
+
 ifneq ($(LOCAL_PREBUILT_LIBS),)
-$(error dont use LOCAL_PREBUILT_LIBS anymore LOCAL_PATH=$(LOCAL_PATH))
+$(call pretty-error,dont use LOCAL_PREBUILT_LIBS anymore)
 endif
 ifneq ($(LOCAL_PREBUILT_EXECUTABLES),)
-$(error dont use LOCAL_PREBUILT_EXECUTABLES anymore LOCAL_PATH=$(LOCAL_PATH))
+$(call pretty-error,dont use LOCAL_PREBUILT_EXECUTABLES anymore)
 endif
 ifneq ($(LOCAL_PREBUILT_JAVA_LIBRARIES),)
-$(error dont use LOCAL_PREBUILT_JAVA_LIBRARIES anymore LOCAL_PATH=$(LOCAL_PATH))
+$(call pretty-error,dont use LOCAL_PREBUILT_JAVA_LIBRARIES anymore)
 endif
 
 my_32_64_bit_suffix := $(if $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)IS_64_BIT),64,32)
@@ -40,9 +42,6 @@
 my_strip_module := $(firstword \
   $(LOCAL_STRIP_MODULE_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) \
   $(LOCAL_STRIP_MODULE))
-my_pack_module_relocations := $(firstword \
-  $(LOCAL_PACK_MODULE_RELOCATIONS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) \
-  $(LOCAL_PACK_MODULE_RELOCATIONS))
 
 ifeq (SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS))
   # LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES indicates that this prebuilt should be
@@ -61,15 +60,6 @@
     # Strip but not try to add debuglink
     my_strip_module := no_debuglink
   endif
-
-  ifeq ($(LOCAL_IS_HOST_MODULE)$(my_pack_module_relocations),)
-    # Do not pack relocations by default
-    my_pack_module_relocations := false
-  endif
-
-  ifeq ($(DISABLE_RELOCATION_PACKER),true)
-    my_pack_module_relocations := false
-  endif
 endif
 
 ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
@@ -133,23 +123,22 @@
 endif  # LOCAL_COMPRESSED_MODULE
 endif
 
-ifneq ($(filter true keep_symbols no_debuglink mini-debug-info,$(my_strip_module) $(my_pack_module_relocations)),)
+ifneq ($(filter true keep_symbols no_debuglink mini-debug-info,$(my_strip_module)),)
   ifdef LOCAL_IS_HOST_MODULE
-    $(error Cannot strip/pack host module LOCAL_PATH=$(LOCAL_PATH))
+    $(call pretty-error,Cannot strip/pack host module)
   endif
   ifeq ($(filter SHARED_LIBRARIES EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
-    $(error Can strip/pack only shared libraries or executables LOCAL_PATH=$(LOCAL_PATH))
+    $(call pretty-error,Can strip/pack only shared libraries or executables)
   endif
   ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
-    $(error Cannot strip/pack scripts LOCAL_PATH=$(LOCAL_PATH))
+    $(call pretty-error,Cannot strip/pack scripts)
   endif
-  # Set the arch-specific variables to set up the strip/pack rules.
+  # Set the arch-specific variables to set up the strip rules
   LOCAL_STRIP_MODULE_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH) := $(my_strip_module)
-  LOCAL_PACK_MODULE_RELOCATIONS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH) := $(my_pack_module_relocations)
   include $(BUILD_SYSTEM)/dynamic_binary.mk
   built_module := $(linked_module)
 
-else  # my_strip_module and my_pack_module_relocations not true
+else  # my_strip_module not true
   include $(BUILD_SYSTEM)/base_rules.mk
   built_module := $(LOCAL_BUILT_MODULE)
 
@@ -500,10 +489,13 @@
 endif # LOCAL_DEX_PREOPT
 
 else  # ! prebuilt_module_is_dex_javalib
+ifneq ($(filter init%rc,$(notdir $(LOCAL_INSTALLED_MODULE)))$(filter %/etc/init,$(dir $(LOCAL_INSTALLED_MODULE))),)
+  $(eval $(call copy-init-script-file-checked,$(my_prebuilt_src_file),$(built_module)))
+else ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
 $(built_module) : $(my_prebuilt_src_file)
-ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
 	$(transform-prebuilt-to-target-strip-comments)
 else
+$(built_module) : $(my_prebuilt_src_file)
 	$(transform-prebuilt-to-target)
 endif
 ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
@@ -579,15 +571,24 @@
 
 my_src_jar := $(intermediates.COMMON)/aar/classes.jar
 my_src_proguard_options := $(intermediates.COMMON)/aar/proguard.txt
+my_src_android_manifest := $(intermediates.COMMON)/aar/AndroidManifest.xml
 
 $(my_src_jar) : .KATI_IMPLICIT_OUTPUTS := $(my_src_proguard_options)
+$(my_src_jar) : .KATI_IMPLICIT_OUTPUTS += $(my_src_android_manifest)
 $(my_src_jar) : $(my_src_aar)
 	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@) $(dir $@)/res
 	$(hide) unzip -qo -d $(dir $@) $<
 	# Make sure the extracted classes.jar has a new timestamp.
 	$(hide) touch $@
-	# Make sure the proguard file exists and has a new timestamp.
+	# Make sure the proguard and AndroidManifest.xml files exist
+	# and have a new timestamp.
 	$(hide) touch $(dir $@)/proguard.txt
+	$(hide) touch $(dir $@)/AndroidManifest.xml
+
+my_prebuilt_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
+$(eval $(call copy-one-file,$(my_src_android_manifest),$(my_prebuilt_android_manifest)))
+$(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_prebuilt_android_manifest))
+
 else
 
 # run Jetifier if needed
@@ -611,11 +612,13 @@
 $(common_javalib_jar) : $(common_classes_jar)
 	$(transform-prebuilt-to-target)
 
+include $(BUILD_SYSTEM)/force_aapt2.mk
+
 ifdef LOCAL_AAPT2_ONLY
 LOCAL_USE_AAPT2 := true
 endif
 
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
 ifneq ($(my_src_aar),)
 
 $(intermediates.COMMON)/export_proguard_flags : $(my_src_proguard_options)
@@ -631,7 +634,7 @@
 ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
 ifneq ($(filter-out current system_current test_current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_RES_VERSION))),)
 framework_res_package_export := \
-    $(HISTORICAL_SDK_VERSIONS_ROOT)/$(LOCAL_SDK_RES_VERSION)/android.jar
+    $(call resolve-prebuilt-sdk-jar-path,$(LOCAL_SDK_RES_VERSION))
 else
 framework_res_package_export := \
     $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk
@@ -643,7 +646,7 @@
 # We needed only very few PRIVATE variables and aapt2.mk input variables. Reset the unnecessary ones.
 $(my_res_package): PRIVATE_AAPT2_CFLAGS :=
 $(my_res_package): PRIVATE_AAPT_FLAGS := --static-lib --no-static-lib-packages --auto-add-overlay
-$(my_res_package): PRIVATE_ANDROID_MANIFEST := $(intermediates.COMMON)/aar/AndroidManifest.xml
+$(my_res_package): PRIVATE_ANDROID_MANIFEST := $(my_src_android_manifest)
 $(my_res_package): PRIVATE_AAPT_INCLUDES := $(framework_res_package_export)
 $(my_res_package): PRIVATE_SOURCE_INTERMEDIATES_DIR :=
 $(my_res_package): PRIVATE_PROGUARD_OPTIONS_FILE :=
@@ -653,6 +656,7 @@
 $(my_res_package): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
 $(my_res_package): PRIVATE_TARGET_AAPT_CHARACTERISTICS :=
 $(my_res_package) : $(framework_res_package_export)
+$(my_res_package) : $(my_src_android_manifest)
 
 full_android_manifest :=
 my_res_resources :=
@@ -671,6 +675,15 @@
 # make sure the classes.jar and javalib.jar are built before $(LOCAL_BUILT_MODULE)
 $(built_module) : $(common_javalib_jar)
 
+my_exported_sdk_libs_file := $(intermediates.COMMON)/exported-sdk-libs
+$(my_exported_sdk_libs_file): PRIVATE_EXPORTED_SDK_LIBS := $(LOCAL_EXPORT_SDK_LIBRARIES)
+$(my_exported_sdk_libs_file):
+	@echo "Export SDK libs $@"
+	$(hide) mkdir -p $(dir $@) && rm -f $@
+	$(if $(PRIVATE_EXPORTED_SDK_LIBS),\
+		$(hide) echo $(PRIVATE_EXPORTED_SDK_LIBS) | tr ' ' '\n' > $@,\
+		$(hide) touch $@)
+
 endif # ! prebuilt_module_is_dex_javalib
 endif # LOCAL_IS_HOST_MODULE is not set
 
diff --git a/core/product-graph.mk b/core/product-graph.mk
index 576d14d..4133bd9 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -18,7 +18,7 @@
 define gather-all-products
 $(sort $(foreach p, \
 	$(eval _all_products_visited := )
-  $(call all-products-inner, $(ALL_PRODUCTS)) \
+  $(call all-products-inner, $(PARENT_PRODUCT_FILES)) \
 	, $(if $(strip $(p)),$(strip $(p)),)) \
 )
 endef
@@ -49,7 +49,7 @@
 endif
 endif
 
-really_all_products := $(call gather-all-products)
+all_products := $(call gather-all-products)
 
 open_parethesis := (
 close_parenthesis := )
@@ -66,7 +66,7 @@
 
 endef
 
-$(products_graph): PRIVATE_PRODUCTS := $(really_all_products)
+$(products_graph): PRIVATE_PRODUCTS := $(all_products)
 $(products_graph): PRIVATE_PRODUCTS_FILTER := $(products_list)
 
 $(products_graph): $(this_makefile)
@@ -130,7 +130,7 @@
 endef
 
 product_debug_files:=
-$(foreach p,$(really_all_products), \
+$(foreach p,$(all_products), \
 			$(eval $(call transform-product-debug, $(p))) \
 			$(eval product_debug_files += $(call product-debug-filename, $(p))) \
    )
diff --git a/core/product.mk b/core/product.mk
index 899b806..51b376a 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -23,39 +23,77 @@
 # and the .mk suffix) of the product makefile, "<product_name>:" can be
 # omitted.
 
-# Search for AndroidProducts.mks in the given dir.
-# $(1): the path to the dir
-define _search-android-products-files-in-dir
-$(sort $(shell test -d $(1) && find -L $(1) \
-  -maxdepth 6 \
-  -name .git -prune \
-  -o -name AndroidProducts.mk -print))
-endef
-
 #
 # Returns the list of all AndroidProducts.mk files.
 # $(call ) isn't necessary.
 #
 define _find-android-products-files
-$(foreach d, device vendor product,$(call _search-android-products-files-in-dir,$(d))) \
+$(file <$(OUT_DIR)/.module_paths/AndroidProducts.mk.list) \
   $(SRC_TARGET_DIR)/product/AndroidProducts.mk
 endef
 
 #
+# For entries returned by get-product-makefiles, decode an entry to a short
+# product name. These either may be in the form of <name>:path/to/file.mk or
+# path/to/<name>.mk
+# $(1): The entry to decode
+#
+# Returns two words:
+#   <name> <file>
+#
+define _decode-product-name
+$(strip \
+  $(eval _cpm_words := $(subst :,$(space),$(1))) \
+  $(if $(word 2,$(_cpm_words)), \
+    $(wordlist 1,2,$(_cpm_words)), \
+    $(basename $(notdir $(1))) $(1)))
+endef
+
+#
+# Validates the new common lunch choices -- ensures that they're in an
+# appropriate form, and are paired with definitions of their products.
+# $(1): The new list of COMMON_LUNCH_CHOICES
+# $(2): The new list of PRODUCT_MAKEFILES
+#
+define _validate-common-lunch-choices
+$(strip $(foreach choice,$(1),\
+  $(eval _parts := $(subst -,$(space),$(choice))) \
+  $(if $(call math_lt,$(words $(_parts)),2), \
+    $(error $(LOCAL_DIR): $(choice): Invalid lunch choice)) \
+  $(if $(call math_gt_or_eq,$(words $(_parts)),4), \
+    $(error $(LOCAL_DIR): $(choice): Invalid lunch choice)) \
+  $(if $(filter-out eng userdebug user,$(word 2,$(_parts))), \
+    $(error $(LOCAL_DIR): $(choice): Invalid variant: $(word 2,$(_parts)))) \
+  $(if $(filter-out $(foreach p,$(2),$(call _decode-product-name,$(p))),$(word 1,$(_parts))), \
+    $(error $(LOCAL_DIR): $(word 1,$(_parts)): Product not defined in this file)) \
+  ))
+endef
+
+#
 # Returns the sorted concatenation of PRODUCT_MAKEFILES
 # variables set in the given AndroidProducts.mk files.
 # $(1): the list of AndroidProducts.mk files.
 #
+# As a side-effect, COMMON_LUNCH_CHOICES will be set to a
+# union of all of the COMMON_LUNCH_CHOICES definitions within
+# each AndroidProducts.mk file.
+#
 define get-product-makefiles
 $(sort \
+  $(eval _COMMON_LUNCH_CHOICES :=) \
   $(foreach f,$(1), \
     $(eval PRODUCT_MAKEFILES :=) \
+    $(eval COMMON_LUNCH_CHOICES :=) \
     $(eval LOCAL_DIR := $(patsubst %/,%,$(dir $(f)))) \
     $(eval include $(f)) \
+    $(call _validate-common-lunch-choices,$(COMMON_LUNCH_CHOICES),$(PRODUCT_MAKEFILES)) \
+    $(eval _COMMON_LUNCH_CHOICES += $(COMMON_LUNCH_CHOICES)) \
     $(PRODUCT_MAKEFILES) \
    ) \
   $(eval PRODUCT_MAKEFILES :=) \
   $(eval LOCAL_DIR :=) \
+  $(eval COMMON_LUNCH_CHOICES := $(sort $(_COMMON_LUNCH_CHOICES) $(LUNCH_MENU_CHOICES))) \
+  $(eval _COMMON_LUNCH_CHOICES :=) \
  )
 endef
 
@@ -81,6 +119,7 @@
     PRODUCT_AAPT_PREBUILT_DPI \
     PRODUCT_PACKAGES \
     PRODUCT_PACKAGES_DEBUG \
+    PRODUCT_PACKAGES_DEBUG_ASAN \
     PRODUCT_PACKAGES_ENG \
     PRODUCT_PACKAGES_TESTS \
     PRODUCT_DEVICE \
@@ -158,6 +197,9 @@
     PRODUCT_CFI_EXCLUDE_PATHS \
     PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE \
     PRODUCT_ACTIONABLE_COMPATIBLE_PROPERTY_DISABLE \
+    PRODUCT_USE_LOGICAL_PARTITIONS \
+    PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS \
+    PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST \
 
 define dump-product
 $(info ==== $(1) ====)\
@@ -173,10 +215,14 @@
 #
 # $(1): product to inherit
 #
-# Does three things:
+# To be called from product makefiles, and is later evaluated during the import-nodes
+# call below. It does three things:
 #  1. Inherits all of the variables from $1.
 #  2. Records the inheritance in the .INHERITS_FROM variable
-#  3. Records that we've visited this node, in ALL_PRODUCTS
+#  3. Records the calling makefile in PARENT_PRODUCT_FILES
+#
+# (2) and (3) can be used together to reconstruct the include hierarchy
+# See e.g. product-graph.mk for an example of this.
 #
 define inherit-product
   $(if $(findstring ../,$(1)),\
@@ -184,13 +230,32 @@
     $(eval np := $(strip $(1))))\
   $(foreach v,$(_product_var_list), \
       $(eval $(v) := $($(v)) $(INHERIT_TAG)$(np))) \
-  $(eval inherit_var := \
-      PRODUCTS.$(strip $(word 1,$(_include_stack))).INHERITS_FROM) \
+  $(eval current_mk := $(strip $(word 1,$(_include_stack)))) \
+  $(eval inherit_var := PRODUCTS.$(current_mk).INHERITS_FROM) \
   $(eval $(inherit_var) := $(sort $($(inherit_var)) $(np))) \
-  $(eval inherit_var:=) \
-  $(eval ALL_PRODUCTS := $(sort $(ALL_PRODUCTS) $(word 1,$(_include_stack))))
+  $(eval PARENT_PRODUCT_FILES := $(sort $(PARENT_PRODUCT_FILES) $(current_mk)))
 endef
 
+# Specifies a number of path prefixes, relative to PRODUCT_OUT, where the
+# product makefile hierarchy rooted in the current node places its artifacts.
+# Creating artifacts outside the specified paths will cause a build-time error.
+define require-artifacts-in-path
+  $(eval current_mk := $(strip $(word 1,$(_include_stack)))) \
+  $(eval PRODUCTS.$(current_mk).ARTIFACT_PATH_REQUIREMENTS := $(strip $(1))) \
+  $(eval PRODUCTS.$(current_mk).ARTIFACT_PATH_WHITELIST := $(strip $(2))) \
+  $(eval ARTIFACT_PATH_REQUIREMENT_PRODUCTS := \
+    $(sort $(ARTIFACT_PATH_REQUIREMENT_PRODUCTS) $(current_mk)))
+endef
+
+# Makes including non-existant modules in PRODUCT_PACKAGES an error.
+# $(1): whitelist of non-existant modules to allow.
+define enforce-product-packages-exist
+  $(eval current_mk := $(strip $(word 1,$(_include_stack)))) \
+  $(eval PRODUCTS.$(current_mk).PRODUCT_ENFORCE_PACKAGES_EXIST := true) \
+  $(eval PRODUCTS.$(current_mk).PRODUCT_ENFORCE_PACKAGES_EXIST_WHITELIST := $(1)) \
+  $(eval .KATI_READONLY := PRODUCTS.$(current_mk).PRODUCT_ENFORCE_PACKAGES_EXIST) \
+  $(eval .KATI_READONLY := PRODUCTS.$(current_mk).PRODUCT_ENFORCE_PACKAGES_EXIST_WHITELIST)
+endef
 
 #
 # Do inherit-product only if $(1) exists
@@ -321,6 +386,13 @@
 	WITH_DEXPREOPT \
 	WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY
 
+# Logical partitions related variables.
+_product_stash_var_list += \
+	BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE \
+	BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE \
+	BOARD_SUPER_PARTITION_SIZE \
+	BOARD_SUPER_PARTITION_PARTITION_LIST \
+
 #
 # Mark the variables in _product_stash_var_list as readonly
 #
diff --git a/core/product_config.mk b/core/product_config.mk
index 9406812..8425b09 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -195,18 +195,13 @@
 current_product_makefile :=
 all_product_makefiles :=
 $(foreach f, $(all_product_configs),\
-    $(eval _cpm_words := $(subst :,$(space),$(f)))\
+    $(eval _cpm_words := $(call _decode-product-name,$(f)))\
     $(eval _cpm_word1 := $(word 1,$(_cpm_words)))\
     $(eval _cpm_word2 := $(word 2,$(_cpm_words)))\
-    $(if $(_cpm_word2),\
-        $(eval all_product_makefiles += $(_cpm_word2))\
-        $(eval all_named_products += $(_cpm_word1))\
-        $(if $(filter $(TARGET_PRODUCT),$(_cpm_word1)),\
-            $(eval current_product_makefile += $(_cpm_word2)),),\
-        $(eval all_product_makefiles += $(f))\
-        $(eval all_named_products += $(basename $(notdir $(f))))\
-        $(if $(filter $(TARGET_PRODUCT),$(basename $(notdir $(f)))),\
-            $(eval current_product_makefile += $(f)),)))
+    $(eval all_product_makefiles += $(_cpm_word2))\
+    $(eval all_named_products += $(_cpm_word1))\
+    $(if $(filter $(TARGET_PRODUCT),$(_cpm_word1)),\
+        $(eval current_product_makefile += $(_cpm_word2)),))
 _cpm_words :=
 _cpm_word1 :=
 _cpm_word2 :=
@@ -239,6 +234,12 @@
 $(call import-products, $(current_product_makefile))
 endif  # Import all or just the current product makefile
 
+# Import all the products that have made artifact path requirements, so that we can verify
+# the artifacts they produce.
+$(foreach makefile,$(ARTIFACT_PATH_REQUIREMENT_PRODUCTS),\
+  $(if $(filter-out $(makefile),$(PRODUCTS)),$(eval $(call import-products,$(makefile))))\
+)
+
 # Sanity check
 $(check-all-products)
 
@@ -505,3 +506,8 @@
 # Whether the whitelist of actionable compatible properties should be disabled or not
 PRODUCT_ACTIONABLE_COMPATIBLE_PROPERTY_DISABLE := \
     $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ACTIONABLE_COMPATIBLE_PROPERTY_DISABLE))
+
+# Logical and Resizable Partitions feature flag.
+PRODUCT_USE_LOGICAL_PARTITIONS := \
+    $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_USE_LOGICAL_PARTITIONS))
+.KATI_READONLY := PRODUCT_USE_LOGICAL_PARTITIONS
diff --git a/core/sdk_check.mk b/core/sdk_check.mk
index c09fc7c..49ea2a8 100644
--- a/core/sdk_check.mk
+++ b/core/sdk_check.mk
@@ -8,11 +8,6 @@
 
 whitelisted_modules := framework-res__auto_generated_rro
 
-
-ifeq (,$(JAVA_SDK_ENFORCEMENT_ERROR))
-  JAVA_SDK_ENFORCEMENT_ERROR := APPS
-endif
-
 ifeq ($(LOCAL_SDK_VERSION)$(LOCAL_PRIVATE_PLATFORM_APIS),)
   ifeq (,$(filter $(LOCAL_MODULE),$(whitelisted_modules)))
     ifneq ($(JAVA_SDK_ENFORCEMENT_WARNING)$(JAVA_SDK_ENFORCEMENT_ERROR),)
diff --git a/core/setup_one_odex.mk b/core/setup_one_odex.mk
index 51df43e..92f58b2 100644
--- a/core/setup_one_odex.mk
+++ b/core/setup_one_odex.mk
@@ -78,21 +78,17 @@
   my_stored_preopt_class_loader_context_libs := $(call normalize-path-list, \
       $(foreach lib_name,$(my_filtered_uses_libraries),/system/framework/$(lib_name).jar))
 
-  # Fix up org.apache.http.legacy.boot since it should be org.apache.http.legacy in the manifest.
-  my_lib_names := $(patsubst org.apache.http.legacy.boot,org.apache.http.legacy,$(my_lib_names))
-  my_optional_lib_names := $(patsubst org.apache.http.legacy.boot,org.apache.http.legacy,$(my_optional_lib_names))
+  # Fix up org.apache.http.legacy.impl since it should be org.apache.http.legacy in the manifest.
+  my_lib_names := $(patsubst org.apache.http.legacy.impl,org.apache.http.legacy,$(my_lib_names))
+  my_optional_lib_names := $(patsubst org.apache.http.legacy.impl,org.apache.http.legacy,$(my_optional_lib_names))
   ifeq (,$(filter org.apache.http.legacy,$(my_lib_names) $(my_optional_lib_names)))
-    my_conditional_uses_libraries_host := $(call intermediates-dir-for,JAVA_LIBRARIES,org.apache.http.legacy.boot,,COMMON)/javalib.jar
-    my_conditional_uses_libraries_target := /system/framework/org.apache.http.legacy.boot.jar
+    my_conditional_uses_libraries_host := $(call intermediates-dir-for,JAVA_LIBRARIES,org.apache.http.legacy.impl,,COMMON)/javalib.jar
+    my_conditional_uses_libraries_target := /system/framework/org.apache.http.legacy.impl.jar
   endif
 endif
 
-# Always depend on org.apache.http.legacy.boot since it may get used by dex2oat-one-file for apps
-# targetting <SDK 28(P).
-my_always_depend_libraries := $(call intermediates-dir-for,JAVA_LIBRARIES,org.apache.http.legacy.boot,,COMMON)/javalib.jar
-
 $(my_built_odex): $(AAPT)
-$(my_built_odex): $(my_always_depend_libraries)
+$(my_built_odex): $(my_conditional_uses_libraries_host)
 $(my_built_odex): $(my_dex_preopt_system_dependencies)
 $(my_built_odex): PRIVATE_ENFORCE_USES_LIBRARIES := $(LOCAL_ENFORCE_USES_LIBRARIES)
 $(my_built_odex): PRIVATE_CONDITIONAL_USES_LIBRARIES_HOST := $(my_conditional_uses_libraries_host)
diff --git a/core/soong_config.mk b/core/soong_config.mk
index f8cb2fb..737dfd2 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -102,6 +102,7 @@
 $(call add_json_list, CFIIncludePaths,                   $(CFI_INCLUDE_PATHS) $(PRODUCT_CFI_INCLUDE_PATHS))
 $(call add_json_list, IntegerOverflowExcludePaths,       $(INTEGER_OVERFLOW_EXCLUDE_PATHS) $(PRODUCT_INTEGER_OVERFLOW_EXCLUDE_PATHS))
 
+$(call add_json_bool, UseClangLld,                       $(call invert_bool,$(filter 0 false,$(USE_CLANG_LLD))))
 $(call add_json_bool, ClangTidy,                         $(filter 1 true,$(WITH_TIDY)))
 $(call add_json_str,  TidyChecks,                        $(WITH_TIDY_CHECKS))
 
@@ -111,7 +112,6 @@
 
 $(call add_json_bool, ArtUseReadBarrier,                 $(call invert_bool,$(filter false,$(PRODUCT_ART_USE_READ_BARRIER))))
 $(call add_json_bool, Binder32bit,                       $(BINDER32BIT))
-$(call add_json_bool, Brillo,                            $(BRILLO))
 $(call add_json_str,  BtConfigIncludeDir,                $(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR))
 $(call add_json_bool, Device_uses_hwc2,                  $(filter true,$(TARGET_USES_HWC2)))
 $(call add_json_list, DeviceKernelHeaders,               $(TARGET_PROJECT_SYSTEM_INCLUDES))
@@ -124,6 +124,8 @@
 $(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, Product_is_iot,                    $(filter true,$(PRODUCT_IOT)))
+
 $(call add_json_bool, Treble_linker_namespaces,          $(filter true,$(PRODUCT_TREBLE_LINKER_NAMESPACES)))
 $(call add_json_bool, Enforce_vintf_manifest,            $(filter true,$(PRODUCT_ENFORCE_VINTF_MANIFEST)))
 
@@ -143,6 +145,11 @@
 
 $(call add_json_list, PgoAdditionalProfileDirs,          $(PGO_ADDITIONAL_PROFILE_DIRS))
 
+$(call add_json_list, BoardVendorSepolicyDirs,           $(BOARD_SEPOLICY_DIRS))
+$(call add_json_list, BoardOdmSepolicyDirs,              $(BOARD_ODM_SEPOLICY_DIRS))
+$(call add_json_list, BoardPlatPublicSepolicyDirs,       $(BOARD_PLAT_PUBLIC_SEPOLICY_DIR))
+$(call add_json_list, BoardPlatPrivateSepolicyDirs,      $(BOARD_PLAT_PRIVATE_SEPOLICY_DIR))
+
 _contents := $(_contents)    "VendorVars": {$(newline)
 $(foreach namespace,$(SOONG_CONFIG_NAMESPACES),\
   $(eval _contents := $$(_contents)        "$(namespace)": {$$(newline)) \
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 13b5f71..ef71107 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -23,13 +23,14 @@
 $(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)))
 
-ifdef LOCAL_DROIDDOC_STUBS_JAR
-$(eval $(call copy-one-file,$(LOCAL_DROIDDOC_STUBS_JAR),$(OUT_DOCS)/$(LOCAL_MODULE)-stubs.srcjar))
+ifdef LOCAL_DROIDDOC_STUBS_SRCJAR
+$(eval $(call copy-one-file,$(LOCAL_DROIDDOC_STUBS_SRCJAR),$(OUT_DOCS)/$(LOCAL_MODULE)-stubs.srcjar))
 ALL_DOCS += $(OUT_DOCS)/$(LOCAL_MODULE)-stubs.srcjar
 endif
 
 ifdef LOCAL_DROIDDOC_DOC_ZIP
 $(eval $(call copy-one-file,$(LOCAL_DROIDDOC_DOC_ZIP),$(OUT_DOCS)/$(LOCAL_MODULE)-docs.zip))
+$(call dist-for-goals,docs,$(OUT_DOCS)/$(LOCAL_MODULE)-docs.zip)
 endif
 
 ifdef LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
@@ -63,6 +64,10 @@
   my_static_library_extra_packages := $(intermediates.COMMON)/extra_packages
   $(eval $(call copy-one-file,$(LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES),$(my_static_library_extra_packages)))
   $(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_static_library_extra_packages))
+
+  my_static_library_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
+  $(eval $(call copy-one-file,$(LOCAL_FULL_MANIFEST_FILE),$(my_static_library_android_manifest)))
+  $(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_static_library_android_manifest))
 endif # LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE
 
 ifneq ($(TURBINE_ENABLED),false)
@@ -74,49 +79,55 @@
 endif # TURBINE_ENABLED != false
 
 ifdef LOCAL_SOONG_DEX_JAR
-  ifndef LOCAL_IS_HOST_MODULE
-    ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),)  # is_boot_jar
-      $(eval $(call hiddenapi-copy-soong-jar,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
-    else # !is_boot_jar
-      $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
-    endif # is_boot_jar
-    $(eval $(call add-dependency,$(common_javalib.jar),$(full_classes_jar) $(full_classes_header_jar)))
+  ifneq ($(LOCAL_UNINSTALLABLE_MODULE),true)
+    ifndef LOCAL_IS_HOST_MODULE
+      ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),)  # is_boot_jar
+        $(eval $(call hiddenapi-copy-soong-jar,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
+      else # !is_boot_jar
+        $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
+      endif # is_boot_jar
+      $(eval $(call add-dependency,$(common_javalib.jar),$(full_classes_jar) $(full_classes_header_jar)))
 
-    dex_preopt_profile_src_file := $(common_javalib.jar)
+      dex_preopt_profile_src_file := $(common_javalib.jar)
 
-    # defines built_odex along with rule to install odex
-    include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
+      # defines built_odex along with rule to install odex
+      include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
 
-    dex_preopt_profile_src_file :=
+      dex_preopt_profile_src_file :=
 
-    ifdef LOCAL_DEX_PREOPT
-      ifneq ($(dexpreopt_boot_jar_module),) # boot jar
-        # boot jar's rules are defined in dex_preopt.mk
-        dexpreopted_boot_jar := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(dexpreopt_boot_jar_module)_nodex.jar
-        $(eval $(call copy-one-file,$(dexpreopted_boot_jar),$(LOCAL_BUILT_MODULE)))
+      ifdef LOCAL_DEX_PREOPT
+        ifneq ($(dexpreopt_boot_jar_module),) # boot jar
+          # boot jar's rules are defined in dex_preopt.mk
+          dexpreopted_boot_jar := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(dexpreopt_boot_jar_module)_nodex.jar
+          $(eval $(call copy-one-file,$(dexpreopted_boot_jar),$(LOCAL_BUILT_MODULE)))
 
-        # For libart boot jars, we don't have .odex files.
-      else # ! boot jar
-        $(built_odex): PRIVATE_MODULE := $(LOCAL_MODULE)
-        # Use pattern rule - we may have multiple built odex files.
+          # For libart boot jars, we don't have .odex files.
+        else # ! boot jar
+          $(built_odex): PRIVATE_MODULE := $(LOCAL_MODULE)
+          # Use pattern rule - we may have multiple built odex files.
 $(built_odex) : $(dir $(LOCAL_BUILT_MODULE))% : $(common_javalib.jar)
 	@echo "Dexpreopt Jar: $(PRIVATE_MODULE) ($@)"
 	$(call dexpreopt-one-file,$<,$@)
 
-       $(eval $(call dexpreopt-copy-jar,$(common_javalib.jar),$(LOCAL_BUILT_MODULE),$(LOCAL_DEX_PREOPT)))
-      endif # ! boot jar
-    else # LOCAL_DEX_PREOPT
-      $(eval $(call copy-one-file,$(common_javalib.jar),$(LOCAL_BUILT_MODULE)))
-    endif # LOCAL_DEX_PREOPT
-  else # LOCAL_IS_HOST_MODULE
-    $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(LOCAL_BUILT_MODULE)))
-    $(eval $(call add-dependency,$(LOCAL_BUILT_MODULE),$(full_classes_jar) $(full_classes_header_jar)))
-  endif
+         $(eval $(call dexpreopt-copy-jar,$(common_javalib.jar),$(LOCAL_BUILT_MODULE),$(LOCAL_DEX_PREOPT)))
+        endif # ! boot jar
+      else # LOCAL_DEX_PREOPT
+        $(eval $(call copy-one-file,$(common_javalib.jar),$(LOCAL_BUILT_MODULE)))
+      endif # LOCAL_DEX_PREOPT
+    else # LOCAL_IS_HOST_MODULE
+      $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(LOCAL_BUILT_MODULE)))
+      $(eval $(call add-dependency,$(LOCAL_BUILT_MODULE),$(full_classes_jar) $(full_classes_header_jar)))
+    endif
 
-  java-dex : $(LOCAL_BUILT_MODULE)
-else
+    java-dex : $(LOCAL_BUILT_MODULE)
+  else  # LOCAL_UNINSTALLABLE_MODULE
+    $(eval $(call copy-one-file,$(full_classes_jar),$(LOCAL_BUILT_MODULE)))
+    $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
+    java-dex : $(common_javalib.jar)
+  endif  # LOCAL_UNINSTALLABLE_MODULE
+else  # LOCAL_SOONG_DEX_JAR
   $(eval $(call copy-one-file,$(full_classes_jar),$(LOCAL_BUILT_MODULE)))
-endif
+endif  # LOCAL_SOONG_DEX_JAR
 
 javac-check : $(full_classes_jar)
 javac-check-$(LOCAL_MODULE) : $(full_classes_jar)
@@ -143,3 +154,13 @@
 my_common := COMMON
 include $(BUILD_SYSTEM)/link_type.mk
 endif # !LOCAL_IS_HOST_MODULE
+
+# LOCAL_EXPORT_SDK_LIBRARIES set by soong is written to exported-sdk-libs file
+my_exported_sdk_libs_file := $(intermediates.COMMON)/exported-sdk-libs
+$(my_exported_sdk_libs_file): PRIVATE_EXPORTED_SDK_LIBS := $(LOCAL_EXPORT_SDK_LIBRARIES)
+$(my_exported_sdk_libs_file):
+	@echo "Export SDK libs $@"
+	$(hide) mkdir -p $(dir $@) && rm -f $@
+	$(if $(PRIVATE_EXPORTED_SDK_LIBS),\
+		$(hide) echo $(PRIVATE_EXPORTED_SDK_LIBS) | tr ' ' '\n' > $@,\
+		$(hide) touch $@)
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 0429dd2..2a87705 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -28,13 +28,15 @@
 
 my_res_package :=
 
+# Process Support Library dependencies.
+include $(BUILD_SYSTEM)/support_libraries.mk
+
+include $(BUILD_SYSTEM)/force_aapt2.mk
+
 ifdef LOCAL_AAPT2_ONLY
 LOCAL_USE_AAPT2 := true
 endif
 
-# Process Support Library dependencies.
-include $(BUILD_SYSTEM)/support_libraries.mk
-
 # Hack to build static Java library with Android resource
 # See bug 5714516
 all_resources :=
@@ -44,8 +46,8 @@
 need_compile_res := true
 LOCAL_RESOURCE_DIR := $(foreach d,$(LOCAL_RESOURCE_DIR),$(call clean-path,$(d)))
 endif
-ifdef LOCAL_USE_AAPT2
-ifneq ($(LOCAL_STATIC_ANDROID_LIBRARIES),)
+ifeq ($(LOCAL_USE_AAPT2),true)
+ifneq ($(strip $(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),)
 need_compile_res := true
 endif
 endif
@@ -82,7 +84,7 @@
 R_file_stamp := $(intermediates.COMMON)/src/R.stamp
 LOCAL_INTERMEDIATE_TARGETS += $(R_file_stamp)
 
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
 # For library we treat all the resource equal with no overlay.
 my_res_resources := $(all_resources)
 my_overlay_resources :=
@@ -110,15 +112,15 @@
 ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
 ifneq ($(filter-out current system_current test_current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_RES_VERSION))),)
 framework_res_package_export := \
-    $(HISTORICAL_SDK_VERSIONS_ROOT)/$(LOCAL_SDK_RES_VERSION)/android.jar
+    $(call resolve-prebuilt-sdk-jar-path,$(LOCAL_SDK_RES_VERSION))
 else
 framework_res_package_export := \
     $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk
 endif
 endif
 
-ifdef LOCAL_USE_AAPT2
-import_proguard_flag_files := $(strip $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES),\
+ifeq ($(LOCAL_USE_AAPT2),true)
+import_proguard_flag_files := $(strip $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
     $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/export_proguard_flags))
 $(intermediates.COMMON)/export_proguard_flags: $(import_proguard_flag_files) $(addprefix $(LOCAL_PATH)/,$(LOCAL_EXPORT_PROGUARD_FLAG_FILES))
 	@echo "Export proguard flags: $@"
@@ -140,7 +142,7 @@
 
 # add --non-constant-id to prevent inlining constants.
 # AAR needs text symbol file R.txt.
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) --static-lib --output-text-symbols $(intermediates.COMMON)/R.txt
 ifndef LOCAL_AAPT_NAMESPACES
   $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS += --no-static-lib-packages
@@ -168,10 +170,10 @@
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_PACKAGE_NAME :=
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_INSTRUMENTATION_FOR :=
 
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
   # One more level with name res so we can zip up the flat resources that can be linked by apps.
   my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res/res
-  ifneq (,$(renderscript_target_api))
+  ifneq (,$(filter-out current,$(renderscript_target_api)))
     ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
       my_generated_res_zips := $(rs_generated_res_zip)
     endif  # renderscript_target_api < 21
diff --git a/core/tasks/apicheck.mk b/core/tasks/apicheck.mk
deleted file mode 100644
index f4aee3f..0000000
--- a/core/tasks/apicheck.mk
+++ /dev/null
@@ -1,165 +0,0 @@
-# Copyright (C) 2008 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.
-
-#
-# Rules for running apicheck to confirm that you haven't broken
-# api compatibility or added apis illegally.
-#
-
-# skip api check for PDK buid
-ifeq (,$(filter true, $(WITHOUT_CHECK_API) $(TARGET_BUILD_PDK)))
-
-.PHONY: checkapi
-
-# Run the checkapi rules by default.
-droidcore: checkapi
-
-last_released_sdk_version := $(lastword $(call numerically_sort, \
-            $(filter-out current, \
-                $(patsubst $(SRC_API_DIR)/%.txt,%, $(wildcard $(SRC_API_DIR)/*.txt)) \
-             )\
-        ))
-
-.PHONY: check-public-api
-checkapi : check-public-api
-
-.PHONY: update-api
-
-# INTERNAL_PLATFORM_API_FILE is the one build by droiddoc.
-# Note that since INTERNAL_PLATFORM_API_FILE is the byproduct of api-stubs module,
-# (See frameworks/base/Android.mk)
-# we need to add api-stubs as additional dependency of the api check.
-
-# Check that the API we're building hasn't broken the last-released
-# SDK version.
-$(eval $(call check-api, \
-    checkpublicapi-last, \
-    $(SRC_API_DIR)/$(last_released_sdk_version).txt, \
-    $(INTERNAL_PLATFORM_API_FILE), \
-    frameworks/base/api/removed.txt, \
-    $(INTERNAL_PLATFORM_REMOVED_API_FILE), \
-    -hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 -hide 26 -hide 27 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 -error 31, \
-    cat $(BUILD_SYSTEM)/apicheck_msg_last.txt, \
-    check-public-api, \
-    $(call doc-timestamp-for,api-stubs) \
-    ))
-
-# Check that the API we're building hasn't changed from the not-yet-released
-# SDK version.
-$(eval $(call check-api, \
-    checkpublicapi-current, \
-    frameworks/base/api/current.txt, \
-    $(INTERNAL_PLATFORM_API_FILE), \
-    frameworks/base/api/removed.txt, \
-    $(INTERNAL_PLATFORM_REMOVED_API_FILE), \
-    -error 2 -error 3 -error 4 -error 5 -error 6 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
-    -error 25 -error 26 -error 27, \
-    cat $(BUILD_SYSTEM)/apicheck_msg_current.txt, \
-    check-public-api, \
-    $(call doc-timestamp-for,api-stubs) \
-    ))
-
-.PHONY: update-public-api
-update-public-api: $(INTERNAL_PLATFORM_API_FILE) | $(ACP)
-	@echo Copying current.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_API_FILE) frameworks/base/api/current.txt
-	@echo Copying removed.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_REMOVED_API_FILE) frameworks/base/api/removed.txt
-
-update-api : update-public-api
-
-#####################Check System API#####################
-.PHONY: check-system-api
-checkapi : check-system-api
-
-# Check that the System API we're building hasn't broken the last-released
-# SDK version.
-$(eval $(call check-api, \
-    checksystemapi-last, \
-    $(SRC_SYSTEM_API_DIR)/$(last_released_sdk_version).txt, \
-    $(INTERNAL_PLATFORM_SYSTEM_API_FILE), \
-    frameworks/base/api/system-removed.txt, \
-    $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE), \
-    -hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 -hide 26 -hide 27 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 -error 31, \
-    cat $(BUILD_SYSTEM)/apicheck_msg_last.txt, \
-    check-system-api, \
-    $(call doc-timestamp-for,system-api-stubs) \
-    ))
-
-# Check that the System API we're building hasn't changed from the not-yet-released
-# SDK version.
-$(eval $(call check-api, \
-    checksystemapi-current, \
-    frameworks/base/api/system-current.txt, \
-    $(INTERNAL_PLATFORM_SYSTEM_API_FILE), \
-    frameworks/base/api/system-removed.txt, \
-    $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE), \
-    -error 2 -error 3 -error 4 -error 5 -error 6 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
-    -error 25 -error 26 -error 27, \
-    cat $(BUILD_SYSTEM)/apicheck_msg_current.txt, \
-    check-system-api, \
-    $(call doc-timestamp-for,system-api-stubs) \
-    ))
-
-.PHONY: update-system-api
-update-api : update-system-api
-
-update-system-api: $(INTERNAL_PLATFORM_SYSTEM_API_FILE) | $(ACP)
-	@echo Copying system-current.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_SYSTEM_API_FILE) frameworks/base/api/system-current.txt
-	@echo Copying system-removed.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE) frameworks/base/api/system-removed.txt
-
-#####################Check Test API#####################
-.PHONY: check-test-api
-checkapi : check-test-api
-
-# Check that the Test API we're building hasn't changed from the not-yet-released
-# SDK version. Note that we don't check that we haven't broken the previous
-# SDK's API because the test API is meant only for CTS which is always
-# associated with the current release.
-$(eval $(call check-api, \
-    checktestapi-current, \
-    frameworks/base/api/test-current.txt, \
-    $(INTERNAL_PLATFORM_TEST_API_FILE), \
-    frameworks/base/api/test-removed.txt, \
-    $(INTERNAL_PLATFORM_TEST_REMOVED_API_FILE), \
-    -error 2 -error 3 -error 4 -error 5 -error 6 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
-    -error 25 -error 26 -error 27, \
-    cat $(BUILD_SYSTEM)/apicheck_msg_current.txt, \
-    check-test-api, \
-    $(call doc-timestamp-for,test-api-stubs) \
-    ))
-
-.PHONY: update-test-api
-update-api : update-test-api
-
-update-test-api: $(INTERNAL_PLATFORM_TEST_API_FILE) | $(ACP)
-	@echo Copying test-current.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_TEST_API_FILE) frameworks/base/api/test-current.txt
-	@echo Copying test-removed.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_TEST_REMOVED_API_FILE) frameworks/base/api/test-removed.txt
-
-
-endif
diff --git a/core/tasks/check_boot_jars/check_boot_jars.py b/core/tasks/check_boot_jars/check_boot_jars.py
index 1b4540c..9d71553 100755
--- a/core/tasks/check_boot_jars/check_boot_jars.py
+++ b/core/tasks/check_boot_jars/check_boot_jars.py
@@ -39,7 +39,7 @@
   return True
 
 
-def CheckJar(jar):
+def CheckJar(whitelist_path, jar):
   """Check a jar file.
   """
   # Get the list of files inside the jar file.
@@ -55,8 +55,9 @@
       package_name = package_name.replace('/', '.')
       # Skip class without a package name
       if package_name and not whitelist_re.match(package_name):
-        print >> sys.stderr, ('Error: %s contains class file %s, which is not in the whitelist'
-                              % (jar, f))
+        print >> sys.stderr, ('Error: %s contains class file %s, whose package name %s is not '
+                              'in the whitelist %s of packages allowed on the bootclasspath.'
+                              % (jar, f, package_name, whitelist_path))
         return False
   return True
 
@@ -65,13 +66,14 @@
   if len(argv) < 2:
     print __doc__
     return 1
+  whitelist_path = argv[0]
 
-  if not LoadWhitelist(argv[0]):
+  if not LoadWhitelist(whitelist_path):
     return 1
 
   passed = True
   for jar in argv[1:]:
-    if not CheckJar(jar):
+    if not CheckJar(whitelist_path, jar):
       passed = False
   if not passed:
     return 1
diff --git a/core/tasks/collect_gpl_sources.mk b/core/tasks/collect_gpl_sources.mk
index 70f0afe..fdbf6c9 100644
--- a/core/tasks/collect_gpl_sources.mk
+++ b/core/tasks/collect_gpl_sources.mk
@@ -22,7 +22,7 @@
 # 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)
-	@echo Package gpl sources: $@
+	@echo Package GPL sources: $@
 	$(hide) tar cfz $@ --exclude ".git*" $(PRIVATE_PATHS)
 
 # Dist the tgz only if we are doing a full build
diff --git a/core/tasks/oem_image.mk b/core/tasks/oem_image.mk
index 66eec22..e9c506a 100644
--- a/core/tasks/oem_image.mk
+++ b/core/tasks/oem_image.mk
@@ -33,7 +33,7 @@
 	$(call pretty,"Target oem fs image: $@")
 	@mkdir -p $(TARGET_OUT_OEM)
 	@mkdir -p $(oemimage_intermediates) && rm -rf $(oemimage_intermediates)/oem_image_info.txt
-	$(call generate-userimage-prop-dictionary, $(oemimage_intermediates)/oem_image_info.txt, skip_fsck=true)
+	$(call generate-image-prop-dictionary, $(oemimage_intermediates)/oem_image_info.txt,oem,skip_fsck=true)
 	$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
 	  build/make/tools/releasetools/build_image.py \
 	  $(TARGET_OUT_OEM) $(oemimage_intermediates)/oem_image_info.txt $@ $(TARGET_OUT)
diff --git a/core/tasks/test_mapping.mk b/core/tasks/test_mapping.mk
index 36275b0..da64cab 100644
--- a/core/tasks/test_mapping.mk
+++ b/core/tasks/test_mapping.mk
@@ -12,7 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Create an artifact to include TEST_MAPPING files in source tree.
+# Create an artifact to include TEST_MAPPING files in source tree. Also include
+# a file (out/disabled-presubmit-tests) containing the tests that should be
+# skipped in presubmit check.
 
 .PHONY: test_mapping
 
@@ -21,13 +23,15 @@
 test_mapping_list := $(OUT_DIR)/.module_paths/TEST_MAPPING.list
 test_mappings := $(file <$(test_mapping_list))
 $(test_mappings_zip) : PRIVATE_test_mappings := $(subst $(newline),\n,$(test_mappings))
+$(test_mappings_zip) : PRIVATE_all_disabled_presubmit_tests := $(ALL_DISABLED_PRESUBMIT_TESTS)
 
 $(test_mappings_zip) : $(test_mappings) $(SOONG_ZIP)
-	@echo "Building artifact to include TEST_MAPPING files."
-	rm -rf $@
+	@echo "Building artifact to include TEST_MAPPING files and tests to skip in presubmit check."
+	rm -rf $@ $(dir $@)/disabled-presubmit-tests
+	echo $(sort $(PRIVATE_all_disabled_presubmit_tests)) | tr " " "\n" > $(dir $@)/disabled-presubmit-tests
 	echo -e "$(PRIVATE_test_mappings)" > $@.list
-	$(SOONG_ZIP) -o $@ -C . -l $@.list
-	rm -f $@.list
+	$(SOONG_ZIP) -o $@ -C . -l $@.list -C $(dir $@) -f $(dir $@)/disabled-presubmit-tests
+	rm -f $@.list $(dir $@)/disabled-presubmit-tests
 
 test_mapping : $(test_mappings_zip)
 
diff --git a/core/tasks/tools/package-modules.mk b/core/tasks/tools/package-modules.mk
index 4155a39..629a9b2 100644
--- a/core/tasks/tools/package-modules.mk
+++ b/core/tasks/tools/package-modules.mk
@@ -28,10 +28,9 @@
 
 # Ignore unknown installed files on partial builds
 my_missing_files :=
-# These warnings are too noisy, silence them for now.
-#ifneq ($(ALLOW_MISSING_DEPENDENCIES),true)
-#my_missing_files = $(shell $(call echo-warning,$(my_makefile),$(my_package_name): Unknown installed file for module '$(1)'))
-#endif
+ifneq ($(ALLOW_MISSING_DEPENDENCIES),true)
+my_missing_files = $(shell $(call echo-warning,$(my_makefile),$(my_package_name): Unknown installed file for module '$(1)'))
+endif
 
 # Iterate over modules' built files and installed files;
 # Calculate the dest files in the output zip file.
diff --git a/core/tasks/vndk.mk b/core/tasks/vndk.mk
index b9133df..ba48df7 100644
--- a/core/tasks/vndk.mk
+++ b/core/tasks/vndk.mk
@@ -36,38 +36,38 @@
 )
 endef
 
-# Returns list of file paths of the intermediate objs
+# Returns list of src:dest paths of the intermediate objs
 #
 # Args:
 #   $(1): list of module and filename pairs (e.g., ld.config.txt:ld.config.27.txt ...)
-#   $(2): target class (e.g., SHARED_LIBRARIES, STATIC_LIBRARIES, ETC)
-#   $(3): if not empty, evaluates for TARGET_2ND_ARCH
+#   $(2): if not empty, evaluates for TARGET_2ND_ARCH
 define paths-of-intermediates
 $(strip \
   $(foreach pair,$(1), \
-    $(eval split_pair := $(subst :,$(space),$(pair))) \
-    $(eval module := $(word 1,$(split_pair))) \
-    $(eval filename := $(word 2,$(split_pair))) \
-    $(eval dir := $(call intermediates-dir-for,$(2),$(module),,,$(3))) \
-    $(call append-path,$(dir),$(filename)) \
+    $(eval module := $(call word-colon,1,$(pair))$(if $(2),$(TARGET_2ND_ARCH_MODULE_SUFFIX))) \
+    $(eval built := $(ALL_MODULES.$(module).BUILT_INSTALLED)) \
+    $(eval filename := $(call word-colon,2,$(pair))) \
+    $(if $(wordlist 2,100,$(built)), \
+      $(error Unable to handle multiple built files ($(module)): $(built))) \
+    $(if $(built),$(call word-colon,1,$(built)):$(filename)) \
   ) \
 )
 endef
 
-# Returns paths of notice files under $(TARGET_OUT_NOTICE_FILES)
+# Returns src:dest list of notice files
 #
 # Args:
 #   $(1): list of lib names (e.g., libfoo.vendor)
-#   $(2): vndk lib type, one of 'vndk' or 'vndk-sp'
 define paths-of-notice-files
 $(strip \
-  $(eval lib_dir := lib$(if $(TARGET_IS_64BIT),64,)) \
-  $(eval vndk_dir := $(2)-$(PLATFORM_VNDK_VERSION)) \
   $(foreach lib,$(1), \
-    $(eval notice_file_name := $(patsubst %.vendor,%.so.txt,$(lib))) \
-    $(TARGET_OUT_NOTICE_FILES)/src/system/$(lib_dir)/$(vndk_dir)/$(notice_file_name) \
-  ) \
-)
+    $(eval notice := $(sort \
+      $(ALL_MODULES.$(lib).NOTICES) \
+      $(if $(TARGET_2ND_ARCH),
+        $(ALL_MODULES.$(lib)$(TARGET_2ND_ARCH_MODULE_SUFFIX).NOTICES)))) \
+    $(if $(wordlist 2,100,$(notice)), \
+      $(error Unable to handle multiple notice files ($(lib)): $(notice))) \
+    $(if $(notice),$(notice):$(subst .vendor,,$(lib)).so.txt)))
 endef
 
 # If in the future libclang_rt.ubsan* is removed from the VNDK-core list,
@@ -103,34 +103,37 @@
 #######################################
 # vndkcore.libraries.txt
 vndkcore.libraries.txt := $(vndk_snapshot_configs_out)/vndkcore.libraries.txt
-$(vndkcore.libraries.txt): $(vndk_core_libs)
+$(vndkcore.libraries.txt): PRIVATE_LIBS := $(vndk_core_libs)
+$(vndkcore.libraries.txt):
 	@echo 'Generating: $@'
 	@rm -f $@
 	@mkdir -p $(dir $@)
 	$(hide) echo -n > $@
-	$(hide) $(foreach lib,$^,echo $(patsubst %.vendor,%,$(lib)).so >> $@;)
+	$(hide) $(foreach lib,$(PRIVATE_LIBS),echo $(patsubst %.vendor,%,$(lib)).so >> $@;)
 
 
 #######################################
 # vndkprivate.libraries.txt
 vndkprivate.libraries.txt := $(vndk_snapshot_configs_out)/vndkprivate.libraries.txt
-$(vndkprivate.libraries.txt): $(vndk_private_libs)
+$(vndkprivate.libraries.txt): PRIVATE_LIBS := $(vndk_private_libs)
+$(vndkprivate.libraries.txt):
 	@echo 'Generating: $@'
 	@rm -f $@
 	@mkdir -p $(dir $@)
 	$(hide) echo -n > $@
-	$(hide) $(foreach lib,$^,echo $(patsubst %.vendor,%,$(lib)).so >> $@;)
+	$(hide) $(foreach lib,$(PRIVATE_LIBS),echo $(patsubst %.vendor,%,$(lib)).so >> $@;)
 
 
 #######################################
 # module_paths.txt
 module_paths.txt := $(vndk_snapshot_configs_out)/module_paths.txt
-$(module_paths.txt): $(vndk_snapshot_libs)
+$(module_paths.txt): PRIVATE_LIBS := $(vndk_snapshot_libs)
+$(module_paths.txt):
 	@echo 'Generating: $@'
 	@rm -f $@
 	@mkdir -p $(dir $@)
 	$(hide) echo -n > $@
-	$(hide) $(foreach lib,$^,echo $(patsubst %.vendor,%,$(lib)).so $(ALL_MODULES.$(lib).PATH) >> $@;)
+	$(hide) $(foreach lib,$(PRIVATE_LIBS),echo $(patsubst %.vendor,%,$(lib)).so $(ALL_MODULES.$(lib).PATH) >> $@;)
 
 
 vndk_snapshot_configs := \
@@ -151,70 +154,76 @@
 
 $(vndk_snapshot_zip): PRIVATE_VNDK_SNAPSHOT_OUT := $(vndk_snapshot_out)
 
+deps := $(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(subst .vendor,,$(lib)).so))
 $(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT := $(vndk_lib_dir)/shared/vndk-core
-$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES := \
-  $(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(lib).so),SHARED_LIBRARIES)
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES := $(deps)
+$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d)))
+deps :=
 
+deps := $(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(subst .vendor,,$(lib)).so))
 $(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT := $(vndk_lib_dir)/shared/vndk-sp
-$(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES := \
-  $(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(lib).so),SHARED_LIBRARIES)
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES := $(deps)
+$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d)))
+deps :=
 
+deps := $(call paths-of-intermediates,$(foreach txt,$(vndk_prebuilt_txts), \
+          $(txt):$(patsubst %.txt,%.$(PLATFORM_VNDK_VERSION).txt,$(txt)))) \
+        $(foreach config,$(vndk_snapshot_configs),$(config):$(notdir $(config)))
 $(vndk_snapshot_zip): PRIVATE_CONFIGS_OUT := $(vndk_snapshot_variant)/configs
-$(vndk_snapshot_zip): PRIVATE_CONFIGS_INTERMEDIATES := \
-  $(call paths-of-intermediates,$(foreach txt,$(vndk_prebuilt_txts), \
-    $(txt):$(patsubst %.txt,%.$(PLATFORM_VNDK_VERSION).txt,$(txt))),ETC) \
-  $(vndk_snapshot_configs)
+$(vndk_snapshot_zip): PRIVATE_CONFIGS_INTERMEDIATES := $(deps)
+$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d)))
+deps :=
 
+notices := $(call paths-of-notice-files,$(vndk_core_libs) $(vndk_sp_libs))
 $(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_OUT := $(vndk_snapshot_variant)/NOTICE_FILES
-$(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_INTERMEDIATES := \
-  $(call paths-of-notice-files,$(vndk_core_libs),vndk) \
-  $(call paths-of-notice-files,$(vndk_sp_libs),vndk-sp)
+$(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_INTERMEDIATES := $(notices)
+$(vndk_snapshot_zip): $(foreach n,$(notices),$(call word-colon,1,$(n)))
+notices :=
 
 ifdef TARGET_2ND_ARCH
+deps := $(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(subst .vendor,,$(lib)).so),true)
 $(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT_2ND := $(vndk_lib_dir_2nd)/shared/vndk-core
-$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES_2ND := \
-  $(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(lib).so),SHARED_LIBRARIES,true)
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES_2ND := $(deps)
+$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d)))
+deps :=
 
+deps := $(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(subst .vendor,,$(lib)).so),true)
 $(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT_2ND := $(vndk_lib_dir_2nd)/shared/vndk-sp
-$(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES_2ND := \
-  $(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(lib).so),SHARED_LIBRARIES,true)
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES_2ND := $(deps)
+$(vndk_snapshot_zip): $(foreach d,$(deps),$(call word-colon,1,$(d)))
+deps :=
 endif
 
 # Args
 #   $(1): destination directory
-#   $(2): list of files to copy
-$(vndk_snapshot_zip): private-copy-vndk-intermediates = \
+#   $(2): list of files (src:dest) to copy
+$(vndk_snapshot_zip): private-copy-intermediates = \
   $(if $(2),$(strip \
-    @mkdir -p $(1); \
+    @mkdir -p $(1) && \
     $(foreach file,$(2), \
-      if [ -e $(file) ]; then \
-        cp -p $(file) $(call append-path,$(1),$(subst .vendor,,$(notdir $(file)))); \
-      fi; \
+      cp $(call word-colon,1,$(file)) $(call append-path,$(1),$(call word-colon,2,$(file))) && \
     ) \
+    true \
   ))
 
-vndk_snapshot_dependencies := \
-  $(vndk_snapshot_libs) \
-  $(vndk_prebuilt_txts) \
-  $(vndk_snapshot_configs)
 
-$(vndk_snapshot_zip): $(vndk_snapshot_dependencies) $(SOONG_ZIP)
+$(vndk_snapshot_zip): $(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, \
+	$(call private-copy-intermediates, \
 		$(PRIVATE_VNDK_CORE_OUT),$(PRIVATE_VNDK_CORE_INTERMEDIATES))
-	$(call private-copy-vndk-intermediates, \
+	$(call private-copy-intermediates, \
 		$(PRIVATE_VNDK_SP_OUT),$(PRIVATE_VNDK_SP_INTERMEDIATES))
-	$(call private-copy-vndk-intermediates, \
+	$(call private-copy-intermediates, \
 		$(PRIVATE_CONFIGS_OUT),$(PRIVATE_CONFIGS_INTERMEDIATES))
-	$(call private-copy-vndk-intermediates, \
+	$(call private-copy-intermediates, \
 		$(PRIVATE_NOTICE_FILES_OUT),$(PRIVATE_NOTICE_FILES_INTERMEDIATES))
 ifdef TARGET_2ND_ARCH
-	$(call private-copy-vndk-intermediates, \
+	$(call private-copy-intermediates, \
 		$(PRIVATE_VNDK_CORE_OUT_2ND),$(PRIVATE_VNDK_CORE_INTERMEDIATES_2ND))
-	$(call private-copy-vndk-intermediates, \
+	$(call private-copy-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)
@@ -240,7 +249,6 @@
 binder :=
 vndk_lib_dir :=
 vndk_lib_dir_2nd :=
-vndk_snapshot_dependencies :=
 
 else # BOARD_VNDK_RUNTIME_DISABLE is set to 'true'
 error_msg := "CANNOT generate VNDK snapshot. BOARD_VNDK_RUNTIME_DISABLE must not be set to 'true'."
diff --git a/core/use_lld_setup.mk b/core/use_lld_setup.mk
new file mode 100644
index 0000000..5f0f412
--- /dev/null
+++ b/core/use_lld_setup.mk
@@ -0,0 +1,29 @@
+#############################################################
+## Set up flags based on USE_CLANG_LLD and LOCAL_USE_CLANG_LLD.
+## Input variables: USE_CLANG_LLD,LOCAL_USE_CLANG_LLD.
+## Output variables: my_use_clang_lld
+#############################################################
+
+# Use LLD by default.
+# Do not use LLD if LOCAL_USE_CLANG_LLD is false or 0,
+# of if LOCAL_USE_CLANG_LLD is not set and USE_CLANG_LLD is 0 or false.
+my_use_clang_lld := true
+ifneq (,$(LOCAL_USE_CLANG_LLD))
+  ifneq (,$(filter 0 false,$(LOCAL_USE_CLANG_LLD)))
+    my_use_clang_lld := false
+  endif
+else
+  ifneq (,$(filter 0 false,$(USE_CLANG_LLD)))
+    my_use_clang_lld := false
+  endif
+endif
+
+# Do not use LLD for Darwin host executables or shared libraries.  See
+# https://lld.llvm.org/AtomLLD.html for status of lld for Mach-O.
+ifeq ($($(my_prefix)OS),darwin)
+my_use_clang_lld := false
+endif
+# http://b/110800681 - lld cannot link Android's Windows modules yet.
+ifeq ($($(my_prefix)OS),windows)
+my_use_clang_lld := false
+endif
diff --git a/core/verify_uses_libraries.sh b/core/verify_uses_libraries.sh
index 8135be6..dde0447 100755
--- a/core/verify_uses_libraries.sh
+++ b/core/verify_uses_libraries.sh
@@ -15,11 +15,13 @@
 # limitations under the License.
 
 
+# apt_binary is $(AAPT) in the build.
+
 # Parse sdk, targetSdk, and uses librares in the APK, then cross reference against build specified ones.
 
 set -e
 local_apk=$1
-badging=$(aapt dump badging "${local_apk}")
+badging=$(${aapt_binary} dump badging "${local_apk}")
 export sdk_version=$(echo "${badging}" | grep "sdkVersion" | sed -n "s/sdkVersion:'\(.*\)'/\1/p")
 # Export target_sdk_version to the caller.
 export target_sdk_version=$(echo "${badging}" | grep "targetSdkVersion" | sed -n "s/targetSdkVersion:'\(.*\)'/\1/p")
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 3c1c3c9..fcf41c9 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -39,9 +39,9 @@
   include $(INTERNAL_BUILD_ID_MAKEFILE)
 endif
 
-DEFAULT_PLATFORM_VERSION := PPR1
-MIN_PLATFORM_VERSION := PPR1
-MAX_PLATFORM_VERSION := PPR1
+DEFAULT_PLATFORM_VERSION := QPR1
+MIN_PLATFORM_VERSION := QPR1
+MAX_PLATFORM_VERSION := QPR1
 
 ALLOWED_VERSIONS := $(call allowed-platform-versions,\
   $(MIN_PLATFORM_VERSION),\
@@ -56,6 +56,13 @@
   $(warning Invalid TARGET_PLATFORM_VERSION '$(TARGET_PLATFORM_VERSION)', must be one of)
   $(error $(ALLOWED_VERSIONS))
 endif
+ALLOWED_VERSIONS :=
+MIN_PLATFORM_VERSION :=
+MAX_PLATFORM_VERSION :=
+
+.KATI_READONLY := \
+  DEFAULT_PLATFORM_VERSION \
+  TARGET_PLATFORM_VERSION
 
 # Default versions for each TARGET_PLATFORM_VERSION
 # TODO: PLATFORM_VERSION, PLATFORM_SDK_VERSION, etc. should be conditional
@@ -75,11 +82,11 @@
 # please add that PLATFORM_VERSION as well as clean up obsolete PLATFORM_VERSION's
 # in the following text file:
 # cts/tests/tests/os/assets/platform_versions.txt
-PLATFORM_VERSION.PPR1 := 9
+PLATFORM_VERSION.QPR1 := Q
 
 # These are the current development codenames, if the build is not a final
 # release build.  If this is a final release build, it is simply "REL".
-PLATFORM_VERSION_CODENAME.PPR1 := REL
+PLATFORM_VERSION_CODENAME.QPR1 := Q
 
 ifndef PLATFORM_VERSION
   PLATFORM_VERSION := $(PLATFORM_VERSION.$(TARGET_PLATFORM_VERSION))
@@ -88,6 +95,7 @@
     PLATFORM_VERSION := $(TARGET_PLATFORM_VERSION)
   endif
 endif
+.KATI_READONLY := PLATFORM_VERSION
 
 ifndef PLATFORM_SDK_VERSION
   # This is the canonical definition of the SDK version, which defines
@@ -108,6 +116,7 @@
   # cts/tests/tests/os/assets/platform_versions.txt
   PLATFORM_SDK_VERSION := 28
 endif
+.KATI_READONLY := PLATFORM_SDK_VERSION
 
 ifndef PLATFORM_VERSION_CODENAME
   PLATFORM_VERSION_CODENAME := $(PLATFORM_VERSION_CODENAME.$(TARGET_PLATFORM_VERSION))
@@ -153,6 +162,10 @@
     $(subst $(space),$(comma),$(strip $(PLATFORM_VERSION_FUTURE_CODENAMES)))
 
 endif
+.KATI_READONLY := \
+  PLATFORM_VERSION_CODENAME \
+  PLATFORM_VERSION_ALL_CODENAMES \
+  PLATFORM_VERSION_FUTURE_CODENAMES
 
 ifeq (REL,$(PLATFORM_VERSION_CODENAME))
   PLATFORM_PREVIEW_SDK_VERSION := 0
@@ -170,6 +183,7 @@
     PLATFORM_PREVIEW_SDK_VERSION := 0
   endif
 endif
+.KATI_READONLY := PLATFORM_PREVIEW_SDK_VERSION
 
 ifndef DEFAULT_APP_TARGET_SDK
   # This is the default minSdkVersion and targetSdkVersion to use for
@@ -183,6 +197,7 @@
     DEFAULT_APP_TARGET_SDK := $(PLATFORM_VERSION_CODENAME)
   endif
 endif
+.KATI_READONLY := DEFAULT_APP_TARGET_SDK
 
 ifndef PLATFORM_VNDK_VERSION
   # This is the definition of the VNDK version for the current VNDK libraries.
@@ -201,6 +216,7 @@
     PLATFORM_VNDK_VERSION := $(PLATFORM_VERSION_CODENAME)
   endif
 endif
+.KATI_READONLY := PLATFORM_VNDK_VERSION
 
 ifndef PLATFORM_SYSTEMSDK_MIN_VERSION
   # This is the oldest version of system SDK that the platform supports. Contrary
@@ -209,6 +225,7 @@
   # old system APIs are gradually deprecated, removed and then deleted.
   PLATFORM_SYSTEMSDK_MIN_VERSION := 28
 endif
+.KATI_READONLY := PLATFORM_SYSTEMSDK_MIN_VERSION
 
 # This is the list of system SDK versions that the current platform supports.
 PLATFORM_SYSTEMSDK_VERSIONS :=
@@ -224,6 +241,7 @@
   PLATFORM_SYSTEMSDK_VERSIONS += $(PLATFORM_VERSION_CODENAME)
 endif
 PLATFORM_SYSTEMSDK_VERSIONS := $(strip $(sort $(PLATFORM_SYSTEMSDK_VERSIONS)))
+.KATI_READONLY := PLATFORM_SYSTEMSDK_VERSIONS
 
 ifndef PLATFORM_SECURITY_PATCH
     #  Used to indicate the security patch that has been applied to the device.
@@ -233,6 +251,7 @@
     #  If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
       PLATFORM_SECURITY_PATCH := 2018-09-05
 endif
+.KATI_READONLY := PLATFORM_SECURITY_PATCH
 
 ifndef PLATFORM_SECURITY_PATCH_TIMESTAMP
   # Used to indicate the matching timestamp for the security patch string in PLATFORM_SECURITY_PATCH.
@@ -251,6 +270,7 @@
   # If there is no $PLATFORM_BASE_OS set, keep it empty.
   PLATFORM_BASE_OS :=
 endif
+.KATI_READONLY := PLATFORM_BASE_OS
 
 ifndef BUILD_ID
   # Used to signify special builds.  E.g., branches and/or releases,
@@ -260,6 +280,7 @@
   # If there is no BUILD_ID set, make it obvious.
   BUILD_ID := UNKNOWN
 endif
+.KATI_READONLY := BUILD_ID
 
 ifndef BUILD_DATETIME
   # Used to reproduce builds by setting the same time. Must be the number
@@ -272,11 +293,12 @@
 else
 DATE := date -d @$(BUILD_DATETIME)
 endif
+.KATI_READONLY := DATE
 
 # Everything should be using BUILD_DATETIME_FROM_FILE instead.
 # BUILD_DATETIME and DATE can be removed once BUILD_NUMBER moves
 # to soong_ui.
-BUILD_DATETIME :=
+$(KATI_obsolete_var BUILD_DATETIME,Use BUILD_DATETIME_FROM_FILE)
 
 HAS_BUILD_NUMBER := true
 ifndef BUILD_NUMBER
@@ -292,6 +314,7 @@
   BUILD_NUMBER := eng.$(shell echo $${USER:0:6}).$(shell $(DATE) +%Y%m%d.%H%M%S)
   HAS_BUILD_NUMBER := false
 endif
+.KATI_READONLY := BUILD_NUMBER HAS_BUILD_NUMBER
 
 ifndef PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION
   # Used to set minimum supported target sdk version. Apps targeting sdk
@@ -299,3 +322,4 @@
   # device.
   PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 17
 endif
+.KATI_READONLY := PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION
diff --git a/envsetup.sh b/envsetup.sh
index cf61950..12168e1 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -301,7 +301,6 @@
 
 function set_stuff_for_environment()
 {
-    settitle
     setpaths
     set_sequence_number
 
@@ -316,24 +315,15 @@
     export BUILD_ENV_SEQUENCE_NUMBER=13
 }
 
-function settitle()
-{
-    # This used to be opt-out with STAY_OFF_MY_LAWN, but this breaks folks
-    # actually using PROMPT_COMMAND (https://issuetracker.google.com/38402256),
-    # and the attempt to set the title doesn't do anything for the default
-    # window manager in debian right now, so switch it to opt-in for anyone
-    # who actually wants this.
-    if [ "$ANDROID_BUILD_SET_WINDOW_TITLE" = "true" ]; then
-        local arch=$(gettargetarch)
-        local product=$TARGET_PRODUCT
-        local variant=$TARGET_BUILD_VARIANT
-        local apps=$TARGET_BUILD_APPS
-        if [ -z "$apps" ]; then
-            export PROMPT_COMMAND="echo -ne \"\033]0;[${arch}-${product}-${variant}] ${USER}@${HOSTNAME}: ${PWD}\007\""
-        else
-            export PROMPT_COMMAND="echo -ne \"\033]0;[$arch $apps $variant] ${USER}@${HOSTNAME}: ${PWD}\007\""
-        fi
-    fi
+# Takes a command name, and check if it's in ENVSETUP_NO_COMPLETION or not.
+function should_add_completion() {
+    local cmd="$1"
+    case :"$ENVSETUP_NO_COMPLETION": in
+    *:"$cmd":*)
+        return 1
+        ;;
+    esac
+    return 0
 }
 
 function addcompletions()
@@ -350,15 +340,19 @@
         return
     fi
 
-    dir="sdk/bash_completion"
-    if [ -d ${dir} ]; then
-        for f in `/bin/ls ${dir}/[a-z]*.bash 2> /dev/null`; do
-            echo "including $f"
+    # Completion can be disabled selectively to allow users to use non-standard completion.
+    # e.g.
+    # ENVSETUP_NO_COMPLETION=adb # -> disable adb completion
+    # ENVSETUP_NO_COMPLETION=adb:bit # -> disable adb and bit completion
+    for f in system/core/adb/adb.bash system/core/fastboot/fastboot.bash; do
+        if [ -f "$f" ] && should_add_completion $(basename "$f" .bash) ; then
             . $f
-        done
-    fi
+        fi
+    done
 
-    complete -C "bit --tab" bit
+    if should_add_completion bit ; then
+        complete -C "bit --tab" bit
+    fi
 }
 
 function choosetype()
@@ -544,14 +538,6 @@
     LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
 }
 
-# add the default one here
-add_lunch_combo aosp_arm-eng
-add_lunch_combo aosp_arm64-eng
-add_lunch_combo aosp_mips-eng
-add_lunch_combo aosp_mips64-eng
-add_lunch_combo aosp_x86-eng
-add_lunch_combo aosp_x86_64-eng
-
 function print_lunch_menu()
 {
     local uname=$(uname)
@@ -562,7 +548,7 @@
 
     local i=1
     local choice
-    for choice in ${LUNCH_MENU_CHOICES[@]}
+    for choice in $(TARGET_BUILD_APPS= LUNCH_MENU_CHOICES="${LUNCH_MENU_CHOICES[@]}" get_build_var COMMON_LUNCH_CHOICES)
     do
         echo "     $i. $choice"
         i=$(($i+1))
@@ -590,9 +576,10 @@
         selection=aosp_arm-eng
     elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
     then
-        if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
+        local choices=($(TARGET_BUILD_APPS= LUNCH_MENU_CHOICES="${LUNCH_MENU_CHOICES[@]}" get_build_var COMMON_LUNCH_CHOICES))
+        if [ $answer -le ${#choices[@]} ]
         then
-            selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
+            selection=${choices[$(($answer-1))]}
         fi
     else
         selection=$answer
@@ -643,6 +630,7 @@
     destroy_build_var_cache
 }
 
+unset COMMON_LUNCH_CHOICES_CACHE
 # Tab completion for lunch.
 function _lunch()
 {
@@ -651,7 +639,11 @@
     cur="${COMP_WORDS[COMP_CWORD]}"
     prev="${COMP_WORDS[COMP_CWORD-1]}"
 
-    COMPREPLY=( $(compgen -W "${LUNCH_MENU_CHOICES[*]}" -- ${cur}) )
+    if [ -z "$COMMON_LUNCH_CHOICES_CACHE" ]; then
+        COMMON_LUNCH_CHOICES_CACHE=$(TARGET_BUILD_APPS= LUNCH_MENU_CHOICES="${LUNCH_MENU_CHOICES[@]}" get_build_var COMMON_LUNCH_CHOICES)
+    fi
+
+    COMPREPLY=( $(compgen -W "${COMMON_LUNCH_CHOICES_CACHE}" -- ${cur}) )
     return 0
 }
 complete -F _lunch lunch
@@ -767,6 +759,7 @@
         \cd ..
     done
     \cd $HERE
+    return 1
 }
 
 function mm()
@@ -894,7 +887,7 @@
       echo "Couldn't locate the top of the tree.  Try setting TOP."
       return 1
     fi
-    local M=$(findmakefile)
+    local M=$(findmakefile || echo $(realpath $PWD)/Android.mk)
     # Remove the path to top as the makefilepath needs to be relative
     local M=`echo $M|sed 's:'$T'/::'`
     local MODULES_IN_PATHS=MODULES-IN-$(dirname ${M})
@@ -999,28 +992,6 @@
     fi
 }
 
-function pid()
-{
-    local prepend=''
-    local append=''
-    if [ "$1" = "--exact" ]; then
-        prepend=' '
-        append='$'
-        shift
-    fi
-    local EXE="$1"
-    if [ "$EXE" ] ; then
-        local PID=`adb shell ps \
-            | tr -d '\r' \
-            | \grep "$prepend$EXE$append" \
-            | sed -e 's/^[^ ]* *\([0-9]*\).*$/\1/'`
-        echo "$PID"
-    else
-        echo "usage: pid [--exact] <process name>"
-        return 255
-    fi
-}
-
 # coredump_setup - enable core dumps globally for any process
 #                  that has the core-file-size limit set correctly
 #
@@ -1107,53 +1078,6 @@
     stacks system_server
 }
 
-function stacks()
-{
-    if [[ $1 =~ ^[0-9]+$ ]] ; then
-        local PID="$1"
-    elif [ "$1" ] ; then
-        local PIDLIST="$(pid $1)"
-        if [[ $PIDLIST =~ ^[0-9]+$ ]] ; then
-            local PID="$PIDLIST"
-        elif [ "$PIDLIST" ] ; then
-            echo "more than one process: $1"
-        else
-            echo "no such process: $1"
-        fi
-    else
-        echo "usage: stacks [pid|process name]"
-    fi
-
-    if [ "$PID" ] ; then
-        # Determine whether the process is native
-        if adb shell ls -l /proc/$PID/exe | grep -q /system/bin/app_process ; then
-            # Dump stacks of Dalvik process
-            local TRACES=/data/anr/traces.txt
-            local ORIG=/data/anr/traces.orig
-            local TMP=/data/anr/traces.tmp
-
-            # Keep original traces to avoid clobbering
-            adb shell mv $TRACES $ORIG
-
-            # Make sure we have a usable file
-            adb shell touch $TRACES
-            adb shell chmod 666 $TRACES
-
-            # Dump stacks and wait for dump to finish
-            adb shell kill -3 $PID
-            adb shell notify $TRACES >/dev/null
-
-            # Restore original stacks, and show current output
-            adb shell mv $TRACES $TMP
-            adb shell mv $ORIG $TRACES
-            adb shell cat $TMP
-        else
-            # Dump stacks of native process
-            adb shell debuggerd -b $PID
-        fi
-    fi
-}
-
 # Read the ELF header from /proc/$PID/exe to determine if the process is
 # 64-bit.
 function is64bit()
diff --git a/target/board/BoardConfigEmuCommon.mk b/target/board/BoardConfigEmuCommon.mk
new file mode 100644
index 0000000..1d58eab
--- /dev/null
+++ b/target/board/BoardConfigEmuCommon.mk
@@ -0,0 +1,51 @@
+# BoardConfigEmuCommon.mk
+#
+# Common compile-time definitions for emulator
+#
+
+# The generic product target doesn't have any hardware-specific pieces.
+TARGET_NO_BOOTLOADER := true
+TARGET_NO_KERNEL := true
+
+HAVE_HTC_AUDIO_DRIVER := true
+BOARD_USES_GENERIC_AUDIO := true
+TARGET_BOOTLOADER_BOARD_NAME := goldfish_$(TARGET_ARCH)
+
+TARGET_USES_64_BIT_BINDER := true
+TARGET_USES_MKE2FS := true
+
+# no hardware camera
+USE_CAMERA_STUB := true
+
+TARGET_USES_HWC2 := true
+NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
+
+# Build OpenGLES emulation guest and host libraries
+BUILD_EMULATOR_OPENGL := true
+BUILD_QEMU_IMAGES := true
+
+# Build and enable the OpenGL ES View renderer. When running on the emulator,
+# the GLES renderer disables itself if host GL acceleration isn't available.
+USE_OPENGL_RENDERER := true
+
+TARGET_COPY_OUT_VENDOR := vendor
+# ~100 MB vendor image. Please adjust system image / vendor image sizes
+# when finalizing them.
+BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
+BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_FLASH_BLOCK_SIZE := 512
+TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
+DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
+
+# Android generic system image always create metadata partition
+BOARD_USES_METADATA_PARTITION := true
+
+# Set this to create /cache mount point for non-A/B devices that mounts /cache.
+# The partition size doesn't matter, just to make build pass.
+BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_CACHEIMAGE_PARTITION_SIZE := 16777216
+
+BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/common
+BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
+
+BUILD_BROKEN_DUP_RULES := false
diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk
new file mode 100644
index 0000000..237cd28
--- /dev/null
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -0,0 +1,28 @@
+# BoardConfigGsiCommon.mk
+#
+# Common compile-time definitions for GSI
+#
+
+# Android Verified Boot (AVB):
+#   Builds a special vbmeta.img that disables AVB verification.
+#   Otherwise, AVB will prevent the device from booting the generic system.img.
+#   Also checks that BOARD_AVB_ENABLE is not set, to prevent adding verity
+#   metadata into system.img.
+ifeq ($(BOARD_AVB_ENABLE),true)
+$(error BOARD_AVB_ENABLE cannot be set for GSI)
+endif
+BOARD_BUILD_DISABLED_VBMETAIMAGE := true
+
+ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+# GSI is always userdebug and needs a couple of properties taking precedence
+# over those set by the vendor.
+TARGET_SYSTEM_PROP := build/make/target/board/gsi_system.prop
+endif
+BOARD_VNDK_VERSION := current
+
+# Pi GSI supports system-as-root
+TARGET_NO_RECOVERY := true
+BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
+
+# Audio: must using XML format for Treblized devices
+USE_XML_AUDIO_POLICY_CONF := 1
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index 6c82846..2331a48 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -1,11 +1,19 @@
-# config.mk
+# Copyright (C) 2018 The Android Open Source Project
 #
-# Product-specific compile-time definitions.
+# 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 generic product target doesn't have any hardware-specific pieces.
-TARGET_NO_BOOTLOADER := true
-TARGET_NO_KERNEL := true
+# arm emulator specific definitions
 TARGET_ARCH := arm
 
 # Note: Before Pi, we built the platform images for ARMv7-A _without_ NEON.
@@ -36,66 +44,14 @@
 TARGET_CPU_VARIANT := generic
 TARGET_CPU_ABI := armeabi-v7a
 TARGET_CPU_ABI2 := armeabi
-HAVE_HTC_AUDIO_DRIVER := true
-BOARD_USES_GENERIC_AUDIO := true
-TARGET_BOOTLOADER_BOARD_NAME := goldfish_$(TARGET_ARCH)
 
-TARGET_USES_64_BIT_BINDER := true
-
-# no hardware camera
-USE_CAMERA_STUB := true
-
-TARGET_USES_HWC2 := true
-NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
-
-# Build OpenGLES emulation guest and host libraries
-BUILD_EMULATOR_OPENGL := true
-BUILD_QEMU_IMAGES := true
-
-# Build and enable the OpenGL ES View renderer. When running on the emulator,
-# the GLES renderer disables itself if host GL acceleration isn't available.
-USE_OPENGL_RENDERER := true
+include build/make/target/board/BoardConfigEmuCommon.mk
+include build/make/target/board/BoardConfigGsiCommon.mk
 
 TARGET_USERIMAGES_USE_EXT4 := true
 # Partition size is default 1.5GB (1536MB) for 64 bits projects
 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1610612736
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
-TARGET_COPY_OUT_VENDOR := vendor
-# ~100 MB vendor image. Please adjust system image / vendor image sizes
-# when finalizing them.
-BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
-BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_FLASH_BLOCK_SIZE := 512
-TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
-DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
-
-# Android generic system image always create metadata partition
-BOARD_USES_METADATA_PARTITION := true
-
-# Set this to create /cache mount point for non-A/B devices that mounts /cache.
-# The partition size doesn't matter, just to make build pass.
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 16777216
-
-BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/common
-BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
-
-# Android Verified Boot (AVB):
-#   Builds a special vbmeta.img that disables AVB verification.
-#   Otherwise, AVB will prevent the device from booting the generic system.img.
-#   Also checks that BOARD_AVB_ENABLE is not set, to prevent adding verity
-#   metadata into system.img.
-ifeq ($(BOARD_AVB_ENABLE),true)
-$(error BOARD_AVB_ENABLE cannot be set for GSI)
-endif
-BOARD_BUILD_DISABLED_VBMETAIMAGE := true
-
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-# GSI is always userdebug and needs a couple of properties taking precedence
-# over those set by the vendor.
-TARGET_SYSTEM_PROP := build/make/target/board/gsi_system.prop
-endif
-BOARD_VNDK_VERSION := current
 
 # Wifi.
 BOARD_WLAN_DEVICE           := emulator
@@ -107,7 +63,3 @@
 WIFI_DRIVER_FW_PATH_PARAM   := "/dev/null"
 WIFI_DRIVER_FW_PATH_STA     := "/dev/null"
 WIFI_DRIVER_FW_PATH_AP      := "/dev/null"
-
-# Enable A/B update
-TARGET_NO_RECOVERY := true
-BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 56f15de..45eb866 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2013 The Android Open Source Project
+# Copyright (C) 2018 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -13,14 +13,11 @@
 # limitations under the License.
 #
 
-# The generic product target doesn't have any hardware-specific pieces.
-TARGET_NO_BOOTLOADER := true
-TARGET_NO_KERNEL := true
+# arm64 emulator specific definitions
 TARGET_ARCH := arm64
 TARGET_ARCH_VARIANT := armv8-a
 TARGET_CPU_VARIANT := generic
 TARGET_CPU_ABI := arm64-v8a
-TARGET_BOOTLOADER_BOARD_NAME := goldfish_$(TARGET_ARCH)
 
 TARGET_2ND_ARCH := arm
 TARGET_2ND_CPU_ABI := armeabi-v7a
@@ -55,62 +52,12 @@
 TARGET_2ND_CPU_VARIANT := generic
 endif
 
-
-TARGET_USES_64_BIT_BINDER := true
-
-# no hardware camera
-USE_CAMERA_STUB := true
-
-TARGET_USES_HWC2 := true
-NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
-
-# Build OpenGLES emulation host and guest libraries
-BUILD_EMULATOR_OPENGL := true
-BUILD_QEMU_IMAGES := true
-
-# Build and enable the OpenGL ES View renderer. When running on the emulator,
-# the GLES renderer disables itself if host GL acceleration isn't available.
-USE_OPENGL_RENDERER := true
+include build/make/target/board/BoardConfigEmuCommon.mk
+include build/make/target/board/BoardConfigGsiCommon.mk
 
 TARGET_USERIMAGES_USE_EXT4 := true
 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2684354560 # 2.5 GB
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
-TARGET_COPY_OUT_VENDOR := vendor
-# ~100 MB vendor image. Please adjust system image / vendor image sizes
-# when finalizing them.
-BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
-BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_FLASH_BLOCK_SIZE := 512
-TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
-DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
-
-# Android generic system image always create metadata partition
-BOARD_USES_METADATA_PARTITION := true
-
-# Set this to create /cache mount point for non-A/B devices that mounts /cache.
-# The partition size doesn't matter, just to make build pass.
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 16777216
-
-BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
-BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/common
-
-# Android Verified Boot (AVB):
-#   Builds a special vbmeta.img that disables AVB verification.
-#   Otherwise, AVB will prevent the device from booting the generic system.img.
-#   Also checks that BOARD_AVB_ENABLE is not set, to prevent adding verity
-#   metadata into system.img.
-ifeq ($(BOARD_AVB_ENABLE),true)
-$(error BOARD_AVB_ENABLE cannot be set for GSI)
-endif
-BOARD_BUILD_DISABLED_VBMETAIMAGE := true
-
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-# GSI is always userdebug and needs a couple of properties taking precedence
-# over those set by the vendor.
-TARGET_SYSTEM_PROP := build/make/target/board/gsi_system.prop
-endif
-BOARD_VNDK_VERSION := current
 
 # Emulator system image is going to be used as GSI and some vendor still hasn't
 # cleaned up all device specific directories under root!
@@ -133,7 +80,3 @@
 WIFI_DRIVER_FW_PATH_PARAM   := "/dev/null"
 WIFI_DRIVER_FW_PATH_STA     := "/dev/null"
 WIFI_DRIVER_FW_PATH_AP      := "/dev/null"
-
-# Enable A/B update
-TARGET_NO_RECOVERY := true
-BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic_arm64_ab/sepolicy/OWNERS b/target/board/generic_arm64_ab/sepolicy/OWNERS
index 3828988..ff29677 100644
--- a/target/board/generic_arm64_ab/sepolicy/OWNERS
+++ b/target/board/generic_arm64_ab/sepolicy/OWNERS
@@ -1,4 +1,8 @@
-jeffv@google.com
-dcashman@google.com
+alanstokes@google.com
+bowgotsai@google.com
 jbires@google.com
+jeffv@google.com
+jgalenson@google.com
 sspatil@google.com
+tomcherry@google.com
+trong@google.com
diff --git a/target/board/generic_mips/BoardConfig.mk b/target/board/generic_mips/BoardConfig.mk
deleted file mode 100644
index 523408b..0000000
--- a/target/board/generic_mips/BoardConfig.mk
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# Copyright (C) 2011 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.
-#
-# BoardConfig.mk
-#
-# Product-specific compile-time definitions.
-#
-
-# The generic product target doesn't have any hardware-specific pieces.
-TARGET_NO_BOOTLOADER := true
-TARGET_NO_KERNEL := true
-
-TARGET_ARCH := mips
-ifeq (,$(TARGET_ARCH_VARIANT))
-TARGET_ARCH_VARIANT := mips32r2-fp
-endif
-TARGET_CPU_ABI  := mips
-
-# Make TARGET_CPU_VARIANT the same as TARGET_ARCH_VARIANT
-TARGET_CPU_VARIANT := $(TARGET_ARCH_VARIANT)
-
-HAVE_HTC_AUDIO_DRIVER := true
-BOARD_USES_GENERIC_AUDIO := true
-
-# no hardware camera
-USE_CAMERA_STUB := true
-
-# Enable dex-preoptimization to speed up the first boot sequence
-# of an SDK AVD. Note that this operation only works on Linux for now
-ifeq ($(HOST_OS),linux)
-  ifeq ($(WITH_DEXPREOPT),)
-    WITH_DEXPREOPT := true
-    WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY := false
-  endif
-endif
-
-TARGET_USES_HWC2 := true
-NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
-
-# Build OpenGLES emulation guest and host libraries
-BUILD_EMULATOR_OPENGL := true
-BUILD_QEMU_IMAGES := true
-
-# Build and enable the OpenGL ES View renderer. When running on the emulator,
-# the GLES renderer disables itself if host GL acceleration isn't available.
-USE_OPENGL_RENDERER := true
-
-TARGET_USERIMAGES_USE_EXT4 := true
-BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2147483648  # 2 GB
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 734003200
-TARGET_COPY_OUT_VENDOR := vendor
-# ~100 MB vendor image. Please adjust system image / vendor image sizes
-# when finalizing them.
-BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
-BOARD_VENDORIMAGE_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_mips/README.txt b/target/board/generic_mips/README.txt
deleted file mode 100644
index b31a857..0000000
--- a/target/board/generic_mips/README.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-The "generic_mips" product defines a MIPS based non-hardware-specific
-target without a kernel or bootloader.
-
-It can be used to build the entire user-level system, and
-will work with the emulator, though sound will not work
-(see the "emulator" product for that).
-
-It is not a product "base class"; no other products inherit
-from it or use it in any way.
diff --git a/target/board/generic_mips/device.mk b/target/board/generic_mips/device.mk
deleted file mode 100644
index a2633e1..0000000
--- a/target/board/generic_mips/device.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (C) 2009 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.
-#
-
-# This is a build configuration for the product aspects that
-# are specific to the emulator.
-
-PRODUCT_PROPERTY_OVERRIDES := \
-    ro.ril.hsxpa=1 \
-    ro.ril.gprsclass=10
-
-PRODUCT_COPY_FILES := \
-    device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
-    device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
-    frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \
-    frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \
-    frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
-    device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml \
-    hardware/libhardware_legacy/audio/audio_policy.conf:system/etc/audio_policy.conf
-
-PRODUCT_PACKAGES := \
-    audio.primary.goldfish \
-    power.goldfish \
-    vibrator.goldfish
diff --git a/target/board/generic_mips/system.prop b/target/board/generic_mips/system.prop
deleted file mode 100644
index 973db2c..0000000
--- a/target/board/generic_mips/system.prop
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# system.prop for generic sdk
-#
-
-rild.libpath=/vendor/lib/libreference-ril.so
-rild.libargs=-d /dev/ttyS0
diff --git a/target/board/generic_mips64/BoardConfig.mk b/target/board/generic_mips64/BoardConfig.mk
deleted file mode 100644
index 2052d7b..0000000
--- a/target/board/generic_mips64/BoardConfig.mk
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# Copyright (C) 2013 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.
-#
-# BoardConfig.mk
-#
-# Product-specific compile-time definitions.
-#
-
-# The generic product target doesn't have any hardware-specific pieces.
-TARGET_NO_BOOTLOADER := true
-TARGET_NO_KERNEL := true
-
-TARGET_ARCH := mips64
-ifeq (,$(TARGET_ARCH_VARIANT))
-TARGET_ARCH_VARIANT := mips64r6
-endif
-TARGET_CPU_ABI  := mips64
-
-TARGET_2ND_ARCH := mips
-ifeq (,$(TARGET_2ND_ARCH_VARIANT))
-ifeq ($(TARGET_ARCH_VARIANT),mips64r6)
-# Imgtec builds use 32r6 arch variant with Imgtec-maintained prebuilts/ndk library:
-# TARGET_2ND_ARCH_VARIANT := mips32r6
-# Aosp builds lack full set of mips32r6 NDK prebuilts, so use 32r2 abi:
-TARGET_2ND_ARCH_VARIANT :=  mips32r2-fp
-else
-TARGET_2ND_ARCH_VARIANT :=  mips32r2-fp
-endif
-endif
-TARGET_2ND_CPU_ABI  := mips
-
-# Make TARGET_XXX_CPU_VARIANT the same as TARGET_XXX_ARCH_VARIANT
-TARGET_CPU_VARIANT := $(TARGET_ARCH_VARIANT)
-TARGET_2ND_CPU_VARIANT := $(TARGET_2ND_ARCH_VARIANT)
-
-# The emulator (qemu) uses the Goldfish devices
-HAVE_HTC_AUDIO_DRIVER := true
-BOARD_USES_GENERIC_AUDIO := true
-
-# no hardware camera
-USE_CAMERA_STUB := true
-
-# Enable dex-preoptimization to speed up the first boot sequence
-# of an SDK AVD. Note that this operation only works on Linux for now
-ifeq ($(HOST_OS),linux)
-  ifeq ($(WITH_DEXPREOPT),)
-    WITH_DEXPREOPT := true
-    WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY := false
-  endif
-endif
-
-TARGET_USES_HWC2 := true
-NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
-
-# Build OpenGLES emulation guest and host libraries
-BUILD_EMULATOR_OPENGL := true
-BUILD_QEMU_IMAGES := true
-
-# Build and enable the OpenGL ES View renderer. When running on the emulator,
-# the GLES renderer disables itself if host GL acceleration isn't available.
-USE_OPENGL_RENDERER := true
-
-TARGET_USERIMAGES_USE_EXT4 := true
-BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1879048192  # 1.75 GB
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 1610612736  # 1.5 GB, lots of space for running tests
-TARGET_COPY_OUT_VENDOR := vendor
-# ~100 MB vendor image. Please adjust system image / vendor image sizes
-# when finalizing them.
-BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
-BOARD_VENDORIMAGE_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
-
-DEX_PREOPT_DEFAULT := nostripping
-
-# Enable A/B update
-TARGET_NO_RECOVERY := true
-BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic_mips64/README.txt b/target/board/generic_mips64/README.txt
deleted file mode 100644
index cd4e05b..0000000
--- a/target/board/generic_mips64/README.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-The "generic_mips64" product defines a MIPS64 based non-hardware-specific
-target without a kernel or bootloader.
-
-It can be used to build the entire user-level system, and
-will work with the emulator.
-
-It is not a product "base class"; no other products inherit
-from it or use it in any way.
diff --git a/target/board/generic_mips64/device.mk b/target/board/generic_mips64/device.mk
deleted file mode 100644
index 2ccbcbd..0000000
--- a/target/board/generic_mips64/device.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (C) 2009 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.
-#
-
-# This is a build configuration for the product aspects that
-# are specific to the emulator.
-
-PRODUCT_PROPERTY_OVERRIDES := \
-    ro.ril.hsxpa=1 \
-    ro.ril.gprsclass=10
-
-PRODUCT_COPY_FILES := \
-    device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
-    device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
-    frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \
-    frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \
-    frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
-    device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml \
-    hardware/libhardware_legacy/audio/audio_policy.conf:system/etc/audio_policy.conf
-
-PRODUCT_PACKAGES := \
-    audio.primary.goldfish \
-    power.goldfish
diff --git a/target/board/generic_mips64/system.prop b/target/board/generic_mips64/system.prop
deleted file mode 100644
index 4da69c0..0000000
--- a/target/board/generic_mips64/system.prop
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# system.prop for generic mips64 sdk
-#
-
-rild.libpath=/vendor/lib64/libreference-ril.so
-rild.libargs=-d /dev/ttyS0
diff --git a/target/board/generic_x86/BoardConfig.mk b/target/board/generic_x86/BoardConfig.mk
index 684dfc7..511cd04 100644
--- a/target/board/generic_x86/BoardConfig.mk
+++ b/target/board/generic_x86/BoardConfig.mk
@@ -1,95 +1,34 @@
-# config.mk
+# Copyright (C) 2018 The Android Open Source Project
 #
-# Product-specific compile-time definitions.
+# 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 generic product target doesn't have any hardware-specific pieces.
-TARGET_NO_BOOTLOADER := true
-TARGET_NO_KERNEL := true
+# x86 emulator specific definitions
 TARGET_CPU_ABI := x86
 TARGET_ARCH := x86
 TARGET_ARCH_VARIANT := x86
+
 TARGET_PRELINK_MODULE := false
-TARGET_BOOTLOADER_BOARD_NAME := goldfish_$(TARGET_ARCH)
 
-#emulator now uses 64bit kernel to run 32bit x86 image
-#
-TARGET_USES_64_BIT_BINDER := true
-
-# The IA emulator (qemu) uses the Goldfish devices
-HAVE_HTC_AUDIO_DRIVER := true
-BOARD_USES_GENERIC_AUDIO := true
-
-# no hardware camera
-USE_CAMERA_STUB := true
-
-# Enable dex-preoptimization to speed up the first boot sequence
-# of an SDK AVD. Note that this operation only works on Linux for now
-ifeq ($(HOST_OS),linux)
-WITH_DEXPREOPT ?= true
-WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY ?= false
-endif
-
-TARGET_USES_HWC2 := true
-NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
-
-# Build OpenGLES emulation host and guest libraries
-BUILD_EMULATOR_OPENGL := true
-
-# Build partitioned system.img and vendor.img (if applicable)
-# for qemu, otherwise, init cannot find PART_NAME
-BUILD_QEMU_IMAGES := true
-
-# Build and enable the OpenGL ES View renderer. When running on the emulator,
-# the GLES renderer disables itself if host GL acceleration isn't available.
-USE_OPENGL_RENDERER := true
+include build/make/target/board/BoardConfigEmuCommon.mk
+include build/make/target/board/BoardConfigGsiCommon.mk
 
 TARGET_USERIMAGES_USE_EXT4 := true
 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2684354560
 # Resize to 4G to accomodate ASAN and CTS
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 4294967296
-TARGET_COPY_OUT_VENDOR := vendor
-BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
-# ~100 MB vendor image. Please adjust system image / vendor image sizes
-# when finalizing them.
-BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
-BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_FLASH_BLOCK_SIZE := 512
-TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
-DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
 
-# Android generic system image always create metadata partition
-BOARD_USES_METADATA_PARTITION := true
-
-# Set this to create /cache mount point for non-A/B devices that mounts /cache.
-# The partition size doesn't matter, just to make build pass.
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 16777216
-
-BOARD_SEPOLICY_DIRS += \
-        device/generic/goldfish/sepolicy/common \
-        device/generic/goldfish/sepolicy/x86
-
-# Android Verified Boot (AVB):
-#   Builds a special vbmeta.img that disables AVB verification.
-#   Otherwise, AVB will prevent the device from booting the generic system.img.
-#   Also checks that BOARD_AVB_ENABLE is not set, to prevent adding verity
-#   metadata into system.img.
-ifeq ($(BOARD_AVB_ENABLE),true)
-$(error BOARD_AVB_ENABLE cannot be set for GSI)
-endif
-BOARD_BUILD_DISABLED_VBMETAIMAGE := true
-
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-# GSI is always userdebug and needs a couple of properties taking precedence
-# over those set by the vendor.
-TARGET_SYSTEM_PROP := build/make/target/board/gsi_system.prop
-endif
-BOARD_VNDK_VERSION := current
-
-# Enable A/B update
-TARGET_NO_RECOVERY := true
-BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
+BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
 
 # Wifi.
 BOARD_WLAN_DEVICE           := emulator
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index 5bcb9ad..b9d7e5a 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -1,89 +1,37 @@
-# config.mk
+# Copyright (C) 2018 The Android Open Source Project
 #
-# Product-specific compile-time definitions.
+# 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 generic product target doesn't have any hardware-specific pieces.
-TARGET_NO_BOOTLOADER := true
-TARGET_NO_KERNEL := true
+# x86_64 emulator specific definitions
 TARGET_CPU_ABI := x86_64
 TARGET_ARCH := x86_64
 TARGET_ARCH_VARIANT := x86_64
-TARGET_PRELINK_MODULE := false
-TARGET_BOOTLOADER_BOARD_NAME := goldfish_$(TARGET_ARCH)
 
 TARGET_2ND_CPU_ABI := x86
 TARGET_2ND_ARCH := x86
 TARGET_2ND_ARCH_VARIANT := x86_64
 
-TARGET_USES_64_BIT_BINDER := true
+TARGET_PRELINK_MODULE := false
 
-# The IA emulator (qemu) uses the Goldfish devices
-HAVE_HTC_AUDIO_DRIVER := true
-BOARD_USES_GENERIC_AUDIO := true
-
-# no hardware camera
-USE_CAMERA_STUB := true
-
-# Enable dex-preoptimization to speed up the first boot sequence
-# of an SDK AVD. Note that this operation only works on Linux for now
-ifeq ($(HOST_OS),linux)
-WITH_DEXPREOPT ?= true
-WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY ?= false
-endif
-
-TARGET_USES_HWC2 := true
-NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
-
-# Build OpenGLES emulation host and guest libraries
-BUILD_EMULATOR_OPENGL := true
-BUILD_QEMU_IMAGES := true
-
-# Build and enable the OpenGL ES View renderer. When running on the emulator,
-# the GLES renderer disables itself if host GL acceleration isn't available.
-USE_OPENGL_RENDERER := true
+include build/make/target/board/BoardConfigEmuCommon.mk
+include build/make/target/board/BoardConfigGsiCommon.mk
 
 TARGET_USERIMAGES_USE_EXT4 := true
 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2684354560 # 2.5 GB
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
-TARGET_COPY_OUT_VENDOR := vendor
-# ~100 MB vendor image. Please adjust system image / vendor image sizes
-# when finalizing them.
-BOARD_VENDORIMAGE_PARTITION_SIZE := 100000000
-BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_FLASH_BLOCK_SIZE := 512
-TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
-BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
-DEVICE_MATRIX_FILE   := device/generic/goldfish/compatibility_matrix.xml
 
-# Android generic system image always create metadata partition
-BOARD_USES_METADATA_PARTITION := true
-
-# Set this to create /cache mount point for non-A/B devices that mounts /cache.
-# The partition size doesn't matter, just to make build pass.
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
-BOARD_CACHEIMAGE_PARTITION_SIZE := 16777216
-
-BOARD_SEPOLICY_DIRS += \
-        device/generic/goldfish/sepolicy/common \
-        device/generic/goldfish/sepolicy/x86
-
-# Android Verified Boot (AVB):
-#   Builds a special vbmeta.img that disables AVB verification.
-#   Otherwise, AVB will prevent the device from booting the generic system.img.
-#   Also checks that BOARD_AVB_ENABLE is not set, to prevent adding verity
-#   metadata into system.img.
-ifeq ($(BOARD_AVB_ENABLE),true)
-$(error BOARD_AVB_ENABLE cannot be set for GSI)
-endif
-BOARD_BUILD_DISABLED_VBMETAIMAGE := true
-
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-# GSI is always userdebug and needs a couple of properties taking precedence
-# over those set by the vendor.
-TARGET_SYSTEM_PROP := build/make/target/board/gsi_system.prop
-endif
-BOARD_VNDK_VERSION := current
+BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
 
 # Wifi.
 BOARD_WLAN_DEVICE           := emulator
@@ -95,7 +43,3 @@
 WIFI_DRIVER_FW_PATH_PARAM   := "/dev/null"
 WIFI_DRIVER_FW_PATH_STA     := "/dev/null"
 WIFI_DRIVER_FW_PATH_AP      := "/dev/null"
-
-# Enable A/B update
-TARGET_NO_RECOVERY := true
-BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic_x86_arm/BoardConfig.mk b/target/board/generic_x86_arm/BoardConfig.mk
index c66aacc..d1e4884 100644
--- a/target/board/generic_x86_arm/BoardConfig.mk
+++ b/target/board/generic_x86_arm/BoardConfig.mk
@@ -31,6 +31,8 @@
 # Tell the build system this isn't a typical 64bit+32bit multilib configuration.
 TARGET_TRANSLATE_2ND_ARCH := true
 
+BUILD_BROKEN_DUP_RULES := true
+
 # no hardware camera
 USE_CAMERA_STUB := true
 
diff --git a/target/board/treble_common.mk b/target/board/treble_common.mk
index c4e68fe..c347060 100644
--- a/target/board/treble_common.mk
+++ b/target/board/treble_common.mk
@@ -59,3 +59,5 @@
 $(error BOARD_AVB_ENABLE cannot be set for Treble GSI)
 endif
 BOARD_BUILD_DISABLED_VBMETAIMAGE := true
+
+BUILD_BROKEN_DUP_RULES := false
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index 85330b3..480b395 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -34,48 +34,47 @@
 # Unbundled apps will be built with the most generic product config.
 ifneq ($(TARGET_BUILD_APPS),)
 PRODUCT_MAKEFILES := \
-    $(LOCAL_DIR)/aosp_arm.mk \
-    $(LOCAL_DIR)/full.mk \
-    $(LOCAL_DIR)/aosp_x86.mk \
-    $(LOCAL_DIR)/full_x86.mk \
-    $(LOCAL_DIR)/aosp_mips.mk \
-    $(LOCAL_DIR)/full_mips.mk \
     $(LOCAL_DIR)/aosp_arm64.mk \
-    $(LOCAL_DIR)/aosp_mips64.mk \
-    $(LOCAL_DIR)/aosp_x86_64.mk
+    $(LOCAL_DIR)/aosp_arm.mk \
+    $(LOCAL_DIR)/aosp_x86_64.mk \
+    $(LOCAL_DIR)/aosp_x86.mk \
+    $(LOCAL_DIR)/full.mk \
+    $(LOCAL_DIR)/full_x86.mk \
+
 else
 PRODUCT_MAKEFILES := \
-    $(LOCAL_DIR)/core.mk \
+    $(LOCAL_DIR)/aosp_arm64_ab.mk \
+    $(LOCAL_DIR)/aosp_arm64_a.mk \
+    $(LOCAL_DIR)/aosp_arm64.mk \
+    $(LOCAL_DIR)/aosp_arm_ab.mk \
+    $(LOCAL_DIR)/aosp_arm_a.mk \
+    $(LOCAL_DIR)/aosp_arm.mk \
+    $(LOCAL_DIR)/aosp_x86_64_ab.mk \
+    $(LOCAL_DIR)/aosp_x86_64_a.mk \
+    $(LOCAL_DIR)/aosp_x86_64.mk \
+    $(LOCAL_DIR)/aosp_x86_ab.mk \
+    $(LOCAL_DIR)/aosp_x86_a.mk \
+    $(LOCAL_DIR)/aosp_x86_arm.mk \
+    $(LOCAL_DIR)/aosp_x86.mk \
+    $(LOCAL_DIR)/full.mk \
+    $(LOCAL_DIR)/full_x86.mk \
     $(LOCAL_DIR)/generic.mk \
     $(LOCAL_DIR)/generic_x86.mk \
-    $(LOCAL_DIR)/generic_mips.mk \
-    $(LOCAL_DIR)/aosp_arm.mk \
-    $(LOCAL_DIR)/aosp_arm_a.mk \
-    $(LOCAL_DIR)/aosp_arm_ab.mk \
-    $(LOCAL_DIR)/full.mk \
-    $(LOCAL_DIR)/aosp_x86.mk \
-    $(LOCAL_DIR)/aosp_x86_a.mk \
-    $(LOCAL_DIR)/aosp_x86_ab.mk \
-    $(LOCAL_DIR)/aosp_x86_arm.mk \
-    $(LOCAL_DIR)/full_x86.mk \
-    $(LOCAL_DIR)/aosp_mips.mk \
-    $(LOCAL_DIR)/full_mips.mk \
-    $(LOCAL_DIR)/aosp_arm64.mk \
-    $(LOCAL_DIR)/aosp_arm64_a.mk \
-    $(LOCAL_DIR)/aosp_arm64_ab.mk \
-    $(LOCAL_DIR)/aosp_mips64.mk \
-    $(LOCAL_DIR)/aosp_x86_64.mk \
-    $(LOCAL_DIR)/aosp_x86_64_a.mk \
-    $(LOCAL_DIR)/aosp_x86_64_ab.mk \
-    $(LOCAL_DIR)/sdk_phone_armv7.mk \
-    $(LOCAL_DIR)/sdk_phone_x86.mk \
-    $(LOCAL_DIR)/sdk_phone_mips.mk \
-    $(LOCAL_DIR)/sdk_phone_arm64.mk \
-    $(LOCAL_DIR)/sdk_phone_x86_64.mk \
-    $(LOCAL_DIR)/sdk_phone_mips64.mk \
-    $(LOCAL_DIR)/sdk.mk \
-    $(LOCAL_DIR)/sdk_x86.mk \
-    $(LOCAL_DIR)/sdk_mips.mk \
+    $(LOCAL_DIR)/mainline_arm64.mk \
+    $(LOCAL_DIR)/mainline_system_arm64.mk \
     $(LOCAL_DIR)/sdk_arm64.mk \
-    $(LOCAL_DIR)/sdk_x86_64.mk
+    $(LOCAL_DIR)/sdk.mk \
+    $(LOCAL_DIR)/sdk_phone_arm64.mk \
+    $(LOCAL_DIR)/sdk_phone_armv7.mk \
+    $(LOCAL_DIR)/sdk_phone_x86_64.mk \
+    $(LOCAL_DIR)/sdk_phone_x86.mk \
+    $(LOCAL_DIR)/sdk_x86_64.mk \
+    $(LOCAL_DIR)/sdk_x86.mk \
+
 endif
+
+COMMON_LUNCH_CHOICES := \
+    aosp_arm64-eng \
+    aosp_arm-eng \
+    aosp_x86_64-eng \
+    aosp_x86-eng \
diff --git a/target/product/aosp_mips.mk b/target/product/aosp_mips.mk
deleted file mode 100644
index 5ee6185..0000000
--- a/target/product/aosp_mips.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright 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.
-#
-
-PRODUCT_PROPERTY_OVERRIDES += \
-	rild.libpath=/vendor/lib/libreference-ril.so
-
-# Note: the following lines need to stay at the beginning so that it can
-# take priority  and override the rules it inherit from other mk files
-# see copy file rules in core/Makefile
-PRODUCT_COPY_FILES += \
-    development/sys-img/advancedFeatures.ini.arm:advancedFeatures.ini \
-    prebuilts/qemu-kernel/mips/3.18/kernel-qemu2:kernel-ranchu \
-    device/generic/goldfish/fstab.ranchu.mips:root/fstab.ranchu \
-    device/generic/goldfish/fstab.ranchu.early.arm:root/fstab.ranchu.early
-
-include $(SRC_TARGET_DIR)/product/full_mips.mk
-
-PRODUCT_NAME := aosp_mips
diff --git a/target/product/aosp_mips64.mk b/target/product/aosp_mips64.mk
deleted file mode 100644
index 73d3731..0000000
--- a/target/product/aosp_mips64.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright 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.
-#
-
-PRODUCT_PROPERTY_OVERRIDES += \
-	rild.libpath=/vendor/lib64/libreference-ril.so
-
-# This is a build configuration for a full-featured build of the
-# Open-Source part of the tree. It's geared toward a US-centric
-# build quite specifically for the emulator, and might not be
-# entirely appropriate to inherit from for on-device configurations.
-
-# Note: the following lines need to stay at the beginning so that it can
-# take priority  and override the rules it inherit from other mk files
-# see copy file rules in core/Makefile
-PRODUCT_COPY_FILES += \
-    development/sys-img/advancedFeatures.ini.arm:advancedFeatures.ini \
-    prebuilts/qemu-kernel/mips64/3.18/kernel-qemu2:kernel-ranchu \
-    device/generic/goldfish/fstab.ranchu.mips:root/fstab.ranchu \
-    device/generic/goldfish/fstab.ranchu.early.arm:root/fstab.ranchu.early
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_mips64/device.mk)
-
-include $(SRC_TARGET_DIR)/product/emulator.mk
-
-# Overrides
-PRODUCT_NAME := aosp_mips64
-PRODUCT_DEVICE := generic_mips64
-PRODUCT_BRAND := Android
-PRODUCT_MODEL := AOSP on MIPS64 Emulator
diff --git a/target/product/base.mk b/target/product/base.mk
index bc3710c..1ecbf4a 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012 The Android Open Source Project
+# Copyright (C) 2018 The Android Open-Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,175 +14,7 @@
 # limitations under the License.
 #
 
-# Base modules (will move elsewhere, previously user tagged)
-PRODUCT_PACKAGES += \
-    20-dns.conf \
-    95-configured \
-    org.apache.http.legacy.boot \
-    appwidget \
-    appops \
-    am \
-    android.policy \
-    android.test.base \
-    android.test.mock \
-    android.test.runner \
-    app_process \
-    applypatch \
-    audioserver \
-    bit \
-    blkid \
-    bmgr \
-    bpfloader \
-    bugreport \
-    bugreportz \
-    cameraserver \
-    content \
-    dnsmasq \
-    dpm \
-    framework \
-    framework-sysconfig.xml \
-    fsck_msdos \
-    hid \
-    ime \
-    incidentd \
-    incident \
-    incident_helper \
-    incident_report \
-    input \
-    javax.obex \
-    libandroid \
-    libandroid_runtime \
-    libandroid_servers \
-    libaudioeffect_jni \
-    libaudioflinger \
-    libaudiopolicyservice \
-    libaudiopolicymanager \
-    libbundlewrapper \
-    libcamera_client \
-    libcameraservice \
-    libcamera2ndk \
-    libdl \
-    libdrmclearkeyplugin \
-    libdynproc \
-    libclearkeycasplugin \
-    libeffectproxy \
-    libeffects \
-    libinput \
-    libinputflinger \
-    libiprouteutil \
-    libjnigraphics \
-    libldnhncr \
-    libmedia \
-    libmedia_jni \
-    libmediaplayerservice \
-    libmtp \
-    libnetd_client \
-    libnetlink \
-    libnetutils \
-    libpdfium \
-    libradio_metadata \
-    libreference-ril \
-    libreverbwrapper \
-    libril \
-    librtp_jni \
-    libsensorservice \
-    libskia \
-    libsonic \
-    libsonivox \
-    libsoundpool \
-    libsoundtrigger \
-    libsoundtriggerservice \
-    libsqlite \
-    libstagefright \
-    libstagefright_amrnb_common \
-    libstagefright_avc_common \
-    libstagefright_enc_common \
-    libstagefright_foundation \
-    libstagefright_omx \
-    libstagefright_yuv \
-    libusbhost \
-    libutils \
-    libvisualizer \
-    libvorbisidec \
-    libmediandk \
-    libvulkan \
-    libwifi-service \
-    locksettings \
-    media \
-    media_cmd \
-    mediadrmserver \
-    mediaserver \
-    mediametrics \
-    mediaextractor \
-    monkey \
-    mtpd \
-    ndc \
-    netd \
-    perfetto \
-    ping \
-    ping6 \
-    platform.xml \
-    privapp-permissions-platform.xml \
-    pppd \
-    pm \
-    racoon \
-    run-as \
-    schedtest \
-    sdcard \
-    secdiscard \
-    services \
-    settings \
-    sgdisk \
-    sm \
-    statsd \
-    svc \
-    tc \
-    telecom \
-    traced \
-    traced_probes \
-    vdc \
-    vold \
-    wm
-
-# Add the compatibility library that is needed when org.apache.http.legacy
-# is removed from the bootclasspath.
-ifeq ($(REMOVE_OAHL_FROM_BCP),true)
-PRODUCT_PACKAGES += framework-oahl-backward-compatibility
-endif
-
-# Add the compatibility library that is needed when android.test.base
-# is removed from the bootclasspath.
-ifeq ($(REMOVE_ATB_FROM_BCP),true)
-PRODUCT_PACKAGES += framework-atb-backward-compatibility
-endif
-
-# Essential HAL modules
-PRODUCT_PACKAGES += \
-    android.hardware.cas@1.0-service \
-    android.hardware.media.omx@1.0-service
-
-# XML schema files
-PRODUCT_PACKAGES += \
-    media_profiles_V1_0.dtd
-
-# Packages included only for eng or userdebug builds, previously debug tagged
-PRODUCT_PACKAGES_DEBUG := \
-    logpersist.start \
-    perfprofd \
-    sqlite3 \
-    strace
-
-PRODUCT_COPY_FILES := $(call add-to-product-copy-files-if-exists,\
-    frameworks/base/config/preloaded-classes:system/etc/preloaded-classes)
-
-# Note: it is acceptable to not have a compiled-classes file. In that case, all boot classpath
-#       classes will be compiled.
-PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
-    frameworks/base/config/compiled-classes:system/etc/compiled-classes)
-
-# Note: it is acceptable to not have a dirty-image-objects file. In that case, the special bin
-#       for known dirty objects in the image will be empty.
-PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
-    frameworks/base/config/dirty-image-objects:system/etc/dirty-image-objects)
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/embedded.mk)
+# This makefile is suitable to inherit by products that don't need to be split
+# up by partition.
+$(call inherit-product, $(SRC_TARGET_DIR)/product/base_system.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/base_vendor.mk)
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
new file mode 100644
index 0000000..fa73d28
--- /dev/null
+++ b/target/product/base_system.mk
@@ -0,0 +1,330 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Base modules and settings for the system partition.
+PRODUCT_PACKAGES += \
+    adb \
+    adbd \
+    am \
+    android.hidl.allocator@1.0-service \
+    android.hidl.base-V1.0-java \
+    android.hidl.manager-V1.0-java \
+    android.hidl.memory@1.0-impl \
+    android.hidl.memory@1.0-impl.vendor \
+    android.test.base \
+    android.test.mock \
+    android.test.runner \
+    applypatch \
+    appops \
+    app_process \
+    appwidget \
+    atest \
+    atrace \
+    audioserver \
+    BackupRestoreConfirmation \
+    bcc \
+    bit \
+    blank_screen \
+    blkid \
+    bmgr \
+    bootanimation \
+    bootstat \
+    bpfloader \
+    bu \
+    bugreport \
+    bugreportz \
+    cameraserver \
+    charger \
+    cmd \
+    com.android.location.provider \
+    ContactsProvider \
+    content \
+    crash_dump \
+    CtsShimPrebuilt \
+    CtsShimPrivPrebuilt \
+    debuggerd\
+    DefaultContainerService \
+    dnsmasq \
+    DownloadProvider \
+    dpm \
+    dumpstate \
+    dumpsys \
+    e2fsck \
+    ExtServices \
+    ExtShared \
+    fastboot \
+    framework \
+    framework-res \
+    framework-sysconfig.xml \
+    fsck_msdos \
+    fs_config_files_system \
+    fs_config_dirs_system \
+    gatekeeperd \
+    healthd \
+    hid \
+    hwservicemanager \
+    idmap \
+    ime \
+    ims-common \
+    incident \
+    incidentd \
+    incident_helper \
+    incident_report \
+    init \
+    init.environ.rc \
+    init.rc \
+    input \
+    installd \
+    ip \
+    ip6tables \
+    iptables \
+    ip-up-vpn \
+    javax.obex \
+    keystore \
+    ld.config.txt \
+    ld.mc \
+    libaaudio \
+    libandroid \
+    libandroidfw \
+    libandroid_runtime \
+    libandroid_servers \
+    libaudioeffect_jni \
+    libaudioflinger \
+    libaudiopolicymanager \
+    libaudiopolicyservice \
+    libaudioutils \
+    libbinder \
+    libc \
+    libcamera2ndk \
+    libcamera_client \
+    libcameraservice \
+    libc_malloc_debug \
+    libc_malloc_hooks \
+    libcutils \
+    libdl \
+    libdrmframework \
+    libdrmframework_jni \
+    libEGL \
+    libETC1 \
+    libFFTEm \
+    libfilterfw \
+    libgatekeeper \
+    libGLESv1_CM \
+    libGLESv2 \
+    libGLESv3 \
+    libgui \
+    libhardware \
+    libhardware_legacy \
+    libinput \
+    libinputflinger \
+    libiprouteutil \
+    libjnigraphics \
+    libjpeg \
+    liblog \
+    libm \
+    libmdnssd \
+    libmedia \
+    libmedia_jni \
+    libmediandk \
+    libmediaplayerservice \
+    libmtp \
+    libnetd_client \
+    libnetlink \
+    libnetutils \
+    libneuralnetworks \
+    libOpenMAXAL \
+    libOpenSLES \
+    libpdfium \
+    libpixelflinger \
+    libpower \
+    libpowermanager \
+    libradio_metadata \
+    librtp_jni \
+    libsensorservice \
+    libsigchain \
+    libskia \
+    libsonic \
+    libsonivox \
+    libsoundpool \
+    libsoundtrigger \
+    libsoundtriggerservice \
+    libspeexresampler \
+    libsqlite \
+    libstagefright \
+    libstagefright_amrnb_common \
+    libstagefright_enc_common \
+    libstagefright_foundation \
+    libstagefright_omx \
+    libstdc++ \
+    libsurfaceflinger \
+    libsurfaceflinger_ddmconnection \
+    libsysutils \
+    libui \
+    libusbhost \
+    libutils \
+    libvorbisidec \
+    libvulkan \
+    libwifi-service \
+    libwilhelm \
+    linker \
+    lmkd \
+    locksettings \
+    logcat \
+    logd \
+    lshal \
+    mdnsd \
+    media \
+    media_cmd \
+    mediadrmserver \
+    mediaextractor \
+    mediametrics \
+    media_profiles_V1_0.dtd \
+    MediaProvider \
+    mediaserver \
+    mke2fs \
+    monkey \
+    mtpd \
+    ndc \
+    netd \
+    org.apache.http.legacy \
+    perfetto \
+    ping \
+    ping6 \
+    platform.xml \
+    pm \
+    pppd \
+    privapp-permissions-platform.xml \
+    racoon \
+    resize2fs \
+    run-as \
+    schedtest \
+    screencap \
+    sdcard \
+    secdiscard \
+    SecureElement \
+    selinux_policy_system \
+    sensorservice \
+    service \
+    servicemanager \
+    services \
+    settings \
+    SettingsProvider \
+    sgdisk \
+    Shell \
+    shell_and_utilities_system \
+    sm \
+    statsd \
+    storaged \
+    surfaceflinger \
+    svc \
+    tc \
+    telecom \
+    telephony-common \
+    thermalserviced \
+    tombstoned \
+    traced \
+    traced_probes \
+    tune2fs \
+    tzdatacheck \
+    uiautomator \
+    uncrypt \
+    usbd \
+    vdc \
+    voip-common \
+    vold \
+    WallpaperBackup \
+    wificond \
+    wifi-service \
+    wm \
+
+# VINTF data for system image
+PRODUCT_PACKAGES += \
+    framework_manifest.xml \
+    framework_compatibility_matrix.xml \
+
+ifeq ($(TARGET_CORE_JARS),)
+$(error TARGET_CORE_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
+endif
+
+# The order matters
+PRODUCT_BOOT_JARS := \
+    $(TARGET_CORE_JARS) \
+    ext \
+    framework \
+    telephony-common \
+    voip-common \
+    ims-common \
+    android.hidl.base-V1.0-java \
+    android.hidl.manager-V1.0-java
+
+# Add the compatibility library that is needed when org.apache.http.legacy
+# is removed from the bootclasspath.
+ifeq ($(REMOVE_OAHL_FROM_BCP),true)
+PRODUCT_PACKAGES += framework-oahl-backward-compatibility
+PRODUCT_BOOT_JARS += framework-oahl-backward-compatibility
+else
+PRODUCT_BOOT_JARS += org.apache.http.legacy.impl
+endif
+
+PRODUCT_COPY_FILES += \
+    system/core/rootdir/init.usb.rc:root/init.usb.rc \
+    system/core/rootdir/init.usb.configfs.rc:root/init.usb.configfs.rc \
+    system/core/rootdir/ueventd.rc:root/ueventd.rc \
+    system/core/rootdir/etc/hosts:system/etc/hosts
+
+# Add the compatibility library that is needed when android.test.base
+# is removed from the bootclasspath.
+ifeq ($(REMOVE_ATB_FROM_BCP),true)
+PRODUCT_PACKAGES += framework-atb-backward-compatibility
+PRODUCT_BOOT_JARS += framework-atb-backward-compatibility
+else
+PRODUCT_BOOT_JARS += android.test.base
+endif
+
+PRODUCT_COPY_FILES += system/core/rootdir/init.zygote32.rc:root/init.zygote32.rc
+PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32
+
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES += debug.atrace.tags.enableflags=0
+
+# Packages included only for eng or userdebug builds, previously debug tagged
+PRODUCT_PACKAGES_DEBUG := \
+    adb_keys \
+    iotop \
+    logpersist.start \
+    micro_bench \
+    perfprofd \
+    procrank \
+    showmap \
+    sqlite3 \
+    strace
+
+# The set of packages whose code can be loaded by the system server.
+PRODUCT_SYSTEM_SERVER_APPS += \
+    SettingsProvider \
+    WallpaperBackup
+
+# Packages included only for eng/userdebug builds, when building with SANITIZE_TARGET=address
+PRODUCT_PACKAGES_DEBUG_ASAN :=
+
+PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
+    frameworks/base/config/preloaded-classes:system/etc/preloaded-classes)
+
+# Note: it is acceptable to not have a dirty-image-objects file. In that case, the special bin
+#       for known dirty objects in the image will be empty.
+PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
+    frameworks/base/config/dirty-image-objects:system/etc/dirty-image-objects)
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
diff --git a/target/product/base_vendor.mk b/target/product/base_vendor.mk
new file mode 100644
index 0000000..27f5441
--- /dev/null
+++ b/target/product/base_vendor.mk
@@ -0,0 +1,55 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Base modules and settings for recovery.
+PRODUCT_PACKAGES += \
+    adbd.recovery \
+    ld.config.recovery.txt \
+    linker.recovery \
+    recovery \
+    shell_and_utilities_recovery \
+
+# Base modules and settings for the vendor partition.
+PRODUCT_PACKAGES += \
+    android.hardware.cas@1.0-service \
+    android.hardware.configstore@1.1-service \
+    android.hardware.media.omx@1.0-service \
+    fs_config_files_nonsystem \
+    fs_config_dirs_nonsystem \
+    gralloc.default \
+    group \
+    libbundlewrapper \
+    libclearkeycasplugin \
+    libdownmix \
+    libdrmclearkeyplugin \
+    libdynproc \
+    libeffectproxy \
+    libeffects \
+    libldnhncr \
+    libreference-ril \
+    libreverbwrapper \
+    libril \
+    libvisualizer \
+    passwd \
+    selinux_policy_nonsystem \
+    shell_and_utilities_vendor \
+    vndservice \
+    vndservicemanager \
+
+# VINTF data for vendor image
+PRODUCT_PACKAGES += \
+    device_manifest.xml \
+    device_compatibility_matrix.xml \
diff --git a/target/product/core.mk b/target/product/core.mk
deleted file mode 100644
index c72bb2f..0000000
--- a/target/product/core.mk
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# Copyright (C) 2007 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.
-#
-
-# Base configuration for communication-oriented android devices
-# (phones, tablets, etc.).  If you want a change to apply to ALMOST ALL
-# devices (including non-phones and non-tablets), modify
-# core_minimal.mk instead. If you care about wearables, you need to modify
-# core_tiny.mk in addition to core_minimal.mk.
-
-PRODUCT_PACKAGES += \
-    BasicDreams \
-    BlockedNumberProvider \
-    BookmarkProvider \
-    Browser2 \
-    BuiltInPrintService \
-    Calendar \
-    CalendarProvider \
-    CaptivePortalLogin \
-    CertInstaller \
-    Contacts \
-    DeskClock \
-    DocumentsUI \
-    DownloadProviderUi \
-    Email \
-    ExactCalculator \
-    ExternalStorageProvider \
-    FusedLocation \
-    InputDevices \
-    KeyChain \
-    Keyguard \
-    LatinIME \
-    Launcher3QuickStep \
-    ManagedProvisioning \
-    MtpDocumentsProvider \
-    PacProcessor \
-    libpac \
-    PrintSpooler \
-    PrintRecommendationService \
-    ProxyHandler \
-    QuickSearchBox \
-    SecureElement \
-    Settings \
-    SettingsIntelligence \
-    SharedStorageBackup \
-    SimAppDialog \
-    StorageManager \
-    Telecom \
-    TeleService \
-    Traceur \
-    VpnDialogs \
-    vr \
-    MmsService
-
-# The set of packages whose code can be loaded by the system server.
-PRODUCT_SYSTEM_SERVER_APPS += \
-    FusedLocation \
-    InputDevices \
-    KeyChain \
-    Telecom \
-
-# The set of packages we want to force 'speed' compilation on.
-PRODUCT_DEXPREOPT_SPEED_APPS += \
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/core_base.mk)
diff --git a/target/product/core_base.mk b/target/product/core_base.mk
deleted file mode 100644
index 7dc0010..0000000
--- a/target/product/core_base.mk
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# Copyright (C) 2013 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.
-#
-# Note that components added here will be also shared in PDK. Components
-# that should not be in PDK should be added in lower level like core.mk.
-
-PRODUCT_PROPERTY_OVERRIDES := \
-    ro.config.notification_sound=OnTheHunt.ogg \
-    ro.config.alarm_alert=Alarm_Classic.ogg
-
-PRODUCT_PACKAGES += \
-    ContactsProvider \
-    DefaultContainerService \
-    Home \
-    TelephonyProvider \
-    UserDictionaryProvider \
-    atrace \
-    libandroidfw \
-    libaudiopreprocessing \
-    libaudioutils \
-    libfilterpack_imageproc \
-    libgabi++ \
-    libmdnssd \
-    libnfc_ndef \
-    libpowermanager \
-    libspeexresampler \
-    libstagefright_soft_aacdec \
-    libstagefright_soft_aacenc \
-    libstagefright_soft_amrdec \
-    libstagefright_soft_amrnbenc \
-    libstagefright_soft_amrwbenc \
-    libstagefright_soft_avcdec \
-    libstagefright_soft_avcenc \
-    libstagefright_soft_flacdec \
-    libstagefright_soft_flacenc \
-    libstagefright_soft_g711dec \
-    libstagefright_soft_gsmdec \
-    libstagefright_soft_hevcdec \
-    libstagefright_soft_mp3dec \
-    libstagefright_soft_mpeg2dec \
-    libstagefright_soft_mpeg4dec \
-    libstagefright_soft_mpeg4enc \
-    libstagefright_soft_opusdec \
-    libstagefright_soft_rawdec \
-    libstagefright_soft_vorbisdec \
-    libstagefright_soft_vpxdec \
-    libstagefright_soft_vpxenc \
-    libvariablespeed \
-    libwebrtc_audio_preprocessing \
-    mdnsd \
-    requestsync \
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/core_minimal.mk)
diff --git a/target/product/core_minimal.mk b/target/product/core_minimal.mk
index 85646c1..b432a91 100644
--- a/target/product/core_minimal.mk
+++ b/target/product/core_minimal.mk
@@ -14,171 +14,16 @@
 # limitations under the License.
 #
 
-# Base configuration for most consumer android devices.  Do not put
-# things that are specific to communication devices (phones, tables,
-# etc.) here -- for that, use core.mk.
+# This product is the base of a generic media-capable device, which
+# means most android products, but excludes wearables.
+#
+# Note: Do not add any contents directly to this file. Choose either
+# media_system or media_vendor depending on partition (also consider
+# base_<x>.mk or handheld_<x>.mk.
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/media_system.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/media_vendor.mk)
 
 PRODUCT_BRAND := generic
 PRODUCT_DEVICE := generic
 PRODUCT_NAME := core
-
-PRODUCT_PACKAGES += \
-    BackupRestoreConfirmation \
-    CompanionDeviceManager \
-    CtsShimPrebuilt \
-    CtsShimPrivPrebuilt \
-    DownloadProvider \
-    ExtShared \
-    ExtServices \
-    HTMLViewer \
-    MediaProvider \
-    PackageInstaller \
-    SecureElement \
-    SettingsProvider \
-    Shell \
-    StatementService \
-    WallpaperBackup \
-    android.hidl.base-V1.0-java \
-    android.hidl.manager-V1.0-java \
-    bcc \
-    bu \
-    com.android.future.usb.accessory \
-    com.android.location.provider \
-    com.android.location.provider.xml \
-    com.android.media.remotedisplay \
-    com.android.media.remotedisplay.xml \
-    com.android.mediadrm.signer \
-    com.android.mediadrm.signer.xml \
-    drmserver \
-    ethernet-service \
-    framework-res \
-    idmap \
-    installd \
-    ims-common \
-    ip \
-    ip-up-vpn \
-    ip6tables \
-    iptables \
-    gatekeeperd \
-    keystore \
-    ld.config.txt \
-    ld.mc \
-    libaaudio \
-    libOpenMAXAL \
-    libOpenSLES \
-    libdownmix \
-    libdrmframework \
-    libdrmframework_jni \
-    libfilterfw \
-    libkeystore \
-    libgatekeeper \
-    libneuralnetworks \
-    libwebviewchromium_loader \
-    libwebviewchromium_plat_support \
-    libwilhelm \
-    logd \
-    mke2fs \
-    e2fsck \
-    resize2fs \
-    tune2fs \
-    screencap \
-    sensorservice \
-    telephony-common \
-    uiautomator \
-    uncrypt \
-    vndk_snapshot_package \
-    voip-common \
-    webview \
-    webview_zygote \
-
-# Wifi modules
-PRODUCT_PACKAGES += \
-    wifi-service \
-    wificond \
-
-PRODUCT_COPY_FILES += \
-    frameworks/native/data/etc/android.software.webview.xml:system/etc/permissions/android.software.webview.xml
-
-ifneq (REL,$(PLATFORM_VERSION_CODENAME))
-PRODUCT_COPY_FILES += \
-    frameworks/native/data/etc/android.software.preview_sdk.xml:system/etc/permissions/android.software.preview_sdk.xml
-endif
-
-ifeq ($(TARGET_CORE_JARS),)
-$(error TARGET_CORE_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
-endif
-
-# The order of PRODUCT_BOOT_JARS matters.
-PRODUCT_BOOT_JARS := \
-    $(TARGET_CORE_JARS) \
-    ext \
-    framework \
-    telephony-common \
-    voip-common \
-    ims-common \
-    android.hidl.base-V1.0-java \
-    android.hidl.manager-V1.0-java
-
-ifeq ($(REMOVE_OAHL_FROM_BCP),true)
-PRODUCT_BOOT_JARS += framework-oahl-backward-compatibility
-else
-PRODUCT_BOOT_JARS += org.apache.http.legacy.boot
-endif
-
-ifeq ($(REMOVE_ATB_FROM_BCP),true)
-PRODUCT_BOOT_JARS += framework-atb-backward-compatibility
-else
-PRODUCT_BOOT_JARS += android.test.base
-endif
-
-# The order of PRODUCT_SYSTEM_SERVER_JARS matters.
-PRODUCT_SYSTEM_SERVER_JARS := \
-    services \
-    ethernet-service \
-    wifi-service \
-    com.android.location.provider \
-
-# The set of packages whose code can be loaded by the system server.
-PRODUCT_SYSTEM_SERVER_APPS += \
-    SettingsProvider \
-    WallpaperBackup
-
-# Adoptable external storage supports both ext4 and f2fs
-PRODUCT_PACKAGES += \
-    e2fsck \
-    mke2fs \
-    fsck.f2fs \
-    make_f2fs \
-
-PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
-    ro.zygote=zygote32
-PRODUCT_COPY_FILES += \
-    system/core/rootdir/init.zygote32.rc:root/init.zygote32.rc
-
-PRODUCT_COPY_FILES += \
-    system/core/rootdir/etc/public.libraries.android.txt:system/etc/public.libraries.txt
-
-# Enable boot.oat filtering of compiled classes to reduce boot.oat size. b/28026683
-PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
-    frameworks/base/config/compiled-classes-phone:system/etc/compiled-classes)
-
-# Enable dirty image object binning to reduce dirty pages in the image.
-PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
-    frameworks/base/dirty-image-objects-phone:system/etc/dirty-image-objects)
-
-# On userdebug builds, collect more tombstones by default.
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-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)
-
-# Enable CFI for security-sensitive components
-$(call inherit-product, $(SRC_TARGET_DIR)/product/cfi-common.mk)
-$(call inherit-product-if-exists, vendor/google/products/cfi-vendor.mk)
diff --git a/target/product/core_tiny.mk b/target/product/core_tiny.mk
deleted file mode 100644
index 4ef7b48..0000000
--- a/target/product/core_tiny.mk
+++ /dev/null
@@ -1,150 +0,0 @@
-#
-# Copyright (C) 2013 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.
-#
-# Tiny configuration for small devices such as wearables. Includes base and embedded.
-# No telephony
-
-PRODUCT_PACKAGES := \
-    Bluetooth \
-    CalendarProvider \
-    ContactsProvider \
-    CertInstaller \
-    FusedLocation \
-    InputDevices
-
-PRODUCT_PACKAGES += \
-    clatd \
-    clatd.conf \
-    pppd
-
-PRODUCT_PACKAGES += \
-    audio.primary.default \
-    local_time.default \
-    power.default
-
-PRODUCT_PACKAGES += \
-    BackupRestoreConfirmation \
-    CtsShimPrebuilt \
-    CtsShimPrivPrebuilt \
-    DefaultContainerService \
-    ExtShared \
-    ExtServices \
-    SecureElement \
-    SettingsProvider \
-    Shell \
-    WallpaperBackup \
-    android.hidl.base-V1.0-java \
-    android.hidl.manager-V1.0-java \
-    bcc \
-    bu \
-    com.android.location.provider \
-    com.android.location.provider.xml \
-    framework-res \
-    installd \
-    ims-common \
-    ip \
-    ip-up-vpn \
-    ip6tables \
-    iptables \
-    gatekeeperd \
-    keystore \
-    ld.config.txt \
-    ld.mc \
-    libaaudio \
-    libOpenMAXAL \
-    libOpenSLES \
-    libdownmix \
-    libfilterfw \
-    libgatekeeper \
-    libkeystore \
-    libwilhelm \
-    libdrmframework_jni \
-    libdrmframework \
-    mke2fs \
-    e2fsck \
-    resize2fs \
-    tune2fs \
-    screencap \
-    sensorservice \
-    uiautomator \
-    uncrypt \
-    telephony-common \
-    voip-common \
-    logd \
-
-# Wifi modules
-PRODUCT_PACKAGES += \
-    wifi-service \
-    wificond \
-
-ifeq ($(TARGET_CORE_JARS),)
-$(error TARGET_CORE_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
-endif
-
-# The order matters
-PRODUCT_BOOT_JARS := \
-    $(TARGET_CORE_JARS) \
-    ext \
-    framework \
-    telephony-common \
-    voip-common \
-    ims-common \
-    android.hidl.base-V1.0-java \
-    android.hidl.manager-V1.0-java
-
-ifeq ($(REMOVE_OAHL_FROM_BCP),true)
-PRODUCT_BOOT_JARS += framework-oahl-backward-compatibility
-else
-PRODUCT_BOOT_JARS += org.apache.http.legacy.boot
-endif
-
-ifeq ($(REMOVE_ATB_FROM_BCP),true)
-PRODUCT_BOOT_JARS += framework-atb-backward-compatibility
-else
-PRODUCT_BOOT_JARS += android.test.base
-endif
-
-# The order of PRODUCT_SYSTEM_SERVER_JARS matters.
-PRODUCT_SYSTEM_SERVER_JARS := \
-    services \
-    wifi-service
-
-# The set of packages whose code can be loaded by the system server.
-PRODUCT_SYSTEM_SERVER_APPS += \
-    FusedLocation \
-    InputDevices \
-    SettingsProvider \
-    WallpaperBackup \
-
-# The set of packages we want to force 'speed' compilation on.
-PRODUCT_DEXPREOPT_SPEED_APPS := \
-
-PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
-    ro.zygote=zygote32
-PRODUCT_COPY_FILES += \
-    system/core/rootdir/init.zygote32.rc:root/init.zygote32.rc
-
-PRODUCT_PROPERTY_OVERRIDES += \
-    ro.carrier=unknown
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/base.mk)
-$(call inherit-product-if-exists, frameworks/base/data/fonts/fonts.mk)
-$(call inherit-product-if-exists, external/roboto-fonts/fonts.mk)
-
-# Overrides
-PRODUCT_BRAND := tiny
-PRODUCT_DEVICE := tiny
-PRODUCT_NAME := core_tiny
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
deleted file mode 100644
index 69cf102..0000000
--- a/target/product/embedded.mk
+++ /dev/null
@@ -1,122 +0,0 @@
-#
-# Copyright (C) 2009 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.
-#
-
-# This is a build configuration for a very minimal build of the
-# Open-Source part of the tree.
-
-PRODUCT_PACKAGES += \
-    adb \
-    adbd \
-    usbd \
-    android.hardware.configstore@1.1-service \
-    android.hidl.allocator@1.0-service \
-    android.hidl.memory@1.0-impl \
-    android.hidl.memory@1.0-impl.vendor \
-    atrace \
-    blank_screen \
-    bootanimation \
-    bootstat \
-    charger \
-    cmd \
-    crash_dump \
-    debuggerd\
-    dumpstate \
-    dumpsys \
-    fastboot \
-    gralloc.default \
-    healthd \
-    hwservicemanager \
-    init \
-    init.environ.rc \
-    init.rc \
-    libEGL \
-    libETC1 \
-    libFFTEm \
-    libGLESv1_CM \
-    libGLESv2 \
-    libGLESv3 \
-    libbinder \
-    libc \
-    libc_malloc_debug \
-    libc_malloc_hooks \
-    libcutils \
-    libdl \
-    libgui \
-    libhardware \
-    libhardware_legacy \
-    libjpeg \
-    liblog \
-    libm \
-    libpixelflinger \
-    libpower \
-    libsigchain \
-    libstdc++ \
-    libsurfaceflinger \
-    libsurfaceflinger_ddmconnection \
-    libsysutils \
-    libui \
-    libutils \
-    linker \
-    lmkd \
-    logcat \
-    lshal \
-    recovery \
-    service \
-    servicemanager \
-    shell_and_utilities \
-    storaged \
-    surfaceflinger \
-    thermalserviced \
-    tombstoned \
-    tzdatacheck \
-    vndservice \
-    vndservicemanager \
-
-# VINTF data
-PRODUCT_PACKAGES += \
-    device_compatibility_matrix.xml \
-    device_manifest.xml \
-    framework_manifest.xml \
-    framework_compatibility_matrix.xml \
-
-# SELinux packages are added as dependencies of the selinux_policy
-# phony package.
-PRODUCT_PACKAGES += \
-    selinux_policy \
-
-# AID Generation for
-# <pwd.h> and <grp.h>
-PRODUCT_PACKAGES += \
-    passwd \
-    group \
-    fs_config_files \
-    fs_config_dirs
-
-# If there are product-specific adb keys defined, install them on debuggable
-# builds.
-PRODUCT_PACKAGES_DEBUG += \
-    adb_keys
-
-# Ensure that this property is always defined so that bionic_systrace.cpp
-# can rely on it being initially set by init.
-PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
-    debug.atrace.tags.enableflags=0
-
-PRODUCT_COPY_FILES += \
-    system/core/rootdir/init.usb.rc:root/init.usb.rc \
-    system/core/rootdir/init.usb.configfs.rc:root/init.usb.configfs.rc \
-    system/core/rootdir/ueventd.rc:root/ueventd.rc \
-    system/core/rootdir/etc/hosts:system/etc/hosts
diff --git a/target/product/full_mips.mk b/target/product/full_mips.mk
deleted file mode 100644
index 61734b4..0000000
--- a/target/product/full_mips.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 2009 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.
-#
-
-# This is a build configuration for a full-featured build of the
-# Open-Source part of the tree. It's geared toward a US-centric
-# mips build quite specifically for the emulator, and might not be
-# entirely appropriate to inherit from for on-device configurations.
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_mips/device.mk)
-
-include $(SRC_TARGET_DIR)/product/emulator.mk
-
-# Overrides
-PRODUCT_NAME := full_mips
-PRODUCT_DEVICE := generic_mips
-PRODUCT_BRAND := Android
-PRODUCT_MODEL := AOSP on MIPS Emulator
diff --git a/target/product/generic.mk b/target/product/generic.mk
index dd0d663..cc856f4 100644
--- a/target/product/generic.mk
+++ b/target/product/generic.mk
@@ -24,3 +24,8 @@
 PRODUCT_BRAND := generic
 PRODUCT_DEVICE := generic
 PRODUCT_NAME := generic
+
+_whitelist := \
+  device_manifest.xml \
+
+$(call enforce-product-packages-exist,$(_whitelist))
diff --git a/target/product/generic_mips.mk b/target/product/generic_mips.mk
deleted file mode 100644
index 7b53d04..0000000
--- a/target/product/generic_mips.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (C) 2007 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.
-#
-
-# This is a generic phone product that isn't specialized for a specific device.
-# It includes the base Android platform.
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_no_telephony.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony.mk)
-
-# Overrides
-PRODUCT_BRAND := generic_mips
-PRODUCT_DEVICE := generic_mips
-PRODUCT_NAME := generic_mips
diff --git a/target/product/generic_no_telephony.mk b/target/product/generic_no_telephony.mk
index 6a84c35..5346476 100644
--- a/target/product/generic_no_telephony.mk
+++ b/target/product/generic_no_telephony.mk
@@ -14,66 +14,15 @@
 # limitations under the License.
 #
 
-# This is a generic phone product that isn't specialized for a specific device.
-# It includes the base Android platform.
+# This product is a generic phone or tablet, that doesn't have telephony.
+#
+# Note: Do not add any contents directly to this file. Choose either
+# handheld_system or handheld_vendor depending on partition (also consider
+# base_<x>.mk or media_<x>.mk.
 
-PRODUCT_PACKAGES := \
-    Bluetooth \
-    BluetoothMidiService \
-    Camera2 \
-    Gallery2 \
-    Music \
-    MusicFX \
-    NfcNci \
-    OneTimeInitializer \
-    Provision \
-    SystemUI \
-    SysuiDarkThemeOverlay \
-    DisplayCutoutEmulationDoubleOverlay \
-    DisplayCutoutEmulationCornerOverlay \
-    DisplayCutoutEmulationTallOverlay \
-    EasterEgg \
-    WallpaperCropper
+$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_vendor.mk)
 
-PRODUCT_PACKAGES += \
-    clatd \
-    clatd.conf \
-    pppd \
-    screenrecord
-
-PRODUCT_PACKAGES += \
-    librs_jni \
-    libvideoeditor_jni \
-    libvideoeditor_core \
-    libvideoeditor_osal \
-    libvideoeditor_videofilters \
-    libvideoeditorplayer \
-
-PRODUCT_PACKAGES += \
-    audio.primary.default \
-    local_time.default \
-    vibrator.default \
-    power.default
-
-PRODUCT_COPY_FILES := \
-        frameworks/av/media/libeffects/data/audio_effects.conf:system/etc/audio_effects.conf
-
-PRODUCT_PROPERTY_OVERRIDES += \
-    ro.carrier=unknown
-
-$(call inherit-product-if-exists, frameworks/base/data/fonts/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/dancing-script/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/carrois-gothic-sc/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/coming-soon/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/cutive-mono/fonts.mk)
-$(call inherit-product-if-exists, external/noto-fonts/fonts.mk)
-$(call inherit-product-if-exists, external/roboto-fonts/fonts.mk)
-$(call inherit-product-if-exists, external/hyphenation-patterns/patterns.mk)
-$(call inherit-product-if-exists, frameworks/base/data/keyboards/keyboards.mk)
-$(call inherit-product-if-exists, frameworks/webview/chromium/chromium.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
-
-# Overrides
 PRODUCT_BRAND := generic
 PRODUCT_DEVICE := generic
 PRODUCT_NAME := generic_no_telephony
diff --git a/target/product/handheld_system.mk b/target/product/handheld_system.mk
new file mode 100644
index 0000000..a961d1e
--- /dev/null
+++ b/target/product/handheld_system.mk
@@ -0,0 +1,108 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This makefile contains the system partition contents for
+# a generic phone or tablet device. Only add something here if
+# it definitely doesn't belong on other types of devices (if it
+# does, use base_vendor.mk).
+$(call inherit-product, $(SRC_TARGET_DIR)/product/media_system.mk)
+$(call inherit-product-if-exists, frameworks/base/data/fonts/fonts.mk)
+$(call inherit-product-if-exists, external/google-fonts/dancing-script/fonts.mk)
+$(call inherit-product-if-exists, external/google-fonts/carrois-gothic-sc/fonts.mk)
+$(call inherit-product-if-exists, external/google-fonts/coming-soon/fonts.mk)
+$(call inherit-product-if-exists, external/google-fonts/cutive-mono/fonts.mk)
+$(call inherit-product-if-exists, external/noto-fonts/fonts.mk)
+$(call inherit-product-if-exists, external/roboto-fonts/fonts.mk)
+$(call inherit-product-if-exists, external/hyphenation-patterns/patterns.mk)
+$(call inherit-product-if-exists, frameworks/base/data/keyboards/keyboards.mk)
+$(call inherit-product-if-exists, frameworks/webview/chromium/chromium.mk)
+
+PRODUCT_PACKAGES += \
+    BasicDreams \
+    BlockedNumberProvider \
+    Bluetooth \
+    BluetoothMidiService \
+    BookmarkProvider \
+    Browser2 \
+    BuiltInPrintService \
+    Calendar \
+    CalendarProvider \
+    Camera2 \
+    CaptivePortalLogin \
+    CertInstaller \
+    clatd \
+    clatd.conf \
+    Contacts \
+    DeskClock \
+    DocumentsUI \
+    DownloadProviderUi \
+    EasterEgg \
+    Email \
+    ExactCalculator \
+    ExternalStorageProvider \
+    FusedLocation \
+    Gallery2 \
+    Home \
+    InputDevices \
+    KeyChain \
+    LatinIME \
+    Launcher3QuickStep \
+    librs_jni \
+    ManagedProvisioning \
+    MmsService \
+    MtpDocumentsProvider \
+    Music \
+    MusicFX \
+    NfcNci \
+    OneTimeInitializer \
+    PacProcessor \
+    PrintRecommendationService \
+    PrintSpooler \
+    Provision \
+    ProxyHandler \
+    QuickSearchBox \
+    screenrecord \
+    SecureElement \
+    Settings \
+    SettingsIntelligence \
+    SharedStorageBackup \
+    SimAppDialog \
+    StorageManager \
+    SystemUI \
+    Telecom \
+    TelephonyProvider \
+    TeleService \
+    Traceur \
+    UserDictionaryProvider \
+    VpnDialogs \
+    vr \
+    WallpaperCropper \
+
+
+PRODUCT_SYSTEM_SERVER_APPS += \
+    FusedLocation \
+    InputDevices \
+    KeyChain \
+    Telecom \
+
+PRODUCT_COPY_FILES += \
+    frameworks/av/media/libeffects/data/audio_effects.conf:system/etc/audio_effects.conf
+
+PRODUCT_PROPERTY_OVERRIDES += \
+    ro.carrier=unknown \
+    ro.config.notification_sound=OnTheHunt.ogg \
+    ro.config.alarm_alert=Alarm_Classic.ogg
+
diff --git a/target/product/handheld_vendor.mk b/target/product/handheld_vendor.mk
new file mode 100644
index 0000000..0f73875
--- /dev/null
+++ b/target/product/handheld_vendor.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This makefile contains the non-system partition contents for
+# a generic phone or tablet device. Only add something here if
+# it definitely doesn't belong on other types of devices (if it
+# does, use base_vendor.mk).
+$(call inherit-product, $(SRC_TARGET_DIR)/product/media_vendor.mk)
+PRODUCT_PACKAGES += \
+    audio.primary.default \
+    DisplayCutoutEmulationCornerOverlay \
+    DisplayCutoutEmulationDoubleOverlay \
+    DisplayCutoutEmulationTallOverlay \
+    local_time.default \
+    power.default \
+    SysuiDarkThemeOverlay \
+    vibrator.default \
diff --git a/target/product/mainline_arm64.mk b/target/product/mainline_arm64.mk
new file mode 100644
index 0000000..9176fb1
--- /dev/null
+++ b/target/product/mainline_arm64.mk
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/base_vendor.mk)
+
+PRODUCT_NAME := mainline_arm64
+PRODUCT_DEVICE := generic_arm64
+PRODUCT_BRAND := generic
+PRODUCT_SHIPPING_API_LEVEL := 28
+
+PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := true
+PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST := \
+  system/etc/seccomp_policy/crash_dump.arm.policy \
+  system/etc/seccomp_policy/mediacodec.policy \
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
new file mode 100644
index 0000000..da6a742
--- /dev/null
+++ b/target/product/mainline_system.mk
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This makefile is the basis of a generic system image for a handheld
+# device with no telephony.
+$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk)
+
+PRODUCT_NAME := mainline_system
+PRODUCT_BRAND := generic
+PRODUCT_SHIPPING_API_LEVEL := 28
+
+_base_mk_whitelist := \
+  recovery/root/etc/mke2fs.conf \
+
+_my_whitelist := $(_base_mk_whitelist)
+
+# Both /system and / are in system.img when PRODUCT_SHIPPING_API_LEVEL>=28.
+_my_paths := \
+  $(TARGET_COPY_OUT_ROOT) \
+  $(TARGET_COPY_OUT_SYSTEM) \
+
+$(call require-artifacts-in-path, $(_my_paths), $(_my_whitelist))
diff --git a/target/product/sdk_mips.mk b/target/product/mainline_system_arm64.mk
similarity index 63%
rename from target/product/sdk_mips.mk
rename to target/product/mainline_system_arm64.mk
index 366994a..b080f43 100644
--- a/target/product/sdk_mips.mk
+++ b/target/product/mainline_system_arm64.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2014 The Android Open Source Project
+# Copyright (C) 2018 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,8 +14,10 @@
 # limitations under the License.
 #
 
-# Don't modify this file - It's just an alias!
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk)
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_phone_mips.mk)
-
-PRODUCT_NAME := sdk_mips
+PRODUCT_NAME := mainline_system_arm64
+PRODUCT_DEVICE := generic_arm64
+PRODUCT_BRAND := generic
+PRODUCT_SHIPPING_API_LEVEL := 28
diff --git a/target/product/media_system.mk b/target/product/media_system.mk
new file mode 100644
index 0000000..992e2ed
--- /dev/null
+++ b/target/product/media_system.mk
@@ -0,0 +1,103 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This makefile contains the system partition contents for
+# media-capable devices (non-wearables). Only add something
+# here if it definitely doesn't belong on wearables. Otherwise,
+# choose base_system.mk.
+$(call inherit-product, $(SRC_TARGET_DIR)/product/base_system.mk)
+
+PRODUCT_PACKAGES += \
+    com.android.future.usb.accessory \
+    com.android.mediadrm.signer \
+    com.android.media.remotedisplay \
+    com.android.media.remotedisplay.xml \
+    CompanionDeviceManager \
+    drmserver \
+    ethernet-service \
+    fsck.f2fs \
+    HTMLViewer \
+    libfilterpack_imageproc \
+    libstagefright_soft_aacdec \
+    libstagefright_soft_aacenc \
+    libstagefright_soft_amrdec \
+    libstagefright_soft_amrnbenc \
+    libstagefright_soft_amrwbenc \
+    libstagefright_soft_avcdec \
+    libstagefright_soft_avcenc \
+    libstagefright_soft_flacdec \
+    libstagefright_soft_flacenc \
+    libstagefright_soft_g711dec \
+    libstagefright_soft_gsmdec \
+    libstagefright_soft_hevcdec \
+    libstagefright_soft_mp3dec \
+    libstagefright_soft_mpeg2dec \
+    libstagefright_soft_mpeg4dec \
+    libstagefright_soft_mpeg4enc \
+    libstagefright_soft_opusdec \
+    libstagefright_soft_rawdec \
+    libstagefright_soft_vorbisdec \
+    libstagefright_soft_vpxdec \
+    libstagefright_soft_vpxenc \
+    libwebviewchromium_loader \
+    libwebviewchromium_plat_support \
+    make_f2fs \
+    PackageInstaller \
+    requestsync \
+    StatementService \
+    vndk_snapshot_package \
+    webview \
+
+
+PRODUCT_COPY_FILES += \
+    frameworks/native/data/etc/android.software.webview.xml:system/etc/permissions/android.software.webview.xml
+
+ifneq (REL,$(PLATFORM_VERSION_CODENAME))
+PRODUCT_COPY_FILES += \
+    frameworks/native/data/etc/android.software.preview_sdk.xml:system/etc/permissions/android.software.preview_sdk.xml
+endif
+
+# The order here is the same order they end up on the classpath, so it matters.
+PRODUCT_SYSTEM_SERVER_JARS := \
+    services \
+    ethernet-service \
+    wifi-service \
+    com.android.location.provider.impl \
+
+PRODUCT_COPY_FILES += \
+    system/core/rootdir/etc/public.libraries.android.txt:system/etc/public.libraries.txt
+
+# Enable boot.oat filtering of compiled classes to reduce boot.oat size. b/28026683
+PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
+    frameworks/base/config/compiled-classes-phone:system/etc/compiled-classes)
+
+# Enable dirty image object binning to reduce dirty pages in the image.
+PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
+    frameworks/base/dirty-image-objects-phone:system/etc/dirty-image-objects)
+
+# On userdebug builds, collect more tombstones by default.
+ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
+    tombstoned.max_tombstone_count=50
+endif
+
+PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+    ro.logd.size.stats=64K \
+    log.tag.stats_log=I
+
+# Enable CFI for security-sensitive components
+$(call inherit-product, $(SRC_TARGET_DIR)/product/cfi-common.mk)
+$(call inherit-product-if-exists, vendor/google/products/cfi-vendor.mk)
diff --git a/target/product/media_vendor.mk b/target/product/media_vendor.mk
new file mode 100644
index 0000000..1db0b58
--- /dev/null
+++ b/target/product/media_vendor.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This makefile contains the non-system partition contents for
+# media-capable devices (non-wearables). Only add something here
+# if it definitely doesn't belong on wearables. Otherwise, choose
+# base_vendor.mk.
+$(call inherit-product, $(SRC_TARGET_DIR)/product/base_vendor.mk)
+
+PRODUCT_PACKAGES += \
+    libaudiopreprocessing \
+    libwebrtc_audio_preprocessing \
diff --git a/target/product/sdk_base.mk b/target/product/sdk_base.mk
deleted file mode 100644
index 1e5ed19..0000000
--- a/target/product/sdk_base.mk
+++ /dev/null
@@ -1,174 +0,0 @@
-#
-# Copyright (C) 2007 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.
-#
-
-PRODUCT_PROPERTY_OVERRIDES :=
-
-PRODUCT_PACKAGES := \
-	CellBroadcastReceiver \
-	CubeLiveWallpapers \
-	CustomLocale \
-	Development \
-	Dialer \
-	Gallery2 \
-	Launcher3QuickStep \
-	Camera2 \
-	librs_jni \
-	LiveWallpapersPicker \
-	Mms \
-	Music \
-	Protips \
-	rild \
-	screenrecord \
-	SdkSetup \
-	SoftKeyboard \
-	sqlite3 \
-	SystemUI \
-	SysuiDarkThemeOverlay \
-	EasterEgg \
-	WallpaperPicker \
-	WidgetPreview \
-
-# Define the host tools and libs that are parts of the SDK.
--include sdk/build/product_sdk.mk
--include development/build/product_sdk.mk
-
-# audio libraries.
-PRODUCT_PACKAGES += \
-	audio.primary.goldfish \
-	audio.r_submix.default \
-	local_time.default
-
-# CDD mandates following codecs
-PRODUCT_PACKAGES += \
-    libstagefright_soft_aacdec \
-    libstagefright_soft_aacenc \
-    libstagefright_soft_amrdec \
-    libstagefright_soft_amrnbenc \
-    libstagefright_soft_amrwbenc \
-    libstagefright_soft_avcdec \
-    libstagefright_soft_avcenc \
-    libstagefright_soft_flacenc \
-    libstagefright_soft_g711dec \
-    libstagefright_soft_gsmdec \
-    libstagefright_soft_hevcdec \
-    libstagefright_soft_mp3dec \
-    libstagefright_soft_mpeg2dec \
-    libstagefright_soft_mpeg4dec \
-    libstagefright_soft_mpeg4enc \
-    libstagefright_soft_opusdec \
-    libstagefright_soft_rawdec \
-    libstagefright_soft_vorbisdec \
-    libstagefright_soft_vpxdec \
-    libstagefright_soft_vpxenc
-
-PRODUCT_PACKAGE_OVERLAYS := development/sdk_overlay
-
-PRODUCT_COPY_FILES := \
-	device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
-	device/sample/etc/old-apns-conf.xml:system/etc/old-apns-conf.xml \
-	frameworks/base/data/sounds/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
-	frameworks/base/data/sounds/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
-	frameworks/base/data/sounds/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
-	device/generic/goldfish/data/etc/handheld_core_hardware.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/handheld_core_hardware.xml \
-	device/generic/goldfish/camera/media_profiles.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_profiles_V1_0.xml \
-	frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_audio.xml \
-	frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_telephony.xml \
-	device/generic/goldfish/camera/media_codecs_google_video.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_video.xml \
-	device/generic/goldfish/camera/media_codecs.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs.xml \
-	device/generic/goldfish/camera/media_codecs_performance.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_performance.xml \
-	frameworks/native/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.touchscreen.multitouch.jazzhand.xml \
-	frameworks/native/data/etc/android.hardware.camera.autofocus.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.autofocus.xml \
-	frameworks/native/data/etc/android.hardware.camera.full.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.full.xml \
-	frameworks/native/data/etc/android.hardware.fingerprint.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.fingerprint.xml \
-	frameworks/native/data/etc/android.software.autofill.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.autofill.xml \
-	frameworks/av/media/libeffects/data/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-	device/generic/goldfish/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
-
-include $(SRC_TARGET_DIR)/product/emulator.mk
-
-$(call inherit-product-if-exists, frameworks/base/data/sounds/AllAudio.mk)
-$(call inherit-product-if-exists, frameworks/base/data/fonts/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/dancing-script/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/carrois-gothic-sc/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/coming-soon/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/cutive-mono/fonts.mk)
-$(call inherit-product-if-exists, external/noto-fonts/fonts.mk)
-$(call inherit-product-if-exists, external/roboto-fonts/fonts.mk)
-$(call inherit-product-if-exists, frameworks/base/data/keyboards/keyboards.mk)
-$(call inherit-product-if-exists, frameworks/webview/chromium/chromium.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
-
-# locale. en_US is both first and in alphabetical order to
-# ensure this is the default locale.
-PRODUCT_LOCALES := \
-	en_US \
-	ar_EG \
-	ar_IL \
-	bg_BG \
-	ca_ES \
-	cs_CZ \
-	da_DK \
-	de_AT \
-	de_CH \
-	de_DE \
-	de_LI \
-	el_GR \
-	en_AU \
-	en_CA \
-	en_GB \
-	en_IE \
-	en_IN \
-	en_NZ \
-	en_SG \
-	en_US \
-	en_ZA \
-	es_ES \
-	es_US \
-	fi_FI \
-	fr_BE \
-	fr_CA \
-	fr_CH \
-	fr_FR \
-	he_IL \
-	hi_IN \
-	hr_HR \
-	hu_HU \
-	id_ID \
-	it_CH \
-	it_IT \
-	ja_JP \
-	ko_KR \
-	lt_LT \
-	lv_LV \
-	nb_NO \
-	nl_BE \
-	nl_NL \
-	pl_PL \
-	pt_BR \
-	pt_PT \
-	ro_RO \
-	ru_RU \
-	sk_SK \
-	sl_SI \
-	sr_RS \
-	sv_SE \
-	th_TH \
-	tl_PH \
-	tr_TR \
-	uk_UA \
-	vi_VN \
-	zh_CN \
-	zh_TW
diff --git a/target/product/sdk_phone_arm64.mk b/target/product/sdk_phone_arm64.mk
index c6b290f..96f0bfd 100644
--- a/target/product/sdk_phone_arm64.mk
+++ b/target/product/sdk_phone_arm64.mk
@@ -20,6 +20,10 @@
 $(call inherit-product, sdk/build/product_sdk.mk)
 $(call inherit-product, development/build/product_sdk.mk)
 
+# keep this apk for sdk targets for now
+PRODUCT_PACKAGES += \
+    EmulatorSmokeTests
+
 # Overrides
 PRODUCT_BRAND := Android
 PRODUCT_NAME := sdk_phone_arm64
diff --git a/target/product/sdk_phone_armv7.mk b/target/product/sdk_phone_armv7.mk
index f2b51cf..04d8d6a 100644
--- a/target/product/sdk_phone_armv7.mk
+++ b/target/product/sdk_phone_armv7.mk
@@ -20,6 +20,10 @@
 $(call inherit-product, sdk/build/product_sdk.mk)
 $(call inherit-product, development/build/product_sdk.mk)
 
+# keep this apk for sdk targets for now
+PRODUCT_PACKAGES += \
+    EmulatorSmokeTests
+
 
 # Overrides
 PRODUCT_BRAND := Android
diff --git a/target/product/sdk_phone_mips.mk b/target/product/sdk_phone_mips.mk
deleted file mode 100644
index 1cc2fe4..0000000
--- a/target/product/sdk_phone_mips.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# Copyright (C) 2012 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.
-#
-
-# This is a build configuration for a full-featured build of the
-# Open-Source part of the tree. It's geared toward a US-centric
-# build quite specifically for the emulator, and might not be
-# entirely appropriate to inherit from for on-device configurations.
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_base.mk)
-
-# AOSP emulator images build the AOSP messaging app.
-# Google API images override with the Google API app.
-# See vendor/google/products/sdk_google_phone_*.mk
-PRODUCT_PACKAGES += \
-    messaging
-
-# Overrides
-PRODUCT_BRAND := Android
-PRODUCT_NAME := sdk_phone_mips
-PRODUCT_DEVICE := generic_mips
-PRODUCT_MODEL := Android SDK for Mips
diff --git a/target/product/sdk_phone_mips64.mk b/target/product/sdk_phone_mips64.mk
deleted file mode 100644
index e45d71b..0000000
--- a/target/product/sdk_phone_mips64.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (C) 2009 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.
-#
-
-# This is a build configuration for a full-featured build of the
-# Open-Source part of the tree. It's geared toward a US-centric
-# build quite specifically for the emulator, and might not be
-# entirely appropriate to inherit from for on-device configurations.
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_base.mk)
-
-# AOSP emulator images build the AOSP messaging app.
-# Google API images override with the Google API app.
-# See vendor/google/products/sdk_google_phone_*.mk
-PRODUCT_PACKAGES += \
-    messaging
-
-# Overrides
-PRODUCT_BRAND := Android
-PRODUCT_NAME := sdk_phone_mips64
-PRODUCT_DEVICE := generic_mips64
-PRODUCT_MODEL := Android SDK built for mips64
diff --git a/target/product/vndk/Android.mk b/target/product/vndk/Android.mk
index 768cb80..5d009f9 100644
--- a/target/product/vndk/Android.mk
+++ b/target/product/vndk/Android.mk
@@ -1,4 +1,3 @@
-ifneq ($(BOARD_VNDK_VERSION),)
 LOCAL_PATH:= $(call my-dir)
 
 #####################################################################
@@ -39,7 +38,13 @@
 droidcore: check-vndk-list
 
 check-vndk-list-timestamp := $(call intermediates-dir-for,PACKAGING,vndk)/check-list-timestamp
+
+ifeq ($(TARGET_IS_64_BIT)|$(TARGET_2ND_ARCH),true|)
+# TODO(b/110429754) remove this condition when we support 64-bit-only device
+check-vndk-list: ;
+else
 check-vndk-list: $(check-vndk-list-timestamp)
+endif
 
 _vndk_check_failure_message := " error: VNDK library list has been changed.\n"
 ifeq (REL,$(PLATFORM_VERSION_CODENAME))
@@ -86,6 +91,8 @@
 endif
 	@chmod a+x $@
 
+ifneq ($(BOARD_VNDK_VERSION),)
+
 include $(CLEAR_VARS)
 LOCAL_MODULE := vndk_package
 LOCAL_REQUIRED_MODULES := \
@@ -98,8 +105,15 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := vndk_snapshot_package
+_binder32 :=
+ifneq ($(TARGET_USES_64_BIT_BINDER),true)
+ifneq ($(TARGET_IS_64_BIT),true)
+_binder32 := _binder32
+endif
+endif
 LOCAL_REQUIRED_MODULES := \
-    $(foreach vndk_ver,$(PRODUCT_EXTRA_VNDK_VERSIONS),vndk_v$(vndk_ver)_$(TARGET_ARCH))
+    $(foreach vndk_ver,$(PRODUCT_EXTRA_VNDK_VERSIONS),vndk_v$(vndk_ver)_$(TARGET_ARCH)$(_binder32))
+_binder32 :=
 include $(BUILD_PHONY_PACKAGE)
 
 endif # BOARD_VNDK_VERSION is set
diff --git a/tools/apicheck/Android.bp b/tools/apicheck/Android.bp
new file mode 100644
index 0000000..8fe20e9
--- /dev/null
+++ b/tools/apicheck/Android.bp
@@ -0,0 +1,22 @@
+// Copyright (C) 2008 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.
+
+java_binary_host {
+    name: "apicheck",
+    wrapper: "etc/apicheck",
+    static_libs: [
+        "doclava",
+        "jsilver",
+    ],
+}
diff --git a/tools/apicheck/Android.mk b/tools/apicheck/Android.mk
deleted file mode 100644
index ab3493d..0000000
--- a/tools/apicheck/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2007-2008 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 hat script
-# ============================================================
-include $(CLEAR_VARS)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE := apicheck
-LOCAL_SRC_FILES := etc/apicheck
-LOCAL_REQUIRED_MODULES := doclava
-include $(BUILD_PREBUILT)
-
-# Apicheck is now part of Doclava -- See external/doclava.
diff --git a/tools/checkowners.py b/tools/checkowners.py
index 1190d30..54198a7 100755
--- a/tools/checkowners.py
+++ b/tools/checkowners.py
@@ -30,12 +30,11 @@
 
 def find_address(address):
   if address not in checked_addresses:
-    request = (gerrit_server + '/accounts/?n=1&o=ALL_EMAILS&q=email:'
+    request = (gerrit_server + '/accounts/?n=1&q=email:'
                + urllib.quote(address))
     echo('Checking email address: ' + address)
     result = urllib2.urlopen(request).read()
-    checked_addresses[address] = (
-        result.find('"email":') >= 0 and result.find('"_account_id":') >= 0)
+    checked_addresses[address] = result.find('"_account_id":') >= 0
   return checked_addresses[address]
 
 
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index ec65aaf..8a4ab94 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -21,5 +21,6 @@
 COPY gitconfig /home/$username/.gitconfig
 RUN chown $userid:$groupid /home/$username/.gitconfig
 ENV HOME=/home/$username
+ENV USER=$username
 
 ENTRYPOINT chroot --userspec=$(cat /root/username):$(cat /root/username) / /bin/bash -i
diff --git a/tools/droiddoc/test/generics/Android.mk b/tools/droiddoc/test/generics/Android.mk
deleted file mode 100644
index 0c808fd..0000000
--- a/tools/droiddoc/test/generics/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2008 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)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=$(call all-subdir-java-files)
-
-LOCAL_MODULE:=test_generics
-LOCAL_DROIDDOC_OPTIONS:=\
-        -stubs __test_generics__
-
-LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=tools/droiddoc/templates-google
-LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=assets-google
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-
-include $(BUILD_DROIDDOC)
diff --git a/tools/droiddoc/test/stubs/Android.mk b/tools/droiddoc/test/stubs/Android.mk
deleted file mode 100644
index fc971e1..0000000
--- a/tools/droiddoc/test/stubs/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2008 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)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=$(call all-java-files-under,src)
-
-LOCAL_MODULE:=test_stubs
-LOCAL_DROIDDOC_OPTIONS:=\
-        -stubs $(OUT_DIR)/__test_stubs__
-
-LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=tools/droiddoc/templates-google
-LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=assets-google
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-
-include $(BUILD_DROIDDOC)
-
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index a01e702..cb32b9e 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -63,6 +63,8 @@
 my_fs_config_h := $(LOCAL_PATH)/default/$(ANDROID_FS_CONFIG_H)
 endif
 
+system_android_filesystem_config := system/core/include/private/android_filesystem_config.h
+
 ##################################
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := fs_config_generate.c
@@ -72,8 +74,6 @@
 LOCAL_CFLAGS := -Werror -Wno-error=\#warnings
 
 ifneq ($(TARGET_FS_CONFIG_GEN),)
-system_android_filesystem_config := system/core/include/private/android_filesystem_config.h
-
 # Generate the "generated_oem_aid.h" file
 oem := $(local-generated-sources-dir)/generated_oem_aid.h
 $(oem): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
@@ -111,13 +111,57 @@
   $(if $(BOARD_USES_ODMIMAGE)$(BOARD_ODMIMAGE_FILE_SYSTEM_TYPE),odm))
 
 ##################################
-# Generate the system/etc/fs_config_dirs binary file for the target
-# Add fs_config_dirs to PRODUCT_PACKAGES in the device make file to enable
+# Generate the <p>/etc/fs_config_dirs binary files for each partition.
+# Add fs_config_dirs to PRODUCT_PACKAGES in the device make file to enable.
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_dirs
+LOCAL_REQUIRED_MODULES := \
+	fs_config_dirs_system \
+	$(foreach t,$(fs_config_generate_extra_partition_list),$(LOCAL_MODULE)_$(t))
+include $(BUILD_PHONY_PACKAGE)
+
+
+##################################
+# Generate the <p>/etc/fs_config_files binary files for each partition.
+# Add fs_config_files to PRODUCT_PACKAGES in the device make file to enable.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_files
+LOCAL_REQUIRED_MODULES := \
+  fs_config_files_system \
+  $(foreach t,$(fs_config_generate_extra_partition_list),$(LOCAL_MODULE)_$(t))
+include $(BUILD_PHONY_PACKAGE)
+
+##################################
+# Generate the <p>/etc/fs_config_dirs binary files for all enabled partitions
+# excluding /system. Add fs_config_dirs_nonsystem to PRODUCT_PACKAGES in the
+# device make file to enable.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_dirs_nonsystem
+LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),fs_config_dirs_$(t))
+include $(BUILD_PHONY_PACKAGE)
+
+##################################
+# Generate the <p>/etc/fs_config_files binary files for all enabled partitions
+# excluding /system. Add fs_config_files_nonsystem to PRODUCT_PACKAGES in the
+# device make file to enable.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_files_nonsystem
+LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),fs_config_files_$(t))
+include $(BUILD_PHONY_PACKAGE)
+
+##################################
+# Generate the system/etc/fs_config_dirs binary file for the target
+# Add fs_config_dirs or fs_config_dirs_system to PRODUCT_PACKAGES in
+# the device make file to enable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_dirs_system
 LOCAL_MODULE_CLASS := ETC
-LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),$(LOCAL_MODULE)_$(t))
+LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 include $(BUILD_SYSTEM)/base_rules.mk
 $(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
 	@mkdir -p $(dir $@)
@@ -127,12 +171,13 @@
 
 ##################################
 # Generate the system/etc/fs_config_files binary file for the target
-# Add fs_config_files to PRODUCT_PACKAGES in the device make file to enable
+# Add fs_config_files or fs_config_files_system to PRODUCT_PACKAGES in
+# the device make file to enable
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := fs_config_files
+LOCAL_MODULE := fs_config_files_system
 LOCAL_MODULE_CLASS := ETC
-LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),$(LOCAL_MODULE)_$(t))
+LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 include $(BUILD_SYSTEM)/base_rules.mk
 $(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
 	@mkdir -p $(dir $@)
@@ -239,19 +284,17 @@
 
 endif
 
-# The newer passwd/group targets are only generated if you
-# use the new TARGET_FS_CONFIG_GEN method.
-ifneq ($(TARGET_FS_CONFIG_GEN),)
-
 ##################################
 # Build the oemaid header library when fs config files are present.
 # Intentionally break build if you require generated AIDs
 # header file, but are not using any fs config files.
+ifneq ($(TARGET_FS_CONFIG_GEN),)
 include $(CLEAR_VARS)
 LOCAL_MODULE := oemaids_headers
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(dir $(my_gen_oem_aid))
 LOCAL_EXPORT_C_INCLUDE_DEPS := $(my_gen_oem_aid)
 include $(BUILD_HEADER_LIBRARY)
+endif
 
 ##################################
 # Generate the vendor/etc/passwd text file for the target
@@ -265,8 +308,11 @@
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
-$(LOCAL_BUILT_MODULE): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
+ifneq ($(TARGET_FS_CONFIG_GEN),)
 $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
+else
+$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := /dev/null
+endif
 $(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
 $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config)
 	@mkdir -p $(dir $@)
@@ -284,15 +330,17 @@
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
-$(LOCAL_BUILT_MODULE): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
+ifneq ($(TARGET_FS_CONFIG_GEN),)
 $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
+else
+$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := /dev/null
+endif
 $(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
 $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config)
 	@mkdir -p $(dir $@)
 	$(hide) $< group --required-prefix=vendor_ --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
 
 system_android_filesystem_config :=
-endif
 
 ANDROID_FS_CONFIG_H :=
 my_fs_config_h :=
diff --git a/tools/fs_config/fs_config_generator.py b/tools/fs_config/fs_config_generator.py
index 4839578..cd534ec 100755
--- a/tools/fs_config/fs_config_generator.py
+++ b/tools/fs_config/fs_config_generator.py
@@ -138,13 +138,13 @@
         'media_codec': 'mediacodec'
     }
 
-    def __init__(self, identifier, value, found):
+    def __init__(self, identifier, value, found, login_shell):
         """
         Args:
             identifier: The identifier name for a #define <identifier>.
             value: The value of the AID, aka the uid.
             found (str): The file found in, not required to be specified.
-
+            login_shell (str): The shell field per man (5) passwd file.
         Raises:
             ValueError: if the friendly name is longer than 31 characters as
                 that is bionic's internal buffer size for name.
@@ -154,6 +154,8 @@
         self.identifier = identifier
         self.value = value
         self.found = found
+        self.login_shell = login_shell
+
         try:
             self.normalized_value = str(int(value, 0))
         except ValueException:
@@ -171,7 +173,8 @@
 
         return self.identifier == other.identifier \
             and self.value == other.value and self.found == other.found \
-            and self.normalized_value == other.normalized_value
+            and self.normalized_value == other.normalized_value \
+            and self.login_shell == other.login_shell
 
     @staticmethod
     def is_friendly(name):
@@ -336,7 +339,7 @@
             ValueError: With message set to indicate the error.
         """
 
-        aid = AID(identifier, value, self._aid_header)
+        aid = AID(identifier, value, self._aid_header, '/system/bin/sh')
 
         # duplicate name
         if aid.friendly in self._aid_name_to_value:
@@ -647,7 +650,7 @@
             sys.exit(error_message('Found specified but unset "value"'))
 
         try:
-            aid = AID(section_name, value, file_name)
+            aid = AID(section_name, value, file_name, '/vendor/bin/sh')
         except ValueError as exception:
             sys.exit(error_message(exception))
 
@@ -1280,7 +1283,7 @@
         except ValueError as exception:
             sys.exit(exception)
 
-        print "%s::%s:%s::/:/system/bin/sh" % (logon, uid, uid)
+        print "%s::%s:%s::/:%s" % (logon, uid, uid, aid.login_shell)
 
 
 @generator('group')
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index f68976e..8ac039f 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -405,7 +405,7 @@
         if os.path.exists(image_path):
           continue
         found = False
-        for dir_name in ['IMAGES', 'RADIO', 'VENDOR_IMAGES', 'PREBUILT_IMAGES']:
+        for dir_name in ['IMAGES', 'RADIO', 'PREBUILT_IMAGES']:
           alt_path = os.path.join(
               OPTIONS.input_tmp, dir_name, os.path.basename(image_path))
           if os.path.exists(alt_path):
@@ -415,9 +415,10 @@
         assert found, 'failed to find %s' % (image_path,)
     cmd.extend(split_args)
 
-  p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-  p.communicate()
-  assert p.returncode == 0, "avbtool make_vbmeta_image failed"
+  p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+  stdoutdata, _ = p.communicate()
+  assert p.returncode == 0, \
+      "avbtool make_vbmeta_image failed:\n{}".format(stdoutdata)
   img.Write()
 
 
@@ -427,7 +428,7 @@
   img = OutputFile(
       output_zip, OPTIONS.input_tmp, "IMAGES", "partition-table.img")
   bpt = OutputFile(
-      output_zip, OPTIONS.input_tmp, "IMAGES", "partition-table.bpt")
+      output_zip, OPTIONS.input_tmp, "META", "partition-table.bpt")
 
   # use BPTTOOL from environ, or "bpttool" if empty or not set.
   bpttool = os.getenv("BPTTOOL") or "bpttool"
@@ -444,9 +445,10 @@
   if args:
     cmd.extend(shlex.split(args))
 
-  p = common.Run(cmd, stdout=subprocess.PIPE)
-  p.communicate()
-  assert p.returncode == 0, "bpttool make_table failed"
+  p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+  stdoutdata, _ = p.communicate()
+  assert p.returncode == 0, \
+      "bpttool make_table failed:\n{}".format(stdoutdata)
 
   img.Write()
   bpt.Write()
@@ -485,19 +487,15 @@
   img.Write()
 
 
-def AddRadioImagesForAbOta(output_zip, ab_partitions):
-  """Adds the radio images needed for A/B OTA to the output file.
+def CheckAbOtaImages(output_zip, ab_partitions):
+  """Checks that all the listed A/B partitions have their images available.
 
-  It parses the list of A/B partitions, looks for the missing ones from RADIO/
-  or VENDOR_IMAGES/ dirs, and copies them to IMAGES/ of the output file (or
-  dir).
-
-  It also ensures that on returning from the function all the listed A/B
-  partitions must have their images available under IMAGES/.
+  The images need to be available under IMAGES/ or RADIO/, with the former takes
+  a priority.
 
   Args:
     output_zip: The output zip file (needs to be already open), or None to
-        write images to OPTIONS.input_tmp/.
+        find images in OPTIONS.input_tmp/.
     ab_partitions: The list of A/B partitions.
 
   Raises:
@@ -505,38 +503,20 @@
   """
   for partition in ab_partitions:
     img_name = partition.strip() + ".img"
-    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
-    if os.path.exists(prebuilt_path):
-      print("%s already exists, no need to overwrite..." % (img_name,))
-      continue
-
-    img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
-    if os.path.exists(img_radio_path):
-      if output_zip:
-        common.ZipWrite(output_zip, img_radio_path, "IMAGES/" + img_name)
-      else:
-        shutil.copy(img_radio_path, prebuilt_path)
-      continue
-
-    # Walk through VENDOR_IMAGES/ since files could be under subdirs.
-    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),
-                          "IMAGES/" + img_name)
-        else:
-          shutil.copy(os.path.join(root, img_name), prebuilt_path)
-        break
 
     # Assert that the image is present under IMAGES/ now.
     if output_zip:
       # Zip spec says: All slashes MUST be forward slashes.
-      img_path = 'IMAGES/' + img_name
-      assert img_path in output_zip.namelist(), "cannot find " + img_name
+      images_path = "IMAGES/" + img_name
+      radio_path = "RADIO/" + img_name
+      available = (images_path in output_zip.namelist() or
+                   radio_path in output_zip.namelist())
     else:
-      img_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
-      assert os.path.exists(img_path), "cannot find " + img_name
+      images_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
+      radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
+      available = os.path.exists(images_path) or os.path.exists(radio_path)
+
+    assert available, "Failed to find " + img_name
 
 
 def AddCareMapTxtForAbOta(output_zip, ab_partitions, image_paths):
@@ -763,10 +743,9 @@
     with open(ab_partitions_txt, 'r') as f:
       ab_partitions = f.readlines()
 
-    # 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
-    # images ready under IMAGES/. All images should have '.img' as extension.
-    AddRadioImagesForAbOta(output_zip, ab_partitions)
+    # For devices using A/B update, make sure we have all the needed images
+    # ready under IMAGES/ or RADIO/.
+    CheckAbOtaImages(output_zip, ab_partitions)
 
     # Generate care_map.txt for system and vendor partitions (if present), then
     # write this file to target_files package.
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 24c5b2d..e82e66a 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -270,7 +270,6 @@
   USED_IMGDIFF_LARGE_APK = "Large APK files split and diff'd with imgdiff"
 
   # Reasons for not applying imgdiff on APKs.
-  SKIPPED_TRIMMED = "Not used imgdiff due to trimmed RangeSet"
   SKIPPED_NONMONOTONIC = "Not used imgdiff due to having non-monotonic ranges"
   SKIPPED_SHARED_BLOCKS = "Not used imgdiff due to using shared blocks"
   SKIPPED_INCOMPLETE = "Not used imgdiff due to incomplete RangeSet"
@@ -279,7 +278,6 @@
   REASONS = (
       USED_IMGDIFF,
       USED_IMGDIFF_LARGE_APK,
-      SKIPPED_TRIMMED,
       SKIPPED_NONMONOTONIC,
       SKIPPED_SHARED_BLOCKS,
       SKIPPED_INCOMPLETE,
@@ -449,10 +447,6 @@
       self.imgdiff_stats.Log(name, ImgdiffStats.SKIPPED_INCOMPLETE)
       return False
 
-    if tgt_ranges.extra.get('trimmed') or src_ranges.extra.get('trimmed'):
-      self.imgdiff_stats.Log(name, ImgdiffStats.SKIPPED_TRIMMED)
-      return False
-
     reason = (ImgdiffStats.USED_IMGDIFF_LARGE_APK if large_apk
               else ImgdiffStats.USED_IMGDIFF)
     self.imgdiff_stats.Log(name, reason)
@@ -836,14 +830,10 @@
                   str(xf.tgt_ranges), str(xf.src_ranges)))
           else:
             if xf.patch:
-              # We have already generated the patch with imgdiff. Check if the
-              # transfer is intact.
+              # We have already generated the patch with imgdiff, while
+              # splitting large APKs (i.e. in FindTransfers()).
               assert not self.disable_imgdiff
               imgdiff = True
-              if (xf.src_ranges.extra.get('trimmed') or
-                  xf.tgt_ranges.extra.get('trimmed')):
-                imgdiff = False
-                xf.patch = None
             else:
               imgdiff = self.CanUseImgdiff(
                   xf.tgt_name, xf.tgt_ranges, xf.src_ranges)
@@ -1045,42 +1035,6 @@
     for i, xf in enumerate(L):
       xf.order = i
 
-  def RemoveBackwardEdges(self):
-    print("Removing backward edges...")
-    in_order = 0
-    out_of_order = 0
-    lost_source = 0
-
-    for xf in self.transfers:
-      lost = 0
-      size = xf.src_ranges.size()
-      for u in xf.goes_before:
-        # xf should go before u
-        if xf.order < u.order:
-          # it does, hurray!
-          in_order += 1
-        else:
-          # it doesn't, boo.  trim the blocks that u writes from xf's
-          # source, so that xf can go after u.
-          out_of_order += 1
-          assert xf.src_ranges.overlaps(u.tgt_ranges)
-          xf.src_ranges = xf.src_ranges.subtract(u.tgt_ranges)
-          xf.src_ranges.extra['trimmed'] = True
-
-      if xf.style == "diff" and not xf.src_ranges:
-        # nothing left to diff from; treat as new data
-        xf.style = "new"
-
-      lost = size - xf.src_ranges.size()
-      lost_source += lost
-
-    print(("  %d/%d dependencies (%.2f%%) were violated; "
-           "%d source blocks removed.") %
-          (out_of_order, in_order + out_of_order,
-           (out_of_order * 100.0 / (in_order + out_of_order))
-           if (in_order + out_of_order) else 0.0,
-           lost_source))
-
   def ReverseBackwardEdges(self):
     """Reverse unsatisfying edges and compute pairs of stashed blocks.
 
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index ca96d01..8e20859 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -18,8 +18,10 @@
 Builds output_image from the given input_directory, properties_file,
 and writes the image to target_output_directory.
 
+If argument generated_prop_file exists, write additional properties to the file.
+
 Usage:  build_image.py input_directory properties_file output_image \\
-            target_output_directory
+            target_output_directory [generated_prop_file]
 """
 
 from __future__ import print_function
@@ -40,22 +42,29 @@
 
 FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
 BLOCK_SIZE = 4096
+BYTES_IN_MB = 1024 * 1024
 
 
-def RunCommand(cmd, verbose=None):
+def RunCommand(cmd, verbose=None, env=None):
   """Echo and run the given command.
 
   Args:
     cmd: the command represented as a list of strings.
     verbose: show commands being executed.
+    env: a dictionary of additional environment variables.
   Returns:
     A tuple of the output and the exit code.
   """
+  env_copy = None
+  if env is not None:
+    env_copy = os.environ.copy()
+    env_copy.update(env)
   if verbose is None:
     verbose = OPTIONS.verbose
   if verbose:
     print("Running: " + " ".join(cmd))
-  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+                       env=env_copy)
   output, _ = p.communicate()
 
   if verbose:
@@ -80,8 +89,7 @@
 
 
 def GetVerityMetadataSize(partition_size):
-  cmd = ["system/extras/verity/build_verity_metadata.py", "size",
-         str(partition_size)]
+  cmd = ["build_verity_metadata.py", "size", str(partition_size)]
   output, exit_code = RunCommand(cmd, False)
   if exit_code != 0:
     return False, 0
@@ -104,6 +112,24 @@
   return verity_size
 
 
+def GetDiskUsage(path):
+  """Return number of bytes that "path" occupies on host.
+
+  Args:
+    path: The directory or file to calculate size on
+  Returns:
+    True and the number of bytes if successful,
+    False and 0 otherwise.
+  """
+  env = {"POSIXLY_CORRECT": "1"}
+  cmd = ["du", "-s", path]
+  output, exit_code = RunCommand(cmd, verbose=False, env=env)
+  if exit_code != 0:
+    return False, 0
+  # POSIX du returns number of blocks with block size 512
+  return True, int(output.split()[0]) * 512
+
+
 def GetSimgSize(image_file):
   simg = sparse_img.SparseImage(image_file, build_map=False)
   return simg.blocksize * simg.total_blocks
@@ -250,9 +276,8 @@
 def BuildVerityMetadata(image_size, verity_metadata_path, root_hash, salt,
                         block_device, signer_path, key, signer_args,
                         verity_disable):
-  cmd = ["system/extras/verity/build_verity_metadata.py", "build",
-         str(image_size), verity_metadata_path, root_hash, salt, block_device,
-         signer_path, key]
+  cmd = ["build_verity_metadata.py", "build", str(image_size),
+         verity_metadata_path, root_hash, salt, block_device, signer_path, key]
   if signer_args:
     cmd.append("--signer_args=\"%s\"" % (' '.join(signer_args),))
   if verity_disable:
@@ -444,6 +469,8 @@
 
 def BuildImage(in_dir, prop_dict, out_file, target_out=None):
   """Build an image to out_file from in_dir with property prop_dict.
+  After the function call, values in prop_dict is updated with
+  computed values.
 
   Args:
     in_dir: path of input directory.
@@ -488,6 +515,21 @@
   verity_supported = prop_dict.get("verity") == "true"
   verity_fec_supported = prop_dict.get("verity_fec") == "true"
 
+  if (prop_dict.get("use_logical_partitions") == "true" and
+      "partition_size" not in prop_dict):
+    # if partition_size is not defined, use output of `du' + reserved_size
+    success, size = GetDiskUsage(origin_in)
+    if not success:
+      return False
+    if OPTIONS.verbose:
+      print("The tree size of %s is %d MB." % (origin_in, size // BYTES_IN_MB))
+    size += int(prop_dict.get("partition_reserved_size", 0))
+    # Round this up to a multiple of 4K so that avbtool works
+    size = common.RoundUpTo4K(size)
+    prop_dict["partition_size"] = str(size)
+    if OPTIONS.verbose:
+      print("Allocating %d MB for %s." % (size // BYTES_IN_MB, out_file))
+
   # Adjust the partition size to make room for the hashes if this is to be
   # verified.
   if verity_supported and is_verity_partition:
@@ -615,6 +657,17 @@
   if exit_code != 0:
     print("Error: '%s' failed with exit code %d:\n%s" % (
         build_command, exit_code, mkfs_output))
+    success, du = GetDiskUsage(origin_in)
+    du_str = ("%d bytes (%d MB)" % (du, du // BYTES_IN_MB)
+             ) if success else "unknown"
+    print("Out of space? The tree size of %s is %s." % (
+        origin_in, du_str))
+    print("The max is %d bytes (%d MB)." % (
+        int(prop_dict["partition_size"]),
+        int(prop_dict["partition_size"]) // BYTES_IN_MB))
+    print("Reserved space is %d bytes (%d MB)." % (
+        int(prop_dict.get("partition_reserved_size", 0)),
+        int(prop_dict.get("partition_reserved_size", 0)) // BYTES_IN_MB))
     return False
 
   # Check if there's enough headroom space available for ext4 image.
@@ -715,6 +768,7 @@
       "avb_enable",
       "avb_avbtool",
       "avb_salt",
+      "use_logical_partitions",
   )
   for p in common_props:
     copy_prop(p, p)
@@ -747,6 +801,7 @@
     copy_prop("system_extfs_inode_count", "extfs_inode_count")
     if not copy_prop("system_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
+    copy_prop("system_reserved_size", "partition_reserved_size")
   elif mount_point == "system_other":
     # We inherit the selinux policies of /system since we contain some of its
     # files.
@@ -769,6 +824,7 @@
     copy_prop("system_extfs_inode_count", "extfs_inode_count")
     if not copy_prop("system_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
+    copy_prop("system_reserved_size", "partition_reserved_size")
   elif mount_point == "data":
     # Copy the generic fs type first, override with specific one if available.
     copy_prop("fs_type", "fs_type")
@@ -799,6 +855,7 @@
     copy_prop("vendor_extfs_inode_count", "extfs_inode_count")
     if not copy_prop("vendor_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
+    copy_prop("vendor_reserved_size", "partition_reserved_size")
   elif mount_point == "product":
     copy_prop("avb_product_hashtree_enable", "avb_hashtree_enable")
     copy_prop("avb_product_add_hashtree_footer_args",
@@ -844,8 +901,29 @@
   return d
 
 
+def GlobalDictFromImageProp(image_prop, mount_point):
+  d = {}
+  def copy_prop(src_p, dest_p):
+    if src_p in image_prop:
+      d[dest_p] = image_prop[src_p]
+      return True
+    return False
+  if mount_point == "system":
+    copy_prop("partition_size", "system_size")
+  elif mount_point == "system_other":
+    copy_prop("partition_size", "system_size")
+  elif mount_point == "vendor":
+    copy_prop("partition_size", "vendor_size")
+  return d
+
+
+def SaveGlobalDict(filename, glob_dict):
+  with open(filename, "w") as f:
+    f.writelines(["%s=%s" % (key, value) for (key, value) in glob_dict.items()])
+
+
 def main(argv):
-  if len(argv) != 4:
+  if len(argv) < 4 or len(argv) > 5:
     print(__doc__)
     sys.exit(1)
 
@@ -853,6 +931,7 @@
   glob_dict_file = argv[1]
   out_file = argv[2]
   target_out = argv[3]
+  prop_file_out = argv[4] if len(argv) >= 5 else None
 
   glob_dict = LoadGlobalDict(glob_dict_file)
   if "mount_point" in glob_dict:
@@ -887,6 +966,9 @@
           file=sys.stderr)
     sys.exit(1)
 
+  if prop_file_out:
+    glob_dict_out = GlobalDictFromImageProp(image_properties, mount_point)
+    SaveGlobalDict(prop_file_out, glob_dict_out)
 
 if __name__ == '__main__':
   try:
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 6defb2b..364d6ac 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -109,6 +109,7 @@
   TUNE_PARTITION_FAILURE = 3007
   APPLY_PATCH_FAILURE = 3008
 
+
 class ExternalError(RuntimeError):
   pass
 
@@ -596,11 +597,12 @@
     cmd = ["unzip", "-o", "-q", filename, "-d", dirname]
     if pattern is not None:
       cmd.extend(pattern)
-    p = Run(cmd, stdout=subprocess.PIPE)
-    p.communicate()
+    p = Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    stdoutdata, _ = p.communicate()
     if p.returncode != 0:
-      raise ExternalError("failed to unzip input target-files \"%s\"" %
-                          (filename,))
+      raise ExternalError(
+          "Failed to unzip input target-files \"{}\":\n{}".format(
+              filename, stdoutdata))
 
   tmp = MakeTempDir(prefix="targetfiles-")
   m = re.match(r"^(.*[.]zip)\+(.*[.]zip)$", filename, re.IGNORECASE)
@@ -652,12 +654,25 @@
   # if they contain all zeros. We can't reconstruct such a file from its block
   # list. Tag such entries accordingly. (Bug: 65213616)
   for entry in image.file_map:
-    # "/system/framework/am.jar" => "SYSTEM/framework/am.jar".
-    arcname = string.replace(entry, which, which.upper(), 1)[1:]
     # Skip artificial names, such as "__ZERO", "__NONZERO-1".
-    if arcname not in input_zip.namelist():
+    if not entry.startswith('/'):
       continue
 
+    # "/system/framework/am.jar" => "SYSTEM/framework/am.jar". Note that when
+    # using system_root_image, the filename listed in system.map may contain an
+    # additional leading slash (i.e. "//system/framework/am.jar"). Using lstrip
+    # to get consistent results.
+    arcname = string.replace(entry, which, which.upper(), 1).lstrip('/')
+
+    # Special handling another case with system_root_image, where files not
+    # under /system (e.g. "/sbin/charger") are packed under ROOT/ in a
+    # target_files.zip.
+    if which == 'system' and not arcname.startswith('SYSTEM'):
+      arcname = 'ROOT/' + arcname
+
+    assert arcname in input_zip.namelist(), \
+        "Failed to find the ZIP entry for {}".format(entry)
+
     info = input_zip.getinfo(arcname)
     ranges = image.file_map[entry]
 
@@ -723,18 +738,31 @@
 
 
 def GetMinSdkVersion(apk_name):
-  """Get the minSdkVersion delared in the APK. This can be both a decimal number
-  (API Level) or a codename.
+  """Gets the minSdkVersion declared in the APK.
+
+  It calls 'aapt' to query the embedded minSdkVersion from the given APK file.
+  This can be both a decimal number (API Level) or a codename.
+
+  Args:
+    apk_name: The APK filename.
+
+  Returns:
+    The parsed SDK version string.
+
+  Raises:
+    ExternalError: On failing to obtain the min SDK version.
   """
+  proc = Run(
+      ["aapt", "dump", "badging", apk_name], stdout=subprocess.PIPE,
+      stderr=subprocess.PIPE)
+  stdoutdata, stderrdata = proc.communicate()
+  if proc.returncode != 0:
+    raise ExternalError(
+        "Failed to obtain minSdkVersion: aapt return code {}:\n{}\n{}".format(
+            proc.returncode, stdoutdata, stderrdata))
 
-  p = Run(["aapt", "dump", "badging", apk_name], stdout=subprocess.PIPE)
-  output, err = p.communicate()
-  if err:
-    raise ExternalError("Failed to obtain minSdkVersion: aapt return code %s"
-        % (p.returncode,))
-
-  for line in output.split("\n"):
-    # Looking for lines such as sdkVersion:'23' or sdkVersion:'M'
+  for line in stdoutdata.split("\n"):
+    # Looking for lines such as sdkVersion:'23' or sdkVersion:'M'.
     m = re.match(r'sdkVersion:\'([^\']*)\'', line)
     if m:
       return m.group(1)
@@ -742,11 +770,20 @@
 
 
 def GetMinSdkVersionInt(apk_name, codename_to_api_level_map):
-  """Get the minSdkVersion declared in the APK as a number (API Level). If
-  minSdkVersion is set to a codename, it is translated to a number using the
-  provided map.
-  """
+  """Returns the minSdkVersion declared in the APK as a number (API Level).
 
+  If minSdkVersion is set to a codename, it is translated to a number using the
+  provided map.
+
+  Args:
+    apk_name: The APK filename.
+
+  Returns:
+    The parsed SDK version number.
+
+  Raises:
+    ExternalError: On failing to get the min SDK version number.
+  """
   version = GetMinSdkVersion(apk_name)
   try:
     return int(version)
@@ -755,8 +792,9 @@
     if version in codename_to_api_level_map:
       return codename_to_api_level_map[version]
     else:
-      raise ExternalError("Unknown minSdkVersion: '%s'. Known codenames: %s"
-                          % (version, codename_to_api_level_map))
+      raise ExternalError(
+          "Unknown minSdkVersion: '{}'. Known codenames: {}".format(
+              version, codename_to_api_level_map))
 
 
 def SignFile(input_name, output_name, key, password, min_api_level=None,
@@ -800,12 +838,15 @@
               key + OPTIONS.private_key_suffix,
               input_name, output_name])
 
-  p = Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+  p = Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+          stderr=subprocess.STDOUT)
   if password is not None:
     password += "\n"
-  p.communicate(password)
+  stdoutdata, _ = p.communicate(password)
   if p.returncode != 0:
-    raise ExternalError("signapk.jar failed: return code %s" % (p.returncode,))
+    raise ExternalError(
+        "Failed to run signapk.jar: return code {}:\n{}".format(
+            p.returncode, stdoutdata))
 
 
 def CheckSize(data, target, info_dict):
@@ -938,17 +979,18 @@
 
 
 COMMON_DOCSTRING = """
-  -p  (--path)  <dir>
-      Prepend <dir>/bin to the list of places to search for binaries
-      run by this script, and expect to find jars in <dir>/framework.
+Global options
+
+  -p  (--path) <dir>
+      Prepend <dir>/bin to the list of places to search for binaries run by this
+      script, and expect to find jars in <dir>/framework.
 
   -s  (--device_specific) <file>
-      Path to the python module containing device-specific
-      releasetools code.
+      Path to the Python module containing device-specific releasetools code.
 
-  -x  (--extra)  <key=value>
-      Add a key/value pair to the 'extras' dict, which device-specific
-      extension code may look at.
+  -x  (--extra) <key=value>
+      Add a key/value pair to the 'extras' dict, which device-specific extension
+      code may look at.
 
   -v  (--verbose)
       Show command lines being executed.
@@ -1716,10 +1758,11 @@
                     '--output={}.new.dat.br'.format(self.path),
                     '{}.new.dat'.format(self.path)]
       print("Compressing {}.new.dat with brotli".format(self.partition))
-      p = Run(brotli_cmd, stdout=subprocess.PIPE)
-      p.communicate()
-      assert p.returncode == 0,\
-          'compression of {}.new.dat failed'.format(self.partition)
+      p = Run(brotli_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+      stdoutdata, _ = p.communicate()
+      assert p.returncode == 0, \
+          'Failed to compress {}.new.dat with brotli:\n{}'.format(
+              self.partition, stdoutdata)
 
       new_data_name = '{}.new.dat.br'.format(self.partition)
       ZipWrite(output_zip,
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 7a81928..5c3533e 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -31,14 +31,6 @@
     else:
       self.fstab = fstab
 
-  def MakeTemporary(self):
-    """Make a temporary script object whose commands can latter be
-    appended to the parent script with AppendScript().  Used when the
-    caller wants to generate script commands out-of-order."""
-    x = EdifyGenerator(self.version, self.info)
-    x.mounts = self.mounts
-    return x
-
   @property
   def required_cache(self):
     """Return the minimum cache size to apply the update."""
@@ -181,22 +173,6 @@
         ') || abort("E%d: \\"%s\\" has unexpected contents.");' % (
             common.ErrorCode.BAD_PATCH_FILE, filename))
 
-  def Verify(self, filename):
-    """Check that the given file has one of the
-    given hashes (encoded in the filename)."""
-    self.script.append(
-        'apply_patch_check("{filename}") && '
-        'ui_print("    Verified.") || '
-        'ui_print("\\"{filename}\\" has unexpected contents.");'.format(
-            filename=filename))
-
-  def FileCheck(self, filename, *sha1):
-    """Check that the given file has one of the
-    given *sha1 hashes."""
-    self.script.append('assert(sha1_check(read_file("%s")' % (filename,) +
-                       "".join([', "%s"' % (i,) for i in sha1]) +
-                       '));')
-
   def CacheFreeSpaceCheck(self, amount):
     """Check that there's at least 'amount' space that can be made
     available on /cache."""
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 10a19b3..31f5cde 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -15,54 +15,12 @@
 # limitations under the License.
 
 """
-Given a target-files zipfile, produces an OTA package that installs
-that build.  An incremental OTA is produced if -i is given, otherwise
-a full OTA is produced.
+Given a target-files zipfile, produces an OTA package that installs that build.
+An incremental OTA is produced if -i is given, otherwise a full OTA is produced.
 
-Usage:  ota_from_target_files [flags] input_target_files output_ota_package
+Usage:  ota_from_target_files [options] input_target_files output_ota_package
 
-  -k (--package_key) <key> Key to use to sign the package (default is
-      the value of default_system_dev_certificate from the input
-      target-files's META/misc_info.txt, or
-      "build/target/product/security/testkey" if that value is not
-      specified).
-
-      For incremental OTAs, the default value is based on the source
-      target-file, not the target build.
-
-  -i  (--incremental_from)  <file>
-      Generate an incremental OTA using the given target-files zip as
-      the starting build.
-
-  --full_radio
-      When generating an incremental OTA, always include a full copy of
-      radio image. This option is only meaningful when -i is specified,
-      because a full radio is always included in a full OTA if applicable.
-
-  --full_bootloader
-      Similar to --full_radio. When generating an incremental OTA, always
-      include a full copy of bootloader image.
-
-  --verify
-      Remount and verify the checksums of the files written to the system and
-      vendor (if used) partitions. Non-A/B incremental OTAs only.
-
-  -o  (--oem_settings)  <main_file[,additional_files...]>
-      Comma seperated list of files used to specify the expected OEM-specific
-      properties on the OEM partition of the intended device. Multiple expected
-      values can be used by providing multiple files. Only the first dict will
-      be used to compute fingerprint, while the rest will be used to assert
-      OEM-specific properties.
-
-  --oem_no_mount
-      For devices with OEM-specific properties but without an OEM partition,
-      do not mount the OEM partition in the updater-script. This should be
-      very rarely used, since it's expected to have a dedicated OEM partition
-      for OEM-specific properties. Only meaningful when -o is specified.
-
-  --wipe_user_data
-      Generate an OTA package that will wipe the user data partition
-      when installed.
+Common options that apply to both of non-A/B and A/B OTAs
 
   --downgrade
       Intentionally generate an incremental OTA that updates from a newer build
@@ -73,6 +31,19 @@
       will be used in the OTA package, unless --binary flag is specified. Please
       also check the comment for --override_timestamp below.
 
+  -i  (--incremental_from) <file>
+      Generate an incremental OTA using the given target-files zip as the
+      starting build.
+
+  -k  (--package_key) <key>
+      Key to use to sign the package (default is the value of
+      default_system_dev_certificate from the input target-files's
+      META/misc_info.txt, or "build/target/product/security/testkey" if that
+      value is not specified).
+
+      For incremental OTAs, the default value is based on the source
+      target-file, not the target build.
+
   --override_timestamp
       Intentionally generate an incremental OTA that updates from a newer build
       to an older one (based on timestamp comparison), by setting the downgrade
@@ -89,13 +60,70 @@
       based on timestamp) with the same "ota-downgrade=yes" flag, with the
       difference being whether "ota-wipe=yes" is set.
 
-  -e  (--extra_script)  <file>
+  --wipe_user_data
+      Generate an OTA package that will wipe the user data partition when
+      installed.
+
+Non-A/B OTA specific options
+
+  -b  (--binary) <file>
+      Use the given binary as the update-binary in the output package, instead
+      of the binary in the build's target_files. Use for development only.
+
+  --block
+      Generate a block-based OTA for non-A/B device. We have deprecated the
+      support for file-based OTA since O. Block-based OTA will be used by
+      default for all non-A/B devices. Keeping this flag here to not break
+      existing callers.
+
+  -e  (--extra_script) <file>
       Insert the contents of file at the end of the update script.
 
+  --full_bootloader
+      Similar to --full_radio. When generating an incremental OTA, always
+      include a full copy of bootloader image.
+
+  --full_radio
+      When generating an incremental OTA, always include a full copy of radio
+      image. This option is only meaningful when -i is specified, because a full
+      radio is always included in a full OTA if applicable.
+
+  --log_diff <file>
+      Generate a log file that shows the differences in the source and target
+      builds for an incremental package. This option is only meaningful when -i
+      is specified.
+
+  -o  (--oem_settings) <main_file[,additional_files...]>
+      Comma seperated list of files used to specify the expected OEM-specific
+      properties on the OEM partition of the intended device. Multiple expected
+      values can be used by providing multiple files. Only the first dict will
+      be used to compute fingerprint, while the rest will be used to assert
+      OEM-specific properties.
+
+  --oem_no_mount
+      For devices with OEM-specific properties but without an OEM partition, do
+      not mount the OEM partition in the updater-script. This should be very
+      rarely used, since it's expected to have a dedicated OEM partition for
+      OEM-specific properties. Only meaningful when -o is specified.
+
+  --stash_threshold <float>
+      Specify the threshold that will be used to compute the maximum allowed
+      stash size (defaults to 0.8).
+
+  -t  (--worker_threads) <int>
+      Specify the number of worker-threads that will be used when generating
+      patches for incremental updates (defaults to 3).
+
+  --verify
+      Verify the checksums of the updated system and vendor (if any) partitions.
+      Non-A/B incremental OTAs only.
+
   -2  (--two_step)
-      Generate a 'two-step' OTA package, where recovery is updated
-      first, so that any changes made to the system partition are done
-      using the new recovery (new kernel, etc.).
+      Generate a 'two-step' OTA package, where recovery is updated first, so
+      that any changes made to the system partition are done using the new
+      recovery (new kernel, etc.).
+
+A/B OTA specific options
 
   --include_secondary
       Additionally include the payload for secondary slot images (default:
@@ -115,30 +143,6 @@
       Due to the special install procedure, the secondary payload will be always
       generated as a full payload.
 
-  --block
-      Generate a block-based OTA for non-A/B device. We have deprecated the
-      support for file-based OTA since O. Block-based OTA will be used by
-      default for all non-A/B devices. Keeping this flag here to not break
-      existing callers.
-
-  -b  (--binary)  <file>
-      Use the given binary as the update-binary in the output package,
-      instead of the binary in the build's target_files.  Use for
-      development only.
-
-  -t  (--worker_threads) <int>
-      Specifies the number of worker-threads that will be used when
-      generating patches for incremental updates (defaults to 3).
-
-  --stash_threshold <float>
-      Specifies the threshold that will be used to compute the maximum
-      allowed stash size (defaults to 0.8).
-
-  --log_diff <file>
-      Generate a log file that shows the differences in the source and target
-      builds for an incremental package. This option is only meaningful when
-      -i is specified.
-
   --payload_signer <signer>
       Specify the signer when signing the payload and metadata for A/B OTAs.
       By default (i.e. without this flag), it calls 'openssl pkeyutl' to sign
@@ -246,12 +250,14 @@
   def __init__(self, info_dict, oem_dicts):
     """Initializes a BuildInfo instance with the given dicts.
 
+    Note that it only wraps up the given dicts, without making copies.
+
     Arguments:
       info_dict: The build-time info dict.
       oem_dicts: A list of OEM dicts (which is parsed from --oem_settings). Note
           that it always uses the first dict to calculate the fingerprint or the
           device name. The rest would be used for asserting OEM properties only
-          (e.g.  one package can be installed on one of these devices).
+          (e.g. one package can be installed on one of these devices).
     """
     self.info_dict = info_dict
     self.oem_dicts = oem_dicts
@@ -285,9 +291,15 @@
   def __getitem__(self, key):
     return self.info_dict[key]
 
+  def __setitem__(self, key, value):
+    self.info_dict[key] = value
+
   def get(self, key, default=None):
     return self.info_dict.get(key, default)
 
+  def items(self):
+    return self.info_dict.items()
+
   def GetBuildProp(self, prop):
     """Returns the inquired build property."""
     try:
@@ -1020,7 +1032,7 @@
       A string with placeholders for the metadata offset/size info, e.g.
       "payload.bin:679:343,payload_properties.txt:378:45,metadata:        ".
     """
-    return self._GetPropertyFilesString(input_zip, reserve_space=True)
+    return self.GetPropertyFilesString(input_zip, reserve_space=True)
 
   class InsufficientSpaceException(Exception):
     pass
@@ -1049,7 +1061,7 @@
       InsufficientSpaceException: If the reserved length is insufficient to hold
           the final string.
     """
-    result = self._GetPropertyFilesString(input_zip, reserve_space=False)
+    result = self.GetPropertyFilesString(input_zip, reserve_space=False)
     if len(result) > reserved_length:
       raise self.InsufficientSpaceException(
           'Insufficient reserved space: reserved={}, actual={}'.format(
@@ -1068,12 +1080,22 @@
     Raises:
       AssertionError: On finding a mismatch.
     """
-    actual = self._GetPropertyFilesString(input_zip)
+    actual = self.GetPropertyFilesString(input_zip)
     assert actual == expected, \
         "Mismatching streaming metadata: {} vs {}.".format(actual, expected)
 
-  def _GetPropertyFilesString(self, zip_file, reserve_space=False):
-    """Constructs the property-files string per request."""
+  def GetPropertyFilesString(self, zip_file, reserve_space=False):
+    """
+    Constructs the property-files string per request.
+
+    Args:
+      zip_file: The input ZIP file.
+      reserved_length: The reserved length of the property-files string.
+
+    Returns:
+      A property-files string including the metadata offset/size info, e.g.
+      "payload.bin:679:343,payload_properties.txt:378:45,metadata:     ".
+    """
 
     def ComputeEntryOffsetSize(name):
       """Computes the zip entry offset and size."""
@@ -1503,10 +1525,16 @@
 
       common.ZipWriteStr(output_zip, "patch/boot.img.p", d)
 
+      # TODO(b/110106408): Remove after properly handling the SHA-1 embedded in
+      # the filename argument in updater code. Prior to that, explicitly list
+      # the SHA-1 of the source image, in case the updater tries to find a
+      # matching backup from /cache. Similarly for the call to
+      # script.ApplyPatch() below.
       script.PatchCheck("%s:%s:%d:%s:%d:%s" %
                         (boot_type, boot_device,
                          source_boot.size, source_boot.sha1,
-                         target_boot.size, target_boot.sha1))
+                         target_boot.size, target_boot.sha1),
+                        source_boot.sha1)
       size.append(target_boot.size)
 
   if size:
@@ -1629,9 +1657,15 @@
   target_file = common.MakeTempFile(prefix="targetfiles-", suffix=".zip")
   target_zip = zipfile.ZipFile(target_file, 'w', allowZip64=True)
 
-  input_tmp = common.UnzipTemp(input_file, UNZIP_PATTERN)
   with zipfile.ZipFile(input_file, 'r') as input_zip:
     infolist = input_zip.infolist()
+    namelist = input_zip.namelist()
+
+  # Additionally unzip 'RADIO/*' if exists.
+  unzip_pattern = UNZIP_PATTERN[:]
+  if any([entry.startswith('RADIO/') for entry in namelist]):
+    unzip_pattern.append('RADIO/*')
+  input_tmp = common.UnzipTemp(input_file, unzip_pattern)
 
   for info in infolist:
     unzipped_file = os.path.join(input_tmp, *info.filename.split('/'))
@@ -1647,7 +1681,7 @@
     elif skip_postinstall and info.filename == POSTINSTALL_CONFIG:
       pass
 
-    elif info.filename.startswith(('META/', 'IMAGES/')):
+    elif info.filename.startswith(('META/', 'IMAGES/', 'RADIO/')):
       common.ZipWrite(target_zip, unzipped_file, arcname=info.filename)
 
   common.ZipClose(target_zip)
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index fa62c8f..393c33d 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -27,6 +27,12 @@
       in the apkcerts.txt file.  Option may be repeated to give
       multiple extra packages.
 
+  --skip_apks_with_path_prefix  <prefix>
+      Skip signing an APK if it has the matching prefix in its path. The prefix
+      should be matching the entry name, which has partition names in upper
+      case, e.g. "VENDOR/app/", or "SYSTEM_OTHER/preloads/". Option may be
+      repeated to give multiple prefixes.
+
   -k  (--key_mapping)  <src_key=dest_key>
       Add a mapping from the key name as specified in apkcerts.txt (the
       src_key) to the real key you wish to sign the package with
@@ -118,6 +124,7 @@
 OPTIONS = common.OPTIONS
 
 OPTIONS.extra_apks = {}
+OPTIONS.skip_apks_with_path_prefix = set()
 OPTIONS.key_map = {}
 OPTIONS.rebuild_recovery = False
 OPTIONS.replace_ota_keys = False
@@ -144,28 +151,83 @@
   return certmap
 
 
+def GetApkFileInfo(filename, compressed_extension, skipped_prefixes):
+  """Returns the APK info based on the given filename.
+
+  Checks if the given filename (with path) looks like an APK file, by taking the
+  compressed extension into consideration. If it appears to be an APK file,
+  further checks if the APK file should be skipped when signing, based on the
+  given path prefixes.
+
+  Args:
+    filename: Path to the file.
+    compressed_extension: The extension string of compressed APKs (e.g. ".gz"),
+        or None if there's no compressed APKs.
+    skipped_prefixes: A set/list/tuple of the path prefixes to be skipped.
+
+  Returns:
+    (is_apk, is_compressed, should_be_skipped): is_apk indicates whether the
+    given filename is an APK file. is_compressed indicates whether the APK file
+    is compressed (only meaningful when is_apk is True). should_be_skipped
+    indicates whether the filename matches any of the given prefixes to be
+    skipped.
+
+  Raises:
+    AssertionError: On invalid compressed_extension or skipped_prefixes inputs.
+  """
+  assert compressed_extension is None or compressed_extension.startswith('.'), \
+      "Invalid compressed_extension arg: '{}'".format(compressed_extension)
+
+  # skipped_prefixes should be one of set/list/tuple types. Other types such as
+  # str shouldn't be accepted.
+  assert (isinstance(skipped_prefixes, tuple) or
+          isinstance(skipped_prefixes, set) or
+          isinstance(skipped_prefixes, list)), \
+              "Invalid skipped_prefixes input type: {}".format(
+                  type(skipped_prefixes))
+
+  compressed_apk_extension = (
+      ".apk" + compressed_extension if compressed_extension else None)
+  is_apk = (filename.endswith(".apk") or
+            (compressed_apk_extension and
+             filename.endswith(compressed_apk_extension)))
+  if not is_apk:
+    return (False, False, False)
+
+  is_compressed = (compressed_apk_extension and
+                   filename.endswith(compressed_apk_extension))
+  should_be_skipped = filename.startswith(tuple(skipped_prefixes))
+  return (True, is_compressed, should_be_skipped)
+
+
 def CheckAllApksSigned(input_tf_zip, apk_key_map, compressed_extension):
-  """Check that all the APKs we want to sign have keys specified, and
-  error out if they don't."""
+  """Checks that all the APKs have keys specified, otherwise errors out.
+
+  Args:
+    input_tf_zip: An open target_files zip file.
+    apk_key_map: A dict of known signing keys key'd by APK names.
+    compressed_extension: The extension string of compressed APKs, such as
+        ".gz", or None if there's no compressed APKs.
+
+  Raises:
+    AssertionError: On finding unknown APKs.
+  """
   unknown_apks = []
-  compressed_apk_extension = None
-  if compressed_extension:
-    compressed_apk_extension = ".apk" + compressed_extension
   for info in input_tf_zip.infolist():
-    if (info.filename.endswith(".apk") or
-        (compressed_apk_extension and
-         info.filename.endswith(compressed_apk_extension))):
-      name = os.path.basename(info.filename)
-      if compressed_apk_extension and name.endswith(compressed_apk_extension):
-        name = name[:-len(compressed_extension)]
-      if name not in apk_key_map:
-        unknown_apks.append(name)
-  if unknown_apks:
-    print("ERROR: no key specified for:\n")
-    print("  " + "\n  ".join(unknown_apks))
-    print("\nUse '-e <apkname>=' to specify a key (which may be an empty "
-          "string to not sign this apk).")
-    sys.exit(1)
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        info.filename, compressed_extension, OPTIONS.skip_apks_with_path_prefix)
+    if not is_apk or should_be_skipped:
+      continue
+    name = os.path.basename(info.filename)
+    if is_compressed:
+      name = name[:-len(compressed_extension)]
+    if name not in apk_key_map:
+      unknown_apks.append(name)
+
+  assert not unknown_apks, \
+      ("No key specified for:\n  {}\n"
+       "Use '-e <apkname>=' to specify a key (which may be an empty string to "
+       "not sign this apk).".format("\n  ".join(unknown_apks)))
 
 
 def SignApk(data, keyname, pw, platform_api_level, codename_to_api_level_map,
@@ -235,32 +297,33 @@
                        apk_key_map, key_passwords, platform_api_level,
                        codename_to_api_level_map,
                        compressed_extension):
-
-  compressed_apk_extension = None
-  if compressed_extension:
-    compressed_apk_extension = ".apk" + compressed_extension
-
+  # maxsize measures the maximum filename length, including the ones to be
+  # skipped.
   maxsize = max(
       [len(os.path.basename(i.filename)) for i in input_tf_zip.infolist()
-       if (i.filename.endswith('.apk') or
-           (compressed_apk_extension and
-            i.filename.endswith(compressed_apk_extension)))])
+       if GetApkFileInfo(i.filename, compressed_extension, [])[0]])
   system_root_image = misc_info.get("system_root_image") == "true"
 
   for info in input_tf_zip.infolist():
-    if info.filename.startswith("IMAGES/"):
+    filename = info.filename
+    if filename.startswith("IMAGES/"):
       continue
 
-    data = input_tf_zip.read(info.filename)
+    data = input_tf_zip.read(filename)
     out_info = copy.copy(info)
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        filename, compressed_extension, OPTIONS.skip_apks_with_path_prefix)
+
+    if is_apk and should_be_skipped:
+      # Copy skipped APKs verbatim.
+      print(
+          "NOT signing: %s\n"
+          "        (skipped due to matching prefix)" % (filename,))
+      common.ZipWriteStr(output_tf_zip, out_info, data)
 
     # Sign APKs.
-    if (info.filename.endswith(".apk") or
-        (compressed_apk_extension and
-         info.filename.endswith(compressed_apk_extension))):
-      is_compressed = (compressed_extension and
-                       info.filename.endswith(compressed_apk_extension))
-      name = os.path.basename(info.filename)
+    elif is_apk:
+      name = os.path.basename(filename)
       if is_compressed:
         name = name[:-len(compressed_extension)]
 
@@ -272,19 +335,21 @@
         common.ZipWriteStr(output_tf_zip, out_info, signed_data)
       else:
         # an APK we're not supposed to sign.
-        print("NOT signing: %s" % (name,))
+        print(
+            "NOT signing: %s\n"
+            "        (skipped due to special cert string)" % (name,))
         common.ZipWriteStr(output_tf_zip, out_info, data)
 
     # System properties.
-    elif info.filename in ("SYSTEM/build.prop",
-                           "VENDOR/build.prop",
-                           "SYSTEM/etc/prop.default",
-                           "BOOT/RAMDISK/prop.default",
-                           "BOOT/RAMDISK/default.prop",  # legacy
-                           "ROOT/default.prop",  # legacy
-                           "RECOVERY/RAMDISK/prop.default",
-                           "RECOVERY/RAMDISK/default.prop"):  # legacy
-      print("Rewriting %s:" % (info.filename,))
+    elif filename in ("SYSTEM/build.prop",
+                      "VENDOR/build.prop",
+                      "SYSTEM/etc/prop.default",
+                      "BOOT/RAMDISK/prop.default",
+                      "BOOT/RAMDISK/default.prop",  # legacy
+                      "ROOT/default.prop",  # legacy
+                      "RECOVERY/RAMDISK/prop.default",
+                      "RECOVERY/RAMDISK/default.prop"):  # legacy
+      print("Rewriting %s:" % (filename,))
       if stat.S_ISLNK(info.external_attr >> 16):
         new_data = data
       else:
@@ -293,20 +358,20 @@
 
     # Replace the certs in *mac_permissions.xml (there could be multiple, such
     # as {system,vendor}/etc/selinux/{plat,nonplat}_mac_permissions.xml).
-    elif info.filename.endswith("mac_permissions.xml"):
-      print("Rewriting %s with new keys." % (info.filename,))
+    elif filename.endswith("mac_permissions.xml"):
+      print("Rewriting %s with new keys." % (filename,))
       new_data = ReplaceCerts(data)
       common.ZipWriteStr(output_tf_zip, out_info, new_data)
 
     # Ask add_img_to_target_files to rebuild the recovery patch if needed.
-    elif info.filename in ("SYSTEM/recovery-from-boot.p",
-                           "SYSTEM/etc/recovery.img",
-                           "SYSTEM/bin/install-recovery.sh"):
+    elif filename in ("SYSTEM/recovery-from-boot.p",
+                      "SYSTEM/etc/recovery.img",
+                      "SYSTEM/bin/install-recovery.sh"):
       OPTIONS.rebuild_recovery = True
 
     # Don't copy OTA keys if we're replacing them.
     elif (OPTIONS.replace_ota_keys and
-          info.filename in (
+          filename in (
               "BOOT/RAMDISK/res/keys",
               "BOOT/RAMDISK/etc/update_engine/update-payload-key.pub.pem",
               "RECOVERY/RAMDISK/res/keys",
@@ -315,22 +380,21 @@
       pass
 
     # Skip META/misc_info.txt since we will write back the new values later.
-    elif info.filename == "META/misc_info.txt":
+    elif filename == "META/misc_info.txt":
       pass
 
     # Skip verity public key if we will replace it.
     elif (OPTIONS.replace_verity_public_key and
-          info.filename in ("BOOT/RAMDISK/verity_key",
-                            "ROOT/verity_key")):
+          filename in ("BOOT/RAMDISK/verity_key",
+                       "ROOT/verity_key")):
       pass
 
     # Skip verity keyid (for system_root_image use) if we will replace it.
-    elif (OPTIONS.replace_verity_keyid and
-          info.filename == "BOOT/cmdline"):
+    elif OPTIONS.replace_verity_keyid and filename == "BOOT/cmdline":
       pass
 
     # Skip the care_map as we will regenerate the system/vendor images.
-    elif info.filename == "META/care_map.txt":
+    elif filename == "META/care_map.txt":
       pass
 
     # A non-APK file; copy it verbatim.
@@ -763,6 +827,12 @@
       names = names.split(",")
       for n in names:
         OPTIONS.extra_apks[n] = key
+    elif o == "--skip_apks_with_path_prefix":
+      # Sanity check the prefix, which must be in all upper case.
+      prefix = a.split('/')[0]
+      if not prefix or prefix != prefix.upper():
+        raise ValueError("Invalid path prefix '%s'" % (a,))
+      OPTIONS.skip_apks_with_path_prefix.add(a)
     elif o in ("-d", "--default_key_mappings"):
       key_mapping_options.append((None, a))
     elif o in ("-k", "--key_mapping"):
@@ -822,6 +892,7 @@
       extra_opts="e:d:k:ot:",
       extra_long_opts=[
           "extra_apks=",
+          "skip_apks_with_path_prefix=",
           "default_key_mappings=",
           "key_mapping=",
           "replace_ota_keys",
diff --git a/tools/releasetools/test_add_img_to_target_files.py b/tools/releasetools/test_add_img_to_target_files.py
index 9a0f78e..a9c7f7c 100644
--- a/tools/releasetools/test_add_img_to_target_files.py
+++ b/tools/releasetools/test_add_img_to_target_files.py
@@ -22,8 +22,7 @@
 import common
 import test_utils
 from add_img_to_target_files import (
-    AddCareMapTxtForAbOta, AddPackRadioImages, AddRadioImagesForAbOta,
-    GetCareMap)
+    AddCareMapTxtForAbOta, AddPackRadioImages, CheckAbOtaImages, GetCareMap)
 from rangelib import RangeSet
 
 
@@ -55,73 +54,25 @@
       os.mkdir(images_path)
     return images, images_path
 
-  def test_AddRadioImagesForAbOta_imageExists(self):
+  def test_CheckAbOtaImages_imageExistsUnderImages(self):
     """Tests the case with existing images under IMAGES/."""
-    images, images_path = self._create_images(['aboot', 'xbl'], 'IMAGES')
-    AddRadioImagesForAbOta(None, images)
+    images, _ = self._create_images(['aboot', 'xbl'], 'IMAGES')
+    CheckAbOtaImages(None, images)
 
-    for image in images:
-      self.assertTrue(
-          os.path.exists(os.path.join(images_path, image + '.img')))
+  def test_CheckAbOtaImages_imageExistsUnderRadio(self):
+    """Tests the case with some image under RADIO/."""
+    images, _ = self._create_images(['system', 'vendor'], 'IMAGES')
+    radio_path = os.path.join(OPTIONS.input_tmp, 'RADIO')
+    if not os.path.exists(radio_path):
+      os.mkdir(radio_path)
+    with open(os.path.join(radio_path, 'modem.img'), 'wb') as image_fp:
+      image_fp.write('modem'.encode())
+    CheckAbOtaImages(None, images + ['modem'])
 
-  def test_AddRadioImagesForAbOta_copyFromRadio(self):
-    """Tests the case that copies images from RADIO/."""
-    images, images_path = self._create_images(['aboot', 'xbl'], 'RADIO')
-    AddRadioImagesForAbOta(None, images)
-
-    for image in images:
-      self.assertTrue(
-          os.path.exists(os.path.join(images_path, image + '.img')))
-
-  def test_AddRadioImagesForAbOta_copyFromRadio_zipOutput(self):
+  def test_CheckAbOtaImages_missingImages(self):
     images, _ = self._create_images(['aboot', 'xbl'], 'RADIO')
-
-    # Set up the output zip.
-    output_file = common.MakeTempFile(suffix='.zip')
-    with zipfile.ZipFile(output_file, 'w') as output_zip:
-      AddRadioImagesForAbOta(output_zip, images)
-
-    with zipfile.ZipFile(output_file, 'r') as verify_zip:
-      for image in images:
-        self.assertIn('IMAGES/' + image + '.img', verify_zip.namelist())
-
-  def test_AddRadioImagesForAbOta_copyFromVendorImages(self):
-    """Tests the case that copies images from VENDOR_IMAGES/."""
-    vendor_images_path = os.path.join(OPTIONS.input_tmp, 'VENDOR_IMAGES')
-    os.mkdir(vendor_images_path)
-
-    partitions = ['aboot', 'xbl']
-    for index, partition in enumerate(partitions):
-      subdir = os.path.join(vendor_images_path, 'subdir-{}'.format(index))
-      os.mkdir(subdir)
-
-      partition_image_path = os.path.join(subdir, partition + '.img')
-      with open(partition_image_path, 'wb') as partition_fp:
-        partition_fp.write(partition.encode())
-
-    # Set up the output dir.
-    images_path = os.path.join(OPTIONS.input_tmp, 'IMAGES')
-    os.mkdir(images_path)
-
-    AddRadioImagesForAbOta(None, partitions)
-
-    for partition in partitions:
-      self.assertTrue(
-          os.path.exists(os.path.join(images_path, partition + '.img')))
-
-  def test_AddRadioImagesForAbOta_missingImages(self):
-    images, _ = self._create_images(['aboot', 'xbl'], 'RADIO')
-    self.assertRaises(AssertionError, AddRadioImagesForAbOta, None,
-                      images + ['baz'])
-
-  def test_AddRadioImagesForAbOta_missingImages_zipOutput(self):
-    images, _ = self._create_images(['aboot', 'xbl'], 'RADIO')
-
-    # Set up the output zip.
-    output_file = common.MakeTempFile(suffix='.zip')
-    with zipfile.ZipFile(output_file, 'w') as output_zip:
-      self.assertRaises(AssertionError, AddRadioImagesForAbOta, output_zip,
-                        images + ['baz'])
+    self.assertRaises(
+        AssertionError, CheckAbOtaImages, None, images + ['baz'])
 
   def test_AddPackRadioImages(self):
     images, images_path = self._create_images(['foo', 'bar'], 'RADIO')
diff --git a/tools/releasetools/test_blockimgdiff.py b/tools/releasetools/test_blockimgdiff.py
index ceada18..124b4d5 100644
--- a/tools/releasetools/test_blockimgdiff.py
+++ b/tools/releasetools/test_blockimgdiff.py
@@ -203,8 +203,8 @@
 
     self.assertDictEqual(
         {
-            ImgdiffStats.USED_IMGDIFF : {"/system/app/app1.apk"},
-            ImgdiffStats.USED_IMGDIFF_LARGE_APK : {"/vendor/app/app2.apk"},
+            ImgdiffStats.USED_IMGDIFF: {"/system/app/app1.apk"},
+            ImgdiffStats.USED_IMGDIFF_LARGE_APK: {"/vendor/app/app2.apk"},
         },
         block_image_diff.imgdiff_stats.stats)
 
@@ -229,13 +229,6 @@
             "/system/app/app2.apk", RangeSet("10-15"),
             RangeSet("15-20 30 10-14")))
 
-    # At least one of the ranges has been modified.
-    src_ranges = RangeSet("0-5")
-    src_ranges.extra['trimmed'] = True
-    self.assertFalse(
-        block_image_diff.CanUseImgdiff(
-            "/vendor/app/app3.apk", RangeSet("10-15"), src_ranges))
-
     # At least one of the ranges is incomplete.
     src_ranges = RangeSet("0-5")
     src_ranges.extra['incomplete'] = True
@@ -246,8 +239,7 @@
     # The stats are correctly logged.
     self.assertDictEqual(
         {
-            ImgdiffStats.SKIPPED_NONMONOTONIC : {'/system/app/app2.apk'},
-            ImgdiffStats.SKIPPED_TRIMMED : {'/vendor/app/app3.apk'},
+            ImgdiffStats.SKIPPED_NONMONOTONIC: {'/system/app/app2.apk'},
             ImgdiffStats.SKIPPED_INCOMPLETE: {'/vendor/app/app4.apk'},
         },
         block_image_diff.imgdiff_stats.stats)
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index fb26b66..1c75d19 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -504,6 +504,23 @@
       actual = common.ParseCertificate(cert_fp.read())
     self.assertEqual(expected, actual)
 
+  def test_GetMinSdkVersion(self):
+    test_app = os.path.join(self.testdata_dir, 'TestApp.apk')
+    self.assertEqual('24', common.GetMinSdkVersion(test_app))
+
+  def test_GetMinSdkVersion_invalidInput(self):
+    self.assertRaises(
+        common.ExternalError, common.GetMinSdkVersion, 'does-not-exist.apk')
+
+  def test_GetMinSdkVersionInt(self):
+    test_app = os.path.join(self.testdata_dir, 'TestApp.apk')
+    self.assertEqual(24, common.GetMinSdkVersionInt(test_app, {}))
+
+  def test_GetMinSdkVersionInt_invalidInput(self):
+    self.assertRaises(
+        common.ExternalError, common.GetMinSdkVersionInt, 'does-not-exist.apk',
+        {})
+
 
 class CommonUtilsTest(unittest.TestCase):
 
@@ -645,6 +662,74 @@
     self.assertFalse(sparse_image.file_map['/system/file1'].extra)
     self.assertTrue(sparse_image.file_map['/system/file2'].extra['incomplete'])
 
+  def test_GetSparseImage_systemRootImage_filenameWithExtraLeadingSlash(self):
+    target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
+    with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+      target_files_zip.write(
+          test_utils.construct_sparse_image([(0xCAC2, 16)]),
+          arcname='IMAGES/system.img')
+      target_files_zip.writestr(
+          'IMAGES/system.map',
+          '\n'.join([
+              '//system/file1 1-5 9-10',
+              '//system/file2 11-12',
+              '/system/app/file3 13-15']))
+      target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 7))
+      # '/system/file2' has less blocks listed (2) than actual (3).
+      target_files_zip.writestr('SYSTEM/file2', os.urandom(4096 * 3))
+      # '/system/app/file3' has less blocks listed (3) than actual (4).
+      target_files_zip.writestr('SYSTEM/app/file3', os.urandom(4096 * 4))
+
+    tempdir = common.UnzipTemp(target_files)
+    with zipfile.ZipFile(target_files, 'r') as input_zip:
+      sparse_image = common.GetSparseImage('system', tempdir, input_zip, False)
+
+    self.assertFalse(sparse_image.file_map['//system/file1'].extra)
+    self.assertTrue(sparse_image.file_map['//system/file2'].extra['incomplete'])
+    self.assertTrue(
+        sparse_image.file_map['/system/app/file3'].extra['incomplete'])
+
+  def test_GetSparseImage_systemRootImage_nonSystemFiles(self):
+    target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
+    with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+      target_files_zip.write(
+          test_utils.construct_sparse_image([(0xCAC2, 16)]),
+          arcname='IMAGES/system.img')
+      target_files_zip.writestr(
+          'IMAGES/system.map',
+          '\n'.join([
+              '//system/file1 1-5 9-10',
+              '//init.rc 13-15']))
+      target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 7))
+      # '/init.rc' has less blocks listed (3) than actual (4).
+      target_files_zip.writestr('ROOT/init.rc', os.urandom(4096 * 4))
+
+    tempdir = common.UnzipTemp(target_files)
+    with zipfile.ZipFile(target_files, 'r') as input_zip:
+      sparse_image = common.GetSparseImage('system', tempdir, input_zip, False)
+
+    self.assertFalse(sparse_image.file_map['//system/file1'].extra)
+    self.assertTrue(sparse_image.file_map['//init.rc'].extra['incomplete'])
+
+  def test_GetSparseImage_fileNotFound(self):
+    target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
+    with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+      target_files_zip.write(
+          test_utils.construct_sparse_image([(0xCAC2, 16)]),
+          arcname='IMAGES/system.img')
+      target_files_zip.writestr(
+          'IMAGES/system.map',
+          '\n'.join([
+              '//system/file1 1-5 9-10',
+              '//system/file2 11-12']))
+      target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 7))
+
+    tempdir = common.UnzipTemp(target_files)
+    with zipfile.ZipFile(target_files, 'r') as input_zip:
+      self.assertRaises(
+          AssertionError, common.GetSparseImage, 'system', tempdir, input_zip,
+          False)
+
 
 class InstallRecoveryScriptFormatTest(unittest.TestCase):
   """Checks the format of install-recovery.sh.
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index 262e701..c8e6750 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -50,17 +50,25 @@
             "POSTINSTALL_OPTIONAL_system=true",
         ]))
 
+    ab_partitions = [
+        ('IMAGES', 'boot'),
+        ('IMAGES', 'system'),
+        ('IMAGES', 'vendor'),
+        ('RADIO', 'bootloader'),
+        ('RADIO', 'modem'),
+    ]
     # META/ab_partitions.txt
-    ab_partitions = ['boot', 'system', 'vendor']
     target_files_zip.writestr(
         'META/ab_partitions.txt',
-        '\n'.join(ab_partitions))
+        '\n'.join([partition[1] for partition in ab_partitions]))
 
     # Create dummy images for each of them.
-    for partition in ab_partitions:
-      target_files_zip.writestr('IMAGES/' + partition + '.img',
-                                os.urandom(len(partition)))
+    for path, partition in ab_partitions:
+      target_files_zip.writestr(
+          '{}/{}.img'.format(path, partition),
+          os.urandom(len(partition)))
 
+    # system_other shouldn't appear in META/ab_partitions.txt.
     if secondary:
       target_files_zip.writestr('IMAGES/system_other.img',
                                 os.urandom(len("system_other")))
@@ -182,6 +190,16 @@
     self.assertRaises(KeyError,
                       lambda: target_info['build.prop']['ro.build.foo'])
 
+  def test___setitem__(self):
+    target_info = BuildInfo(copy.deepcopy(self.TEST_INFO_DICT), None)
+    self.assertEqual('value1', target_info['property1'])
+    target_info['property1'] = 'value2'
+    self.assertEqual('value2', target_info['property1'])
+
+    self.assertEqual('build-foo', target_info['build.prop']['ro.build.foo'])
+    target_info['build.prop']['ro.build.foo'] = 'build-bar'
+    self.assertEqual('build-bar', target_info['build.prop']['ro.build.foo'])
+
   def test_get(self):
     target_info = BuildInfo(self.TEST_INFO_DICT, None)
     self.assertEqual('value1', target_info.get('property1'))
@@ -201,6 +219,12 @@
     self.assertRaises(KeyError,
                       lambda: target_info.get('build.prop')['ro.build.foo'])
 
+  def test_items(self):
+    target_info = BuildInfo(self.TEST_INFO_DICT, None)
+    items = target_info.items()
+    self.assertIn(('property1', 'value1'), items)
+    self.assertIn(('property2', 4096), items)
+
   def test_GetBuildProp(self):
     target_info = BuildInfo(self.TEST_INFO_DICT, None)
     self.assertEqual('build-foo', target_info.GetBuildProp('ro.build.foo'))
@@ -542,6 +566,8 @@
     self.assertIn('IMAGES/boot.img', namelist)
     self.assertIn('IMAGES/system.img', namelist)
     self.assertIn('IMAGES/vendor.img', namelist)
+    self.assertIn('RADIO/bootloader.img', namelist)
+    self.assertIn('RADIO/modem.img', namelist)
     self.assertIn(POSTINSTALL_CONFIG, namelist)
 
     self.assertNotIn('IMAGES/system_other.img', namelist)
@@ -559,11 +585,33 @@
     self.assertIn('IMAGES/boot.img', namelist)
     self.assertIn('IMAGES/system.img', namelist)
     self.assertIn('IMAGES/vendor.img', namelist)
+    self.assertIn('RADIO/bootloader.img', namelist)
+    self.assertIn('RADIO/modem.img', namelist)
 
     self.assertNotIn('IMAGES/system_other.img', namelist)
     self.assertNotIn('IMAGES/system.map', namelist)
     self.assertNotIn(POSTINSTALL_CONFIG, namelist)
 
+  def test_GetTargetFilesZipForSecondaryImages_withoutRadioImages(self):
+    input_file = construct_target_files(secondary=True)
+    common.ZipDelete(input_file, 'RADIO/bootloader.img')
+    common.ZipDelete(input_file, 'RADIO/modem.img')
+    target_file = GetTargetFilesZipForSecondaryImages(input_file)
+
+    with zipfile.ZipFile(target_file) as verify_zip:
+      namelist = verify_zip.namelist()
+
+    self.assertIn('META/ab_partitions.txt', namelist)
+    self.assertIn('IMAGES/boot.img', namelist)
+    self.assertIn('IMAGES/system.img', namelist)
+    self.assertIn('IMAGES/vendor.img', namelist)
+    self.assertIn(POSTINSTALL_CONFIG, namelist)
+
+    self.assertNotIn('IMAGES/system_other.img', namelist)
+    self.assertNotIn('IMAGES/system.map', namelist)
+    self.assertNotIn('RADIO/bootloader.img', namelist)
+    self.assertNotIn('RADIO/modem.img', namelist)
+
   def test_GetTargetFilesZipWithoutPostinstallConfig(self):
     input_file = construct_target_files()
     target_file = GetTargetFilesZipWithoutPostinstallConfig(input_file)
@@ -742,8 +790,7 @@
     zip_file = self.construct_zip_package(entries)
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
       streaming_metadata = property_files.Finalize(zip_fp, len(raw_metadata))
     tokens = self._parse_property_files_string(streaming_metadata)
@@ -766,8 +813,7 @@
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # First get the raw metadata string (i.e. without padding space).
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
       raw_length = len(raw_metadata)
 
@@ -801,8 +847,7 @@
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # First get the raw metadata string (i.e. without padding space).
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
 
       # Should pass the test if verification passes.
@@ -859,8 +904,7 @@
     zip_file = self.construct_zip_package(entries)
     property_files = StreamingPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
       streaming_metadata = property_files.Finalize(zip_fp, len(raw_metadata))
     tokens = self._parse_property_files_string(streaming_metadata)
@@ -883,8 +927,7 @@
     property_files = StreamingPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # First get the raw metadata string (i.e. without padding space).
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
 
       # Should pass the test if verification passes.
@@ -1019,8 +1062,7 @@
     zip_file = self.construct_zip_package_withValidPayload(with_metadata=True)
     property_files = AbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
       property_files_string = property_files.Finalize(zip_fp, len(raw_metadata))
 
@@ -1035,8 +1077,7 @@
     zip_file = self.construct_zip_package_withValidPayload(with_metadata=True)
     property_files = AbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
 
       property_files.Verify(zip_fp, raw_metadata)
@@ -1069,8 +1110,7 @@
     zip_file = self.construct_zip_package(entries)
     property_files = NonAbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file) as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
       property_files_string = property_files.Finalize(zip_fp, len(raw_metadata))
     tokens = self._parse_property_files_string(property_files_string)
@@ -1087,8 +1127,7 @@
     zip_file = self.construct_zip_package(entries)
     property_files = NonAbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file) as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
 
       property_files.Verify(zip_fp, raw_metadata)
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 26f9e10..ac1b567 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -24,7 +24,8 @@
 import common
 import test_utils
 from sign_target_files_apks import (
-    EditTags, ReplaceCerts, ReplaceVerityKeyId, RewriteProps)
+    CheckAllApksSigned, EditTags, GetApkFileInfo, ReplaceCerts,
+    ReplaceVerityKeyId, RewriteProps)
 
 
 class SignTargetFilesApksTest(unittest.TestCase):
@@ -211,3 +212,141 @@
         cert2_path[:-9] : 'non-existent',
     }
     self.assertEqual(output_xml, ReplaceCerts(input_xml))
+
+  def test_CheckAllApksSigned(self):
+    input_file = common.MakeTempFile(suffix='.zip')
+    with zipfile.ZipFile(input_file, 'w') as input_zip:
+      input_zip.writestr('SYSTEM/app/App1.apk', "App1-content")
+      input_zip.writestr('SYSTEM/app/App2.apk.gz', "App2-content")
+
+    apk_key_map = {
+        'App1.apk' : 'key1',
+        'App2.apk' : 'key2',
+        'App3.apk' : 'key3',
+    }
+    with zipfile.ZipFile(input_file) as input_zip:
+      CheckAllApksSigned(input_zip, apk_key_map, None)
+      CheckAllApksSigned(input_zip, apk_key_map, '.gz')
+
+      # 'App2.apk.gz' won't be considered as an APK.
+      CheckAllApksSigned(input_zip, apk_key_map, None)
+      CheckAllApksSigned(input_zip, apk_key_map, '.xz')
+
+      del apk_key_map['App2.apk']
+      self.assertRaises(
+          AssertionError, CheckAllApksSigned, input_zip, apk_key_map, '.gz')
+
+  def test_GetApkFileInfo(self):
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/apps/Chats.apk", None, [])
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/apps/Chats.apk", None, [])
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/apps/Chats.dat", None, [])
+    self.assertFalse(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
+
+  def test_GetApkFileInfo_withCompressedApks(self):
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/apps/Chats.apk.gz", ".gz", [])
+    self.assertTrue(is_apk)
+    self.assertTrue(is_compressed)
+    self.assertFalse(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/apps/Chats.apk.gz", ".xz", [])
+    self.assertFalse(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
+
+    self.assertRaises(
+        AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "", [])
+
+    self.assertRaises(
+        AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "apk", [])
+
+  def test_GetApkFileInfo_withSkippedPrefixes(self):
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/preloads/apps/Chats.apk", None, set())
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/preloads/apps/Chats.apk",
+        None,
+        set(["PRODUCT/preloads/"]))
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None,
+        set(["SYSTEM/preloads/", "SYSTEM_OTHER/preloads/"]))
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.apk.gz",
+        ".gz",
+        set(["PRODUCT/prebuilts/", "SYSTEM_OTHER/preloads/"]))
+    self.assertTrue(is_apk)
+    self.assertTrue(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.dat",
+        None,
+        set(["SYSTEM_OTHER/preloads/"]))
+    self.assertFalse(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
+
+  def test_GetApkFileInfo_checkSkippedPrefixesInput(self):
+    # set
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None,
+        set(["SYSTEM_OTHER/preloads/"]))
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    # tuple
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None,
+        ("SYSTEM_OTHER/preloads/",))
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    # list
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None,
+        ["SYSTEM_OTHER/preloads/"])
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    # str is invalid.
+    self.assertRaises(
+        AssertionError, GetApkFileInfo, "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None, "SYSTEM_OTHER/preloads/")
+
+    # None is invalid.
+    self.assertRaises(
+        AssertionError, GetApkFileInfo, "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None, None)
diff --git a/tools/releasetools/test_validate_target_files.py b/tools/releasetools/test_validate_target_files.py
new file mode 100644
index 0000000..d62ea95
--- /dev/null
+++ b/tools/releasetools/test_validate_target_files.py
@@ -0,0 +1,166 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""Unittests for validate_target_files.py."""
+
+from __future__ import print_function
+
+import os
+import os.path
+import shutil
+import subprocess
+import unittest
+
+import build_image
+import common
+import test_utils
+from validate_target_files import ValidateVerifiedBootImages
+
+
+class ValidateTargetFilesTest(unittest.TestCase):
+
+  def setUp(self):
+    self.testdata_dir = test_utils.get_testdata_dir()
+
+  def tearDown(self):
+    common.Cleanup()
+
+  def _generate_boot_image(self, output_file):
+    kernel = common.MakeTempFile(prefix='kernel-')
+    with open(kernel, 'wb') as kernel_fp:
+      kernel_fp.write(os.urandom(10))
+
+    cmd = ['mkbootimg', '--kernel', kernel, '-o', output_file]
+    proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    stdoutdata, _ = proc.communicate()
+    self.assertEqual(
+        0, proc.returncode,
+        "Failed to run mkbootimg: {}".format(stdoutdata))
+
+    cmd = ['boot_signer', '/boot', output_file,
+           os.path.join(self.testdata_dir, 'testkey.pk8'),
+           os.path.join(self.testdata_dir, 'testkey.x509.pem'), output_file]
+    proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    stdoutdata, _ = proc.communicate()
+    self.assertEqual(
+        0, proc.returncode,
+        "Failed to sign boot image with boot_signer: {}".format(stdoutdata))
+
+  def test_ValidateVerifiedBootImages_bootImage(self):
+    input_tmp = common.MakeTempDir()
+    os.mkdir(os.path.join(input_tmp, 'IMAGES'))
+    boot_image = os.path.join(input_tmp, 'IMAGES', 'boot.img')
+    self._generate_boot_image(boot_image)
+
+    info_dict = {
+        'boot_signer' : 'true',
+    }
+    options = {
+        'verity_key' : os.path.join(self.testdata_dir, 'testkey.x509.pem'),
+    }
+    ValidateVerifiedBootImages(input_tmp, info_dict, options)
+
+  def test_ValidateVerifiedBootImages_bootImage_wrongKey(self):
+    input_tmp = common.MakeTempDir()
+    os.mkdir(os.path.join(input_tmp, 'IMAGES'))
+    boot_image = os.path.join(input_tmp, 'IMAGES', 'boot.img')
+    self._generate_boot_image(boot_image)
+
+    info_dict = {
+        'boot_signer' : 'true',
+    }
+    options = {
+        'verity_key' : os.path.join(self.testdata_dir, 'verity.x509.pem'),
+    }
+    self.assertRaises(
+        AssertionError, ValidateVerifiedBootImages, input_tmp, info_dict,
+        options)
+
+  def test_ValidateVerifiedBootImages_bootImage_corrupted(self):
+    input_tmp = common.MakeTempDir()
+    os.mkdir(os.path.join(input_tmp, 'IMAGES'))
+    boot_image = os.path.join(input_tmp, 'IMAGES', 'boot.img')
+    self._generate_boot_image(boot_image)
+
+    # Corrupt the late byte of the image.
+    with open(boot_image, 'r+b') as boot_fp:
+      boot_fp.seek(-1, os.SEEK_END)
+      last_byte = boot_fp.read(1)
+      last_byte = chr(255 - ord(last_byte))
+      boot_fp.seek(-1, os.SEEK_END)
+      boot_fp.write(last_byte)
+
+    info_dict = {
+        'boot_signer' : 'true',
+    }
+    options = {
+        'verity_key' : os.path.join(self.testdata_dir, 'testkey.x509.pem'),
+    }
+    self.assertRaises(
+        AssertionError, ValidateVerifiedBootImages, input_tmp, info_dict,
+        options)
+
+  def _generate_system_image(self, output_file):
+    verity_fec = True
+    partition_size = 1024 * 1024
+    adjusted_size, verity_size = build_image.AdjustPartitionSizeForVerity(
+        partition_size, verity_fec)
+
+    # Use an empty root directory.
+    system_root = common.MakeTempDir()
+    cmd = ['mkuserimg_mke2fs.sh', '-s', system_root, output_file, 'ext4',
+           '/system', str(adjusted_size), '-j', '0']
+    proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    stdoutdata, _ = proc.communicate()
+    self.assertEqual(
+        0, proc.returncode,
+        "Failed to create system image with mkuserimg_mke2fs.sh: {}".format(
+            stdoutdata))
+
+    # Append the verity metadata.
+    prop_dict = {
+        'original_partition_size' : str(partition_size),
+        'partition_size' : str(adjusted_size),
+        'verity_block_device' : '/dev/block/system',
+        'verity_key' : os.path.join(self.testdata_dir, 'testkey'),
+        'verity_signer_cmd' : 'verity_signer',
+        'verity_size' : str(verity_size),
+    }
+    self.assertTrue(
+        build_image.MakeVerityEnabledImage(output_file, verity_fec, prop_dict))
+
+  def test_ValidateVerifiedBootImages_systemImage(self):
+    input_tmp = common.MakeTempDir()
+    os.mkdir(os.path.join(input_tmp, 'IMAGES'))
+    system_image = os.path.join(input_tmp, 'IMAGES', 'system.img')
+    self._generate_system_image(system_image)
+
+    # Pack the verity key.
+    verity_key_mincrypt = os.path.join(
+        input_tmp, 'BOOT', 'RAMDISK', 'verity_key')
+    os.makedirs(os.path.dirname(verity_key_mincrypt))
+    shutil.copyfile(
+        os.path.join(self.testdata_dir, 'testkey_mincrypt'),
+        verity_key_mincrypt)
+
+    info_dict = {
+        'verity' : 'true',
+    }
+    options = {
+        'verity_key' : os.path.join(self.testdata_dir, 'testkey.x509.pem'),
+        'verity_key_mincrypt' : verity_key_mincrypt,
+    }
+    ValidateVerifiedBootImages(input_tmp, info_dict, options)
diff --git a/tools/releasetools/testdata/TestApp.apk b/tools/releasetools/testdata/TestApp.apk
new file mode 100644
index 0000000..a911603
--- /dev/null
+++ b/tools/releasetools/testdata/TestApp.apk
Binary files differ
diff --git a/tools/releasetools/testdata/testkey_mincrypt b/tools/releasetools/testdata/testkey_mincrypt
new file mode 100644
index 0000000..7f5d31b
--- /dev/null
+++ b/tools/releasetools/testdata/testkey_mincrypt
Binary files differ
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index 8c9e07c..886de26 100755
--- a/tools/releasetools/validate_target_files.py
+++ b/tools/releasetools/validate_target_files.py
@@ -17,16 +17,25 @@
 """
 Validate a given (signed) target_files.zip.
 
-It performs checks to ensure the integrity of the input zip.
+It performs the following checks to assert the integrity of the input zip.
+
  - It verifies the file consistency between the ones in IMAGES/system.img (read
    via IMAGES/system.map) and the ones under unpacked folder of SYSTEM/. The
    same check also applies to the vendor image if present.
+
+ - It verifies the install-recovery script consistency, by comparing the
+   checksums in the script against the ones of IMAGES/{boot,recovery}.img.
+
+ - It verifies the signed Verified Boot related images, for both of Verified
+   Boot 1.0 and 2.0 (aka AVB).
 """
 
+import argparse
+import filecmp
 import logging
 import os.path
 import re
-import sys
+import subprocess
 import zipfile
 
 import common
@@ -188,33 +197,152 @@
   logging.info('Done checking %s', script_path)
 
 
-def main(argv):
-  def option_handler():
-    return True
+def ValidateVerifiedBootImages(input_tmp, info_dict, options):
+  """Validates the Verified Boot related images.
 
-  args = common.ParseOptions(
-      argv, __doc__, extra_opts="",
-      extra_long_opts=[],
-      extra_option_handler=option_handler)
+  For Verified Boot 1.0, it verifies the signatures of the bootable images
+  (boot/recovery etc), as well as the dm-verity metadata in system images
+  (system/vendor/product). For Verified Boot 2.0, it calls avbtool to verify
+  vbmeta.img, which in turn verifies all the descriptors listed in vbmeta.
 
-  if len(args) != 1:
-    common.Usage(__doc__)
-    sys.exit(1)
+  Args:
+    input_tmp: The top-level directory of unpacked target-files.zip.
+    info_dict: The loaded info dict.
+    options: A dict that contains the user-supplied public keys to be used for
+        image verification. In particular, 'verity_key' is used to verify the
+        bootable images in VB 1.0, and the vbmeta image in VB 2.0, where
+        applicable. 'verity_key_mincrypt' will be used to verify the system
+        images in VB 1.0.
+
+  Raises:
+    AssertionError: On any verification failure.
+  """
+  # Verified boot 1.0 (images signed with boot_signer and verity_signer).
+  if info_dict.get('boot_signer') == 'true':
+    logging.info('Verifying Verified Boot images...')
+
+    # Verify the boot/recovery images (signed with boot_signer), against the
+    # given X.509 encoded pubkey (or falling back to the one in the info_dict if
+    # none given).
+    verity_key = options['verity_key']
+    if verity_key is None:
+      verity_key = info_dict['verity_key'] + '.x509.pem'
+    for image in ('boot.img', 'recovery.img', 'recovery-two-step.img'):
+      image_path = os.path.join(input_tmp, 'IMAGES', image)
+      if not os.path.exists(image_path):
+        continue
+
+      cmd = ['boot_signer', '-verify', image_path, '-certificate', verity_key]
+      proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+      stdoutdata, _ = proc.communicate()
+      assert proc.returncode == 0, \
+          'Failed to verify {} with boot_signer:\n{}'.format(image, stdoutdata)
+      logging.info(
+          'Verified %s with boot_signer (key: %s):\n%s', image, verity_key,
+          stdoutdata.rstrip())
+
+  # Verify verity signed system images in Verified Boot 1.0. Note that not using
+  # 'elif' here, since 'boot_signer' and 'verity' are not bundled in VB 1.0.
+  if info_dict.get('verity') == 'true':
+    # First verify that the verity key that's built into the root image (as
+    # /verity_key) matches the one given via command line, if any.
+    if info_dict.get("system_root_image") == "true":
+      verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key')
+    else:
+      verity_key_mincrypt = os.path.join(
+          input_tmp, 'BOOT', 'RAMDISK', 'verity_key')
+    assert os.path.exists(verity_key_mincrypt), 'Missing verity_key'
+
+    if options['verity_key_mincrypt'] is None:
+      logging.warn(
+          'Skipped checking the content of /verity_key, as the key file not '
+          'provided. Use --verity_key_mincrypt to specify.')
+    else:
+      expected_key = options['verity_key_mincrypt']
+      assert filecmp.cmp(expected_key, verity_key_mincrypt, shallow=False), \
+          "Mismatching mincrypt verity key files"
+      logging.info('Verified the content of /verity_key')
+
+    # Then verify the verity signed system/vendor/product images, against the
+    # verity pubkey in mincrypt format.
+    for image in ('system.img', 'vendor.img', 'product.img'):
+      image_path = os.path.join(input_tmp, 'IMAGES', image)
+
+      # We are not checking if the image is actually enabled via info_dict (e.g.
+      # 'system_verity_block_device=...'). Because it's most likely a bug that
+      # skips signing some of the images in signed target-files.zip, while
+      # having the top-level verity flag enabled.
+      if not os.path.exists(image_path):
+        continue
+
+      cmd = ['verity_verifier', image_path, '-mincrypt', verity_key_mincrypt]
+      proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+      stdoutdata, _ = proc.communicate()
+      assert proc.returncode == 0, \
+          'Failed to verify {} with verity_verifier (key: {}):\n{}'.format(
+              image, verity_key_mincrypt, stdoutdata)
+      logging.info(
+          'Verified %s with verity_verifier (key: %s):\n%s', image,
+          verity_key_mincrypt, stdoutdata.rstrip())
+
+  # Handle the case of Verified Boot 2.0 (AVB).
+  if info_dict.get("avb_enable") == "true":
+    logging.info('Verifying Verified Boot 2.0 (AVB) images...')
+
+    key = options['verity_key']
+    if key is None:
+      key = info_dict['avb_vbmeta_key_path']
+    # avbtool verifies all the images that have descriptors listed in vbmeta.
+    image = os.path.join(input_tmp, 'IMAGES', 'vbmeta.img')
+    cmd = ['avbtool', 'verify_image', '--image', image, '--key', key]
+    proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    stdoutdata, _ = proc.communicate()
+    assert proc.returncode == 0, \
+        'Failed to verify {} with verity_verifier (key: {}):\n{}'.format(
+            image, key, stdoutdata)
+
+    logging.info(
+        'Verified %s with avbtool (key: %s):\n%s', image, key,
+        stdoutdata.rstrip())
+
+
+def main():
+  parser = argparse.ArgumentParser(
+      description=__doc__,
+      formatter_class=argparse.RawDescriptionHelpFormatter)
+  parser.add_argument(
+      'target_files',
+      help='the input target_files.zip to be validated')
+  parser.add_argument(
+      '--verity_key',
+      help='the verity public key to verify the bootable images (Verified '
+           'Boot 1.0), or the vbmeta image (Verified Boot 2.0), where '
+           'applicable')
+  parser.add_argument(
+      '--verity_key_mincrypt',
+      help='the verity public key in mincrypt format to verify the system '
+           'images, if target using Verified Boot 1.0')
+  args = parser.parse_args()
+
+  # Unprovided args will have 'None' as the value.
+  options = vars(args)
 
   logging_format = '%(asctime)s - %(filename)s - %(levelname)-8s: %(message)s'
   date_format = '%Y/%m/%d %H:%M:%S'
   logging.basicConfig(level=logging.INFO, format=logging_format,
                       datefmt=date_format)
 
-  logging.info("Unzipping the input target_files.zip: %s", args[0])
-  input_tmp = common.UnzipTemp(args[0])
+  logging.info("Unzipping the input target_files.zip: %s", args.target_files)
+  input_tmp = common.UnzipTemp(args.target_files)
 
   info_dict = common.LoadInfoDict(input_tmp)
-  with zipfile.ZipFile(args[0], 'r') as input_zip:
+  with zipfile.ZipFile(args.target_files, 'r') as input_zip:
     ValidateFileConsistency(input_zip, input_tmp, info_dict)
 
   ValidateInstallRecoveryScript(input_tmp, info_dict)
 
+  ValidateVerifiedBootImages(input_tmp, info_dict, options)
+
   # TODO: Check if the OTA keys have been properly updated (the ones on /system,
   # in recovery image).
 
@@ -223,6 +351,6 @@
 
 if __name__ == '__main__':
   try:
-    main(sys.argv[1:])
+    main()
   finally:
     common.Cleanup()
diff --git a/tools/signapk/src/com/android/signapk/CountingOutputStream.java b/tools/signapk/src/com/android/signapk/CountingOutputStream.java
new file mode 100644
index 0000000..893a780
--- /dev/null
+++ b/tools/signapk/src/com/android/signapk/CountingOutputStream.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.signapk;
+import java.io.OutputStream;
+import java.io.IOException;
+
+class CountingOutputStream extends OutputStream {
+    private final OutputStream mBase;
+    private long mWrittenBytes;
+
+    public CountingOutputStream(OutputStream base) {
+        mBase = base;
+    }
+
+    @Override
+    public void close() throws IOException {
+        mBase.close();
+    }
+
+    @Override
+    public void flush() throws IOException {
+        mBase.flush();
+    }
+
+    @Override
+    public void write(byte[] b) throws IOException {
+        mBase.write(b);
+        mWrittenBytes += b.length;
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        mBase.write(b, off, len);
+        mWrittenBytes += len;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        mBase.write(b);
+        mWrittenBytes += 1;
+    }
+
+    public long getWrittenBytes() {
+        return mWrittenBytes;
+    }
+}
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index fdf6283..57973ec 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -36,6 +36,7 @@
 
 import com.android.apksig.ApkSignerEngine;
 import com.android.apksig.DefaultApkSignerEngine;
+import com.android.apksig.Hints;
 import com.android.apksig.apk.ApkUtils;
 import com.android.apksig.apk.MinSdkVersionException;
 import com.android.apksig.util.DataSink;
@@ -73,6 +74,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.TimeZone;
@@ -80,6 +82,7 @@
 import java.util.jar.JarFile;
 import java.util.jar.JarOutputStream;
 import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
 
 import javax.crypto.Cipher;
 import javax.crypto.EncryptedPrivateKeyInfo;
@@ -372,11 +375,16 @@
             Pattern ignoredFilenamePattern,
             ApkSignerEngine apkSigner,
             JarOutputStream out,
+            CountingOutputStream outCounter,
             long timestamp,
             int defaultAlignment) throws IOException {
         byte[] buffer = new byte[4096];
         int num;
 
+        List<Pattern> pinPatterns = extractPinPatterns(in);
+        ArrayList<Hints.ByteRange> pinByteRanges = pinPatterns == null ? null : new ArrayList<>();
+        HashSet<String> namesToPin = new HashSet<>();
+
         ArrayList<String> names = new ArrayList<String>();
         for (Enumeration<JarEntry> e = in.entries(); e.hasMoreElements();) {
             JarEntry entry = e.nextElement();
@@ -388,6 +396,16 @@
                     && (ignoredFilenamePattern.matcher(entryName).matches())) {
                 continue;
             }
+            if (Hints.PIN_BYTE_RANGE_ZIP_ENTRY_NAME.equals(entryName)) {
+                continue;  // We regenerate it below.
+            }
+            if (pinPatterns != null) {
+                for (Pattern pinPattern : pinPatterns) {
+                    if (pinPattern.matcher(entryName).matches()) {
+                        namesToPin.add(entryName);
+                    }
+                }
+            }
             names.add(entryName);
         }
         Collections.sort(names);
@@ -460,6 +478,7 @@
             outEntry.setExtra(extra);
             offset += extra.length;
 
+            long entryHeaderStart = outCounter.getWrittenBytes();
             out.putNextEntry(outEntry);
             ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
                     (apkSigner != null) ? apkSigner.outputJarEntry(name) : null;
@@ -475,10 +494,18 @@
                     offset += num;
                 }
             }
+            out.closeEntry();
             out.flush();
             if (inspectEntryRequest != null) {
                 inspectEntryRequest.done();
             }
+
+            if (namesToPin.contains(name)) {
+                pinByteRanges.add(
+                    new Hints.ByteRange(
+                        entryHeaderStart,
+                        outCounter.getWrittenBytes()));
+            }
         }
 
         // Copy all the non-STORED entries.  We don't attempt to
@@ -494,6 +521,7 @@
             // Create a new entry so that the compressed len is recomputed.
             JarEntry outEntry = new JarEntry(name);
             outEntry.setTime(timestamp);
+            long entryHeaderStart = outCounter.getWrittenBytes();
             out.putNextEntry(outEntry);
             ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
                     (apkSigner != null) ? apkSigner.outputJarEntry(name) : null;
@@ -507,11 +535,47 @@
                     entryDataSink.consume(buffer, 0, num);
                 }
             }
+            out.closeEntry();
             out.flush();
             if (inspectEntryRequest != null) {
                 inspectEntryRequest.done();
             }
+
+            if (namesToPin.contains(name)) {
+                pinByteRanges.add(
+                    new Hints.ByteRange(
+                        entryHeaderStart,
+                        outCounter.getWrittenBytes()));
+            }
         }
+
+        if (pinByteRanges != null) {
+            // Cover central directory
+            pinByteRanges.add(
+                new Hints.ByteRange(outCounter.getWrittenBytes(),
+                                    Long.MAX_VALUE));
+            addPinByteRanges(out, pinByteRanges, timestamp);
+        }
+    }
+
+    private static List<Pattern> extractPinPatterns(JarFile in) throws IOException {
+        ZipEntry pinMetaEntry = in.getEntry(Hints.PIN_HINT_ASSET_ZIP_ENTRY_NAME);
+        if (pinMetaEntry == null) {
+            return null;
+        }
+        InputStream pinMetaStream = in.getInputStream(pinMetaEntry);
+        byte[] patternBlob = new byte[(int) pinMetaEntry.getSize()];
+        pinMetaStream.read(patternBlob);
+        return Hints.parsePinPatterns(patternBlob);
+    }
+
+    private static void addPinByteRanges(JarOutputStream outputJar,
+                                         ArrayList<Hints.ByteRange> pinByteRanges,
+                                         long timestamp) throws IOException {
+        JarEntry je = new JarEntry(Hints.PIN_BYTE_RANGE_ZIP_ENTRY_NAME);
+        je.setTime(timestamp);
+        outputJar.putNextEntry(je);
+        outputJar.write(Hints.encodeByteRangeList(pinByteRanges));
     }
 
     private static boolean shouldOutputApkEntry(
@@ -679,9 +743,11 @@
         public void write(OutputStream out) throws IOException {
             try {
                 signer = new WholeFileSignerOutputStream(out, outputStream);
-                JarOutputStream outputJar = new JarOutputStream(signer);
+                CountingOutputStream outputJarCounter = new CountingOutputStream(signer);
+                JarOutputStream outputJar = new JarOutputStream(outputJarCounter);
 
-                copyFiles(inputJar, STRIP_PATTERN, null, outputJar, timestamp, 0);
+                copyFiles(inputJar, STRIP_PATTERN, null, outputJar,
+                          outputJarCounter, timestamp, 0);
                 addOtacert(outputJar, publicKeyFile, timestamp);
 
                 signer.notifyClosing();
@@ -1065,11 +1131,14 @@
                     // Build the output APK in memory, by copying input APK's ZIP entries across
                     // and then signing the output APK.
                     ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream();
-                    JarOutputStream outputJar = new JarOutputStream(v1SignedApkBuf);
+                    CountingOutputStream outputJarCounter =
+                            new CountingOutputStream(v1SignedApkBuf);
+                    JarOutputStream outputJar = new JarOutputStream(outputJarCounter);
                     // Use maximum compression for compressed entries because the APK lives forever
                     // on the system partition.
                     outputJar.setLevel(9);
-                    copyFiles(inputJar, null, apkSigner, outputJar, timestamp, alignment);
+                    copyFiles(inputJar, null, apkSigner, outputJar,
+                              outputJarCounter, timestamp, alignment);
                     ApkSignerEngine.OutputJarSignatureRequest addV1SignatureRequest =
                             apkSigner.outputJarEntries();
                     if (addV1SignatureRequest != null) {
diff --git a/tools/warn.py b/tools/warn.py
index 01398be..89f4778 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -177,6 +177,9 @@
     {'category': 'make', 'severity': Severity.MEDIUM,
      'description': 'Invalid SDK/NDK linking',
      'patterns': [r".*: warning: .+ \(.+\) should not link to .+ \(.+\)"]},
+    {'category': 'make', 'severity': Severity.MEDIUM,
+     'description': 'Duplicate header copy',
+     'patterns': [r".*: warning: Duplicate header copy: .+"]},
     {'category': 'C/C++', 'severity': Severity.HIGH, 'option': '-Wimplicit-function-declaration',
      'description': 'Implicit function declaration',
      'patterns': [r".*: warning: implicit declaration of function .+",
@@ -238,9 +241,11 @@
      'description': 'Unused parameter',
      'patterns': [r".*: warning: unused parameter '.*'"]},
     {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wunused',
-     'description': 'Unused function, variable or label',
+     'description': 'Unused function, variable, label, comparison, etc.',
      'patterns': [r".*: warning: '.+' defined but not used",
                   r".*: warning: unused function '.+'",
+                  r".*: warning: unused label '.+'",
+                  r".*: warning: relational comparison result unused",
                   r".*: warning: lambda capture .* is not used",
                   r".*: warning: private field '.+' is not used",
                   r".*: warning: unused variable '.+'"]},
@@ -494,18 +499,23 @@
     {'category': 'java',
      'severity': Severity.LOW,
      'description':
+         'Java: Use parameter comments to document ambiguous literals',
+     'patterns': [r".*: warning: \[BooleanParameter\] .+"]},
+    {'category': 'java',
+     'severity': Severity.LOW,
+     'description':
+         'Java: Field name is CONSTANT_CASE, but field is not static and final',
+     'patterns': [r".*: warning: \[ConstantField\] .+"]},
+    {'category': 'java',
+     'severity': Severity.LOW,
+     'description':
          'Java: @Multibinds is a more efficient and declarative mechanism for ensuring that a set multibinding is present in the graph.',
      'patterns': [r".*: warning: \[EmptySetMultibindingContributions\] .+"]},
     {'category': 'java',
      'severity': Severity.LOW,
      'description':
-         'Java: Add a private constructor to modules that will not be instantiated by Dagger.',
-     'patterns': [r".*: warning: \[PrivateConstructorForNoninstantiableModuleTest\] .+"]},
-    {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
-         'Java: @Binds is a more efficient and declarative mechanism for delegating a binding.',
-     'patterns': [r".*: warning: \[UseBinds\] .+"]},
+         'Java: This field is only assigned during initialization; consider making it final',
+     'patterns': [r".*: warning: \[FieldCanBeFinal\] .+"]},
     {'category': 'java',
      'severity': Severity.LOW,
      'description':
@@ -514,41 +524,11 @@
     {'category': 'java',
      'severity': Severity.LOW,
      'description':
-         'Java: Method parameters that aren\'t checked for null shouldn\'t be annotated @Nullable',
-     'patterns': [r".*: warning: \[ParameterNotNullable\] .+"]},
-    {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
-         'Java: Methods that can return null should be annotated @Nullable',
-     'patterns': [r".*: warning: \[ReturnMissingNullable\] .+"]},
-    {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
-         'Java: Use parameter comments to document ambiguous literals',
-     'patterns': [r".*: warning: \[BooleanParameter\] .+"]},
-    {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
-         'Java: Field name is CONSTANT CASE, but field is not static and final',
-     'patterns': [r".*: warning: \[ConstantField\] .+"]},
-    {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
-         'Java: Deprecated item is not annotated with @Deprecated',
-     'patterns': [r".*: warning: \[DepAnn\] .+"]},
-    {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
-         'Java: Use Java\'s utility functional interfaces instead of Function\u003cA, B> for primitive types.',
+         r'Java: Use Java\'s utility functional interfaces instead of Function\u003cA, B> for primitive types.',
      'patterns': [r".*: warning: \[LambdaFunctionalInterface\] .+"]},
     {'category': 'java',
      'severity': Severity.LOW,
      'description':
-         'Java: Prefer \'L\' to \'l\' for the suffix to long literals',
-     'patterns': [r".*: warning: \[LongLiteralLowerCaseSuffix\] .+"]},
-    {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
          'Java: A private method that does not reference the enclosing instance can be static',
      'patterns': [r".*: warning: \[MethodCanBeStatic\] .+"]},
     {'category': 'java',
@@ -584,6 +564,16 @@
     {'category': 'java',
      'severity': Severity.LOW,
      'description':
+         'Java: Method parameters that aren\'t checked for null shouldn\'t be annotated @Nullable',
+     'patterns': [r".*: warning: \[ParameterNotNullable\] .+"]},
+    {'category': 'java',
+     'severity': Severity.LOW,
+     'description':
+         'Java: Add a private constructor to modules that will not be instantiated by Dagger.',
+     'patterns': [r".*: warning: \[PrivateConstructorForNoninstantiableModule\] .+"]},
+    {'category': 'java',
+     'severity': Severity.LOW,
+     'description':
          'Java: Utility classes (only static members) are not designed to be instantiated and should be made noninstantiable with a default constructor.',
      'patterns': [r".*: warning: \[PrivateConstructorForUtilityClass\] .+"]},
     {'category': 'java',
@@ -594,6 +584,16 @@
     {'category': 'java',
      'severity': Severity.LOW,
      'description':
+         'Java: Methods that can return null should be annotated @Nullable',
+     'patterns': [r".*: warning: \[ReturnMissingNullable\] .+"]},
+    {'category': 'java',
+     'severity': Severity.LOW,
+     'description':
+         'Java: Scopes on modules have no function and will soon be an error.',
+     'patterns': [r".*: warning: \[ScopeOnModule\] .+"]},
+    {'category': 'java',
+     'severity': Severity.LOW,
+     'description':
          'Java: The default case of a switch should appear at the end of the last statement group',
      'patterns': [r".*: warning: \[SwitchDefault\] .+"]},
     {'category': 'java',
@@ -624,78 +624,18 @@
     {'category': 'java',
      'severity': Severity.LOW,
      'description':
+         'Java: @Binds is a more efficient and declarative mechanism for delegating a binding.',
+     'patterns': [r".*: warning: \[UseBinds\] .+"]},
+    {'category': 'java',
+     'severity': Severity.LOW,
+     'description':
          'Java: Wildcard imports, static or otherwise, should not be used',
      'patterns': [r".*: warning: \[WildcardImport\] .+"]},
     {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
-         'Java: ',
-     'patterns': [r".*: warning: \[RemoveFieldPrefixes\] .+"]},
-    {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
-         'Java: Prefer assertThrows to ExpectedException',
-     'patterns': [r".*: warning: \[ExpectedExceptionMigration\] .+"]},
-    {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
-         'Java: Logger instances are not constants -- they are mutable and have side effects -- and should not be named using CONSTANT CASE',
-     'patterns': [r".*: warning: \[LoggerVariableCase\] .+"]},
-    {'category': 'java',
-     'severity': Severity.LOW,
-     'description':
-         'Java: Prefer assertThrows to @Test(expected=...)',
-     'patterns': [r".*: warning: \[TestExceptionMigration\] .+"]},
-    {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
-         'Java: Public fields must be final.',
-     'patterns': [r".*: warning: \[NonFinalPublicFields\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Private fields that are only assigned in the initializer should be made final.',
-     'patterns': [r".*: warning: \[PrivateFieldsNotAssigned\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Lists returned by methods should be immutable.',
-     'patterns': [r".*: warning: \[ReturnedListNotImmutable\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Parameters to log methods should not be generated by a call to String.format() or MessageFormat.format().',
-     'patterns': [r".*: warning: \[SaferLoggerFormat\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Parameters to log methods should not be generated by a call to toString(); see b/22986665.',
-     'patterns': [r".*: warning: \[SaferLoggerToString\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: A call to Binder.clearCallingIdentity() should be followed by Binder.restoreCallingIdentity() in a finally block. Otherwise the wrong Binder identity may be used by subsequent code.',
-     'patterns': [r".*: warning: \[BinderIdentityRestoredDangerously\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Classes extending PreferenceActivity must implement isValidFragment such that it does not unconditionally return true to prevent vulnerability to fragment injection attacks.',
-     'patterns': [r".*: warning: \[FragmentInjection\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Subclasses of Fragment must be instantiable via Class#newInstance(): the class must be public, static and have a public nullary constructor',
-     'patterns': [r".*: warning: \[FragmentNotInstantiable\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Hardcoded reference to /sdcard',
-     'patterns': [r".*: warning: \[HardCodedSdCardPath\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: A wakelock acquired with a timeout may be released by the system before calling `release`, even after checking `isHeld()`. If so, it will throw a RuntimeException. Please wrap in a try/catch block.',
-     'patterns': [r".*: warning: \[WakelockReleasedDangerously\] .+"]},
+         'Java: Method reference is ambiguous',
+     'patterns': [r".*: warning: \[AmbiguousMethodReference\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
@@ -709,81 +649,26 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
-         'Java: An equality test between objects with incompatible types always returns false',
-     'patterns': [r".*: warning: \[EqualsIncompatibleType\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: @AssistedInject and @Inject should not be used on different constructors in the same class.',
-     'patterns': [r".*: warning: \[AssistedInjectAndInjectOnConstructors\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Constructors on abstract classes are never directly @Injected, only the constructors of their subclasses can be @Inject\'ed.',
-     'patterns': [r".*: warning: \[InjectOnConstructorOfAbstractClass\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Injection frameworks currently don\'t understand Qualifiers in TYPE PARAMETER or TYPE USE contexts.',
-     'patterns': [r".*: warning: \[QualifierWithTypeUse\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: This code declares a binding for a common value type without a Qualifier annotation.',
-     'patterns': [r".*: warning: \[BindingToUnqualifiedCommonType\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: This method is not annotated with @Inject, but it overrides a method that is annotated with @com.google.inject.Inject. Guice will inject this method, and it is recommended to annotate it explicitly.',
-     'patterns': [r".*: warning: \[OverridesGuiceInjectableMethod\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: The ordering of parameters in overloaded methods should be as consistent as possible (when viewed from left to right)',
-     'patterns': [r".*: warning: \[InconsistentOverloads\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Double-checked locking on non-volatile fields is unsafe',
-     'patterns': [r".*: warning: \[DoubleCheckedLocking\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Annotations should always be immutable',
-     'patterns': [r".*: warning: \[ImmutableAnnotationChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Enums should always be immutable',
-     'patterns': [r".*: warning: \[ImmutableEnumChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Writes to static fields should not be guarded by instance locks',
-     'patterns': [r".*: warning: \[StaticGuardedByInstance\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Synchronizing on non-final fields is not safe: if the field is ever updated, different threads may end up locking on different objects.',
-     'patterns': [r".*: warning: \[SynchronizeOnNonFinalField\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Method reference is ambiguous',
-     'patterns': [r".*: warning: \[AmbiguousMethodReference\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
          'Java: Assertions may be disabled at runtime and do not guarantee that execution will halt here; consider throwing an exception instead',
      'patterns': [r".*: warning: \[AssertFalse\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: The lambda passed to assertThows should contain exactly one statement',
+     'patterns': [r".*: warning: \[AssertThrowsMultipleStatements\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: This assertion throws an AssertionError if it fails, which will be caught by an enclosing try block.',
      'patterns': [r".*: warning: \[AssertionFailureIgnored\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: @AssistedInject and @Inject should not be used on different constructors in the same class.',
+     'patterns': [r".*: warning: \[AssistedInjectAndInjectOnConstructors\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: Classes that implement Annotation must override equals and hashCode. Consider using AutoAnnotation instead of implementing Annotation by hand.',
      'patterns': [r".*: warning: \[BadAnnotationImplementation\] .+"]},
     {'category': 'java',
@@ -799,11 +684,26 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: A call to Binder.clearCallingIdentity() should be followed by Binder.restoreCallingIdentity() in a finally block. Otherwise the wrong Binder identity may be used by subsequent code.',
+     'patterns': [r".*: warning: \[BinderIdentityRestoredDangerously\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
+         'Java: This code declares a binding for a common value type without a Qualifier annotation.',
+     'patterns': [r".*: warning: \[BindingToUnqualifiedCommonType\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: valueOf or autoboxing provides better time and space performance',
      'patterns': [r".*: warning: \[BoxedPrimitiveConstructor\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: ByteBuffer.array() shouldn\'t be called unless ByteBuffer.arrayOffset() is used or if the ByteBuffer was initialized using ByteBuffer.wrap() or ByteBuffer.allocate().',
+     'patterns': [r".*: warning: \[ByteBufferBackingArray\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: Mockito cannot mock final classes',
      'patterns': [r".*: warning: \[CannotMockFinalClass\] .+"]},
     {'category': 'java',
@@ -864,11 +764,21 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
-         'Java: Implicit use of the platform default charset, which can result in differing behavior between JVM executions or incorrect behavior if the encoding of the data source doesn\'t match expectations.',
+         'Java: Implicit use of the platform default charset, which can result in differing behaviour between JVM executions or incorrect behavior if the encoding of the data source doesn\'t match expectations.',
      'patterns': [r".*: warning: \[DefaultCharset\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: Prefer collection factory methods or builders to the double-brace initialization pattern.',
+     'patterns': [r".*: warning: \[DoubleBraceInitialization\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
+         'Java: Double-checked locking on non-volatile fields is unsafe',
+     'patterns': [r".*: warning: \[DoubleCheckedLocking\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: Empty top-level type declaration',
      'patterns': [r".*: warning: \[EmptyTopLevelDeclaration\] .+"]},
     {'category': 'java',
@@ -879,6 +789,11 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: An equality test between objects with incompatible types always returns false',
+     'patterns': [r".*: warning: \[EqualsIncompatibleType\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: Calls to ExpectedException#expect should always be followed by exactly one statement.',
      'patterns': [r".*: warning: \[ExpectedExceptionChecker\] .+"]},
     {'category': 'java',
@@ -904,6 +819,16 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: Classes extending PreferenceActivity must implement isValidFragment such that it does not unconditionally return true to prevent vulnerability to fragment injection attacks.',
+     'patterns': [r".*: warning: \[FragmentInjection\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
+         'Java: Subclasses of Fragment must be instantiable via Class#newInstance(): the class must be public, static and have a public nullary constructor',
+     'patterns': [r".*: warning: \[FragmentNotInstantiable\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: Overloads will be ambiguous when passing lambda arguments',
      'patterns': [r".*: warning: \[FunctionalInterfaceClash\] .+"]},
     {'category': 'java',
@@ -919,21 +844,51 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: Hardcoded reference to /sdcard',
+     'patterns': [r".*: warning: \[HardCodedSdCardPath\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: Hiding fields of superclasses may cause confusion and errors',
      'patterns': [r".*: warning: \[HidingField\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: Annotations should always be immutable',
+     'patterns': [r".*: warning: \[ImmutableAnnotationChecker\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
+         'Java: Enums should always be immutable',
+     'patterns': [r".*: warning: \[ImmutableEnumChecker\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: This annotation has incompatible modifiers as specified by its @IncompatibleModifiers annotation',
      'patterns': [r".*: warning: \[IncompatibleModifiers\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: It is confusing to have a field and a parameter under the same scope that differ only in capitalization.',
+     'patterns': [r".*: warning: \[InconsistentCapitalization\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
+         'Java: The ordering of parameters in overloaded methods should be as consistent as possible (when viewed from left to right)',
+     'patterns': [r".*: warning: \[InconsistentOverloads\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: This for loop increments the same variable in the header and in the body',
      'patterns': [r".*: warning: \[IncrementInForLoopAndHeader\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: Constructors on abstract classes are never directly @Injected, only the constructors of their subclasses can be @Inject\'ed.',
+     'patterns': [r".*: warning: \[InjectOnConstructorOfAbstractClass\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: Please also override int read(byte[], int, int), otherwise multi-byte reads from this input stream are likely to be slow.',
      'patterns': [r".*: warning: \[InputStreamSlowMultibyteRead\] .+"]},
     {'category': 'java',
@@ -1064,6 +1019,11 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: Calling toString on Objects that don\'t override toString() doesn\'t provide useful information',
+     'patterns': [r".*: warning: \[ObjectToString\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: Use grouping parenthesis to make the operator precedence explicit',
      'patterns': [r".*: warning: \[OperatorPrecedence\] .+"]},
     {'category': 'java',
@@ -1089,6 +1049,11 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: This method is not annotated with @Inject, but it overrides a method that is annotated with @com.google.inject.Inject. Guice will inject this method, and it is recommended to annotate it explicitly.',
+     'patterns': [r".*: warning: \[OverridesGuiceInjectableMethod\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: Detects `/* name= */`-style comments on actual parameters where the name doesn\'t match the formal parameter',
      'patterns': [r".*: warning: \[ParameterName\] .+"]},
     {'category': 'java',
@@ -1114,6 +1079,16 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: Qualifiers/Scope annotations on @Inject methods don\'t have any effect. Move the qualifier annotation to the binding location.',
+     'patterns': [r".*: warning: \[QualifierOrScopeOnInjectMethod\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
+         'Java: Injection frameworks currently don\'t understand Qualifiers in TYPE_PARAMETER or TYPE_USE contexts.',
+     'patterns': [r".*: warning: \[QualifierWithTypeUse\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: reachabilityFence should always be called inside a finally block',
      'patterns': [r".*: warning: \[ReachabilityFenceUsage\] .+"]},
     {'category': 'java',
@@ -1134,11 +1109,16 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
-         'Java: Prefer the short-circuiting boolean operators \u0026\u0026 and || to \u0026 and |.',
+         r'Java: Prefer the short-circuiting boolean operators \u0026\u0026 and || to \u0026 and |.',
      'patterns': [r".*: warning: \[ShortCircuitBoolean\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: Writes to static fields should not be guarded by instance locks',
+     'patterns': [r".*: warning: \[StaticGuardedByInstance\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: A static variable or method should be qualified with a class name, not expression',
      'patterns': [r".*: warning: \[StaticQualifiedUsingExpression\] .+"]},
     {'category': 'java',
@@ -1154,13 +1134,13 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
-         'Java: String.split should never take only a single argument; it has surprising behavior',
-     'patterns': [r".*: warning: \[StringSplit\] .+"]},
+         'Java: String.split(String) has surprising behavior',
+     'patterns': [r".*: warning: \[StringSplitter\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
-         'Java: Prefer Splitter to String.split',
-     'patterns': [r".*: warning: \[StringSplitter\] .+"]},
+         'Java: Synchronizing on non-final fields is not safe: if the field is ever updated, different threads may end up locking on different objects.',
+     'patterns': [r".*: warning: \[SynchronizeOnNonFinalField\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
@@ -1189,6 +1169,11 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
+         'Java: Argument is not compatible with the subject\'s type.',
+     'patterns': [r".*: warning: \[TruthIncompatibleType\] .+"]},
+    {'category': 'java',
+     'severity': Severity.MEDIUM,
+     'description':
          'Java: Type parameter declaration overrides another type parameter already declared',
      'patterns': [r".*: warning: \[TypeParameterShadowing\] .+"]},
     {'category': 'java',
@@ -1199,7 +1184,7 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
-         'Java: Creation of a Set/HashSet/HashMap of java.net.URL. equals() and hashCode() of java.net.URL class make blocking internet connections.',
+         'Java: Avoid hash-based containers of java.net.URL--the containers rely on equals() and hashCode(), which cause java.net.URL to make blocking internet connections.',
      'patterns': [r".*: warning: \[URLEqualsHashCode\] .+"]},
     {'category': 'java',
      'severity': Severity.MEDIUM,
@@ -1234,208 +1219,13 @@
     {'category': 'java',
      'severity': Severity.MEDIUM,
      'description':
-         'Java: Pluggable Type checker internal error',
-     'patterns': [r".*: warning: \[PluggableTypeChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Invalid message format-style format specifier ({0}), expected printf-style (%s)',
-     'patterns': [r".*: warning: \[FloggerMessageFormat\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Logger level check is already implied in the log() call. An explicit at[Level]().isEnabled() check is redundant.',
-     'patterns': [r".*: warning: \[FloggerRedundantIsEnabled\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Calling withCause(Throwable) with an inline allocated Throwable is discouraged. Consider using withStackTrace(StackSize) instead, and specifying a reduced stack size (e.g. SMALL, MEDIUM or LARGE) instead of FULL, to improve performance.',
-     'patterns': [r".*: warning: \[FloggerWithCause\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Use withCause to associate Exceptions with log statements',
-     'patterns': [r".*: warning: \[FloggerWithoutCause\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: No bug exists to track an ignored test',
-     'patterns': [r".*: warning: \[IgnoredTestWithoutBug\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: @Ignore is preferred to @Suppress for JUnit4 tests. @Suppress may silently fail in JUnit4 (that is, tests may run anyway.)',
-     'patterns': [r".*: warning: \[JUnit4SuppressWithoutIgnore\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Medium and large test classes should document why they are medium or large',
-     'patterns': [r".*: warning: \[JUnit4TestAttributeMissing\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: java.net.IDN implements the older IDNA2003 standard. Prefer com.google.i18n.Idn, which implements the newer UTS #46 standard',
-     'patterns': [r".*: warning: \[JavaNetIdn\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Consider requiring strict parsing on JodaDurationFlag instances. Before adjusting existing flags, check the documentation and your existing configuration to avoid crashes!',
-     'patterns': [r".*: warning: \[JodaDurationFlagStrictParsing\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Logging an exception and throwing it (or a new exception) for the same exceptional situation is an anti-pattern.',
-     'patterns': [r".*: warning: \[LogAndThrow\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: FormattingLogger uses wrong or mismatched format string',
-     'patterns': [r".*: warning: \[MisusedFormattingLogger\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Flags should be final',
-     'patterns': [r".*: warning: \[NonFinalFlag\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Reading a flag from a static field or initializer block will cause it to always receive the default value and will cause an IllegalFlagStateException if the flag is ever set.',
-     'patterns': [r".*: warning: \[StaticFlagUsage\] .+"]},
-    {'category': 'java',
-     'severity': Severity.MEDIUM,
-     'description':
-         'Java: Apps must use BuildCompat.isAtLeastO to check whether they\'re running on Android O',
-     'patterns': [r".*: warning: \[UnsafeSdkVersionCheck\] .+"]},
+         'Java: A wakelock acquired with a timeout may be released by the system before calling `release`, even after checking `isHeld()`. If so, it will throw a RuntimeException. Please wrap in a try/catch block.',
+     'patterns': [r".*: warning: \[WakelockReleasedDangerously\] .+"]},
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
-         'Java: Logging tag cannot be longer than 23 characters.',
-     'patterns': [r".*: warning: \[LogTagLength\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Relative class name passed to ComponentName constructor',
-     'patterns': [r".*: warning: \[RelativeComponentName\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Explicitly enumerate all cases in switch statements for certain enum types.',
-     'patterns': [r".*: warning: \[EnumerateAllCasesInEnumSwitch\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Do not call assumeTrue(tester.getExperimentValueFor(...)). Use @RequireEndToEndTestExperiment instead.',
-     'patterns': [r".*: warning: \[JUnitAssumeExperiment\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: The accessed field or method is not visible here. Note that the default production visibility for @VisibleForTesting is Visibility.PRIVATE.',
-     'patterns': [r".*: warning: \[VisibleForTestingChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Detects errors encountered building Error Prone plugins',
-     'patterns': [r".*: warning: \[ErrorPronePluginCorrectness\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Parcelable CREATOR fields should be Creator\u003cT>',
-     'patterns': [r".*: warning: \[ParcelableCreatorType\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Enforce reflected Parcelables are kept by Proguard',
-     'patterns': [r".*: warning: \[ReflectedParcelable\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Any class that extends IntentService should have @Nullable notation on method onHandleIntent(@Nullable Intent intent) and handle the case if intent is null.',
-     'patterns': [r".*: warning: \[OnHandleIntentNullableChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: In many cases, randomUUID is not necessary, and it slows the performance, which can be quite severe especially when this operation happens at start up time. Consider replacing it with cheaper alternatives, like object.hashCode() or IdGenerator.INSTANCE.getRandomId()',
-     'patterns': [r".*: warning: \[UUIDChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: DynamicActivity.findViewById(int) is slow and should not be used inside View.onDraw(Canvas)!',
-     'patterns': [r".*: warning: \[NoFindViewByIdInOnDrawChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Passing Throwable/Exception argument to the message format L.x(). Calling L.w(tag, message, ex) instead of L.w(tag, ex, message)',
-     'patterns': [r".*: warning: \[WrongThrowableArgumentInLogChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: New splicers are disallowed on paths that are being Libsearched',
-     'patterns': [r".*: warning: \[BlacklistedSplicerPathChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Object serialized in Bundle may have been flattened to base type.',
-     'patterns': [r".*: warning: \[BundleDeserializationCast\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Log tag too long, cannot exceed 23 characters.',
-     'patterns': [r".*: warning: \[IsLoggableTagLength\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Certain resources in `android.R.string` have names that do not match their content',
-     'patterns': [r".*: warning: \[MislabeledAndroidString\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Return value of android.graphics.Rect.intersect() must be checked',
-     'patterns': [r".*: warning: \[RectIntersectReturnValueIgnored\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Incompatible type as argument to Object-accepting Java collections method',
-     'patterns': [r".*: warning: \[CollectionIncompatibleType\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: @CompatibleWith\'s value is not a type argument.',
-     'patterns': [r".*: warning: \[CompatibleWithAnnotationMisuse\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Passing argument to a generic method with an incompatible type.',
-     'patterns': [r".*: warning: \[IncompatibleArgumentType\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Invalid printf-style format string',
-     'patterns': [r".*: warning: \[FormatString\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Invalid format string passed to formatting method.',
-     'patterns': [r".*: warning: \[FormatStringAnnotation\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Checks for unguarded accesses to fields and methods with @GuardedBy annotations',
-     'patterns': [r".*: warning: \[GuardedBy\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Type declaration annotated with @Immutable is not immutable',
-     'patterns': [r".*: warning: \[Immutable\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: This method does not acquire the locks specified by its @LockMethod annotation',
-     'patterns': [r".*: warning: \[LockMethodChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: This method does not acquire the locks specified by its @UnlockMethod annotation',
-     'patterns': [r".*: warning: \[UnlockMethod\] .+"]},
+         'Java: AndroidInjection.inject() should always be invoked before calling super.lifecycleMethod()',
+     'patterns': [r".*: warning: \[AndroidInjectionBeforeSuper\] .+"]},
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
@@ -1464,6 +1254,11 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: @AssistedInject and @Inject cannot be used on the same constructor.',
+     'patterns': [r".*: warning: \[AssistedInjectAndInjectOnSameConstructor\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: AsyncCallable should not return a null Future, only a Future whose result is null.',
      'patterns': [r".*: warning: \[AsyncCallableReturnsNull\] .+"]},
     {'category': 'java',
@@ -1474,11 +1269,26 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: @AutoFactory and @Inject should not be used in the same type.',
+     'patterns': [r".*: warning: \[AutoFactoryAtInject\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Arguments to AutoValue constructor are in the wrong order',
+     'patterns': [r".*: warning: \[AutoValueConstructorOrderChecker\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Shift by an amount that is out of range',
      'patterns': [r".*: warning: \[BadShiftAmount\] .+"]},
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Object serialized in Bundle may have been flattened to base type.',
+     'patterns': [r".*: warning: \[BundleDeserializationCast\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: The called constructor accepts a parameter with the same name and type as one of its caller\'s parameters, but its caller doesn\'t pass that parameter to it.  It\'s likely that it was intended to.',
      'patterns': [r".*: warning: \[ChainingConstructorIgnoresParameter\] .+"]},
     {'category': 'java',
@@ -1494,7 +1304,12 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
-         'Java:  Implementing \'Comparable\u003cT>\' where T is not compatible with the implementing class.',
+         'Java: Incompatible type as argument to Object-accepting Java collections method',
+     'patterns': [r".*: warning: \[CollectionIncompatibleType\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         r'Java:  Implementing \'Comparable\u003cT>\' where T is not compatible with the implementing class.',
      'patterns': [r".*: warning: \[ComparableType\] .+"]},
     {'category': 'java',
      'severity': Severity.HIGH,
@@ -1509,6 +1324,11 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: @CompatibleWith\'s value is not a type argument.',
+     'patterns': [r".*: warning: \[CompatibleWithAnnotationMisuse\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Non-compile-time constant expression passed to parameter with @CompileTimeConstant type annotation.',
      'patterns': [r".*: warning: \[CompileTimeConstant\] .+"]},
     {'category': 'java',
@@ -1529,6 +1349,11 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Dagger @Provides methods may not return null unless annotated with @Nullable',
+     'patterns': [r".*: warning: \[DaggerProvidesNull\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Exception created but not thrown',
      'patterns': [r".*: warning: \[DeadException\] .+"]},
     {'category': 'java',
@@ -1539,6 +1364,11 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Deprecated item is not annotated with @Deprecated',
+     'patterns': [r".*: warning: \[DepAnn\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Division by integer literal zero',
      'patterns': [r".*: warning: \[DivZero\] .+"]},
     {'category': 'java',
@@ -1569,6 +1399,16 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Invalid printf-style format string',
+     'patterns': [r".*: warning: \[FormatString\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Invalid format string passed to formatting method.',
+     'patterns': [r".*: warning: \[FormatStringAnnotation\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Casting a lambda to this @FunctionalInterface can cause a behavior change from casting to a functional superinterface, which is surprising to users.  Prefer decorator methods to this surprising behavior.',
      'patterns': [r".*: warning: \[FunctionalInterfaceMethodChanged\] .+"]},
     {'category': 'java',
@@ -1594,6 +1434,26 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Checks for unguarded accesses to fields and methods with @GuardedBy annotations',
+     'patterns': [r".*: warning: \[GuardedBy\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Scope annotation on implementation class of AssistedInject factory is not allowed',
+     'patterns': [r".*: warning: \[GuiceAssistedInjectScoping\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: A constructor cannot have two @Assisted parameters of the same type unless they are disambiguated with named @Assisted annotations.',
+     'patterns': [r".*: warning: \[GuiceAssistedParameters\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Although Guice allows injecting final fields, doing so is disallowed because the injected value may not be visible to other threads.',
+     'patterns': [r".*: warning: \[GuiceInjectOnFinalField\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: contains() is a legacy method that is equivalent to containsValue()',
      'patterns': [r".*: warning: \[HashtableContains\] .+"]},
     {'category': 'java',
@@ -1604,11 +1464,21 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Type declaration annotated with @Immutable is not immutable',
+     'patterns': [r".*: warning: \[Immutable\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Modifying an immutable collection is guaranteed to throw an exception and leave the collection unmodified',
      'patterns': [r".*: warning: \[ImmutableModification\] .+"]},
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Passing argument to a generic method with an incompatible type.',
+     'patterns': [r".*: warning: \[IncompatibleArgumentType\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: The first argument to indexOf is a Unicode code point, and the second is the index to start the search from',
      'patterns': [r".*: warning: \[IndexOfChar\] .+"]},
     {'category': 'java',
@@ -1624,6 +1494,36 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: A scoping annotation\'s Target should include TYPE and METHOD.',
+     'patterns': [r".*: warning: \[InjectInvalidTargetingOnScopingAnnotation\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Using more than one qualifier annotation on the same element is not allowed.',
+     'patterns': [r".*: warning: \[InjectMoreThanOneQualifier\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: A class can be annotated with at most one scope annotation.',
+     'patterns': [r".*: warning: \[InjectMoreThanOneScopeAnnotationOnClass\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Scope annotation on an interface or abstact class is not allowed',
+     'patterns': [r".*: warning: \[InjectScopeAnnotationOnInterfaceOrAbstractClass\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Scoping and qualifier annotations must have runtime retention.',
+     'patterns': [r".*: warning: \[InjectScopeOrQualifierAnnotationRetention\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Injected constructors cannot be optional nor have binding annotations',
+     'patterns': [r".*: warning: \[InjectedConstructorAnnotations\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: A standard cryptographic operation is used in a mode that is prone to vulnerabilities',
      'patterns': [r".*: warning: \[InsecureCryptoUsage\] .+"]},
     {'category': 'java',
@@ -1644,7 +1544,12 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
-         'Java: Path implements Iterable\u003cPath>; prefer Collection\u003cPath> for clarity',
+         'Java: Log tag too long, cannot exceed 23 characters.',
+     'patterns': [r".*: warning: \[IsLoggableTagLength\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         r'Java: Path implements Iterable\u003cPath>; prefer Collection\u003cPath> for clarity',
      'patterns': [r".*: warning: \[IterablePathParameter\] .+"]},
     {'category': 'java',
      'severity': Severity.HIGH,
@@ -1674,7 +1579,7 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
-         'Java: This looks like a test method but is not run; please add @Test or @Ignore, or, if this is a helper method, reduce its visibility.',
+         'Java: This looks like a test method but is not run; please add @Test and @Ignore, or, if this is a helper method, reduce its visibility.',
      'patterns': [r".*: warning: \[JUnit4TestNotRun\] .+"]},
     {'category': 'java',
      'severity': Severity.HIGH,
@@ -1684,16 +1589,41 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Abstract and default methods are not injectable with javax.inject.Inject',
+     'patterns': [r".*: warning: \[JavaxInjectOnAbstractMethod\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: @javax.inject.Inject cannot be put on a final field.',
+     'patterns': [r".*: warning: \[JavaxInjectOnFinalField\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: This pattern will silently corrupt certain byte sequences from the serialized protocol message. Use ByteString or byte[] directly',
      'patterns': [r".*: warning: \[LiteByteStringUtf8\] .+"]},
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: This method does not acquire the locks specified by its @LockMethod annotation',
+     'patterns': [r".*: warning: \[LockMethodChecker\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Prefer \'L\' to \'l\' for the suffix to long literals',
+     'patterns': [r".*: warning: \[LongLiteralLowerCaseSuffix\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Loop condition is never modified in loop body.',
      'patterns': [r".*: warning: \[LoopConditionChecker\] .+"]},
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Certain resources in `android.R.string` have names that do not match their content',
+     'patterns': [r".*: warning: \[MislabeledAndroidString\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Overriding method is missing a call to overridden super method',
      'patterns': [r".*: warning: \[MissingSuperCall\] .+"]},
     {'category': 'java',
@@ -1719,6 +1649,11 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: This class has more than one @Inject-annotated constructor. Please remove the @Inject annotation from all but one of them.',
+     'patterns': [r".*: warning: \[MoreThanOneInjectableConstructor\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: The result of this method must be closed.',
      'patterns': [r".*: warning: \[MustBeClosedChecker\] .+"]},
     {'category': 'java',
@@ -1764,11 +1699,31 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Annotations cannot be both Scope annotations and Qualifier annotations: this causes confusion when trying to use them.',
+     'patterns': [r".*: warning: \[OverlappingQualifierAndScopeAnnotation\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: This method is not annotated with @Inject, but it overrides a method that is  annotated with @javax.inject.Inject. The method will not be Injected.',
+     'patterns': [r".*: warning: \[OverridesJavaxInjectableMethod\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Declaring types inside package-info.java files is very bad form',
      'patterns': [r".*: warning: \[PackageInfo\] .+"]},
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Method parameter has wrong package',
+     'patterns': [r".*: warning: \[ParameterPackage\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Detects classes which implement Parcelable but don\'t have CREATOR',
+     'patterns': [r".*: warning: \[ParcelableCreator\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Literal passed as first argument to Preconditions.checkNotNull() can never be null',
      'patterns': [r".*: warning: \[PreconditionsCheckNotNull\] .+"]},
     {'category': 'java',
@@ -1804,6 +1759,11 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: @Provides methods need to be declared in a Module to have any effect.',
+     'patterns': [r".*: warning: \[ProvidesMethodOutsideOfModule\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Casting a random number in the range [0.0, 1.0) to an integer or long always results in 0.',
      'patterns': [r".*: warning: \[RandomCast\] .+"]},
     {'category': 'java',
@@ -1814,6 +1774,16 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Return value of android.graphics.Rect.intersect() must be checked',
+     'patterns': [r".*: warning: \[RectIntersectReturnValueIgnored\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
+         'Java: Use of method or class annotated with @RestrictTo',
+     'patterns': [r".*: warning: \[RestrictTo\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java:  Check for non-whitelisted callers to RestrictedApiChecker.',
      'patterns': [r".*: warning: \[RestrictedApiChecker\] .+"]},
     {'category': 'java',
@@ -1849,6 +1819,11 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: Static and default interface methods are not natively supported on older Android devices. ',
+     'patterns': [r".*: warning: \[StaticOrDefaultInterfaceMethod\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Calling toString on a Stream does not provide useful information',
      'patterns': [r".*: warning: \[StreamToString\] .+"]},
     {'category': 'java',
@@ -1889,6 +1864,11 @@
     {'category': 'java',
      'severity': Severity.HIGH,
      'description':
+         'Java: This method does not acquire the locks specified by its @UnlockMethod annotation',
+     'patterns': [r".*: warning: \[UnlockMethod\] .+"]},
+    {'category': 'java',
+     'severity': Severity.HIGH,
+     'description':
          'Java: Non-generic methods should not be invoked with type arguments',
      'patterns': [r".*: warning: \[UnnecessaryTypeArgument\] .+"]},
     {'category': 'java',
@@ -1906,191 +1886,6 @@
      'description':
          'Java: `var` should not be used as a type name.',
      'patterns': [r".*: warning: \[VarTypeName\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Method parameter has wrong package',
-     'patterns': [r".*: warning: \[ParameterPackage\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Type declaration annotated with @ThreadSafe is not thread safe',
-     'patterns': [r".*: warning: \[ThreadSafe\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use of class, field, or method that is not compatible with legacy Android devices',
-     'patterns': [r".*: warning: \[AndroidApiChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Invalid use of Flogger format string',
-     'patterns': [r".*: warning: \[AndroidFloggerFormatString\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use TunnelException.getCauseAs(Class) instead of casting the result of TunnelException.getCause().',
-     'patterns': [r".*: warning: \[DoNotCastTunnelExceptionCause\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Identifies undesirable mocks.',
-     'patterns': [r".*: warning: \[DoNotMock_ForJavaBuilder\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Duration Flag should NOT have units in the variable name or the @FlagSpec\'s name or altName field.',
-     'patterns': [r".*: warning: \[DurationFlagWithUnits\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Duration.get() only works with SECONDS or NANOS.',
-     'patterns': [r".*: warning: \[DurationGetTemporalUnit\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Invalid printf-style format string',
-     'patterns': [r".*: warning: \[FloggerFormatString\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Test class may not be run because it is missing a @RunWith annotation',
-     'patterns': [r".*: warning: \[JUnit4RunWithMissing\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use of class, field, or method that is not compatible with JDK 7',
-     'patterns': [r".*: warning: \[Java7ApiChecker\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use of java.time.Duration.withNanos(int) is not allowed.',
-     'patterns': [r".*: warning: \[JavaDurationWithNanos\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use of java.time.Duration.withSeconds(long) is not allowed.',
-     'patterns': [r".*: warning: \[JavaDurationWithSeconds\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: java.time APIs that silently use the default system time-zone are not allowed.',
-     'patterns': [r".*: warning: \[JavaTimeDefaultTimeZone\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use of new Duration(long) is not allowed. Please use Duration.millis(long) instead.',
-     'patterns': [r".*: warning: \[JodaDurationConstructor\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use of duration.withMillis(long) is not allowed. Please use Duration.millis(long) instead.',
-     'patterns': [r".*: warning: \[JodaDurationWithMillis\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use of instant.withMillis(long) is not allowed. Please use new Instant(long) instead.',
-     'patterns': [r".*: warning: \[JodaInstantWithMillis\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use of JodaTime\'s type.plus(long) or type.minus(long) is not allowed (where \u003ctype> = {Duration,Instant,DateTime,DateMidnight}). Please use type.plus(Duration.millis(long)) or type.minus(Duration.millis(long)) instead.',
-     'patterns': [r".*: warning: \[JodaPlusMinusLong\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Changing JodaTime\'s current time is not allowed in non-testonly code.',
-     'patterns': [r".*: warning: \[JodaSetCurrentMillis\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use of Joda-Time\'s DateTime.toDateTime(), Duration.toDuration(), Instant.toInstant(), Interval.toInterval(), and Period.toPeriod() are not allowed.',
-     'patterns': [r".*: warning: \[JodaToSelf\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Use of JodaTime\'s type.withDurationAdded(long, int) (where \u003ctype> = {Duration,Instant,DateTime}). Please use type.withDurationAdded(Duration.millis(long), int) instead.',
-     'patterns': [r".*: warning: \[JodaWithDurationAddedLong\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: LanguageCode comparison using reference equality instead of value equality',
-     'patterns': [r".*: warning: \[LanguageCodeEquality\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: The zero argument toString is not part of the Localizable interface and likely is just the java Object toString.  You probably want to call toString(Locale).',
-     'patterns': [r".*: warning: \[LocalizableWrongToString\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Period.get() only works with YEARS, MONTHS, or DAYS.',
-     'patterns': [r".*: warning: \[PeriodGetTemporalUnit\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Return value of methods returning Promise must be checked. Ignoring returned Promises suppresses exceptions thrown from the code that completes the Promises.',
-     'patterns': [r".*: warning: \[PromiseReturnValueIgnored\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: When returning a Promise, use thenChain() instead of then()',
-     'patterns': [r".*: warning: \[PromiseThenReturningPromise\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Streams.iterating() is unsafe for use except in the header of a for-each loop; please see its Javadoc for details.',
-     'patterns': [r".*: warning: \[StreamsIteratingNotInLoop\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: TemporalAccessor.get() only works for certain values of ChronoField.',
-     'patterns': [r".*: warning: \[TemporalAccessorGetChronoField\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Try-with-resources is not supported in this code, use try/finally instead',
-     'patterns': [r".*: warning: \[TryWithResources\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Adds checkOrThrow calls where needed',
-     'patterns': [r".*: warning: \[AddCheckOrThrow\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Equality on Nano protos (== or .equals) might not be the same in Lite',
-     'patterns': [r".*: warning: \[ForbidNanoEquality\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Submessages of a proto cannot be mutated',
-     'patterns': [r".*: warning: \[ForbidSubmessageMutation\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Repeated fields on proto messages cannot be directly referenced',
-     'patterns': [r".*: warning: \[NanoUnsafeRepeatedFieldUsage\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Requires that non-@enum int assignments to @enum ints is wrapped in a checkOrThrow',
-     'patterns': [r".*: warning: \[RequireCheckOrThrow\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Assignments into repeated field elements must be sequential',
-     'patterns': [r".*: warning: \[RequireSequentialRepeatedFields\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: Future.get in Google Now Producers code',
-     'patterns': [r".*: warning: \[FutureGetInNowProducers\] .+"]},
-    {'category': 'java',
-     'severity': Severity.HIGH,
-     'description':
-         'Java: @SimpleEnum applied to non-enum type',
-     'patterns': [r".*: warning: \[SimpleEnumUsage\] .+"]},
 
     # End warnings generated by Error Prone
 
@@ -2513,6 +2308,29 @@
 
     # warnings from clang-tidy
     group_tidy_warn_pattern('android'),
+    simple_tidy_warn_pattern('bugprone-argument-comment'),
+    simple_tidy_warn_pattern('bugprone-copy-constructor-init'),
+    simple_tidy_warn_pattern('bugprone-fold-init-type'),
+    simple_tidy_warn_pattern('bugprone-forward-declaration-namespace'),
+    simple_tidy_warn_pattern('bugprone-forwarding-reference-overload'),
+    simple_tidy_warn_pattern('bugprone-inaccurate-erase'),
+    simple_tidy_warn_pattern('bugprone-incorrect-roundings'),
+    simple_tidy_warn_pattern('bugprone-integer-division'),
+    simple_tidy_warn_pattern('bugprone-lambda-function-name'),
+    simple_tidy_warn_pattern('bugprone-macro-parentheses'),
+    simple_tidy_warn_pattern('bugprone-misplaced-widening-cast'),
+    simple_tidy_warn_pattern('bugprone-move-forwarding-reference'),
+    simple_tidy_warn_pattern('bugprone-sizeof-expression'),
+    simple_tidy_warn_pattern('bugprone-string-constructor'),
+    simple_tidy_warn_pattern('bugprone-string-integer-assignment'),
+    simple_tidy_warn_pattern('bugprone-suspicious-enum-usage'),
+    simple_tidy_warn_pattern('bugprone-suspicious-missing-comma'),
+    simple_tidy_warn_pattern('bugprone-suspicious-string-compare'),
+    simple_tidy_warn_pattern('bugprone-suspicious-semicolon'),
+    simple_tidy_warn_pattern('bugprone-undefined-memory-manipulation'),
+    simple_tidy_warn_pattern('bugprone-unused-raii'),
+    simple_tidy_warn_pattern('bugprone-use-after-move'),
+    group_tidy_warn_pattern('bugprone'),
     group_tidy_warn_pattern('cert'),
     group_tidy_warn_pattern('clang-diagnostic'),
     group_tidy_warn_pattern('cppcoreguidelines'),
@@ -2635,7 +2453,6 @@
     simple_project_pattern('frameworks/av/cmds'),
     simple_project_pattern('frameworks/av/drm'),
     simple_project_pattern('frameworks/av/include'),
-    simple_project_pattern('frameworks/av/media/common_time'),
     simple_project_pattern('frameworks/av/media/img_utils'),
     simple_project_pattern('frameworks/av/media/libcpustats'),
     simple_project_pattern('frameworks/av/media/libeffects'),
@@ -3006,6 +2823,7 @@
 
 
 def classify_one_warning(line, results):
+  """Classify one warning line."""
   for i in range(len(warn_patterns)):
     w = warn_patterns[i]
     for cpat in w['compiled_patterns']: