Merge "Generate SBOM of .kcm files in layoutlib." into main
diff --git a/common/math.mk b/common/math.mk
index 0271ea8..ecee474 100644
--- a/common/math.mk
+++ b/common/math.mk
@@ -25,6 +25,7 @@
                       61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
                       81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
 __MATH_NUMBERS := 0 $(__MATH_POS_NUMBERS)
+__MATH_ONE_NUMBERS := 0 1 2 3 4 5 6 7 8 9
 
 math-error = $(call pretty-error,$(1))
 math-expect :=
@@ -36,6 +37,10 @@
 #  make -f ${ANDROID_BUILD_TOP}/build/make/common/math.mk RUN_MATH_TESTS=true
 #  $(get_build_var CKATI) -f ${ANDROID_BUILD_TOP}//build/make/common/math.mk RUN_MATH_TESTS=true
 ifdef RUN_MATH_TESTS
+  ifndef empty
+    empty :=
+    space := $(empty) $(empty)
+  endif
   MATH_TEST_FAILURE :=
   MATH_TEST_ERROR :=
   math-error = $(if $(MATH_TEST_ERROR),,$(eval MATH_TEST_ERROR:=$(1)))
@@ -61,13 +66,29 @@
 endif
 
 # Returns true if $(1) is a non-negative integer <= 100, otherwise returns nothing.
-define math_is_number
+define math_is_number_in_100
 $(strip \
   $(if $(1),,$(call math-error,Argument missing)) \
   $(if $(word 2,$(1)),$(call math-error,Multiple words in a single argument: $(1))) \
   $(if $(filter $(1),$(__MATH_NUMBERS)),true))
 endef
 
+# Same with math_is_number_in_100, but no limit.
+define _math_ext_is_number
+$(strip \
+  $(if $(1),,$(call math-error,Argument missing)) \
+  $(if $(word 2,$(1)),$(call math-error,Multiple words in a single argument: $(1))) \
+  $(eval should_empty:=$(1)) \
+  $(foreach num,$(__MATH_ONE_NUMBERS),\
+    $(eval should_empty:=$(subst $(num),$(empty),$(should_empty)))) \
+  $(if $(should_empty),,true))
+endef
+
+# Returns true if $(1) is a non-negative integer.
+define math_is_number
+$(strip $(if $(call math_is_number_in_100,$(1)),true,$(call _math_ext_is_number,$(1))))
+endef
+
 define math_is_zero
 $(strip \
   $(if $(word 2,$(1)),$(call math-error,Multiple words in a single argument: $(1))) \
@@ -76,6 +97,7 @@
 
 $(call math-expect-true,(call math_is_number,0))
 $(call math-expect-true,(call math_is_number,2))
+$(call math-expect-true,(call math_is_number,202412))
 $(call math-expect-false,(call math_is_number,foo))
 $(call math-expect-false,(call math_is_number,-1))
 $(call math-expect-error,(call math_is_number,1 2),Multiple words in a single argument: 1 2)
@@ -88,7 +110,7 @@
 $(call math-expect-error,(call math_is_zero,no 2),Multiple words in a single argument: no 2)
 
 define _math_check_valid
-$(if $(call math_is_number,$(1)),,$(call math-error,Only non-negative integers <= 100 are supported (not $(1))))
+$(if $(call math_is_number_in_100,$(1)),,$(call math-error,Only non-negative integers <= 100 are supported (not $(1))))
 endef
 
 $(call math-expect,(call _math_check_valid,0))
@@ -113,18 +135,81 @@
 $(call math-expect,(call int_range_list,2,1),)
 $(call math-expect-error,(call int_range_list,1,101),Only non-negative integers <= 100 are supported (not 101))
 
+# Split an integer into a list of digits
+define _math_number_to_list
+$(strip \
+  $(if $(call _math_ext_is_number,$(1)),,\
+    $(call math-error,Only non-negative integers are supported (not $(1)))) \
+  $(eval num_list:=$(1)) \
+  $(foreach num,$(__MATH_ONE_NUMBERS),\
+    $(eval num_list:=$(subst $(num),$(space)$(num),$(num_list)))) \
+  $(if $(filter $(words $(num_list)),$(__MATH_ONE_NUMBERS)),,\
+    $(call math-error,Only non-negative integers with less than 9 digits are supported (not $(1)))) \
+  $(if $(filter 0,$(word 1,$(num_list))),\
+    $(call math-error,Only non-negative integers without leading zeros are supported (not $(1)))) \
+  $(num_list))
+endef
+
+$(call math-expect,(call _math_number_to_list,123),1 2 3)
+$(call math-expect-error,(call _math_number_to_list,123 456),Multiple words in a single argument: 123 456)
+$(call math-expect-error,(call _math_number_to_list,-123),Only non-negative integers are supported (not -123))
+$(call math-expect-error,(call _math_number_to_list,002),Only non-negative integers without leading zeros are supported (not 002))
+$(call math-expect-error,(call _math_number_to_list,1234567890),Only non-negative integers with less than 9 digits are supported (not 1234567890))
+
+# Compare 1-digit integer $(1) and $(2).
+# Returns 1 if $(1) > $(2), -1 if $(1) < $(2), nothing if equals.
+define _math_1digit_comp
+$(strip \
+  $(if $(filter $(1),$(2)),,\
+    $(if $(filter $(1),$(firstword $(filter $(1) $(2),$(__MATH_ONE_NUMBERS)))),-1,1)))
+endef
+
+$(call math-expect,(call _math_1digit_comp,1,1))
+$(call math-expect,(call _math_1digit_comp,0,9),-1)
+$(call math-expect,(call _math_1digit_comp,3,1),1)
+
+# Compare the same $(3)-digit-length integers $(1) and $(2) that are split into a list of digits.
+# Returns 1 if $(1) > $(2), -1 if $(1) < $(2), nothing if equals.
+define _math_list_comp
+$(strip \
+  $(eval ans:=) \
+  $(foreach num,$(call int_range_list,1,$(3)),\
+    $(if $(ans),,$(eval ans:=$(call _math_1digit_comp,$(word $(num),$(1)),$(word $(num),$(2)))))) \
+  $(ans))
+endef
+
+# Compare any two non-negative integers $(1) and $(2).
+# Returns 1 if $(1) > $(2), -1 if $(1) < $(2), nothing if equals.
+define _math_ext_comp
+$(strip \
+  $(eval num_list1:=$(call _math_number_to_list,$(1))) \
+  $(eval len1:=$(words $(num_list1))) \
+  $(eval num_list2:=$(call _math_number_to_list,$(2))) \
+  $(eval len2:=$(words $(num_list2))) \
+  $(eval comp:=$(call _math_1digit_comp,$(len1),$(len2))) \
+  $(if $(comp),$(comp),$(call _math_list_comp,$(num_list1),$(num_list2),$(len1))))
+endef
+
+$(call math-expect,(call _math_ext_comp,5,10),-1)
+$(call math-expect,(call _math_ext_comp,12345,12345))
+$(call math-expect,(call _math_ext_comp,500,5),1)
+$(call math-expect,(call _math_ext_comp,202404,202504),-1)
 
 # Returns the greater of $1 or $2.
-# If $1 or $2 is not a positive integer <= 100, then an error is generated.
+# If $1 or $2 is not a positive integer, then an error is generated.
 define math_max
-$(strip $(call _math_check_valid,$(1)) $(call _math_check_valid,$(2)) \
-  $(lastword $(filter $(1) $(2),$(__MATH_NUMBERS))))
+$(strip \
+  $(if $(filter truetrue,$(call math_is_number_in_100,$(1))$(call math_is_number_in_100,$(2))),\
+    $(lastword $(filter $(1) $(2),$(__MATH_NUMBERS))),\
+    $(if $(filter 1,$(call _math_ext_comp,$(1),$(2))),$(1),$(2))))
 endef
 
 # Returns the lesser of $1 or $2.
 define math_min
-$(strip $(call _math_check_valid,$(1)) $(call _math_check_valid,$(2)) \
-  $(firstword $(filter $(1) $(2),$(__MATH_NUMBERS))))
+$(strip \
+  $(if $(filter truetrue,$(call math_is_number_in_100,$(1))$(call math_is_number_in_100,$(2))),\
+    $(firstword $(filter $(1) $(2),$(__MATH_NUMBERS))),\
+    $(if $(filter -1,$(call _math_ext_comp,$(1),$(2))),$(1),$(2))))
 endef
 
 $(call math-expect-error,(call math_max),Argument missing)
@@ -142,6 +227,15 @@
 $(call math-expect,(call math_min,7,32),7)
 $(call math-expect,(call math_min,32,7),7)
 
+$(call math-expect,(call math_max,32759,7),32759)
+$(call math-expect,(call math_max,7,32759),32759)
+$(call math-expect,(call math_max,202404,202505),202505)
+$(call math-expect,(call math_max,202404,202404),202404)
+$(call math-expect,(call math_min,8908527,32),32)
+$(call math-expect,(call math_min,32,8908527),32)
+$(call math-expect,(call math_min,202404,202505),202404)
+$(call math-expect,(call math_min,202404,202404),202404)
+
 define math_gt_or_eq
 $(if $(filter $(1),$(call math_max,$(1),$(2))),true)
 endef
@@ -150,6 +244,10 @@
 $(if $(call math_gt_or_eq,$(2),$(1)),,true)
 endef
 
+define math_lt_or_eq
+$(if $(call math_gt_or_eq,$(2),$(1)),true)
+endef
+
 define math_lt
 $(if $(call math_gt_or_eq,$(1),$(2)),,true)
 endef
@@ -160,10 +258,17 @@
 $(call math-expect-true,(call math_gt, 4, 3))
 $(call math-expect-false,(call math_gt, 5, 5))
 $(call math-expect-false,(call math_gt, 6, 7))
+$(call math-expect-true,(call math_lt_or_eq, 11, 11))
+$(call math-expect-false,(call math_lt_or_eq, 25, 15))
+$(call math-expect-true,(call math_lt_or_eq, 9, 16))
 $(call math-expect-false,(call math_lt, 1, 0))
 $(call math-expect-false,(call math_lt, 8, 8))
 $(call math-expect-true,(call math_lt, 10, 11))
 
+$(call math-expect-true,(call math_gt_or_eq, 2573904, 2573900))
+$(call math-expect-true,(call math_gt_or_eq, 12345, 12345))
+$(call math-expect-false,(call math_gt_or_eq, 56, 2780))
+
 # $1 is the variable name to increment
 define inc_and_print
 $(strip $(eval $(1) := $($(1)) .)$(words $($(1))))
@@ -192,6 +297,7 @@
 $(call math-expect,(call numbers_less_than,3,0 2 1 3),0 2 1)
 $(call math-expect,(call numbers_less_than,4,0 2 1 3),0 2 1 3)
 $(call math-expect,(call numbers_less_than,3,0 2 1 3 2),0 2 1 2)
+$(call math-expect,(call numbers_less_than,100,0 1000 50 101 100),0 50)
 
 # Returns the words in $2 that are numbers and are greater or equal to $1
 define numbers_greater_or_equal_to
diff --git a/core/Makefile b/core/Makefile
index 37dd0f6..d371fb8 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1065,6 +1065,18 @@
 
 endif
 
+# BOARD_KERNEL_MODULES_16K might contain duplicate modules under different path.
+# for example, foo/bar/wifi.ko and foo/wifi.ko . To avoid build issues, de-dup
+# module list on basename first.
+BOARD_KERNEL_MODULES_16K := $(foreach \
+  pattern,\
+  $(sort $(foreach \
+    path,\
+    $(BOARD_KERNEL_MODULES_16K),\
+    %/$(notdir $(path)))\
+  ),\
+  $(firstword $(filter $(pattern),$(BOARD_KERNEL_MODULES_16K))) \
+)
 # For non-GKI modules, strip them before install. As debug symbols take up
 # significant space.
 $(foreach \
@@ -1444,15 +1456,19 @@
 INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
 
 ifeq ($(BOARD_AVB_ENABLE),true)
-$(INSTALLED_BOOTIMAGE_TARGET): $(INTERNAL_PREBUILT_BOOTIMAGE) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH)
+$(INSTALLED_BOOTIMAGE_TARGET): PRIVATE_WORKING_DIR := $(call intermediates-dir-for,PACKAGING,prebuilt_bootimg)
+$(INSTALLED_BOOTIMAGE_TARGET): $(INTERNAL_PREBUILT_BOOTIMAGE) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) $(UNPACK_BOOTIMG)
 	cp $(INTERNAL_PREBUILT_BOOTIMAGE) $@
+	$(UNPACK_BOOTIMG) --boot_img $(INTERNAL_PREBUILT_BOOTIMAGE) --out $(PRIVATE_WORKING_DIR)
 	chmod +w $@
 	$(AVBTOOL) add_hash_footer \
 	    --image $@ \
+	    --salt `sha256sum $(PRIVATE_WORKING_DIR)/kernel | cut -d " " -f 1` \
 	    $(call get-partition-size-argument,$(BOARD_BOOTIMAGE_PARTITION_SIZE)) \
 	    --partition_name boot $(INTERNAL_AVB_BOOT_SIGNING_ARGS) \
 	    $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)
 
+
 $(call declare-container-license-metadata,$(INSTALLED_BOOTIMAGE_TARGET),SPDX-license-identifier-GPL-2.0-only SPDX-license-identifier-Apache-2.0,restricted notice,$(BUILD_SYSTEM)/LINUX_KERNEL_COPYING build/soong/licenses/LICENSE,"Boot Image",bool)
 $(call declare-container-license-deps,$(INSTALLED_BOOTIMAGE_TARGET),$(INTERNAL_PREBUILT_BOOTIMAGE),$(PRODUCT_OUT)/:/)
 
diff --git a/core/config.mk b/core/config.mk
index 196f07c..c747fd5 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -722,6 +722,7 @@
 BUILD_SUPER_IMAGE := $(BOARD_CUSTOM_BUILD_SUPER_IMAGE)
 endif
 IMG_FROM_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/img_from_target_files$(HOST_EXECUTABLE_SUFFIX)
+UNPACK_BOOTIMG := $(HOST_OUT_EXECUTABLES)/unpack_bootimg
 MAKE_RECOVERY_PATCH := $(HOST_OUT_EXECUTABLES)/make_recovery_patch$(HOST_EXECUTABLE_SUFFIX)
 OTA_FROM_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/ota_from_target_files$(HOST_EXECUTABLE_SUFFIX)
 OTA_FROM_RAW_IMG := $(HOST_OUT_EXECUTABLES)/ota_from_raw_img$(HOST_EXECUTABLE_SUFFIX)
diff --git a/core/main.mk b/core/main.mk
index c345c96..cd6d4b7 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -335,19 +335,6 @@
     ro.build.ab_update=$(AB_OTA_UPDATER)
 endif
 
-# Set ro.product.vndk.version to know the VNDK version required by product
-# modules. It uses the version in PRODUCT_PRODUCT_VNDK_VERSION. If the value
-# is "current", use PLATFORM_VNDK_VERSION.
-ifdef PRODUCT_PRODUCT_VNDK_VERSION
-ifeq ($(KEEP_VNDK),true)
-ifeq ($(PRODUCT_PRODUCT_VNDK_VERSION),current)
-ADDITIONAL_PRODUCT_PROPERTIES += ro.product.vndk.version=$(PLATFORM_VNDK_VERSION)
-else
-ADDITIONAL_PRODUCT_PROPERTIES += ro.product.vndk.version=$(PRODUCT_PRODUCT_VNDK_VERSION)
-endif
-endif
-endif
-
 ADDITIONAL_PRODUCT_PROPERTIES += ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS)
 
 ifeq ($(AB_OTA_UPDATER),true)
diff --git a/core/packaging/flags.mk b/core/packaging/flags.mk
index a7e8d35..3b0bde8 100644
--- a/core/packaging/flags.mk
+++ b/core/packaging/flags.mk
@@ -72,28 +72,42 @@
 # $(1): built aconfig flags file (out)
 # $(2): installed aconfig flags file (out)
 # $(3): input aconfig files for the partition (in)
+# $(4): file format, passed to `aconfig dump` (in)
+# $(5): text placed in aconfig file when no flags present (out)
 define generate-partition-aconfig-flag-file
 $(eval $(strip $(1)): PRIVATE_OUT := $(strip $(1)))
 $(eval $(strip $(1)): PRIVATE_IN := $(strip $(3)))
 $(strip $(1)): $(ACONFIG) $(strip $(3))
 	mkdir -p $$(dir $$(PRIVATE_OUT))
 	$$(if $$(PRIVATE_IN), \
-		$$(ACONFIG) dump --format protobuf --out $$(PRIVATE_OUT) \
+		$$(ACONFIG) dump --format $(4) --out $$(PRIVATE_OUT) \
 			$$(addprefix --cache ,$$(PRIVATE_IN)), \
-		echo -n > $$(PRIVATE_OUT) \
+		echo -n "$(5)" > $$(PRIVATE_OUT) \
 	)
 $(call copy-one-file, $(1), $(2))
 endef
 
 
 $(foreach partition, $(_FLAG_PARTITIONS), \
+	$(eval aconfig_flag_summaries_textproto.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/aconfig_flags.textproto) \
 	$(eval aconfig_flag_summaries_protobuf.$(partition) := $(PRODUCT_OUT)/$(partition)/etc/aconfig_flags.pb) \
 	$(eval $(call generate-partition-aconfig-flag-file, \
+				$(TARGET_OUT_FLAGS)/$(partition)/aconfig_flags.textproto, \
+				$(aconfig_flag_summaries_textproto.$(partition)), \
+				$(sort $(foreach m,$(call register-names-for-partition, $(partition)), \
+					$(ALL_MODULES.$(m).ACONFIG_FILES) \
+				)), \
+				textproto, \
+				"# No aconfig flags" \
+	)) \
+	$(eval $(call generate-partition-aconfig-flag-file, \
 				$(TARGET_OUT_FLAGS)/$(partition)/aconfig_flags.pb, \
 				$(aconfig_flag_summaries_protobuf.$(partition)), \
 				$(sort $(foreach m,$(call register-names-for-partition, $(partition)), \
 					$(ALL_MODULES.$(m).ACONFIG_FILES) \
 				)), \
+				protobuf, \
+				"" \
 	)) \
 )
 
@@ -103,6 +117,7 @@
 required_flags_files := \
 		$(sort $(foreach partition, $(filter $(IMAGES_TO_BUILD), $(_FLAG_PARTITIONS)), \
 			$(build_flag_summaries.$(partition)) \
+			$(aconfig_flag_summaries_textproto.$(partition)) \
 			$(aconfig_flag_summaries_protobuf.$(partition)) \
 		))
 
@@ -118,6 +133,7 @@
 required_flags_files:=
 $(foreach partition, $(_FLAG_PARTITIONS), \
 	$(eval build_flag_summaries.$(partition):=) \
+	$(eval aconfig_flag_summaries_textproto.$(partition):=) \
 	$(eval aconfig_flag_summaries_protobuf.$(partition):=) \
 )
 
diff --git a/envsetup.sh b/envsetup.sh
index e448bd3..ee45280 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -56,7 +56,7 @@
 Run "m help" for help with the build system itself.
 
 Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
-- lunch:      lunch <product_name>-<build_variant>
+- lunch:      lunch <product_name>-<release_type>-<build_variant>
               Selects <product_name> as the product to build, and <build_variant> as the variant to
               build, and stores those selections in the environment to be read by subsequent
               invocations of 'm' etc.
@@ -205,6 +205,7 @@
         return
     fi
         TARGET_PRODUCT=$1 \
+        TARGET_RELEASE= \
         TARGET_BUILD_VARIANT= \
         TARGET_BUILD_TYPE= \
         TARGET_BUILD_APPS= \
@@ -486,7 +487,7 @@
 
 function multitree_lunch_help()
 {
-    echo "usage: lunch PRODUCT-VARIANT" 1>&2
+    echo "usage: lunch PRODUCT-RELEASE-VARIANT" 1>&2
     echo "    Set up android build environment based on a product short name and variant" 1>&2
     echo 1>&2
     echo "lunch COMBO_FILE VARIANT" 1>&2
@@ -728,7 +729,7 @@
 {
     local uname=$(uname)
     local choices
-    choices=$(TARGET_BUILD_APPS= TARGET_PRODUCT= TARGET_BUILD_VARIANT= get_build_var COMMON_LUNCH_CHOICES 2>/dev/null)
+    choices=$(TARGET_BUILD_APPS= TARGET_PRODUCT= TARGET_RELEASE= TARGET_BUILD_VARIANT= get_build_var COMMON_LUNCH_CHOICES 2>/dev/null)
     local ret=$?
 
     echo
@@ -774,7 +775,7 @@
         answer=$1
     else
         print_lunch_menu
-        echo "Which would you like? [aosp_arm-eng]"
+        echo "Which would you like? [aosp_arm-trunk_staging-eng]"
         echo -n "Pick from common choices above (e.g. 13) or specify your own (e.g. aosp_barbet-eng): "
         read answer
         used_lunch_menu=1
@@ -784,7 +785,7 @@
 
     if [ -z "$answer" ]
     then
-        selection=aosp_arm-eng
+        selection=aosp_arm-trunk_staging-eng
     elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
     then
         local choices=($(TARGET_BUILD_APPS= get_build_var COMMON_LUNCH_CHOICES))
@@ -804,26 +805,16 @@
 
     export TARGET_BUILD_APPS=
 
-    # Support either <product>-<variant> or <product>-<release>-<variant>
-    local product release_and_variant release variant
-    product=${selection%%-*} # Trim everything after first dash
-    release_and_variant=${selection#*-} # Trim everything up to first dash
-    if [ "$release_and_variant" != "$selection" ]; then
-        local first=${release_and_variant%%-*} # Trim everything after first dash
-        if [ "$first" != "$release_and_variant" ]; then
-            # There is a 2nd dash, split into release-variant
-            release=$first # Everything up to the dash
-            variant=${release_and_variant#*-} # Trim everything up to dash
-        else
-            # There is not a 2nd dash, default to variant as the second param
-            variant=$first
-        fi
-    fi
+    # This must be <product>-<release>-<variant>
+    local product release variant
+    # Split string on the '-' character.
+    IFS="-" read -r product release variant <<< "$selection"
 
-    if [ -z "$product" ]
+    if [[ -z "$product" ]] || [[ -z "$release" ]] || [[ -z "$variant" ]]
     then
         echo
         echo "Invalid lunch combo: $selection"
+        echo "Valid combos must be of the form <product>-<release>-<variant>"
         return 1
     fi
 
@@ -841,11 +832,8 @@
     fi
     export TARGET_PRODUCT=$(get_build_var TARGET_PRODUCT)
     export TARGET_BUILD_VARIANT=$(get_build_var TARGET_BUILD_VARIANT)
-    if [ -n "$release" ]; then
-      export TARGET_RELEASE=$release
-    else
-      unset TARGET_RELEASE
-    fi
+    export TARGET_RELEASE=$release
+    # Note this is the string "release", not the value of the variable.
     export TARGET_BUILD_TYPE=release
 
     if [ $used_lunch_menu -eq 1 ]; then
@@ -887,6 +875,8 @@
 {
     local showHelp="$(echo $* | xargs -n 1 echo | \grep -E '^(help)$' | xargs)"
     local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|arm64|x86_64)$' | xargs)"
+    # TODO(b/307975293): Expand tapas to take release arguments (and update hmm() usage).
+    local release="trunk_staging"
     local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)"
     local density="$(echo $* | xargs -n 1 echo | \grep -E '^(ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
     local keys="$(echo $* | xargs -n 1 echo | \grep -E '^(devkeys)$' | xargs)"
@@ -902,6 +892,10 @@
         echo "tapas: Error: Multiple build archs supplied: $arch"
         return
     fi
+    if [ $(echo $release | wc -w) -gt 1 ]; then
+        echo "tapas: Error: Multiple build releases supplied: $release"
+        return
+    fi
     if [ $(echo $variant | wc -w) -gt 1 ]; then
         echo "tapas: Error: Multiple build variants supplied: $variant"
         return
@@ -936,6 +930,7 @@
     fi
 
     export TARGET_PRODUCT=$product
+    export TARGET_RELEASE=$release
     export TARGET_BUILD_VARIANT=$variant
     export TARGET_BUILD_DENSITY=$density
     export TARGET_BUILD_TYPE=release
@@ -953,6 +948,8 @@
 {
     local showHelp="$(echo $* | xargs -n 1 echo | \grep -E '^(help)$' | xargs)"
     local product="$(echo $* | xargs -n 1 echo | \grep -E '^(.*_)?(arm|x86|arm64|riscv64|x86_64|arm64only|x86_64only)$' | xargs)"
+    # TODO: Expand banchan to take release arguments (and update hmm() usage).
+    local release="trunk_staging"
     local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)"
     local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|(.*_)?(arm|x86|arm64|riscv64|x86_64))$' | xargs)"
 
@@ -967,6 +964,10 @@
         echo "banchan: Error: Multiple build archs or products supplied: $products"
         return
     fi
+    if [ $(echo $release | wc -w) -gt 1 ]; then
+        echo "banchan: Error: Multiple build releases supplied: $release"
+        return
+    fi
     if [ $(echo $variant | wc -w) -gt 1 ]; then
         echo "banchan: Error: Multiple build variants supplied: $variant"
         return
@@ -990,6 +991,7 @@
     fi
 
     export TARGET_PRODUCT=$product
+    export TARGET_RELEASE=$release
     export TARGET_BUILD_VARIANT=$variant
     export TARGET_BUILD_DENSITY=alldpi
     export TARGET_BUILD_TYPE=release
diff --git a/target/board/emulator_x86_arm/BoardConfig.mk b/target/board/emulator_x86_arm/BoardConfig.mk
deleted file mode 100644
index 21fdbc8..0000000
--- a/target/board/emulator_x86_arm/BoardConfig.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# x86 emulator specific definitions
-TARGET_CPU_ABI := x86
-TARGET_ARCH := x86
-TARGET_ARCH_VARIANT := x86
-
-TARGET_NATIVE_BRIDGE_ARCH := arm
-TARGET_NATIVE_BRIDGE_ARCH_VARIANT := armv7-a-neon
-TARGET_NATIVE_BRIDGE_CPU_VARIANT := generic
-TARGET_NATIVE_BRIDGE_ABI := armeabi-v7a armeabi
-
-BUILD_BROKEN_DUP_RULES := true
-
-#
-# The inclusion order below is important.
-# The settings in latter makefiles overwrite those in the former.
-#
-include build/make/target/board/BoardConfigMainlineCommon.mk
-include build/make/target/board/BoardConfigEmuCommon.mk
-
-# the settings differ from BoardConfigMainlineCommon.mk
-BOARD_USES_SYSTEM_OTHER_ODEX :=
-
-# Resize to 4G to accommodate ASAN and CTS
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 4294967296
-
-BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
-
-# Wifi.
-BOARD_WLAN_DEVICE           := emulator
-BOARD_HOSTAPD_DRIVER        := NL80211
-BOARD_WPA_SUPPLICANT_DRIVER := NL80211
-BOARD_HOSTAPD_PRIVATE_LIB   := lib_driver_cmd_simulated
-BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
-WPA_SUPPLICANT_VERSION      := VER_0_8_X
-WIFI_DRIVER_FW_PATH_PARAM   := "/dev/null"
-WIFI_DRIVER_FW_PATH_STA     := "/dev/null"
-WIFI_DRIVER_FW_PATH_AP      := "/dev/null"
diff --git a/target/board/emulator_x86_arm/device.mk b/target/board/emulator_x86_arm/device.mk
deleted file mode 100644
index af023eb..0000000
--- a/target/board/emulator_x86_arm/device.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish # for libwifi-hal-emu
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish-opengl # for goldfish deps.
diff --git a/target/board/emulator_x86_arm/system_ext.prop b/target/board/emulator_x86_arm/system_ext.prop
deleted file mode 100644
index 64829f3..0000000
--- a/target/board/emulator_x86_arm/system_ext.prop
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# system.prop for generic sdk
-#
-
-rild.libpath=/vendor/lib/libreference-ril.so
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index c3bc14b..18b36aa 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -84,7 +84,7 @@
     $(LOCAL_DIR)/module_x86_64only.mk \
 
 COMMON_LUNCH_CHOICES := \
-    aosp_arm64-eng \
-    aosp_arm-eng \
-    aosp_x86_64-eng \
-    aosp_x86-eng \
+    aosp_arm64-trunk_staging-eng \
+    aosp_arm-trunk_staging-eng \
+    aosp_x86_64-trunk_staging-eng \
+    aosp_x86-trunk_staging-eng \
diff --git a/tools/aconfig/Android.bp b/tools/aconfig/Android.bp
index 02fc57c..425d8a9 100644
--- a/tools/aconfig/Android.bp
+++ b/tools/aconfig/Android.bp
@@ -13,6 +13,11 @@
         type: "lite",
     },
     sdk_version: "current",
+    min_sdk_version: "UpsideDownCake",
+    apex_available: [
+        "com.android.configinfrastructure",
+        "//apex_available:platform",
+    ]
 }
 
 java_library_host {
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 33eba7c..893eced 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1235,26 +1235,16 @@
   system_root_image = info_dict.get('system_root_image') == 'true'
   if info_dict.get('no_recovery') != 'true':
     recovery_fstab_path = 'RECOVERY/RAMDISK/system/etc/recovery.fstab'
-    if isinstance(input_file, zipfile.ZipFile):
-      if recovery_fstab_path not in input_file.namelist():
-        recovery_fstab_path = 'RECOVERY/RAMDISK/etc/recovery.fstab'
-    else:
-      path = os.path.join(input_file, *recovery_fstab_path.split('/'))
-      if not os.path.exists(path):
-        recovery_fstab_path = 'RECOVERY/RAMDISK/etc/recovery.fstab'
+    if not DoesInputFileContain(input_file, recovery_fstab_path):
+      recovery_fstab_path = 'RECOVERY/RAMDISK/etc/recovery.fstab'
     return LoadRecoveryFSTab(
         read_helper, info_dict['fstab_version'], recovery_fstab_path,
         system_root_image)
 
   if info_dict.get('recovery_as_boot') == 'true':
     recovery_fstab_path = 'BOOT/RAMDISK/system/etc/recovery.fstab'
-    if isinstance(input_file, zipfile.ZipFile):
-      if recovery_fstab_path not in input_file.namelist():
-        recovery_fstab_path = 'BOOT/RAMDISK/etc/recovery.fstab'
-    else:
-      path = os.path.join(input_file, *recovery_fstab_path.split('/'))
-      if not os.path.exists(path):
-        recovery_fstab_path = 'BOOT/RAMDISK/etc/recovery.fstab'
+    if not DoesInputFileContain(input_file, recovery_fstab_path):
+      recovery_fstab_path = 'BOOT/RAMDISK/etc/recovery.fstab'
     return LoadRecoveryFSTab(
         read_helper, info_dict['fstab_version'], recovery_fstab_path,
         system_root_image)
@@ -1947,7 +1937,15 @@
     cmd = [avbtool, "add_hash_footer", "--image", image_path,
            "--partition_size", str(part_size), "--partition_name",
            partition_name]
-    AppendAVBSigningArgs(cmd, partition_name)
+    # Use sha256 of the kernel as salt for reproducible builds
+    with tempfile.TemporaryDirectory() as tmpdir:
+      RunAndCheckOutput(["unpack_bootimg", "--boot_img", image_path, "--out", tmpdir])
+      for filename in ["kernel", "ramdisk", "vendor_ramdisk00"]:
+        path = os.path.join(tmpdir, filename)
+        if os.path.exists(path) and os.path.getsize(path):
+          with open(path, "rb") as fp:
+            salt = sha256(fp.read()).hexdigest()
+    AppendAVBSigningArgs(cmd, partition_name, salt)
     args = info_dict.get("avb_" + partition_name + "_add_hash_footer_args")
     if args and args.strip():
       split_args = ResolveAVBSigningPathArgs(shlex.split(args))