Merge "Add "hwaddress" sanitizer."
diff --git a/OWNERS b/OWNERS
index 1e9b763..b9fee4e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -2,10 +2,7 @@
 dwillemsen@google.com
 nanzhang@google.com
 
-per-file * = ccross@android.com
-per-file * = dwillemsen@google.com
-per-file * = nanzhang@google.com
+per-file * = ccross@android.com,dwillemsen@google.com,nanzhang@google.com
 
 # for version updates
-per-file version_defaults.mk = aseaton@google.com
-per-file version_defaults.mk = elisapascual@google.com
+per-file version_defaults.mk = aseaton@google.com,elisapascual@google.com
diff --git a/core/Makefile b/core/Makefile
index afebd35..2f9b141 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -69,15 +69,24 @@
 # If more than one makefile declared a header, print a warning,
 # then copy the last one defined. This matches the previous make
 # behavior.
+has_dup_copy_headers :=
 $(foreach dest,$(ALL_COPIED_HEADERS), \
     $(eval _srcs := $(ALL_COPIED_HEADERS.$(dest).SRC)) \
     $(eval _src := $(word $(words $(_srcs)),$(_srcs))) \
     $(if $(call streq,$(_src),$(_srcs)),, \
         $(warning Duplicate header copy: $(dest)) \
-	$(warning Defined in: $(ALL_COPIED_HEADERS.$(dest).MAKEFILE))) \
+	$(warning Defined in: $(ALL_COPIED_HEADERS.$(dest).MAKEFILE)) \
+	$(eval has_dup_copy_headers := true)) \
     $(eval $(call copy-one-header,$(_src),$(dest))))
 all_copied_headers: $(ALL_COPIED_HEADERS)
 
+ifdef has_dup_copy_headers
+  has_dup_copy_headers :=
+  ifneq ($(BUILD_BROKEN_DUP_COPY_HEADERS),true)
+    $(error duplicate header copies are no longer allowed. For more information about headers, see: https://android.googlesource.com/platform/build/soong/+/master/docs/best_practices.md#headers)
+  endif
+endif
+
 # -----------------------------------------------------------------
 # docs/index.html
 ifeq (,$(TARGET_BUILD_APPS))
@@ -300,7 +309,7 @@
 endef
 
 BUILDINFO_SH := build/make/tools/buildinfo.sh
-VENDOR_BUILDINFO_SH := build/make/tools/vendor_buildinfo.sh
+DEVICE_BUILDINFO_SH := build/make/tools/device_buildinfo.sh
 
 # TARGET_BUILD_FLAVOR and ro.build.flavor are used only by the test
 # harness to distinguish builds. Only add _asan for a sanitized build
@@ -410,7 +419,7 @@
     $(FINAL_VENDOR_BUILD_PROPERTIES),=)
 endif  # property_overrides_split_enabled
 
-$(INSTALLED_VENDOR_BUILD_PROP_TARGET): $(VENDOR_BUILDINFO_SH) $(intermediate_system_build_prop)
+$(INSTALLED_VENDOR_BUILD_PROP_TARGET): $(DEVICE_BUILDINFO_SH) $(intermediate_system_build_prop)
 	@echo Target vendor buildinfo: $@
 	@mkdir -p $(dir $@)
 	$(hide) echo > $@
@@ -435,7 +444,7 @@
 			PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
 			TARGET_BOOTLOADER_BOARD_NAME="$(TARGET_BOOTLOADER_BOARD_NAME)" \
 			TARGET_BOARD_PLATFORM="$(TARGET_BOARD_PLATFORM)" \
-	        bash $(VENDOR_BUILDINFO_SH) >> $@
+	        bash $(DEVICE_BUILDINFO_SH) "vendor" >> $@
 ifdef property_overrides_split_enabled
 	$(hide) echo "#" >> $@; \
 	        echo "# ADDITIONAL VENDOR BUILD PROPERTIES" >> $@; \
@@ -472,6 +481,39 @@
 	$(hide) build/make/tools/post_process_props.py $@
 
 # ----------------------------------------------------------------
+# odm build.prop
+INSTALLED_ODM_BUILD_PROP_TARGET := $(TARGET_OUT_ODM)/build.prop
+ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_ODM_BUILD_PROP_TARGET)
+
+FINAL_ODM_BUILD_PROPERTIES += \
+    $(call collapse-pairs, $(PRODUCT_ODM_PROPERTIES))
+FINAL_ODM_BUILD_PROPERTIES := $(call uniq-pairs-by-first-component, \
+    $(FINAL_ODM_BUILD_PROPERTIES),=)
+
+$(INSTALLED_ODM_BUILD_PROP_TARGET): $(DEVICE_BUILDINFO_SH)
+	@echo Target odm buildinfo: $@
+	@mkdir -p $(dir $@)
+	$(hide) echo > $@
+	$(hide) echo ro.odm.build.date=`$(DATE_FROM_FILE)`>>$@
+	$(hide) echo ro.odm.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
+	$(hide) echo ro.odm.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
+	$(hide) echo ro.odm.product.cpu.abilist="$(TARGET_CPU_ABI_LIST)">>$@
+	$(hide) echo ro.odm.product.cpu.abilist32="$(TARGET_CPU_ABI_LIST_32_BIT)">>$@
+	$(hide) echo ro.odm.product.cpu.abilist64="$(TARGET_CPU_ABI_LIST_64_BIT)">>$@
+	$(hide) TARGET_DEVICE="$(TARGET_DEVICE)" \
+			PRODUCT_NAME="$(TARGET_PRODUCT)" \
+			PRODUCT_BRAND="$(PRODUCT_BRAND)" \
+			PRODUCT_MODEL="$(PRODUCT_MODEL)" \
+			PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
+			TARGET_BOOTLOADER_BOARD_NAME="$(TARGET_BOOTLOADER_BOARD_NAME)" \
+			TARGET_BOARD_PLATFORM="$(TARGET_BOARD_PLATFORM)" \
+	        bash $(DEVICE_BUILDINFO_SH) "odm" >> $@
+	$(hide) echo "#" >> $@; \
+	        echo "# ADDITIONAL ODM BUILD PROPERTIES" >> $@; \
+	        echo "#" >> $@;
+	$(hide) $(foreach line,$(FINAL_ODM_BUILD_PROPERTIES), \
+		echo "$(line)" >> $@;)
+	$(hide) build/make/tools/post_process_props.py $@
 
 # -----------------------------------------------------------------
 # product-services build.prop
@@ -863,23 +905,18 @@
 endif # TARGET_BOOTIMAGE_USE_EXT2
 endif # BOARD_USES_RECOVERY_AS_BOOT
 
-else	# TARGET_NO_KERNEL
+else # TARGET_NO_KERNEL == "true"
 ifdef BOARD_PREBUILT_BOOTIMAGE
 ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
 # Remove when b/63676296 is resolved.
 $(error Prebuilt bootimage is only supported for AB targets)
 endif
 $(eval $(call copy-one-file,$(BOARD_PREBUILT_BOOTIMAGE),$(INSTALLED_BOOTIMAGE_TARGET)))
-else
+else # BOARD_PREBUILT_BOOTIMAGE not defined
 INTERNAL_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE))
-# HACK: The top-level targets depend on the bootimage.  Not all targets
-# can produce a bootimage, though, and emulator targets need the ramdisk
-# instead.  Fake it out by calling the ramdisk the bootimage.
-# TODO: make the emulator use bootimages, and make mkbootimg accept
-#       kernel-less inputs.
-INSTALLED_BOOTIMAGE_TARGET := $(INSTALLED_RAMDISK_TARGET)
-endif
-endif
+INSTALLED_BOOTIMAGE_TARGET :=
+endif # BOARD_PREBUILT_BOOTIMAGE
+endif # TARGET_NO_KERNEL
 
 # -----------------------------------------------------------------
 # NOTICE files
@@ -1136,7 +1173,7 @@
 ifneq (true,$(TARGET_USERIMAGES_SPARSE_SQUASHFS_DISABLED))
   INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG := -s
 endif
-ifneq ($(filter $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE) $(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE) $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE) $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs),)
+ifneq ($(filter $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE) $(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE) $(BOARD_ODMIMAGE_FILE_SYSTEM_TYPE) $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE) $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs),)
 INTERNAL_USERIMAGES_DEPS += $(MAKE_SQUASHFS) $(MKSQUASHFSUSERIMG) $(IMG2SIMG)
 endif
 
@@ -1170,7 +1207,7 @@
 endif # PRODUCT_USE_LOGICAL_PARTITIONS
 
 # $(1): the path of the output dictionary file
-# $(2): a subset of "system vendor cache userdata product product_services oem"
+# $(2): a subset of "system vendor cache userdata product product_services oem odm"
 # $(3): additional "key=value" pairs to append to the dictionary file.
 define generate-image-prop-dictionary
 $(if $(filter $(2),system),\
@@ -1233,6 +1270,19 @@
     $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "product_services_squashfs_disable_4k_align=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
     $(if $(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "product_services_reserved_size=$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
 )
+$(if $(filter $(2),odm),\
+    $(if $(BOARD_ODMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "odm_fs_type=$(BOARD_ODMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
+    $(if $(BOARD_ODMIMAGE_EXTFS_INODE_COUNT),$(hide) echo "odm_extfs_inode_count=$(BOARD_ODMIMAGE_EXTFS_INODE_COUNT)" >> $(1))
+    $(if $(BOARD_ODMIMAGE_EXTFS_RSV_PCT),$(hide) echo "odm_extfs_rsv_pct=$(BOARD_ODMIMAGE_EXTFS_RSV_PCT)" >> $(1))
+    $(if $(BOARD_ODMIMAGE_PARTITION_SIZE),$(hide) echo "odm_size=$(BOARD_ODMIMAGE_PARTITION_SIZE)" >> $(1))
+    $(if $(BOARD_ODMIMAGE_JOURNAL_SIZE),$(hide) echo "odm_journal_size=$(BOARD_ODMIMAGE_JOURNAL_SIZE)" >> $(1))
+    $(if $(BOARD_ODMIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "odm_squashfs_compressor=$(BOARD_ODMIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
+    $(if $(BOARD_ODMIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "odm_squashfs_compressor_opt=$(BOARD_ODMIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
+    $(if $(BOARD_ODMIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "odm_squashfs_block_size=$(BOARD_ODMIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
+    $(if $(BOARD_ODMIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "odm_squashfs_disable_4k_align=$(BOARD_ODMIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
+    $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ODM_BASE_FS_PATH),$(hide) echo "odm_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ODM_BASE_FS_PATH)" >> $(1))
+    $(if $(BOARD_ODMIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "odm_reserved_size=$(BOARD_ODMIMAGE_PARTITION_RESERVED_SIZE)" >> $(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))
@@ -1240,6 +1290,7 @@
     $(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 $(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))
@@ -1292,6 +1343,13 @@
         $(hide) echo "avb_product_services_key_path=$(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH)" >> $(1)
         $(hide) echo "avb_product_services_algorithm=$(BOARD_AVB_PRODUCT_SERVICES_ALGORITHM)" >> $(1)
         $(hide) echo "avb_product_services_rollback_index_location=$(BOARD_AVB_PRODUCT_SERVICES_ROLLBACK_INDEX_LOCATION)" >> $(1)))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_odm_hashtree_enable=$(BOARD_AVB_ENABLE)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_odm_add_hashtree_footer_args=$(BOARD_AVB_ODM_ADD_HASHTREE_FOOTER_ARGS)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),\
+    $(if $(BOARD_AVB_ODM_KEY_PATH),\
+        $(hide) echo "avb_odm_key_path=$(BOARD_AVB_ODM_KEY_PATH)" >> $(1)
+        $(hide) echo "avb_odm_algorithm=$(BOARD_AVB_ODM_ALGORITHM)" >> $(1)
+        $(hide) echo "avb_odm_rollback_index_location=$(BOARD_AVB_ODM_ROLLBACK_INDEX_LOCATION)" >> $(1)))
 $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
     $(hide) echo "recovery_as_boot=true" >> $(1))
 $(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
@@ -1304,7 +1362,7 @@
 # $(1): the path of the output dictionary file
 # $(2): additional "key=value" pairs to append to the dictionary file.
 define generate-userimage-prop-dictionary
-$(call generate-image-prop-dictionary,$(1),system vendor cache userdata product product_services oem,$(2))
+$(call generate-image-prop-dictionary,$(1),system vendor cache userdata product product_services oem odm,$(2))
 endef
 
 # $(1): the path of the input dictionary file, where each line has the format key=value
@@ -1341,6 +1399,17 @@
 
 INSTALLED_FILES_FILE_RECOVERY := $(PRODUCT_OUT)/installed-files-recovery.txt
 INSTALLED_FILES_JSON_RECOVERY := $(INSTALLED_FILES_FILE_RECOVERY:.txt=.json)
+
+# TODO(b/30414428): Can't depend on INTERNAL_RECOVERYIMAGE_FILES alone like other
+# INSTALLED_FILES_FILE_* rules. Because currently there're cp/rsync/rm commands in
+# build-recoveryimage-target, which would touch the files under TARGET_RECOVERY_OUT and race with
+# the call to FILELIST.
+ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+$(INSTALLED_FILES_FILE_RECOVERY): $(INSTALLED_BOOTIMAGE_TARGET)
+else
+$(INSTALLED_FILES_FILE_RECOVERY): $(INSTALLED_RECOVERYIMAGE_TARGET)
+endif
+
 $(INSTALLED_FILES_FILE_RECOVERY): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_RECOVERY)
 $(INSTALLED_FILES_FILE_RECOVERY): $(INTERNAL_RECOVERYIMAGE_FILES) $(FILESLIST)
 	@echo Installed file list: $@
@@ -1478,6 +1547,7 @@
 		$(INSTALLED_VENDOR_DEFAULT_PROP_TARGET) \
 		$(intermediate_system_build_prop) \
 		$(INSTALLED_VENDOR_BUILD_PROP_TARGET) \
+		$(INSTALLED_ODM_BUILD_PROP_TARGET) \
 		$(INSTALLED_PRODUCT_BUILD_PROP_TARGET) \
 		$(INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET)
 	@echo "Target recovery buildinfo: $@
@@ -1487,6 +1557,7 @@
 	$(hide) cat $(INSTALLED_VENDOR_DEFAULT_PROP_TARGET) >> $@
 	$(hide) cat $(intermediate_system_build_prop) >> $@
 	$(hide) cat $(INSTALLED_VENDOR_BUILD_PROP_TARGET) >> $@
+	$(hide) cat $(INSTALLED_ODM_BUILD_PROP_TARGET) >> $@
 	$(hide) cat $(INSTALLED_PRODUCT_BUILD_PROP_TARGET) >> $@
 	$(hide) cat $(INSTALLED_PRODUCT_SERVICES_BUILD_PROP_TARGET) >> $@
 	$(call append-recovery-ui-properties,$(PRIVATE_RECOVERY_UI_PROPERTIES),$@)
@@ -1544,7 +1615,7 @@
   # Removes $(TARGET_RECOVERY_ROOT_OUT)/init*.rc EXCEPT init.recovery*.rc.
   $(hide) find $(TARGET_RECOVERY_ROOT_OUT) -maxdepth 1 -name 'init*.rc' -type f -not -name "init.recovery.*.rc" | xargs rm -f
   $(hide) cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/
-  $(hide) cp $(TARGET_ROOT_OUT)/init.recovery.*.rc $(TARGET_RECOVERY_ROOT_OUT)/ || true # Ignore error when the src file doesn't exist.
+  $(hide) cp $(TARGET_ROOT_OUT)/init.recovery.*.rc $(TARGET_RECOVERY_ROOT_OUT)/ 2> /dev/null || true # Ignore error when the src file doesn't exist.
   $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/res
   $(hide) rm -rf $(TARGET_RECOVERY_ROOT_OUT)/res/*
   $(hide) cp -rf $(recovery_resources_common)/* $(TARGET_RECOVERY_ROOT_OUT)/res
@@ -1765,6 +1836,21 @@
 endef
 endif
 
+# Create symlink /vendor/odm to /odm if necessary.
+ifdef BOARD_USES_ODMIMAGE
+define create-vendor-odm-symlink
+$(hide) if [ -d $(TARGET_OUT_VENDOR)/odm ] && [ ! -h $(TARGET_OUT_VENDOR)/odm ]; then \
+  echo 'Non-symlink $(TARGET_OUT_VENDOR)/odm detected!' 1>&2; \
+  echo 'You cannot install files to $(TARGET_OUT_VENDOR)/odm while building a separate odm.img!' 1>&2; \
+  exit 1; \
+fi
+$(hide) ln -sf /odm $(TARGET_OUT_VENDOR)/odm
+endef
+else
+define create-vendor-odm-symlink
+endef
+endif
+
 # $(1): output file
 define build-systemimage-target
   @echo "Target system fs image: $(1)"
@@ -1794,6 +1880,7 @@
 # as the source (since they are very similar).  Generate the patch so
 # we can see how big it's going to be, and include that in the system
 # image size check calculation.
+ifneq ($(INSTALLED_BOOTIMAGE_TARGET),)
 ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
 ifneq ($(BOARD_USES_FULL_RECOVERY_IMAGE),true)
 ifneq (,$(filter true, $(BOARD_BUILD_SYSTEM_ROOT_IMAGE) $(BOARD_INCLUDE_RECOVERY_DTBO)))
@@ -1813,9 +1900,9 @@
 	$(PRIVATE_DIFF_TOOL) $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_RECOVERYIMAGE_TARGET) $@
 else # $(BOARD_USES_FULL_RECOVERY_IMAGE) == true
 RECOVERY_FROM_BOOT_PATCH := $(INSTALLED_RECOVERYIMAGE_TARGET)
-endif
-endif
-
+endif # BOARD_USES_FULL_RECOVERY_IMAGE
+endif # INSTALLED_RECOVERYIMAGE_TARGET
+endif # INSTALLED_BOOTIMAGE_TARGET
 
 $(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH)
 	@echo "Install system fs image: $@"
@@ -1939,6 +2026,10 @@
 	$(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
 		$(TARGET_COPY_OUT_PRODUCT_SERVICES)
 endif
+ifdef BOARD_ODMIMAGE_FILE_SYSTEM_TYPE
+	$(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
+		$(TARGET_COPY_OUT_ODM)
+endif
 ifneq ($(PDK_PLATFORM_JAVA_ZIP_CONTENTS),)
 	$(hide) cd $(OUT_DIR) && zip -qryX $(patsubst $(OUT_DIR)/%,%,$@) $(PDK_PLATFORM_JAVA_ZIP_CONTENTS)
 endif
@@ -2256,6 +2347,7 @@
 define build-vendorimage-target
   $(call pretty,"Target vendor fs image: $(INSTALLED_VENDORIMAGE_TARGET)")
   @mkdir -p $(TARGET_OUT_VENDOR)
+  $(call create-vendor-odm-symlink)
   @mkdir -p $(vendorimage_intermediates) && rm -rf $(vendorimage_intermediates)/vendor_image_info.txt
   $(call generate-image-prop-dictionary, $(vendorimage_intermediates)/vendor_image_info.txt,vendor,skip_fsck=true)
   $(if $(BOARD_VENDOR_KERNEL_MODULES), \
@@ -2399,6 +2491,62 @@
 endif
 
 # -----------------------------------------------------------------
+# odm partition image
+ifdef BOARD_ODMIMAGE_FILE_SYSTEM_TYPE
+INTERNAL_ODMIMAGE_FILES := \
+    $(filter $(TARGET_OUT_ODM)/%,\
+      $(ALL_DEFAULT_INSTALLED_MODULES)\
+      $(ALL_PDK_FUSION_FILES)) \
+    $(PDK_FUSION_SYMLINK_STAMP)
+# platform.zip depends on $(INTERNAL_ODMIMAGE_FILES).
+$(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_ODMIMAGE_FILES)
+
+INSTALLED_FILES_FILE_ODM := $(PRODUCT_OUT)/installed-files-odm.txt
+INSTALLED_FILES_JSON_ODM := $(INSTALLED_FILES_FILE_ODM:.txt=.json)
+$(INSTALLED_FILES_FILE_ODM): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_ODM)
+$(INSTALLED_FILES_FILE_ODM) : $(INTERNAL_ODMIMAGE_FILES) $(FILESLIST)
+	@echo Installed file list: $@
+	@mkdir -p $(dir $@)
+	@rm -f $@
+	$(hide) $(FILESLIST) $(TARGET_OUT_ODM) > $(@:.txt=.json)
+	$(hide) build/tools/fileslist_util.py -c $(@:.txt=.json) > $@
+
+odmimage_intermediates := \
+    $(call intermediates-dir-for,PACKAGING,odm)
+BUILT_ODMIMAGE_TARGET := $(PRODUCT_OUT)/odm.img
+define build-odmimage-target
+  $(call pretty,"Target odm fs image: $(INSTALLED_ODMIMAGE_TARGET)")
+  @mkdir -p $(TARGET_OUT_ODM)
+  @mkdir -p $(odmimage_intermediates) && rm -rf $(odmimage_intermediates)/odm_image_info.txt
+  $(call generate-userimage-prop-dictionary, $(odmimage_intermediates)/odm_image_info.txt, skip_fsck=true)
+  $(if $(BOARD_ODM_KERNEL_MODULES), \
+    $(call build-image-kernel-modules,$(BOARD_ODM_KERNEL_MODULES),$(TARGET_OUT_ODM),odm/,$(call intermediates-dir-for,PACKAGING,depmod_odm)))
+  $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
+      ./build/tools/releasetools/build_image.py \
+      $(TARGET_OUT_ODM) $(odmimage_intermediates)/odm_image_info.txt $(INSTALLED_ODMIMAGE_TARGET) $(TARGET_OUT) \
+	  $(odmimage_intermediates)/generated_odm_image_info.txt
+  $(hide) $(call assert-max-image-size,$(INSTALLED_ODMIMAGE_TARGET),\
+      $(call read-image-prop-dictionary,\
+          $(odmimage_intermediates)/generated_odm_image_info.txt,odm_size))
+endef
+
+# We just build this directly to the install location.
+INSTALLED_ODMIMAGE_TARGET := $(BUILT_ODMIMAGE_TARGET)
+$(INSTALLED_ODMIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_ODMIMAGE_FILES) $(INSTALLED_FILES_FILE_ODM) $(BUILD_IMAGE_SRCS) $(DEPMOD) $(BOARD_ODM_KERNEL_MODULES)
+	$(build-odmimage-target)
+
+.PHONY: odmimage-nodeps onod
+odmimage-nodeps onod: | $(INTERNAL_USERIMAGES_DEPS) $(DEPMOD)
+	$(build-odmimage-target)
+
+sync: $(INTERNAL_ODMIMAGE_FILES)
+
+else ifdef BOARD_PREBUILT_ODMIMAGE
+INSTALLED_ODMIMAGE_TARGET := $(PRODUCT_OUT)/odm.img
+$(eval $(call copy-one-file,$(BOARD_PREBUILT_ODMIMAGE),$(INSTALLED_ODMIMAGE_TARGET)))
+endif
+
+# -----------------------------------------------------------------
 # dtbo image
 ifdef BOARD_PREBUILT_DTBOIMAGE
 INSTALLED_DTBOIMAGE_TARGET := $(PRODUCT_OUT)/dtbo.img
@@ -2443,6 +2591,7 @@
 RECOVERY_FOOTER_ARGS := BOARD_AVB_RECOVERY_ADD_HASH_FOOTER_ARGS
 PRODUCT_FOOTER_ARGS := BOARD_AVB_PRODUCT_ADD_HASHTREE_FOOTER_ARGS
 PRODUCT_SERVICES_FOOTER_ARGS := BOARD_AVB_PRODUCT_SERVICES_ADD_HASHTREE_FOOTER_ARGS
+ODM_FOOTER_ARGS := BOARD_AVB_ODM_ADD_HASHTREE_FOOTER_ARGS
 
 # Check and set required build variables for a chain partition.
 # $(1): the partition to enable AVB chain, e.g., BOOT or SYSTEM.
@@ -2472,12 +2621,14 @@
 $(eval $($(_footer_args)) += --rollback_index $($(_rollback_index)))
 endef
 
+ifdef INSTALLED_BOOTIMAGE_TARGET
 ifdef BOARD_AVB_BOOT_KEY_PATH
 $(eval $(call check-and-set-avb-chain-args,BOOT))
 else
 INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
     --include_descriptors_from_image $(INSTALLED_BOOTIMAGE_TARGET)
 endif
+endif
 
 ifdef BOARD_AVB_SYSTEM_KEY_PATH
 $(eval $(call check-and-set-avb-chain-args,SYSTEM))
@@ -2504,6 +2655,15 @@
 endif
 endif
 
+ifdef INSTALLED_ODMIMAGE_TARGET
+ifdef BOARD_AVB_ODM_KEY_PATH
+$(eval $(call check-and-set-avb-chain-args,ODM))
+else
+INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
+    --include_descriptors_from_image $(INSTALLED_ODMIMAGE_TARGET)
+endif
+endif
+
 ifdef INSTALLED_DTBOIMAGE_TARGET
 ifdef BOARD_AVB_DTBO_KEY_PATH
 $(eval $(call check-and-set-avb-chain-args,DTBO))
@@ -2563,6 +2723,9 @@
   $(if $(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH),\
     $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_PRODUCT_SERVICES_KEY_PATH) \
       --output $(1)/product-services.avbpubkey)
+  $(if $(BOARD_AVB_ODM_KEY_PATH),\
+    $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_ODM_KEY_PATH) \
+      --output $(1)/odm.avbpubkey)
   $(if $(BOARD_AVB_DTBO_KEY_PATH),\
     $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_DTBO_KEY_PATH) \
       --output $(1)/dtbo.avbpubkey)
@@ -2591,6 +2754,7 @@
 		$(INSTALLED_VENDORIMAGE_TARGET) \
 		$(INSTALLED_PRODUCTIMAGE_TARGET) \
 		$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) \
+		$(INSTALLED_ODMIMAGE_TARGET) \
 		$(INSTALLED_DTBOIMAGE_TARGET) \
 		$(INSTALLED_RECOVERYIMAGE_TARGET) \
 		$(BOARD_AVB_KEY_PATH)
@@ -2770,6 +2934,7 @@
   $(HOST_OUT_EXECUTABLES)/brillo_update_payload \
   $(HOST_OUT_EXECUTABLES)/lib/shflags/shflags \
   $(HOST_OUT_EXECUTABLES)/delta_generator \
+  $(HOST_OUT_EXECUTABLES)/care_map_generator \
   $(AVBTOOL) \
   $(BLK_ALLOC_TO_BASE_FS) \
   $(BROTLI) \
@@ -2935,6 +3100,7 @@
 # Depending on the various images guarantees that the underlying
 # directories are up-to-date.
 $(BUILT_TARGET_FILES_PACKAGE): \
+		$(INSTALLED_RAMDISK_TARGET) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
 		$(INSTALLED_RADIOIMAGE_TARGET) \
 		$(INSTALLED_RECOVERYIMAGE_TARGET) \
@@ -2945,6 +3111,7 @@
 		$(INSTALLED_PRODUCTIMAGE_TARGET) \
 		$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) \
 		$(INSTALLED_VBMETAIMAGE_TARGET) \
+		$(INSTALLED_ODMIMAGE_TARGET) \
 		$(INSTALLED_DTBOIMAGE_TARGET) \
 		$(INTERNAL_SYSTEMOTHERIMAGE_FILES) \
 		$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
@@ -2954,6 +3121,7 @@
 		$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH) \
 		$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH) \
 		$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_BASE_FS_PATH) \
+		$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ODM_BASE_FS_PATH) \
 		$(SELINUX_FC) \
 		$(APKCERTS_FILE) \
 		$(SOONG_ZIP) \
@@ -2970,6 +3138,7 @@
 	$(call create-system-vendor-symlink)
 	$(call create-system-product-symlink)
 	$(call create-system-product-services-symlink)
+	$(call create-vendor-odm-symlink)
 	$(hide) rm -rf $@ $@.list $(zip_root)
 	$(hide) mkdir -p $(dir $@) $(zip_root)
 ifneq (,$(INSTALLED_RECOVERYIMAGE_TARGET)$(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)))
@@ -3048,6 +3217,11 @@
 	$(hide) $(call package_files-copy-root, \
 		$(TARGET_OUT_PRODUCT_SERVICES),$(zip_root)/PRODUCT-SERVICES)
 endif
+ifdef BOARD_ODMIMAGE_FILE_SYSTEM_TYPE
+	@# Contents of the odm image
+	$(hide) $(call package_files-copy-root, \
+		$(TARGET_OUT_ODM),$(zip_root)/ODM)
+endif
 ifdef INSTALLED_SYSTEMOTHERIMAGE_TARGET
 	@# Contents of the system_other image
 	$(hide) $(call package_files-copy-root, \
@@ -3123,6 +3297,10 @@
 	$(hide) cp $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_BASE_FS_PATH) \
 	  $(zip_root)/META/$(notdir $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_BASE_FS_PATH))
 endif
+ifneq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ODM_BASE_FS_PATH),)
+	$(hide) cp $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ODM_BASE_FS_PATH) \
+	  $(zip_root)/META/$(notdir $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ODM_BASE_FS_PATH))
+endif
 ifneq ($(strip $(SANITIZE_TARGET)),)
 	# We need to create userdata.img with real data because the instrumented libraries are in userdata.img.
 	$(hide) echo "userdata_img_with_data=true" >> $(zip_root)/META/misc_info.txt
@@ -3207,6 +3385,10 @@
 	$(hide) mkdir -p $(zip_root)/IMAGES
 	$(hide) cp $(INSTALLED_BOOTIMAGE_TARGET) $(zip_root)/IMAGES/
 endif
+ifdef BOARD_PREBUILT_ODMIMAGE
+	$(hide) mkdir -p $(zip_root)/IMAGES
+	$(hide) cp $(INSTALLED_ODMIMAGE_TARGET) $(zip_root)/IMAGES/
+endif
 ifdef BOARD_PREBUILT_DTBOIMAGE
 	$(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
 	$(hide) cp $(INSTALLED_DTBOIMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
@@ -3239,6 +3421,9 @@
 ifdef BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE
 	$(hide) $(call fs_config,$(zip_root)/PRODUCT_SERVICES,product-services/) > $(zip_root)/META/product_services_filesystem_config.txt
 endif
+ifdef BOARD_ODMIMAGE_FILE_SYSTEM_TYPE
+	$(hide) $(call fs_config,$(zip_root)/ODM,odm/) > $(zip_root)/META/odm_filesystem_config.txt
+endif
 ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
 	@# When using BOARD_BUILD_SYSTEM_ROOT_IMAGE, ROOT always contains the files for the root under
 	@# normal boot. BOOT/RAMDISK exists only if additionally using BOARD_USES_RECOVERY_AS_BOOT.
@@ -3351,6 +3536,7 @@
 # For apps_only build we'll establish the dependency later in build/make/core/main.mk.
 ifndef TARGET_BUILD_APPS
 $(APPCOMPAT_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+		$(INSTALLED_RAMDISK_TARGET) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
 		$(INSTALLED_USERDATAIMAGE_TARGET) \
 		$(INSTALLED_VENDORIMAGE_TARGET) \
@@ -3380,11 +3566,13 @@
 # For apps_only build we'll establish the dependency later in build/make/core/main.mk.
 ifndef TARGET_BUILD_APPS
 $(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+		$(INSTALLED_RAMDISK_TARGET) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
 		$(INSTALLED_USERDATAIMAGE_TARGET) \
 		$(INSTALLED_VENDORIMAGE_TARGET) \
 		$(INSTALLED_PRODUCTIMAGE_TARGET) \
 		$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) \
+		$(INSTALLED_ODMIMAGE_TARGET) \
 		$(updater_dep)
 endif
 $(SYMBOLS_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,symbols)/filelist
@@ -3405,11 +3593,13 @@
 COVERAGE_ZIP := $(PRODUCT_OUT)/$(name).zip
 ifndef TARGET_BUILD_APPS
 $(COVERAGE_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+		$(INSTALLED_RAMDISK_TARGET) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
 		$(INSTALLED_USERDATAIMAGE_TARGET) \
 		$(INSTALLED_VENDORIMAGE_TARGET) \
 		$(INSTALLED_PRODUCTIMAGE_TARGET) \
-		$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)
+		$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) \
+		$(INSTALLED_ODMIMAGE_TARGET)
 endif
 $(COVERAGE_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,coverage)/filelist
 $(COVERAGE_ZIP): $(SOONG_ZIP)
@@ -3527,6 +3717,15 @@
 productservicesimage: $(INSTALLED_QEMU_PRODUCT_SERVICESIMAGE)
 droidcore: $(INSTALLED_QEMU_PRODUCT_SERVICESIMAGE)
 endif
+ifeq ($(BOARD_USES_ODMIMAGE),true)
+INSTALLED_QEMU_ODMIMAGE := $(PRODUCT_OUT)/odm-qemu.img
+$(INSTALLED_QEMU_ODMIMAGE): $(INSTALLED_ODMIMAGE_TARGET) $(MK_QEMU_IMAGE_SH) $(SGDISK_HOST)
+	@echo Create odm-qemu.img
+	(export SGDISK=$(SGDISK_HOST); $(MK_QEMU_IMAGE_SH) ${PRODUCT_OUT}/odm.img)
+
+odmimage: $(INSTALLED_QEMU_ODMIMAGE)
+droidcore: $(INSTALLED_QEMU_ODMIMAGE)
+endif
 endif
 # -----------------------------------------------------------------
 # The emulator package
@@ -3590,7 +3789,7 @@
 	$(ALL_DEFAULT_INSTALLED_MODULES) \
 	$(INSTALLED_RAMDISK_TARGET) \
 	$(ALL_DOCS) \
-	$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/metalava-api-stubs-docs_annotations.zip \
+	$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/api-stubs-docs_annotations.zip \
 	$(ALL_SDK_FILES)
 endif
 
diff --git a/core/OWNERS b/core/OWNERS
index 4045061..570ede8 100644
--- a/core/OWNERS
+++ b/core/OWNERS
@@ -1,8 +1 @@
-per-file * = ccross@android.com
-per-file * = dwillemsen@google.com
-per-file * = nanzhang@google.com
-
-per-file dex_preopt*.mk = ngeoffray@google.com
-per-file dex_preopt*.mk = calin@google.com
-per-file dex_preopt*.mk = mathewi@google.com
-per-file dex_preopt*.mk = dbrazdil@google.com
+per-file dex_preopt*.mk = ngeoffray@google.com,calin@google.com,mathewi@google.com,dbrazdil@google.com
diff --git a/core/autogen_test_config.mk b/core/autogen_test_config.mk
index bf87c9d..a01d80f 100644
--- a/core/autogen_test_config.mk
+++ b/core/autogen_test_config.mk
@@ -26,7 +26,11 @@
 ifeq ($(LOCAL_NATIVE_BENCHMARK),true)
 autogen_test_config_template := $(NATIVE_BENCHMARK_TEST_CONFIG_TEMPLATE)
 else
-autogen_test_config_template := $(NATIVE_TEST_CONFIG_TEMPLATE)
+  ifeq ($(LOCAL_IS_HOST_MODULE),true)
+    autogen_test_config_template := $(NATIVE_HOST_TEST_CONFIG_TEMPLATE)
+  else
+    autogen_test_config_template := $(NATIVE_TEST_CONFIG_TEMPLATE)
+  endif
 endif
 # Auto generating test config file for native test
 $(autogen_test_config_file): PRIVATE_MODULE_NAME := $(LOCAL_MODULE)
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 037b2cb..3a1f396 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -66,6 +66,12 @@
   my_host_cross :=
 endif
 
+ifeq (true, $(LOCAL_PRODUCT_MODULE))
+ifneq (,$(filter $(LOCAL_MODULE),$(PRODUCT_FORCE_PRODUCT_MODULES_TO_SYSTEM_PARTITION)))
+  LOCAL_PRODUCT_MODULE :=
+endif
+endif
+
 _path := $(LOCAL_MODULE_PATH) $(LOCAL_MODULE_PATH_32) $(LOCAL_MODULE_PATH_64)
 ifneq ($(filter $(TARGET_OUT_VENDOR)%,$(_path)),)
 LOCAL_VENDOR_MODULE := true
@@ -583,10 +589,12 @@
       $(eval n := $(or $(word 2,$(p)),$(notdir $(word 1, $(p))))) \
       $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
         $(s):$(dir)/$(n)))))
-  ifeq (,$(LOCAL_TEST_CONFIG))
-    test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
-  else
+  ifneq (,$(LOCAL_FULL_TEST_CONFIG))
+    test_config := $(LOCAL_FULL_TEST_CONFIG)
+  else ifneq (,$(LOCAL_TEST_CONFIG))
     test_config := $(LOCAL_PATH)/$(LOCAL_TEST_CONFIG)
+  else
+    test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
   endif
   ifeq (,$(test_config))
     ifneq (true,$(is_native))
@@ -639,6 +647,19 @@
   endif
 endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
 
+# HACK: pretend a soong LOCAL_FULL_TEST_CONFIG is autogenerated by copying it to
+# the location autogenerated test configs use and setting the flag in
+# module-info.json
+ifdef LOCAL_FULL_TEST_CONFIG
+  ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+    my_test_config_file := $(dir $(LOCAL_BUILT_MODULE))$(LOCAL_MODULE).config
+    $(eval $(call copy-one-file,$(LOCAL_FULL_TEST_CONFIG),$(my_test_config_file)))
+    $(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_test_config_file))
+    ALL_MODULES.$(my_register_name).auto_test_config := true
+    my_test_config_file :=
+  endif
+endif
+
 ifneq ($(my_test_data_file_pairs),)
 $(foreach pair, $(my_test_data_file_pairs), \
   $(eval parts := $(subst :,$(space),$(pair))) \
@@ -748,6 +769,7 @@
 ALL_MODULES.$(my_register_name).FOR_2ND_ARCH := true
 endif
 ALL_MODULES.$(my_register_name).FOR_HOST_CROSS := $(my_host_cross)
+ALL_MODULES.$(my_register_name).MODULE_NAME := $(LOCAL_MODULE)
 ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES := $(LOCAL_COMPATIBILITY_SUITE)
 
 INSTALLABLE_FILES.$(LOCAL_INSTALLED_MODULE).MODULE := $(my_register_name)
diff --git a/core/binary.mk b/core/binary.mk
index 74e08d3..a28561c 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -854,7 +854,7 @@
 my_proto_source_suffix := .c
 my_proto_c_includes := external/nanopb-c
 my_protoc_flags := --nanopb_out=$(proto_gen_dir) \
-    --plugin=external/nanopb-c/generator/protoc-gen-nanopb
+    --plugin=$(HOST_OUT_EXECUTABLES)/protoc-gen-nanopb
 my_protoc_deps := $(NANOPB_SRCS) $(proto_sources_fullpath:%.proto=%.options)
 else
 my_proto_source_suffix := $(LOCAL_CPP_EXTENSION)
@@ -1626,6 +1626,9 @@
 installed_static_library_notice_file_targets :=
 endif
 
+$(notice_target): | $(installed_static_library_notice_file_targets)
+$(LOCAL_INSTALLED_MODULE): | $(notice_target)
+
 # Default is -fno-rtti.
 ifeq ($(strip $(LOCAL_RTTI_FLAG)),)
 LOCAL_RTTI_FLAG := -fno-rtti
@@ -1831,11 +1834,6 @@
     $(built_static_libraries) \
     $(built_whole_libraries)
 
-# Also depend on the notice files for any static libraries that
-# are linked into this module.  This will force them to be installed
-# when this module is.
-$(LOCAL_INSTALLED_MODULE): | $(installed_static_library_notice_file_targets)
-
 ###########################################################
 # Export includes
 ###########################################################
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index a4c47d5..07c7e51 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -94,10 +94,11 @@
 LOCAL_FDO_SUPPORT:=
 LOCAL_FINDBUGS_FLAGS:=
 LOCAL_FORCE_STATIC_EXECUTABLE:=
-LOCAL_FULL_LIBS_MANIFEST_FILES:=
-LOCAL_FULL_MANIFEST_FILE:=
 LOCAL_FULL_CLASSES_JACOCO_JAR:=
 LOCAL_FULL_CLASSES_PRE_JACOCO_JAR:=
+LOCAL_FULL_LIBS_MANIFEST_FILES:=
+LOCAL_FULL_MANIFEST_FILE:=
+LOCAL_FULL_TEST_CONFIG:=
 LOCAL_FUZZ_ENGINE:=
 LOCAL_GCNO_FILES:=
 LOCAL_GENERATED_SOURCES:=
@@ -281,7 +282,6 @@
 LOCAL_UNSTRIPPED_PATH:=
 LOCAL_USE_AAPT2:=$(USE_AAPT2)
 LOCAL_USE_CLANG_LLD:=
-LOCAL_USE_R8:=
 LOCAL_USE_VNDK:=
 LOCAL_USES_LIBRARIES:=
 LOCAL_VENDOR_MODULE:=
diff --git a/core/config.mk b/core/config.mk
index 091b1d1..4226f2f 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -167,14 +167,6 @@
 BUILD_HOST_TEST_CONFIG := $(BUILD_SYSTEM)/host_test_config.mk
 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
-
-# Tool to generate TradeFed test config file automatically.
-AUTOGEN_TEST_CONFIG_SCRIPT := build/make/tools/auto_gen_test_config.py
-
 # ###############################################################
 # Parse out any modifier targets.
 # ###############################################################
@@ -588,12 +580,6 @@
 USE_D8 := true
 .KATI_READONLY := USE_D8
 
-# Default R8 behavior when USE_R8 is not specified.
-ifndef USE_R8
-  USE_R8 := true
-endif
-.KATI_READONLY := USE_R8
-
 #
 # Tools that are prebuilts for TARGET_BUILD_APPS
 #
@@ -665,10 +651,7 @@
 BREAKPAD_GENERATE_SYMBOLS := false
 endif
 PROTOC := $(HOST_OUT_EXECUTABLES)/aprotoc$(HOST_EXECUTABLE_SUFFIX)
-NANOPB_SRCS := external/nanopb-c/generator/protoc-gen-nanopb \
-    $(wildcard external/nanopb-c/generator/*.py \
-               external/nanopb-c/generator/google/*.py \
-               external/nanopb-c/generator/proto/*.py)
+NANOPB_SRCS := $(HOST_OUT_EXECUTABLES)/protoc-gen-nanopb
 VTSC := $(HOST_OUT_EXECUTABLES)/vtsc$(HOST_EXECUTABLE_SUFFIX)
 MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
 MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)
@@ -863,11 +846,6 @@
 
 
 ifdef PRODUCT_SHIPPING_API_LEVEL
-  ifneq ($(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),27),)
-    ifneq ($(TARGET_USES_MKE2FS),true)
-      $(error When PRODUCT_SHIPPING_API_LEVEL >= 27, TARGET_USES_MKE2FS must be true)
-    endif
-  endif
   ifneq ($(call numbers_less_than,$(PRODUCT_SHIPPING_API_LEVEL),$(BOARD_SYSTEMSDK_VERSIONS)),)
     $(error BOARD_SYSTEMSDK_VERSIONS ($(BOARD_SYSTEMSDK_VERSIONS)) must all be greater than or equal to PRODUCT_SHIPPING_API_LEVEL ($(PRODUCT_SHIPPING_API_LEVEL)))
   endif
@@ -883,6 +861,11 @@
       endif
     endif
   endif
+  ifneq ($(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),29),)
+    ifneq ($(BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE),)
+      $(error When PRODUCT_SHIPPING_API_LEVEL >= 29, BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE cannot be set)
+    endif
+  endif
 endif
 
 # The default key if not set as LOCAL_CERTIFICATE
@@ -978,6 +961,13 @@
 endif
 endif
 
+ifneq ($(BOARD_ODMIMAGE_PARTITION_SIZE),)
+ifneq ($(BOARD_ODMIMAGE_PARTITION_RESERVED_SIZE),)
+$(error Should not define BOARD_ODMIMAGE_PARTITION_SIZE and \
+    BOARD_ODMIMAGE_PARTITION_RESERVED_SIZE together)
+endif
+endif
+
 ifneq ($(BOARD_PRODUCTIMAGE_PARTITION_SIZE),)
 ifneq ($(BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE),)
 $(error Should not define BOARD_PRODUCTIMAGE_PARTITION_SIZE and \
@@ -1177,6 +1167,7 @@
     vnod vendorimage-nodeps \
     pnod productimage-nodeps \
     psnod productservicesimage-nodeps \
+    onod odmimage-nodeps \
     systemotherimage-nodeps \
     ramdisk-nodeps \
     bootimage-nodeps \
diff --git a/core/definitions.mk b/core/definitions.mk
index 02eb725..d36e7f0 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2875,12 +2875,15 @@
 
 # Generate a greylist.txt from a classes.jar
 define hiddenapi-generate-greylist-txt
-$(2): $(1) $(CLASS2GREYLIST)
-	$(CLASS2GREYLIST) $(1) > $(2)
+ifneq (,$(wildcard frameworks/base))
+# Only generate this target if we're in a tree with frameworks/base present.
+$(2): $(1) $(CLASS2GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
+	$(CLASS2GREYLIST) --public-api-list $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) $(1) > $(2)
 
 $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): $(2)
 $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): \
     PRIVATE_GREYLIST_INPUTS := $$(PRIVATE_GREYLIST_INPUTS) $(2)
+endif
 endef
 
 # File names for intermediate dex files of `hiddenapi-copy-soong-jar`.
@@ -2906,22 +2909,6 @@
 	$(MERGE_ZIPS) -D -zipToNotStrip $${OUTPUT_JAR} -stripFile "classes*.dex" $(2) $${OUTPUT_JAR} $(1)
 endef
 
-###########################################################
-## Commands to call Proguard
-###########################################################
-ifdef TARGET_OPENJDK9
-define transform-jar-to-proguard
-@echo Skipping Proguard: $< $@
-$(hide) cp '$<' $@
-endef
-else
-define transform-jar-to-proguard
-@echo Proguard: $@
-$(hide) $(PROGUARD) -injars $< -outjars $@ $(PRIVATE_PROGUARD_FLAGS) \
-    $(addprefix -injars , $(PRIVATE_EXTRA_INPUT_JAR))
-endef
-endif
-
 
 ###########################################################
 ## Commands to call R8
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index 6c0a4b4..a7caac1 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -107,6 +107,19 @@
 HIDDENAPI_STUBS_TEST := \
     $(call hiddenapi_stubs_jar,android_test_stubs_current)
 
+# Allow products to define their own stubs for custom product jars that apps can use.
+ifdef PRODUCT_HIDDENAPI_STUBS
+  HIDDENAPI_STUBS += $(foreach stub,$(PRODUCT_HIDDENAPI_STUBS), $(call hiddenapi_stubs_jar,$(stub)))
+endif
+
+ifdef PRODUCT_HIDDENAPI_STUBS_SYSTEM
+  HIDDENAPI_STUBS_SYSTEM += $(foreach stub,$(PRODUCT_HIDDENAPI_STUBS_SYSTEM), $(call hiddenapi_stubs_jar,$(stub)))
+endif
+
+ifdef PRODUCT_HIDDENAPI_STUBS_TEST
+  HIDDENAPI_STUBS_TEST += $(foreach stub,$(PRODUCT_HIDDENAPI_STUBS_TEST), $(call hiddenapi_stubs_jar,$(stub)))
+endif
+
 # 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)
diff --git a/core/envsetup.mk b/core/envsetup.mk
index c7c3f92..125dadf 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -222,6 +222,17 @@
 TARGET_COPY_OUT_PRODUCT_SERVICES := $(_product_services_path_placeholder)
 ###########################################
 
+###########################################
+# Define TARGET_COPY_OUT_ODM to a placeholder, for at this point
+# we don't know if the device wants to build a separate odm.img
+# or just build odm stuff into vendor.img.
+# A device can set up TARGET_COPY_OUT_ODM to "odm" in its
+# BoardConfig.mk.
+# We'll substitute with the real value after loading BoardConfig.mk.
+_odm_path_placeholder := ||ODM-PATH-PH||
+TARGET_COPY_OUT_ODM := $(_odm_path_placeholder)
+###########################################
+
 #################################################################
 # Set up minimal BOOTCLASSPATH list of jars to build/execute
 # java code with dalvikvm/art.
@@ -302,8 +313,7 @@
 
 CHANGES_URL := https://android.googlesource.com/platform/build/+/master/Changes.md
 
-# "" is equivalent to true currently.
-ifeq ($(BUILD_BROKEN_ANDROIDMK_EXPORTS),false)
+ifneq ($(BUILD_BROKEN_ANDROIDMK_EXPORTS),true)
 $(KATI_obsolete_export It is a global setting. See $(CHANGES_URL)#export_keyword)
 endif
 
@@ -376,6 +386,28 @@
 endif
 
 ###########################################
+# Now we can substitute with the real value of TARGET_COPY_OUT_ODM
+ifeq ($(TARGET_COPY_OUT_ODM),$(_odm_path_placeholder))
+TARGET_COPY_OUT_ODM := vendor/odm
+else ifeq ($(filter odm vendor/odm,$(TARGET_COPY_OUT_ODM)),)
+$(error TARGET_COPY_OUT_ODM must be either 'odm' or 'vendor/odm', seeing '$(TARGET_COPY_OUT_ODM)'.)
+endif
+PRODUCT_COPY_FILES := $(subst $(_odm_path_placeholder),$(TARGET_COPY_OUT_ODM),$(PRODUCT_COPY_FILES))
+
+BOARD_USES_ODMIMAGE :=
+ifdef BOARD_PREBUILT_ODMIMAGE
+BOARD_USES_ODMIMAGE := true
+endif
+ifdef BOARD_ODMIMAGE_FILE_SYSTEM_TYPE
+BOARD_USES_ODMIMAGE := true
+endif
+ifeq ($(TARGET_COPY_OUT_ODM),odm)
+BOARD_USES_ODMIMAGE := true
+else ifdef BOARD_USES_ODMIMAGE
+$(error TARGET_COPY_OUT_ODM must be set to 'odm' to use an odm image)
+endif
+
+###########################################
 # Ensure that only TARGET_RECOVERY_UPDATER_LIBS *or* AB_OTA_UPDATER is set.
 TARGET_RECOVERY_UPDATER_LIBS ?=
 AB_OTA_UPDATER ?=
@@ -839,32 +871,58 @@
   $(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
-ifeq ($(TARGET_IS_64_BIT),true)
-TARGET_OUT_ODM_SHARED_LIBRARIES := $(TARGET_OUT_ODM)/lib64
+ifneq ($(filter address,$(SANITIZE_TARGET)),)
+target_out_odm_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/odm
+ifeq ($(SANITIZE_LITE),true)
+# When using SANITIZE_LITE, APKs must not be packaged with sanitized libraries, as they will not
+# work with unsanitized app_process. For simplicity, generate APKs into /data/asan/.
+target_out_odm_app_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/odm
 else
-TARGET_OUT_ODM_SHARED_LIBRARIES := $(TARGET_OUT_ODM)/lib
+target_out_odm_app_base := $(TARGET_OUT_ODM)
 endif
-TARGET_OUT_ODM_APPS := $(TARGET_OUT_ODM)/app
+else
+target_out_odm_shared_libraries_base := $(TARGET_OUT_ODM)
+target_out_odm_app_base := $(TARGET_OUT_ODM)
+endif
+
+TARGET_OUT_ODM_EXECUTABLES := $(TARGET_OUT_ODM)/bin
+TARGET_OUT_ODM_OPTIONAL_EXECUTABLES := $(TARGET_OUT_ODM)/xbin
+ifeq ($(TARGET_IS_64_BIT),true)
+TARGET_OUT_ODM_SHARED_LIBRARIES := $(target_out_odm_shared_libraries_base)/lib64
+else
+TARGET_OUT_ODM_SHARED_LIBRARIES := $(target_out_odm_shared_libraries_base)/lib
+endif
+TARGET_OUT_ODM_RENDERSCRIPT_BITCODE := $(TARGET_OUT_ODM_SHARED_LIBRARIES)
+TARGET_OUT_ODM_JAVA_LIBRARIES := $(TARGET_OUT_ODM)/framework
+TARGET_OUT_ODM_APPS := $(target_out_odm_app_base)/app
+TARGET_OUT_ODM_APPS_PRIVILEGED := $(target_out_odm_app_base)/priv-app
 TARGET_OUT_ODM_ETC := $(TARGET_OUT_ODM)/etc
 .KATI_READONLY := \
   TARGET_OUT_ODM \
   TARGET_OUT_ODM_EXECUTABLES \
+  TARGET_OUT_ODM_OPTIONAL_EXECUTABLES \
   TARGET_OUT_ODM_SHARED_LIBRARIES \
+  TARGET_OUT_ODM_RENDERSCRIPT_BITCODE \
+  TARGET_OUT_ODM_JAVA_LIBRARIES \
   TARGET_OUT_ODM_APPS \
+  TARGET_OUT_ODM_APPS_PRIVILEGED \
   TARGET_OUT_ODM_ETC
 
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_EXECUTABLES := $(TARGET_OUT_ODM_EXECUTABLES)
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES := $(TARGET_OUT_ODM)/lib/$(TARGET_2ND_ARCH)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES := $(target_out_odm_shared_libraries_base)/lib/$(TARGET_2ND_ARCH)
 else
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES := $(TARGET_OUT_ODM)/lib
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES := $(target_out_odm_shared_libraries_base)/lib
 endif
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_RENDERSCRIPT_BITCODE := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_APPS := $(TARGET_OUT_ODM_APPS)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_APPS_PRIVILEGED := $(TARGET_OUT_ODM_APPS_PRIVILEGED)
 .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_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_RENDERSCRIPT_BITCODE \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_APPS \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_APPS_PRIVILEGED
 
 TARGET_OUT_PRODUCT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_PRODUCT)
 TARGET_OUT_PRODUCT_EXECUTABLES := $(TARGET_OUT_PRODUCT)/bin
diff --git a/core/java.mk b/core/java.mk
index 768860b..d428eb2 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -15,10 +15,6 @@
 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))
 
@@ -73,7 +69,6 @@
 full_classes_compiled_jar := $(intermediates.COMMON)/classes-full-debug.jar
 full_classes_processed_jar := $(intermediates.COMMON)/classes-processed.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
 built_dex_intermediate := $(intermediates.COMMON)/dex/classes.dex
 built_dex_hiddenapi := $(intermediates.COMMON)/dex-hiddenapi/classes.dex
@@ -97,7 +92,6 @@
     $(full_classes_jarjar_jar) \
     $(full_classes_jar) \
     $(full_classes_combined_jar) \
-    $(full_classes_proguard_jar) \
     $(built_dex_intermediate) \
     $(built_dex) \
     $(full_classes_stubs_jar) \
@@ -405,12 +399,7 @@
 endif
 endif
 
-ifeq ($(USE_R8),true)
-proguard_jars_prefix := -libraryjars
-else
-proguard_jars_prefix := -systemjars
-endif
-legacy_proguard_flags := $(addprefix $(proguard_jars_prefix) ,$(my_proguard_sdk_raise) \
+legacy_proguard_flags := $(addprefix -libraryjars ,$(my_proguard_sdk_raise) \
   $(filter-out $(my_proguard_sdk_raise), \
     $(full_java_bootclasspath_libs) \
     $(full_shared_java_header_libs)))
@@ -477,9 +466,7 @@
 endif # LOCAL_INSTRUMENTATION_FOR
 
 proguard_flag_files := $(addprefix $(LOCAL_PATH)/, $(LOCAL_PROGUARD_FLAG_FILES))
-ifeq ($(LOCAL_USE_R8),true)
 proguard_flag_files += $(addprefix $(LOCAL_PATH)/, $(LOCAL_R8_FLAG_FILES))
-endif # LOCAL_USE_R8
 LOCAL_PROGUARD_FLAGS += $(addprefix -include , $(proguard_flag_files))
 
 ifdef LOCAL_TEST_MODULE_TO_PROGUARD_WITH
@@ -489,60 +476,33 @@
 endif
 
 ifneq ($(filter obfuscation,$(LOCAL_PROGUARD_ENABLED)),)
-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) $(proguard_configuration)
 endif
-endif
-
-# If R8 is not enabled run Proguard.
-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 # !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 # !LOCAL_USE_R8
 
 else  # LOCAL_PROGUARD_ENABLED not defined
 proguard_flag_files :=
-full_classes_proguard_jar := $(full_classes_pre_proguard_jar)
 endif # LOCAL_PROGUARD_ENABLED defined
 
 ifneq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
 $(built_dex_intermediate): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
 
-my_r8 :=
 ifdef LOCAL_PROGUARD_ENABLED
-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_proguard_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) $(legacy_proguard_lib_deps) $(R8_COMPAT_PROGUARD)
+  $(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_pre_proguard_jar) $(extra_input_jar) $(my_proguard_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) $(legacy_proguard_lib_deps) $(R8_COMPAT_PROGUARD)
 	$(transform-jar-to-dex-r8)
-endif # LOCAL_USE_R8
-endif # LOCAL_PROGUARD_ENABLED
-
-ifndef my_r8
-$(built_dex_intermediate): $(full_classes_proguard_jar) $(DX) $(ZIP2ZIP)
+else # !LOCAL_PROGUARD_ENABLED
+  $(built_dex_intermediate): $(full_classes_pre_proguard_jar) $(DX) $(ZIP2ZIP)
 	$(transform-classes.jar-to-dex)
 endif
 
 ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),) # is_boot_jar
   # Derive API greylist from the classes jar.
-  # We use full_classes_proguard_jar here, as that is what is converted to dex
-  # later on. The difference is academic currently, as we don't proguard any
+  # We use full_classes_pre_proguard_jar here, as that is what is converted to
+  # dex later on. The difference is academic currently, as we don't proguard any
   # bootclasspath code at the moment. If we were to do that, we should add keep
   # rules for all members with the @UnsupportedAppUsage annotation.
-  $(eval $(call hiddenapi-generate-greylist-txt,$(full_classes_proguard_jar),$(greylist_txt)))
+  $(eval $(call hiddenapi-generate-greylist-txt,$(full_classes_pre_proguard_jar),$(greylist_txt)))
   LOCAL_INTERMEDIATE_TARGETS += $(greylist_txt)
   $(eval $(call hiddenapi-copy-dex-files,$(built_dex_intermediate),$(built_dex_hiddenapi)))
   built_dex_copy_from := $(built_dex_hiddenapi)
diff --git a/core/java_common.mk b/core/java_common.mk
index d63c15f..e1ec30b 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -6,6 +6,10 @@
 my_soong_problems += dotdot_srcs
 endif
 
+ifneq (,$(LOCAL_JNI_SHARED_LIBRARIES))
+my_soong_problems += jni_libs
+endif
+
 ###########################################################
 ## Java version
 ###########################################################
@@ -487,6 +491,21 @@
 ALL_MODULES.$(my_register_name).INTERMEDIATE_SOURCE_DIR := \
     $(ALL_MODULES.$(my_register_name).INTERMEDIATE_SOURCE_DIR) $(LOCAL_INTERMEDIATE_SOURCE_DIR)
 
+
+##########################################################
+# Copy NOTICE files of transitive static dependencies
+# 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,$(LOCAL_STATIC_JAVA_LIBRARIES), \
+      NOTICE-$(if $(LOCAL_IS_HOST_MODULE),HOST,TARGET)-JAVA_LIBRARIES-$(lib))
+else
+installed_static_library_notice_file_targets :=
+endif
+
+$(notice_target): | $(installed_static_library_notice_file_targets)
+$(LOCAL_INSTALLED_MODULE): | $(notice_target)
+
 ###########################################################
 # Verify that all libraries are safe to use
 ###########################################################
diff --git a/core/java_host_test_config_template.xml b/core/java_host_test_config_template.xml
new file mode 100644
index 0000000..d808001
--- /dev/null
+++ b/core/java_host_test_config_template.xml
@@ -0,0 +1,23 @@
+<?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-junit" />
+    <test class="com.android.tradefed.testtype.HostTest" >
+        <option name="jar" value="{MODULE}.jar" />
+    </test>
+</configuration>
diff --git a/core/java_library.mk b/core/java_library.mk
index 1b914f5..9a7422d 100644
--- a/core/java_library.mk
+++ b/core/java_library.mk
@@ -57,9 +57,9 @@
 ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
 # There are some dependencies outside the build system that assume classes.jar
 # is available as javalib.jar so copy it there too.
-$(eval $(call copy-one-file,$(full_classes_proguard_jar),$(common_javalib.jar)))
+$(eval $(call copy-one-file,$(full_classes_pre_proguard_jar),$(common_javalib.jar)))
 
-$(eval $(call copy-one-file,$(full_classes_proguard_jar),$(LOCAL_BUILT_MODULE)))
+$(eval $(call copy-one-file,$(full_classes_pre_proguard_jar),$(LOCAL_BUILT_MODULE)))
 
 else # !LOCAL_IS_STATIC_JAVA_LIBRARY
 
diff --git a/core/java_test_config_template.xml b/core/java_test_config_template.xml
new file mode 100644
index 0000000..4ee5b07
--- /dev/null
+++ b/core/java_test_config_template.xml
@@ -0,0 +1,30 @@
+<?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-junit" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+        <option name="push" value="cts-dalvik-device-test-runner.jar->/data/local/tmp/{MODULE}/cts-dalvik-device-test-runner.jar" />
+        <option name="push" value="{MODULE}.jar->/data/local/tmp/{MODULE}/{MODULE}.jar" />
+    </target_preparer>
+    <test class="com.android.compatibility.testtype.DalvikTest" >
+        <option name="run-name" value="{MODULE}" />
+        <option name="classpath" value="/data/local/tmp/{MODULE}/{MODULE}.jar" />
+        <option name="classpath" value="/data/local/tmp/{MODULE}/cts-dalvik-device-test-runner.jar" />
+    </test>
+</configuration>
diff --git a/core/local_vndk.mk b/core/local_vndk.mk
index 3677d40..198e361 100644
--- a/core/local_vndk.mk
+++ b/core/local_vndk.mk
@@ -1,5 +1,5 @@
 
-#Set LOCAL_USE_VNDK for modules going into vendor partition, except for host modules
+#Set LOCAL_USE_VNDK for modules going into vendor or odm partition, except for host modules
 #If LOCAL_SDK_VERSION is set, thats a more restrictive set, so they dont need LOCAL_USE_VNDK
 ifndef LOCAL_IS_HOST_MODULE
 ifndef LOCAL_SDK_VERSION
diff --git a/core/main.mk b/core/main.mk
index 07042d2..5eebe1e 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1202,6 +1202,9 @@
 .PHONY: productservicesimage
 productservicesimage: $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET)
 
+.PHONY: odmimage
+odmimage: $(INSTALLED_ODMIMAGE_TARGET)
+
 .PHONY: systemotherimage
 systemotherimage: $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)
 
@@ -1221,6 +1224,7 @@
 .PHONY: droidcore
 droidcore: files \
     systemimage \
+    $(INSTALLED_RAMDISK_TARGET) \
     $(INSTALLED_BOOTIMAGE_TARGET) \
     $(INSTALLED_RECOVERYIMAGE_TARGET) \
     $(INSTALLED_VBMETAIMAGE_TARGET) \
@@ -1228,12 +1232,15 @@
     $(INSTALLED_CACHEIMAGE_TARGET) \
     $(INSTALLED_BPTIMAGE_TARGET) \
     $(INSTALLED_VENDORIMAGE_TARGET) \
+    $(INSTALLED_ODMIMAGE_TARGET) \
     $(INSTALLED_PRODUCTIMAGE_TARGET) \
     $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
     $(INSTALLED_FILES_FILE) \
     $(INSTALLED_FILES_JSON) \
     $(INSTALLED_FILES_FILE_VENDOR) \
     $(INSTALLED_FILES_JSON_VENDOR) \
+    $(INSTALLED_FILES_FILE_ODM) \
+    $(INSTALLED_FILES_JSON_ODM) \
     $(INSTALLED_FILES_FILE_PRODUCT) \
     $(INSTALLED_FILES_JSON_PRODUCT) \
     $(INSTALLED_FILES_FILE_PRODUCT_SERVICES) \
@@ -1309,6 +1316,8 @@
     $(INSTALLED_FILES_JSON) \
     $(INSTALLED_FILES_FILE_VENDOR) \
     $(INSTALLED_FILES_JSON_VENDOR) \
+    $(INSTALLED_FILES_FILE_ODM) \
+    $(INSTALLED_FILES_JSON_ODM) \
     $(INSTALLED_FILES_FILE_PRODUCT) \
     $(INSTALLED_FILES_JSON_PRODUCT) \
     $(INSTALLED_FILES_FILE_PRODUCT_SERVICES) \
diff --git a/core/native_host_test_config_template.xml b/core/native_host_test_config_template.xml
new file mode 100644
index 0000000..c0fcd1a
--- /dev/null
+++ b/core/native_host_test_config_template.xml
@@ -0,0 +1,23 @@
+<?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="null-device" value="true" />
+    <test class="com.android.tradefed.testtype.HostGTest" >
+        <option name="module-name" value="{MODULE}" />
+    </test>
+</configuration>
+
diff --git a/core/product-graph.mk b/core/product-graph.mk
index 696aabf..1efc687 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -106,6 +106,7 @@
 	$(hide) echo 'PRODUCT_SYSTEM_DEFAULT_PROPERTIES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SYSTEM_DEFAULT_PROPERTIES)' >> $$@
 	$(hide) echo 'PRODUCT_PRODUCT_PROPERTIES=$$(PRODUCTS.$(strip $(1)).PRODUCT_PRODUCT_PROPERTIES)' >> $$@
 	$(hide) echo 'PRODUCT_PRODUCT_SERVICES_PROPERTIES=$$(PRODUCTS.$(strip $(1)).PRODUCT_PRODUCT_SERVICES_PROPERTIES)' >> $$@
+	$(hide) echo 'PRODUCT_ODM_PROPERTIES=$$(PRODUCTS.$(strip $(1)).PRODUCT_ODM_PROPERTIES)' >> $$@
 	$(hide) echo 'PRODUCT_CHARACTERISTICS=$$(PRODUCTS.$(strip $(1)).PRODUCT_CHARACTERISTICS)' >> $$@
 	$(hide) echo 'PRODUCT_COPY_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_COPY_FILES)' >> $$@
 	$(hide) echo 'PRODUCT_OTA_PUBLIC_KEYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_OTA_PUBLIC_KEYS)' >> $$@
diff --git a/core/product.mk b/core/product.mk
index ddf774f..8c8246e 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -129,6 +129,7 @@
     PRODUCT_DEFAULT_PROPERTY_OVERRIDES \
     PRODUCT_PRODUCT_PROPERTIES \
     PRODUCT_PRODUCT_SERVICES_PROPERTIES \
+    PRODUCT_ODM_PROPERTIES \
     PRODUCT_CHARACTERISTICS \
     PRODUCT_COPY_FILES \
     PRODUCT_OTA_PUBLIC_KEYS \
@@ -169,6 +170,7 @@
     PRODUCT_VENDOR_VERITY_PARTITION \
     PRODUCT_PRODUCT_VERITY_PARTITION \
     PRODUCT_PRODUCT_SERVICES_VERITY_PARTITION \
+    PRODUCT_ODM_VERITY_PARTITION \
     PRODUCT_SYSTEM_SERVER_DEBUG_INFO \
     PRODUCT_OTHER_JAVA_DEBUG_INFO \
     PRODUCT_DEX_PREOPT_MODULE_CONFIGS \
@@ -185,6 +187,7 @@
     PRODUCT_VENDOR_BASE_FS_PATH \
     PRODUCT_PRODUCT_BASE_FS_PATH \
     PRODUCT_PRODUCT_SERVICES_BASE_FS_PATH \
+    PRODUCT_ODM_BASE_FS_PATH \
     PRODUCT_SHIPPING_API_LEVEL \
     VENDOR_PRODUCT_RESTRICT_VENDOR_FILES \
     VENDOR_EXCEPTION_MODULES \
@@ -206,6 +209,7 @@
     PRODUCT_USE_DYNAMIC_PARTITION_SIZE \
     PRODUCT_BUILD_SUPER_PARTITION \
     PRODUCT_USE_FASTBOOTD \
+    PRODUCT_FORCE_PRODUCT_MODULES_TO_SYSTEM_PARTITION \
 
 define dump-product
 $(info ==== $(1) ====)\
@@ -386,6 +390,8 @@
 	BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE \
 	BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE \
 	BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE \
+	BOARD_ODMIMAGE_PARTITION_SIZE \
+	BOARD_ODMIMAGE_FILE_SYSTEM_TYPE \
 	BOARD_INSTALLER_CMDLINE \
 
 
@@ -398,6 +404,7 @@
 _product_stash_var_list += \
 	BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE \
 	BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE \
+	BOARD_ODMIMAGE_PARTITION_RESERVED_SIZE \
 	BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE \
 	BOARD_PRODUCT_SERVICESIMAGE_PARTITION_RESERVED_SIZE \
 	BOARD_SUPER_PARTITION_SIZE \
diff --git a/core/product_config.mk b/core/product_config.mk
index b5f2896..c5d182a 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -534,3 +534,9 @@
     $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_USE_FASTBOOTD)),\
     $(PRODUCT_USE_LOGICAL_PARTITIONS))
 .KATI_READONLY := PRODUCT_USE_FASTBOOTD
+
+# List of modules that should be forcefully unmarked from being LOCAL_PRODUCT_MODULE, and hence
+# installed on /system directory by default.
+PRODUCT_FORCE_PRODUCT_MODULES_TO_SYSTEM_PARTITION := \
+    $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_FORCE_PRODUCT_MODULES_TO_SYSTEM_PARTITION))
+.KATI_READONLY := PRODUCT_FORCE_PRODUCT_MODULES_TO_SYSTEM_PARTITION
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index fcd3baf..241a2f4 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -104,3 +104,5 @@
       $(LOCAL_EXPORT_PACKAGE_RESOURCES), \
       $(LOCAL_SOONG_RRO_DIRS))
 endif
+
+SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 210ee5f..92b97bd 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -161,3 +161,5 @@
 	$(if $(PRIVATE_EXPORTED_SDK_LIBS),\
 		$(hide) echo $(PRIVATE_EXPORTED_SDK_LIBS) | tr ' ' '\n' > $@,\
 		$(hide) touch $@)
+
+SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
diff --git a/core/tasks/general-tests.mk b/core/tasks/general-tests.mk
index c7f1dc9..b28f8ef 100644
--- a/core/tasks/general-tests.mk
+++ b/core/tasks/general-tests.mk
@@ -14,22 +14,37 @@
 
 .PHONY: general-tests
 
-general-tests-zip := $(PRODUCT_OUT)/general-tests.zip
+general_tests_tools := \
+    $(HOST_OUT_JAVA_LIBRARIES)/cts-tradefed.jar \
+    $(HOST_OUT_JAVA_LIBRARIES)/compatibility-host-util.jar \
+
+intermediates_dir := $(call intermediates-dir-for,PACKAGING,general-tests)
+general_tests_zip := $(PRODUCT_OUT)/general-tests.zip
 # Create an artifact to include a list of test config files in general-tests.
-general-tests-list-zip := $(PRODUCT_OUT)/general-tests_list.zip
-$(general-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(general-tests-list-zip)
-$(general-tests-zip) : PRIVATE_general_tests_list := $(PRODUCT_OUT)/general-tests_list
+general_tests_list_zip := $(PRODUCT_OUT)/general-tests_list.zip
+$(general_tests_zip) : PRIVATE_general_tests_list_zip := $(general_tests_list_zip)
+$(general_tests_zip) : .KATI_IMPLICIT_OUTPUTS := $(general_tests_list_zip)
+$(general_tests_zip) : PRIVATE_TOOLS := $(general_tests_tools)
+$(general_tests_zip) : PRIVATE_INTERMEDIATES_DIR := $(intermediates_dir)
+$(general_tests_zip) : $(COMPATIBILITY.general-tests.FILES) $(general_tests_tools) $(SOONG_ZIP)
+	rm -rf $(PRIVATE_INTERMEDIATES_DIR)
+	mkdir -p $(PRIVATE_INTERMEDIATES_DIR) $(PRIVATE_INTERMEDIATES_DIR)/tools
+	echo $(sort $(COMPATIBILITY.general-tests.FILES)) | tr " " "\n" > $(PRIVATE_INTERMEDIATES_DIR)/list
+	grep $(HOST_OUT_TESTCASES) $(PRIVATE_INTERMEDIATES_DIR)/list > $(PRIVATE_INTERMEDIATES_DIR)/host.list || true
+	grep $(TARGET_OUT_TESTCASES) $(PRIVATE_INTERMEDIATES_DIR)/list > $(PRIVATE_INTERMEDIATES_DIR)/target.list || true
+	cp -fp $(PRIVATE_TOOLS) $(PRIVATE_INTERMEDIATES_DIR)/tools/
+	$(SOONG_ZIP) -d -o $@ \
+	  -P host -C $(PRIVATE_INTERMEDIATES_DIR) -D $(PRIVATE_INTERMEDIATES_DIR)/tools \
+	  -P host -C $(HOST_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/host.list \
+	  -P target -C $(PRODUCT_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/target.list
+	grep -e .*.config$$ $(PRIVATE_INTERMEDIATES_DIR)/host.list | sed s%$(HOST_OUT)%host%g > $(PRIVATE_INTERMEDIATES_DIR)/general-tests_list
+	grep -e .*.config$$ $(PRIVATE_INTERMEDIATES_DIR)/target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_INTERMEDIATES_DIR)/general-tests_list
+	$(SOONG_ZIP) -d -o $(general_tests_list_zip) -C $(PRIVATE_INTERMEDIATES_DIR) -f $(PRIVATE_INTERMEDIATES_DIR)/general-tests_list
 
-$(general-tests-zip) : $(COMPATIBILITY.general-tests.FILES) $(SOONG_ZIP)
-	echo $(sort $(COMPATIBILITY.general-tests.FILES)) | tr " " "\n" > $@.list
-	grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true
-	grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
-	$(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list -P target -C $(PRODUCT_OUT) -l $@-target.list
-	rm -f $(PRIVATE_general_tests_list)
-	$(hide) grep -e .*.config$$ $@-host.list | sed s%$(HOST_OUT)%host%g > $(PRIVATE_general_tests_list)
-	$(hide) grep -e .*.config$$ $@-target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_general_tests_list)
-	$(hide) $(SOONG_ZIP) -d -o $(general-tests-list-zip) -C $(dir $@) -f $(PRIVATE_general_tests_list)
-	rm -f $@.list $@-host.list $@-target.list $(PRIVATE_general_tests_list)
+general-tests: $(general_tests_zip)
+$(call dist-for-goals, general-tests, $(general_tests_zip) $(general_tests_list_zip))
 
-general-tests: $(general-tests-zip)
-$(call dist-for-goals, general-tests, $(general-tests-zip) $(general-tests-list-zip))
+intermediates_dir :=
+general_tests_tools :=
+general_tests_zip :=
+general_tests_list_zip :=
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index b45526f..38149d7 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -13,6 +13,7 @@
 			'"installed": [$(foreach w,$(sort $(ALL_MODULES.$(m).INSTALLED)),"$(w)", )], ' \
 			'"compatibility_suites": [$(foreach w,$(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES)),"$(w)", )], ' \
 			'"auto_test_config": [$(ALL_MODULES.$(m).auto_test_config)], ' \
+			'"module_name": ["$(ALL_MODULES.$(m).MODULE_NAME)"], ' \
 			'},\n' \
 	 ) | sed -e 's/, *\]/]/g' -e 's/, *\}/ }/g' -e '$$s/,$$//' >> $@
 	$(hide) echo '}' >> $@
diff --git a/help.sh b/help.sh
index ad22253..3ecdbc2 100755
--- a/help.sh
+++ b/help.sh
@@ -42,6 +42,8 @@
                             Stands for "Product, NO Dependencies"
     psnod                   Quickly rebuild the product-services image from built packages
                             Stands for "ProductServices, NO Dependencies"
+    onod                    Quickly rebuild the odm image from built packages
+                            Stands for "ODM, NO Dependencies"
 
 
 So, for example, you could run:
diff --git a/target/board/BoardConfigEmuCommon.mk b/target/board/BoardConfigEmuCommon.mk
index e8a562a..ca2176c 100644
--- a/target/board/BoardConfigEmuCommon.mk
+++ b/target/board/BoardConfigEmuCommon.mk
@@ -36,5 +36,3 @@
 
 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
index 47107a0..c1f3627 100644
--- a/target/board/BoardConfigGsiCommon.mk
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -9,7 +9,6 @@
 # Some vendors' bootloaders don't work properly with raw format images. So
 # we explicit specify this need below (even though it's the current default).
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := false
-TARGET_USES_MKE2FS := true
 
 # Enable dyanmic system image size and reserved 64MB in it.
 BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE := 67108864
diff --git a/target/board/treble_common.mk b/target/board/treble_common.mk
index 7da7b30..daa0f4c 100644
--- a/target/board/treble_common.mk
+++ b/target/board/treble_common.mk
@@ -34,7 +34,6 @@
 TARGET_USERIMAGES_USE_EXT4 := true
 TARGET_USERIMAGES_USE_F2FS := true
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := false
-TARGET_USES_MKE2FS := true
 
 # Enable dyanmic system image size and reserved 64MB in it.
 BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE := 67108864
@@ -62,5 +61,3 @@
 $(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/base_vendor.mk b/target/product/base_vendor.mk
index 8aa5b8b..1b25f27 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -17,6 +17,8 @@
 # Base modules and settings for recovery.
 PRODUCT_PACKAGES += \
     adbd.recovery \
+    android.hardware.health@2.0-impl-default.recovery \
+    init_second_stage.recovery \
     ld.config.recovery.txt \
     linker.recovery \
     recovery \
diff --git a/target/product/full_base.mk b/target/product/full_base.mk
index c390ffd..447576c 100644
--- a/target/product/full_base.mk
+++ b/target/product/full_base.mk
@@ -24,13 +24,7 @@
     WAPPushManager
 
 PRODUCT_PACKAGES += \
-    Galaxy4 \
-    HoloSpiralWallpaper \
-    LiveWallpapers \
     LiveWallpapersPicker \
-    MagicSmokeWallpapers \
-    NoiseField \
-    PhaseBeam \
     PhotoTable
 
 # Bluetooth:
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index 74a3b19..a0d14c6 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -27,21 +27,6 @@
 
 _base_mk_whitelist := \
   recovery/root/etc/mke2fs.conf \
-  recovery/root/system/bin/init \
-  recovery/root/system/bin/ueventd \
-  recovery/root/system/lib64/ld-android.so \
-  recovery/root/system/lib64/libbase.so \
-  recovery/root/system/lib64/libc++.so \
-  recovery/root/system/lib64/libc.so \
-  recovery/root/system/lib64/libcrypto.so \
-  recovery/root/system/lib64/libcutils.so \
-  recovery/root/system/lib64/libdl.so \
-  recovery/root/system/lib64/liblog.so \
-  recovery/root/system/lib64/libm.so \
-  recovery/root/system/lib64/libpackagelistparser.so \
-  recovery/root/system/lib64/libpcre2.so \
-  recovery/root/system/lib64/libselinux.so \
-  recovery/root/system/lib64/libz.so \
 
 _my_whitelist := $(_base_mk_whitelist)
 
diff --git a/target/product/vndk/current.txt b/target/product/vndk/current.txt
index 32fd5da..81d04db 100644
--- a/target/product/vndk/current.txt
+++ b/target/product/vndk/current.txt
@@ -115,11 +115,13 @@
 VNDK-core: android.hardware.power@1.0.so
 VNDK-core: android.hardware.power@1.1.so
 VNDK-core: android.hardware.power@1.2.so
+VNDK-core: android.hardware.power@1.3.so
 VNDK-core: android.hardware.radio.config@1.0.so
 VNDK-core: android.hardware.radio.deprecated@1.0.so
 VNDK-core: android.hardware.radio@1.0.so
 VNDK-core: android.hardware.radio@1.1.so
 VNDK-core: android.hardware.radio@1.2.so
+VNDK-core: android.hardware.radio@1.3.so
 VNDK-core: android.hardware.secure_element@1.0.so
 VNDK-core: android.hardware.sensors@1.0.so
 VNDK-core: android.hardware.soundtrigger@2.0.so
@@ -152,6 +154,7 @@
 VNDK-core: android.hidl.token@1.0-utils.so
 VNDK-core: android.system.net.netd@1.0.so
 VNDK-core: android.system.net.netd@1.1.so
+VNDK-core: android.system.suspend@1.0.so
 VNDK-core: android.system.wifi.keystore@1.0.so
 VNDK-core: libadf.so
 VNDK-core: libaudioroute.so
@@ -232,7 +235,6 @@
 VNDK-core: libstagefright_soft_vpxdec.so
 VNDK-core: libstagefright_soft_vpxenc.so
 VNDK-core: libstagefright_xmlparser.so
-VNDK-core: libsuspend.so
 VNDK-core: libsysutils.so
 VNDK-core: libtinyalsa.so
 VNDK-core: libtinyxml2.so
diff --git a/tools/OWNERS b/tools/OWNERS
index 7a23adc..7d666f1 100644
--- a/tools/OWNERS
+++ b/tools/OWNERS
@@ -1,2 +1 @@
-per-file warn.py = chh@google.com
-per-file checkowners.py = chh@google.com
+per-file warn.py,checkowners.py = chh@google.com
diff --git a/tools/checkowners.py b/tools/checkowners.py
index 54198a7..8568ccf 100755
--- a/tools/checkowners.py
+++ b/tools/checkowners.py
@@ -35,22 +35,31 @@
     echo('Checking email address: ' + address)
     result = urllib2.urlopen(request).read()
     checked_addresses[address] = result.find('"_account_id":') >= 0
+    if checked_addresses[address]:
+      echo('Found email address: ' + address)
   return checked_addresses[address]
 
 
+def check_address(fname, num, address):
+  if find_address(address):
+    return 0
+  print '%s:%d: ERROR: unknown email address: %s' % (fname, num, address)
+  return 1
+
+
 def main():
   # One regular expression to check all valid lines.
   noparent = 'set +noparent'
   email = '([^@ ]+@[^ @]+|\\*)'
-  directive = '(%s|%s)' % (email, noparent)
+  emails = '(%s( *, *%s)*)' % (email, email)
+  directive = '(%s|%s)' % (emails, noparent)
   glob = '[a-zA-Z0-9_\\.\\-\\*\\?]+'
-  perfile = 'per-file +' + glob + ' *= *' + directive
+  globs = '(%s( *, *%s)*)' % (glob, glob)
+  perfile = 'per-file +' + globs + ' *= *' + directive
   pats = '(|%s|%s|%s)$' % (noparent, email, perfile)
   patterns = re.compile(pats)
-
-  # One pattern to capture email address.
-  email_address = '.*(@| |=|^)([^@ =]+@[^ @]+)'
-  address_pattern = re.compile(email_address)
+  address_pattern = re.compile('([^@ ]+@[^ @]+)')
+  perfile_pattern = re.compile('per-file +.*=(.*)')
 
   error = 0
   for fname in args.owners:
@@ -60,17 +69,16 @@
       num += 1
       stripped_line = re.sub('#.*$', '', line).strip()
       if not patterns.match(stripped_line):
-        error = 1
-        print('%s:%d: ERROR: unknown line [%s]'
-              % (fname, num, line.strip()))
-      elif args.check_address and address_pattern.match(stripped_line):
-        address = address_pattern.match(stripped_line).group(2)
-        if find_address(address):
-          echo('Found email address: ' + address)
-        else:
-          error = 1
-          print('%s:%d: ERROR: unknown email address: %s'
-                % (fname, num, address))
+        error += 1
+        print '%s:%d: ERROR: unknown line [%s]' % (fname, num, line.strip())
+      elif args.check_address:
+        if perfile_pattern.match(stripped_line):
+          for addr in perfile_pattern.match(stripped_line).group(1).split(','):
+            a = addr.strip()
+            if a and a != '*':
+              error += check_address(fname, num, addr.strip())
+        elif address_pattern.match(stripped_line):
+          error += check_address(fname, num, stripped_line)
   sys.exit(error)
 
 if __name__ == '__main__':
diff --git a/tools/device_buildinfo.sh b/tools/device_buildinfo.sh
new file mode 100755
index 0000000..0782565
--- /dev/null
+++ b/tools/device_buildinfo.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+partition="$1"
+
+if [ "$#" -ne 1 ]; then
+  echo "Usage: $0 <vendor|odm>" 1>&2
+  exit 1
+fi
+
+if [ "$partition" != "vendor" ] && [ "$partition" != "odm" ]; then
+  echo "Unknown partition name: $partition" 1>&2
+  exit 1
+fi
+
+echo "# begin build properties"
+echo "# autogenerated by device_buildinfo.sh"
+
+echo "ro.${partition}.build.id=$BUILD_ID"
+echo "ro.${partition}.build.version.incremental=$BUILD_NUMBER"
+echo "ro.${partition}.build.version.sdk=$PLATFORM_SDK_VERSION"
+echo "ro.${partition}.build.version.release=$PLATFORM_VERSION"
+echo "ro.${partition}.build.type=$TARGET_BUILD_TYPE"
+echo "ro.${partition}.build.tags=$BUILD_VERSION_TAGS"
+
+echo "ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"
+echo "ro.board.platform=$TARGET_BOARD_PLATFORM"
+
+echo "ro.product.${partition}.manufacturer=$PRODUCT_MANUFACTURER"
+echo "ro.product.${partition}.model=$PRODUCT_MODEL"
+echo "ro.product.${partition}.brand=$PRODUCT_BRAND"
+echo "ro.product.${partition}.name=$PRODUCT_NAME"
+echo "ro.product.${partition}.device=$TARGET_DEVICE"
+
+echo "# end build properties"
diff --git a/tools/findleaves.py b/tools/findleaves.py
index f152a87..97302e9 100755
--- a/tools/findleaves.py
+++ b/tools/findleaves.py
@@ -103,7 +103,7 @@
       prune.append(p)
     elif arg.startswith("--dir="):
       d = arg[len("--dir="):]
-      if len(p) == 0:
+      if len(d) == 0:
         usage()
       dirlist.append(d)
     else:
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index fb4b882..6d2c499 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -73,12 +73,14 @@
 OPTIONS.is_signing = False
 
 # Partitions that should have their care_map added to META/care_map.txt.
-PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'product-services')
+PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'product-services',
+                            'odm')
 # Use a fixed timestamp (01/01/2009 00:00:00 UTC) for files when packaging
 # images. (b/24377993, b/80600931)
 FIXED_FILE_TIMESTAMP = (datetime.datetime(2009, 1, 1, 0, 0, 0, 0, None)
                         - datetime.datetime.utcfromtimestamp(0)).total_seconds()
 
+
 class OutputFile(object):
   def __init__(self, output_zip, input_dir, prefix, name):
     self._output_zip = output_zip
@@ -215,6 +217,22 @@
   return img.name
 
 
+def AddOdm(output_zip):
+  """Turn the contents of ODM into an odm image and store it in output_zip."""
+
+  img = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "odm.img")
+  if os.path.exists(img.input_name):
+    print("odm.img already exists; no need to rebuild...")
+    return img.input_name
+
+  block_list = OutputFile(
+      output_zip, OPTIONS.input_tmp, "IMAGES", "odm.map")
+  CreateImage(
+      OPTIONS.input_tmp, OPTIONS.info_dict, "odm", img,
+      block_list=block_list)
+  return img.name
+
+
 def AddDtbo(output_zip):
   """Adds the DTBO image.
 
@@ -527,7 +545,7 @@
 
   Args:
     output_zip: The output zip file (needs to be already open), or None to
-        write images to OPTIONS.input_tmp/.
+        write care_map.txt to OPTIONS.input_tmp/.
     ab_partitions: The list of A/B partitions.
     image_paths: A map from the partition name to the image path.
   """
@@ -545,15 +563,32 @@
       assert os.path.exists(image_path)
       care_map_list += GetCareMap(partition, image_path)
 
-  if care_map_list:
-    care_map_path = "META/care_map.txt"
-    if output_zip and care_map_path not in output_zip.namelist():
-      common.ZipWriteStr(output_zip, care_map_path, '\n'.join(care_map_list))
-    else:
-      with open(os.path.join(OPTIONS.input_tmp, care_map_path), 'w') as fp:
-        fp.write('\n'.join(care_map_list))
-      if output_zip:
-        OPTIONS.replace_updated_files_list.append(care_map_path)
+  if not care_map_list:
+    return
+
+  # Converts the list into proto buf message by calling care_map_generator; and
+  # writes the result to a temp file.
+  temp_care_map_text = common.MakeTempFile(prefix="caremap_text-",
+                                           suffix=".txt")
+  with open(temp_care_map_text, 'w') as text_file:
+    text_file.write('\n'.join(care_map_list))
+
+  temp_care_map = common.MakeTempFile(prefix="caremap-", suffix=".txt")
+  care_map_gen_cmd = (["care_map_generator", temp_care_map_text, temp_care_map])
+  p = common.Run(care_map_gen_cmd, stdout=subprocess.PIPE,
+                 stderr=subprocess.STDOUT)
+  output, _ = p.communicate()
+  assert p.returncode == 0, "Failed to generate the care_map proto message."
+  if OPTIONS.verbose:
+    print(output.rstrip())
+
+  care_map_path = "META/care_map.txt"
+  if output_zip and care_map_path not in output_zip.namelist():
+    common.ZipWrite(output_zip, temp_care_map, arcname=care_map_path)
+  else:
+    shutil.copy(temp_care_map, os.path.join(OPTIONS.input_tmp, care_map_path))
+    if output_zip:
+      OPTIONS.replace_updated_files_list.append(care_map_path)
 
 
 def AddPackRadioImages(output_zip, images):
@@ -631,7 +666,7 @@
 
   has_recovery = OPTIONS.info_dict.get("no_recovery") != "true"
 
-  # {vendor,product,product-services}.img are unlike system.img or
+  # {vendor,odm,product,product-services}.img are unlike system.img or
   # system_other.img. Because it could be built from source, or dropped into
   # target_files.zip as a prebuilt blob. We consider either of them as
   # {vendor,product,product-services}.img being available, which could be
@@ -639,6 +674,9 @@
   has_vendor = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR")) or
                 os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
                                             "vendor.img")))
+  has_odm = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "ODM")) or
+                 os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
+                                             "odm.img")))
   has_product = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "PRODUCT")) or
                  os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
                                              "product.img")))
@@ -727,6 +765,10 @@
     banner("product-services")
     partitions['product-services'] = AddProductServices(output_zip)
 
+  if has_odm:
+    banner("odm")
+    partitions['odm'] = AddOdm(output_zip)
+
   if has_system_other:
     banner("system_other")
     AddSystemOther(output_zip)
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 5b46ab0..86ba1a6 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -931,6 +931,26 @@
     if not copy_prop("product_services_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
     copy_prop("product_services_reserved_size", "partition_reserved_size")
+  elif mount_point == "odm":
+    copy_prop("avb_odm_hashtree_enable", "avb_hashtree_enable")
+    copy_prop("avb_odm_add_hashtree_footer_args",
+              "avb_add_hashtree_footer_args")
+    copy_prop("avb_odm_key_path", "avb_key_path")
+    copy_prop("avb_odm_algorithm", "avb_algorithm")
+    copy_prop("odm_fs_type", "fs_type")
+    copy_prop("odm_size", "partition_size")
+    if not copy_prop("odm_journal_size", "journal_size"):
+      d["journal_size"] = "0"
+    copy_prop("odm_verity_block_device", "verity_block_device")
+    copy_prop("odm_squashfs_compressor", "squashfs_compressor")
+    copy_prop("odm_squashfs_compressor_opt", "squashfs_compressor_opt")
+    copy_prop("odm_squashfs_block_size", "squashfs_block_size")
+    copy_prop("odm_squashfs_disable_4k_align", "squashfs_disable_4k_align")
+    copy_prop("odm_base_fs_file", "base_fs_file")
+    copy_prop("odm_extfs_inode_count", "extfs_inode_count")
+    if not copy_prop("odm_extfs_rsv_pct", "extfs_rsv_pct"):
+      d["extfs_rsv_pct"] = "0"
+    copy_prop("odm_reserved_size", "partition_reserved_size")
   elif mount_point == "oem":
     copy_prop("fs_type", "fs_type")
     copy_prop("oem_size", "partition_size")
@@ -976,6 +996,8 @@
     copy_prop(size_property, "system_size")
   elif mount_point == "vendor":
     copy_prop(size_property, "vendor_size")
+  elif mount_point == "odm":
+    copy_prop(size_property, "odm_size")
   elif mount_point == "product":
     copy_prop(size_property, "product_size")
   elif mount_point == "product-services":
@@ -1017,6 +1039,8 @@
       mount_point = "cache"
     elif image_filename == "vendor.img":
       mount_point = "vendor"
+    elif image_filename == "odm.img":
+      mount_point = "odm"
     elif image_filename == "oem.img":
       mount_point = "oem"
     elif image_filename == "product.img":
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 89b4037..bf380bc 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -79,7 +79,7 @@
 
 # The partitions allowed to be signed by AVB (Android verified boot 2.0).
 AVB_PARTITIONS = ('boot', 'recovery', 'system', 'vendor', 'product',
-                  'product-services', 'dtbo')
+                  'product-services', 'dtbo', 'odm')
 
 
 class ErrorCode(object):
diff --git a/tools/releasetools/test_add_img_to_target_files.py b/tools/releasetools/test_add_img_to_target_files.py
index 3f2e5ea..834e989 100644
--- a/tools/releasetools/test_add_img_to_target_files.py
+++ b/tools/releasetools/test_add_img_to_target_files.py
@@ -16,6 +16,7 @@
 
 import os
 import os.path
+import subprocess
 import unittest
 import zipfile
 
@@ -38,6 +39,20 @@
   def tearDown(self):
     common.Cleanup()
 
+  def _verifyCareMap(self, expected, file_name):
+    """Parses the care_map proto; and checks the content in plain text."""
+    text_file = common.MakeTempFile(prefix="caremap-", suffix=".txt")
+
+    # Calls an external binary to convert the proto message.
+    cmd = ["care_map_generator", "--parse_proto", file_name, text_file]
+    p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    output, _ = p.communicate()
+    self.assertEqual(0, p.returncode)
+
+    with open(text_file, 'r') as verify_fp:
+      plain_text = verify_fp.read()
+    self.assertEqual('\n'.join(expected), plain_text)
+
   @staticmethod
   def _create_images(images, prefix):
     """Creates images under OPTIONS.input_tmp/prefix."""
@@ -155,15 +170,10 @@
     AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths)
 
     care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
-    with open(care_map_file, 'r') as verify_fp:
-      care_map = verify_fp.read()
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), 'vendor',
+                RangeSet("0-9").to_string_raw()]
 
-    lines = care_map.split('\n')
-    self.assertEqual(4, len(lines))
-    self.assertEqual('system', lines[0])
-    self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1])
-    self.assertEqual('vendor', lines[2])
-    self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3])
+    self._verifyCareMap(expected, care_map_file)
 
   def test_AddCareMapTxtForAbOta_withNonCareMapPartitions(self):
     """Partitions without care_map should be ignored."""
@@ -173,15 +183,10 @@
         None, ['boot', 'system', 'vendor', 'vbmeta'], image_paths)
 
     care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
-    with open(care_map_file, 'r') as verify_fp:
-      care_map = verify_fp.read()
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), 'vendor',
+                RangeSet("0-9").to_string_raw()]
 
-    lines = care_map.split('\n')
-    self.assertEqual(4, len(lines))
-    self.assertEqual('system', lines[0])
-    self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1])
-    self.assertEqual('vendor', lines[2])
-    self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3])
+    self._verifyCareMap(expected, care_map_file)
 
   def test_AddCareMapTxtForAbOta_withAvb(self):
     """Tests the case for device using AVB."""
@@ -194,15 +199,10 @@
     AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths)
 
     care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
-    with open(care_map_file, 'r') as verify_fp:
-      care_map = verify_fp.read()
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), 'vendor',
+                RangeSet("0-9").to_string_raw()]
 
-    lines = care_map.split('\n')
-    self.assertEqual(4, len(lines))
-    self.assertEqual('system', lines[0])
-    self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1])
-    self.assertEqual('vendor', lines[2])
-    self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3])
+    self._verifyCareMap(expected, care_map_file)
 
   def test_AddCareMapTxtForAbOta_verityNotEnabled(self):
     """No care_map.txt should be generated if verity not enabled."""
@@ -228,15 +228,15 @@
     with zipfile.ZipFile(output_file, 'w') as output_zip:
       AddCareMapTxtForAbOta(output_zip, ['system', 'vendor'], image_paths)
 
+    care_map_name = "META/care_map.txt"
+    temp_dir = common.MakeTempDir()
     with zipfile.ZipFile(output_file, 'r') as verify_zip:
-      care_map = verify_zip.read('META/care_map.txt').decode('ascii')
+      self.assertTrue(care_map_name in verify_zip.namelist())
+      verify_zip.extract(care_map_name, path=temp_dir)
 
-    lines = care_map.split('\n')
-    self.assertEqual(4, len(lines))
-    self.assertEqual('system', lines[0])
-    self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1])
-    self.assertEqual('vendor', lines[2])
-    self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3])
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), 'vendor',
+                RangeSet("0-9").to_string_raw()]
+    self._verifyCareMap(expected, os.path.join(temp_dir, care_map_name))
 
   def test_AddCareMapTxtForAbOta_zipOutput_careMapEntryExists(self):
     """Tests the case with ZIP output which already has care_map entry."""
@@ -252,15 +252,10 @@
 
     # The one under OPTIONS.input_tmp must have been replaced.
     care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt')
-    with open(care_map_file, 'r') as verify_fp:
-      care_map = verify_fp.read()
+    expected = ['system', RangeSet("0-5 10-15").to_string_raw(), 'vendor',
+                RangeSet("0-9").to_string_raw()]
 
-    lines = care_map.split('\n')
-    self.assertEqual(4, len(lines))
-    self.assertEqual('system', lines[0])
-    self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1])
-    self.assertEqual('vendor', lines[2])
-    self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3])
+    self._verifyCareMap(expected, care_map_file)
 
     # The existing entry should be scheduled to be replaced.
     self.assertIn('META/care_map.txt', OPTIONS.replace_updated_files_list)
diff --git a/tools/vendor_buildinfo.sh b/tools/vendor_buildinfo.sh
deleted file mode 100755
index 6590049..0000000
--- a/tools/vendor_buildinfo.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-
-echo "# begin build properties"
-echo "# autogenerated by vendor_buildinfo.sh"
-
-echo "ro.vendor.build.id=$BUILD_ID"
-echo "ro.vendor.build.version.incremental=$BUILD_NUMBER"
-echo "ro.vendor.build.version.sdk=$PLATFORM_SDK_VERSION"
-echo "ro.vendor.build.version.release=$PLATFORM_VERSION"
-echo "ro.vendor.build.type=$TARGET_BUILD_TYPE"
-echo "ro.vendor.build.tags=$BUILD_VERSION_TAGS"
-
-echo "ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"
-echo "ro.board.platform=$TARGET_BOARD_PLATFORM"
-
-echo "ro.product.vendor.manufacturer=$PRODUCT_MANUFACTURER"
-echo "ro.product.vendor.model=$PRODUCT_MODEL"
-echo "ro.product.vendor.brand=$PRODUCT_BRAND"
-echo "ro.product.vendor.name=$PRODUCT_NAME"
-echo "ro.product.vendor.device=$TARGET_DEVICE"
-
-echo "# end build properties"