Merge "aconfig: enforce all file versions are tested" 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/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/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/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/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/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
index 5c7bfc7..ef8c867 100644
--- a/tools/otatools_package/Android.bp
+++ b/tools/otatools_package/Android.bp
@@ -45,6 +45,55 @@
     out: ["otatools_package_cert_files.zip"],
 }
 
+cc_genrule {
+    name: "otatools_package_dep_libs",
+    host_supported: true,
+    device_supported: false,
+    compile_multilib: "first",
+    tools: ["soong_zip"],
+    cmd: "mkdir -p $(genDir)/$$CC_MULTILIB &&" +
+        "cp $(in) $(genDir)/$$CC_MULTILIB && " +
+        "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)/$$CC_MULTILIB",
+    srcs: [
+        ":libbase",
+        ":libbrillo",
+        ":libbrillo-stream",
+        ":libc++",
+        "//external/libchrome:libchrome",
+        ":libconscrypt_openjdk_jni",
+        ":libcrypto",
+        ":libcrypto_utils",
+        ":libcutils",
+        ":libevent",
+        ":libext2_blkid",
+        ":libext2_com_err",
+        ":libext2_e2p",
+        ":libext2_quota",
+        ":libext2_uuid",
+        ":libext2fs",
+        ":libext4_utils",
+        ":libfec",
+        ":libhidl-gen-utils",
+        ":libhidlmetadata",
+        ":libicui18n",
+        ":libicuuc",
+        ":liblog",
+        ":liblp",
+        ":liblz4",
+        ":libpcre2",
+        ":libprocessgroup",
+        ":libprotobuf-cpp-lite",
+        ":libselinux",
+        ":libsparse",
+        ":libsqlite",
+        ":libsquashfs_utils",
+        ":libssl",
+        ":libz",
+        ":libziparchive",
+    ],
+    out: ["otatools_package_dep_libs.zip"],
+}
+
 java_genrule_host {
     name: "otatools_package",
     tools: ["merge_zips"],
@@ -53,6 +102,7 @@
     srcs: [
         ":otatools_package_cert_files",
         ":otatools_package_dep_jars",
+        ":otatools_package_dep_libs",
         ":otatools_package_releasetools",
     ],
     // TODO: Rename as "otatools.zip" when the rest files are ready.
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)