Merge "Revert "Do not generate aconfig_flags.textproto"" into main
diff --git a/Changes.md b/Changes.md
index 6c0cf70..fc15e60 100644
--- a/Changes.md
+++ b/Changes.md
@@ -1,5 +1,14 @@
 # Build System Changes for Android.mk/Android.bp Writers
 
+## Soong genrules are now sandboxed
+
+Previously, soong genrules could access any files in the source tree, without specifying them as
+inputs. This makes them incorrect in incremental builds, and incompatible with RBE and Bazel.
+
+Now, genrules are sandboxed so they can only access their listed srcs. Modules denylisted in
+genrule/allowlists.go are exempt from this. You can also set `BUILD_BROKEN_GENRULE_SANDBOXING`
+in board config to disable this behavior.
+
 ## Partitions are no longer affected by previous builds
 
 Partition builds used to include everything in their staging directories, and building an
diff --git a/core/Makefile b/core/Makefile
index 453a013..a190a3d 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1060,9 +1060,16 @@
 BUILT_RAMDISK_16K_TARGET := $(PRODUCT_OUT)/ramdisk_16k.img
 RAMDISK_16K_STAGING_DIR := $(call intermediates-dir-for,PACKAGING,depmod_ramdisk_16k)
 
+ifneq ($(BOARD_SYSTEM_KERNEL_MODULES),)
+SYSTEM_DLKM_MODULE_PATTERNS := $(foreach path,$(BOARD_SYSTEM_KERNEL_MODULES),%/$(notdir $(path)))
+
+endif
+
+# For non-GKI modules, strip them before install. As debug symbols take up
+# significant space.
 $(foreach \
   file,\
-  $(BOARD_KERNEL_MODULES_16K),\
+  $(filter-out $(SYSTEM_DLKM_MODULE_PATTERNS),$(BOARD_KERNEL_MODULES_16K)),\
   $(eval \
     $(call copy-and-strip-kernel-module,\
       $(file),\
@@ -1071,6 +1078,20 @@
   ) \
 )
 
+# For GKI modules, copy as-is without stripping, because stripping would
+# remove the signature of kernel modules, and GKI modules must be signed
+# for kernel to load them.
+$(foreach \
+  file,\
+  $(filter $(SYSTEM_DLKM_MODULE_PATTERNS),$(BOARD_KERNEL_MODULES_16K)),\
+  $(eval \
+    $(call copy-one-file,\
+      $(file),\
+      $(RAMDISK_16K_STAGING_DIR)/lib/modules/0.0/$(notdir $(file)) \
+    ) \
+  ) \
+)
+
 BOARD_VENDOR_RAMDISK_FRAGMENT.16K.PREBUILT := $(BUILT_RAMDISK_16K_TARGET)
 
 $(BUILT_RAMDISK_16K_TARGET): $(DEPMOD) $(MKBOOTFS) $(EXTRACT_KERNEL) $(COMPRESSION_COMMAND_DEPS)
@@ -1423,15 +1444,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)/:/)
 
@@ -2110,6 +2135,7 @@
 $(if $(BOARD_$(_var)IMAGE_EROFS_COMPRESSOR),$(hide) echo "$(1)_erofs_compressor=$(BOARD_$(_var)IMAGE_EROFS_COMPRESSOR)" >> $(2))
 $(if $(BOARD_$(_var)IMAGE_EROFS_COMPRESS_HINTS),$(hide) echo "$(1)_erofs_compress_hints=$(BOARD_$(_var)IMAGE_EROFS_COMPRESS_HINTS)" >> $(2))
 $(if $(BOARD_$(_var)IMAGE_EROFS_PCLUSTER_SIZE),$(hide) echo "$(1)_erofs_pcluster_size=$(BOARD_$(_var)IMAGE_EROFS_PCLUSTER_SIZE)" >> $(2))
+$(if $(BOARD_$(_var)IMAGE_EROFS_BLOCKSIZE),$(hide) echo "$(1)_erofs_blocksize=$(BOARD_$(_var)IMAGE_EROFS_BLOCKSIZE)" >> $(2))
 $(if $(BOARD_$(_var)IMAGE_EXTFS_INODE_COUNT),$(hide) echo "$(1)_extfs_inode_count=$(BOARD_$(_var)IMAGE_EXTFS_INODE_COUNT)" >> $(2))
 $(if $(BOARD_$(_var)IMAGE_EXTFS_RSV_PCT),$(hide) echo "$(1)_extfs_rsv_pct=$(BOARD_$(_var)IMAGE_EXTFS_RSV_PCT)" >> $(2))
 $(if $(BOARD_$(_var)IMAGE_F2FS_SLOAD_COMPRESS_FLAGS),$(hide) echo "$(1)_f2fs_sldc_flags=$(BOARD_$(_var)IMAGE_F2FS_SLOAD_COMPRESS_FLAGS)" >> $(2))
@@ -2199,6 +2225,7 @@
 $(if $(BOARD_EROFS_COMPRESSOR),$(hide) echo "erofs_default_compressor=$(BOARD_EROFS_COMPRESSOR)" >> $(1))
 $(if $(BOARD_EROFS_COMPRESS_HINTS),$(hide) echo "erofs_default_compress_hints=$(BOARD_EROFS_COMPRESS_HINTS)" >> $(1))
 $(if $(BOARD_EROFS_PCLUSTER_SIZE),$(hide) echo "erofs_pcluster_size=$(BOARD_EROFS_PCLUSTER_SIZE)" >> $(1))
+$(if $(BOARD_EROFS_BLOCKSIZE),$(hide) echo "erofs_blocksize=$(BOARD_EROFS_BLOCKSIZE)" >> $(1))
 $(if $(BOARD_EROFS_SHARE_DUP_BLOCKS),$(hide) echo "erofs_share_dup_blocks=$(BOARD_EROFS_SHARE_DUP_BLOCKS)" >> $(1))
 $(if $(BOARD_EROFS_USE_LEGACY_COMPRESSION),$(hide) echo "erofs_use_legacy_compression=$(BOARD_EROFS_USE_LEGACY_COMPRESSION)" >> $(1))
 $(if $(BOARD_EXT4_SHARE_DUP_BLOCKS),$(hide) echo "ext4_share_dup_blocks=$(BOARD_EXT4_SHARE_DUP_BLOCKS)" >> $(1))
@@ -5049,8 +5076,11 @@
 APEX_INFO_FILE := $(APEX_OUT)/apex-info-list.xml
 
 # apexd_host scans/activates APEX files and writes /apex/apex-info-list.xml
+# Note that `@echo $(PRIVATE_APEX_FILES)` line is added to trigger the rule when the APEX list is changed.
+$(APEX_INFO_FILE): PRIVATE_APEX_FILES := $(apex_files)
 $(APEX_INFO_FILE): $(HOST_OUT_EXECUTABLES)/apexd_host $(apex_files)
 	@echo "Extracting apexes..."
+	@echo $(PRIVATE_APEX_FILES) > /dev/null
 	@rm -rf $(APEX_OUT)
 	@mkdir -p $(APEX_OUT)
 	$< --vendor_path $(TARGET_OUT_VENDOR) \
@@ -7650,7 +7680,7 @@
 
 # -----------------------------------------------------------------
 # Extract platform fonts used in Layoutlib
-include $(BUILD_SYSTEM)/layoutlib_fonts.mk
+include $(BUILD_SYSTEM)/layoutlib_data.mk
 
 
 # -----------------------------------------------------------------
diff --git a/core/all_versions.bzl b/core/all_versions.bzl
deleted file mode 100644
index 33da673..0000000
--- a/core/all_versions.bzl
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2023 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.
-
-_all_versions = ["OPR1", "OPD1", "OPD2", "OPM1", "OPM2", "PPR1", "PPD1", "PPD2", "PPM1", "PPM2", "QPR1"] + [
-    version + subversion
-    for version in ["Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
-    for subversion in ["P1A", "P1B", "P2A", "P2B", "D1A", "D1B", "D2A", "D2B", "Q1A", "Q1B", "Q2A", "Q2B", "Q3A", "Q3B"]
-]
-
-variables_to_export_to_make = {
-    "ALL_VERSIONS": _all_versions,
-}
diff --git a/core/board_config.mk b/core/board_config.mk
index eb4c5ec..b7ca3a4 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -188,6 +188,7 @@
   BUILD_BROKEN_VENDOR_PROPERTY_NAMESPACE \
   BUILD_BROKEN_VINTF_PRODUCT_COPY_FILES \
   BUILD_BROKEN_INCORRECT_PARTITION_IMAGES \
+  BUILD_BROKEN_GENRULE_SANDBOXING \
 
 _build_broken_var_list += \
   $(foreach m,$(AVAILABLE_BUILD_MODULE_TYPES) \
@@ -223,6 +224,8 @@
   board_config_mk := \
     $(strip $(sort $(wildcard \
       $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \
+      device/generic/goldfish/board/$(TARGET_DEVICE)/BoardConfig.mk \
+      device/google/cuttlefish/board/$(TARGET_DEVICE)/BoardConfig.mk \
       $(shell test -d device && find -L device -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \
       $(shell test -d vendor && find -L vendor -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \
     )))
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/definitions.mk b/core/definitions.mk
index b6b0d69..ebc6c6e 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2955,7 +2955,7 @@
 ifeq ($(HOST_OS),linux)
 # Runs appcompat and store logs in $(PRODUCT_OUT)/appcompat
 define extract-package
-$(AAPT2) dump resources $@ | awk -F ' |=' '/^Package/{print $$3}' >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log &&
+$(AAPT2) dump resources $@ | awk -F ' |=' '/^Package/{print $$3; exit}' >> $(PRODUCT_OUT)/appcompat/$(PRIVATE_MODULE).log &&
 endef
 define appcompat-header
 $(hide) \
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 091c2e3..7ddbf32 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -51,44 +51,15 @@
 include $(BUILD_SYSTEM)/release_config.mk
 
 # ---------------------------------------------------------------
-# defines ALL_VERSIONS
-$(call run-starlark,build/make/core/all_versions.bzl)
+# Set up version information
+include $(BUILD_SYSTEM)/version_util.mk
 
-# Filters ALL_VERSIONS down to the range [$1, $2], and errors if $1 > $2 or $3 is
-# not in [$1, $2]
-# $(1): min platform version
-# $(2): max platform version
-# $(3): default platform version
-define allowed-platform-versions
-$(strip \
-  $(if $(filter $(ALL_VERSIONS),$(1)),,
-    $(error Invalid MIN_PLATFORM_VERSION '$(1)'))
-  $(if $(filter $(ALL_VERSIONS),$(2)),,
-    $(error Invalid MAX_PLATFORM_VERSION '$(2)'))
-  $(if $(filter $(ALL_VERSIONS),$(3)),,
-    $(error Invalid RELEASE_PLATFORM_VERSION '$(3)'))
+# This used to be calculated, but is now fixed and not expected
+# to change over time anymore. New code attempting to use a
+# variable like IS_AT_LAST_* should instead use a
+# build system flag.
 
-  $(eval allowed_versions_ := $(call find_and_earlier,$(ALL_VERSIONS),$(2)))
-
-  $(if $(filter $(allowed_versions_),$(1)),,
-    $(error MIN_PLATFORM_VERSION '$(1)' must be before MAX_PLATFORM_VERSION '$(2)'))
-
-  $(eval allowed_versions_ := $(1) \
-    $(filter-out $(call find_and_earlier,$(allowed_versions_),$(1)),$(allowed_versions_)))
-
-  $(if $(filter $(allowed_versions_),$(3)),,
-    $(error RELEASE_PLATFORM_VERSION '$(3)' must be between MIN_PLATFORM_VERSION '$(1)' and MAX_PLATFORM_VERSION '$(2)'))
-
-  $(allowed_versions_))
-endef
-
-#$(warning $(call allowed-platform-versions,OPR1,PPR1,OPR1))
-#$(warning $(call allowed-platform-versions,OPM1,PPR1,OPR1))
-
-# Set up version information.
-include $(BUILD_SYSTEM)/version_defaults.mk
-
-ENABLED_VERSIONS := $(call find_and_earlier,$(ALL_VERSIONS),$(TARGET_PLATFORM_VERSION))
+ENABLED_VERSIONS := "OPR1 OPD1 OPD2 OPM1 OPM2 PPR1 PPD1 PPD2 PPM1 PPM2 QPR1 QP1A QP1B QP2A QP2B QD1A QD1B QD2A QD2B QQ1A QQ1B QQ2A QQ2B QQ3A QQ3B RP1A RP1B RP2A RP2B RD1A RD1B RD2A RD2B RQ1A RQ1B RQ2A RQ2B RQ3A RQ3B SP1A SP1B SP2A SP2B SD1A SD1B SD2A SD2B SQ1A SQ1B SQ2A SQ2B SQ3A SQ3B TP1A TP1B TP2A TP2B TD1A TD1B TD2A TD2B TQ1A TQ1B TQ2A TQ2B TQ3A TQ3B UP1A UP1B UP2A UP2B UD1A UD1B UD2A UD2B UQ1A UQ1B UQ2A UQ2B UQ3A UQ3B"
 
 $(foreach v,$(ENABLED_VERSIONS), \
   $(eval IS_AT_LEAST_$(v) := true))
diff --git a/core/layoutlib_data.mk b/core/layoutlib_data.mk
new file mode 100644
index 0000000..09e48f3
--- /dev/null
+++ b/core/layoutlib_data.mk
@@ -0,0 +1,128 @@
+# Data files for layoutlib
+
+FONT_TEMP := $(call intermediates-dir-for,PACKAGING,fonts,HOST,COMMON)
+
+# The font configuration files - system_fonts.xml, fallback_fonts.xml etc.
+font_config := $(sort $(wildcard frameworks/base/data/fonts/*.xml))
+font_config := $(addprefix $(FONT_TEMP)/, $(notdir $(font_config)))
+
+$(font_config): $(FONT_TEMP)/%.xml: \
+			frameworks/base/data/fonts/%.xml
+	$(hide) mkdir -p $(dir $@)
+	$(hide) cp -vf $< $@
+
+# List of fonts on the device that we want to ship. This is all .ttf, .ttc and .otf fonts.
+fonts_device := $(filter $(TARGET_OUT)/fonts/%.ttf $(TARGET_OUT)/fonts/%.ttc $(TARGET_OUT)/fonts/%.otf, $(INTERNAL_SYSTEMIMAGE_FILES))
+fonts_device := $(addprefix $(FONT_TEMP)/, $(notdir $(fonts_device)))
+
+# TODO: If the font file is a symlink, reuse the font renamed from the symlink
+# target.
+$(fonts_device): $(FONT_TEMP)/%: $(TARGET_OUT)/fonts/%
+	$(hide) mkdir -p $(dir $@)
+	$(hide) cp -vf $< $@
+
+KEYBOARD_TEMP := $(call intermediates-dir-for,PACKAGING,keyboards,HOST,COMMON)
+
+# The key character map files needed for supporting KeyEvent
+keyboards := $(sort $(wildcard frameworks/base/data/keyboards/*.kcm))
+keyboards := $(addprefix $(KEYBOARD_TEMP)/, $(notdir $(keyboards)))
+
+$(keyboards): $(KEYBOARD_TEMP)/%.kcm: frameworks/base/data/keyboards/%.kcm
+	$(hide) mkdir -p $(dir $@)
+	$(hide) cp -vf $< $@
+
+# List of all data files - font files, font configuration files, key character map files
+LAYOUTLIB_FILES := $(fonts_device) $(font_config) $(keyboards)
+
+.PHONY: layoutlib layoutlib-tests
+layoutlib layoutlib-tests: $(LAYOUTLIB_FILES)
+
+$(call dist-for-goals, layoutlib, $(foreach m,$(fonts_device), $(m):layoutlib_native/fonts/$(notdir $(m))))
+$(call dist-for-goals, layoutlib, $(foreach m,$(font_config), $(m):layoutlib_native/fonts/$(notdir $(m))))
+$(call dist-for-goals, layoutlib, $(foreach m,$(keyboards), $(m):layoutlib_native/keyboards/$(notdir $(m))))
+
+FONT_TEMP :=
+font_config :=
+fonts_device :=
+FONT_FILES :=
+
+# The following build process of build.prop, layoutlib-res.zip is moved here from release_layoutlib.sh
+# so the SBOM of all platform neutral artifacts and Linux/Windows artifacts of layoutlib can be built in Make/Soong.
+# See go/layoutlib-sbom.
+
+# build.prop shipped with layoutlib
+LAYOUTLIB_BUILD_PROP := $(call intermediates-dir-for,PACKAGING,layoutlib-build-prop,HOST,COMMON)
+$(LAYOUTLIB_BUILD_PROP)/layoutlib-build.prop: $(INSTALLED_SDK_BUILD_PROP_TARGET)
+	rm -rf $@
+	cp $< $@
+	# Remove all the uncommon build properties
+	sed -i '/^ro\.\(build\|product\|config\|system\)/!d' $@
+	# Mark the build as layoutlib. This can be read at runtime by apps
+	sed -i 's|ro.product.brand=generic|ro.product.brand=studio|' $@
+	sed -i 's|ro.product.device=generic|ro.product.device=layoutlib|' $@
+
+$(call dist-for-goals,layoutlib,$(LAYOUTLIB_BUILD_PROP)/layoutlib-build.prop:layoutlib_native/build.prop)
+
+# Resource files from frameworks/base/core/res/res
+LAYOUTLIB_RES := $(call intermediates-dir-for,PACKAGING,layoutlib-res,HOST,COMMON)
+LAYOUTLIB_RES_FILES := $(shell find frameworks/base/core/res/res -type f -not -path 'frameworks/base/core/res/res/values-m[nc]c*' | sort)
+$(LAYOUTLIB_RES)/layoutlib-res.zip: $(SOONG_ZIP) $(HOST_OUT_EXECUTABLES)/aapt2 $(LAYOUTLIB_RES_FILES)
+	rm -rf $@
+	echo $(LAYOUTLIB_RES_FILES) > $(LAYOUTLIB_RES)/filelist.txt
+	$(SOONG_ZIP) -C frameworks/base/core/res -l $(LAYOUTLIB_RES)/filelist.txt -o $(LAYOUTLIB_RES)/temp.zip
+	rm -rf $(LAYOUTLIB_RES)/data && unzip -q -d $(LAYOUTLIB_RES)/data $(LAYOUTLIB_RES)/temp.zip
+	rm -rf $(LAYOUTLIB_RES)/compiled && mkdir $(LAYOUTLIB_RES)/compiled && $(HOST_OUT_EXECUTABLES)/aapt2 compile $(LAYOUTLIB_RES)/data/res/**/*.9.png -o $(LAYOUTLIB_RES)/compiled
+	printf '<?xml version="1.0" encoding="utf-8"?>\n<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.layoutlib" />' > $(LAYOUTLIB_RES)/AndroidManifest.xml
+	$(HOST_OUT_EXECUTABLES)/aapt2 link -R $(LAYOUTLIB_RES)/compiled/* -o $(LAYOUTLIB_RES)/compiled.apk --manifest $(LAYOUTLIB_RES)/AndroidManifest.xml
+	rm -rf $(LAYOUTLIB_RES)/compiled_apk && unzip -q -d $(LAYOUTLIB_RES)/compiled_apk $(LAYOUTLIB_RES)/compiled.apk
+	for f in $(LAYOUTLIB_RES)/compiled_apk/res/*; do mv "$$f" "$${f/-v4/}";done
+	for f in $(LAYOUTLIB_RES)/compiled_apk/res/**/*.9.png; do mv "$$f" "$${f/.9.png/.compiled.9.png}";done
+	cp -r $(LAYOUTLIB_RES)/compiled_apk/res $(LAYOUTLIB_RES)/data
+	$(SOONG_ZIP) -C $(LAYOUTLIB_RES)/data -D $(LAYOUTLIB_RES)/data/res -o $@
+
+$(call dist-for-goals,layoutlib,$(LAYOUTLIB_RES)/layoutlib-res.zip:layoutlib_native/res.zip)
+
+# SBOM of layoutlib artifacts
+LAYOUTLIB_SBOM := $(call intermediates-dir-for,PACKAGING,layoutlib-sbom,HOST)
+_layoutlib_font_config_files := $(sort $(wildcard frameworks/base/data/fonts/*.xml))
+_layoutlib_fonts_files := $(filter $(TARGET_OUT)/fonts/%.ttf $(TARGET_OUT)/fonts/%.ttc $(TARGET_OUT)/fonts/%.otf, $(INTERNAL_SYSTEMIMAGE_FILES))
+$(LAYOUTLIB_SBOM)/sbom-metadata.csv:
+	rm -rf $@
+	echo installed_file,module_path,soong_module_type,is_prebuilt_make_module,product_copy_files,kernel_module_copy_files,is_platform_generated,build_output_path,static_libraries,whole_static_libraries,is_static_lib >> $@
+	echo build.prop,,,,,,Y,$(LAYOUTLIB_BUILD_PROP)/layoutlib-build.prop,,, >> $@
+
+	$(foreach f,$(_layoutlib_font_config_files),\
+	  echo data/fonts/$(notdir $f),frameworks/base/data/fonts,prebuilt_etc,,,,,$f,,, >> $@; \
+	)
+
+	$(foreach f,$(_layoutlib_fonts_files), \
+	  $(eval _module_name := $(ALL_INSTALLED_FILES.$f)) \
+	  $(eval _module_path := $(strip $(sort $(ALL_MODULES.$(_module_name).PATH)))) \
+	  $(eval _soong_module_type := $(strip $(sort $(ALL_MODULES.$(_module_name).SOONG_MODULE_TYPE)))) \
+	  echo data/fonts/$(notdir $f),$(_module_path),$(_soong_module_type),,,,,$f,,, >> $@; \
+	)
+
+	$(foreach f,$(LAYOUTLIB_RES_FILES), \
+	  $(eval _path := $(subst frameworks/base/core/res,data,$f)) \
+	  echo $(_path),,,,,,Y,$f,,, >> $@; \
+	)
+
+.PHONY: layoutlib-sbom
+layoutlib-sbom: $(LAYOUTLIB_SBOM)/layoutlib.spdx.json
+$(LAYOUTLIB_SBOM)/layoutlib.spdx.json: $(PRODUCT_OUT)/always_dirty_file.txt $(LAYOUTLIB_SBOM)/sbom-metadata.csv $(_layoutlib_font_config_files) $(_layoutlib_fonts_files) $(LAYOUTLIB_BUILD_PROP)/layoutlib-build.prop $(LAYOUTLIB_RES_FILES)
+	rm -rf $@
+	$(GEN_SBOM) --output_file $@ --metadata $(LAYOUTLIB_SBOM)/sbom-metadata.csv --build_version $(BUILD_FINGERPRINT_FROM_FILE) --product_mfr "$(PRODUCT_MANUFACTURER)" --json
+
+$(call dist-for-goals,layoutlib,$(LAYOUTLIB_SBOM)/layoutlib.spdx.json:layoutlib_native/sbom/layoutlib.spdx.json)
+
+# Generate SBOM of framework_res.jar that is created in release_layoutlib.sh.
+# The generated SBOM contains placeholders for release_layotlib.sh to substitute, and the placeholders include:
+# document name, document namespace, document creation info, organization and SHA1 value of framework_res.jar.
+GEN_SBOM_FRAMEWORK_RES := $(HOST_OUT_EXECUTABLES)/generate-sbom-framework_res
+.PHONY: layoutlib-framework_res-sbom
+layoutlib-framework_res-sbom: $(LAYOUTLIB_SBOM)/framework_res.jar.spdx.json
+$(LAYOUTLIB_SBOM)/framework_res.jar.spdx.json: $(LAYOUTLIB_SBOM)/layoutlib.spdx.json $(GEN_SBOM_FRAMEWORK_RES)
+	rm -rf $@
+	$(GEN_SBOM_FRAMEWORK_RES) --output_file $(LAYOUTLIB_SBOM)/framework_res.jar.spdx.json --layoutlib_sbom $(LAYOUTLIB_SBOM)/layoutlib.spdx.json
+
+$(call dist-for-goals,layoutlib,$(LAYOUTLIB_SBOM)/framework_res.jar.spdx.json:layoutlib_native/sbom/framework_res.jar.spdx.json)
\ No newline at end of file
diff --git a/core/layoutlib_fonts.mk b/core/layoutlib_fonts.mk
deleted file mode 100644
index d2a814f..0000000
--- a/core/layoutlib_fonts.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# Fonts for layoutlib
-
-FONT_TEMP := $(call intermediates-dir-for,PACKAGING,fonts,HOST,COMMON)
-
-# The font configuration files - system_fonts.xml, fallback_fonts.xml etc.
-font_config := $(sort $(wildcard frameworks/base/data/fonts/*.xml))
-font_config := $(addprefix $(FONT_TEMP)/, $(notdir $(font_config)))
-
-$(font_config): $(FONT_TEMP)/%.xml: \
-			frameworks/base/data/fonts/%.xml
-	$(hide) mkdir -p $(dir $@)
-	$(hide) cp -vf $< $@
-
-# List of fonts on the device that we want to ship. This is all .ttf, .ttc and .otf fonts.
-fonts_device := $(filter $(TARGET_OUT)/fonts/%.ttf $(TARGET_OUT)/fonts/%.ttc $(TARGET_OUT)/fonts/%.otf, $(INTERNAL_SYSTEMIMAGE_FILES))
-fonts_device := $(addprefix $(FONT_TEMP)/, $(notdir $(fonts_device)))
-
-# TODO: If the font file is a symlink, reuse the font renamed from the symlink
-# target.
-$(fonts_device): $(FONT_TEMP)/%: $(TARGET_OUT)/fonts/%
-	$(hide) mkdir -p $(dir $@)
-	$(hide) cp -vf $< $@
-
-# List of all dependencies - all fonts and configuration files.
-FONT_FILES := $(fonts_device) $(font_config)
-
-.PHONY: layoutlib layoutlib-tests
-layoutlib layoutlib-tests: $(FONT_FILES)
-
-$(call dist-for-goals, layoutlib, $(foreach m,$(FONT_FILES), $(m):layoutlib_native/fonts/$(notdir $(m))))
-
-FONT_TEMP :=
-font_config :=
-fonts_device :=
-FONT_FILES :=
diff --git a/core/main.mk b/core/main.mk
index 7c25862..c345c96 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -563,6 +563,7 @@
 # sources or dependencies for these tools may be missing from the tree.
 ifeq (,$(TARGET_BUILD_UNBUNDLED_IMAGE))
 droid_targets : blueprint_tools
+checkbuild: blueprint_tests
 endif
 
 endif # dont_bother
diff --git a/core/release_config.bzl b/core/release_config.bzl
index a2f59e6..0c08858 100644
--- a/core/release_config.bzl
+++ b/core/release_config.bzl
@@ -11,6 +11,9 @@
 # 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.
+"""
+Export build flags (with values) to make.
+"""
 
 load("//build/bazel/utils:schema_validation.bzl", "validate")
 
@@ -73,7 +76,16 @@
 }
 
 def flag(name, partitions, default):
-    "Declare a flag."
+    """Declare a flag.
+
+    Args:
+      name: name of the flag
+      partitions: the partitions where this should be recorded.
+      default: the default value of the flag.
+
+    Returns:
+      A dictionary containing the flag declaration.
+    """
     if not partitions:
         fail("At least 1 partition is required")
     if not name.startswith("RELEASE_"):
@@ -96,14 +108,29 @@
     }
 
 def value(name, value):
-    "Define the flag value for a particular configuration."
+    """Define the flag value for a particular configuration.
+
+    Args:
+      name: The name of the flag.
+      value: The value for the flag.
+
+    Returns:
+      A dictionary containing the name and value to be used.
+    """
     return {
         "name": name,
         "value": value,
     }
 
 def _format_value(val):
-    "Format the starlark type correctly for make"
+    """Format the starlark type correctly for make.
+
+    Args:
+      val: The value to format
+
+    Returns:
+      The value, formatted correctly for make.
+    """
     if type(val) == "NoneType":
         return ""
     elif type(val) == "bool":
@@ -112,7 +139,15 @@
         return val
 
 def release_config(all_flags, all_values):
-    "Return the make variables that should be set for this release config."
+    """Return the make variables that should be set for this release config.
+
+    Args:
+      all_flags: A list of flag objects (from flag() calls).
+      all_values: A list of value objects (from value() calls).
+
+    Returns:
+      A dictionary of {name: value} variables for make.
+    """
     validate(all_flags, _all_flags_schema)
     validate(all_values, _all_values_schema)
 
diff --git a/core/soong_config.mk b/core/soong_config.mk
index e541c12..be6a795 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -8,6 +8,7 @@
 ifndef AFDO_PROFILES
 # Set AFDO_PROFILES
 -include vendor/google_data/pgo_profile/sampling/afdo_profiles.mk
+include toolchain/pgo-profiles/sampling/afdo_profiles.mk
 else
 $(error AFDO_PROFILES can only be set from soong_config.mk. For product-specific fdo_profiles, please use PRODUCT_AFDO_PROFILES)
 endif
@@ -15,6 +16,10 @@
 # PRODUCT_AFDO_PROFILES takes precedence over product-agnostic profiles in AFDO_PROFILES
 ALL_AFDO_PROFILES := $(PRODUCT_AFDO_PROFILES) $(AFDO_PROFILES)
 
+ifneq (,$(filter-out environment undefined,$(origin GENRULE_SANDBOXING)))
+  $(error GENRULE_SANDBOXING can only be provided via an environment variable, use BUILD_BROKEN_GENRULE_SANDBOXING to disable genrule sandboxing in board config)
+endif
+
 ifeq ($(WRITE_SOONG_VARIABLES),true)
 
 # Create soong.variables with copies of makefile settings.  Runs every build,
@@ -280,7 +285,8 @@
 $(call add_json_bool, BuildBrokenClangProperty,            $(filter true,$(BUILD_BROKEN_CLANG_PROPERTY)))
 $(call add_json_bool, BuildBrokenClangAsFlags,             $(filter true,$(BUILD_BROKEN_CLANG_ASFLAGS)))
 $(call add_json_bool, BuildBrokenClangCFlags,              $(filter true,$(BUILD_BROKEN_CLANG_CFLAGS)))
-$(call add_json_bool, GenruleSandboxing,                   $(filter true,$(GENRULE_SANDBOXING)))
+# Use the value of GENRULE_SANDBOXING if set, otherwise use the inverse of BUILD_BROKEN_GENRULE_SANDBOXING
+$(call add_json_bool, GenruleSandboxing,                   $(if $(GENRULE_SANDBOXING),$(filter true,$(GENRULE_SANDBOXING)),$(if $(filter true,$(BUILD_BROKEN_GENRULE_SANDBOXING)),,true)))
 $(call add_json_bool, BuildBrokenEnforceSyspropOwner,      $(filter true,$(BUILD_BROKEN_ENFORCE_SYSPROP_OWNER)))
 $(call add_json_bool, BuildBrokenTrebleSyspropNeverallow,  $(filter true,$(BUILD_BROKEN_TREBLE_SYSPROP_NEVERALLOW)))
 $(call add_json_bool, BuildBrokenUsesSoongPython2Modules,  $(filter true,$(BUILD_BROKEN_USES_SOONG_PYTHON2_MODULES)))
@@ -313,7 +319,7 @@
 $(call add_json_list, BuildVersionTags,    $(BUILD_VERSION_TAGS))
 
 $(call add_json_str, ReleaseVersion,    $(_RELEASE_VERSION))
-$(call add_json_str, ReleaseAconfigValueSets,    $(RELEASE_ACONFIG_VALUE_SETS))
+$(call add_json_list, ReleaseAconfigValueSets,    $(RELEASE_ACONFIG_VALUE_SETS))
 $(call add_json_str, ReleaseAconfigFlagDefaultPermission,    $(RELEASE_ACONFIG_FLAG_DEFAULT_PERMISSION))
 
 $(call add_json_bool, ReleaseDefaultModuleBuildFromSource,   $(RELEASE_DEFAULT_MODULE_BUILD_FROM_SOURCE))
@@ -380,6 +386,8 @@
   $(call add_json_bool, CopyImagesForTargetFilesZip, $(filter true,$(COPY_IMAGES_FOR_TARGET_FILES_ZIP)))
 
   $(call add_json_bool, BoardAvbEnable, $(filter true,$(BOARD_AVB_ENABLE)))
+
+  $(call add_json_list, ProductPackages, $(sort $(PRODUCT_PACKAGES)))
 $(call end_json_map)
 
 $(call add_json_bool, NextReleaseHideFlaggedApi, $(filter true,$(PRODUCT_NEXT_RELEASE_HIDE_FLAGGED_API)))
diff --git a/core/sysprop.mk b/core/sysprop.mk
index a37fd05..4e8e976 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -46,7 +46,6 @@
         echo "ro.product.$(1).manufacturer=$(PRODUCT_MANUFACTURER)" >> $(2);\
         echo "ro.product.$(1).model=$(PRODUCT_MODEL)" >> $(2);\
         echo "ro.product.$(1).name=$(TARGET_PRODUCT)" >> $(2);\
-        # Attestation specific properties for AOSP/GSI build running on device.
         if [ -n "$(strip $(PRODUCT_MODEL_FOR_ATTESTATION))" ]; then \
             echo "ro.product.model_for_attestation=$(PRODUCT_MODEL_FOR_ATTESTATION)" >> $(2);\
         fi; \
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index 593b7b6..91cb2c9 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -37,7 +37,7 @@
   cts_platform_release_path := cts/tests/tests/os/assets/platform_releases.txt
   cts_platform_release_string := $(shell cat $(cts_platform_release_path))
 
-  ifeq ($(RELEASE_PLATFORM_VERSION_CODENAME_REL),)
+  ifneq (REL,$(PLATFORM_VERSION_CODENAME))
     ifeq (,$(findstring $(PLATFORM_VERSION),$(cts_platform_version_string)))
       define error_msg
         ============================================================
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
deleted file mode 100644
index 379369e..0000000
--- a/core/version_defaults.mk
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#
-# Handle various build version information.
-#
-# Guarantees that the following are defined:
-#     PLATFORM_VERSION
-#     PLATFORM_DISPLAY_VERSION
-#     PLATFORM_SDK_VERSION
-#     PLATFORM_VERSION_CODENAME
-#     DEFAULT_APP_TARGET_SDK
-#     BUILD_ID
-#     BUILD_NUMBER
-#     PLATFORM_SECURITY_PATCH
-#     PLATFORM_VNDK_VERSION
-#     PLATFORM_SYSTEMSDK_VERSIONS
-#
-
-# Look for an optional file containing overrides of the defaults,
-# but don't cry if we don't find it.  We could just use -include, but
-# the build.prop target also wants INTERNAL_BUILD_ID_MAKEFILE to be set
-# if the file exists.
-#
-INTERNAL_BUILD_ID_MAKEFILE := $(wildcard $(BUILD_SYSTEM)/build_id.mk)
-ifdef INTERNAL_BUILD_ID_MAKEFILE
-  include $(INTERNAL_BUILD_ID_MAKEFILE)
-endif
-
-# Set release configuration. The default resides in build/release/build_flags.mk.
-MIN_PLATFORM_VERSION := UP1A
-MAX_PLATFORM_VERSION := VP1A
-
-# The last stable version name of the platform that was released.  During
-# development, this stays at that previous version, while the codename indicates
-# further work based on the previous version.
-PLATFORM_VERSION_LAST_STABLE := 14
-.KATI_READONLY := PLATFORM_VERSION_LAST_STABLE
-
-# These are the current development codenames, if the build is not a final
-# release build.  If this is a final release build, it is simply "REL".
-# Note that this may be overridden by RELEASE_VERSION_CODENAME_REL in
-# version_util.mk.
-PLATFORM_VERSION_CODENAME.UP1A := UpsideDownCake
-PLATFORM_VERSION_CODENAME.VP1A := VanillaIceCream
-
-# This is the user-visible version.  In a final release build it should
-# be empty to use PLATFORM_VERSION as the user-visible version.  For
-# a preview release it can be set to a user-friendly value like `12 Preview 1`
-PLATFORM_DISPLAY_VERSION :=
-
-ifndef PLATFORM_SDK_VERSION
-  # This is the canonical definition of the SDK version, which defines
-  # the set of APIs and functionality available in the platform.  It
-  # is a single integer that increases monotonically as updates to
-  # the SDK are released.  It should only be incremented when the APIs for
-  # the new release are frozen (so that developers don't write apps against
-  # intermediate builds).  During development, this number remains at the
-  # SDK version the branch is based on and PLATFORM_VERSION_CODENAME holds
-  # the code-name of the new development work.
-
-  # When you increment the PLATFORM_SDK_VERSION please ensure you also
-  # clear out the following text file of all older PLATFORM_VERSION's:
-  # cts/tests/tests/os/assets/platform_versions.txt
-  PLATFORM_SDK_VERSION := 34
-endif
-.KATI_READONLY := PLATFORM_SDK_VERSION
-
-# This is the sdk extension version of this tree.
-PLATFORM_SDK_EXTENSION_VERSION := 7
-.KATI_READONLY := PLATFORM_SDK_EXTENSION_VERSION
-
-# This is the sdk extension version that PLATFORM_SDK_VERSION ships with.
-PLATFORM_BASE_SDK_EXTENSION_VERSION := $(PLATFORM_SDK_EXTENSION_VERSION)
-.KATI_READONLY := PLATFORM_BASE_SDK_EXTENSION_VERSION
-
-# This are all known codenames.
-PLATFORM_VERSION_KNOWN_CODENAMES := \
-Base Base11 Cupcake Donut Eclair Eclair01 EclairMr1 Froyo Gingerbread GingerbreadMr1 \
-Honeycomb HoneycombMr1 HoneycombMr2 IceCreamSandwich IceCreamSandwichMr1 \
-JellyBean JellyBeanMr1 JellyBeanMr2 Kitkat KitkatWatch Lollipop LollipopMr1 M N NMr1 O OMr1 P \
-Q R S Sv2 Tiramisu UpsideDownCake VanillaIceCream
-
-# Convert from space separated list to comma separated
-PLATFORM_VERSION_KNOWN_CODENAMES := \
-  $(call normalize-comma-list,$(PLATFORM_VERSION_KNOWN_CODENAMES))
-.KATI_READONLY := PLATFORM_VERSION_KNOWN_CODENAMES
-
-ifndef PLATFORM_SECURITY_PATCH
-    #  Used to indicate the security patch that has been applied to the device.
-    #  It must signify that the build includes all security patches issued up through the designated Android Public Security Bulletin.
-    #  It must be of the form "YYYY-MM-DD" on production devices.
-    #  It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
-    #  If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
-    PLATFORM_SECURITY_PATCH := 2023-10-05
-endif
-
-include $(BUILD_SYSTEM)/version_util.mk
diff --git a/core/version_util.mk b/core/version_util.mk
index 0cc3442..dfa0277 100644
--- a/core/version_util.mk
+++ b/core/version_util.mk
@@ -14,119 +14,99 @@
 # limitations under the License.
 #
 
-ALLOWED_VERSIONS := $(call allowed-platform-versions,\
-  $(MIN_PLATFORM_VERSION),\
-  $(MAX_PLATFORM_VERSION),\
-  $(RELEASE_PLATFORM_VERSION))
+
+#
+# Handle various build version information.
+#
+# Guarantees that the following are defined:
+#     PLATFORM_VERSION
+#     PLATFORM_DISPLAY_VERSION
+#     PLATFORM_SDK_VERSION
+#     PLATFORM_SDK_EXTENSION_VERSION
+#     PLATFORM_VERSION_CODENAME
+#     DEFAULT_APP_TARGET_SDK
+#     BUILD_ID
+#     BUILD_NUMBER
+#     PLATFORM_SECURITY_PATCH
+#     PLATFORM_VNDK_VERSION
+#     PLATFORM_SYSTEMSDK_VERSIONS
+#     PLATFORM_VERSION_LAST_STABLE
+#
+
+# Look for an optional file containing overrides of the defaults,
+# but don't cry if we don't find it.  We could just use -include, but
+# the build.prop target also wants INTERNAL_BUILD_ID_MAKEFILE to be set
+# if the file exists.
+#
+INTERNAL_BUILD_ID_MAKEFILE := $(wildcard $(BUILD_SYSTEM)/build_id.mk)
+ifdef INTERNAL_BUILD_ID_MAKEFILE
+  include $(INTERNAL_BUILD_ID_MAKEFILE)
+endif
 
 ifdef TARGET_PLATFORM_VERSION
   $(error Do not set TARGET_PLATFORM_VERSION directly. Use RELEASE_PLATFORM_VERSION. value: $(TARGET_PLATFORM_VERSION))
 endif
-
 TARGET_PLATFORM_VERSION := $(RELEASE_PLATFORM_VERSION)
-
-ifeq (,$(filter $(ALLOWED_VERSIONS), $(TARGET_PLATFORM_VERSION)))
-  $(warning Invalid TARGET_PLATFORM_VERSION '$(TARGET_PLATFORM_VERSION)', must be one of)
-  $(error $(ALLOWED_VERSIONS))
-endif
-ALLOWED_VERSIONS :=
-MIN_PLATFORM_VERSION :=
-MAX_PLATFORM_VERSION :=
-
 .KATI_READONLY := TARGET_PLATFORM_VERSION
 
-# Default versions for each TARGET_PLATFORM_VERSION
-# TODO: PLATFORM_VERSION, PLATFORM_SDK_VERSION, etc. should be conditional
-# on this
-
-# This is the canonical definition of the platform version,
-# which is the version that we reveal to the end user.
-# Update this value when the platform version changes (rather
-# than overriding it somewhere else).  Can be an arbitrary string.
-
-# When you change PLATFORM_VERSION for a given PLATFORM_SDK_VERSION
-# please add that PLATFORM_VERSION as well as clean up obsolete PLATFORM_VERSION's
-# in the following text file:
-# cts/tests/tests/os/assets/platform_versions.txt
-
-# Note that there should be one PLATFORM_VERSION and PLATFORM_VERSION_CODENAME
-# entry for each unreleased API level, regardless of
-# MIN_PLATFORM_VERSION/MAX_PLATFORM_VERSION. PLATFORM_VERSION is used to
-# generate the range of allowed SDK versions, so it must have an entry for every
-# unreleased API level targetable by this branch, not just those that are valid
-# lunch targets for this branch.
-
-# Release config flag to override the current version to REL.  Note that the
-# codename can also be locked to REL by setting it in versino_defaults.mk.
-ifneq ($(RELEASE_PLATFORM_VERSION_CODENAME_REL),)
-  PLATFORM_VERSION_CODENAME.$(TARGET_PLATFORM_VERSION) := REL
+ifdef PLATFORM_SECURITY_PATCH
+  $(error Do not set PLATFORM_SECURITY_PATCH directly. Use RELEASE_PLATFORM_SECURITY_PATCH. value: $(PLATFORM_SECURITY_PATCH))
 endif
+PLATFORM_SECURITY_PATCH := $(RELEASE_PLATFORM_SECURITY_PATCH)
+.KATI_READONLY := PLATFORM_SECURITY_PATCH
 
-PLATFORM_VERSION_CODENAME := $(PLATFORM_VERSION_CODENAME.$(TARGET_PLATFORM_VERSION))
-ifndef PLATFORM_VERSION_CODENAME
-  # PLATFORM_VERSION_CODENAME falls back to TARGET_PLATFORM_VERSION
-  PLATFORM_VERSION_CODENAME := $(TARGET_PLATFORM_VERSION)
+ifdef PLATFORM_SDK_VERSION
+  $(error Do not set PLATFORM_SDK_VERSION directly. Use RELEASE_PLATFORM_SDK_VERSION. value: $(PLATFORM_SDK_VERSION))
 endif
+PLATFORM_SDK_VERSION := $(RELEASE_PLATFORM_SDK_VERSION)
+.KATI_READONLY := PLATFORM_SDK_VERSION
 
-# This is all of the *active* development codenames.
-# This confusing name is needed because
-# all_codenames has been baked into build.prop for ages.
-#
-# Should be either the same as PLATFORM_VERSION_CODENAME or a comma-separated
-# list of additional codenames after PLATFORM_VERSION_CODENAME.
-PLATFORM_VERSION_ALL_CODENAMES :=
-
-# Build a list of all active code names. Avoid duplicates, and stop when we
-# reach a codename that matches PLATFORM_VERSION_CODENAME (anything beyond
-# that is not included in our build).
-_versions_in_target := \
-  $(call find_and_earlier,$(ALL_VERSIONS),$(TARGET_PLATFORM_VERSION))
-$(foreach version,$(_versions_in_target),\
-  $(eval _codename := $(PLATFORM_VERSION_CODENAME.$(version)))\
-  $(if $(filter $(_codename),$(PLATFORM_VERSION_ALL_CODENAMES)),,\
-    $(eval PLATFORM_VERSION_ALL_CODENAMES += $(_codename))))
-
-# And the list of actually all the codenames that are in preview. The
-# ALL_CODENAMES variable is sort of a lie for historical reasons and only
-# includes codenames up to and including the currently active codename, whereas
-# this variable also includes future codenames. For example, while AOSP is still
-# merging into U, but V development has started, ALL_CODENAMES will only be U,
-# but ALL_PREVIEW_CODENAMES will be U and V.
-#
-# REL is filtered out of the list. The codename of the current release is
-# replaced by "REL" when the build is configured as a release rather than a
-# preview. For example, PLATFORM_VERSION_CODENAME.UpsideDownCake will be "REL"
-# rather than UpsideDownCake in a -next target when the upcoming release is
-# UpsideDownCake. "REL" is a codename (and android.os.Build relies on this:
-# https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/os/Build.java;l=484-487;drc=316e3d16c9f34212f3beace7695289651d15a071),
-# so it should be in PLATFORM_VERSION_ALL_CODENAMES, but it definitely is not a
-# preview codename.
-PLATFORM_VERSION_ALL_PREVIEW_CODENAMES :=
-$(foreach version,$(ALL_VERSIONS),\
-  $(eval _codename := $(PLATFORM_VERSION_CODENAME.$(version)))\
-  $(if $(filter REL,$(_codename)),,\
-      $(if $(filter $(_codename),$(PLATFORM_VERSION_ALL_PREVIEW_CODENAMES)),,\
-        $(eval PLATFORM_VERSION_ALL_PREVIEW_CODENAMES += $(_codename)))))
-
-# And convert from space separated to comma separated.
-PLATFORM_VERSION_ALL_CODENAMES := \
-  $(subst $(space),$(comma),$(strip $(PLATFORM_VERSION_ALL_CODENAMES)))
-PLATFORM_VERSION_ALL_PREVIEW_CODENAMES := \
-  $(subst $(space),$(comma),$(strip $(PLATFORM_VERSION_ALL_PREVIEW_CODENAMES)))
-
-.KATI_READONLY := \
-  PLATFORM_VERSION_CODENAME \
-  PLATFORM_VERSION_ALL_CODENAMES \
-  PLATFORM_VERSION_ALL_PREVIEW_CODENAMES \
-
-ifneq (REL,$(PLATFORM_VERSION_CODENAME))
-  codenames := \
-    $(subst $(comma),$(space),$(strip $(PLATFORM_VERSION_KNOWN_CODENAMES)))
-  ifeq ($(filter $(PLATFORM_VERSION_CODENAME),$(codenames)),)
-    $(error '$(PLATFORM_VERSION_CODENAME)' is not in '$(codenames)'. \
-        Add PLATFORM_VERSION_CODENAME to PLATFORM_VERSION_KNOWN_CODENAMES)
-  endif
+ifdef PLATFORM_SDK_EXTENSION_VERSION
+  $(error Do not set PLATFORM_SDK_EXTENSION_VERSION directly. Use RELEASE_PLATFORM_SDK_EXTENSION_VERSION. value: $(PLATFORM_SDK_EXTENSION_VERSION))
 endif
+PLATFORM_SDK_EXTENSION_VERSION := $(RELEASE_PLATFORM_SDK_EXTENSION_VERSION)
+.KATI_READONLY := PLATFORM_SDK_EXTENSION_VERSION
+
+# This is the sdk extension version that PLATFORM_SDK_VERSION ships with.
+PLATFORM_BASE_SDK_EXTENSION_VERSION := $(PLATFORM_SDK_EXTENSION_VERSION)
+.KATI_READONLY := PLATFORM_BASE_SDK_EXTENSION_VERSION
+
+ifdef PLATFORM_VERSION_CODENAME
+  $(error Do not set PLATFORM_VERSION_CODENAME directly. Use RELEASE_PLATFORM_VERSION. value: $(PLATFORM_VERSION_CODENAME))
+endif
+PLATFORM_VERSION_CODENAME := $(RELEASE_PLATFORM_VERSION_CODENAME)
+.KATI_READONLY := PLATFORM_VERSION_CODENAME
+
+ifdef PLATFORM_VERSION_ALL_CODENAMES
+  $(error Do not set PLATFORM_VERSION_ALL_CODENAMES directly. Use RELEASE_PLATFORM_VERSION_ALL_CODENAMES. value: $(PLATFORM_VERSION_ALL_CODENAMES))
+endif
+PLATFORM_VERSION_ALL_CODENAMES := $(RELEASE_PLATFORM_VERSION_ALL_CODENAMES)
+.KATI_READONLY := PLATFORM_VERSION_ALL_CODENAMES
+
+ifdef PLATFORM_VERSION_ALL_PREVIEW_CODENAMES
+  $(error Do not set PLATFORM_VERSION_ALL_PREVIEW_CODENAMES directly. Use RELEASE_PLATFORM_VERSION_ALL_PREVIEW_CODENAMES. value: $(PLATFORM_VERSION_ALL_PREVIEW_CODENAMES))
+endif
+PLATFORM_VERSION_ALL_PREVIEW_CODENAMES := $(RELEASE_PLATFORM_VERSION_ALL_PREVIEW_CODENAMES)
+.KATI_READONLY := PLATFORM_VERSION_ALL_PREVIEW_CODENAMES
+
+ifdef PLATFORM_VERSION_LAST_STABLE
+  $(error Do not set PLATFORM_VERSION_LAST_STABLE directly. Use RELEASE_PLATFORM_VERSION_LAST_STABLE. value: $(PLATFORM_VERSION_CODENAME))
+endif
+PLATFORM_VERSION_LAST_STABLE := $(RELEASE_PLATFORM_VERSION_LAST_STABLE)
+.KATI_READONLY := PLATFORM_VERSION_LAST_STABLE
+
+
+# This are all known codenames. Should this move into the release config?
+PLATFORM_VERSION_KNOWN_CODENAMES := \
+Base Base11 Cupcake Donut Eclair Eclair01 EclairMr1 Froyo Gingerbread GingerbreadMr1 \
+Honeycomb HoneycombMr1 HoneycombMr2 IceCreamSandwich IceCreamSandwichMr1 \
+JellyBean JellyBeanMr1 JellyBeanMr2 Kitkat KitkatWatch Lollipop LollipopMr1 M N NMr1 O OMr1 P \
+Q R S Sv2 Tiramisu UpsideDownCake VanillaIceCream
+
+# Convert from space separated list to comma separated
+PLATFORM_VERSION_KNOWN_CODENAMES := \
+  $(call normalize-comma-list,$(PLATFORM_VERSION_KNOWN_CODENAMES))
+.KATI_READONLY := PLATFORM_VERSION_KNOWN_CODENAMES
 
 ifndef PLATFORM_VERSION
   ifeq (REL,$(PLATFORM_VERSION_CODENAME))
diff --git a/envsetup.sh b/envsetup.sh
index 63837ec..2ea5507 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -774,7 +774,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 +784,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))
@@ -1613,8 +1613,8 @@
 # Return the Bazel label of a Soong module if it is converted with bp2build.
 function bmod()
 (
-    if [ $# -ne 1 ]; then
-        echo "usage: bmod <module>" >&2
+    if [ $# -eq 0 ]; then
+        echo "usage: bmod <module 1> <module 2> ... <module n>" >&2
         return 1
     fi
 
@@ -1631,19 +1631,24 @@
       return 1
     fi
 
-    local target_label=$(python3 -c "import json
-module = '$1'
+    modules=()
+    for m in "$@"; do
+        modules+=("\"$m\",")
+    done
+    local res=$(python3 -c "import json
+modules = [${modules[*]}]
 converted_json='$converted_json'
 bp2build_converted_map = json.load(open(converted_json))
-if module not in bp2build_converted_map:
-    exit(1)
-print(bp2build_converted_map[module] + ':' + module)")
+for module in modules:
+    if module not in bp2build_converted_map:
+        print(module + ' is not converted to Bazel.')
+    else:
+        print(bp2build_converted_map[module] + ':' + module)")
 
-    if [ -z "${target_label}" ]; then
-      echo "$1 is not converted to Bazel." >&2
-      return 1
-    else
-      echo "${target_label}"
+    echo "${res}"
+    unconverted_count=$(echo "${res}" | grep -c "not converted to Bazel")
+    if [[ ${unconverted_count} -ne 0 ]]; then
+        return 1
     fi
 )
 
@@ -2049,6 +2054,16 @@
     "$ANDROID_SOONG_HOST_OUT"/bin/avbtool $@
 }
 
+function overrideflags() {
+    local T="$(gettop)"
+    (\cd "${T}" && build/make/tools/overrideflags.sh "$@")
+}
+
+function aninja() {
+    local T="$(gettop)"
+    (\cd "${T}" && prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-${TARGET_PRODUCT}.ninja "$@")
+}
+
 validate_current_shell
 set_global_paths
 source_vendorsetup
diff --git a/target/board/emulator_arm/AndroidBoard.mk b/target/board/emulator_arm/AndroidBoard.mk
deleted file mode 100644
index 7911f61..0000000
--- a/target/board/emulator_arm/AndroidBoard.mk
+++ /dev/null
@@ -1 +0,0 @@
-LOCAL_PATH := $(call my-dir)
diff --git a/target/board/emulator_arm/BoardConfig.mk b/target/board/emulator_arm/BoardConfig.mk
deleted file mode 100644
index 287824f..0000000
--- a/target/board/emulator_arm/BoardConfig.mk
+++ /dev/null
@@ -1,37 +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.
-#
-
-# arm emulator specific definitions
-TARGET_ARCH := arm
-TARGET_ARCH_VARIANT := armv7-a-neon
-TARGET_CPU_VARIANT := generic
-TARGET_CPU_ABI := armeabi-v7a
-TARGET_CPU_ABI2 := armeabi
-
-include build/make/target/board/BoardConfigGsiCommon.mk
-include build/make/target/board/BoardConfigEmuCommon.mk
-
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
-
-# 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_arm/device.mk b/target/board/emulator_arm/device.mk
deleted file mode 100644
index af023eb..0000000
--- a/target/board/emulator_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_arm/system_ext.prop b/target/board/emulator_arm/system_ext.prop
deleted file mode 100644
index 64829f3..0000000
--- a/target/board/emulator_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/board/emulator_x86/BoardConfig.mk b/target/board/emulator_x86/BoardConfig.mk
deleted file mode 100644
index 8f79166..0000000
--- a/target/board/emulator_x86/BoardConfig.mk
+++ /dev/null
@@ -1,40 +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_PRELINK_MODULE := false
-
-include build/make/target/board/BoardConfigGsiCommon.mk
-include build/make/target/board/BoardConfigEmuCommon.mk
-
-# 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/device.mk b/target/board/emulator_x86/device.mk
deleted file mode 100644
index 8a9d8da..0000000
--- a/target/board/emulator_x86/device.mk
+++ /dev/null
@@ -1,27 +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.
-
-ifdef NET_ETH0_STARTONBOOT
-  PRODUCT_VENDOR_PROPERTIES += net.eth0.startonboot=1
-endif
-
-# Ensure we package the BIOS files too.
-PRODUCT_HOST_PACKAGES += \
-	bios.bin \
-	vgabios-cirrus.bin \
diff --git a/target/board/emulator_x86/system_ext.prop b/target/board/emulator_x86/system_ext.prop
deleted file mode 100644
index 64829f3..0000000
--- a/target/board/emulator_x86/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 8787c59..18b36aa 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -68,9 +68,7 @@
     $(LOCAL_DIR)/ndk.mk \
     $(LOCAL_DIR)/sdk.mk \
     $(LOCAL_DIR)/sdk_phone_arm64.mk \
-    $(LOCAL_DIR)/sdk_phone_armv7.mk \
     $(LOCAL_DIR)/sdk_phone_x86_64.mk \
-    $(LOCAL_DIR)/sdk_phone_x86.mk \
 
 endif
 
@@ -86,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/target/product/base_system.mk b/target/product/base_system.mk
index aa08002..eac3026 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -53,6 +53,7 @@
     com.android.btservices \
     com.android.configinfrastructure \
     com.android.conscrypt \
+    com.android.crashrecovery \
     com.android.devicelock \
     com.android.extservices \
     com.android.healthfitness \
@@ -94,6 +95,7 @@
     flags_health_check \
     framework-graphics \
     framework-minus-apex \
+    framework-minus-apex-install-dependencies \
     framework-res \
     framework-sysconfig.xml \
     fsck.erofs \
@@ -294,7 +296,7 @@
 # These packages are not used on Android TV
 ifneq ($(PRODUCT_IS_ATV),true)
   PRODUCT_PACKAGES += \
-      SoundPicker \
+      $(RELEASE_PACKAGE_SOUND_PICKER) \
 
 endif
 
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index 04e9748..f7c92aa 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -65,6 +65,7 @@
     com.android.btservices:framework-bluetooth \
     com.android.configinfrastructure:framework-configinfrastructure \
     com.android.conscrypt:conscrypt \
+    com.android.crashrecovery:framework-crashrecovery \
     com.android.devicelock:framework-devicelock \
     com.android.healthfitness:framework-healthfitness \
     com.android.i18n:core-icu4j \
@@ -93,6 +94,7 @@
     com.android.appsearch:service-appsearch \
     com.android.art:service-art \
     com.android.configinfrastructure:service-configinfrastructure \
+    com.android.crashrecovery:service-crashrecovery \
     com.android.healthfitness:service-healthfitness \
     com.android.media:service-media-s \
     com.android.ondevicepersonalization:service-ondevicepersonalization \
diff --git a/target/product/fullmte.mk b/target/product/fullmte.mk
index d47c685..5726c06 100644
--- a/target/product/fullmte.mk
+++ b/target/product/fullmte.mk
@@ -20,7 +20,8 @@
 # For more details, see:
 # https://source.android.com/docs/security/test/memory-safety/arm-mte
 ifeq ($(filter memtag_heap,$(SANITIZE_TARGET)),)
-  SANITIZE_TARGET := $(strip $(SANITIZE_TARGET) memtag_heap memtag_stack)
+  # TODO(b/292478827): Re-enable memtag_stack when new toolchain rolls.
+  SANITIZE_TARGET := $(strip $(SANITIZE_TARGET) memtag_heap)
   SANITIZE_TARGET_DIAG := $(strip $(SANITIZE_TARGET_DIAG) memtag_heap)
 endif
 PRODUCT_PRODUCT_PROPERTIES += persist.arm64.memtag.default=sync
diff --git a/target/product/generic_system.mk b/target/product/generic_system.mk
index ab36eb1..6d40436 100644
--- a/target/product/generic_system.mk
+++ b/target/product/generic_system.mk
@@ -104,10 +104,6 @@
     libpolicy-subsystem
 
 
-ifneq ($(KEEP_VNDK),true)
-PRODUCT_PACKAGES += llndk.libraries.txt
-endif
-
 # Include all zygote init scripts. "ro.zygote" will select one of them.
 PRODUCT_COPY_FILES += \
     system/core/rootdir/init.zygote32.rc:system/etc/init/hw/init.zygote32.rc \
diff --git a/target/product/gsi/Android.mk b/target/product/gsi/Android.mk
index 655a666..fa3d1da 100644
--- a/target/product/gsi/Android.mk
+++ b/target/product/gsi/Android.mk
@@ -230,7 +230,9 @@
 
 # Filter LLNDK libs moved to APEX to avoid pulling them into /system/LIB
 LOCAL_REQUIRED_MODULES := \
-    $(filter-out $(LLNDK_MOVED_TO_APEX_LIBRARIES),$(LLNDK_LIBRARIES))
+    $(filter-out $(LLNDK_MOVED_TO_APEX_LIBRARIES),$(LLNDK_LIBRARIES)) \
+    llndk.libraries.txt
+
 
 include $(BUILD_PHONY_PACKAGE)
 
diff --git a/target/product/handheld_system.mk b/target/product/handheld_system.mk
index 6c93dd7..00b62bc 100644
--- a/target/product/handheld_system.mk
+++ b/target/product/handheld_system.mk
@@ -40,6 +40,7 @@
     BuiltInPrintService \
     CalendarProvider \
     cameraserver \
+    com.android.nfcservices \
     CameraExtensionsProxy \
     CaptivePortalLogin \
     CertInstaller \
@@ -56,7 +57,6 @@
     MmsService \
     MtpService \
     MusicFX \
-    NfcNci \
     PacProcessor \
     preinstalled-packages-platform-handheld-system.xml \
     PrintRecommendationService \
diff --git a/target/product/sdk_phone_armv7.mk b/target/product/sdk_phone_armv7.mk
deleted file mode 100644
index 293b1ea..0000000
--- a/target/product/sdk_phone_armv7.mk
+++ /dev/null
@@ -1,66 +0,0 @@
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-PRODUCT_USE_DYNAMIC_PARTITIONS := true
-
-# This is a build configuration for a full-featured build of the
-# Open-Source part of the tree. It's geared toward a US-centric
-# build quite specifically for the emulator, and might not be
-# entirely appropriate to inherit from for on-device configurations.
-
-# Enable mainline checking for exact this product name
-ifeq (sdk_phone_armv7,$(TARGET_PRODUCT))
-PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := relaxed
-endif
-
-#
-# All components inherited here go to system image
-#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_system.mk)
-
-#
-# All components inherited here go to system_ext image
-#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system_ext.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system_ext.mk)
-
-#
-# All components inherited here go to product image
-#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_product.mk)
-
-#
-# All components inherited here go to vendor image
-#
-$(call inherit-product-if-exists, build/make/target/product/ramdisk_stub.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/board/emulator_arm/device.mk)
-
-# keep this apk for sdk targets for now
-PRODUCT_PACKAGES += \
-    EmulatorSmokeTests
-
-
-# Overrides
-PRODUCT_BRAND := Android
-PRODUCT_NAME := sdk_phone_armv7
-PRODUCT_DEVICE := emulator_arm
-PRODUCT_MODEL := Android SDK built for arm
-# Disable <uses-library> checks for SDK product. It lacks some libraries (e.g.
-# RadioConfigLib), which makes it impossible to translate their module names to
-# library name, so the check fails.
-PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true
-
-PRODUCT_NEXT_RELEASE_HIDE_FLAGGED_API := true
diff --git a/target/product/sdk_phone_x86.mk b/target/product/sdk_phone_x86.mk
deleted file mode 100644
index 90cd8d5..0000000
--- a/target/product/sdk_phone_x86.mk
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-PRODUCT_USE_DYNAMIC_PARTITIONS := true
-
-# This is a build configuration for a full-featured build of the
-# Open-Source part of the tree. It's geared toward a US-centric
-# build quite specifically for the emulator, and might not be
-# entirely appropriate to inherit from for on-device configurations.
-
-#
-# All components inherited here go to system image
-#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_system.mk)
-
-# Enable mainline checking for exact this product name
-ifeq (sdk_phone_x86,$(TARGET_PRODUCT))
-PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := relaxed
-endif
-
-#
-# All components inherited here go to system_ext image
-#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system_ext.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system_ext.mk)
-
-#
-# All components inherited here go to product image
-#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_product.mk)
-
-#
-# All components inherited here go to vendor image
-#
-$(call inherit-product-if-exists, device/generic/goldfish/x86-vendor.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/board/emulator_x86/device.mk)
-
-# Overrides
-PRODUCT_BRAND := Android
-PRODUCT_NAME := sdk_phone_x86
-PRODUCT_DEVICE := emulator_x86
-PRODUCT_MODEL := Android SDK built for x86
-# Disable <uses-library> checks for SDK product. It lacks some libraries (e.g.
-# RadioConfigLib), which makes it impossible to translate their module names to
-# library name, so the check fails.
-PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true
-
-PRODUCT_NEXT_RELEASE_HIDE_FLAGGED_API := true
diff --git a/tools/aconfig/fake_device_config/Android.bp b/tools/aconfig/fake_device_config/Android.bp
index 5f62ae9..7420aa8 100644
--- a/tools/aconfig/fake_device_config/Android.bp
+++ b/tools/aconfig/fake_device_config/Android.bp
@@ -15,7 +15,7 @@
 java_library {
 	name: "fake_device_config",
 	srcs: ["src/**/*.java"],
-	sdk_version: "core_platform",
-    host_supported: true,
+	sdk_version: "core_current",
+	host_supported: true,
 }
 
diff --git a/tools/aconfig/overrideflags/overrideflags.py b/tools/aconfig/overrideflags/overrideflags.py
new file mode 100644
index 0000000..e355c21
--- /dev/null
+++ b/tools/aconfig/overrideflags/overrideflags.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 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.
+"""Create Aconfig value building rules.
+
+This script will help to create Aconfig flag value building rules. It will
+parse necessary information in the value file to create the building rules, but
+it will not validate the value file. The validation will defer to the building
+system.
+"""
+
+import argparse
+import pathlib
+import re
+import sys
+
+
+_VALUE_LIST_TEMPLATE: str = """
+ACONFIG_VALUES_LIST_LOCAL = [{}]
+"""
+
+_ACONFIG_VALUES_TEMPLATE: str = """
+aconfig_values {{
+    name: "{}",
+    package: "{}",
+    srcs: [
+        "{}",
+    ]
+}}
+"""
+
+_ACONFIG_VALUES_NAME_SUFFIX: str = "aconfig-local-override-{}"
+
+_PACKAGE_REGEX = re.compile(r"^package\:\s*\"([\w\d\.]+)\"")
+_ANDROID_BP_FILE_NAME = r"Android.bp"
+
+
+def _parse_packages(file: pathlib.Path) -> set[str]:
+  packages = set()
+  with open(file) as f:
+    for line in f:
+      line = line.strip()
+      package_match = _PACKAGE_REGEX.match(line)
+      if package_match is None:
+        continue
+      package_name = package_match.group(1)
+      packages.add(package_name)
+
+  return packages
+
+
+def _create_android_bp(packages: set[str], file_name: str) -> str:
+  android_bp = ""
+  value_list = ",\n    ".join(
+      map(f'"{_ACONFIG_VALUES_NAME_SUFFIX}"'.format, packages)
+  )
+  if value_list:
+    value_list = "\n    " + value_list + "\n"
+  android_bp += _VALUE_LIST_TEMPLATE.format(value_list) + "\n"
+
+  for package in packages:
+    android_bp += _ACONFIG_VALUES_TEMPLATE.format(
+        _ACONFIG_VALUES_NAME_SUFFIX.format(package), package, file_name
+    )
+    android_bp += "\n"
+
+  return android_bp
+
+
+def _write_android_bp(new_android_bp: str, out: pathlib.Path) -> None:
+  if not out.is_dir():
+    out.mkdir(parents=True, exist_ok=True)
+
+  output = out.joinpath(_ANDROID_BP_FILE_NAME)
+  with open(output, "r+", encoding="utf8") as file:
+    lines = []
+    for line in file:
+      line = line.rstrip("\n")
+      if line.startswith("ACONFIG_VALUES_LIST_LOCAL"):
+        break
+      lines.append(line)
+    # Overwrite the file with the updated contents.
+    file.seek(0)
+    file.truncate()
+    file.write("\n".join(lines))
+    file.write(new_android_bp)
+
+
+def main(args):
+  """Program entry point."""
+  args_parser = argparse.ArgumentParser()
+  args_parser.add_argument(
+      "--overrides",
+      required=True,
+      help="The path to override file.",
+  )
+  args_parser.add_argument(
+      "--out",
+      required=True,
+      help="The path to output directory.",
+  )
+
+  args = args_parser.parse_args(args)
+  file = pathlib.Path(args.overrides)
+  out = pathlib.Path(args.out)
+  if not file.is_file():
+    raise FileNotFoundError(f"File '{file}' is not found")
+
+  packages = _parse_packages(file)
+  new_android_bp = _create_android_bp(packages, file.name)
+  _write_android_bp(new_android_bp, out)
+
+
+if __name__ == "__main__":
+  main(sys.argv[1:])
diff --git a/tools/aconfig/src/codegen_cpp.rs b/tools/aconfig/src/codegen_cpp.rs
index cf0abb9..aeb57a3 100644
--- a/tools/aconfig/src/codegen_cpp.rs
+++ b/tools/aconfig/src/codegen_cpp.rs
@@ -34,13 +34,17 @@
     let class_elements: Vec<ClassElement> =
         parsed_flags_iter.map(|pf| create_class_element(package, pf)).collect();
     let readwrite = class_elements.iter().any(|item| item.readwrite);
+    let has_fixed_read_only = class_elements.iter().any(|item| item.is_fixed_read_only);
     let header = package.replace('.', "_");
+    let package_macro = header.to_uppercase();
     let cpp_namespace = package.replace('.', "::");
     ensure!(codegen::is_valid_name_ident(&header));
     let context = Context {
         header: &header,
+        package_macro: &package_macro,
         cpp_namespace: &cpp_namespace,
         package,
+        has_fixed_read_only,
         readwrite,
         for_test: codegen_mode == CodegenMode::Test,
         class_elements,
@@ -79,8 +83,10 @@
 #[derive(Serialize)]
 pub struct Context<'a> {
     pub header: &'a str,
+    pub package_macro: &'a str,
     pub cpp_namespace: &'a str,
     pub package: &'a str,
+    pub has_fixed_read_only: bool,
     pub readwrite: bool,
     pub for_test: bool,
     pub class_elements: Vec<ClassElement>,
@@ -89,8 +95,10 @@
 #[derive(Serialize)]
 pub struct ClassElement {
     pub readwrite: bool,
+    pub is_fixed_read_only: bool,
     pub default_value: String,
     pub flag_name: String,
+    pub flag_macro: String,
     pub device_config_namespace: String,
     pub device_config_flag: String,
 }
@@ -98,12 +106,14 @@
 fn create_class_element(package: &str, pf: &ProtoParsedFlag) -> ClassElement {
     ClassElement {
         readwrite: pf.permission() == ProtoFlagPermission::READ_WRITE,
+        is_fixed_read_only: pf.is_fixed_read_only(),
         default_value: if pf.state() == ProtoFlagState::ENABLED {
             "true".to_string()
         } else {
             "false".to_string()
         },
         flag_name: pf.name().to_string(),
+        flag_macro: pf.name().to_uppercase(),
         device_config_namespace: pf.namespace().to_string(),
         device_config_flag: codegen::create_device_config_ident(package, pf.name())
             .expect("values checked at flag parse time"),
@@ -118,6 +128,14 @@
     const EXPORTED_PROD_HEADER_EXPECTED: &str = r#"
 #pragma once
 
+#ifndef COM_ANDROID_ACONFIG_TEST
+#define COM_ANDROID_ACONFIG_TEST(FLAG) COM_ANDROID_ACONFIG_TEST_##FLAG
+#endif
+
+#ifndef COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO
+#define COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO true
+#endif
+
 #ifdef __cplusplus
 
 #include <memory>
@@ -149,7 +167,7 @@
 }
 
 inline bool enabled_fixed_ro() {
-    return true;
+    return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
 }
 
 inline bool enabled_ro() {
@@ -319,7 +337,7 @@
             }
 
             virtual bool enabled_fixed_ro() override {
-                return true;
+                return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
             }
 
             virtual bool enabled_ro() override {
@@ -348,7 +366,7 @@
 }
 
 bool com_android_aconfig_test_enabled_fixed_ro() {
-    return true;
+    return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
 }
 
 bool com_android_aconfig_test_enabled_ro() {
diff --git a/tools/aconfig/templates/cpp_exported_header.template b/tools/aconfig/templates/cpp_exported_header.template
index 4d56dbc..6413699 100644
--- a/tools/aconfig/templates/cpp_exported_header.template
+++ b/tools/aconfig/templates/cpp_exported_header.template
@@ -1,9 +1,25 @@
 #pragma once
 
+{{ if not for_test- }}
+{{ if has_fixed_read_only- }}
+#ifndef {package_macro}
+#define {package_macro}(FLAG) {package_macro}_##FLAG
+#endif
+{{ for item in class_elements- }}
+{{ if item.is_fixed_read_only- }}
+#ifndef {package_macro}_{item.flag_macro}
+#define {package_macro}_{item.flag_macro} {item.default_value}
+#endif
+{{ endif }}
+{{ -endfor }}
+{{ -endif }}
+{{ -endif }}
+
 #ifdef __cplusplus
 
 #include <memory>
 
+
 namespace {cpp_namespace} \{
 
 class flag_provider_interface \{
@@ -15,7 +31,7 @@
     {{ if for_test }}
     virtual void {item.flag_name}(bool val) = 0;
     {{ -endif }}
-    {{ endfor }}
+    {{ -endfor }}
 
     {{ if for_test }}
     virtual void reset_flags() \{}
@@ -29,10 +45,14 @@
     {{ if for_test }}
     return provider_->{item.flag_name}();
     {{ -else- }}
-    {{ if not item.readwrite- }}
-    return {item.default_value};
-    {{ -else- }}
+    {{ if item.readwrite- }}
     return provider_->{item.flag_name}();
+    {{ -else- }}
+    {{ if item.is_fixed_read_only }}
+    return {package_macro}_{item.flag_macro};
+    {{ -else- }}
+    return {item.default_value};
+    {{ -endif }}
     {{ -endif }}
     {{ -endif }}
 }
@@ -42,7 +62,7 @@
     provider_->{item.flag_name}(val);
 }
 {{ -endif }}
-{{ endfor }}
+{{ -endfor }}
 
 {{ if for_test }}
 inline void reset_flags() \{
@@ -61,7 +81,7 @@
 {{ if for_test }}
 void set_{header}_{item.flag_name}(bool val);
 {{ -endif }}
-{{ endfor - }}
+{{ -endfor }}
 
 {{ if for_test }}
 void {header}_reset_flags();
diff --git a/tools/aconfig/templates/cpp_source_file.template b/tools/aconfig/templates/cpp_source_file.template
index 5b71b31..0f1b845 100644
--- a/tools/aconfig/templates/cpp_source_file.template
+++ b/tools/aconfig/templates/cpp_source_file.template
@@ -58,7 +58,11 @@
                 "{item.device_config_flag}",
                 "{item.default_value}") == "true";
             {{ -else- }}
-                return {item.default_value};
+            {{ if item.is_fixed_read_only }}
+            return {package_macro}_{item.flag_macro};
+            {{ -else- }}
+            return {item.default_value};
+            {{ -endif }}
             {{ -endif }}
         }
         {{ endfor }}
@@ -79,10 +83,14 @@
     {{ if for_test }}
     return {cpp_namespace}::{item.flag_name}();
     {{ -else- }}
-    {{ if not item.readwrite- }}
-    return {item.default_value};
-    {{ -else- }}
+    {{ if item.readwrite- }}
     return {cpp_namespace}::{item.flag_name}();
+    {{ -else- }}
+    {{ if item.is_fixed_read_only }}
+    return {package_macro}_{item.flag_macro};
+    {{ -else- }}
+    return {item.default_value};
+    {{ -endif }}
     {{ -endif }}
     {{ -endif }}
 }
diff --git a/tools/overrideflags.sh b/tools/overrideflags.sh
new file mode 100755
index 0000000..b8605dc
--- /dev/null
+++ b/tools/overrideflags.sh
@@ -0,0 +1,99 @@
+#!/bin/bash -e
+# Copyright (C) 2023 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.
+
+
+source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../shell_utils.sh
+require_top
+
+function print_help() {
+    echo -e "overrideflags is used to set default value for local build."
+    echo -e "\nOptions:"
+    echo -e "\t--release-config  \tPath to release configuration directory. Required"
+    echo -e "\t--no-edit         \tIf present, skip editing flag value file."
+    echo -e "\t-h/--help         \tShow this help."
+}
+
+function main() {
+    while (($# > 0)); do
+        case $1 in
+        --release-config)
+            if [[ $# -le 1 ]]; then
+                echo "--release-config requires a path"
+                return 1
+            fi
+            local release_config_dir="$2"
+            shift 2
+            ;;
+        --no-edit)
+            local no_edit="true"
+            shift 1
+            ;;
+        -h|--help)
+            print_help
+            return
+            ;;
+        *)
+            echo "$1 is unrecognized"
+            print_help
+            return 1
+            ;;
+        esac
+    done
+
+
+
+    case $(uname -s) in
+        Darwin)
+            local host_arch=darwin-x86
+            ;;
+        Linux)
+            local host_arch=linux-x86
+            ;;
+        *)
+            >&2 echo Unknown host $(uname -s)
+            return
+            ;;
+    esac
+
+    if [[ -z "${release_config_dir}" ]]; then
+        echo "Please provide release configuration path by --release-config"
+        exit 1
+    elif [ ! -d "${release_config_dir}" ]; then
+        echo "${release_config_dir} is an invalid directory"
+        exit 1
+    fi
+    local T="$(gettop)"
+    local aconfig_dir="${T}"/build/make/tools/aconfig/
+    local overrideflag_py="${aconfig_dir}"/overrideflags/overrideflags.py
+    local overridefile="${release_config_dir}/aconfig/override_values.textproto"
+
+    # Edit override file
+    if [[ -z "${no_edit}" ]]; then
+        editor="${EDITOR:-$(which vim)}"
+
+        eval "${editor} ${overridefile}"
+        if [ $? -ne 0 ]; then
+            echo "Fail to set override values"
+            return 1
+        fi
+    fi
+
+    ${T}/prebuilts/build-tools/${host_arch}/bin/py3-cmd -u "${overrideflag_py}" \
+        --overrides "${overridefile}" \
+        --out "${release_config_dir}/aconfig"
+}
+
+
+main "$@"
diff --git a/tools/protos/metadata_file.proto b/tools/protos/metadata_file.proto
index ac1129a..47562c5 100644
--- a/tools/protos/metadata_file.proto
+++ b/tools/protos/metadata_file.proto
@@ -92,6 +92,8 @@
     SBOMRef sbom_ref = 10;
   }
 
+  // Identifiers for the package.
+  repeated Identifier identifier = 11;
 }
 
 // URL associated with a third-party package.
@@ -278,4 +280,136 @@
   // https://spdx.github.io/spdx-spec/v2.3/package-information/#72-package-spdx-identifier-field or
   // https://spdx.github.io/spdx-spec/v2.3/file-information/#82-file-spdx-identifier-field
   optional string element_id = 3;
+}
+
+// Identifier for a third-package package.
+// See go/tp-metadata-id.
+message Identifier {
+  // The type of the identifier. Either an "ecosystem" value from
+  // https://ossf.github.io/osv-schema/#affectedpackage-field such as "Go",
+  // "npm" or "PyPI". The "value" and "version" fields follow the same rules as
+  // defined in the OSV spec.
+
+  // Or one of:
+  //  - "Git": The "value" field is the URL of the upstream git repository this
+  //  package is retrieved from.
+  //  For example:
+  //   - https://github.com/git/git
+  //   - git://git.kernel.org/pub/scm/git/git
+  //
+  //  Use of a git URL requires that the package "version" value must specify a
+  //  specific git tag or revision. This must not be a branch name.
+  //
+  //  - "SVN": The "value" field is the URL of the upstream SVN repository this
+  //  package is retrieved from.
+  //  For example:
+  //   - http://llvm.org/svn/llvm-project/llvm/
+  //
+  //  Use of an SVN URL requires that the package "version" value must specify
+  //  a specific SVN tag or revision. This must not be a branch name.
+  //
+  //  - "Hg": The "value" field is the URL of the upstream mercurial repository
+  //  this package is retrieved from.
+  //  For example:
+  //   - https://mercurial-scm.org/repo/evolve
+  //
+  //  Use of a mercurial URL requires that the package "version" value must
+  //  specify a specific tag or revision. This must not be a branch name.
+  //
+  //  - "Darcs": the "value" field is the URL of the upstream darcs repository
+  //  this package is retrieved from.
+  //  For example:
+  //   - https://hub.darcs.net/hu.dwim/hu.dwim.util
+  //
+  //  Use of a Darcs URL requires that the package "version" value must
+  //  specify a specific tag or revision. This must not be a branch name.
+  //
+  //  - "Piper": The "value" field is the URL of the upstream piper location.
+  //  This is primarily used when a package is being migrated into third_party
+  //  from elsewhere in Piper, or when a package is being newly developed in
+  //  third_party.
+  //
+  //  - "VCS": This is a generic fallback for an unlisted VCS system. The
+  // "value" field is the URL of the repository for this VCS.
+  //
+  //  - "Archive": The "value" field is the URL of the archive containing the
+  //  source code for the package, for example a zip or tgz file.
+  //
+  //  - "PrebuiltByAlphabet": This type should be used for archives of primarily
+  //  Google-owned source code (may contain non-Google-owned dependencies),
+  //  which has been built using production Google infrastructure, and copied
+  //  into third_party.
+  //
+  //  - "LocalSource": The "value" field is the URL identifying where the local
+  //  copy of the package source code can be found.
+  //  Examples:
+  //   - https://android.googlesource.com/platform/external/apache-http/
+  //
+  //  Typically, the metadata files describing a package reside in the same
+  //  directory as the source code for the package. In a few rare cases where
+  //  they are separate, the LocalSource URL identifies where to find the
+  //  source code. This only describes where to find the local copy of the
+  //  source; there should always be an additional URL describing where the
+  //  package was retrieved from.
+  //
+  //  - "Other": An identifier that does not fit any other type. This may also
+  //  indicate that the Source code was received via email or some other
+  //  out-of-band way. This is most commonly used with commercial software
+  //  received directly from the Vendor. In the case of email, the "value" field
+  //  can be used to provide additional information about how it was received.
+  optional string type = 1;
+
+  // A human readable string to indicate why a third-package package does not
+  // have this identifier type set.
+  // Example:
+  //   identifier {
+  //     type: "PyPI"
+  //     omission_reason: "Only on Git. Not published to PyPI."
+  //   }
+  optional string omission_reason = 2;
+
+  // The value of the package identifier as defined by the "type".
+  // Example:
+  //  identifier {
+  //    type: "PyPI"
+  //    value: "django"
+  //    version: "3.2.8"
+  //  }
+  optional string value = 3;
+
+  // The version associated with this package as defined by the "type".
+  // Example:
+  //  identifier {
+  //    type: "PyPI"
+  //    value: "django"
+  //    version: "3.2.8"
+  //  }
+  optional string version = 4;
+
+  // The closest version associated with this package as defined by the "type".
+  // This should only be set by automated infrastructure by applying automated
+  // heuristics, such as the closest git tag or package version from a package
+  // manifest file (e.g. pom.xml).
+  //
+  // For most identifier types, only one of `version` or `closest_version`
+  // should be set (not both). The exception is source repository types such as
+  // "Git", where `version` will refer to a git commit, and `closest_version`
+  // refers to a git tag.
+  // Example:
+  //  identifier {
+  //    type: "Git",
+  //    value: "https://github.com/my/repo"
+  //    version: "e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e"
+  //    closest_version: "v1.4"
+  //  }
+  optional string closest_version = 5;
+
+  // When `true`, this Identifier represents the location from which the source
+  // code for this package was originally obtained. This should only be set for
+  // *one* Identifier in a third_party package's METADATA.
+
+  // For external packages, this is typically for the Identifier associated
+  // with the version control system or package manager that was used to
+  // check out or download the code.
+  optional bool primary_source = 6;
 }
\ No newline at end of file
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 971518a..ee266b7 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -235,6 +235,9 @@
         "rangelib.py",
         "sparse_img.py",
     ],
+    data: [
+        ":zip2zip",
+    ],
     // Only the tools that are referenced directly are listed as required modules. For example,
     // `avbtool` is not here, as the script always uses the one from info_dict['avb_avbtool'].
     required: [
@@ -249,7 +252,6 @@
         "signapk",
         "toybox",
         "unpack_bootimg",
-        "zip2zip",
     ],
 }
 
diff --git a/tools/releasetools/apex_utils.py b/tools/releasetools/apex_utils.py
index bfc87b8..1ddffc1 100644
--- a/tools/releasetools/apex_utils.py
+++ b/tools/releasetools/apex_utils.py
@@ -68,7 +68,7 @@
     self.avbtool = avbtool if avbtool else "avbtool"
     self.sign_tool = sign_tool
 
-  def ProcessApexFile(self, apk_keys, payload_key, signing_args=None, is_sepolicy=False):
+  def ProcessApexFile(self, apk_keys, payload_key, signing_args=None):
     """Scans and signs the payload files and repack the apex
 
     Args:
@@ -86,13 +86,9 @@
                 'list', self.apex_path]
     entries_names = common.RunAndCheckOutput(list_cmd).split()
     apk_entries = [name for name in entries_names if name.endswith('.apk')]
-    sepolicy_entries = []
-    if is_sepolicy:
-      sepolicy_entries = [name for name in entries_names if
-          name.startswith('./etc/SEPolicy') and name.endswith('.zip')]
 
     # No need to sign and repack, return the original apex path.
-    if not apk_entries and not sepolicy_entries and self.sign_tool is None:
+    if not apk_entries and self.sign_tool is None:
       logger.info('No apk file to sign in %s', self.apex_path)
       return self.apex_path
 
@@ -108,14 +104,14 @@
                        ' %s', entry)
 
     payload_dir, has_signed_content = self.ExtractApexPayloadAndSignContents(
-        apk_entries, sepolicy_entries, apk_keys, payload_key, signing_args)
+        apk_entries, apk_keys, payload_key, signing_args)
     if not has_signed_content:
-      logger.info('No contents have been signed in %s', self.apex_path)
+      logger.info('No contents has been signed in %s', self.apex_path)
       return self.apex_path
 
     return self.RepackApexPayload(payload_dir, payload_key, signing_args)
 
-  def ExtractApexPayloadAndSignContents(self, apk_entries, sepolicy_entries, apk_keys, payload_key, signing_args):
+  def ExtractApexPayloadAndSignContents(self, apk_entries, apk_keys, payload_key, signing_args):
     """Extracts the payload image and signs the containing apk files."""
     if not os.path.exists(self.debugfs_path):
       raise ApexSigningError(
@@ -133,11 +129,11 @@
                    'extract',
                    self.apex_path, payload_dir]
     common.RunAndCheckOutput(extract_cmd)
-    assert os.path.exists(self.apex_path)
 
     has_signed_content = False
     for entry in apk_entries:
       apk_path = os.path.join(payload_dir, entry)
+      assert os.path.exists(self.apex_path)
 
       key_name = apk_keys.get(os.path.basename(entry))
       if key_name in common.SPECIAL_CERT_STRINGS:
@@ -154,37 +150,6 @@
           codename_to_api_level_map=self.codename_to_api_level_map)
       has_signed_content = True
 
-    for entry in sepolicy_entries:
-      sepolicy_path = os.path.join(payload_dir, entry)
-
-      if not 'etc' in entry:
-        logger.warning('Sepolicy path does not contain the intended directory name etc:'
-                       ' %s', entry)
-
-      key_name = apk_keys.get(os.path.basename(entry))
-      if key_name is None:
-        logger.warning('Failed to find signing keys for {} in'
-                       ' apex {}, payload key will be used instead.'
-                       ' Use "-e <name>=" to specify a key'
-                       .format(entry, self.apex_path))
-        key_name = payload_key
-
-      if key_name in common.SPECIAL_CERT_STRINGS:
-        logger.info('Not signing: %s due to special cert string', sepolicy_path)
-        continue
-
-      if OPTIONS.sign_sepolicy_path is not None:
-        sig_path = os.path.join(payload_dir, sepolicy_path + '.sig')
-        fsv_sig_path = os.path.join(payload_dir, sepolicy_path + '.fsv_sig')
-        old_sig = common.MakeTempFile()
-        old_fsv_sig = common.MakeTempFile()
-        os.rename(sig_path, old_sig)
-        os.rename(fsv_sig_path, old_fsv_sig)
-
-      logger.info('Signing sepolicy file %s in apex %s', sepolicy_path, self.apex_path)
-      if common.SignSePolicy(sepolicy_path, key_name, self.key_passwords.get(key_name)):
-        has_signed_content = True
-
     if self.sign_tool:
       logger.info('Signing payload contents in apex %s with %s', self.apex_path, self.sign_tool)
       # Pass avbtool to the custom signing tool
@@ -368,8 +333,7 @@
 
 def SignUncompressedApex(avbtool, apex_file, payload_key, container_key,
                          container_pw, apk_keys, codename_to_api_level_map,
-                         no_hashtree, signing_args=None, sign_tool=None,
-                         is_sepolicy=False):
+                         no_hashtree, signing_args=None, sign_tool=None):
   """Signs the current uncompressed APEX with the given payload/container keys.
 
   Args:
@@ -382,7 +346,6 @@
     no_hashtree: Don't include hashtree in the signed APEX.
     signing_args: Additional args to be passed to the payload signer.
     sign_tool: A tool to sign the contents of the APEX.
-    is_sepolicy: Indicates if the apex is a sepolicy.apex
 
   Returns:
     The path to the signed APEX file.
@@ -392,8 +355,7 @@
   apk_signer = ApexApkSigner(apex_file, container_pw,
                              codename_to_api_level_map,
                              avbtool, sign_tool)
-  apex_file = apk_signer.ProcessApexFile(
-      apk_keys, payload_key, signing_args, is_sepolicy)
+  apex_file = apk_signer.ProcessApexFile(apk_keys, payload_key, signing_args)
 
   # 2a. Extract and sign the APEX_PAYLOAD_IMAGE entry with the given
   # payload_key.
@@ -447,8 +409,7 @@
 
 def SignCompressedApex(avbtool, apex_file, payload_key, container_key,
                        container_pw, apk_keys, codename_to_api_level_map,
-                       no_hashtree, signing_args=None, sign_tool=None,
-                       is_sepolicy=False):
+                       no_hashtree, signing_args=None, sign_tool=None):
   """Signs the current compressed APEX with the given payload/container keys.
 
   Args:
@@ -460,7 +421,6 @@
     codename_to_api_level_map: A dict that maps from codename to API level.
     no_hashtree: Don't include hashtree in the signed APEX.
     signing_args: Additional args to be passed to the payload signer.
-    is_sepolicy: Indicates if the apex is a sepolicy.apex
 
   Returns:
     The path to the signed APEX file.
@@ -487,8 +447,7 @@
       codename_to_api_level_map,
       no_hashtree,
       signing_args,
-      sign_tool,
-      is_sepolicy)
+      sign_tool)
 
   # 3. Compress signed original apex.
   compressed_apex_file = common.MakeTempFile(prefix='apex-container-',
@@ -515,8 +474,8 @@
 
 
 def SignApex(avbtool, apex_data, payload_key, container_key, container_pw,
-             apk_keys, codename_to_api_level_map, no_hashtree,
-             signing_args=None, sign_tool=None, is_sepolicy=False):
+             apk_keys, codename_to_api_level_map,
+             no_hashtree, signing_args=None, sign_tool=None):
   """Signs the current APEX with the given payload/container keys.
 
   Args:
@@ -528,7 +487,6 @@
     codename_to_api_level_map: A dict that maps from codename to API level.
     no_hashtree: Don't include hashtree in the signed APEX.
     signing_args: Additional args to be passed to the payload signer.
-    is_sepolicy: Indicates if the apex is a sepolicy.apex
 
   Returns:
     The path to the signed APEX file.
@@ -554,8 +512,7 @@
           no_hashtree=no_hashtree,
           apk_keys=apk_keys,
           signing_args=signing_args,
-          sign_tool=sign_tool,
-          is_sepolicy=is_sepolicy)
+          sign_tool=sign_tool)
     elif apex_type == 'COMPRESSED':
       return SignCompressedApex(
           avbtool,
@@ -567,8 +524,7 @@
           no_hashtree=no_hashtree,
           apk_keys=apk_keys,
           signing_args=signing_args,
-          sign_tool=sign_tool,
-          is_sepolicy=is_sepolicy)
+          sign_tool=sign_tool)
     else:
       # TODO(b/172912232): support signing compressed apex
       raise ApexInfoError('Unsupported apex type {}'.format(apex_type))
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 5e4130c..34b7172 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -353,6 +353,8 @@
     if compress_hints:
       build_command.extend(["--compress-hints", compress_hints])
 
+    build_command.extend(["-b", prop_dict.get("erofs_blocksize", "4096")])
+
     build_command.extend(["--mount-point", prop_dict["mount_point"]])
     if target_out:
       build_command.extend(["--product-out", target_out])
@@ -711,6 +713,7 @@
       "erofs_default_compressor",
       "erofs_default_compress_hints",
       "erofs_pcluster_size",
+      "erofs_blocksize",
       "erofs_share_dup_blocks",
       "erofs_sparse_flag",
       "erofs_use_legacy_compression",
@@ -762,6 +765,7 @@
       (True, "{}_erofs_compressor", "erofs_compressor"),
       (True, "{}_erofs_compress_hints", "erofs_compress_hints"),
       (True, "{}_erofs_pcluster_size", "erofs_pcluster_size"),
+      (True, "{}_erofs_blocksize", "erofs_blocksize"),
       (True, "{}_erofs_share_dup_blocks", "erofs_share_dup_blocks"),
       (True, "{}_extfs_inode_count", "extfs_inode_count"),
       (True, "{}_f2fs_compress", "f2fs_compress"),
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 0f3c430..843d8ca 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -75,9 +75,7 @@
       if "ANDROID_HOST_OUT" in os.environ:
         self.search_path = os.environ["ANDROID_HOST_OUT"]
     self.signapk_shared_library_path = "lib64"   # Relative to search_path
-    self.sign_sepolicy_path = None
     self.extra_signapk_args = []
-    self.extra_sign_sepolicy_args = []
     self.aapt2_path = "aapt2"
     self.java_path = "java"  # Use the one on the path by default.
     self.java_args = ["-Xmx4096m"]  # The default JVM args.
@@ -97,7 +95,6 @@
     self.cache_size = None
     self.stash_threshold = 0.8
     self.logfile = None
-    self.sepolicy_name = 'sepolicy.apex'
 
 
 OPTIONS = Options()
@@ -213,7 +210,7 @@
           '': {
               'handlers': ['default'],
               'propagate': True,
-              'level': 'WARNING',
+              'level': 'NOTSET',
           }
       }
   }
@@ -1950,7 +1947,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))
@@ -2629,38 +2634,6 @@
                                                        proc.returncode, stdoutdata))
 
 
-def SignSePolicy(sepolicy, key, password):
-  """Sign the sepolicy zip, producing an fsverity .fsv_sig and
-  an RSA .sig signature files.
-  """
-
-  if OPTIONS.sign_sepolicy_path is None:
-    logger.info("No sign_sepolicy_path specified, %s was not signed", sepolicy)
-    return False
-
-  java_library_path = os.path.join(
-      OPTIONS.search_path, OPTIONS.signapk_shared_library_path)
-
-  cmd = ([OPTIONS.java_path] + OPTIONS.java_args +
-         ["-Djava.library.path=" + java_library_path,
-          "-jar", os.path.join(OPTIONS.search_path, OPTIONS.sign_sepolicy_path)] +
-         OPTIONS.extra_sign_sepolicy_args)
-
-  cmd.extend([key + OPTIONS.public_key_suffix,
-              key + OPTIONS.private_key_suffix,
-              sepolicy, os.path.dirname(sepolicy)])
-
-  proc = Run(cmd, stdin=subprocess.PIPE)
-  if password is not None:
-    password += "\n"
-  stdoutdata, _ = proc.communicate(password)
-  if proc.returncode != 0:
-    raise ExternalError(
-        "Failed to run sign sepolicy: return code {}:\n{}".format(
-            proc.returncode, stdoutdata))
-  return True
-
-
 def CheckSize(data, target, info_dict):
   """Checks the data string passed against the max size limit.
 
@@ -2836,8 +2809,7 @@
     opts, args = getopt.getopt(
         argv, "hvp:s:x:" + extra_opts,
         ["help", "verbose", "path=", "signapk_path=",
-         "signapk_shared_library_path=", "extra_signapk_args=",
-         "sign_sepolicy_path=", "extra_sign_sepolicy_args=", "aapt2_path=",
+         "signapk_shared_library_path=", "extra_signapk_args=", "aapt2_path=",
          "java_path=", "java_args=", "android_jar_path=", "public_key_suffix=",
          "private_key_suffix=", "boot_signer_path=", "boot_signer_args=",
          "verity_signer_path=", "verity_signer_args=", "device_specific=",
@@ -2861,10 +2833,6 @@
       OPTIONS.signapk_shared_library_path = a
     elif o in ("--extra_signapk_args",):
       OPTIONS.extra_signapk_args = shlex.split(a)
-    elif o in ("--sign_sepolicy_path",):
-      OPTIONS.sign_sepolicy_path = a
-    elif o in ("--extra_sign_sepolicy_args",):
-      OPTIONS.extra_sign_sepolicy_args = shlex.split(a)
     elif o in ("--aapt2_path",):
       OPTIONS.aapt2_path = a
     elif o in ("--java_path",):
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
index a3e3681..b7a5ad8 100755
--- a/tools/releasetools/img_from_target_files.py
+++ b/tools/releasetools/img_from_target_files.py
@@ -67,6 +67,7 @@
 OPTIONS.use_fastboot_info = True
 OPTIONS.build_super_image = None
 
+
 def LoadOptions(input_file):
   """Loads information from input_file to OPTIONS.
 
@@ -105,6 +106,13 @@
   common.RunAndCheckOutput(cmd)
 
 
+def LocatePartitionEntry(partition_name, namelist):
+  for subdir in ["IMAGES", "PREBUILT_IMAGES", "RADIO"]:
+    entry_name = os.path.join(subdir, partition_name + ".img")
+    if entry_name in namelist:
+      return entry_name
+
+
 def EntriesForUserImages(input_file):
   """Returns the user images entries to be copied.
 
@@ -122,13 +130,18 @@
   ]
   if OPTIONS.use_fastboot_info:
     entries.append('META/fastboot-info.txt:fastboot-info.txt')
+  ab_partitions = []
   with zipfile.ZipFile(input_file) as input_zip:
     namelist = input_zip.namelist()
+    if "META/ab_partitions.txt" in namelist:
+      ab_partitions = input_zip.read(
+          "META/ab_partitions.txt").decode().strip().split()
   if 'PREBUILT_IMAGES/kernel_16k' in namelist:
     entries.append('PREBUILT_IMAGES/kernel_16k:kernel_16k')
   if 'PREBUILT_IMAGES/ramdisk_16k.img' in namelist:
     entries.append('PREBUILT_IMAGES/ramdisk_16k.img:ramdisk_16k.img')
 
+  visited_partitions = set(OPTIONS.dynamic_partition_list)
   for image_path in [name for name in namelist if name.startswith('IMAGES/')]:
     image = os.path.basename(image_path)
     if OPTIONS.bootable_only and image not in ('boot.img', 'recovery.img', 'bootloader', 'init_boot.img'):
@@ -143,7 +156,14 @@
         continue
       if image in dynamic_images:
         continue
+    partition_name = image.rstrip(".img")
+    visited_partitions.add(partition_name)
     entries.append('{}:{}'.format(image_path, image))
+  for part in [part for part in ab_partitions if part not in visited_partitions]:
+    entry = LocatePartitionEntry(part, namelist)
+    image = os.path.basename(entry)
+    if entry is not None:
+      entries.append('{}:{}'.format(entry, image))
   return entries
 
 
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 7be9876..de0e187 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -995,7 +995,7 @@
   metadata = GetPackageMetadata(target_info, source_info)
   # Generate payload.
   payload = PayloadGenerator(
-      wipe_user_data=OPTIONS.wipe_user_data, minor_version=OPTIONS.force_minor_version, is_partial_update=OPTIONS.partial)
+      wipe_user_data=OPTIONS.wipe_user_data, minor_version=OPTIONS.force_minor_version, is_partial_update=OPTIONS.partial, spl_downgrade=OPTIONS.spl_downgrade)
 
   partition_timestamps_flags = []
   # Enforce a max timestamp this payload can be applied on top of.
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index 5c70223..6ca9d64 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -791,7 +791,7 @@
   SECONDARY_PAYLOAD_BIN = 'secondary/payload.bin'
   SECONDARY_PAYLOAD_PROPERTIES_TXT = 'secondary/payload_properties.txt'
 
-  def __init__(self, secondary=False, wipe_user_data=False, minor_version=None, is_partial_update=False):
+  def __init__(self, secondary=False, wipe_user_data=False, minor_version=None, is_partial_update=False, spl_downgrade=False):
     """Initializes a Payload instance.
 
     Args:
@@ -803,6 +803,7 @@
     self.wipe_user_data = wipe_user_data
     self.minor_version = minor_version
     self.is_partial_update = is_partial_update
+    self.spl_downgrade = spl_downgrade
 
   def _Run(self, cmd):  # pylint: disable=no-self-use
     # Don't pipe (buffer) the output if verbose is set. Let
@@ -912,13 +913,15 @@
            "--properties_file=" + properties_file]
     self._Run(cmd)
 
-    if self.secondary:
-      with open(properties_file, "a") as f:
-        f.write("SWITCH_SLOT_ON_REBOOT=0\n")
 
-    if self.wipe_user_data:
-      with open(properties_file, "a") as f:
+    with open(properties_file, "a") as f:
+      if self.wipe_user_data:
         f.write("POWERWASH=1\n")
+      if self.secondary:
+        f.write("SWITCH_SLOT_ON_REBOOT=0\n")
+      if self.spl_downgrade:
+        f.write("SPL_DOWNGRADE=1\n")
+
 
     self.payload_properties = properties_file
 
diff --git a/tools/releasetools/sign_apex.py b/tools/releasetools/sign_apex.py
index d739982..a0a94f6 100755
--- a/tools/releasetools/sign_apex.py
+++ b/tools/releasetools/sign_apex.py
@@ -56,7 +56,6 @@
 import common
 
 logger = logging.getLogger(__name__)
-OPTIONS = common.OPTIONS
 
 
 def SignApexFile(avbtool, apex_file, payload_key, container_key, no_hashtree,
@@ -75,8 +74,7 @@
       no_hashtree=no_hashtree,
       apk_keys=apk_keys,
       signing_args=signing_args,
-      sign_tool=sign_tool,
-      is_sepolicy=apex_file.endswith(OPTIONS.sepolicy_name))
+      sign_tool=sign_tool)
 
 
 def main(argv):
diff --git a/tools/releasetools/test_sign_apex.py b/tools/releasetools/test_sign_apex.py
index 7723de7..8470f20 100644
--- a/tools/releasetools/test_sign_apex.py
+++ b/tools/releasetools/test_sign_apex.py
@@ -59,21 +59,6 @@
     self.assertTrue(os.path.exists(signed_test_apex))
 
   @test_utils.SkipIfExternalToolsUnavailable()
-  def test_SignSepolicyApex(self):
-    test_apex = os.path.join(self.testdata_dir, 'sepolicy.apex')
-    payload_key = os.path.join(self.testdata_dir, 'testkey_RSA4096.key')
-    container_key = os.path.join(self.testdata_dir, 'testkey')
-    apk_keys = {'SEPolicy-33.zip': os.path.join(self.testdata_dir, 'testkey')}
-    signed_test_apex = sign_apex.SignApexFile(
-        'avbtool',
-        test_apex,
-        payload_key,
-        container_key,
-        False,
-        None)
-    self.assertTrue(os.path.exists(signed_test_apex))
-
-  @test_utils.SkipIfExternalToolsUnavailable()
   def test_SignCompressedApexFile(self):
     apex = os.path.join(test_utils.get_current_dir(), 'com.android.apex.compressed.v1.capex')
     payload_key = os.path.join(self.testdata_dir, 'testkey_RSA4096.key')
diff --git a/tools/releasetools/testdata/sepolicy.apex b/tools/releasetools/testdata/sepolicy.apex
deleted file mode 100644
index 2c646cd..0000000
--- a/tools/releasetools/testdata/sepolicy.apex
+++ /dev/null
Binary files differ
diff --git a/tools/sbom/Android.bp b/tools/sbom/Android.bp
index 519251e..27a160e 100644
--- a/tools/sbom/Android.bp
+++ b/tools/sbom/Android.bp
@@ -77,3 +77,18 @@
     },
     test_suites: ["general-tests"],
 }
+
+python_binary_host {
+    name: "generate-sbom-framework_res",
+        srcs: [
+            "generate-sbom-framework_res.py",
+        ],
+        version: {
+            py3: {
+                embedded_launcher: true,
+            },
+        },
+        libs: [
+            "sbom_lib",
+        ],
+}
\ No newline at end of file
diff --git a/tools/sbom/generate-sbom-framework_res.py b/tools/sbom/generate-sbom-framework_res.py
new file mode 100644
index 0000000..d6be734
--- /dev/null
+++ b/tools/sbom/generate-sbom-framework_res.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 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.
+
+import argparse
+import hashlib
+import json
+import sbom_data
+import sbom_writers
+
+
+def get_args():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('-v', '--verbose', action='store_true', default=False,
+                      help='Print more information.')
+  parser.add_argument('--output_file', required=True,
+                      help='The generated SBOM file in SPDX format.')
+  parser.add_argument('--layoutlib_sbom', required=True,
+                      help='The file path of the SBOM of layoutlib.')
+
+  return parser.parse_args()
+
+
+def main():
+  global args
+  args = get_args()
+
+  doc = sbom_data.Document(name='<name>',
+                           namespace='<namespace>',
+                           creators=['Organization: <organization>'],
+                           created='<created>')
+
+  filename = 'data/framework_res.jar'
+  file_id = f'SPDXRef-{sbom_data.encode_for_spdxid(filename)}'
+  file = sbom_data.File(id=file_id, name=filename, checksum='SHA1: <checksum>')
+  doc.files.append(file)
+  doc.describes = file_id
+
+  with open(args.layoutlib_sbom, 'r', encoding='utf-8') as f:
+    layoutlib_sbom = json.load(f)
+
+  with open(args.layoutlib_sbom, 'rb') as f:
+    sha1 = hashlib.file_digest(f, 'sha1')
+
+  layoutlib_sbom_namespace = layoutlib_sbom[sbom_writers.PropNames.DOCUMENT_NAMESPACE]
+  external_doc_ref = 'DocumentRef-layoutlib'
+  doc.external_refs = [
+    sbom_data.DocumentExternalReference(external_doc_ref, layoutlib_sbom_namespace,
+                                        f'SHA1: {sha1.hexdigest()}')]
+
+  resource_file_spdxids = []
+  for file in layoutlib_sbom[sbom_writers.PropNames.FILES]:
+    if file[sbom_writers.PropNames.FILE_NAME].startswith('data/res/'):
+      resource_file_spdxids.append(file[sbom_writers.PropNames.SPDXID])
+
+  doc.relationships = []
+  for spdxid in resource_file_spdxids:
+    doc.relationships.append(
+      sbom_data.Relationship(file_id, sbom_data.RelationshipType.GENERATED_FROM,
+                             f'{external_doc_ref}:{spdxid}'))
+
+  # write sbom file
+  with open(args.output_file, 'w', encoding='utf-8') as f:
+    sbom_writers.JSONWriter.write(doc, f)
+
+
+if __name__ == '__main__':
+  main()
diff --git a/tools/sbom/generate-sbom.py b/tools/sbom/generate-sbom.py
index b19be87..a2b33b5 100755
--- a/tools/sbom/generate-sbom.py
+++ b/tools/sbom/generate-sbom.py
@@ -82,6 +82,46 @@
   'vndk_prebuilt_shared',
 ]
 
+THIRD_PARTY_IDENTIFIER_TYPES = [
+    # Types defined in metadata_file.proto
+    'Git',
+    'SVN',
+    'Hg',
+    'Darcs',
+    'VCS',
+    'Archive',
+    'PrebuiltByAlphabet',
+    'LocalSource',
+    'Other',
+    # OSV ecosystems defined at https://ossf.github.io/osv-schema/#affectedpackage-field.
+    'Go',
+    'npm',
+    'OSS-Fuzz',
+    'PyPI',
+    'RubyGems',
+    'crates.io',
+    'Hackage',
+    'GHC',
+    'Packagist',
+    'Maven',
+    'NuGet',
+    'Linux',
+    'Debian',
+    'Alpine',
+    'Hex',
+    'Android',
+    'GitHub Actions',
+    'Pub',
+    'ConanCenter',
+    'Rocky Linux',
+    'AlmaLinux',
+    'Bitnami',
+    'Photon OS',
+    'CRAN',
+    'Bioconductor',
+    'SwiftURL'
+]
+
 
 def get_args():
   parser = argparse.ArgumentParser()
@@ -103,26 +143,12 @@
       print(i)
 
 
-def encode_for_spdxid(s):
-  """Simple encode for string values used in SPDXID which uses the charset of A-Za-Z0-9.-"""
-  result = ''
-  for c in s:
-    if c.isalnum() or c in '.-':
-      result += c
-    elif c in '_@/':
-      result += '-'
-    else:
-      result += '0x' + c.encode('utf-8').hex()
-
-  return result.lstrip('-')
-
-
 def new_package_id(package_name, type):
-  return f'SPDXRef-{type}-{encode_for_spdxid(package_name)}'
+  return f'SPDXRef-{type}-{sbom_data.encode_for_spdxid(package_name)}'
 
 
 def new_file_id(file_path):
-  return f'SPDXRef-{encode_for_spdxid(file_path)}'
+  return f'SPDXRef-{sbom_data.encode_for_spdxid(file_path)}'
 
 
 def checksum(file_path):
@@ -360,6 +386,20 @@
   return True
 
 
+# Validate identifiers in a package's METADATA.
+# 1) Only known identifier type is allowed
+# 2) Only one identifier's primary_source can be true
+def validate_package_metadata(metadata_file_path, package_metadata):
+  primary_source_found = False
+  for identifier in package_metadata.third_party.identifier:
+    if identifier.type not in THIRD_PARTY_IDENTIFIER_TYPES:
+      sys.exit(f'Unknown value of third_party.identifier.type in {metadata_file_path}/METADATA: {identifier.type}.')
+    if primary_source_found and identifier.primary_source:
+      sys.exit(
+        f'Field "primary_source" is set to true in multiple third_party.identifier in {metadata_file_path}/METADATA.')
+    primary_source_found = identifier.primary_source
+
+
 def report_metadata_file(metadata_file_path, installed_file_metadata, report):
   if metadata_file_path:
     report[INFO_METADATA_FOUND_FOR_PACKAGE].append(
@@ -372,6 +412,8 @@
     with open(metadata_file_path + '/METADATA', 'rt') as f:
       text_format.Parse(f.read(), package_metadata)
 
+    validate_package_metadata(metadata_file_path, package_metadata)
+
     if not metadata_file_path in metadata_file_protos:
       metadata_file_protos[metadata_file_path] = package_metadata
       if not package_metadata.name:
diff --git a/tools/sbom/sbom_data.py b/tools/sbom/sbom_data.py
index 71f8660..b5ac8a5 100644
--- a/tools/sbom/sbom_data.py
+++ b/tools/sbom/sbom_data.py
@@ -138,3 +138,16 @@
       h = hashlib.sha1()
       h.update(''.join(checksums).encode(encoding='utf-8'))
       package.verification_code = h.hexdigest()
+
+def encode_for_spdxid(s):
+  """Simple encode for string values used in SPDXID which uses the charset of A-Za-Z0-9.-"""
+  result = ''
+  for c in s:
+    if c.isalnum() or c in '.-':
+      result += c
+    elif c in '_@/':
+      result += '-'
+    else:
+      result += '0x' + c.encode('utf-8').hex()
+
+  return result.lstrip('-')
\ No newline at end of file
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index 25c53d3..2f2b833 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -687,7 +687,7 @@
         if (entryName.endsWith(".so")) {
             // Align .so contents to memory page boundary to enable memory-mapped
             // execution.
-            return 4096;
+            return 16384;
         } else {
             return defaultAlignment;
         }