Merge "Build file lists for general-tests and device-tests" into main
diff --git a/core/Makefile b/core/Makefile
index 2051c2c..9db50a3 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -6119,9 +6119,6 @@
 ifneq ($(BOARD_PARTIAL_OTA_UPDATE_PARTITIONS_LIST),)
 	$(hide) echo "partial_ota_update_partitions_list=$(BOARD_PARTIAL_OTA_UPDATE_PARTITIONS_LIST)" >> $@
 endif
-ifeq ($(BUILDING_WITH_VSDK),true)
-	$(hide) echo "building_with_vsdk=true" >> $@
-endif
 
 $(call declare-0p-target,$(INSTALLED_FASTBOOT_INFO_TARGET))
 
@@ -7189,6 +7186,12 @@
 $(call declare-1p-target,$(DEXPREOPT_CONFIG_ZIP),)
 
 # -----------------------------------------------------------------
+# Zips of the symbols directory per test suites
+#
+
+$(foreach suite,$(ALL_COMPATIBILITY_SUITES),$(eval $(call create-suite-symbols-map,$(suite))))
+
+# -----------------------------------------------------------------
 # A zip of the symbols directory.  Keep the full paths to make it
 # more obvious where these files came from.
 # Also produces a textproto containing mappings from elf IDs to symbols
@@ -7206,29 +7209,37 @@
 # The path to a file containing mappings from elf IDs to filenames.
 SYMBOLS_MAPPING := $(PRODUCT_OUT)/$(name)-symbols-mapping.textproto
 .KATI_READONLY := SYMBOLS_ZIP SYMBOLS_MAPPING
-# For apps_only build we'll establish the dependency later in build/make/core/main.mk.
+
 ifeq (,$(TARGET_BUILD_UNBUNDLED))
-$(SYMBOLS_ZIP): $(INTERNAL_ALLIMAGES_FILES) $(updater_dep)
+  _symbols_zip_modules := $(call product-installed-modules,$(INTERNAL_PRODUCT))
+  $(SYMBOLS_ZIP): $(updater_dep)
+else
+  _symbols_zip_modules := $(unbundled_build_modules)
 endif
-$(SYMBOLS_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,symbols)/filelist
-$(SYMBOLS_ZIP): PRIVATE_MAPPING_PACKAGING_DIR := $(call intermediates-dir-for,PACKAGING,elf_symbol_mapping)
-$(SYMBOLS_ZIP): $(SOONG_ZIP) $(SYMBOLS_MAP)
+
+_symbols_zip_modules_symbols_files := $(foreach m,$(_symbols_zip_modules),$(ALL_MODULES.$(m).SYMBOLIC_OUTPUT_PATH))
+_symbols_zip_modules_mapping_files := $(foreach m,$(_symbols_zip_modules),$(ALL_MODULES.$(m).ELF_SYMBOL_MAPPING_PATH))
+
+$(SYMBOLS_ZIP): PRIVATE_SYMBOLS_MODULES_FILES := $(_symbols_zip_modules_symbols_files)
+$(SYMBOLS_ZIP): PRIVATE_SYMBOLS_MODULES_MAPPING_FILES := $(_symbols_zip_modules_mapping_files)
+$(SYMBOLS_ZIP): $(SOONG_ZIP) $(SYMBOLS_MAP) $(_symbols_zip_modules_symbols_files) $(_symbols_zip_modules_mapping_files)
 	@echo "Package symbols: $@"
-	$(hide) rm -rf $@ $(PRIVATE_LIST_FILE)
-	$(hide) mkdir -p $(TARGET_OUT_UNSTRIPPED) $(dir $(PRIVATE_LIST_FILE)) $(PRIVATE_MAPPING_PACKAGING_DIR)
-	# Find all of the files in the symbols directory and zip them into the symbols zip.
-	$(hide) find -L $(TARGET_OUT_UNSTRIPPED) -type f | sort >$(PRIVATE_LIST_FILE)
-	$(hide) $(SOONG_ZIP) --ignore_missing_files -d -o $@ -C $(OUT_DIR)/.. -l $(PRIVATE_LIST_FILE)
-	# Find all of the files in the symbols mapping directory and merge them into the symbols mapping textproto.
-	$(hide) find -L $(PRIVATE_MAPPING_PACKAGING_DIR) -type f | sort >$(PRIVATE_LIST_FILE)
-	$(hide) $(SYMBOLS_MAP) -merge $(SYMBOLS_MAPPING) -ignore_missing_files @$(PRIVATE_LIST_FILE)
+	$(hide) rm -rf $@ $@.symbols_list $@.mapping_list
+	# Find all installed files in the symbols directory and zip them into the symbols zip.
+	echo "$(PRIVATE_SYMBOLS_MODULES_FILES)" | tr " " "\n" | sort > $@.symbols_list
+	$(hide) $(SOONG_ZIP) -d -o $@ -l $@.symbols_list
+	# Find all installed files in the symbols mapping directory and merge them into the symbols mapping textproto.
+	echo "$(PRIVATE_SYMBOLS_MODULES_MAPPING_FILES)" | tr " " "\n" | sort > $@.mapping_list
+	$(hide) $(SYMBOLS_MAP) -merge $(SYMBOLS_MAPPING) @$@.mapping_list
 $(SYMBOLS_ZIP): .KATI_IMPLICIT_OUTPUTS := $(SYMBOLS_MAPPING)
 
 $(call declare-1p-container,$(SYMBOLS_ZIP),)
 ifeq (,$(TARGET_BUILD_UNBUNDLED))
-$(call declare-container-license-deps,$(SYMBOLS_ZIP),$(INTERNAL_ALLIMAGES_FILES) $(updater_dep),$(PRODUCT_OUT)/:/)
+$(call declare-container-license-deps,$(SYMBOLS_ZIP),$(PRIVATE_SYMBOLS_MODULES_FILES) $(updater_dep),$(PRODUCT_OUT)/:/)
 endif
 
+_symbols_zip_modules_symbols_files :=
+_symbols_zip_modules_mapping_files :=
 # -----------------------------------------------------------------
 # A zip of the coverage directory.
 #
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index f57ec81..b2c4fb5 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -346,3 +346,12 @@
 ifneq ($(filter arm x86 true,$(TARGET_ARCH) $(TARGET_2ND_ARCH) $(TARGET_ENABLE_MEDIADRM_64)),)
   $(call soong_config_set_bool,ci_tests,uses_widevine_tests, true)
 endif
+
+# Flags used in GTVS prebuilt apps
+$(call soong_config_set_bool,GTVS,GTVS_COMPRESSED_PREBUILTS,$(if $(findstring $(GTVS_COMPRESSED_PREBUILTS),true yes),true,false))
+$(call soong_config_set_bool,GTVS,GTVS_GMSCORE_BETA,$(if $(findstring $(GTVS_GMSCORE_BETA),true yes),true,false))
+$(call soong_config_set_bool,GTVS,GTVS_SETUPWRAITH_BETA,$(if $(findstring $(GTVS_SETUPWRAITH_BETA),true yes),true,false))
+$(call soong_config_set_bool,GTVS,PRODUCT_USE_PREBUILT_GTVS,$(if $(findstring $(PRODUCT_USE_PREBUILT_GTVS),true yes),true,false))
+
+# Flags used in GTVS_GTV prebuilt apps
+$(call soong_config_set_bool,GTVS_GTV,PRODUCT_USE_PREBUILT_GTVS_GTV,$(if $(findstring $(PRODUCT_USE_PREBUILT_GTVS_GTV),true yes),true,false))
diff --git a/core/combo/arch/arm64/armv9-3a.mk b/core/combo/arch/arm64/armv9-3a.mk
new file mode 100644
index 0000000..0f2c620
--- /dev/null
+++ b/core/combo/arch/arm64/armv9-3a.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2025 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.
+#
+
+# .mk file required to support build for the ARMv9.3-A arch variant.
+# The file just needs to be present, it does not need to contain anything.
diff --git a/core/combo/arch/arm64/armv9-4a.mk b/core/combo/arch/arm64/armv9-4a.mk
new file mode 100644
index 0000000..6ab3bed
--- /dev/null
+++ b/core/combo/arch/arm64/armv9-4a.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2025 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.
+#
+
+# .mk file required to support build for the ARMv9.4-A arch variant.
+# The file just needs to be present, it does not need to contain anything.
diff --git a/core/config.mk b/core/config.mk
index 47018aa..fafdfe1 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -598,10 +598,7 @@
 DISABLE_PREOPT_BOOT_IMAGES :=
 ifneq (,$(TARGET_BUILD_APPS)$(TARGET_BUILD_UNBUNDLED_IMAGE))
   DISABLE_PREOPT := true
-  # VSDK builds perform dexpreopt during merge_target_files build step.
-  ifneq (true,$(BUILDING_WITH_VSDK))
-    DISABLE_PREOPT_BOOT_IMAGES := true
-  endif
+  DISABLE_PREOPT_BOOT_IMAGES := true
 endif
 ifeq (true,$(TARGET_BUILD_UNBUNDLED))
   ifneq (true,$(UNBUNDLED_BUILD_SDKS_FROM_SOURCE))
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index ab2d5c1..c0f2c68 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -284,9 +284,9 @@
 ifneq ($(filter memtag_stack,$(my_sanitize)),)
   my_cflags += -fsanitize=memtag-stack
   my_ldflags += -fsanitize=memtag-stack
-  my_cflags += -march=armv8a+memtag
-  my_ldflags += -march=armv8a+memtag
-  my_asflags += -march=armv8a+memtag
+  my_cflags += -Xclang -target-feature -Xclang +mte
+  my_ldflags += -Xclang -target-feature -Xclang +mte
+  my_asflags += -Xclang -target-feature -Xclang +mte
   my_sanitize := $(filter-out memtag_stack,$(my_sanitize))
 endif
 
diff --git a/core/definitions.mk b/core/definitions.mk
index 60034cd..ea151fa 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -3422,9 +3422,9 @@
 # a hash mapping to the mapping directory.
 # $(1): unstripped intermediates file
 # $(2): path in symbols directory
+# $(3): path in elf_symbol_mapping packaging directory
 define copy-unstripped-elf-file-with-mapping
-$(call _copy-symbols-file-with-mapping,$(1),$(2),\
-  elf,$(patsubst $(TARGET_OUT_UNSTRIPPED)/%,$(call intermediates-dir-for,PACKAGING,elf_symbol_mapping)/%,$(2).textproto))
+$(call _copy-symbols-file-with-mapping,$(1),$(2),elf,$(3))
 endef
 
 # Copy an R8 dictionary to the packaging directory while also extracting
@@ -3689,6 +3689,32 @@
     $(sort $(foreach suite,$(LOCAL_COMPATIBILITY_SUITE),$(my_compat_dist_config_$(suite))))))
 endef
 
+# Define symbols.zip and symbols-mapping.textproto build rule per test suite
+#
+# $(1): Name of the test suite to create the zip and mapping build rules
+define create-suite-symbols-map
+_suite_symbols_zip := $$(subst -tests-,-tests_-,$$(PRODUCT_OUT)/$(1)-symbols.zip)
+_suite_symbols_mapping := $$(subst -tests-,-tests_-,$$(PRODUCT_OUT)/$(1)-symbols-mapping.textproto)
+_suite_modules_symbols_files := $$(foreach m,$$(COMPATIBILITY.$(1).MODULES),$$(ALL_MODULES.$$(m).SYMBOLIC_OUTPUT_PATH))
+_suite_modules_mapping_files := $$(foreach m,$$(COMPATIBILITY.$(1).MODULES),$$(ALL_MODULES.$$(m).ELF_SYMBOL_MAPPING_PATH))
+
+$$(_suite_symbols_zip): PRIVATE_SUITE_SYMBOLS_MAPPING := $$(_suite_symbols_mapping)
+$$(_suite_symbols_zip): PRIVATE_SUITE_MODULES_SYMBOLS_FILES := $$(_suite_modules_symbols_files)
+$$(_suite_symbols_zip): PRIVATE_SUITE_MODULES_MAPPING_FILES := $$(_suite_modules_mapping_files)
+$$(_suite_symbols_zip): $$(SOONG_ZIP) $$(SYMBOLS_MAP) $$(_suite_modules_symbols_files) $$(_suite_modules_mapping_files)
+	@echo "Package $(1) symbols: $$@"
+	$(hide) rm -rf $$@ $$@.symbols_list $$@.mapping_list
+	echo "$$(PRIVATE_SUITE_MODULES_SYMBOLS_FILES)" | tr " " "\n" | sort > $$@.symbols_list
+	$(hide) $$(SOONG_ZIP) -d -o $$@ -l $$@.symbols_list
+	echo "$$(PRIVATE_SUITE_MODULES_MAPPING_FILES)" | tr " " "\n" | sort > $$@.mapping_list
+	$(hide) $$(SYMBOLS_MAP) -merge $$(PRIVATE_SUITE_SYMBOLS_MAPPING) @$$@.mapping_list
+$$(_suite_symbols_zip): .KATI_IMPLICIT_OUTPUTS := $$(_suite_symbols_mapping)
+
+.PHONY: $(1)
+$(1): $$(_suite_symbols_zip) $$(_suite_symbols_mapping)
+$$(call dist-for-goals-with-filenametag,$(1), $$(_suite_symbols_zip) $$(_suite_symbols_mapping))
+endef
+
 ###########################################################
 ## Path Cleaning
 ###########################################################
diff --git a/core/dynamic_binary.mk b/core/dynamic_binary.mk
index 0d2cd7f..878989d 100644
--- a/core/dynamic_binary.mk
+++ b/core/dynamic_binary.mk
@@ -55,7 +55,12 @@
 endif
 symbolic_input := $(inject_module)
 symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem)
-$(eval $(call copy-unstripped-elf-file-with-mapping,$(symbolic_input),$(symbolic_output)))
+elf_mapping_path := $(patsubst $(TARGET_OUT_UNSTRIPPED)/%,$(call intermediates-dir-for,PACKAGING,elf_symbol_mapping)/%,$(symbolic_output).textproto)
+
+ALL_MODULES.$(my_register_name).SYMBOLIC_OUTPUT_PATH := $(symbolic_output)
+ALL_MODULES.$(my_register_name).ELF_SYMBOL_MAPPING_PATH := $(elf_mapping_path)
+
+$(eval $(call copy-unstripped-elf-file-with-mapping,$(symbolic_input),$(symbolic_output),$(elf_mapping_path)))
 
 ###########################################################
 ## Store breakpad symbols
diff --git a/core/main.mk b/core/main.mk
index b9edfc1..aed3fa2 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -299,6 +299,8 @@
 
 $(foreach mk,$(subdir_makefiles),$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] including $(mk) ...)$(eval include $(mk)))
 
+-include device/generic/goldfish/tasks/emu_img_zip.mk
+
 # Build bootloader.img/radio.img, and unpack the partitions.
 -include vendor/google_devices/$(TARGET_SOC)/prebuilts/misc_bins/update_bootloader_radio_image.mk
 
@@ -993,6 +995,7 @@
 define auto-included-modules
   $(foreach vndk_ver,$(PRODUCT_EXTRA_VNDK_VERSIONS),com.android.vndk.v$(vndk_ver)) \
   llndk.libraries.txt \
+  $(if $(DEVICE_MANIFEST_FILE),vendor_manifest.xml) \
   $(if $(DEVICE_MANIFEST_SKUS),$(foreach sku, $(DEVICE_MANIFEST_SKUS),vendor_manifest_$(sku).xml)) \
   $(if $(ODM_MANIFEST_FILES),odm_manifest.xml) \
   $(if $(ODM_MANIFEST_SKUS),$(foreach sku, $(ODM_MANIFEST_SKUS),odm_manifest_$(sku).xml)) \
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index ab9227f..62b5d5b 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -142,7 +142,21 @@
 # install symbol files of JNI libraries
 my_jni_lib_symbols_copy_files := $(foreach f,$(LOCAL_SOONG_JNI_LIBS_SYMBOLS),\
   $(call word-colon,1,$(f)):$(patsubst $(PRODUCT_OUT)/%,$(TARGET_OUT_UNSTRIPPED)/%,$(call word-colon,2,$(f))))
-$(LOCAL_BUILT_MODULE): | $(call copy-many-files, $(my_jni_lib_symbols_copy_files))
+
+$(foreach f, $(my_jni_lib_symbols_copy_files), \
+  $(eval $(call copy-unstripped-elf-file-with-mapping, \
+    $(call word-colon,1,$(f)), \
+    $(call word-colon,2,$(f)), \
+    $(patsubst $(TARGET_OUT_UNSTRIPPED)/%,$(call intermediates-dir-for,PACKAGING,elf_symbol_mapping)/%,$(call word-colon,2,$(f)).textproto)\
+  ))\
+)
+
+symbolic_outputs := $(foreach f,$(my_jni_lib_symbols_copy_files),$(call word-colon,2,$(f)))
+symbolic_mappings := $(foreach f,$(symbolic_outputs),$(patsubst $(TARGET_OUT_UNSTRIPPED)/%,$(call intermediates-dir-for,PACKAGING,elf_symbol_mapping)/%,$(f).textproto))
+ALL_MODULES.$(my_register_name).SYMBOLIC_OUTPUT_PATH := $(symbolic_outputs)
+ALL_MODULES.$(my_register_name).ELF_SYMBOL_MAPPING_PATH := $(symbolic_mappings)
+
+$(LOCAL_BUILT_MODULE): | $(symbolic_outputs)
 
 # embedded JNI will already have been handled by soong
 my_embed_jni :=
diff --git a/core/soong_cc_rust_prebuilt.mk b/core/soong_cc_rust_prebuilt.mk
index da60832..9ea24f7 100644
--- a/core/soong_cc_rust_prebuilt.mk
+++ b/core/soong_cc_rust_prebuilt.mk
@@ -190,7 +190,12 @@
       # drop /root as /root is mounted as /
       my_unstripped_path := $(patsubst $(TARGET_OUT_UNSTRIPPED)/root/%,$(TARGET_OUT_UNSTRIPPED)/%, $(my_unstripped_path))
       symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem)
-      $(eval $(call copy-unstripped-elf-file-with-mapping,$(LOCAL_SOONG_UNSTRIPPED_BINARY),$(symbolic_output)))
+      elf_symbol_mapping_path := $(patsubst $(TARGET_OUT_UNSTRIPPED)/%,$(call intermediates-dir-for,PACKAGING,elf_symbol_mapping)/%,$(symbolic_output).textproto)
+
+      ALL_MODULES.$(my_register_name).SYMBOLIC_OUTPUT_PATH := $(symbolic_output)
+      ALL_MODULES.$(my_register_name).ELF_SYMBOL_MAPPING_PATH := $(elf_symbol_mapping_path)
+
+      $(eval $(call copy-unstripped-elf-file-with-mapping,$(LOCAL_SOONG_UNSTRIPPED_BINARY),$(symbolic_output),$(elf_symbol_mapping_path)))
       $(LOCAL_BUILT_MODULE): | $(symbolic_output)
 
       ifeq ($(BREAKPAD_GENERATE_SYMBOLS),true)
diff --git a/core/tasks/meta-lic.mk b/core/tasks/meta-lic.mk
index 620b1e2..0675a90 100644
--- a/core/tasks/meta-lic.mk
+++ b/core/tasks/meta-lic.mk
@@ -30,59 +30,6 @@
 $(eval $(call declare-1p-copy-files,device/google/atv,atv-component-overrides.xml))
 $(eval $(call declare-1p-copy-files,device/google/atv,tv_core_hardware.xml))
 
-# Moved here from device/google/bramble/Android.mk
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,default-permissions.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,libnfc-nci.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,fstab.postinstall,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,ueventd.rc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,hals.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,media_profiles_V1_0.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,media_codecs_performance.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,device_state_configuration.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,task_profiles.json,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,p2p_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/bramble,wpa_supplicant_overlay.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-
-$(eval $(call declare-1p-copy-files,device/google/bramble,audio_policy_configuration.xml))
-
-# Moved here from device/google/barbet/Android.mk
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,default-permissions.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,libnfc-nci.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,fstab.postinstall,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,ueventd.rc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,hals.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,media_profiles_V1_0.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,media_codecs_performance.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,device_state_configuration.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,task_profiles.json,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,p2p_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/barbet,wpa_supplicant_overlay.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-
-$(eval $(call declare-1p-copy-files,device/google/barbet,audio_policy_configuration.xml))
-
-# Moved here from device/google/coral/Android.mk
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,default-permissions.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,libnfc-nci.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,fstab.postinstall,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,ueventd.rc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,hals.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,media_profiles_V1_0.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,media_codecs_performance.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,device_state_configuration.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,task_profiles.json,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,p2p_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,wpa_supplicant_overlay.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/coral,display_19261132550654593.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-
-$(eval $(call declare-1p-copy-files,device/google/coral,audio_policy_configuration.xml))
-$(eval $(call declare-1p-copy-files,device/google/coral,display_19260504575090817.xml))
-
 # Moved here from device/google/cuttlefish/Android.mk
 $(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,.idc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
 $(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,default-permissions.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
@@ -152,23 +99,6 @@
 
 $(eval $(call declare-1p-copy-files,device/google/raviole,audio_policy_configuration.xml))
 
-# Moved here from device/google/redfin/Android.mk
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,default-permissions.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,libnfc-nci.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,fstab.postinstall,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,ueventd.rc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,hals.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,media_profiles_V1_0.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,media_codecs_performance.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,device_state_configuration.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,task_profiles.json,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,p2p_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/redfin,wpa_supplicant_overlay.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-
-$(eval $(call declare-1p-copy-files,device/google/redfin,audio_policy_configuration.xml))
-
 # Moved here from device/sample/Android.mk
 $(eval $(call declare-1p-copy-files,device/sample,))
 
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 3fe97ba..ab4abac 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -395,10 +395,6 @@
     system_manifest.xml \
     system_compatibility_matrix.xml \
 
-# Base modules when shipping api level is less than or equal to 34
-PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34 += \
-    android.hidl.memory@1.0-impl \
-
 # hwservicemanager is now installed on system_ext, but apexes might be using
 # old libraries that are expecting it to be installed on system. This allows
 # those apexes to continue working. The symlink can be removed once we are sure
diff --git a/target/product/base_system_ext.mk b/target/product/base_system_ext.mk
index 6767b9a..ad6828a 100644
--- a/target/product/base_system_ext.mk
+++ b/target/product/base_system_ext.mk
@@ -30,6 +30,7 @@
 PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34 += \
     hwservicemanager \
     android.hidl.allocator@1.0-service \
+    android.hidl.memory@1.0-impl \
 
 # AppFunction Extensions
 ifneq (,$(RELEASE_APPFUNCTION_SIDECAR))
diff --git a/target/product/base_vendor.mk b/target/product/base_vendor.mk
index 16fc7fd..b4e450e 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -106,7 +106,6 @@
 # VINTF data for vendor image
 PRODUCT_PACKAGES += \
     vendor_compatibility_matrix.xml \
-    vendor_manifest.xml \
 
 # Base modules and settings for the debug ramdisk, which is then packed
 # into a boot-debug.img and a vendor_boot-debug.img.
diff --git a/teams/Android.bp b/teams/Android.bp
index 8689267..d5bef59 100644
--- a/teams/Android.bp
+++ b/teams/Android.bp
@@ -2520,7 +2520,7 @@
 }
 
 team {
-    name: "trendy_team_xr_framework",
+    name: "trendy_team_virtual_device_framework",
 
     // go/trendy/manage/engineers/4798040542445568
     trendy_team_id: "4798040542445568",
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index d74e87a..e9c95fd 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -893,12 +893,16 @@
         package com.android.aconfig.test;
 
         import java.util.Arrays;
+        import java.util.HashMap;
+        import java.util.Map;
         import java.util.HashSet;
         import java.util.List;
         import java.util.Set;
         import java.util.function.BiPredicate;
         import java.util.function.Predicate;
 
+        import android.os.Build;
+
         /** @hide */
         public class CustomFeatureFlags implements FeatureFlags {
 
@@ -941,6 +945,19 @@
                     ""
                 )
             );
+
+            private Map<String, Integer> mFinalizedFlags = new HashMap<>(
+                Map.ofEntries(
+                    Map.entry("", Integer.MAX_VALUE)
+                )
+            );
+
+            public boolean isFlagFinalized(String flagName) {
+                if (!mFinalizedFlags.containsKey(flagName)) {
+                    return false;
+                }
+                return Build.VERSION.SDK_INT >= mFinalizedFlags.get(flagName);
+            }
         }
     "#;
 
@@ -1089,11 +1106,14 @@
         package com.android.aconfig.test;
 
         import java.util.Arrays;
+        import java.util.HashMap;
+        import java.util.Map;
         import java.util.HashSet;
         import java.util.List;
         import java.util.Set;
         import java.util.function.BiPredicate;
         import java.util.function.Predicate;
+        import android.os.Build;
 
         /** @hide */
         public class CustomFeatureFlags implements FeatureFlags {
@@ -1137,6 +1157,19 @@
                     ""
                 )
             );
+
+            private Map<String, Integer> mFinalizedFlags = new HashMap<>(
+                Map.ofEntries(
+                    Map.entry("", Integer.MAX_VALUE)
+                )
+            );
+
+            public boolean isFlagFinalized(String flagName) {
+                if (!mFinalizedFlags.containsKey(flagName)) {
+                    return false;
+                }
+                return Build.VERSION.SDK_INT >= mFinalizedFlags.get(flagName);
+            }
         }
     "#;
 
@@ -1296,11 +1329,14 @@
         package com.android.aconfig.test;
 
         import java.util.Arrays;
+        import java.util.HashMap;
+        import java.util.Map;
         import java.util.HashSet;
         import java.util.List;
         import java.util.Set;
         import java.util.function.BiPredicate;
         import java.util.function.Predicate;
+        import android.os.Build;
 
         /** @hide */
         public class CustomFeatureFlags implements FeatureFlags {
@@ -1344,6 +1380,20 @@
                     ""
                 )
             );
+
+            private Map<String, Integer> mFinalizedFlags = new HashMap<>(
+                Map.ofEntries(
+                    Map.entry(Flags.FLAG_DISABLED_RW_EXPORTED, 36),
+                    Map.entry("", Integer.MAX_VALUE)
+                )
+            );
+
+            public boolean isFlagFinalized(String flagName) {
+                if (!mFinalizedFlags.containsKey(flagName)) {
+                    return false;
+                }
+                return Build.VERSION.SDK_INT >= mFinalizedFlags.get(flagName);
+            }
         }
     "#;
 
diff --git a/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template b/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
index ef18367..c702c9b 100644
--- a/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
+++ b/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
@@ -5,11 +5,18 @@
 import android.compat.annotation.UnsupportedAppUsage;
 {{ -endif }}
 import java.util.Arrays;
+{{ -if library_exported }}
+import java.util.HashMap;
+import java.util.Map;
+{{ -endif }}
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.function.BiPredicate;
 import java.util.function.Predicate;
+{{ -if library_exported }}
+import android.os.Build;
+{{ -endif }}
 
 {{ -if single_exported_file }}
 {{ -if library_exported }}
@@ -73,4 +80,24 @@
             ""{# The empty string here is to resolve the ending comma #}
         )
     );
+
+{{ -if library_exported }}
+    private Map<String, Integer> mFinalizedFlags = new HashMap<>(
+        Map.ofEntries(
+            {{ -for item in flag_elements }}
+            {{ -if item.finalized_sdk_present }}
+            Map.entry(Flags.FLAG_{item.flag_name_constant_suffix}, {item.finalized_sdk_value}),
+            {{ -endif }}
+            {{ -endfor }}
+            Map.entry("", Integer.MAX_VALUE){# The empty entry to avoid empty entries #}
+        )
+    );
+
+    public boolean isFlagFinalized(String flagName) \{
+        if (!mFinalizedFlags.containsKey(flagName)) \{
+            return false;
+        }
+        return Build.VERSION.SDK_INT >= mFinalizedFlags.get(flagName);
+    }
+{{ -endif }}
 }
diff --git a/tools/aconfig/aconfig_storage_file/src/flag_info.rs b/tools/aconfig/aconfig_storage_file/src/flag_info.rs
index cf16834..a39b7ed 100644
--- a/tools/aconfig/aconfig_storage_file/src/flag_info.rs
+++ b/tools/aconfig/aconfig_storage_file/src/flag_info.rs
@@ -199,49 +199,28 @@
     };
 
     // this test point locks down the value list serialization
-    // TODO: b/376108268 - Use parameterized tests.
     #[test]
-    fn test_serialization_default() {
-        let flag_info_list = create_test_flag_info_list(DEFAULT_FILE_VERSION);
+    fn test_serialization() {
+        for file_version in 1..=MAX_SUPPORTED_FILE_VERSION {
+            let flag_info_list = create_test_flag_info_list(file_version);
 
-        let header: &FlagInfoHeader = &flag_info_list.header;
-        let reinterpreted_header = FlagInfoHeader::from_bytes(&header.into_bytes());
-        assert!(reinterpreted_header.is_ok());
-        assert_eq!(header, &reinterpreted_header.unwrap());
+            let header: &FlagInfoHeader = &flag_info_list.header;
+            let reinterpreted_header = FlagInfoHeader::from_bytes(&header.into_bytes());
+            assert!(reinterpreted_header.is_ok());
+            assert_eq!(header, &reinterpreted_header.unwrap());
 
-        let nodes: &Vec<FlagInfoNode> = &flag_info_list.nodes;
-        for node in nodes.iter() {
-            let reinterpreted_node = FlagInfoNode::from_bytes(&node.into_bytes()).unwrap();
-            assert_eq!(node, &reinterpreted_node);
+            let nodes: &Vec<FlagInfoNode> = &flag_info_list.nodes;
+            for node in nodes.iter() {
+                let reinterpreted_node = FlagInfoNode::from_bytes(&node.into_bytes()).unwrap();
+                assert_eq!(node, &reinterpreted_node);
+            }
+
+            let flag_info_bytes = flag_info_list.into_bytes();
+            let reinterpreted_info_list = FlagInfoList::from_bytes(&flag_info_bytes);
+            assert!(reinterpreted_info_list.is_ok());
+            assert_eq!(&flag_info_list, &reinterpreted_info_list.unwrap());
+            assert_eq!(flag_info_bytes.len() as u32, header.file_size);
         }
-
-        let flag_info_bytes = flag_info_list.into_bytes();
-        let reinterpreted_info_list = FlagInfoList::from_bytes(&flag_info_bytes);
-        assert!(reinterpreted_info_list.is_ok());
-        assert_eq!(&flag_info_list, &reinterpreted_info_list.unwrap());
-        assert_eq!(flag_info_bytes.len() as u32, header.file_size);
-    }
-
-    #[test]
-    fn test_serialization_max() {
-        let flag_info_list = create_test_flag_info_list(MAX_SUPPORTED_FILE_VERSION);
-
-        let header: &FlagInfoHeader = &flag_info_list.header;
-        let reinterpreted_header = FlagInfoHeader::from_bytes(&header.into_bytes());
-        assert!(reinterpreted_header.is_ok());
-        assert_eq!(header, &reinterpreted_header.unwrap());
-
-        let nodes: &Vec<FlagInfoNode> = &flag_info_list.nodes;
-        for node in nodes.iter() {
-            let reinterpreted_node = FlagInfoNode::from_bytes(&node.into_bytes()).unwrap();
-            assert_eq!(node, &reinterpreted_node);
-        }
-
-        let flag_info_bytes = flag_info_list.into_bytes();
-        let reinterpreted_info_list = FlagInfoList::from_bytes(&flag_info_bytes);
-        assert!(reinterpreted_info_list.is_ok());
-        assert_eq!(&flag_info_list, &reinterpreted_info_list.unwrap());
-        assert_eq!(flag_info_bytes.len() as u32, header.file_size);
     }
 
     // this test point locks down that version number should be at the top of serialized
diff --git a/tools/aconfig/aconfig_storage_file/src/flag_table.rs b/tools/aconfig/aconfig_storage_file/src/flag_table.rs
index 6fbee02..1b70c49 100644
--- a/tools/aconfig/aconfig_storage_file/src/flag_table.rs
+++ b/tools/aconfig/aconfig_storage_file/src/flag_table.rs
@@ -225,49 +225,28 @@
     };
 
     // this test point locks down the table serialization
-    // TODO: b/376108268 - Use parameterized tests.
     #[test]
-    fn test_serialization_default() {
-        let flag_table = create_test_flag_table(DEFAULT_FILE_VERSION);
+    fn test_serialization() {
+        for file_version in 1..=MAX_SUPPORTED_FILE_VERSION {
+            let flag_table = create_test_flag_table(file_version);
 
-        let header: &FlagTableHeader = &flag_table.header;
-        let reinterpreted_header = FlagTableHeader::from_bytes(&header.into_bytes());
-        assert!(reinterpreted_header.is_ok());
-        assert_eq!(header, &reinterpreted_header.unwrap());
+            let header: &FlagTableHeader = &flag_table.header;
+            let reinterpreted_header = FlagTableHeader::from_bytes(&header.into_bytes());
+            assert!(reinterpreted_header.is_ok());
+            assert_eq!(header, &reinterpreted_header.unwrap());
 
-        let nodes: &Vec<FlagTableNode> = &flag_table.nodes;
-        for node in nodes.iter() {
-            let reinterpreted_node = FlagTableNode::from_bytes(&node.into_bytes()).unwrap();
-            assert_eq!(node, &reinterpreted_node);
+            let nodes: &Vec<FlagTableNode> = &flag_table.nodes;
+            for node in nodes.iter() {
+                let reinterpreted_node = FlagTableNode::from_bytes(&node.into_bytes()).unwrap();
+                assert_eq!(node, &reinterpreted_node);
+            }
+
+            let flag_table_bytes = flag_table.into_bytes();
+            let reinterpreted_table = FlagTable::from_bytes(&flag_table_bytes);
+            assert!(reinterpreted_table.is_ok());
+            assert_eq!(&flag_table, &reinterpreted_table.unwrap());
+            assert_eq!(flag_table_bytes.len() as u32, header.file_size);
         }
-
-        let flag_table_bytes = flag_table.into_bytes();
-        let reinterpreted_table = FlagTable::from_bytes(&flag_table_bytes);
-        assert!(reinterpreted_table.is_ok());
-        assert_eq!(&flag_table, &reinterpreted_table.unwrap());
-        assert_eq!(flag_table_bytes.len() as u32, header.file_size);
-    }
-
-    #[test]
-    fn test_serialization_max() {
-        let flag_table = create_test_flag_table(MAX_SUPPORTED_FILE_VERSION);
-
-        let header: &FlagTableHeader = &flag_table.header;
-        let reinterpreted_header = FlagTableHeader::from_bytes(&header.into_bytes());
-        assert!(reinterpreted_header.is_ok());
-        assert_eq!(header, &reinterpreted_header.unwrap());
-
-        let nodes: &Vec<FlagTableNode> = &flag_table.nodes;
-        for node in nodes.iter() {
-            let reinterpreted_node = FlagTableNode::from_bytes(&node.into_bytes()).unwrap();
-            assert_eq!(node, &reinterpreted_node);
-        }
-
-        let flag_table_bytes = flag_table.into_bytes();
-        let reinterpreted_table = FlagTable::from_bytes(&flag_table_bytes);
-        assert!(reinterpreted_table.is_ok());
-        assert_eq!(&flag_table, &reinterpreted_table.unwrap());
-        assert_eq!(flag_table_bytes.len() as u32, header.file_size);
     }
 
     // this test point locks down that version number should be at the top of serialized
diff --git a/tools/aconfig/aconfig_storage_file/src/flag_value.rs b/tools/aconfig/aconfig_storage_file/src/flag_value.rs
index 9a14bec..d73bcfb 100644
--- a/tools/aconfig/aconfig_storage_file/src/flag_value.rs
+++ b/tools/aconfig/aconfig_storage_file/src/flag_value.rs
@@ -138,37 +138,21 @@
 
     #[test]
     // this test point locks down the value list serialization
-    // TODO: b/376108268 - Use parameterized tests.
-    fn test_serialization_default() {
-        let flag_value_list = create_test_flag_value_list(DEFAULT_FILE_VERSION);
+    fn test_serialization() {
+        for file_version in 1..=MAX_SUPPORTED_FILE_VERSION {
+            let flag_value_list = create_test_flag_value_list(file_version);
 
-        let header: &FlagValueHeader = &flag_value_list.header;
-        let reinterpreted_header = FlagValueHeader::from_bytes(&header.into_bytes());
-        assert!(reinterpreted_header.is_ok());
-        assert_eq!(header, &reinterpreted_header.unwrap());
+            let header: &FlagValueHeader = &flag_value_list.header;
+            let reinterpreted_header = FlagValueHeader::from_bytes(&header.into_bytes());
+            assert!(reinterpreted_header.is_ok());
+            assert_eq!(header, &reinterpreted_header.unwrap());
 
-        let flag_value_bytes = flag_value_list.into_bytes();
-        let reinterpreted_value_list = FlagValueList::from_bytes(&flag_value_bytes);
-        assert!(reinterpreted_value_list.is_ok());
-        assert_eq!(&flag_value_list, &reinterpreted_value_list.unwrap());
-        assert_eq!(flag_value_bytes.len() as u32, header.file_size);
-    }
-
-    #[test]
-    // this test point locks down the value list serialization
-    fn test_serialization_max() {
-        let flag_value_list = create_test_flag_value_list(MAX_SUPPORTED_FILE_VERSION);
-
-        let header: &FlagValueHeader = &flag_value_list.header;
-        let reinterpreted_header = FlagValueHeader::from_bytes(&header.into_bytes());
-        assert!(reinterpreted_header.is_ok());
-        assert_eq!(header, &reinterpreted_header.unwrap());
-
-        let flag_value_bytes = flag_value_list.into_bytes();
-        let reinterpreted_value_list = FlagValueList::from_bytes(&flag_value_bytes);
-        assert!(reinterpreted_value_list.is_ok());
-        assert_eq!(&flag_value_list, &reinterpreted_value_list.unwrap());
-        assert_eq!(flag_value_bytes.len() as u32, header.file_size);
+            let flag_value_bytes = flag_value_list.into_bytes();
+            let reinterpreted_value_list = FlagValueList::from_bytes(&flag_value_bytes);
+            assert!(reinterpreted_value_list.is_ok());
+            assert_eq!(&flag_value_list, &reinterpreted_value_list.unwrap());
+            assert_eq!(flag_value_bytes.len() as u32, header.file_size);
+        }
     }
 
     #[test]
diff --git a/tools/aconfig/aconfig_storage_file/src/package_table.rs b/tools/aconfig/aconfig_storage_file/src/package_table.rs
index 21357c7..4d6bd91 100644
--- a/tools/aconfig/aconfig_storage_file/src/package_table.rs
+++ b/tools/aconfig/aconfig_storage_file/src/package_table.rs
@@ -287,50 +287,28 @@
 
     #[test]
     // this test point locks down the table serialization
-    // TODO: b/376108268 - Use parameterized tests.
-    fn test_serialization_default() {
-        let package_table = create_test_package_table(DEFAULT_FILE_VERSION);
-        let header: &PackageTableHeader = &package_table.header;
-        let reinterpreted_header = PackageTableHeader::from_bytes(&header.into_bytes());
-        assert!(reinterpreted_header.is_ok());
-        assert_eq!(header, &reinterpreted_header.unwrap());
+    fn test_serialization() {
+        for file_version in 1..=MAX_SUPPORTED_FILE_VERSION {
+            let package_table = create_test_package_table(file_version);
+            let header: &PackageTableHeader = &package_table.header;
+            let reinterpreted_header = PackageTableHeader::from_bytes(&header.into_bytes());
+            assert!(reinterpreted_header.is_ok());
+            assert_eq!(header, &reinterpreted_header.unwrap());
 
-        let nodes: &Vec<PackageTableNode> = &package_table.nodes;
-        for node in nodes.iter() {
-            let reinterpreted_node =
-                PackageTableNode::from_bytes(&node.into_bytes(header.version), header.version)
-                    .unwrap();
-            assert_eq!(node, &reinterpreted_node);
+            let nodes: &Vec<PackageTableNode> = &package_table.nodes;
+            for node in nodes.iter() {
+                let reinterpreted_node =
+                    PackageTableNode::from_bytes(&node.into_bytes(header.version), header.version)
+                        .unwrap();
+                assert_eq!(node, &reinterpreted_node);
+            }
+
+            let package_table_bytes = package_table.into_bytes();
+            let reinterpreted_table = PackageTable::from_bytes(&package_table_bytes);
+            assert!(reinterpreted_table.is_ok());
+            assert_eq!(&package_table, &reinterpreted_table.unwrap());
+            assert_eq!(package_table_bytes.len() as u32, header.file_size);
         }
-
-        let package_table_bytes = package_table.into_bytes();
-        let reinterpreted_table = PackageTable::from_bytes(&package_table_bytes);
-        assert!(reinterpreted_table.is_ok());
-        assert_eq!(&package_table, &reinterpreted_table.unwrap());
-        assert_eq!(package_table_bytes.len() as u32, header.file_size);
-    }
-
-    #[test]
-    fn test_serialization_max() {
-        let package_table = create_test_package_table(MAX_SUPPORTED_FILE_VERSION);
-        let header: &PackageTableHeader = &package_table.header;
-        let reinterpreted_header = PackageTableHeader::from_bytes(&header.into_bytes());
-        assert!(reinterpreted_header.is_ok());
-        assert_eq!(header, &reinterpreted_header.unwrap());
-
-        let nodes: &Vec<PackageTableNode> = &package_table.nodes;
-        for node in nodes.iter() {
-            let reinterpreted_node =
-                PackageTableNode::from_bytes(&node.into_bytes(header.version), header.version)
-                    .unwrap();
-            assert_eq!(node, &reinterpreted_node);
-        }
-
-        let package_table_bytes = package_table.into_bytes();
-        let reinterpreted_table = PackageTable::from_bytes(&package_table_bytes);
-        assert!(reinterpreted_table.is_ok());
-        assert_eq!(&package_table, &reinterpreted_table.unwrap());
-        assert_eq!(package_table_bytes.len() as u32, header.file_size);
     }
 
     #[test]
diff --git a/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java b/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
index 63baf9e..3dd24b2 100644
--- a/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
+++ b/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
@@ -120,11 +120,11 @@
             return aconfigPackage;
         } catch (AconfigStorageException e) {
             throw new AconfigStorageReadException(
-                    e.getErrorCode(), "Fail to create AconfigPackage", e);
+                    e.getErrorCode(), "Fail to create PlatformAconfigPackage: " + packageName, e);
         } catch (Exception e) {
             throw new AconfigStorageReadException(
                     AconfigStorageReadException.ERROR_GENERIC,
-                    "Fail to create PlatformAconfigPackage",
+                    "Fail to create PlatformAconfigPackage: " + packageName,
                     e);
         }
     }
diff --git a/tools/aconfig/exported_flag_check/allow_list.txt b/tools/aconfig/exported_flag_check/allow_flag_list.txt
similarity index 100%
rename from tools/aconfig/exported_flag_check/allow_list.txt
rename to tools/aconfig/exported_flag_check/allow_flag_list.txt
diff --git a/tools/aconfig/exported_flag_check/allow_package_list.txt b/tools/aconfig/exported_flag_check/allow_package_list.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/aconfig/exported_flag_check/allow_package_list.txt
diff --git a/tools/aconfig/exported_flag_check/src/utils.rs b/tools/aconfig/exported_flag_check/src/utils.rs
index 2c30424..3686fec 100644
--- a/tools/aconfig/exported_flag_check/src/utils.rs
+++ b/tools/aconfig/exported_flag_check/src/utils.rs
@@ -60,9 +60,15 @@
     Ok(HashSet::from_iter(iter))
 }
 
-fn get_allow_list() -> Result<HashSet<FlagId>> {
+fn get_allow_flag_list() -> Result<HashSet<FlagId>> {
     let allow_list: HashSet<FlagId> =
-        include_str!("../allow_list.txt").lines().map(|x| x.into()).collect();
+        include_str!("../allow_flag_list.txt").lines().map(|x| x.into()).collect();
+    Ok(allow_list)
+}
+
+fn get_allow_package_list() -> Result<HashSet<FlagId>> {
+    let allow_list: HashSet<FlagId> =
+        include_str!("../allow_package_list.txt").lines().map(|x| x.into()).collect();
     Ok(allow_list)
 }
 
@@ -73,7 +79,9 @@
     all_flags: &HashSet<FlagId>,
     already_finalized_flags: &HashSet<FlagId>,
 ) -> Result<Vec<FlagId>> {
-    let allow_list = get_allow_list()?;
+    let allow_flag_list = get_allow_flag_list()?;
+    let allow_package_list = get_allow_package_list()?;
+
     let new_flags: Vec<FlagId> = all_flags
         .difference(flags_used_with_flaggedapi_annotation)
         .cloned()
@@ -81,11 +89,19 @@
         .difference(already_finalized_flags)
         .cloned()
         .collect::<HashSet<_>>()
-        .difference(&allow_list)
+        .difference(&allow_flag_list)
+        .filter(|flag| {
+            if let Some(last_dot_index) = flag.rfind('.') {
+                let package_name = &flag[..last_dot_index];
+                !allow_package_list.contains(package_name)
+            } else {
+                true
+            }
+        })
         .cloned()
         .collect();
 
-    Ok(new_flags.into_iter().collect())
+    Ok(new_flags)
 }
 
 #[cfg(test)]
diff --git a/tools/aconfig/fake_device_config/src/android/os/Build.java b/tools/aconfig/fake_device_config/src/android/os/Build.java
index 8ec72fb..790ff82 100644
--- a/tools/aconfig/fake_device_config/src/android/os/Build.java
+++ b/tools/aconfig/fake_device_config/src/android/os/Build.java
@@ -18,6 +18,9 @@
 
 public class Build {
     public static class VERSION {
-        public static final int SDK_INT = 0;
+        public static final int SDK_INT = placeholder();
+        private static int placeholder() {
+            throw new UnsupportedOperationException("Stub!");
+        }
     }
 }
diff --git a/tools/otatools_package/Android.bp b/tools/otatools_package/Android.bp
deleted file mode 100644
index 5c7bfc7..0000000
--- a/tools/otatools_package/Android.bp
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (C) 2025 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.
-
-package {
-    // See: http://go/android-license-faq
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-java_genrule_host {
-    name: "otatools_package_dep_jars",
-    tools: ["soong_zip"],
-    compile_multilib: "first",
-    cmd: "mkdir -p $(genDir)/framework && " +
-        "cp $(in) $(genDir)/framework && " +
-        "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)/framework",
-    srcs: [
-        ":apksigner",
-        ":boot_signer",
-        ":signapk",
-        ":verity_signer",
-    ],
-    out: ["otatools_package_dep_jars.zip"],
-}
-
-genrule {
-    name: "otatools_package_cert_files",
-    tools: ["soong_zip"],
-    cmd: "mkdir -p $(genDir)/tmp/ && " +
-        "echo $(in) > $(genDir)/tmp/zip_files.list && " +
-        "$(location soong_zip) -o $(out) -l $(genDir)/tmp/zip_files.list ",
-    srcs: [
-        ":soong_generated_otatools_package_filegroup",
-    ],
-    out: ["otatools_package_cert_files.zip"],
-}
-
-java_genrule_host {
-    name: "otatools_package",
-    tools: ["merge_zips"],
-    compile_multilib: "first",
-    cmd: "$(location merge_zips) $(out) $(in)",
-    srcs: [
-        ":otatools_package_cert_files",
-        ":otatools_package_dep_jars",
-        ":otatools_package_releasetools",
-    ],
-    // TODO: Rename as "otatools.zip" when the rest files are ready.
-    out: ["otatools_temp.zip"],
-    dist: {
-        targets: [
-            "otatools-package-temp",
-        ],
-    },
-}
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 2232385..3467152 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -650,12 +650,3 @@
         unit_test: true,
     },
 }
-
-genrule {
-    name: "otatools_package_releasetools",
-    tools: ["soong_zip"],
-    srcs: ["**/*"],
-    cmd: "find build/make/tools/releasetools -name '*.pyc' -prune -o \\( -type f -o -type l \\) -print | sort > $(genDir)/files.txt && " +
-        "$(location soong_zip) -o $(out) -C build/make/tools -l $(genDir)/files.txt",
-    out: ["otatools_package_releasetools.zip"],
-}
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index e5f5f92..3fc08c6 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1410,7 +1410,22 @@
   return errors
 
 
-def RunHostInitVerifier(product_out, partition_map):
+def RunVendoredHostInitVerifier(product_out, partition_map):
+  """Runs vendor host_init_verifier on the init rc files within selected partitions.
+
+  host_init_verifier searches the etc/init path within each selected partition.
+
+  Args:
+    product_out: PRODUCT_OUT directory, containing partition directories.
+    partition_map: A map of partition name -> relative path within product_out.
+  """
+  return RunHostInitVerifier(
+      product_out,
+      partition_map,
+      tool=os.path.join(OPTIONS.vendor_otatools, 'bin', 'host_init_verifier'))
+
+
+def RunHostInitVerifier(product_out, partition_map, tool="host_init_verifier"):
   """Runs host_init_verifier on the init rc files within partitions.
 
   host_init_verifier searches the etc/init path within each partition.
@@ -1418,9 +1433,10 @@
   Args:
     product_out: PRODUCT_OUT directory, containing partition directories.
     partition_map: A map of partition name -> relative path within product_out.
+    tool: Full path to host_init_verifier or binary name
   """
   allowed_partitions = ("system", "system_ext", "product", "vendor", "odm")
-  cmd = ["host_init_verifier"]
+  cmd = [tool]
   for partition, path in partition_map.items():
     if partition not in allowed_partitions:
       raise ExternalError("Unable to call host_init_verifier for partition %s" %
diff --git a/tools/releasetools/merge/merge_compatibility_checks.py b/tools/releasetools/merge/merge_compatibility_checks.py
index 8c9993f..80b5caa 100644
--- a/tools/releasetools/merge/merge_compatibility_checks.py
+++ b/tools/releasetools/merge/merge_compatibility_checks.py
@@ -95,8 +95,19 @@
 def CheckInitRcFiles(target_files_dir, partition_map):
   """Check for any init.rc issues using host_init_verifier."""
   try:
+    vendor_partitions = set()
+    if OPTIONS.vendor_otatools:
+      vendor_partitions = {"vendor", "odm"}
+      common.RunVendoredHostInitVerifier(
+          product_out=target_files_dir,
+          partition_map={p: partition_map[p] for p in vendor_partitions})
+
     common.RunHostInitVerifier(
-        product_out=target_files_dir, partition_map=partition_map)
+        product_out=target_files_dir,
+        partition_map={
+            p: partition_map[p]
+            for p in partition_map.keys() - vendor_partitions
+        })
   except RuntimeError as err:
     return [str(err)]
   return []
diff --git a/tools/releasetools/merge/merge_target_files.py b/tools/releasetools/merge/merge_target_files.py
index fdba927..de4d9a8 100755
--- a/tools/releasetools/merge/merge_target_files.py
+++ b/tools/releasetools/merge/merge_target_files.py
@@ -87,8 +87,8 @@
       If provided, rebuilds odm.img or vendor.img to include merged sepolicy
       files. If odm is present then odm is preferred.
 
-  --vendor-otatools otatools.zip
-      If provided, use this otatools.zip when recompiling the odm or vendor
+  --vendor-otatools otatools.zip or directory
+      If provided, use these otatools when recompiling the odm or vendor
       image to include sepolicy.
 
   --keep-tmp
@@ -312,12 +312,9 @@
       '%s recompilation will be performed using the vendor otatools.zip',
       partition_img)
 
-  # Unzip the vendor build's otatools.zip and target-files archive.
-  vendor_otatools_dir = common.MakeTempDir(
-      prefix='merge_target_files_vendor_otatools_')
+  # Unzip the vendor build's target-files archive.
   vendor_target_files_dir = common.MakeTempDir(
       prefix='merge_target_files_vendor_target_files_')
-  common.UnzipToDir(OPTIONS.vendor_otatools, vendor_otatools_dir)
   merge_utils.CollectTargetFiles(
       input_zipfile_or_dir=OPTIONS.vendor_target_files,
       output_dir=vendor_target_files_dir,
@@ -335,7 +332,7 @@
   remove_file_if_exists(
       os.path.join(vendor_target_files_dir, 'IMAGES', partition_img))
   rebuild_partition_command = [
-      os.path.join(vendor_otatools_dir, 'bin', 'add_img_to_target_files'),
+      os.path.join(OPTIONS.vendor_otatools, 'bin', 'add_img_to_target_files'),
       '--verbose',
       '--add_missing',
   ]
@@ -669,6 +666,12 @@
   if OPTIONS.output_item_list:
     OPTIONS.output_item_list = common.LoadListFromFile(OPTIONS.output_item_list)
 
+  if OPTIONS.vendor_otatools and zipfile.is_zipfile(OPTIONS.vendor_otatools):
+    vendor_otatools_dir = common.MakeTempDir(
+        prefix='merge_target_files_vendor_otatools_')
+    common.UnzipToDir(OPTIONS.vendor_otatools, vendor_otatools_dir)
+    OPTIONS.vendor_otatools = vendor_otatools_dir
+
   if not merge_utils.ValidateConfigLists():
     sys.exit(1)