Merge "Fix typo in APEX_LIBS_ABSENCE_CHECK_EXCLUDE"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1d0685d..cbfca3e 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -634,6 +634,10 @@
 $(call add-clean-step, rm -rf $(HOST_OUT_EXECUTABLES)/build_verity_metadata.py)
 
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib*/libc_malloc*)
+
+# Move odm build.prop to /odm/etc/.
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/odm/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/odm/build.prop)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index 57a05d4..a4eb0f3 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -567,7 +567,7 @@
 
 # ----------------------------------------------------------------
 # odm build.prop
-INSTALLED_ODM_BUILD_PROP_TARGET := $(TARGET_OUT_ODM)/build.prop
+INSTALLED_ODM_BUILD_PROP_TARGET := $(TARGET_OUT_ODM)/etc/build.prop
 ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_ODM_BUILD_PROP_TARGET)
 
 FINAL_ODM_BUILD_PROPERTIES += \
@@ -695,7 +695,7 @@
 	@echo APK certs list: $@
 	@mkdir -p $(dir $@)
 	@rm -f $@
-	$(foreach p,$(PACKAGES),\
+	$(foreach p,$(sort $(PACKAGES)),\
 	  $(if $(PACKAGES.$(p).EXTERNAL_KEY),\
 	    $(call _apkcerts_write_line,$(p),"EXTERNAL","",$(PACKAGES.$(p).COMPRESSED),$@),\
 	    $(call _apkcerts_write_line,$(p),$(PACKAGES.$(p).CERTIFICATE),$(PACKAGES.$(p).PRIVATE_KEY),$(PACKAGES.$(p).COMPRESSED),$@)))
@@ -866,12 +866,13 @@
 
 #------------------------------------------------------------------
 # dtb
-
-ifdef BOARD_PREBUILT_DTBIMAGE_DIR
+ifdef BOARD_INCLUDE_DTB_IN_BOOTIMG
 INSTALLED_DTBIMAGE_TARGET := $(PRODUCT_OUT)/dtb.img
+ifdef BOARD_PREBUILT_DTBIMAGE_DIR
 $(INSTALLED_DTBIMAGE_TARGET) : $(sort $(wildcard $(BOARD_PREBUILT_DTBIMAGE_DIR)/*.dtb))
 	cat $^ > $@
 endif
+endif
 
 # -----------------------------------------------------------------
 # the ramdisk
@@ -1328,14 +1329,17 @@
     $(if $(PRODUCT_SYSTEM_BASE_FS_PATH),$(hide) echo "system_base_fs_file=$(PRODUCT_SYSTEM_BASE_FS_PATH)" >> $(1))
     $(if $(PRODUCT_SYSTEM_HEADROOM),$(hide) echo "system_headroom=$(PRODUCT_SYSTEM_HEADROOM)" >> $(1))
     $(if $(BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "system_reserved_size=$(BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
+    $(hide) echo "system_selinux_fc=$(SELINUX_FC)" >> $(1)
 )
 $(if $(filter $(2),userdata),\
     $(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
     $(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(1))
+    $(hide) echo "userdata_selinux_fc=$(SELINUX_FC)" >> $(1)
 )
 $(if $(filter $(2),cache),\
     $(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
     $(if $(BOARD_CACHEIMAGE_PARTITION_SIZE),$(hide) echo "cache_size=$(BOARD_CACHEIMAGE_PARTITION_SIZE)" >> $(1))
+    $(hide) echo "cache_selinux_fc=$(SELINUX_FC)" >> $(1)
 )
 $(if $(filter $(2),vendor),\
     $(if $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "vendor_fs_type=$(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
@@ -1349,6 +1353,7 @@
     $(if $(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "vendor_squashfs_disable_4k_align=$(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
     $(if $(PRODUCT_VENDOR_BASE_FS_PATH),$(hide) echo "vendor_base_fs_file=$(PRODUCT_VENDOR_BASE_FS_PATH)" >> $(1))
     $(if $(BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "vendor_reserved_size=$(BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
+    $(hide) echo "vendor_selinux_fc=$(SELINUX_FC)" >> $(1)
 )
 $(if $(filter $(2),product),\
     $(if $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "product_fs_type=$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
@@ -1362,6 +1367,7 @@
     $(if $(BOARD_PRODUCTIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "product_squashfs_disable_4k_align=$(BOARD_PRODUCTIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
     $(if $(PRODUCT_PRODUCT_BASE_FS_PATH),$(hide) echo "product_base_fs_file=$(PRODUCT_PRODUCT_BASE_FS_PATH)" >> $(1))
     $(if $(BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "product_reserved_size=$(BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
+    $(hide) echo "product_selinux_fc=$(SELINUX_FC)" >> $(1)
 )
 $(if $(filter $(2),product_services),\
     $(if $(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "product_services_fs_type=$(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
@@ -1374,6 +1380,7 @@
     $(if $(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "product_services_squashfs_block_size=$(BOARD_PRODUCT_SERVICESIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
     $(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))
+    $(hide) echo "product_services_selinux_fc=$(SELINUX_FC)" >> $(1)
 )
 $(if $(filter $(2),odm),\
     $(if $(BOARD_ODMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "odm_fs_type=$(BOARD_ODMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
@@ -1387,12 +1394,14 @@
     $(if $(BOARD_ODMIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "odm_squashfs_disable_4k_align=$(BOARD_ODMIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
     $(if $(PRODUCT_ODM_BASE_FS_PATH),$(hide) echo "odm_base_fs_file=$(PRODUCT_ODM_BASE_FS_PATH)" >> $(1))
     $(if $(BOARD_ODMIMAGE_PARTITION_RESERVED_SIZE),$(hide) echo "odm_reserved_size=$(BOARD_ODMIMAGE_PARTITION_RESERVED_SIZE)" >> $(1))
+    $(hide) echo "odm_selinux_fc=$(SELINUX_FC)" >> $(1)
 )
 $(if $(filter $(2),oem),\
     $(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
     $(if $(BOARD_OEMIMAGE_JOURNAL_SIZE),$(hide) echo "oem_journal_size=$(BOARD_OEMIMAGE_JOURNAL_SIZE)" >> $(1))
     $(if $(BOARD_OEMIMAGE_EXTFS_INODE_COUNT),$(hide) echo "oem_extfs_inode_count=$(BOARD_OEMIMAGE_EXTFS_INODE_COUNT)" >> $(1))
     $(if $(BOARD_OEMIMAGE_EXTFS_RSV_PCT),$(hide) echo "oem_extfs_rsv_pct=$(BOARD_OEMIMAGE_EXTFS_RSV_PCT)" >> $(1))
+    $(hide) echo "oem_selinux_fc=$(SELINUX_FC)" >> $(1)
 )
 $(hide) echo "ext_mkuserimg=$(notdir $(MKEXTUSERIMG))" >> $(1)
 
@@ -1402,7 +1411,6 @@
 $(if $(BOARD_EXT4_SHARE_DUP_BLOCKS),$(hide) echo "ext4_share_dup_blocks=$(BOARD_EXT4_SHARE_DUP_BLOCKS)" >> $(1))
 $(if $(BOARD_FLASH_LOGICAL_BLOCK_SIZE), $(hide) echo "flash_logical_block_size=$(BOARD_FLASH_LOGICAL_BLOCK_SIZE)" >> $(1))
 $(if $(BOARD_FLASH_ERASE_BLOCK_SIZE), $(hide) echo "flash_erase_block_size=$(BOARD_FLASH_ERASE_BLOCK_SIZE)" >> $(1))
-$(hide) echo "selinux_fc=$(SELINUX_FC)" >> $(1)
 $(if $(PRODUCT_SUPPORTS_BOOT_SIGNER),$(hide) echo "boot_signer=$(PRODUCT_SUPPORTS_BOOT_SIGNER)" >> $(1))
 $(if $(PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity=$(PRODUCT_SUPPORTS_VERITY)" >> $(1))
 $(if $(PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity_key=$(PRODUCT_VERITY_SIGNING_KEY)" >> $(1))
@@ -1472,8 +1480,30 @@
 
 # $(1): the path of the output dictionary file
 # $(2): additional "key=value" pairs to append to the dictionary file.
+PROP_DICTIONARY_IMAGES := oem
+ifdef BUILDING_CACHE_IMAGE
+  PROP_DICTIONARY_IMAGES += cache
+endif
+ifdef BUILDING_SYSTEM_IMAGE
+  PROP_DICTIONARY_IMAGES += system
+endif
+ifdef BUILDING_USERDATA_IMAGE
+  PROP_DICTIONARY_IMAGES += userdata
+endif
+ifdef BUILDING_VENDOR_IMAGE
+  PROP_DICTIONARY_IMAGES += vendor
+endif
+ifdef BUILDING_PRODUCT_IMAGE
+  PROP_DICTIONARY_IMAGES += product
+endif
+ifdef BUILDING_PRODUCT_SERVICES_IMAGE
+  PROP_DICTIONARY_IMAGES += product_services
+endif
+ifdef BUILDING_ODM_IMAGE
+  PROP_DICTIONARY_IMAGES += odm
+endif
 define generate-userimage-prop-dictionary
-$(call generate-image-prop-dictionary,$(1),system vendor cache userdata product product_services oem odm,$(2))
+  $(call generate-image-prop-dictionary,$(1),$(PROP_DICTIONARY_IMAGES),$(2))
 endef
 
 # $(1): the path of the input dictionary file, where each line has the format key=value
@@ -3381,8 +3411,12 @@
 
 .PHONY: check-all-partition-sizes check-all-partition-sizes-nodeps
 
+check_all_partition_sizes_file := $(call intermediates-dir-for,PACKAGING,check-all-partition-sizes)/timestamp
+
+check-all-partition-sizes: $(check_all_partition_sizes_file)
+
 # Add image dependencies so that generated_*_image_info.txt are written before checking.
-check-all-partition-sizes: \
+$(check_all_partition_sizes_file): \
     build/make/tools/releasetools/sparse_img.py \
     $(call images-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
 
@@ -3450,7 +3484,12 @@
   fi
 endef
 
-check-all-partition-sizes check-all-partition-sizes-nodeps:
+$(check_all_partition_sizes_file):
+	$(call check-all-partition-sizes-target)
+	$(call check-super-partition-size)
+	touch $@
+
+check-all-partition-sizes-nodeps:
 	$(call check-all-partition-sizes-target)
 	$(call check-super-partition-size)
 
@@ -3752,6 +3791,7 @@
 	    $(INTERNAL_SYSTEMOTHERIMAGE_FILES) \
 	    $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
 	    $(INSTALLED_KERNEL_TARGET) \
+	    $(INSTALLED_DTBIMAGE_TARGET) \
 	    $(INSTALLED_2NDBOOTLOADER_TARGET) \
 	    $(BOARD_PREBUILT_DTBOIMAGE) \
 	    $(BOARD_PREBUILT_RECOVERY_DTBOIMAGE) \
@@ -3804,7 +3844,7 @@
 ifdef BOARD_INCLUDE_RECOVERY_ACPIO
 	$(hide) cp $(BOARD_RECOVERY_ACPIO) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/recovery_acpio
 endif
-ifdef BOARD_INCLUDE_DTB_IN_BOOTIMG
+ifdef INSTALLED_DTBIMAGE_TARGET
 	$(hide) cp $(INSTALLED_DTBIMAGE_TARGET) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/dtb
 endif
 ifdef INTERNAL_KERNEL_CMDLINE
diff --git a/core/board_config.mk b/core/board_config.mk
index d83fa32..e14ba00 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -518,6 +518,12 @@
   endif
 endif
 
+ifdef BOARD_PREBUILT_DTBIMAGE_DIR
+  ifneq ($(BOARD_INCLUDE_DTB_IN_BOOTIMG),true)
+    $(error BOARD_PREBUILT_DTBIMAGE_DIR with 'BOARD_INCLUDE_DTB_IN_BOOTIMG != true' is not supported)
+  endif
+endif
+
 # Check BOARD_VNDK_VERSION
 define check_vndk_version
   $(eval vndk_path := prebuilts/vndk/v$(1)) \
diff --git a/core/config.mk b/core/config.mk
index 088bb15..57c1d7a 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -1102,7 +1102,7 @@
 TARGET_AVAIALBLE_SDK_VERSIONS := $(call numerically_sort,$(TARGET_AVAILABLE_SDK_VERSIONS))
 
 TARGET_SDK_VERSIONS_WITHOUT_JAVA_18_SUPPORT := $(call numbers_less_than,24,$(TARGET_AVAILABLE_SDK_VERSIONS))
-TARGET_SDK_VERSIONS_WITHOUT_JAVA_19_SUPPORT := $(call numbers_less_than,27,$(TARGET_AVAILABLE_SDK_VERSIONS))
+TARGET_SDK_VERSIONS_WITHOUT_JAVA_19_SUPPORT := $(call numbers_less_than,30,$(TARGET_AVAILABLE_SDK_VERSIONS))
 
 ifndef INTERNAL_PLATFORM_PRIVATE_API_FILE
 INTERNAL_PLATFORM_PRIVATE_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/private.txt
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index d3adee5..ebce00b 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -235,12 +235,17 @@
   my_sanitize := $(CLANG_DEFAULT_UB_CHECKS)
 endif
 
-ifneq ($(filter coverage,$(my_sanitize)),)
-  ifeq ($(filter address,$(my_sanitize)),)
-    $(error $(LOCAL_PATH): $(LOCAL_MODULE): Use of 'coverage' also requires 'address')
-  endif
-  my_cflags += -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp
-  my_sanitize := $(filter-out coverage,$(my_sanitize))
+ifneq ($(filter fuzzer,$(my_sanitize)),)
+  # SANITIZE_TARGET='fuzzer' actually means to create the fuzzer coverage
+  # information, not to link against the fuzzer main().
+  my_sanitize := $(filter-out fuzzer,$(my_sanitize))
+  my_sanitize += fuzzer-no-link
+
+  # TODO(b/131771163): Disable LTO for fuzzer builds. Note that Cfi causes
+  # dependency on LTO.
+  my_sanitize := $(filter-out cfi,$(my_sanitize))
+  my_cflags += -fno-lto
+  my_ldflags += -fno-lto
 endif
 
 ifneq ($(filter integer_overflow,$(my_sanitize)),)
@@ -280,7 +285,12 @@
   my_cflags += -fsanitize=$(fsanitize_arg)
   my_asflags += -fsanitize=$(fsanitize_arg)
 
-  ifdef LOCAL_IS_HOST_MODULE
+  # When fuzzing, we wish to crash with diagnostics on any bug.
+  ifneq ($(filter fuzzer-no-link,$(my_sanitize)),)
+    my_cflags += -fno-sanitize-trap=all
+    my_cflags += -fno-sanitize-recover=all
+    my_ldflags += -fsanitize=fuzzer-no-link
+  else ifdef LOCAL_IS_HOST_MODULE
     my_cflags += -fno-sanitize-recover=all
     my_ldflags += -fsanitize=$(fsanitize_arg)
   else
@@ -378,7 +388,7 @@
   ifneq ($(filter unsigned-integer-overflow signed-integer-overflow integer,$(my_sanitize)),)
     ifeq ($(filter unsigned-integer-overflow signed-integer-overflow integer,$(my_sanitize_diag)),)
       ifeq ($(filter cfi,$(my_sanitize_diag)),)
-        ifeq ($(filter address hwaddress,$(my_sanitize)),)
+        ifeq ($(filter address hwaddress fuzzer-no-link,$(my_sanitize)),)
           my_cflags += -fsanitize-minimal-runtime
           my_cflags += -fno-sanitize-trap=integer
           my_cflags += -fno-sanitize-recover=integer
diff --git a/core/dumpvar.mk b/core/dumpvar.mk
index 59efb04..2f1023f 100644
--- a/core/dumpvar.mk
+++ b/core/dumpvar.mk
@@ -17,6 +17,7 @@
 ANDROID_BUILD_PATHS := $(ABP)
 ANDROID_PREBUILTS := prebuilt/$(HOST_PREBUILT_TAG)
 ANDROID_GCC_PREBUILTS := prebuilts/gcc/$(HOST_PREBUILT_TAG)
+ANDROID_CLANG_PREBUILTS := prebuilts/clang/host/$(HOST_PREBUILT_TAG)
 
 # Dump mulitple variables to "<var>=<value>" pairs, one per line.
 # The output may be executed as bash script.
diff --git a/core/fuzz_test.mk b/core/fuzz_test.mk
index 2cc2e2c..f5bdef0 100644
--- a/core/fuzz_test.mk
+++ b/core/fuzz_test.mk
@@ -15,8 +15,7 @@
     my_fuzzer:=$(TARGET_FUZZ_ENGINE)
 endif
 
-
-LOCAL_CFLAGS += -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp
+LOCAL_SANITIZE += fuzzer
 
 ifeq ($(my_fuzzer),libFuzzer)
 LOCAL_STATIC_LIBRARIES += libFuzzer
diff --git a/core/host_fuzz_test.mk b/core/host_fuzz_test.mk
index 556e02f..54c6577 100644
--- a/core/host_fuzz_test.mk
+++ b/core/host_fuzz_test.mk
@@ -4,7 +4,7 @@
 ################################################
 $(call record-module-type,HOST_FUZZ_TEST)
 
-LOCAL_CFLAGS += -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp
+LOCAL_SANITIZE += fuzzer
 LOCAL_STATIC_LIBRARIES += libLLVMFuzzer
 
 include $(BUILD_HOST_EXECUTABLE)
diff --git a/core/java.mk b/core/java.mk
index b951f14..41a1686 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -240,6 +240,8 @@
 $(java_source_list_file): $(java_sources_deps)
 	$(write-java-source-list)
 
+ALL_MODULES.$(my_register_name).SRCJARS := $(LOCAL_SRCJARS)
+
 ifneq ($(TURBINE_ENABLED),false)
 
 $(full_classes_turbine_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS) $(annotation_processor_flags)
diff --git a/core/main.mk b/core/main.mk
index b423422..94bfd4b 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1825,22 +1825,6 @@
 # Phony target to run all java compilations that use javac
 .PHONY: javac-check
 
-ifneq (,$(filter samplecode, $(MAKECMDGOALS)))
-.PHONY: samplecode
-sample_MODULES := $(sort $(call get-tagged-modules,samples))
-sample_APKS_DEST_PATH := $(TARGET_COMMON_OUT_ROOT)/samples
-sample_APKS_COLLECTION := \
-        $(foreach module,$(sample_MODULES),$(sample_APKS_DEST_PATH)/$(notdir $(module)))
-$(foreach module,$(sample_MODULES),$(eval $(call \
-        copy-one-file,$(module),$(sample_APKS_DEST_PATH)/$(notdir $(module)))))
-sample_ADDITIONAL_INSTALLED := \
-        $(filter-out $(modules_to_install) $(modules_to_check),$(sample_MODULES))
-samplecode: $(sample_APKS_COLLECTION)
-	@echo "Collect sample code apks: $^"
-	# remove apks that are not intended to be installed.
-	rm -f $(sample_ADDITIONAL_INSTALLED)
-endif  # samplecode in $(MAKECMDGOALS)
-
 .PHONY: findbugs
 findbugs: $(INTERNAL_FINDBUGS_HTML_TARGET) $(INTERNAL_FINDBUGS_XML_TARGET)
 
diff --git a/core/product-graph.mk b/core/product-graph.mk
index a114b65..9db277c 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -52,13 +52,27 @@
 open_parethesis := (
 close_parenthesis := )
 
+node_color_target := orange
+node_color_common := beige
+node_color_vendor := lavenderblush
+node_color_default := white
+define node-color
+$(if $(filter $(1),$(PRIVATE_PRODUCTS_FILTER)),\
+  $(node_color_target),\
+  $(if $(filter build/make/target/product/%,$(1)),\
+    $(node_color_common),\
+    $(if $(filter vendor/%,$(1)),$(node_color_vendor),$(node_color_default))\
+  )\
+)
+endef
+
 # Emit properties of a product node to a file.
 # $(1) the product
 # $(2) the output file
 define emit-product-node-props
 $(hide) echo \"$(1)\" [ \
 label=\"$(dir $(1))\\n$(notdir $(1))\\n\\n$(subst $(close_parenthesis),,$(subst $(open_parethesis),,$(PRODUCTS.$(strip $(1)).PRODUCT_MODEL)))\\n$(PRODUCTS.$(strip $(1)).PRODUCT_DEVICE)\" \
-$(if $(filter $(1),$(PRIVATE_PRODUCTS_FILTER)), style=\"filled\" fillcolor=\"#FFFDB0\",) \
+style=\"filled\" fillcolor=\"$(strip $(call node-color,$(1)))\" \
 colorscheme=\"svg\" fontcolor=\"darkblue\" href=\"products/$(1).html\" \
 ] >> $(2)
 
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index 2c56162..2d93128 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -17,6 +17,7 @@
 			'"test_config": [$(if $(ALL_MODULES.$(m).TEST_CONFIG),"$(ALL_MODULES.$(m).TEST_CONFIG)")], ' \
 			'"dependencies": [$(foreach w,$(sort $(ALL_DEPS.$(m).ALL_DEPS)),"$(w)", )], ' \
 			'"srcs": [$(foreach w,$(sort $(ALL_MODULES.$(m).SRCS)),"$(w)", )], ' \
+			'"srcjars": [$(foreach w,$(sort $(ALL_MODULES.$(m).SRCJARS)),"$(w)", )], ' \
 			'},\n' \
 	 ) | sed -e 's/, *\]/]/g' -e 's/, *\}/ }/g' -e '$$s/,$$//' >> $@
 	$(hide) echo '}' >> $@
diff --git a/envsetup.sh b/envsetup.sh
index 5292d38..2fa5660 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -246,8 +246,11 @@
     if [ -n "$ANDROID_TOOLCHAIN_2ND_ARCH" ]; then
         ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_TOOLCHAIN_2ND_ARCH
     fi
-    ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_DEV_SCRIPTS:
-    export ANDROID_BUILD_PATHS
+    ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_DEV_SCRIPTS
+
+    # Append llvm binutils prebuilts path to ANDROID_BUILD_PATHS.
+    local ANDROID_LLVM_BINUTILS=$(get_abs_build_var ANDROID_CLANG_PREBUILTS)/llvm-binutils-stable
+    ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_LLVM_BINUTILS
 
     # If prebuilts/android-emulator/<system>/ exists, prepend it to our PATH
     # to ensure that the corresponding 'emulator' binaries are used.
@@ -263,7 +266,7 @@
             ;;
     esac
     if [ -n "$ANDROID_EMULATOR_PREBUILTS" -a -d "$ANDROID_EMULATOR_PREBUILTS" ]; then
-        ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS$ANDROID_EMULATOR_PREBUILTS:
+        ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_EMULATOR_PREBUILTS
         export ANDROID_EMULATOR_PREBUILTS
     fi
 
@@ -272,9 +275,9 @@
     local ACLOUD_PATH="$T/prebuilts/asuite/acloud/$os_arch:"
     local AIDEGEN_PATH="$T/prebuilts/asuite/aidegen/$os_arch:"
     local ATEST_PATH="$T/prebuilts/asuite/atest/$os_arch:"
-    export ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS$ACLOUD_PATH$AIDEGEN_PATH$ATEST_PATH
+    export ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ACLOUD_PATH$AIDEGEN_PATH$ATEST_PATH
 
-    export PATH=$ANDROID_BUILD_PATHS$PATH
+    export PATH=$ANDROID_BUILD_PATHS:$PATH
 
     # out with the duplicate old
     if [ -n $ANDROID_PYTHONPATH ]; then
diff --git a/target/product/gsi_common.mk b/target/product/gsi_common.mk
index c38dd80..0e9b29e 100644
--- a/target/product/gsi_common.mk
+++ b/target/product/gsi_common.mk
@@ -41,7 +41,6 @@
     system/lib/libgiftranscode.so \
     system/lib64/libframesequence.so \
     system/lib64/libgiftranscode.so \
-    system/priv-app/Dialer/Dialer.apk \
 
 # Some GSI builds enable dexpreopt, whitelist these preopt files
 PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST += %.odex %.vdex %.art
@@ -74,14 +73,12 @@
 # Support addtional P vendor interface
 PRODUCT_EXTRA_VNDK_VERSIONS := 28
 
-# Default AOSP packages
+# More AOSP packages
 PRODUCT_PACKAGES += \
     messaging \
-
-# Default AOSP packages
-PRODUCT_PACKAGES += \
     PhotoTable \
     WAPPushManager \
+    WallpaperPicker \
 
 # Telephony:
 #   Provide a APN configuration to GSI product
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 4136ed4..ba04651 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -519,7 +519,6 @@
   common_props = (
       "extfs_sparse_flag",
       "squashfs_sparse_flag",
-      "selinux_fc",
       "skip_fsck",
       "ext_mkuserimg",
       "verity",
@@ -564,6 +563,7 @@
     if not copy_prop("system_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
     copy_prop("system_reserved_size", "partition_reserved_size")
+    copy_prop("system_selinux_fc", "selinux_fc")
   elif mount_point == "system_other":
     # We inherit the selinux policies of /system since we contain some of its
     # files.
@@ -587,6 +587,7 @@
     if not copy_prop("system_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
     copy_prop("system_reserved_size", "partition_reserved_size")
+    copy_prop("system_selinux_fc", "selinux_fc")
   elif mount_point == "data":
     # Copy the generic fs type first, override with specific one if available.
     copy_prop("fs_type", "fs_type")
@@ -594,9 +595,11 @@
     copy_prop("userdata_size", "partition_size")
     copy_prop("flash_logical_block_size", "flash_logical_block_size")
     copy_prop("flash_erase_block_size", "flash_erase_block_size")
+    copy_prop("userdata_selinux_fc", "selinux_fc")
   elif mount_point == "cache":
     copy_prop("cache_fs_type", "fs_type")
     copy_prop("cache_size", "partition_size")
+    copy_prop("cache_selinux_fc", "selinux_fc")
   elif mount_point == "vendor":
     copy_prop("avb_vendor_hashtree_enable", "avb_hashtree_enable")
     copy_prop("avb_vendor_add_hashtree_footer_args",
@@ -618,6 +621,7 @@
     if not copy_prop("vendor_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
     copy_prop("vendor_reserved_size", "partition_reserved_size")
+    copy_prop("vendor_selinux_fc", "selinux_fc")
   elif mount_point == "product":
     copy_prop("avb_product_hashtree_enable", "avb_hashtree_enable")
     copy_prop("avb_product_add_hashtree_footer_args",
@@ -639,6 +643,7 @@
     if not copy_prop("product_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
     copy_prop("product_reserved_size", "partition_reserved_size")
+    copy_prop("product_selinux_fc", "selinux_fc")
   elif mount_point == "product_services":
     copy_prop("avb_product_services_hashtree_enable", "avb_hashtree_enable")
     copy_prop("avb_product_services_add_hashtree_footer_args",
@@ -662,6 +667,7 @@
     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")
+    copy_prop("product_services_selinux_fc", "selinux_fc")
   elif mount_point == "odm":
     copy_prop("avb_odm_hashtree_enable", "avb_hashtree_enable")
     copy_prop("avb_odm_add_hashtree_footer_args",
@@ -683,6 +689,7 @@
     if not copy_prop("odm_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
     copy_prop("odm_reserved_size", "partition_reserved_size")
+    copy_prop("odm_selinux_fc", "selinux_fc")
   elif mount_point == "oem":
     copy_prop("fs_type", "fs_type")
     copy_prop("oem_size", "partition_size")
@@ -692,6 +699,7 @@
     copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
     if not copy_prop("oem_extfs_rsv_pct", "extfs_rsv_pct"):
       d["extfs_rsv_pct"] = "0"
+    copy_prop("oem_selinux_fc", "selinux_fc")
   d["partition_name"] = mount_point
   return d
 
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index e642297..9d67c49 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -332,13 +332,15 @@
     raise ValueError("Failed to find 'fstab_version'")
 
   if repacking:
-    # "selinux_fc" should point to the file_contexts file (file_contexts.bin)
-    # under META/.
-    fc_basename = os.path.basename(d.get("selinux_fc", "file_contexts"))
-    fc_config = os.path.join(input_file, "META", fc_basename)
-    assert os.path.exists(fc_config)
+    # "selinux_fc" properties should point to the file_contexts files
+    # (file_contexts.bin) under META/.
+    for key in d:
+      if key.endswith("selinux_fc"):
+        fc_basename = os.path.basename(d[key])
+        fc_config = os.path.join(input_file, "META", fc_basename)
+        assert os.path.exists(fc_config)
 
-    d["selinux_fc"] = fc_config
+        d[key] = fc_config
 
     # Similarly we need to redirect "root_dir", and "root_fs_config".
     d["root_dir"] = os.path.join(input_file, "ROOT")
@@ -415,8 +417,14 @@
   # Tries to load the build props for all partitions with care_map, including
   # system and vendor.
   for partition in PARTITIONS_WITH_CARE_MAP:
-    d["{}.build.prop".format(partition)] = LoadBuildProp(
+    partition_prop = "{}.build.prop".format(partition)
+    d[partition_prop] = LoadBuildProp(
         read_helper, "{}/build.prop".format(partition.upper()))
+    # Some partition might use /<partition>/etc/build.prop as the new path.
+    # TODO: try new path first when majority of them switch to the new path.
+    if not d[partition_prop]:
+      d[partition_prop] = LoadBuildProp(
+          read_helper, "{}/etc/build.prop".format(partition.upper()))
   d["build.prop"] = d["system.build.prop"]
 
   # Set up the salt (based on fingerprint or thumbprint) that will be used when
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index f03cc1e..e8c3cf7 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -160,7 +160,6 @@
 
 default_other_item_list = [
     'META/boot_filesystem_config.txt',
-    'META/file_contexts.bin',
     'META/otakeys.txt',
     'META/releasetools.py',
     'META/vendor_filesystem_config.txt',
@@ -185,6 +184,26 @@
 ]
 
 
+def write_sorted_data(data, path):
+  """Write the sorted contents of either a list or dict to file.
+
+  This function sorts the contents of the list or dict and then
+  writes the resulting sorted contents to a file specified by path.
+
+  Args:
+    data: The list or dict to sort and write.
+    path: Path to the file to write the sorted values to. The file at path will
+      be overridden if it exists.
+  """
+  with open(path, 'w') as output:
+    sorted_data = sorted(data.keys()) if isinstance(data,
+                                                    dict) else sorted(data)
+    for entry in sorted_data:
+      out_str = '{}={}\n'.format(entry, data[entry]) if isinstance(
+          data, dict) else '{}\n'.format(entry)
+      output.write(out_str)
+
+
 def extract_items(target_files, target_files_temp_dir, extract_item_list):
   """Extract items from target files to temporary directory.
 
@@ -341,9 +360,7 @@
   output_ab_partitions_txt = os.path.join(output_target_files_temp_dir, 'META',
                                           'ab_partitions.txt')
 
-  with open(output_ab_partitions_txt, 'w') as output:
-    for partition in sorted(output_ab_partitions):
-      output.write('%s\n' % partition)
+  write_sorted_data(data=output_ab_partitions, path=output_ab_partitions_txt)
 
 
 def append_recovery_to_filesystem_config(output_target_files_temp_dir):
@@ -483,12 +500,21 @@
         list_suffix='_partition_list')
     merged_info_dict.update(merged_dynamic_partitions_dict)
 
+  # Replace <image>_selinux_fc values with system or other file_contexts.bin
+  # depending on which dictionary the key came from.
+  # Only the file basename is required because all selinux_fc properties are
+  # replaced with the full path to the file under META/ when misc_info.txt is
+  # loaded from target files for repacking. See common.py LoadInfoDict().
+  for key in merged_info_dict:
+    if key.endswith('_selinux_fc'):
+      merged_info_dict[key] = 'other_file_contexts.bin'
+  for key in system_info_dict:
+    if key.endswith('_selinux_fc'):
+      merged_info_dict[key] = 'system_file_contexts.bin'
+
   output_misc_info_txt = os.path.join(output_target_files_temp_dir, 'META',
                                       'misc_info.txt')
-  with open(output_misc_info_txt, 'w') as output:
-    sorted_keys = sorted(merged_info_dict.keys())
-    for key in sorted_keys:
-      output.write('{}={}\n'.format(key, merged_info_dict[key]))
+  write_sorted_data(data=merged_info_dict, path=output_misc_info_txt)
 
 
 def process_dynamic_partitions_info_txt(system_target_files_dir,
@@ -538,10 +564,78 @@
 
   output_dynamic_partitions_info_txt = os.path.join(
       output_target_files_dir, 'META', 'dynamic_partitions_info.txt')
-  with open(output_dynamic_partitions_info_txt, 'w') as output:
-    sorted_keys = sorted(merged_dynamic_partitions_dict.keys())
-    for key in sorted_keys:
-      output.write('{}={}\n'.format(key, merged_dynamic_partitions_dict[key]))
+  write_sorted_data(
+      data=merged_dynamic_partitions_dict,
+      path=output_dynamic_partitions_info_txt)
+
+
+def process_apex_keys_apk_certs_common(system_target_files_dir,
+                                       other_target_files_dir,
+                                       output_target_files_dir, file_name):
+  """Perform special processing for META/apexkeys.txt or META/apkcerts.txt.
+
+  This function merges the contents of the META/apexkeys.txt or
+  META/apkcerts.txt
+  files from the system directory and the other directory, placing the merged
+  result in the output directory. The precondition in that the files are already
+  extracted.
+  The post condition is that the output META/apexkeys.txt or META/apkcerts.txt
+  contains the merged content.
+
+  Args:
+    system_target_files_dir: The name of a directory containing the special
+      items extracted from the system target files package.
+    other_target_files_dir: The name of a directory containing the special items
+      extracted from the other target files package.
+    output_target_files_dir: The name of a directory that will be used to create
+      the output target files package after all the special cases are processed.
+    file_name: The name of the file to merge. One of apkcerts.txt or
+      apexkeys.txt.
+  """
+
+  def read_helper(d):
+    temp = {}
+    file_path = os.path.join(d, 'META', file_name)
+    with open(file_path) as f:
+      for line in f:
+        if line.strip():
+          temp[line.split()[0]] = line.strip()
+    return temp
+
+  system_dict = read_helper(system_target_files_dir)
+  other_dict = read_helper(other_target_files_dir)
+
+  for key in system_dict:
+    if key in other_dict and other_dict[key] != system_dict[key]:
+      raise ValueError('Conflicting entries found in %s:\n %s and\n %s' %
+                       (file_name, system_dict[key], other_dict[key]))
+    other_dict[key] = system_dict[key]
+
+  output_file = os.path.join(output_target_files_dir, 'META', file_name)
+
+  write_sorted_data(data=other_dict.values(), path=output_file)
+
+
+def copy_file_contexts(system_target_files_dir, other_target_files_dir,
+                       output_target_files_dir):
+  """Creates named copies of each build's file_contexts.bin in output META/."""
+  system_fc_path = os.path.join(system_target_files_dir, 'META', 'system_file_contexts.bin')
+  if not os.path.exists(system_fc_path):
+    system_fc_path = os.path.join(system_target_files_dir, 'META', 'file_contexts.bin')
+    if not os.path.exists(system_fc_path):
+      raise ValueError('Missing system file_contexts.bin.')
+  shutil.copyfile(
+      system_fc_path,
+      os.path.join(output_target_files_dir, 'META', 'system_file_contexts.bin'))
+
+  other_fc_path = os.path.join(other_target_files_dir, 'META', 'other_file_contexts.bin')
+  if not os.path.exists(other_fc_path):
+    other_fc_path = os.path.join(other_target_files_dir, 'META', 'file_contexts.bin')
+    if not os.path.exists(other_fc_path):
+      raise ValueError('Missing other file_contexts.bin.')
+  shutil.copyfile(
+      other_fc_path,
+      os.path.join(output_target_files_dir, 'META', 'other_file_contexts.bin'))
 
 
 def process_special_cases(system_target_files_temp_dir,
@@ -577,6 +671,11 @@
     append_recovery_to_filesystem_config(
         output_target_files_temp_dir=output_target_files_temp_dir)
 
+  copy_file_contexts(
+      system_target_files_dir=system_target_files_temp_dir,
+      other_target_files_dir=other_target_files_temp_dir,
+      output_target_files_dir=output_target_files_temp_dir)
+
   process_misc_info_txt(
       system_target_files_temp_dir=system_target_files_temp_dir,
       other_target_files_temp_dir=other_target_files_temp_dir,
@@ -588,6 +687,18 @@
       other_target_files_dir=other_target_files_temp_dir,
       output_target_files_dir=output_target_files_temp_dir)
 
+  process_apex_keys_apk_certs_common(
+      system_target_files_dir=system_target_files_temp_dir,
+      other_target_files_dir=other_target_files_temp_dir,
+      output_target_files_dir=output_target_files_temp_dir,
+      file_name='apkcerts.txt')
+
+  process_apex_keys_apk_certs_common(
+      system_target_files_dir=system_target_files_temp_dir,
+      other_target_files_dir=other_target_files_temp_dir,
+      output_target_files_dir=output_target_files_temp_dir,
+      file_name='apexkeys.txt')
+
 
 def merge_target_files(temp_dir, system_target_files, system_item_list,
                        system_misc_info_keys, other_target_files,
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 7de0978..c174d2f 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -491,8 +491,10 @@
     elif filename in ("SYSTEM/build.prop",
                       "VENDOR/build.prop",
                       "SYSTEM/vendor/build.prop",
-                      "ODM/build.prop",
-                      "VENDOR/odm/build.prop",
+                      "ODM/build.prop",  # legacy
+                      "ODM/etc/build.prop",
+                      "VENDOR/odm/build.prop",  # legacy
+                      "VENDOR/odm/etc/build.prop",
                       "PRODUCT/build.prop",
                       "SYSTEM/product/build.prop",
                       "PRODUCT_SERVICES/build.prop",
diff --git a/tools/releasetools/test_merge_target_files.py b/tools/releasetools/test_merge_target_files.py
index 3f15d8f..1e29fde 100644
--- a/tools/releasetools/test_merge_target_files.py
+++ b/tools/releasetools/test_merge_target_files.py
@@ -22,7 +22,8 @@
                                 default_system_item_list,
                                 default_other_item_list,
                                 default_system_misc_info_keys, copy_items,
-                                merge_dynamic_partition_info_dicts)
+                                merge_dynamic_partition_info_dicts,
+                                process_apex_keys_apk_certs_common)
 
 
 class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase):
@@ -160,3 +161,55 @@
         'super_group_b_size': '2000',
     }
     self.assertEqual(merged_dict, expected_merged_dict)
+
+  def test_process_apex_keys_apk_certs_ReturnsTrueIfNoConflicts(self):
+    output_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(output_dir, 'META'))
+
+    system_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(system_dir, 'META'))
+    os.symlink(
+        os.path.join(self.testdata_dir, 'apexkeys_system.txt'),
+        os.path.join(system_dir, 'META', 'apexkeys.txt'))
+
+    other_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(other_dir, 'META'))
+    os.symlink(
+        os.path.join(self.testdata_dir, 'apexkeys_other.txt'),
+        os.path.join(other_dir, 'META', 'apexkeys.txt'))
+
+    process_apex_keys_apk_certs_common(system_dir, other_dir, output_dir,
+                                       'apexkeys.txt')
+
+    merged_entries = []
+    merged_path = os.path.join(self.testdata_dir, 'apexkeys_merge.txt')
+
+    with open(merged_path) as f:
+      merged_entries = f.read().split('\n')
+
+    output_entries = []
+    output_path = os.path.join(output_dir, 'META', 'apexkeys.txt')
+
+    with open(output_path) as f:
+      output_entries = f.read().split('\n')
+
+    return self.assertEqual(merged_entries, output_entries)
+
+  def test_process_apex_keys_apk_certs_ReturnsFalseIfConflictsPresent(self):
+    output_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(output_dir, 'META'))
+
+    system_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(system_dir, 'META'))
+    os.symlink(
+        os.path.join(self.testdata_dir, 'apexkeys_system.txt'),
+        os.path.join(system_dir, 'META', 'apexkeys.txt'))
+
+    conflict_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(conflict_dir, 'META'))
+    os.symlink(
+        os.path.join(self.testdata_dir, 'apexkeys_system_conflict.txt'),
+        os.path.join(conflict_dir, 'META', 'apexkeys.txt'))
+
+    self.assertRaises(ValueError, process_apex_keys_apk_certs_common,
+                      system_dir, conflict_dir, output_dir, 'apexkeys.txt')
diff --git a/tools/releasetools/testdata/apexkeys_merge.txt b/tools/releasetools/testdata/apexkeys_merge.txt
new file mode 100644
index 0000000..48e789f
--- /dev/null
+++ b/tools/releasetools/testdata/apexkeys_merge.txt
@@ -0,0 +1,4 @@
+name="com.android.conscrypt.apex" public_key="external/conscrypt/apex/com.android.conscrypt.avbpubkey" private_key="external/conscrypt/apex/com.android.conscrypt.pem" container_certificate="external/conscrypt/apex/com.android.conscrypt.x509.pem" container_private_key="external/conscrypt/apex/com.android.conscrypt.pk8"
+name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.debug.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"
+name="com.android.runtime.release.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.release.x509.pem" container_private_key="art/build/apex/com.android.runtime.release.pk8"
+name="com.android.support.apexer.apex" public_key="system/apex/apexer/etc/com.android.support.apexer.avbpubkey" private_key="system/apex/apexer/etc/com.android.support.apexer.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
diff --git a/tools/releasetools/testdata/apexkeys_other.txt b/tools/releasetools/testdata/apexkeys_other.txt
new file mode 100644
index 0000000..b751227
--- /dev/null
+++ b/tools/releasetools/testdata/apexkeys_other.txt
@@ -0,0 +1,3 @@
+name="com.android.runtime.release.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.release.x509.pem" container_private_key="art/build/apex/com.android.runtime.release.pk8"
+name="com.android.support.apexer.apex" public_key="system/apex/apexer/etc/com.android.support.apexer.avbpubkey" private_key="system/apex/apexer/etc/com.android.support.apexer.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
+name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.debug.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"
diff --git a/tools/releasetools/testdata/apexkeys_system.txt b/tools/releasetools/testdata/apexkeys_system.txt
new file mode 100644
index 0000000..2346668
--- /dev/null
+++ b/tools/releasetools/testdata/apexkeys_system.txt
@@ -0,0 +1,2 @@
+name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.debug.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"
+name="com.android.conscrypt.apex" public_key="external/conscrypt/apex/com.android.conscrypt.avbpubkey" private_key="external/conscrypt/apex/com.android.conscrypt.pem" container_certificate="external/conscrypt/apex/com.android.conscrypt.x509.pem" container_private_key="external/conscrypt/apex/com.android.conscrypt.pk8"
diff --git a/tools/releasetools/testdata/apexkeys_system_conflict.txt b/tools/releasetools/testdata/apexkeys_system_conflict.txt
new file mode 100644
index 0000000..caa21c2
--- /dev/null
+++ b/tools/releasetools/testdata/apexkeys_system_conflict.txt
@@ -0,0 +1 @@
+name="com.android.runtime.debug.apex" public_key="art/build/apex/com.android.runtime.avbpubkey" private_key="art/build/apex/com.android.runtime.pem" container_certificate="art/build/apex/com.android.runtime.release.x509.pem" container_private_key="art/build/apex/com.android.runtime.debug.pk8"