Merge "Add out/soong/late-${TARGET_PRODUCT}.mk"
diff --git a/core/Makefile b/core/Makefile
index f96e3d7..220b620 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -130,7 +130,7 @@
 
 # -----------------------------------------------------------------
 # docs/index.html
-ifeq (,$(TARGET_BUILD_APPS))
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
 gen := $(OUT_DOCS)/index.html
 ALL_DOCS += $(gen)
 $(gen): frameworks/base/docs/docs-redirect-index.html
@@ -220,17 +220,20 @@
 # $(9): module directory name
 # Returns the a list of src:dest pairs to install the modules using copy-many-files.
 define build-image-kernel-modules
+  $(if $(9), \
+    $(eval _dir := $(9)/), \
+    $(eval _dir :=)) \
   $(foreach module,$(1), \
     $(eval _src := $(module)) \
     $(if $(8), \
       $(eval _src := $(8)/$(notdir $(module))) \
       $(eval $(call copy-and-strip-kernel-module,$(module),$(_src)))) \
-    $(_src):$(2)/lib/modules/$(9)/$(notdir $(module))) \
+    $(_src):$(2)/lib/modules/$(_dir)$(notdir $(module))) \
   $(eval $(call build-image-kernel-modules-depmod,$(1),$(3),$(4),$(5),$(6),$(7),$(2),$(9))) \
-  $(4)/$(DEPMOD_STAGING_SUBDIR)/modules.dep:$(2)/lib/modules/$(9)/modules.dep \
-  $(4)/$(DEPMOD_STAGING_SUBDIR)/modules.alias:$(2)/lib/modules/$(9)/modules.alias \
-  $(4)/$(DEPMOD_STAGING_SUBDIR)/modules.softdep:$(2)/lib/modules/$(9)/modules.softdep \
-  $(4)/$(DEPMOD_STAGING_SUBDIR)/$(6):$(2)/lib/modules/$(9)/$(6)
+  $(4)/$(DEPMOD_STAGING_SUBDIR)/modules.dep:$(2)/lib/modules/$(_dir)modules.dep \
+  $(4)/$(DEPMOD_STAGING_SUBDIR)/modules.alias:$(2)/lib/modules/$(_dir)modules.alias \
+  $(4)/$(DEPMOD_STAGING_SUBDIR)/modules.softdep:$(2)/lib/modules/$(_dir)modules.softdep \
+  $(4)/$(DEPMOD_STAGING_SUBDIR)/$(6):$(2)/lib/modules/$(_dir)$(6)
 endef
 
 # $(1): modules list
@@ -360,10 +363,16 @@
 	VENDOR_STRIPPED_MODULE_STAGING_DIR :=
 endif
 
+ifneq ($(BOARD_DO_NOT_STRIP_VENDOR_RAMDISK_MODULES),true)
+  VENDOR_RAMDISK_STRIPPED_MODULE_STAGING_DIR := $(call intermediates-dir-for,PACKAGING,depmod_vendor_ramdisk_stripped)
+else
+  VENDOR_RAMDISK_STRIPPED_MODULE_STAGING_DIR :=
+endif
+
 BOARD_KERNEL_MODULE_DIRS += top
 $(foreach dir,$(BOARD_KERNEL_MODULE_DIRS), \
   $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,RECOVERY,$(TARGET_RECOVERY_ROOT_OUT),,modules.load.recovery,,$(dir))) \
-  $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,VENDOR_RAMDISK,$(TARGET_VENDOR_RAMDISK_OUT),,modules.load,$(call intermediates-dir-for,PACKAGING,depmod_vendor_ramdisk_stripped),$(dir))) \
+  $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,VENDOR_RAMDISK,$(TARGET_VENDOR_RAMDISK_OUT),,modules.load,$(VENDOR_RAMDISK_STRIPPED_MODULE_STAGING_DIR),$(dir))) \
   $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-vendor-ramdisk-recovery-load,$(dir))) \
   $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,VENDOR,$(TARGET_OUT_VENDOR),vendor,modules.load,$(VENDOR_STRIPPED_MODULE_STAGING_DIR),$(dir))) \
   $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,ODM,$(TARGET_OUT_ODM),odm,modules.load,,$(dir))) \
@@ -1636,7 +1645,7 @@
 endef
 
 $(INSTALLED_RECOVERY_BUILD_PROP_TARGET): \
-	    $(intermediate_system_build_prop) \
+	    $(INSTALLED_BUILD_PROP_TARGET) \
 	    $(INSTALLED_VENDOR_BUILD_PROP_TARGET) \
 	    $(INSTALLED_ODM_BUILD_PROP_TARGET) \
 	    $(INSTALLED_PRODUCT_BUILD_PROP_TARGET) \
@@ -1644,7 +1653,7 @@
 	@echo "Target recovery buildinfo: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) rm -f $@
-	$(hide) cat $(intermediate_system_build_prop) >> $@
+	$(hide) cat $(INSTALLED_BUILD_PROP_TARGET) >> $@
 	$(hide) cat $(INSTALLED_VENDOR_BUILD_PROP_TARGET) >> $@
 	$(hide) cat $(INSTALLED_ODM_BUILD_PROP_TARGET) >> $@
 	$(hide) cat $(INSTALLED_PRODUCT_BUILD_PROP_TARGET) >> $@
@@ -3297,7 +3306,7 @@
 # -----------------------------------------------------------------
 # Check VINTF of build
 
-ifndef TARGET_BUILD_APPS
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
 intermediates := $(call intermediates-dir-for,PACKAGING,check_vintf_all)
 check_vintf_all_deps :=
 
@@ -3503,13 +3512,12 @@
 check_vintf_common_srcs :=
 check_vintf_all_deps :=
 intermediates :=
-endif # !TARGET_BUILD_APPS
+endif # !TARGET_BUILD_UNBUNDLED
 
 # -----------------------------------------------------------------
 # Check image sizes <= size of super partition
 
-ifeq (,$(TARGET_BUILD_APPS))
-# Do not check for apps-only build
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
 
 ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION))
 
@@ -3545,7 +3553,7 @@
 
 endif # PRODUCT_BUILD_SUPER_PARTITION
 
-endif # TARGET_BUILD_APPS
+endif # !TARGET_BUILD_UNBUNDLED
 
 # -----------------------------------------------------------------
 # bring in the installer image generation defines if necessary
@@ -3765,6 +3773,9 @@
 else
 	echo "boot_images=$(foreach b,$(INSTALLED_BOOTIMAGE_TARGET),$(notdir $(b)))" >> $@
 endif
+ifeq ($(BOARD_RAMDISK_USE_LZ4),true)
+	echo "lz4_ramdisks=true" >> $@
+endif
 ifneq ($(INSTALLED_VENDOR_BOOTIMAGE_TARGET),)
 	echo "vendor_boot=true" >> $@
 	echo "vendor_boot_size=$(BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE)" >> $@
@@ -3946,7 +3957,7 @@
 # We can't build static executables when SANITIZE_TARGET=address
 ifeq (,$(filter address, $(SANITIZE_TARGET)))
 built_ota_tools += \
-    $(call intermediates-dir-for,EXECUTABLES,updater,,,$(TARGET_PREFER_32_BIT))/updater
+    $(call intermediates-dir-for,EXECUTABLES,updater)/updater
 endif
 
 $(BUILT_TARGET_FILES_PACKAGE): PRIVATE_OTA_TOOLS := $(built_ota_tools)
@@ -4472,7 +4483,7 @@
 # A zip of the appcompat directory containing logs
 APPCOMPAT_ZIP := $(PRODUCT_OUT)/appcompat.zip
 # For apps_only build we'll establish the dependency later in build/make/core/main.mk.
-ifndef TARGET_BUILD_APPS
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
 $(APPCOMPAT_ZIP): $(INSTALLED_SYSTEMIMAGE_TARGET) \
 	    $(INSTALLED_RAMDISK_TARGET) \
 	    $(INSTALLED_BOOTIMAGE_TARGET) \
@@ -4501,7 +4512,7 @@
 
 SYMBOLS_ZIP := $(PRODUCT_OUT)/$(name).zip
 # For apps_only build we'll establish the dependency later in build/make/core/main.mk.
-ifndef TARGET_BUILD_APPS
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
 $(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE_TARGET) \
 	    $(INSTALLED_RAMDISK_TARGET) \
 	    $(INSTALLED_BOOTIMAGE_TARGET) \
@@ -4527,7 +4538,7 @@
 name := $(name)_debug
 endif
 COVERAGE_ZIP := $(PRODUCT_OUT)/$(name).zip
-ifndef TARGET_BUILD_APPS
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
 $(COVERAGE_ZIP): $(INSTALLED_SYSTEMIMAGE_TARGET) \
 	    $(INSTALLED_RAMDISK_TARGET) \
 	    $(INSTALLED_BOOTIMAGE_TARGET) \
@@ -4602,7 +4613,7 @@
 #
 PROGUARD_DICT_ZIP := $(PRODUCT_OUT)/$(TARGET_PRODUCT)-proguard-dict-$(FILE_NAME_TAG).zip
 # For apps_only build we'll establish the dependency later in build/make/core/main.mk.
-ifndef TARGET_BUILD_APPS
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
 $(PROGUARD_DICT_ZIP): \
     $(INSTALLED_SYSTEMIMAGE_TARGET) \
     $(INSTALLED_RAMDISK_TARGET) \
diff --git a/core/base_rules.mk b/core/base_rules.mk
index f5e8e35..9818d60 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -174,11 +174,10 @@
 # file, tag the module as "gnu".  Search for "*_GPL*", "*_LGPL*" and "*_MPL*"
 # so that we can also find files like MODULE_LICENSE_GPL_AND_AFL
 #
-license_files := $(call find-parent-file,$(LOCAL_PATH),MODULE_LICENSE*)
 gpl_license_file := $(call find-parent-file,$(LOCAL_PATH),MODULE_LICENSE*_GPL* MODULE_LICENSE*_MPL* MODULE_LICENSE*_LGPL*)
 ifneq ($(gpl_license_file),)
   my_module_tags += gnu
-  ALL_GPL_MODULE_LICENSE_FILES := $(sort $(ALL_GPL_MODULE_LICENSE_FILES) $(gpl_license_file))
+  ALL_GPL_MODULE_LICENSE_FILES += $(gpl_license_file)
 endif
 
 LOCAL_MODULE_CLASS := $(strip $(LOCAL_MODULE_CLASS))
@@ -316,9 +315,19 @@
 endif
 $(module_id) := $(LOCAL_PATH)
 
-intermediates := $(call local-intermediates-dir,,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))
-intermediates.COMMON := $(call local-intermediates-dir,COMMON)
-generated_sources_dir := $(call local-generated-sources-dir)
+# These are the same as local-intermediates-dir / local-generated-sources dir, but faster
+intermediates.COMMON := $($(my_prefix)OUT_COMMON_INTERMEDIATES)/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates
+ifneq (,$(filter $(my_prefix)$(LOCAL_MODULE_CLASS),$(COMMON_MODULE_CLASSES)))
+  intermediates := $($(my_prefix)OUT_COMMON_INTERMEDIATES)/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates
+  generated_sources_dir := $($(my_prefix)OUT_COMMON_GEN)/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates
+else
+  ifneq (,$(filter $(LOCAL_MODULE_CLASS),$(PER_ARCH_MODULE_CLASSES)))
+    intermediates := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATES)/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates
+  else
+    intermediates := $($(my_prefix)OUT_INTERMEDIATES)/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates
+  endif
+  generated_sources_dir := $($(my_prefix)OUT_GEN)/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates
+endif
 
 ifneq ($(LOCAL_OVERRIDES_MODULES),)
   ifndef LOCAL_IS_HOST_MODULE
@@ -562,17 +571,35 @@
 ifneq ($(strip $(LOCAL_TEST_DATA)),)
 ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
 
-my_test_data_pairs := $(strip $(foreach td,$(LOCAL_TEST_DATA), \
-    $(eval _file := $(call word-colon,2,$(td))) \
-    $(if $(_file), \
-      $(eval _src_base := $(call word-colon,1,$(td))), \
-      $(eval _src_base := $(LOCAL_PATH)) \
-        $(eval _file := $(call word-colon,1,$(td)))) \
-    $(if $(call streq,$(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK)),, \
-      $(if $(findstring ..,$(_file)),$(error $(LOCAL_MODULE_MAKEFILE): LOCAL_TEST_DATA may not include '..': $(_file))) \
-      $(if $(filter /%,$(_src_base) $(_file)),$(error $(LOCAL_MODULE_MAKEFILE): LOCAL_TEST_DATA may not include absolute paths: $(_src_base) $(_file)))) \
-    $(eval my_test_data_file_pairs := $(my_test_data_file_pairs) $(call append-path,$(_src_base),$(_file)):$(_file)) \
-    $(call append-path,$(_src_base),$(_file)):$(call append-path,$(my_module_path),$(_file))))
+ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+  define copy_test_data_pairs
+    _src_base := $$(call word-colon,1,$$(td))
+    _file := $$(call word-colon,2,$$(td))
+    my_test_data_pairs += $$(call append-path,$$(_src_base),$$(_file)):$$(call append-path,$$(my_module_path),$$(_file))
+    my_test_data_file_pairs += $$(call append-path,$$(_src_base),$$(_file)):$$(_file)
+  endef
+else
+  define copy_test_data_pairs
+    _src_base := $$(call word-colon,1,$$(td))
+    _file := $$(call word-colon,2,$$(td))
+    ifndef _file
+      _file := $$(_src_base)
+      _src_base := $$(LOCAL_PATH)
+    endif
+    ifneq (,$$(findstring ..,$$(_file)))
+      $$(call pretty-error,LOCAL_TEST_DATA may not include '..': $$(_file))
+    endif
+    ifneq (,$$(filter/%,$$(_src_base) $$(_file)))
+      $$(call pretty-error,LOCAL_TEST_DATA may not include absolute paths: $$(_src_base) $$(_file))
+    endif
+    my_test_data_pairs += $$(call append-path,$$(_src_base),$$(_file)):$$(call append-path,$$(my_module_path),$$(_file))
+    my_test_data_file_pairs += $$(call append-path,$$(_src_base),$$(_file)):$$(_file)
+  endef
+endif
+
+$(foreach td,$(LOCAL_TEST_DATA),$(eval $(copy_test_data_pairs)))
+
+copy_test_data_pairs :=
 
 my_installed_test_data := $(call copy-many-files,$(my_test_data_pairs))
 $(LOCAL_INSTALLED_MODULE): $(my_installed_test_data)
@@ -907,7 +934,7 @@
 # Track module-level dependencies.
 # Use $(LOCAL_MODULE) instead of $(my_register_name) to ignore module's bitness.
 ifdef RECORD_ALL_DEPS
-ALL_DEPS.MODULES := $(ALL_DEPS.MODULES) $(LOCAL_MODULE)
+ALL_DEPS.MODULES += $(LOCAL_MODULE)
 ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS := $(sort \
   $(ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS) \
   $(LOCAL_STATIC_LIBRARIES) \
@@ -921,6 +948,7 @@
   $(LOCAL_JAVA_LIBRARIES) \
   $(LOCAL_JNI_SHARED_LIBRARIES))
 
+license_files := $(call find-parent-file,$(LOCAL_PATH),MODULE_LICENSE*)
 ALL_DEPS.$(LOCAL_MODULE).LICENSE := $(sort $(ALL_DEPS.$(LOCAL_MODULE).LICENSE) $(license_files))
 endif
 
diff --git a/core/binary.mk b/core/binary.mk
index b14d8b8..4894bf2 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1799,7 +1799,7 @@
      $(call intermediates-dir-for,HEADER_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))))
 
 ifneq ($(strip $(my_export_c_include_dirs)$(export_include_deps)),)
-  EXPORTS_LIST := $(EXPORTS_LIST) $(intermediates)
+  EXPORTS_LIST += $(intermediates)
   EXPORTS.$(intermediates).FLAGS := $(foreach d,$(my_export_c_include_dirs),-I $(call clean-path,$(d)))
   EXPORTS.$(intermediates).REEXPORT := $(export_include_deps)
   EXPORTS.$(intermediates).DEPS := $(my_export_c_include_deps) $(my_generated_sources) $(LOCAL_EXPORT_C_INCLUDE_DEPS)
diff --git a/core/board_config.mk b/core/board_config.mk
index 0ff28c5..ae1614f 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -242,13 +242,8 @@
 # build a list out of the TARGET_CPU_ABIs specified by the config.
 # Add NATIVE_BRIDGE_ABIs at the end to keep order of preference.
 ifeq (,$(TARGET_CPU_ABI_LIST))
-  ifeq ($(TARGET_IS_64_BIT)|$(TARGET_PREFER_32_BIT_APPS),true|true)
-    TARGET_CPU_ABI_LIST := $(TARGET_CPU_ABI_LIST_32_BIT) $(TARGET_CPU_ABI_LIST_64_BIT) \
-                           $(_target_native_bridge_abi_list_32_bit) $(_target_native_bridge_abi_list_64_bit)
-  else
-    TARGET_CPU_ABI_LIST := $(TARGET_CPU_ABI_LIST_64_BIT) $(TARGET_CPU_ABI_LIST_32_BIT) \
-                           $(_target_native_bridge_abi_list_64_bit) $(_target_native_bridge_abi_list_32_bit)
-  endif
+  TARGET_CPU_ABI_LIST := $(TARGET_CPU_ABI_LIST_64_BIT) $(TARGET_CPU_ABI_LIST_32_BIT) \
+                         $(_target_native_bridge_abi_list_64_bit) $(_target_native_bridge_abi_list_32_bit)
 endif
 
 # Add NATIVE_BRIDGE_ABIs at the end of 32 and 64 bit CPU_ABIs to keep order of preference.
@@ -622,7 +617,7 @@
   endif
 endif
 
-ifeq (,$(TARGET_BUILD_APPS))
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
 ifdef PRODUCT_EXTRA_VNDK_VERSIONS
   $(foreach v,$(PRODUCT_EXTRA_VNDK_VERSIONS),$(call check_vndk_version,$(v)))
 endif
diff --git a/core/cc_prebuilt_internal.mk b/core/cc_prebuilt_internal.mk
index 1d959b5..99b7d0f 100644
--- a/core/cc_prebuilt_internal.mk
+++ b/core/cc_prebuilt_internal.mk
@@ -75,7 +75,7 @@
   built_module := $(LOCAL_BUILT_MODULE)
 
 ifdef prebuilt_module_is_a_library
-EXPORTS_LIST := $(EXPORTS_LIST) $(intermediates)
+EXPORTS_LIST += $(intermediates)
 EXPORTS.$(intermediates).FLAGS := $(foreach d,$(LOCAL_EXPORT_C_INCLUDE_DIRS),-I $(d))
 EXPORTS.$(intermediates).DEPS := $(LOCAL_EXPORT_C_INCLUDE_DEPS)
 
diff --git a/core/config.mk b/core/config.mk
index 5be1b86..eaabe64 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -22,6 +22,13 @@
 
 include $(BUILD_SYSTEM_COMMON)/core.mk
 
+# -----------------------------------------------------------------
+# Rules and functions to help copy important files to DIST_DIR
+# when requested. This must be included once only, and must be included before
+# soong_config (as soong_config calls make_vars-$(TARGET).mk, and soong may
+# propagate calls to dist-for-goals there).
+include $(BUILD_SYSTEM)/distdir.mk
+
 # Mark variables that should be coming as environment variables from soong_ui
 # as readonly
 .KATI_READONLY := OUT_DIR TMPDIR BUILD_DATETIME_FILE
@@ -141,6 +148,7 @@
   TARGET_PROJECT_SYSTEM_INCLUDES \
   2ND_TARGET_PROJECT_SYSTEM_INCLUDES \
   ,Project include variables have been removed)
+$(KATI_obsolete_var TARGET_PREFER_32_BIT TARGET_PREFER_32_BIT_APPS TARGET_PREFER_32_BIT_EXECUTABLES)
 
 # Used to force goals to build.  Only use for conditionally defined goals.
 .PHONY: FORCE
@@ -375,11 +383,6 @@
 include $(BUILD_SYSTEM)/rbe.mk
 endif
 
-ifdef TARGET_PREFER_32_BIT
-TARGET_PREFER_32_BIT_APPS := true
-TARGET_PREFER_32_BIT_EXECUTABLES := true
-endif
-
 # GCC version selection
 TARGET_GCC_VERSION := 4.9
 ifdef TARGET_2ND_ARCH
diff --git a/core/definitions.mk b/core/definitions.mk
index 3672900..2bf1ba6 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -110,6 +110,18 @@
 # All compatibility suites mentioned in LOCAL_COMPATIBILITY_SUITES
 ALL_COMPATIBILITY_SUITES :=
 
+# All LINK_TYPE entries
+ALL_LINK_TYPES :=
+
+# All exported/imported include entries
+EXPORTS_LIST :=
+
+# All modules already converted to Soong
+SOONG_ALREADY_CONV :=
+
+# ALL_DEPS.*.ALL_DEPS keys
+ALL_DEPS.MODULES :=
+
 ###########################################################
 ## Debugging; prints a variable list to stdout
 ###########################################################
@@ -527,6 +539,14 @@
 endef
 
 ###########################################################
+## Convert install path to on-device path.
+###########################################################
+# $(1): install path
+define install-path-to-on-device-path
+$(patsubst $(PRODUCT_OUT)%,%,$(1))
+endef
+
+###########################################################
 ## The intermediates directory.  Where object files go for
 ## a given target.  We could technically get away without
 ## the "_intermediates" suffix on the directory, but it's
@@ -550,7 +570,7 @@
         $(error $(LOCAL_PATH): Name not defined in call to intermediates-dir-for)) \
     $(eval _idfPrefix := $(call find-idf-prefix,$(3),$(6))) \
     $(eval _idf2ndArchPrefix := $(if $(strip $(5)),$(TARGET_2ND_ARCH_VAR_PREFIX))) \
-    $(if $(filter $(_idfPrefix)-$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
+    $(if $(filter $(_idfPrefix)_$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
         $(eval _idfIntBase := $($(_idfPrefix)_OUT_COMMON_INTERMEDIATES)) \
       ,$(if $(filter $(_idfClass),$(PER_ARCH_MODULE_CLASSES)),\
           $(eval _idfIntBase := $($(_idf2ndArchPrefix)$(_idfPrefix)_OUT_INTERMEDIATES)) \
@@ -599,7 +619,7 @@
     $(if $(_idfName),, \
         $(error $(LOCAL_PATH): Name not defined in call to generated-sources-dir-for)) \
     $(eval _idfPrefix := $(call find-idf-prefix,$(3),)) \
-    $(if $(filter $(_idfPrefix)-$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
+    $(if $(filter $(_idfPrefix)_$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
         $(eval _idfIntBase := $($(_idfPrefix)_OUT_COMMON_GEN)) \
       , \
         $(eval _idfIntBase := $($(_idfPrefix)_OUT_GEN)) \
@@ -2796,13 +2816,15 @@
 #    and use my_compat_dist_$(suite) to define the others.
 define create-suite-dependencies
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-  $(if $(filter $(suite),$(ALL_COMPATIBILITY_SUITES)),,$(eval ALL_COMPATIBILITY_SUITES += $(suite))) \
-  $(eval COMPATIBILITY.$(suite).FILES := \
-    $$(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))) \
-      $$(my_compat_dist_test_data_$(suite))) \
-  $(eval COMPATIBILITY.$(suite).MODULES := \
-    $$(COMPATIBILITY.$(suite).MODULES) $$(my_register_name))) \
+  $(if $(filter $(suite),$(ALL_COMPATIBILITY_SUITES)),,\
+    $(eval ALL_COMPATIBILITY_SUITES += $(suite)) \
+    $(eval COMPATIBILITY.$(suite).FILES :=) \
+    $(eval COMPATIBILITY.$(suite).MODULES :=)) \
+  $(eval 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))) \
+    $$(my_compat_dist_test_data_$(suite))) \
+  $(eval COMPATIBILITY.$(suite).MODULES += $$(my_register_name))) \
 $(eval $(my_all_targets) : $(call copy-many-files, \
   $(sort $(foreach suite,$(LOCAL_COMPATIBILITY_SUITE),$(my_compat_dist_$(suite))))) \
   $(call copy-many-xml-files-checked, \
@@ -3064,11 +3086,6 @@
 ## Other includes
 ###########################################################
 
-# -----------------------------------------------------------------
-# Rules and functions to help copy important files to DIST_DIR
-# when requested.
-include $(BUILD_SYSTEM)/distdir.mk
-
 # Include any vendor specific definitions.mk file
 -include $(TOPDIR)vendor/*/build/core/definitions.mk
 -include $(TOPDIR)device/*/build/core/definitions.mk
diff --git a/core/dex_preopt_config.mk b/core/dex_preopt_config.mk
index 598ac2d..7d7d526 100644
--- a/core/dex_preopt_config.mk
+++ b/core/dex_preopt_config.mk
@@ -1,5 +1,14 @@
 DEX_PREOPT_CONFIG := $(SOONG_OUT_DIR)/dexpreopt.config
 
+ENABLE_PREOPT := true
+ifneq (true,$(filter true,$(WITH_DEXPREOPT)))
+  ENABLE_PREOPT :=
+else ifneq (true,$(filter true,$(PRODUCT_USES_DEFAULT_ART_CONFIG)))
+  ENABLE_PREOPT :=
+else ifneq (,$(TARGET_BUILD_APPS))
+  ENABLE_PREOPT :=
+endif
+
 # The default value for LOCAL_DEX_PREOPT
 DEX_PREOPT_DEFAULT ?= true
 
@@ -60,40 +69,41 @@
 
   $(call json_start)
 
-  $(call add_json_bool, DisablePreopt,                      $(call invert_bool,$(and $(filter true,$(PRODUCT_USES_DEFAULT_ART_CONFIG)),$(filter true,$(WITH_DEXPREOPT)))))
-  $(call add_json_list, DisablePreoptModules,               $(DEXPREOPT_DISABLED_MODULES))
-  $(call add_json_bool, OnlyPreoptBootImageAndSystemServer, $(filter true,$(WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY)))
-  $(call add_json_bool, UseArtImage,                        $(filter true,$(DEXPREOPT_USE_ART_IMAGE)))
-  $(call add_json_bool, DontUncompressPrivAppsDex,          $(filter true,$(DONT_UNCOMPRESS_PRIV_APPS_DEXS)))
-  $(call add_json_list, ModulesLoadedByPrivilegedModules,   $(PRODUCT_LOADED_BY_PRIVILEGED_MODULES))
-  $(call add_json_bool, HasSystemOther,                     $(BOARD_USES_SYSTEM_OTHER_ODEX))
-  $(call add_json_list, PatternsOnSystemOther,              $(SYSTEM_OTHER_ODEX_FILTER))
-  $(call add_json_bool, DisableGenerateProfile,             $(filter false,$(WITH_DEX_PREOPT_GENERATE_PROFILE)))
-  $(call add_json_str,  ProfileDir,                         $(PRODUCT_DEX_PREOPT_PROFILE_DIR))
-  $(call add_json_list, BootJars,                           $(PRODUCT_BOOT_JARS))
-  $(call add_json_list, UpdatableBootJars,                  $(PRODUCT_UPDATABLE_BOOT_JARS))
-  $(call add_json_list, ArtApexJars,                        $(ART_APEX_JARS))
-  $(call add_json_list, SystemServerJars,                   $(PRODUCT_SYSTEM_SERVER_JARS))
-  $(call add_json_list, SystemServerApps,                   $(PRODUCT_SYSTEM_SERVER_APPS))
-  $(call add_json_list, UpdatableSystemServerJars,          $(PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS))
-  $(call add_json_list, SpeedApps,                          $(PRODUCT_DEXPREOPT_SPEED_APPS))
-  $(call add_json_list, PreoptFlags,                        $(PRODUCT_DEX_PREOPT_DEFAULT_FLAGS))
-  $(call add_json_str,  DefaultCompilerFilter,              $(PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER))
-  $(call add_json_str,  SystemServerCompilerFilter,         $(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER))
-  $(call add_json_bool, GenerateDmFiles,                    $(PRODUCT_DEX_PREOPT_GENERATE_DM_FILES))
-  $(call add_json_bool, NeverAllowStripping,                $(PRODUCT_DEX_PREOPT_NEVER_ALLOW_STRIPPING))
-  $(call add_json_bool, NoDebugInfo,                        $(filter false,$(WITH_DEXPREOPT_DEBUG_INFO)))
-  $(call add_json_bool, DontResolveStartupStrings,          $(filter false,$(PRODUCT_DEX_PREOPT_RESOLVE_STARTUP_STRINGS)))
-  $(call add_json_bool, AlwaysSystemServerDebugInfo,        $(filter true,$(PRODUCT_SYSTEM_SERVER_DEBUG_INFO)))
-  $(call add_json_bool, NeverSystemServerDebugInfo,         $(filter false,$(PRODUCT_SYSTEM_SERVER_DEBUG_INFO)))
-  $(call add_json_bool, AlwaysOtherDebugInfo,               $(filter true,$(PRODUCT_OTHER_JAVA_DEBUG_INFO)))
-  $(call add_json_bool, NeverOtherDebugInfo,                $(filter false,$(PRODUCT_OTHER_JAVA_DEBUG_INFO)))
-  $(call add_json_bool, IsEng,                              $(filter eng,$(TARGET_BUILD_VARIANT)))
-  $(call add_json_bool, SanitizeLite,                       $(SANITIZE_LITE))
-  $(call add_json_bool, DefaultAppImages,                   $(WITH_DEX_PREOPT_APP_IMAGE))
-  $(call add_json_str,  Dex2oatXmx,                         $(DEX2OAT_XMX))
-  $(call add_json_str,  Dex2oatXms,                         $(DEX2OAT_XMS))
-  $(call add_json_str,  EmptyDirectory,                     $(OUT_DIR)/empty)
+  $(call add_json_bool, DisablePreopt,                           $(call invert_bool,$(ENABLE_PREOPT)))
+  $(call add_json_list, DisablePreoptModules,                    $(DEXPREOPT_DISABLED_MODULES))
+  $(call add_json_bool, OnlyPreoptBootImageAndSystemServer,      $(filter true,$(WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY)))
+  $(call add_json_bool, UseArtImage,                             $(filter true,$(DEXPREOPT_USE_ART_IMAGE)))
+  $(call add_json_bool, DontUncompressPrivAppsDex,               $(filter true,$(DONT_UNCOMPRESS_PRIV_APPS_DEXS)))
+  $(call add_json_list, ModulesLoadedByPrivilegedModules,        $(PRODUCT_LOADED_BY_PRIVILEGED_MODULES))
+  $(call add_json_bool, HasSystemOther,                          $(BOARD_USES_SYSTEM_OTHER_ODEX))
+  $(call add_json_list, PatternsOnSystemOther,                   $(SYSTEM_OTHER_ODEX_FILTER))
+  $(call add_json_bool, DisableGenerateProfile,                  $(filter false,$(WITH_DEX_PREOPT_GENERATE_PROFILE)))
+  $(call add_json_str,  ProfileDir,                              $(PRODUCT_DEX_PREOPT_PROFILE_DIR))
+  $(call add_json_list, BootJars,                                $(PRODUCT_BOOT_JARS))
+  $(call add_json_list, UpdatableBootJars,                       $(PRODUCT_UPDATABLE_BOOT_JARS))
+  $(call add_json_list, ArtApexJars,                             $(ART_APEX_JARS))
+  $(call add_json_list, SystemServerJars,                        $(PRODUCT_SYSTEM_SERVER_JARS))
+  $(call add_json_list, SystemServerApps,                        $(PRODUCT_SYSTEM_SERVER_APPS))
+  $(call add_json_list, UpdatableSystemServerJars,               $(PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS))
+  $(call add_json_bool, BrokenSuboptimalOrderOfSystemServerJars, $(PRODUCT_BROKEN_SUBOPTIMAL_ORDER_OF_SYSTEM_SERVER_JARS))
+  $(call add_json_list, SpeedApps,                               $(PRODUCT_DEXPREOPT_SPEED_APPS))
+  $(call add_json_list, PreoptFlags,                             $(PRODUCT_DEX_PREOPT_DEFAULT_FLAGS))
+  $(call add_json_str,  DefaultCompilerFilter,                   $(PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER))
+  $(call add_json_str,  SystemServerCompilerFilter,              $(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER))
+  $(call add_json_bool, GenerateDmFiles,                         $(PRODUCT_DEX_PREOPT_GENERATE_DM_FILES))
+  $(call add_json_bool, NeverAllowStripping,                     $(PRODUCT_DEX_PREOPT_NEVER_ALLOW_STRIPPING))
+  $(call add_json_bool, NoDebugInfo,                             $(filter false,$(WITH_DEXPREOPT_DEBUG_INFO)))
+  $(call add_json_bool, DontResolveStartupStrings,               $(filter false,$(PRODUCT_DEX_PREOPT_RESOLVE_STARTUP_STRINGS)))
+  $(call add_json_bool, AlwaysSystemServerDebugInfo,             $(filter true,$(PRODUCT_SYSTEM_SERVER_DEBUG_INFO)))
+  $(call add_json_bool, NeverSystemServerDebugInfo,              $(filter false,$(PRODUCT_SYSTEM_SERVER_DEBUG_INFO)))
+  $(call add_json_bool, AlwaysOtherDebugInfo,                    $(filter true,$(PRODUCT_OTHER_JAVA_DEBUG_INFO)))
+  $(call add_json_bool, NeverOtherDebugInfo,                     $(filter false,$(PRODUCT_OTHER_JAVA_DEBUG_INFO)))
+  $(call add_json_bool, IsEng,                                   $(filter eng,$(TARGET_BUILD_VARIANT)))
+  $(call add_json_bool, SanitizeLite,                            $(SANITIZE_LITE))
+  $(call add_json_bool, DefaultAppImages,                        $(WITH_DEX_PREOPT_APP_IMAGE))
+  $(call add_json_str,  Dex2oatXmx,                              $(DEX2OAT_XMX))
+  $(call add_json_str,  Dex2oatXms,                              $(DEX2OAT_XMS))
+  $(call add_json_str,  EmptyDirectory,                          $(OUT_DIR)/empty)
 
   $(call add_json_map,  CpuVariant)
   $(call add_json_str,  $(TARGET_ARCH), $(DEX2OAT_TARGET_CPU_VARIANT))
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index 2a2427d..440ffd9 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -234,7 +234,11 @@
   $(call add_json_list, UsesLibraries,                  $(LOCAL_USES_LIBRARIES))
   $(call add_json_map,  LibraryPaths)
   $(foreach lib,$(my_dexpreopt_libs),\
-    $(call add_json_str, $(lib), $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar))
+    $(call add_json_map, $(lib)) \
+    $(eval file := $(filter %/$(lib).jar, $(call module-installed-files,$(lib)))) \
+    $(call add_json_str, Host,   $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar) \
+    $(call add_json_str, Device, $(call install-path-to-on-device-path,$(file))) \
+    $(call end_json_map))
   $(call end_json_map)
   $(call add_json_list, Archs,                          $(my_dexpreopt_archs))
   $(call add_json_list, DexPreoptImages,                $(my_dexpreopt_images))
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 2a97acf..3aff007 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -94,10 +94,24 @@
 
 TARGET_BUILD_APPS ?=
 
+# Set to true for an unbundled build, i.e. a build without
+# support for platform targets like the system image. This also
+# disables consistency checks that only apply to full platform
+# builds.
+TARGET_BUILD_UNBUNDLED ?=
+
+# TARGET_BUILD_APPS implies unbundled build, otherwise we default
+# to bundled (i.e. platform targets such as the system image are
+# included).
+ifneq ($(TARGET_BUILD_APPS),)
+  TARGET_BUILD_UNBUNDLED := true
+endif
+
 .KATI_READONLY := \
   TARGET_PRODUCT \
   TARGET_BUILD_VARIANT \
-  TARGET_BUILD_APPS
+  TARGET_BUILD_APPS \
+  TARGET_BUILD_UNBUNDLED \
 
 # ---------------------------------------------------------------
 # Set up configuration for host machine.  We don't do cross-
@@ -853,7 +867,7 @@
   TARGET_INSTALLER_ROOT_OUT \
   TARGET_INSTALLER_SYSTEM_OUT
 
-COMMON_MODULE_CLASSES := TARGET-NOTICE_FILES HOST-NOTICE_FILES HOST-JAVA_LIBRARIES
+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 RLIB_LIBRARIES DYLIB_LIBRARIES
 .KATI_READONLY := COMMON_MODULE_CLASSES PER_ARCH_MODULE_CLASSES
 
diff --git a/core/executable.mk b/core/executable.mk
index db8dcc6..9175e0a 100644
--- a/core/executable.mk
+++ b/core/executable.mk
@@ -40,14 +40,9 @@
 LOCAL_NO_2ND_ARCH_MODULE_SUFFIX := true
 endif
 
-# if TARGET_PREFER_32_BIT_EXECUTABLES is set, try to build 32-bit first
 ifdef TARGET_2ND_ARCH
-ifeq ($(TARGET_PREFER_32_BIT_EXECUTABLES),true)
-LOCAL_2ND_ARCH_VAR_PREFIX := $(TARGET_2ND_ARCH_VAR_PREFIX)
-else
 LOCAL_2ND_ARCH_VAR_PREFIX :=
 endif
-endif
 
 my_skip_non_preferred_arch :=
 
@@ -65,12 +60,7 @@
 ifndef my_skip_non_preferred_arch
 ifdef TARGET_2ND_ARCH
 
-# check if the non-preferred arch is the primary or secondary
-ifeq ($(TARGET_PREFER_32_BIT_EXECUTABLES),true)
-LOCAL_2ND_ARCH_VAR_PREFIX :=
-else
 LOCAL_2ND_ARCH_VAR_PREFIX := $(TARGET_2ND_ARCH_VAR_PREFIX)
-endif
 
 # check if non-preferred arch is supported
 include $(BUILD_SYSTEM)/module_arch_supported.mk
diff --git a/core/executable_prefer_symlink.mk b/core/executable_prefer_symlink.mk
index ad6698d..fea0bef 100644
--- a/core/executable_prefer_symlink.mk
+++ b/core/executable_prefer_symlink.mk
@@ -5,22 +5,13 @@
 # Note: now only limited to the binaries that will be installed under system/bin directory
 
 # Create link to the one used depending on the target
-# configuration. Note that we require the TARGET_IS_64_BIT
-# check because 32 bit targets may not define TARGET_PREFER_32_BIT_APPS
-# et al. since those variables make no sense in that context.
+# configuration.
 ifneq ($(LOCAL_IS_HOST_MODULE),true)
   my_symlink := $(addprefix $(TARGET_OUT)/bin/, $(LOCAL_MODULE))
   my_src_binary_name :=
   ifeq ($(TARGET_IS_64_BIT),true)
     ifeq ($(TARGET_SUPPORTS_64_BIT_APPS)|$(TARGET_SUPPORTS_32_BIT_APPS),true|true)
-      # We support both 32 and 64 bit apps, so we will have to
-      # base our decision on whether the target prefers one or the
-      # other.
-      ifeq ($(TARGET_PREFER_32_BIT_APPS),true)
-        my_src_binary_name := $(LOCAL_MODULE_STEM_32)
-      else
-        my_src_binary_name := $(LOCAL_MODULE_STEM_64)
-      endif
+      my_src_binary_name := $(LOCAL_MODULE_STEM_64)
     else ifeq ($(TARGET_SUPPORTS_64_BIT_APPS),true)
       # We support only 64 bit apps.
       my_src_binary_name := $(LOCAL_MODULE_STEM_64)
diff --git a/core/link_type.mk b/core/link_type.mk
index ff525cb..48cd8f3 100644
--- a/core/link_type.mk
+++ b/core/link_type.mk
@@ -12,7 +12,7 @@
 
 my_link_prefix := LINK_TYPE:$(call find-idf-prefix,$(my_kind),$(my_host_cross)):$(if $(my_common),$(my_common):_,_:$(if $(my_2nd_arch_prefix),$(my_2nd_arch_prefix),_))
 link_type := $(my_link_prefix):$(LOCAL_MODULE_CLASS):$(LOCAL_MODULE)
-ALL_LINK_TYPES := $(ALL_LINK_TYPES) $(link_type)
+ALL_LINK_TYPES += $(link_type)
 $(link_type).TYPE := $(my_link_type)
 $(link_type).MAKEFILE := $(LOCAL_MODULE_MAKEFILE)
 $(link_type).WARN := $(my_warn_types)
diff --git a/core/main.mk b/core/main.mk
index fec88cd..76f915c 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -329,6 +329,8 @@
 endif
 endif
 
+ADDITIONAL_PRODUCT_PROPERTIES += ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS)
+
 # -----------------------------------------------------------------
 ###
 ### In this section we set up the things that are different
@@ -552,6 +554,13 @@
 endif
 
 # -------------------------------------------------------------------
+# Sort ALL_MODULES to remove duplicate entries.
+# -------------------------------------------------------------------
+ALL_MODULES := $(sort $(ALL_MODULES))
+# Cannot set to readonly because Makefile extends ALL_MODULES
+# .KATI_READONLY := ALL_MODULES
+
+# -------------------------------------------------------------------
 # Fix up CUSTOM_MODULES to refer to installed files rather than
 # just bare module names.  Leave unknown modules alone in case
 # they're actually full paths to a particular file.
@@ -573,7 +582,6 @@
 #
 # Resolve the required module name to 32-bit or 64-bit variant.
 
-# TODO(b/155869107): Replace get-32-bit-modules with get-modules-for-2nd-arch
 # Get a list of corresponding module names for the second arch, if they exist.
 # $(1): TARGET, HOST or HOST_CROSS
 # $(2): A list of module names
@@ -587,96 +595,85 @@
 )
 endef
 
-# Get a list of corresponding 32-bit module names, if one exists.
-define get-32-bit-modules
-$(sort $(foreach m,$(1),\
-  $(if $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).CLASS),\
-    $(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX))))
-endef
-# Get a list of corresponding 32-bit module names, if one exists;
-# otherwise return the original module name
-define get-32-bit-modules-if-we-can
-$(sort $(foreach m,$(1),\
-  $(if $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).CLASS),\
-    $(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX), \
-    $(m))))
-endef
-
-# TODO: we can probably check to see if these modules are actually host
-# modules
-define get-host-32-bit-modules
-$(sort $(foreach m,$(1),\
-  $(if $(ALL_MODULES.$(m)$(HOST_2ND_ARCH_MODULE_SUFFIX).CLASS),\
-    $(m)$(HOST_2ND_ARCH_MODULE_SUFFIX))))
-endef
-# Get a list of corresponding 32-bit module names, if one exists;
-# otherwise return the original module name
-define get-host-32-bit-modules-if-we-can
-$(sort $(foreach m,$(1),\
-  $(if $(ALL_MODULES.$(m)$(HOST_2ND_ARCH_MODULE_SUFFIX).CLASS),\
-    $(m)$(HOST_2ND_ARCH_MODULE_SUFFIX),\
-    $(m))))
-endef
-
-# If a module is for a cross host os, the required modules must be for
-# that OS too.
-# If a module is built for 32-bit, the required modules must be 32-bit too;
-# Otherwise if the module is an executable or shared library,
-#   the required modules must be 64-bit;
-#   otherwise we require both 64-bit and 32-bit variant, if one exists.
-define target-select-bitness-of-required-modules
-$(foreach m,$(ALL_MODULES),\
-  $(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_TARGET))\
-  $(if $(r),\
-    $(if $(ALL_MODULES.$(m).FOR_2ND_ARCH),\
-      $(eval r_r := $(call get-32-bit-modules-if-we-can,$(r))),\
-      $(if $(filter EXECUTABLES SHARED_LIBRARIES NATIVE_TESTS,$(ALL_MODULES.$(m).CLASS)),\
-        $(eval r_r := $(r)),\
-        $(eval r_r := $(r) $(call get-32-bit-modules,$(r)))\
-       )\
-     )\
-     $(eval ALL_MODULES.$(m).REQUIRED_FROM_TARGET := $(strip $(r_r)))\
-  )\
+# Resolves module bitness for PRODUCT_PACKAGES and PRODUCT_HOST_PACKAGES.
+# The returned list of module names can be used to access
+# ALL_MODULES.<module>.<*> variables.
+# Name resolution for PRODUCT_PACKAGES / PRODUCT_HOST_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 HOST_CROSS modules:
+#   foo:32 resolves to foo;
+#   foo:64 resolves to foo_64;
+#   foo resolves to both foo and foo_64 (if foo_64 is defined).
+#
+# $(1): TARGET, HOST or HOST_CROSS
+# $(2): A list of simple module names with :32 and :64 suffix
+define resolve-bitness-for-modules
+$(strip \
+  $(eval modules_32 := $(patsubst %:32,%,$(filter %:32,$(2)))) \
+  $(eval modules_64 := $(patsubst %:64,%,$(filter %:64,$(2)))) \
+  $(eval modules_both := $(filter-out %:32 %:64,$(2))) \
+  $(eval ### For host cross modules, the primary arch is windows x86 and secondary is x86_64) \
+  $(if $(filter HOST_CROSS,$(1)), \
+    $(eval modules_1st_arch := $(modules_32)) \
+    $(eval modules_2nd_arch := $(modules_64)), \
+    $(eval modules_1st_arch := $(modules_64)) \
+    $(eval modules_2nd_arch := $(modules_32))) \
+  $(eval ### Note for 32-bit product, 32 and 64 will be added as their original module names.) \
+  $(eval modules := $(modules_1st_arch)) \
+  $(if $($(1)_2ND_ARCH), \
+    $(eval modules += $(call get-modules-for-2nd-arch,$(1),$(modules_2nd_arch))), \
+    $(eval modules += $(modules_2nd_arch))) \
+  $(eval ### For the rest we add both) \
+  $(eval modules += $(modules_both)) \
+  $(if $($(1)_2ND_ARCH), \
+    $(eval modules += $(call get-modules-for-2nd-arch,$(1),$(modules_both)))) \
+  $(modules) \
 )
 endef
-$(call target-select-bitness-of-required-modules)
 
-define host-select-bitness-of-required-modules
-$(foreach m,$(ALL_MODULES),\
-  $(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_HOST))\
-  $(if $(r),\
-    $(if $(ALL_MODULES.$(m).FOR_2ND_ARCH),\
-      $(eval r_r := $(call get-host-32-bit-modules-if-we-can,$(r))),\
-      $(if $(filter EXECUTABLES SHARED_LIBRARIES NATIVE_TESTS,$(ALL_MODULES.$(m).CLASS)),\
-        $(eval r_r := $(r)),\
-        $(eval r_r := $(r) $(call get-host-32-bit-modules,$(r)))\
-       )\
-     )\
-     $(eval ALL_MODULES.$(m).REQUIRED_FROM_HOST := $(strip $(r_r)))\
-  )\
+# TODO(b/7456955): error if a required module doesn't exist.
+# Resolve the required module names in ALL_MODULES.*.REQUIRED_FROM_TARGET,
+# ALL_MODULES.*.REQUIRED_FROM_HOST and ALL_MODULES.*.REQUIRED_FROM_HOST_CROSS
+# to 32-bit or 64-bit variant.
+# If a module is for cross host OS, the required modules are also for that OS.
+# Required modules explicitly suffixed with :32 or :64 resolve to that bitness.
+# Otherwise if the requiring module is native and the required module is shared
+# library or native test, then the required module resolves to the same bitness.
+# Otherwise the required module resolves to both variants, if they exist.
+# $(1): TARGET, HOST or HOST_CROSS
+define select-bitness-of-required-modules
+$(foreach m,$(ALL_MODULES), \
+  $(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_$(1))) \
+  $(if $(r), \
+    $(if $(filter HOST_CROSS,$(1)), \
+      $(if $(ALL_MODULES.$(m).FOR_HOST_CROSS),,$(error Only expected REQUIRED_FROM_HOST_CROSS on FOR_HOST_CROSS modules - $(m))) \
+      $(eval r := $(addprefix host_cross_,$(r)))) \
+    $(eval module_is_native := \
+      $(filter EXECUTABLES SHARED_LIBRARIES NATIVE_TESTS,$(ALL_MODULES.$(m).CLASS))) \
+    $(eval r_r := $(foreach r_i,$(r), \
+      $(if $(filter %:32 %:64,$(r_i)), \
+        $(eval r_m := $(call resolve-bitness-for-modules,$(1),$(r_i))), \
+        $(eval r_m := \
+          $(eval r_i_2nd := $(call get-modules-for-2nd-arch,$(1),$(r_i))) \
+          $(eval required_is_shared_library_or_native_test := \
+            $(filter SHARED_LIBRARIES NATIVE_TESTS, \
+              $(ALL_MODULES.$(r_i).CLASS) $(ALL_MODULES.$(r_i_2nd).CLASS))) \
+          $(if $(and $(module_is_native),$(required_is_shared_library_or_native_test)), \
+            $(if $(ALL_MODULES.$(m).FOR_2ND_ARCH),$(r_i_2nd),$(r_i)), \
+            $(r_i) $(r_i_2nd)))) \
+      $(eval ### TODO(b/7456955): error if r_m is empty / does not exist) \
+      $(r_m))) \
+    $(eval ALL_MODULES.$(m).REQUIRED_FROM_$(1) := $(sort $(r_r))) \
+  ) \
 )
 endef
-$(call host-select-bitness-of-required-modules)
 
-define host-cross-select-bitness-of-required-modules
-$(foreach m,$(ALL_MODULES),\
-  $(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_HOST_CROSS))\
-  $(if $(r),\
-    $(if $(ALL_MODULES.$(m).FOR_HOST_CROSS),,$(error Only expected REQUIRED_FROM_HOST_CROSS on FOR_HOST_CROSS modules - $(m)))\
-    $(eval r := $(addprefix host_cross_,$(r)))\
-    $(if $(ALL_MODULES.$(m).FOR_2ND_ARCH),\
-      $(eval r_r := $(call get-host-32-bit-modules-if-we-can,$(r))),\
-      $(if $(filter EXECUTABLES SHARED_LIBRARIES NATIVE_TESTS,$(ALL_MODULES.$(m).CLASS)),\
-        $(eval r_r := $(r)),\
-        $(eval r_r := $(r) $(call get-host-32-bit-modules,$(r)))\
-       )\
-     )\
-     $(eval ALL_MODULES.$(m).REQUIRED_FROM_HOST_CROSS := $(strip $(r_r)))\
-  )\
-)
-endef
-$(call host-cross-select-bitness-of-required-modules)
-r_r :=
+$(call select-bitness-of-required-modules,TARGET)
+$(call select-bitness-of-required-modules,HOST)
+$(call select-bitness-of-required-modules,HOST_CROSS)
 
 define add-required-deps
 $(1): | $(2)
@@ -1126,45 +1123,6 @@
 
 endef
 
-# Resolves module bitness for PRODUCT_PACKAGES and PRODUCT_HOST_PACKAGES.
-# The returned list of module names can be used to access
-# ALL_MODULES.<module>.<*> variables.
-# Name resolution for PRODUCT_PACKAGES / PRODUCT_HOST_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 HOST_CROSS modules:
-#   foo:32 resolves to foo;
-#   foo:64 resolves to foo_64;
-#   foo resolves to both foo and foo_64 (if foo_64 is defined).
-#
-# $(1): TARGET, HOST or HOST_CROSS
-# $(2): A list of simple module names with :32 and :64 suffix
-define resolve-bitness-for-modules
-$(strip \
-  $(eval modules_32 := $(patsubst %:32,%,$(filter %:32,$(2)))) \
-  $(eval modules_64 := $(patsubst %:64,%,$(filter %:64,$(2)))) \
-  $(eval modules_both := $(filter-out %:32 %:64,$(2))) \
-  $(eval ### For host cross modules, the primary arch is windows x86 and secondary is x86_64) \
-  $(if $(filter HOST_CROSS,$(1)), \
-    $(eval modules_1st_arch := $(modules_32)) \
-    $(eval modules_2nd_arch := $(modules_64)), \
-    $(eval modules_1st_arch := $(modules_64)) \
-    $(eval modules_2nd_arch := $(modules_32))) \
-  $(eval ### Note for 32-bit product, 32 and 64 will be added as their original module names.) \
-  $(eval modules := $(modules_1st_arch)) \
-  $(if $($(1)_2ND_ARCH), \
-    $(eval modules += $(call get-modules-for-2nd-arch,$(1),$(modules_2nd_arch))), \
-    $(eval modules += $(modules_2nd_arch))) \
-  $(eval ### For the rest we add both) \
-  $(eval modules += $(modules_both)) \
-  $(if $($(1)_2ND_ARCH), \
-    $(eval modules += $(call get-modules-for-2nd-arch,$(1),$(modules_both)))) \
-  $(modules) \
-)
-endef
-
 # Lists most of the files a particular product installs, including:
 # - PRODUCT_PACKAGES, and their LOCAL_REQUIRED_MODULES
 # - PRODUCT_COPY_FILES
@@ -1177,8 +1135,7 @@
 #   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.
+#   See the select-bitness-of-required-modules definition.
 # $(1): product makefile
 define product-installed-files
   $(eval _pif_modules := \
@@ -1264,8 +1221,8 @@
     endif
   endif
 
-  # Some modules produce only host installed files when building with TARGET_BUILD_APPS
-  ifeq ($(TARGET_BUILD_APPS),)
+  # Modules may produce only host installed files in unbundled builds.
+  ifeq (,$(TARGET_BUILD_UNBUNDLED))
     _modules := $(call resolve-bitness-for-modules,TARGET, \
       $(PRODUCT_PACKAGES) \
       $(PRODUCT_PACKAGES_DEBUG) \
@@ -1654,7 +1611,7 @@
     $(apps_only_installed_files)))
 
 
-else # TARGET_BUILD_APPS
+else ifeq (,$(TARGET_BUILD_UNBUNDLED))
   $(call dist-for-goals, droidcore, \
     $(INTERNAL_UPDATE_PACKAGE_TARGET) \
     $(INTERNAL_OTA_PACKAGE_TARGET) \
@@ -1748,10 +1705,15 @@
   $(call dist-for-goals, dist_files, $(api_xmls))
   api_xmls :=
 
+  ifdef CLANG_COVERAGE
+    $(foreach f,$(SOONG_NDK_API_XML), \
+        $(call dist-for-goals,droidcore,$(f):ndk_coverage_xml_dir/$(notdir $(f))))
+  endif
+
 # Building a full system-- the default is to build droidcore
 droid_targets: droidcore dist_files
 
-endif # TARGET_BUILD_APPS
+endif # !TARGET_BUILD_UNBUNDLED
 
 .PHONY: docs
 docs: $(ALL_DOCS)
diff --git a/core/package.mk b/core/package.mk
index 6bde485..591f7aa 100644
--- a/core/package.mk
+++ b/core/package.mk
@@ -41,15 +41,7 @@
 endif
 
 LOCAL_NO_2ND_ARCH_MODULE_SUFFIX := true
-
-# if TARGET_PREFER_32_BIT_APPS is set, try to build 32-bit first
-ifdef TARGET_2ND_ARCH
-ifeq ($(TARGET_PREFER_32_BIT_APPS),true)
-LOCAL_2ND_ARCH_VAR_PREFIX := $(TARGET_2ND_ARCH_VAR_PREFIX)
-else
 LOCAL_2ND_ARCH_VAR_PREFIX :=
-endif
-endif
 
 # check if preferred arch is supported
 include $(BUILD_SYSTEM)/module_arch_supported.mk
@@ -57,13 +49,7 @@
 # first arch is supported
 include $(BUILD_SYSTEM)/package_internal.mk
 else ifneq (,$(TARGET_2ND_ARCH))
-# check if the non-preferred arch is the primary or secondary
-ifeq ($(TARGET_PREFER_32_BIT_APPS),true)
-LOCAL_2ND_ARCH_VAR_PREFIX :=
-else
 LOCAL_2ND_ARCH_VAR_PREFIX := $(TARGET_2ND_ARCH_VAR_PREFIX)
-endif
-
 # check if non-preferred arch is supported
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
diff --git a/core/product.mk b/core/product.mk
index 9c54849..94466fa 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -239,6 +239,8 @@
 _product_list_vars += PRODUCT_SYSTEM_SERVER_JARS
 # List of system_server jars delivered via apex. Format = <apex name>:<jar name>.
 _product_list_vars += PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS
+# If true, then suboptimal order of system server jars does not cause an error.
+_product_list_vars += PRODUCT_BROKEN_SUBOPTIMAL_ORDER_OF_SYSTEM_SERVER_JARS
 
 # Additional system server jars to be appended at the end of the common list.
 # This is necessary to avoid jars reordering due to makefile inheritance order.
diff --git a/core/shell_test_config_template.xml b/core/shell_test_config_template.xml
new file mode 100644
index 0000000..5e1c8ee
--- /dev/null
+++ b/core/shell_test_config_template.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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="Config for running {MODULE} through Atest or in Infra">
+    <option name="test-suite-tag" value="{MODULE}" />
+
+    {EXTRA_CONFIGS}
+
+    <!-- This test requires a device, so it's not annotated with a null-device. -->
+    <test class="com.android.tradefed.testtype.binary.ExecutableHostTest" >
+        <option name="binary" value="{OUTPUT_FILENAME}" />
+        <!-- Test script assumes a relative path with the tests/ folders. -->
+        <option name="relative-path-execution" value="true" />
+        <!-- Tests shouldn't be that long but set 15m to be safe. -->
+        <option name="per-binary-timeout" value="15m" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/core/soong_android_app_set.mk b/core/soong_android_app_set.mk
index 4c27e53..5ed9b2c 100644
--- a/core/soong_android_app_set.mk
+++ b/core/soong_android_app_set.mk
@@ -31,4 +31,4 @@
 $(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
 PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
 
-SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
+SOONG_ALREADY_CONV += $(LOCAL_MODULE)
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index 09c79f6..3549c1d 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -218,4 +218,4 @@
   $(LOCAL_INSTALLED_MODULE): $(my_coverage_files)
 endif
 
-SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
+SOONG_ALREADY_CONV += $(LOCAL_MODULE)
diff --git a/core/soong_cc_prebuilt.mk b/core/soong_cc_prebuilt.mk
index 6317b53..986609b 100644
--- a/core/soong_cc_prebuilt.mk
+++ b/core/soong_cc_prebuilt.mk
@@ -51,7 +51,7 @@
 
 ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES HEADER_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
   # Soong module is a static or shared library
-  EXPORTS_LIST := $(EXPORTS_LIST) $(intermediates)
+  EXPORTS_LIST += $(intermediates)
   EXPORTS.$(intermediates).FLAGS := $(LOCAL_EXPORT_CFLAGS)
   EXPORTS.$(intermediates).DEPS := $(LOCAL_EXPORT_C_INCLUDE_DEPS)
 
@@ -61,7 +61,7 @@
     $(my_all_targets): $(LOCAL_BUILT_MODULE).toc
   endif
 
-  SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
+  SOONG_ALREADY_CONV += $(LOCAL_MODULE)
 
   my_link_type := $(LOCAL_SOONG_LINK_TYPE)
   my_warn_types :=
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 18949be..53c7b0d 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -39,7 +39,7 @@
 $(call add_json_str,  Platform_min_supported_target_sdk_version, $(PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION))
 
 $(call add_json_bool, Allow_missing_dependencies,        $(ALLOW_MISSING_DEPENDENCIES))
-$(call add_json_bool, Unbundled_build,                   $(TARGET_BUILD_APPS))
+$(call add_json_bool, Unbundled_build,                   $(TARGET_BUILD_UNBUNDLED))
 $(call add_json_bool, Unbundled_build_sdks_from_source,  $(UNBUNDLED_BUILD_SDKS_FROM_SOURCE))
 $(call add_json_bool, Pdk,                               $(filter true,$(TARGET_BUILD_PDK)))
 
@@ -122,8 +122,6 @@
 $(call add_json_bool, Binder32bit,                       $(BINDER32BIT))
 $(call add_json_str,  BtConfigIncludeDir,                $(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR))
 $(call add_json_list, DeviceKernelHeaders,               $(TARGET_DEVICE_KERNEL_HEADERS) $(TARGET_BOARD_KERNEL_HEADERS) $(TARGET_PRODUCT_KERNEL_HEADERS))
-$(call add_json_bool, DevicePrefer32BitApps,             $(filter true,$(TARGET_PREFER_32_BIT_APPS)))
-$(call add_json_bool, DevicePrefer32BitExecutables,      $(filter true,$(TARGET_PREFER_32_BIT_EXECUTABLES)))
 $(call add_json_str,  DeviceVndkVersion,                 $(BOARD_VNDK_VERSION))
 $(call add_json_str,  Platform_vndk_version,             $(PLATFORM_VNDK_VERSION))
 $(call add_json_str,  ProductVndkVersion,                $(PRODUCT_PRODUCT_VNDK_VERSION))
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index b15e7f6..e4c84e0 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -173,4 +173,4 @@
 		$(hide) echo $(PRIVATE_EXPORTED_SDK_LIBS) | tr ' ' '\n' > $@,\
 		$(hide) touch $@)
 
-SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
+SOONG_ALREADY_CONV += $(LOCAL_MODULE)
diff --git a/core/sysprop.mk b/core/sysprop.mk
index ad3e8c9..14fa828 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -24,62 +24,92 @@
 endif
 
 BUILDINFO_SH := build/make/tools/buildinfo.sh
-BUILDINFO_COMMON_SH := build/make/tools/buildinfo_common.sh
 POST_PROCESS_PROPS := $(HOST_OUT_EXECUTABLES)/post_process_props$(HOST_EXECUTABLE_SUFFIX)
 
-# Generates a set of sysprops common to all partitions to a file.
+# Emits a set of sysprops common to all partitions to a file.
 # $(1): Partition name
 # $(2): Output file name
 define generate-common-build-props
-	PRODUCT_BRAND="$(PRODUCT_BRAND)" \
-	PRODUCT_DEVICE="$(TARGET_DEVICE)" \
-	PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
-	PRODUCT_MODEL="$(PRODUCT_MODEL)" \
-	PRODUCT_NAME="$(TARGET_PRODUCT)" \
-	$(call generate-common-build-props-with-product-vars-set,$(1),$(2))
+    echo "####################################" >> $(2);\
+    echo "# from generate-common-build-props" >> $(2);\
+    echo "# These properties identify this partition image." >> $(2);\
+    echo "####################################" >> $(2);\
+    $(if $(filter system,$(1)),\
+        echo "ro.product.$(1).brand=$(PRODUCT_SYSTEM_BRAND)" >> $(2);\
+        echo "ro.product.$(1).device=$(PRODUCT_SYSTEM_DEVICE)" >> $(2);\
+        echo "ro.product.$(1).manufacturer=$(PRODUCT_SYSTEM_MANUFACTURER)" >> $(2);\
+        echo "ro.product.$(1).model=$(PRODUCT_SYSTEM_MODEL)" >> $(2);\
+        echo "ro.product.$(1).name=$(PRODUCT_SYSTEM_NAME)" >> $(2);\
+      ,\
+        echo "ro.product.$(1).brand=$(PRODUCT_BRAND)" >> $(2);\
+        echo "ro.product.$(1).device=$(TARGET_DEVICE)" >> $(2);\
+        echo "ro.product.$(1).manufacturer=$(PRODUCT_MANUFACTURER)" >> $(2);\
+        echo "ro.product.$(1).model=$(PRODUCT_MODEL)" >> $(2);\
+        echo "ro.product.$(1).name=$(TARGET_PRODUCT)" >> $(2);\
+    )\
+    echo "ro.$(1).build.date=`$(DATE_FROM_FILE)`" >> $(2);\
+    echo "ro.$(1).build.date.utc=`$(DATE_FROM_FILE) +%s`" >> $(2);\
+    echo "ro.$(1).build.fingerprint=$(BUILD_FINGERPRINT_FROM_FILE)" >> $(2);\
+    echo "ro.$(1).build.id=$(BUILD_ID)" >> $(2);\
+    echo "ro.$(1).build.tags=$(BUILD_VERSION_TAGS)" >> $(2);\
+    echo "ro.$(1).build.type=$(TARGET_BUILD_VARIANT)" >> $(2);\
+    echo "ro.$(1).build.version.incremental=$(BUILD_NUMBER_FROM_FILE)" >> $(2);\
+    echo "ro.$(1).build.version.release=$(PLATFORM_VERSION)" >> $(2);\
+    echo "ro.$(1).build.version.sdk=$(PLATFORM_SDK_VERSION)" >> $(2);\
+
 endef
 
-# Like the above macro, but requiring the relevant PRODUCT_ environment
-# variables to be set when called.
-define generate-common-build-props-with-product-vars-set
-	BUILD_FINGERPRINT="$(BUILD_FINGERPRINT_FROM_FILE)" \
-	BUILD_ID="$(BUILD_ID)" \
-	BUILD_NUMBER="$(BUILD_NUMBER_FROM_FILE)" \
-	BUILD_VERSION_TAGS="$(BUILD_VERSION_TAGS)" \
-	DATE="$(DATE_FROM_FILE)" \
-	PLATFORM_SDK_VERSION="$(PLATFORM_SDK_VERSION)" \
-	PLATFORM_VERSION_LAST_STABLE="$(PLATFORM_VERSION_LAST_STABLE)" \
-	PLATFORM_VERSION="$(PLATFORM_VERSION)" \
-	TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
-	bash $(BUILDINFO_COMMON_SH) "$(1)" >> $(2)
+# Rule for generating <partition>/build.prop file
+#
+# $(1): partition name
+# $(2): path to the output
+# $(3): path to the input *.prop files. The contents of the files are directly
+#       emitted to the output
+# $(4): list of variable names each of which contains name=value pairs
+# $(5): optional list of prop names to force remove from the output. Properties from both
+#       $(3) and (4) are affected.
+define build-properties
+ALL_DEFAULT_INSTALLED_MODULES += $(2)
+
+# TODO(b/117892318): eliminate the call to uniq-pairs-by-first-component when
+# it is guaranteed that there is no dup.
+$(foreach name,$(strip $(4)),\
+    $(eval _resolved_$(name) := $$(call collapse-pairs, $$(call uniq-pairs-by-first-component,$$($(name)),=)))\
+)
+
+$(2): $(POST_PROCESS_PROPS) $(INTERNAL_BUILD_ID_MAKEFILE) $(API_FINGERPRINT) $(3)
+	$(hide) echo Building $$@
+	$(hide) mkdir -p $$(dir $$@)
+	$(hide) rm -f $$@ && touch $$@
+	$(hide) $$(call generate-common-build-props,$(call to-lower,$(strip $(1))),$$@)
+	$(hide) $(foreach file,$(strip $(3)),\
+	    if [ -f "$(file)" ]; then\
+	        echo "" >> $$@;\
+	        echo "####################################" >> $$@;\
+	        echo "# from $(file)" >> $$@;\
+	        echo "####################################" >> $$@;\
+	        cat $(file) >> $$@;\
+	    fi;)
+	$(hide) $(foreach name,$(strip $(4)),\
+	    echo "" >> $$@;\
+	    echo "####################################" >> $$@;\
+	    echo "# from variable $(name)" >> $$@;\
+	    echo "####################################" >> $$@;\
+	    $$(foreach line,$$(_resolved_$(name)),\
+	        echo "$$(line)" >> $$@;\
+	    )\
+	)
+	$(hide) $(POST_PROCESS_PROPS) $$@ $(5)
+	$(hide) echo "# end of file" >> $$@
 endef
 
 # -----------------------------------------------------------------
-# build.prop
-intermediate_system_build_prop := $(call intermediates-dir-for,ETC,system_build_prop)/build.prop
-INSTALLED_BUILD_PROP_TARGET := $(TARGET_OUT)/build.prop
-ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_BUILD_PROP_TARGET)
-
-# TODO(b/117892318) merge DEFAULT into BUILD
-FINAL_DEFAULT_PROPERTIES := \
-    $(call collapse-pairs, $(PRODUCT_SYSTEM_DEFAULT_PROPERTIES))
-FINAL_DEFAULT_PROPERTIES := $(call uniq-pairs-by-first-component, \
-    $(FINAL_DEFAULT_PROPERTIES),=)
-
-FINAL_BUILD_PROPERTIES := \
-    $(call collapse-pairs, $(ADDITIONAL_SYSTEM_PROPERTIES))
-
-# For non-Treble devices, consider vendor properties as system properties
-ifndef property_overrides_split_enabled
-FINAL_BUILD_PROPERTIES += \
-    $(call collapse-pairs, $(ADDITIONAL_VENDOR_PROPERTIES))
-endif
-
-FINAL_BUILD_PROPERTIES := $(call uniq-pairs-by-first-component, \
-    $(FINAL_BUILD_PROPERTIES),=)
-
-# A list of arbitrary tags describing the build configuration.
-# Force ":=" so we can use +=
+# Define fingerprint, thumbprint, and version tags for the current build
+#
+# BUILD_VERSION_TAGS is a comma-separated list of tags chosen by the device
+# implementer that further distinguishes the build. It's basically defined
+# by the device implementer. Here, we are adding a mandatory tag that
+# identifies the signing config of the build.
 BUILD_VERSION_TAGS := $(BUILD_VERSION_TAGS)
 ifeq ($(TARGET_BUILD_TYPE),debug)
   BUILD_VERSION_TAGS += debug
@@ -97,11 +127,8 @@
 BUILD_VERSION_TAGS += $(BUILD_KEYS)
 BUILD_VERSION_TAGS := $(subst $(space),$(comma),$(sort $(BUILD_VERSION_TAGS)))
 
-# A human-readable string that descibes this build in detail.
-build_desc := $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT) $(PLATFORM_VERSION) $(BUILD_ID) $(BUILD_NUMBER_FROM_FILE) $(BUILD_VERSION_TAGS)
-$(intermediate_system_build_prop): PRIVATE_BUILD_DESC := $(build_desc)
-
-# The string used to uniquely identify the combined build and product; used by the OTA server.
+# BUILD_FINGERPRINT is used used to uniquely identify the combined build and
+# product; used by the OTA server.
 ifeq (,$(strip $(BUILD_FINGERPRINT)))
   ifeq ($(strip $(HAS_BUILD_NUMBER)),false)
     BF_BUILD_NUMBER := $(BUILD_USERNAME)$$($(DATE_FROM_FILE) +%m%d%H%M)
@@ -121,8 +148,8 @@
 # unset it for safety.
 BUILD_FINGERPRINT :=
 
-# The string used to uniquely identify the system build; used by the OTA server.
-# This purposefully excludes any product-specific variables.
+# BUILD_THUMBPRINT is used to uniquely identify the system build; used by the
+# OTA server. This purposefully excludes any product-specific variables.
 ifeq (,$(strip $(BUILD_THUMBPRINT)))
   BUILD_THUMBPRINT := $(PLATFORM_VERSION)/$(BUILD_ID)/$(BUILD_NUMBER_FROM_FILE):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)
 endif
@@ -135,14 +162,14 @@
 # unset it for safety.
 BUILD_THUMBPRINT :=
 
-KNOWN_OEM_THUMBPRINT_PROPERTIES := \
-    ro.product.brand \
-    ro.product.name \
-    ro.product.device
-OEM_THUMBPRINT_PROPERTIES := $(filter $(KNOWN_OEM_THUMBPRINT_PROPERTIES),\
-    $(PRODUCT_OEM_PROPERTIES))
+# -----------------------------------------------------------------
+# Define human readable strings that describe this build
+#
 
-# Display parameters shown under Settings -> About Phone
+# BUILD_ID: detail info; has the same info as the build fingerprint
+BUILD_DESC := $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT) $(PLATFORM_VERSION) $(BUILD_ID) $(BUILD_NUMBER_FROM_FILE) $(BUILD_VERSION_TAGS)
+
+# BUILD_DISPLAY_ID is shown under Settings -> About Phone
 ifeq ($(TARGET_BUILD_VARIANT),user)
   # User builds should show:
   # release build number or branch.buld_number non-release builds
@@ -155,17 +182,9 @@
   endif
 else
   # Non-user builds should show detailed build information
-  BUILD_DISPLAY_ID := $(build_desc)
+  BUILD_DISPLAY_ID := $(BUILD_DESC)
 endif
 
-# Accepts a whitespace separated list of product locales such as
-# (en_US en_AU en_GB...) and returns the first locale in the list with
-# underscores replaced with hyphens. In the example above, this will
-# return "en-US".
-define get-default-product-locale
-$(strip $(subst _,-, $(firstword $(1))))
-endef
-
 # TARGET_BUILD_FLAVOR and ro.build.flavor are used only by the test
 # harness to distinguish builds. Only add _asan for a sanitized build
 # if it isn't already a part of the flavor (via a dedicated lunch
@@ -177,36 +196,36 @@
 endif
 endif
 
-ifdef TARGET_SYSTEM_PROP
-system_prop_file := $(TARGET_SYSTEM_PROP)
-else
-system_prop_file := $(wildcard $(TARGET_DEVICE_DIR)/system.prop)
-endif
-$(intermediate_system_build_prop): $(BUILDINFO_SH) $(BUILDINFO_COMMON_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(API_FINGERPRINT) $(POST_PROCESS_PROPS)
-	@echo Target buildinfo: $@
-	@mkdir -p $(dir $@)
-	$(hide) rm -f $@ && touch $@
-	$(hide) $(foreach line,$(FINAL_DEFAULT_PROPERTIES), \
-	    echo "$(line)" >> $@;)
-ifneq ($(PRODUCT_OEM_PROPERTIES),)
-	$(hide) echo "#" >> $@; \
-	        echo "# PRODUCT_OEM_PROPERTIES" >> $@; \
-	        echo "#" >> $@;
-	$(hide) $(foreach prop,$(PRODUCT_OEM_PROPERTIES), \
-	    echo "import /oem/oem.prop $(prop)" >> $@;)
-endif
-	$(hide) PRODUCT_BRAND="$(PRODUCT_SYSTEM_BRAND)" \
-	        PRODUCT_MANUFACTURER="$(PRODUCT_SYSTEM_MANUFACTURER)" \
-	        PRODUCT_MODEL="$(PRODUCT_SYSTEM_MODEL)" \
-	        PRODUCT_NAME="$(PRODUCT_SYSTEM_NAME)" \
-	        PRODUCT_DEVICE="$(PRODUCT_SYSTEM_DEVICE)" \
-	        $(call generate-common-build-props-with-product-vars-set,system,$@)
+KNOWN_OEM_THUMBPRINT_PROPERTIES := \
+    ro.product.brand \
+    ro.product.name \
+    ro.product.device
+OEM_THUMBPRINT_PROPERTIES := $(filter $(KNOWN_OEM_THUMBPRINT_PROPERTIES),\
+    $(PRODUCT_OEM_PROPERTIES))
+KNOWN_OEM_THUMBPRINT_PROPERTIES:=
+
+# -----------------------------------------------------------------
+# system/build.prop
+#
+# Note: parts of this file that can't be generated by the build-properties
+# macro are manually created as separate files and then fed into the macro
+
+# Accepts a whitespace separated list of product locales such as
+# (en_US en_AU en_GB...) and returns the first locale in the list with
+# underscores replaced with hyphens. In the example above, this will
+# return "en-US".
+define get-default-product-locale
+$(strip $(subst _,-, $(firstword $(1))))
+endef
+
+gen_from_buildinfo_sh := $(call intermediates-dir-for,ETC,system_build_prop)/buildinfo.prop
+$(gen_from_buildinfo_sh): $(INTERNAL_BUILD_ID_MAKEFILE) $(API_FINGERPRINT)
 	$(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
 	        TARGET_BUILD_FLAVOR="$(TARGET_BUILD_FLAVOR)" \
 	        TARGET_DEVICE="$(TARGET_DEVICE)" \
 	        PRODUCT_DEFAULT_LOCALE="$(call get-default-product-locale,$(PRODUCT_LOCALES))" \
 	        PRODUCT_DEFAULT_WIFI_CHANNELS="$(PRODUCT_DEFAULT_WIFI_CHANNELS)" \
-	        PRIVATE_BUILD_DESC="$(PRIVATE_BUILD_DESC)" \
+	        PRIVATE_BUILD_DESC="$(BUILD_DESC)" \
 	        BUILD_ID="$(BUILD_ID)" \
 	        BUILD_DISPLAY_ID="$(BUILD_DISPLAY_ID)" \
 	        DATE="$(DATE_FROM_FILE)" \
@@ -231,194 +250,143 @@
 	        TARGET_CPU_ABI_LIST_64_BIT="$(TARGET_CPU_ABI_LIST_64_BIT)" \
 	        TARGET_CPU_ABI="$(TARGET_CPU_ABI)" \
 	        TARGET_CPU_ABI2="$(TARGET_CPU_ABI2)" \
-	        bash $(BUILDINFO_SH) >> $@
-	$(hide) $(foreach file,$(system_prop_file), \
-	    if [ -f "$(file)" ]; then \
-	        echo Target buildinfo from: "$(file)"; \
-	        echo "" >> $@; \
-	        echo "#" >> $@; \
-	        echo "# from $(file)" >> $@; \
-	        echo "#" >> $@; \
-	        cat $(file) >> $@; \
-	        echo "# end of $(file)" >> $@; \
-	    fi;)
-	$(if $(FINAL_BUILD_PROPERTIES), \
-	    $(hide) echo >> $@; \
-	            echo "#" >> $@; \
-	            echo "# ADDITIONAL_SYSTEM_PROPERTIES" >> $@; \
-	            echo "#" >> $@; )
-	$(hide) $(foreach line,$(FINAL_BUILD_PROPERTIES), \
-	    echo "$(line)" >> $@;)
-	$(hide) $(POST_PROCESS_PROPS) $@ $(PRODUCT_SYSTEM_PROPERTY_BLACKLIST)
+	        bash $(BUILDINFO_SH) > $@
 
-build_desc :=
+ifneq ($(PRODUCT_OEM_PROPERTIES),)
+import_oem_prop := $(call intermediates-dir-for,ETC,system_build_prop)/oem.prop
 
-$(INSTALLED_BUILD_PROP_TARGET): $(intermediate_system_build_prop)
-	@echo "Target build info: $@"
-	$(hide) grep -v 'ro.product.first_api_level' $(intermediate_system_build_prop) > $@
+$(import_oem_prop):
+	$(hide) echo "#" >> $@; \
+	        echo "# PRODUCT_OEM_PROPERTIES" >> $@; \
+	        echo "#" >> $@;
+	$(hide) $(foreach prop,$(PRODUCT_OEM_PROPERTIES), \
+	    echo "import /oem/oem.prop $(prop)" >> $@;)
+else
+import_oem_prop :=
+endif
+
+ifdef TARGET_SYSTEM_PROP
+system_prop_file := $(TARGET_SYSTEM_PROP)
+else
+system_prop_file := $(wildcard $(TARGET_DEVICE_DIR)/system.prop)
+endif
+
+_prop_files_ := \
+  $(import_oem_prop) \
+  $(gen_from_buildinfo_sh) \
+  $(system_prop_file)
+
+# Order matters here. When there are duplicates, the last one wins.
+# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
+_prop_vars_ := \
+    ADDITIONAL_SYSTEM_PROPERTIES \
+    PRODUCT_SYSTEM_DEFAULT_PROPERTIES
+
+ifndef property_overrides_split_enabled
+_prop_vars_ += \
+    ADDITIONAL_VENDOR_PROPERTIES
+endif
+
+_blacklist_names_ := \
+    $(PRODUCT_SYSTEM_PROPERTY_BLACKLIST) \
+    ro.product.first_api_level
+
+INSTALLED_BUILD_PROP_TARGET := $(TARGET_OUT)/build.prop
+
+$(eval $(call build-properties,system,$(INSTALLED_BUILD_PROP_TARGET),\
+$(_prop_files_),$(_prop_vars_),\
+$(_blacklist_names_)))
+
 
 # -----------------------------------------------------------------
-# vendor build.prop
+# vendor/build.prop
 #
-# For verifying that the vendor build is what we think it is
-INSTALLED_VENDOR_BUILD_PROP_TARGET := $(TARGET_OUT_VENDOR)/build.prop
-ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_VENDOR_BUILD_PROP_TARGET)
-
-ifdef TARGET_VENDOR_PROP
-vendor_prop_files := $(TARGET_VENDOR_PROP)
-else
-vendor_prop_files := $(wildcard $(TARGET_DEVICE_DIR)/vendor.prop)
-endif
+_prop_files_ := $(if $(TARGET_VENDOR_PROP),\
+    $(TARGET_VENDOR_PROP),\
+    $(wildcard $(TARGET_DEVICE_DIR)/vendor.prop))
 
 android_info_prop := $(call intermediates-dir-for,ETC,android_info_prop)/android_info.prop
 $(android_info_prop): $(INSTALLED_ANDROID_INFO_TXT_TARGET)
 	cat $< | grep 'require version-' | sed -e 's/require version-/ro.build.expect./g' > $@
 
-vendor_prop_files += $(android_info_prop)
+_prop_files_ += $(android_info_pro)
 
 ifdef property_overrides_split_enabled
-FINAL_VENDOR_BUILD_PROPERTIES += \
-    $(call collapse-pairs, $(PRODUCT_PROPERTY_OVERRIDES) $(ADDITIONAL_VENDOR_PROPERTIES))
-FINAL_VENDOR_BUILD_PROPERTIES := $(call uniq-pairs-by-first-component, \
-    $(FINAL_VENDOR_BUILD_PROPERTIES),=)
-endif  # property_overrides_split_enabled
-
-$(INSTALLED_VENDOR_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) $(vendor_prop_files)
-	@echo Target vendor buildinfo: $@
-	@mkdir -p $(dir $@)
-	$(hide) rm -f $@ && touch $@
-	$(hide) $(call generate-common-build-props,vendor,$@)
-	$(hide) echo "#" >> $@; \
-	        echo "# ADDITIONAL VENDOR BUILD PROPERTIES" >> $@; \
-	        echo "#" >> $@;
-ifdef property_overrides_split_enabled
-	$(hide) $(foreach file,$(vendor_prop_files), \
-	    if [ -f "$(file)" ]; then \
-	        echo Target vendor properties from: "$(file)"; \
-	        echo "" >> $@; \
-	        echo "#" >> $@; \
-	        echo "# from $(file)" >> $@; \
-	        echo "#" >> $@; \
-	        cat $(file) >> $@; \
-	        echo "# end of $(file)" >> $@; \
-	    fi;)
-	$(hide) $(foreach line,$(FINAL_VENDOR_BUILD_PROPERTIES), \
-	    echo "$(line)" >> $@;)
-endif  # property_overrides_split_enabled
-	$(hide) $(POST_PROCESS_PROPS) $@ $(PRODUCT_VENDOR_PROPERTY_BLACKLIST)
-
-
-# -----------------------------------------------------------------
-# product build.prop
-INSTALLED_PRODUCT_BUILD_PROP_TARGET := $(TARGET_OUT_PRODUCT)/build.prop
-ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_PRODUCT_BUILD_PROP_TARGET)
-
-ifdef TARGET_PRODUCT_PROP
-product_prop_files := $(TARGET_PRODUCT_PROP)
+# Order matters here. When there are duplicates, the last one wins.
+# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
+_prop_vars_ := \
+    ADDITIONAL_VENDOR_PROPERTIES \
+    PRODUCT_PROPERTY_OVERRIDES
 else
-product_prop_files := $(wildcard $(TARGET_DEVICE_DIR)/product.prop)
+_prop_vars_ :=
 endif
 
-FINAL_PRODUCT_PROPERTIES += \
-    $(call collapse-pairs, $(PRODUCT_PRODUCT_PROPERTIES) $(ADDITIONAL_PRODUCT_PROPERTIES))
-FINAL_PRODUCT_PROPERTIES := $(call uniq-pairs-by-first-component, \
-    $(FINAL_PRODUCT_PROPERTIES),=)
+INSTALLED_VENDOR_BUILD_PROP_TARGET := $(TARGET_OUT_VENDOR)/build.prop
+$(eval $(call build-properties,\
+    vendor,\
+    $(INSTALLED_VENDOR_BUILD_PROP_TARGET),\
+    $(_prop_files_),\
+    $(_prop_vars_),\
+    $(PRODUCT_VENDOR_PROPERTY_BLACKLIST)))
 
-$(INSTALLED_PRODUCT_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) $(product_prop_files)
-	@echo Target product buildinfo: $@
-	@mkdir -p $(dir $@)
-	$(hide) rm -f $@ && touch $@
-	$(hide) $(call generate-common-build-props,product,$@)
-	$(hide) $(foreach file,$(product_prop_files), \
-	    if [ -f "$(file)" ]; then \
-	        echo Target product properties from: "$(file)"; \
-	        echo "" >> $@; \
-	        echo "#" >> $@; \
-	        echo "# from $(file)" >> $@; \
-	        echo "#" >> $@; \
-	        cat $(file) >> $@; \
-	        echo "# end of $(file)" >> $@; \
-	    fi;)
-	$(hide) echo "#" >> $@; \
-	        echo "# ADDITIONAL PRODUCT PROPERTIES" >> $@; \
-	        echo "#" >> $@; \
-	        echo "ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS)" >> $@;
-	$(hide) $(foreach line,$(FINAL_PRODUCT_PROPERTIES), \
-	    echo "$(line)" >> $@;)
-	$(hide) $(POST_PROCESS_PROPS) $@
+# -----------------------------------------------------------------
+# product/build.prop
+#
+
+_prop_files_ := $(if $(TARGET_PRODUCT_PROP),\
+    $(TARGET_PRODUCT_PROP),\
+    $(wildcard $(TARGET_DEVICE_DIR)/product.prop))
+
+# Order matters here. When there are duplicates, the last one wins.
+# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
+_prop_vars_ := \
+    ADDITIONAL_PRODUCT_PROPERTIES \
+    PRODUCT_PRODUCT_PROPERTIES
+
+INSTALLED_PRODUCT_BUILD_PROP_TARGET := $(TARGET_OUT_PRODUCT)/build.prop
+$(eval $(call build-properties,\
+    product,\
+    $(INSTALLED_PRODUCT_BUILD_PROP_TARGET),\
+    $(_prop_files_),\
+    $(_prop_vars_),\
+    $(empty)))
 
 # ----------------------------------------------------------------
-# odm build.prop
-INSTALLED_ODM_BUILD_PROP_TARGET := $(TARGET_OUT_ODM)/etc/build.prop
-ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_ODM_BUILD_PROP_TARGET)
+# odm/build.prop
+#
+_prop_files_ := $(if $(TARGET_ODM_PROP),\
+    $(TARGET_ODM_PROP),\
+    $(wildcard $(TARGET_DEVICE_DIR)/odm.prop))
 
-ifdef TARGET_ODM_PROP
-odm_prop_files := $(TARGET_ODM_PROP)
-else
-odm_prop_files := $(wildcard $(TARGET_DEVICE_DIR)/odm.prop)
-endif
+# Order matters here. When there are duplicates, the last one wins.
+# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
+_prop_vars_ := \
+    ADDITIONAL_ODM_PROPERTIES \
+    PRODUCT_ODM_PROPERTIES
 
-FINAL_ODM_BUILD_PROPERTIES += \
-    $(call collapse-pairs, $(PRODUCT_ODM_PROPERTIES) $(ADDITIONAL_ODM_PROPERTIES))
-FINAL_ODM_BUILD_PROPERTIES := $(call uniq-pairs-by-first-component, \
-    $(FINAL_ODM_BUILD_PROPERTIES),=)
-
-$(INSTALLED_ODM_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) $(odm_prop_files)
-	@echo Target odm buildinfo: $@
-	@mkdir -p $(dir $@)
-	$(hide) rm -f $@ && touch $@
-	$(hide) $(call generate-common-build-props,odm,$@)
-	$(hide) $(foreach file,$(odm_prop_files), \
-	    if [ -f "$(file)" ]; then \
-	        echo Target odm properties from: "$(file)"; \
-	        echo "" >> $@; \
-	        echo "#" >> $@; \
-	        echo "# from $(file)" >> $@; \
-	        echo "#" >> $@; \
-	        cat $(file) >> $@; \
-	        echo "# end of $(file)" >> $@; \
-	    fi;)
-	$(hide) echo "#" >> $@; \
-	        echo "# ADDITIONAL ODM BUILD PROPERTIES" >> $@; \
-	        echo "#" >> $@;
-	$(hide) $(foreach line,$(FINAL_ODM_BUILD_PROPERTIES), \
-	    echo "$(line)" >> $@;)
-	$(hide) $(POST_PROCESS_PROPS) $@
+INSTALLED_ODM_BUILD_PROP_TARGET := $(TARGET_OUT_ODM)/build.prop
+$(eval $(call build-properties,\
+    odm,\
+    $(INSTALLED_ODM_BUILD_PROP_TARGET),\
+    $(_prop_files),\
+    $(_prop_vars_),\
+    $(empty)))
 
 # -----------------------------------------------------------------
-# system_ext build.prop
+# system_ext/build.prop
+#
+_prop_files_ := $(if $(TARGET_SYSTEM_EXT_PROP),\
+    $(TARGET_SYSTEM_EXT_PROP),\
+    $(wildcard $(TARGET_DEVICE_DIR)/system_ext.prop))
+
+# Order matters here. When there are duplicates, the last one wins.
+# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
+_prop_vars_ := PRODUCT_SYSTEM_EXT_PROPERTIES
+
 INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET := $(TARGET_OUT_SYSTEM_EXT)/build.prop
-ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET)
-
-ifdef TARGET_SYSTEM_EXT_PROP
-system_ext_prop_files := $(TARGET_SYSTEM_EXT_PROP)
-else
-system_ext_prop_files := $(wildcard $(TARGET_DEVICE_DIR)/system_ext.prop)
-endif
-
-FINAL_SYSTEM_EXT_PROPERTIES += \
-    $(call collapse-pairs, $(PRODUCT_SYSTEM_EXT_PROPERTIES))
-FINAL_SYSTEM_EXT_PROPERTIES := $(call uniq-pairs-by-first-component, \
-    $(FINAL_SYSTEM_EXT_PROPERTIES),=)
-
-$(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) $(system_ext_prop_files)
-	@echo Target system_ext buildinfo: $@
-	@mkdir -p $(dir $@)
-	$(hide) rm -f $@ && touch $@
-	$(hide) $(call generate-common-build-props,system_ext,$@)
-	$(hide) $(foreach file,$(system_ext_prop_files), \
-	    if [ -f "$(file)" ]; then \
-	        echo Target system_ext properties from: "$(file)"; \
-	        echo "" >> $@; \
-	        echo "#" >> $@; \
-	        echo "# from $(file)" >> $@; \
-	        echo "#" >> $@; \
-	        cat $(file) >> $@; \
-	        echo "# end of $(file)" >> $@; \
-	    fi;)
-	$(hide) echo "#" >> $@; \
-	        echo "# ADDITIONAL SYSTEM_EXT BUILD PROPERTIES" >> $@; \
-	        echo "#" >> $@;
-	$(hide) $(foreach line,$(FINAL_SYSTEM_EXT_PROPERTIES), \
-	    echo "$(line)" >> $@;)
-	$(hide) $(POST_PROCESS_PROPS) $@
+$(eval $(call build-properties,\
+    system_ext,\
+    $(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET),\
+    $(_prop_files_),\
+    $(_prop_vars_),\
+    $(empty)))
diff --git a/core/tasks/collect_gpl_sources.mk b/core/tasks/collect_gpl_sources.mk
index acbe9be..ebc4181 100644
--- a/core/tasks/collect_gpl_sources.mk
+++ b/core/tasks/collect_gpl_sources.mk
@@ -17,6 +17,8 @@
 # in installclean between incremental builds on build servers.
 gpl_source_tgz := $(call intermediates-dir-for,PACKAGING,gpl_source)/gpl_source.tgz
 
+ALL_GPL_MODULE_LICENSE_FILES := $(sort $(ALL_GPL_MODULE_LICENSE_FILES))
+
 # 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)
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index f16b7a7..d375780 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -237,7 +237,7 @@
     #  It must be of the form "YYYY-MM-DD" on production devices.
     #  It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
     #  If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
-      PLATFORM_SECURITY_PATCH := 2020-05-05
+      PLATFORM_SECURITY_PATCH := 2020-06-05
 endif
 .KATI_READONLY := PLATFORM_SECURITY_PATCH
 
diff --git a/envsetup.sh b/envsetup.sh
index 0ec7e6f..e981034 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -650,7 +650,6 @@
     export TARGET_BUILD_APPS=
 
     local product variant_and_version variant version
-
     product=${selection%%-*} # Trim everything after first dash
     variant_and_version=${selection#*-} # Trim everything up to first dash
     if [ "$variant_and_version" != "$selection" ]; then
@@ -675,7 +674,6 @@
     then
         return 1
     fi
-
     export TARGET_PRODUCT=$(get_build_var TARGET_PRODUCT)
     export TARGET_BUILD_VARIANT=$(get_build_var TARGET_BUILD_VARIANT)
     if [ -n "$version" ]; then
@@ -685,10 +683,10 @@
     fi
     export TARGET_BUILD_TYPE=release
 
-    echo
+    [[ -n "${ANDROID_QUIET_BUILD:-}" ]] || echo
 
     set_stuff_for_environment
-    printconfig
+    [[ -n "${ANDROID_QUIET_BUILD:-}" ]] || printconfig
     destroy_build_var_cache
 }
 
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index a3ca2a5..9e82048 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -16,7 +16,7 @@
 
 # Base modules and settings for the system partition.
 PRODUCT_PACKAGES += \
-    adbd_system_binaries \
+    adbd_system_api \
     am \
     android.hidl.allocator@1.0-service \
     android.hidl.base-V1.0-java \
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index bed1b28..f21a4e4 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -118,7 +118,6 @@
 PRODUCT_COPY_FILES += \
     system/core/rootdir/init.zygote32.rc:system/etc/init/hw/init.zygote32.rc \
     system/core/rootdir/init.zygote64.rc:system/etc/init/hw/init.zygote64.rc \
-    system/core/rootdir/init.zygote32_64.rc:system/etc/init/hw/init.zygote32_64.rc \
     system/core/rootdir/init.zygote64_32.rc:system/etc/init/hw/init.zygote64_32.rc \
 
 # Enable dynamic partition size
diff --git a/tools/buildinfo_common.sh b/tools/buildinfo_common.sh
deleted file mode 100755
index 6041d79..0000000
--- a/tools/buildinfo_common.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-partition="$1"
-
-if [ "$#" -ne 1 ]; then
-  echo "Usage: $0 <partition>" 1>&2
-  exit 1
-fi
-
-echo "# begin common build properties"
-echo "# autogenerated by $0"
-
-echo "ro.${partition}.build.date=`$DATE`"
-echo "ro.${partition}.build.date.utc=`$DATE +%s`"
-echo "ro.${partition}.build.fingerprint=$BUILD_FINGERPRINT"
-echo "ro.${partition}.build.id=$BUILD_ID"
-echo "ro.${partition}.build.tags=$BUILD_VERSION_TAGS"
-echo "ro.${partition}.build.type=$TARGET_BUILD_TYPE"
-echo "ro.${partition}.build.version.incremental=$BUILD_NUMBER"
-echo "ro.${partition}.build.version.release=$PLATFORM_VERSION"
-echo "ro.${partition}.build.version.sdk=$PLATFORM_SDK_VERSION"
-
-echo "ro.product.${partition}.brand=$PRODUCT_BRAND"
-echo "ro.product.${partition}.device=$PRODUCT_DEVICE"
-echo "ro.product.${partition}.manufacturer=$PRODUCT_MANUFACTURER"
-echo "ro.product.${partition}.model=$PRODUCT_MODEL"
-echo "ro.product.${partition}.name=$PRODUCT_NAME"
-
-echo "# end common build properties"
diff --git a/tools/post_process_props.py b/tools/post_process_props.py
index b221041..4fa15bc 100755
--- a/tools/post_process_props.py
+++ b/tools/post_process_props.py
@@ -108,7 +108,10 @@
       self.props[index].value = value
 
   def delete(self, name):
-    self.props = [p for p in self.props if p.name != name]
+    index = next((i for i,p in enumerate(self.props) if p.name == name), -1)
+    if index != -1:
+      new_comment = "# removed by post_process_props.py\n#" + str(self.props[index])
+      self.props[index] = Prop.from_line(new_comment)
 
   def write(self, filename):
     with open(filename, 'w+') as f:
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index b52da87..11f92ab 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -184,6 +184,7 @@
         "bsdiff",
         "imgdiff",
         "minigzip",
+        "lz4",
         "mkbootfs",
         "signapk",
     ],
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 93e14e5..8a59a39 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1191,7 +1191,7 @@
     AddAftlInclusionProof(image_path)
 
 
-def _MakeRamdisk(sourcedir, fs_config_file=None):
+def _MakeRamdisk(sourcedir, fs_config_file=None, lz4_ramdisks=False):
   ramdisk_img = tempfile.NamedTemporaryFile()
 
   if fs_config_file is not None and os.access(fs_config_file, os.F_OK):
@@ -1200,12 +1200,16 @@
   else:
     cmd = ["mkbootfs", os.path.join(sourcedir, "RAMDISK")]
   p1 = Run(cmd, stdout=subprocess.PIPE)
-  p2 = Run(["minigzip"], stdin=p1.stdout, stdout=ramdisk_img.file.fileno())
+  if lz4_ramdisks:
+    p2 = Run(["lz4", "-l", "-12" , "--favor-decSpeed"], stdin=p1.stdout,
+             stdout=ramdisk_img.file.fileno())
+  else:
+    p2 = Run(["minigzip"], stdin=p1.stdout, stdout=ramdisk_img.file.fileno())
 
   p2.wait()
   p1.wait()
   assert p1.returncode == 0, "mkbootfs of %s ramdisk failed" % (sourcedir,)
-  assert p2.returncode == 0, "minigzip of %s ramdisk failed" % (sourcedir,)
+  assert p2.returncode == 0, "compression of %s ramdisk failed" % (sourcedir,)
 
   return ramdisk_img
 
@@ -1243,7 +1247,8 @@
   img = tempfile.NamedTemporaryFile()
 
   if has_ramdisk:
-    ramdisk_img = _MakeRamdisk(sourcedir, fs_config_file)
+    use_lz4 = info_dict.get("lz4_ramdisks") == 'true'
+    ramdisk_img = _MakeRamdisk(sourcedir, fs_config_file, lz4_ramdisks=use_lz4)
 
   # use MKBOOTIMG from environ, or "mkbootimg" if empty or not set
   mkbootimg = os.getenv('MKBOOTIMG') or "mkbootimg"
@@ -1427,7 +1432,8 @@
 
   img = tempfile.NamedTemporaryFile()
 
-  ramdisk_img = _MakeRamdisk(sourcedir)
+  use_lz4 = info_dict.get("lz4_ramdisks") == 'true'
+  ramdisk_img = _MakeRamdisk(sourcedir, lz4_ramdisks=use_lz4)
 
   # use MKBOOTIMG from environ, or "mkbootimg" if empty or not set
   mkbootimg = os.getenv('MKBOOTIMG') or "mkbootimg"