Merge "CameraX trendy team has been renamed to `Android Camera Innovation Team` and Trendy has been updated as well. This is to fix Androidbp to align with trendy name." into main
diff --git a/Changes.md b/Changes.md
index 9f2449c..eddec04 100644
--- a/Changes.md
+++ b/Changes.md
@@ -40,14 +40,8 @@
 
 ## Python 2 to 3 migration
 
-The path set when running builds now makes the `python` executable point to python 3,
-whereas on previous versions it pointed to python 2. If you still have python 2 scripts,
-you can change the shebang line to use `python2` explicitly. This only applies for
-scripts run directly from makefiles, or from soong genrules.
-
-In addition, `python_*` soong modules no longer allow python 2.
-
-Python 2 is slated for complete removal in V.
+Python 2 has been completely removed from the build. Please migrate any remaining usages to
+Python 3, and remove any version-specific properties from bp files.
 
 ## Stop referencing sysprop_library directly from cc modules
 
diff --git a/core/Makefile b/core/Makefile
index 7b4f58d..92f9b9c 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -295,11 +295,6 @@
 .PHONY: ndk-docs
 endif
 
-ifeq ($(HOST_OS),linux)
-$(call dist-for-goals,sdk,$(API_FINGERPRINT))
-$(call dist-for-goals,droidcore,$(API_FINGERPRINT))
-endif
-
 INSTALLED_RECOVERYIMAGE_TARGET :=
 # Build recovery image if
 # BUILDING_RECOVERY_IMAGE && !BOARD_USES_RECOVERY_AS_BOOT && !BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT.
@@ -3599,7 +3594,6 @@
 ifeq ($(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE),)
 $(error PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE must be set if USE_SOONG_DEFINED_SYSTEM_IMAGE is true)
 endif
-SOONG_DEFINED_SYSTEM_IMAGE_PATH := $(call intermediates-dir-for,ETC,$(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE))/$(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE)
 SOONG_DEFINED_SYSTEM_IMAGE_BASE := $(dir $(ALL_MODULES.$(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE).FILESYSTEM_FILELIST))
 $(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(systemimage_intermediates)/file_list.txt $(SOONG_DEFINED_SYSTEM_IMAGE_PATH)
 $(eval $(call copy-one-file, $(SOONG_DEFINED_SYSTEM_IMAGE_PATH), $(BUILT_SYSTEMIMAGE)))
@@ -7324,29 +7318,6 @@
   $(call dist-for-goals,droidcore-unbundled apps_only,$(LLVM_COVERAGE_TOOLS_ZIP))
 endif
 
-# -----------------------------------------------------------------
-# A zip of the Android Apps. Not keeping full path so that we don't
-# include product names when distributing
-#
-name := $(TARGET_PRODUCT)
-ifeq ($(TARGET_BUILD_TYPE),debug)
-  name := $(name)_debug
-endif
-name := $(name)-apps
-
-APPS_ZIP := $(PRODUCT_OUT)/$(name).zip
-$(APPS_ZIP): $(FULL_SYSTEMIMAGE_DEPS)
-	@echo "Package apps: $@"
-	$(hide) rm -rf $@
-	$(hide) mkdir -p $(dir $@)
-	$(hide) apps_to_zip=`find $(TARGET_OUT_APPS) $(TARGET_OUT_APPS_PRIVILEGED) -mindepth 2 -maxdepth 3 -name "*.apk"`; \
-	if [ -z "$$apps_to_zip" ]; then \
-	    echo "No apps to zip up. Generating empty apps archive." ; \
-	    a=$$(mktemp /tmp/XXXXXXX) && touch $$a && zip $@ $$a && zip -d $@ $$a; \
-	else \
-	    zip -qjX $@ $$apps_to_zip; \
-	fi
-
 ifeq (true,$(EMMA_INSTRUMENT))
 #------------------------------------------------------------------
 # An archive of classes for use in generating code-coverage reports
@@ -8079,6 +8050,46 @@
 
 endif # ANDROID_DESKTOP_MIGRATION_IMAGE
 
+ifdef SOONG_ONLY_ALL_IMAGES_ZIP
+
+allimages_soong_zip_args :=
+allimages_deps :=
+
+define include_image
+$(if $(1), \
+  $(eval allimages_soong_zip_args += -e $(notdir $(1)) -f $(1)) \
+  $(eval allimages_deps += $(1)))
+endef
+
+$(call include_image,$(INSTALLED_SUPERIMAGE_TARGET))
+$(call include_image,$(INSTALLED_BOOTIMAGE_TARGET))
+$(call include_image,$(INSTALLED_INIT_BOOT_IMAGE_TARGET))
+$(call include_image,$(INSTALLED_VENDOR_BOOTIMAGE_TARGET))
+$(call include_image,$(INSTALLED_USERDATAIMAGE_TARGET))
+$(call include_image,$(INSTALLED_RECOVERYIMAGE_TARGET))
+$(call include_image,$(INSTALLED_VBMETAIMAGE_TARGET))
+$(call include_image,$(INSTALLED_VBMETA_SYSTEMIMAGE_TARGET))
+$(call include_image,$(INSTALLED_VBMETA_VENDORIMAGE_TARGET))
+$(foreach partition,$(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)), \
+  $(call include_image,$(INSTALLED_VBMETA_$(partition)IMAGE_TARGET)))
+
+allimages_zip := $(PRODUCT_OUT)/all_images.zip
+$(allimages_zip): PRIVATE_SOONG_ZIP_ARGUMENTS := $(allimages_soong_zip_args)
+$(allimages_zip): $(SOONG_ZIP) $(allimages_deps)
+	$(SOONG_ZIP) -o $@ --sort_entries $(PRIVATE_SOONG_ZIP_ARGUMENTS)
+
+.PHONY: soong_only_diff_test
+soong_only_diff_test: PRIVATE_ALLIMAGES_ZIP := $(allimages_zip)
+soong_only_diff_test: $(allimages_zip) $(SOONG_ONLY_ALL_IMAGES_ZIP)
+	diff $(PRIVATE_ALLIMAGES_ZIP) $(SOONG_ONLY_ALL_IMAGES_ZIP)
+
+allimages_soong_zip_args :=
+allimages_deps :=
+allimages_zip :=
+include_image :=
+
+endif # ifdef SOONG_ONLY_ALL_IMAGES_ZIP
+
 # -----------------------------------------------------------------
 # OS Licensing
 
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index a205ab5..6fbc255 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -45,6 +45,7 @@
 $(call soong_config_set_bool,ANDROID,PRODUCT_FSVERITY_GENERATE_METADATA,$(if $(filter true,$(PRODUCT_FSVERITY_GENERATE_METADATA)),true,false))
 
 $(call add_soong_config_var,ANDROID,ADDITIONAL_M4DEFS,$(if $(BOARD_SEPOLICY_M4DEFS),$(addprefix -D,$(BOARD_SEPOLICY_M4DEFS))))
+$(call add_soong_config_var,ANDROID,TARGET_ADD_ROOT_EXTRA_VENDOR_SYMLINKS)
 
 # For BUILDING_GSI
 $(call soong_config_set_bool,gsi,building_gsi,$(if $(filter true,$(BUILDING_GSI)),true,false))
diff --git a/core/definitions.mk b/core/definitions.mk
index 1ab6388..ade8a9c 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -3286,7 +3286,7 @@
 	$(hide) mkdir -p "$$(dir $$@)"
 	$(hide) rm -f "$$@"
 	$(hide) \
-	    if $(LLVM_READOBJ) -h "$$<" >/dev/null 2>&1; then \
+	    if $(LLVM_READOBJ) -h "$$<" 2>/dev/null | grep -q "^Format: elf"; then \
 	        $(call echo-error,$(2),$(3)); \
 	        $(call echo-error,$(2),found ELF file: $$<); \
 	        false; \
diff --git a/core/main.mk b/core/main.mk
index 5ab807e..41a36ca 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -45,11 +45,6 @@
 $(KATI_obsolete_var BUILD_HOSTNAME,Use BUILD_HOSTNAME_FROM_FILE instead)
 $(KATI_obsolete_var FILE_NAME_TAG,https://android.googlesource.com/platform/build/+/master/Changes.md#FILE_NAME_TAG)
 
-$(BUILD_NUMBER_FILE):
-	# empty rule to prevent dangling rule error for a file that is written by soong_ui
-$(BUILD_HOSTNAME_FILE):
-	# empty rule to prevent dangling rule error for a file that is written by soong_ui
-
 .KATI_RESTAT: $(BUILD_NUMBER_FILE)
 .KATI_RESTAT: $(BUILD_HOSTNAME_FILE)
 
@@ -1200,8 +1195,9 @@
 ifneq ($(TARGET_BUILD_APPS),)
   # If this build is just for apps, only build apps and not the full system by default.
   ifneq ($(filter all,$(TARGET_BUILD_APPS)),)
-    # If they used the magic goal "all" then build all apps in the source tree.
-    unbundled_build_modules := $(foreach m,$(sort $(ALL_MODULES)),$(if $(filter APPS,$(ALL_MODULES.$(m).CLASS)),$(m)))
+    # The magic goal "all" used to build all apps in the source tree. This was deprecated
+    # so that we can know all TARGET_BUILD_APPS apps are built with soong for soong-only builds.
+    $(error TARGET_BUILD_APPS=all is deprecated)
   else
     unbundled_build_modules := $(sort $(TARGET_BUILD_APPS))
   endif
@@ -1625,7 +1621,6 @@
 
   ifneq ($(ANDROID_BUILD_EMBEDDED),true)
     $(call dist-for-goals-with-filenametag, droidcore, \
-      $(APPS_ZIP) \
       $(INTERNAL_EMULATOR_PACKAGE_TARGET) \
     )
   endif
@@ -1672,24 +1667,6 @@
     $(call dist-for-goals, dist_files, $(JACOCO_REPORT_CLASSES_ALL))
   endif
 
-  # Put XML formatted API files in the dist dir.
-  $(TARGET_OUT_COMMON_INTERMEDIATES)/api.xml: $(call java-lib-files,$(ANDROID_PUBLIC_STUBS)) $(APICHECK)
-  $(TARGET_OUT_COMMON_INTERMEDIATES)/system-api.xml: $(call java-lib-files,$(ANDROID_SYSTEM_STUBS)) $(APICHECK)
-  $(TARGET_OUT_COMMON_INTERMEDIATES)/module-lib-api.xml: $(call java-lib-files,$(ANDROID_MODULE_LIB_STUBS)) $(APICHECK)
-  $(TARGET_OUT_COMMON_INTERMEDIATES)/system-server-api.xml: $(call java-lib-files,$(ANDROID_SYSTEM_SERVER_STUBS)) $(APICHECK)
-  $(TARGET_OUT_COMMON_INTERMEDIATES)/test-api.xml: $(call java-lib-files,$(ANDROID_TEST_STUBS)) $(APICHECK)
-
-  api_xmls := $(addprefix $(TARGET_OUT_COMMON_INTERMEDIATES)/,api.xml system-api.xml module-lib-api.xml system-server-api.xml test-api.xml)
-  $(api_xmls):
-	$(hide) echo "Converting API file to XML: $@"
-	$(hide) mkdir -p $(dir $@)
-	$(hide) $(APICHECK_COMMAND) jar-to-jdiff $< $@
-
-  $(foreach xml,$(sort $(api_xmls)),$(call declare-1p-target,$(xml),))
-
-  $(call dist-for-goals, dist_files, $(api_xmls))
-  api_xmls :=
-
   ifdef CLANG_COVERAGE
     $(foreach f,$(SOONG_NDK_API_XML), \
         $(call dist-for-goals,droidcore,$(f):ndk_apis/$(notdir $(f))))
diff --git a/core/ninja_config.mk b/core/ninja_config.mk
index d4b7c6d..a1fff4d 100644
--- a/core/ninja_config.mk
+++ b/core/ninja_config.mk
@@ -19,8 +19,6 @@
 	build-art% \
 	build_kernel-nodeps \
 	clean-oat% \
-	continuous_instrumentation_tests \
-	continuous_native_tests \
 	cts \
 	custom_images \
 	dicttool_aosp \
diff --git a/core/release_config.mk b/core/release_config.mk
index 68e115f..c6986c7 100644
--- a/core/release_config.mk
+++ b/core/release_config.mk
@@ -156,20 +156,6 @@
     _used_files :=
     ifeq (,$(_must_protobuf)$(RELEASE_BUILD_FLAGS_IN_PROTOBUF))
         _use_protobuf :=
-    else
-        _base_all_release := all_release_configs-$(TARGET_PRODUCT)
-        $(call dist-for-goals,droid,\
-            $(_flags_dir)/$(_base_all_release).pb:build_flags/all_release_configs.pb \
-            $(_flags_dir)/$(_base_all_release).textproto:build_flags/all_release_configs.textproto \
-            $(_flags_dir)/$(_base_all_release).json:build_flags/all_release_configs.json \
-            $(_flags_dir)/inheritance_graph-$(TARGET_PRODUCT).dot:build_flags/inheritance_graph-$(TARGET_PRODUCT).dot \
-        )
-# These are always created, add an empty rule for them to keep ninja happy.
-$(_flags_dir)/inheritance_graph-$(TARGET_PRODUCT).dot:
-	: created by $(OUT_DIR)/release-config
-$(_flags_dir)/$(_base_all_release).pb $(_flags_dir)/$(_base_all_release).textproto $(_flags_dir)/$(_base_all_release).json:
-	: created by $(OUT_DIR)/release-config
-        _base_all_release :=
     endif
     _flags_dir:=
     _flags_file:=
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index d9f6150..1a55bf4 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -98,7 +98,7 @@
 api_map_out := $(HOST_OUT)/cts-api-map
 
 cts_jar_files := $(api_map_out)/cts_jar_files.txt
-cts_interactive_jar_files := $(api_map_out)/cts_interactive_jar_files.txt
+cts_v_host_jar_files := $(api_map_out)/cts_v_host_jar_files.txt
 cts_all_jar_files := $(api_map_out)/cts_all_jar_files.txt
 
 $(cts_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts.API_MAP_FILES))
@@ -106,14 +106,14 @@
 	mkdir -p $(dir $@)
 	echo $(PRIVATE_API_MAP_FILES) > $@
 
-$(cts_interactive_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts-interactive.API_MAP_FILES))
-$(cts_interactive_jar_files): $(SOONG_ANDROID_CTS_VERIFIER_APP_LIST)
+$(cts_v_host_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts-v-host.API_MAP_FILES))
+$(cts_v_host_jar_files): $(SOONG_ANDROID_CTS_VERIFIER_APP_LIST)
 	mkdir -p $(dir $@)
 	cp $< $@
 	echo $(PRIVATE_API_MAP_FILES) >> $@
 
 $(cts_all_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts.API_MAP_FILES) \
-                                                      $(COMPATIBILITY.cts-interactive.API_MAP_FILES))
+                                                      $(COMPATIBILITY.cts-v-host.API_MAP_FILES))
 $(cts_all_jar_files): $(SOONG_ANDROID_CTS_VERIFIER_APP_LIST)
 	mkdir -p $(dir $@)
 	cp $< $@
@@ -129,6 +129,13 @@
 		$(hide) $(ACP)  $< $@
 
 system_api_xml_description := $(TARGET_OUT_COMMON_INTERMEDIATES)/system-api.xml
+module_lib_api_xml_description := $(TARGET_OUT_COMMON_INTERMEDIATES)/module-lib-api.xml
+system_service_api_description := $(TARGET_OUT_COMMON_INTERMEDIATES)/system-server-api.xml
+
+combined_api_xml_description := $(api_xml_description) \
+  $(system_api_xml_description) \
+  $(module_lib_api_xml_description) \
+  $(system_service_api_description)
 
 cts-test-coverage-report := $(coverage_out)/test-coverage.html
 cts-system-api-coverage-report := $(coverage_out)/system-api-coverage.html
@@ -140,14 +147,14 @@
 cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description) $(napi_xml_description)
 cts_system_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(system_api_xml_description)
 
-cts-system-api-map-xml-report := $(api_map_out)/cts-system-api-map.xml
-cts-interactive-system-api-map-xml-report := $(api_map_out)/cts-interactive-system-api-map.xml
-cts-combined-system-api-map-xml-report := $(api_map_out)/cts-combined-system-api-map.xml
-cts-combined-system-api-map-html-report := $(api_map_out)/cts-combined-system-api-map.html
+cts-api-map-xml-report := $(api_map_out)/cts-api-map.xml
+cts-v-host-api-map-xml-report := $(api_map_out)/cts-v-host-api-map.xml
+cts-combined-api-map-xml-report := $(api_map_out)/cts-combined-api-map.xml
+cts-combined-api-map-html-report := $(api_map_out)/cts-combined-api-map.html
 
-cts_system_api_map_dependencies := $(cts_api_map_exe) $(system_api_xml_description) $(cts_jar_files)
-cts_interactive_system_api_map_dependencies := $(cts_api_map_exe) $(system_api_xml_description) $(cts_interactive_jar_files)
-cts_combined_system_api_map_dependencies := $(cts_api_map_exe) $(system_api_xml_description) $(cts_all_jar_files)
+cts_api_map_dependencies := $(cts_api_map_exe) $(combined_api_xml_description) $(cts_jar_files)
+cts_v_host_api_map_dependencies := $(cts_api_map_exe) $(combined_api_xml_description) $(cts_v_host_jar_files)
+cts_combined_api_map_dependencies := $(cts_api_map_exe) $(combined_api_xml_description) $(cts_all_jar_files)
 
 android_cts_zip := $(HOST_OUT)/cts/android-cts.zip
 cts_verifier_apk := $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk
@@ -227,42 +234,42 @@
 .PHONY: cts-coverage-report-all cts-api-coverage
 cts-coverage-report-all: cts-test-coverage cts-verifier-coverage cts-combined-coverage cts-combined-xml-coverage
 
-$(cts-system-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-system-api-map-xml-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-system-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_jar_files)
-$(cts-system-api-map-xml-report) : $(android_cts_zip) $(cts_system_api_map_dependencies) | $(ACP)
-	$(call generate-api-map-report-cts,"CTS System API MAP Report - XML",\
+$(cts-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-api-map-xml-report): PRIVATE_API_XML_DESC := $(combined_api_xml_description)
+$(cts-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_jar_files)
+$(cts-api-map-xml-report) : $(android_cts_zip) $(cts_api_map_dependencies) | $(ACP)
+	$(call generate-api-map-report-cts,"CTS API MAP Report - XML",\
 			$(PRIVATE_JAR_FILES),xml)
 
-$(cts-interactive-system-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-interactive-system-api-map-xml-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-interactive-system-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_interactive_jar_files)
-$(cts-interactive-system-api-map-xml-report) : $(verifier_zip) $(cts_interactive_system_api_map_dependencies) | $(ACP)
-	$(call generate-api-map-report-cts,"CTS Interactive System API MAP Report - XML",\
+$(cts-v-host-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-v-host-api-map-xml-report): PRIVATE_API_XML_DESC := $(combined_api_xml_description)
+$(cts-v-host-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_v_host_jar_files)
+$(cts-v-host-api-map-xml-report) : $(verifier_zip) $(cts_v_host_api_map_dependencies) | $(ACP)
+	$(call generate-api-map-report-cts,"CTS-V-HOST API MAP Report - XML",\
 			$(PRIVATE_JAR_FILES),xml)
 
-$(cts-combined-system-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-combined-system-api-map-xml-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-combined-system-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
-$(cts-combined-system-api-map-xml-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_system_api_map_dependencies) | $(ACP)
-	$(call generate-api-map-report-cts,"CTS Combined System API MAP Report - XML",\
+$(cts-combined-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-combined-api-map-xml-report): PRIVATE_API_XML_DESC := $(combined_api_xml_description)
+$(cts-combined-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
+$(cts-combined-api-map-xml-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_api_map_dependencies) | $(ACP)
+	$(call generate-api-map-report-cts,"CTS Combined API MAP Report - XML",\
 			$(PRIVATE_JAR_FILES),xml)
 
-$(cts-combined-system-api-map-html-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-combined-system-api-map-html-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-combined-system-api-map-html-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
-$(cts-combined-system-api-map-html-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_system_api_map_dependencies) | $(ACP)
-	$(call generate-api-map-report-cts,"CTS Combined System API MAP Report - HTML",\
+$(cts-combined-api-map-html-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-combined-api-map-html-report): PRIVATE_API_XML_DESC := $(combined_api_xml_description)
+$(cts-combined-api-map-html-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
+$(cts-combined-api-map-html-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_api_map_dependencies) | $(ACP)
+	$(call generate-api-map-report-cts,"CTS Combined API MAP Report - HTML",\
 			$(PRIVATE_JAR_FILES),html)
 
-.PHONY: cts-system-api-map-xml
-cts-system-api-map-xml : $(cts-system-api-map-xml-report)
+.PHONY: cts-api-map-xml
+cts-api-map-xml : $(cts-api-map-xml-report)
 
-.PHONY: cts-interactive-system-api-map-xml
-cts-interactive-system-api-map-xml: $(cts-interactive-system-api-map-xml-report)
+.PHONY: cts-v-host-api-map-xml
+cts-v-host-api-map-xml: $(cts-v-host-api-map-xml-report)
 
-.PHONY: cts-combined-system-api-map-xml
-cts-combined-system-api-map-xml : $(cts-combined-system-api-map-xml-report)
+.PHONY: cts-combined-api-map-xml
+cts-combined-api-map-xml : $(cts-combined-api-map-xml-report)
 
 .PHONY: cts-api-map-all
 
@@ -282,13 +289,13 @@
 ALL_TARGETS.$(cts-combined-xml-coverage-report).META_LIC:=$(module_license_metadata)
 
 # Put the test api map report in the dist dir if "cts-api-map-all" is among the build goals.
-$(call dist-for-goals, cts-api-map-all, $(cts-combined-system-api-map-xml-report):cts-api-map-report.xml)
-$(call dist-for-goals, cts-api-map-all, $(cts-combined-system-api-map-html-report):cts-api-map-report.html)
+$(call dist-for-goals, cts-api-map-all, $(cts-combined-api-map-xml-report):cts-api-map-report.xml)
+$(call dist-for-goals, cts-api-map-all, $(cts-combined-api-map-html-report):cts-api-map-report.html)
 
-ALL_TARGETS.$(cts-system-api-map-xml-report).META_LIC:=$(module_license_metadata)
-ALL_TARGETS.$(cts-interactive-system-api-map-xml-report).META_LIC:=$(module_license_metadata)
-ALL_TARGETS.$(cts-combined-system-api-map-xml-report).META_LIC:=$(module_license_metadata)
-ALL_TARGETS.$(cts-combined-system-api-map-html-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-api-map-xml-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-v-host-api-map-xml-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-combined-api-map-xml-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-combined-api-map-html-report).META_LIC:=$(module_license_metadata)
 
 # Arguments;
 #  1 - Name of the report printed out on the screen
@@ -306,29 +313,30 @@
 #  3 - Format of the report
 define generate-api-map-report-cts
 	$(hide) mkdir -p $(dir $@)
-	$(hide) $(PRIVATE_CTS_API_MAP_EXE) -j 8 -a $(PRIVATE_API_XML_DESC) -i $(2) -f $(3) -o $@
+	$(hide) $(PRIVATE_CTS_API_MAP_EXE) -j 8 -a $(shell echo "$(PRIVATE_API_XML_DESC)" | tr ' ' ',') -i $(2) -f $(3) -o $@
 	@ echo $(1): file://$$(cd $(dir $@); pwd)/$(notdir $@)
 endef
 
 # Reset temp vars
 cts_api_coverage_dependencies :=
 cts_system_api_coverage_dependencies :=
-cts_system_api_map_dependencies :=
-cts_interactive_system_api_map_dependencies :=
-cts_combined_system_api_map_dependencies :=
+cts_api_map_dependencies :=
+cts_v_host_api_map_dependencies :=
+cts_combined_api_map_dependencies :=
 cts-combined-coverage-report :=
 cts-combined-xml-coverage-report :=
 cts-verifier-coverage-report :=
 cts-test-coverage-report :=
 cts-system-api-coverage-report :=
 cts-system-api-xml-coverage-report :=
-cts-system-api-map-xml-report :=
-cts-interactive-system-api-map-xml-report :=
-cts-combined-system-api-map-xml-report :=
-cts-combined-system-api-map-html-report :=
+cts-api-map-xml-report :=
+cts-v-host-api-map-xml-report :=
+cts-combined-api-map-xml-report :=
+cts-combined-api-map-html-report :=
 api_xml_description :=
 api_text_description :=
 system_api_xml_description :=
+combined_api_xml_description :=
 napi_xml_description :=
 napi_text_description :=
 coverage_out :=
diff --git a/core/tasks/device-tests.mk b/core/tasks/device-tests.mk
index 6164c2e..062ac23 100644
--- a/core/tasks/device-tests.mk
+++ b/core/tasks/device-tests.mk
@@ -14,7 +14,6 @@
 
 
 .PHONY: device-tests
-.PHONY: device-tests-host-shared-libs
 
 device-tests-zip := $(PRODUCT_OUT)/device-tests.zip
 # Create an artifact to include a list of test config files in device-tests.
@@ -22,7 +21,6 @@
 # Create an artifact to include all test config files in device-tests.
 device-tests-configs-zip := $(PRODUCT_OUT)/device-tests_configs.zip
 my_host_shared_lib_for_device_tests := $(call copy-many-files,$(COMPATIBILITY.device-tests.HOST_SHARED_LIBRARY.FILES))
-device_tests_host_shared_libs_zip := $(PRODUCT_OUT)/device-tests_host-shared-libs.zip
 
 $(device-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(device-tests-list-zip) $(device-tests-configs-zip)
 $(device-tests-zip) : PRIVATE_device_tests_list := $(PRODUCT_OUT)/device-tests_list
@@ -47,22 +45,9 @@
 	rm -f $@.list $@-host.list $@-target.list $@-host-test-configs.list $@-target-test-configs.list \
 		$(PRIVATE_device_tests_list)
 
-$(device_tests_host_shared_libs_zip) : PRIVATE_device_host_shared_libs_zip := $(device_tests_host_shared_libs_zip)
-$(device_tests_host_shared_libs_zip) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_device_tests)
-$(device_tests_host_shared_libs_zip) : $(my_host_shared_lib_for_device_tests) $(SOONG_ZIP)
-	rm -f $@-shared-libs.list
-	$(hide) for shared_lib in $(PRIVATE_HOST_SHARED_LIBS); do \
-	  echo $$shared_lib >> $@-shared-libs.list; \
-	done
-	grep $(HOST_OUT_TESTCASES) $@-shared-libs.list > $@-host-shared-libs.list || true
-	$(SOONG_ZIP) -d -o $(PRIVATE_device_host_shared_libs_zip) \
-	  -P host -C $(HOST_OUT) -l $@-host-shared-libs.list
-
 device-tests: $(device-tests-zip)
-device-tests-host-shared-libs: $(device_tests_host_shared_libs_zip)
 
-$(call dist-for-goals, device-tests, $(device-tests-zip) $(device-tests-list-zip) $(device-tests-configs-zip) $(device_tests_host_shared_libs_zip))
-$(call dist-for-goals, device-tests-host-shared-libs, $(device_tests_host_shared_libs_zip))
+$(call dist-for-goals, device-tests, $(device-tests-zip) $(device-tests-list-zip) $(device-tests-configs-zip))
 
 $(call declare-1p-container,$(device-tests-zip),)
 $(call declare-container-license-deps,$(device-tests-zip),$(COMPATIBILITY.device-tests.FILES) $(my_host_shared_lib_for_device_tests),$(PRODUCT_OUT)/:/)
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index e2d5fb4..401f557 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -66,6 +66,8 @@
 BOARD_ROOT_EXTRA_SYMLINKS += /vendor/lib/dsp:/dsp
 BOARD_ROOT_EXTRA_SYMLINKS += /mnt/vendor/persist:/persist
 BOARD_ROOT_EXTRA_SYMLINKS += /vendor/firmware_mnt:/firmware
+# for Android.bp
+TARGET_ADD_ROOT_EXTRA_VENDOR_SYMLINKS := true
 
 # TODO(b/36764215): remove this setting when the generic system image
 # no longer has QCOM-specific directories under /.
diff --git a/target/board/generic_arm64_plus_armv7/BoardConfig.mk b/target/board/generic_arm64_plus_armv7/BoardConfig.mk
new file mode 100644
index 0000000..2dca04f
--- /dev/null
+++ b/target/board/generic_arm64_plus_armv7/BoardConfig.mk
@@ -0,0 +1,55 @@
+# 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.
+#
+
+# arm64 emulator specific definitions
+TARGET_ARCH := arm64
+TARGET_ARCH_VARIANT := armv8-a
+TARGET_CPU_VARIANT := generic
+TARGET_CPU_ABI := arm64-v8a
+
+TARGET_2ND_ARCH := arm
+TARGET_2ND_CPU_ABI := armeabi-v7a
+TARGET_2ND_CPU_ABI2 := armeabi
+
+# DO NOT USE
+# DO NOT USE
+#
+# This architecture / CPU variant must NOT be used for any 64 bit
+# platform builds. It is the lowest common denominator required
+# to build an unbundled application or cts for all supported 32 and 64 bit
+# platforms.
+#
+# If you're building a 64 bit platform (and not an application) the
+# ARM-v8 specification allows you to assume all the features available in an
+# armv7-a-neon CPU. You should set the following as 2nd arch/cpu variant:
+#
+# TARGET_2ND_ARCH_VARIANT := armv8-a
+# TARGET_2ND_CPU_VARIANT := generic
+#
+# DO NOT USE
+# DO NOT USE
+TARGET_2ND_ARCH_VARIANT := armv7-a-neon
+# DO NOT USE
+# DO NOT USE
+TARGET_2ND_CPU_VARIANT := generic
+# DO NOT USE
+# DO NOT USE
+
+# Include 64-bit mediaserver to support 64-bit only devices
+TARGET_DYNAMIC_64_32_MEDIASERVER := true
+# Include 64-bit drmserver to support 64-bit only devices
+TARGET_DYNAMIC_64_32_DRMSERVER := true
+
+include build/make/target/board/BoardConfigGsiCommon.mk
diff --git a/target/board/generic_arm64_plus_armv7/README.txt b/target/board/generic_arm64_plus_armv7/README.txt
new file mode 100644
index 0000000..284bdc2
--- /dev/null
+++ b/target/board/generic_arm64_plus_armv7/README.txt
@@ -0,0 +1,7 @@
+The "generic_arm64_plus_armv7" product defines a non-hardware-specific arm64
+target with armv7 compatible arm32.  It is used for building CTS and other
+test suites for which the 32-bit binaries may be run on older devices with
+armv7 CPUs.
+
+It is not a product "base class"; no other products inherit
+from it or use it in any way.
diff --git a/target/board/generic_arm64_plus_armv7/device.mk b/target/board/generic_arm64_plus_armv7/device.mk
new file mode 100644
index 0000000..a9586f3
--- /dev/null
+++ b/target/board/generic_arm64_plus_armv7/device.mk
@@ -0,0 +1,15 @@
+#
+# 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.
+#
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index 07eb96d..5a7414e 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -36,6 +36,7 @@
 PRODUCT_MAKEFILES := \
     $(LOCAL_DIR)/aosp_arm64.mk \
     $(LOCAL_DIR)/aosp_arm64_fullmte.mk \
+    $(LOCAL_DIR)/aosp_arm64_plus_armv7.mk \
     $(LOCAL_DIR)/aosp_arm.mk \
     $(LOCAL_DIR)/aosp_riscv64.mk \
     $(LOCAL_DIR)/aosp_x86_64.mk \
@@ -48,6 +49,7 @@
     $(LOCAL_DIR)/aosp_64bitonly_x86_64.mk \
     $(LOCAL_DIR)/aosp_arm64.mk \
     $(LOCAL_DIR)/aosp_arm64_fullmte.mk \
+    $(LOCAL_DIR)/aosp_arm64_plus_armv7.mk \
     $(LOCAL_DIR)/aosp_arm.mk \
     $(LOCAL_DIR)/aosp_riscv64.mk \
     $(LOCAL_DIR)/aosp_x86_64.mk \
diff --git a/target/product/aosp_arm.mk b/target/product/aosp_arm.mk
index d9c362e..595c3db 100644
--- a/target/product/aosp_arm.mk
+++ b/target/product/aosp_arm.mk
@@ -60,8 +60,12 @@
 MODULE_BUILD_FROM_SOURCE ?= true
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
-endif
 
+PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE := aosp_system_image
+USE_SOONG_DEFINED_SYSTEM_IMAGE := true
+PRODUCT_USE_SOONG_NOTICE_XML := true
+
+endif
 
 PRODUCT_NAME := aosp_arm
 PRODUCT_DEVICE := generic
diff --git a/target/product/aosp_arm64.mk b/target/product/aosp_arm64.mk
index 7a9325d..cd3de51 100644
--- a/target/product/aosp_arm64.mk
+++ b/target/product/aosp_arm64.mk
@@ -66,8 +66,12 @@
 MODULE_BUILD_FROM_SOURCE ?= true
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
-endif
 
+PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE := aosp_system_image
+USE_SOONG_DEFINED_SYSTEM_IMAGE := true
+PRODUCT_USE_SOONG_NOTICE_XML := true
+
+endif
 
 PRODUCT_NAME := aosp_arm64
 PRODUCT_DEVICE := generic_arm64
diff --git a/target/product/aosp_arm64_plus_armv7.mk b/target/product/aosp_arm64_plus_armv7.mk
new file mode 100644
index 0000000..7322629
--- /dev/null
+++ b/target/product/aosp_arm64_plus_armv7.mk
@@ -0,0 +1,64 @@
+#
+# 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.
+#
+
+# aosp_arm64_plus_armv7 is for building CTS and other test suites with
+# arm64 as the primary architecture and armv7 arm32 as the secondary
+# architecture.
+
+#
+# All components inherited here go to system image
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_system.mk)
+
+PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := relaxed
+
+#
+# All components inherited here go to system_ext image
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system_ext.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system_ext.mk)
+
+# pKVM
+$(call inherit-product-if-exists, packages/modules/Virtualization/apex/product_packages.mk)
+
+#
+# All components inherited here go to product image
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_product.mk)
+
+#
+# All components inherited here go to vendor or vendor_boot image
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_arm64/device.mk)
+AB_OTA_UPDATER := true
+AB_OTA_PARTITIONS ?= system
+
+#
+# Special settings for GSI releasing
+#
+# Build modules from source if this has not been pre-configured
+MODULE_BUILD_FROM_SOURCE ?= true
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
+
+
+PRODUCT_NAME := aosp_arm64_plus_armv7
+PRODUCT_DEVICE := generic_arm64_plus_armv7
+PRODUCT_BRAND := Android
+PRODUCT_MODEL := AOSP on ARM64 with ARMV7
+
+PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
diff --git a/target/product/aosp_x86.mk b/target/product/aosp_x86.mk
index c26a8bf..d14abc2 100644
--- a/target/product/aosp_x86.mk
+++ b/target/product/aosp_x86.mk
@@ -58,8 +58,12 @@
 MODULE_BUILD_FROM_SOURCE ?= true
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
-endif
 
+PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE := aosp_system_image
+USE_SOONG_DEFINED_SYSTEM_IMAGE := true
+PRODUCT_USE_SOONG_NOTICE_XML := true
+
+endif
 
 PRODUCT_NAME := aosp_x86
 PRODUCT_DEVICE := generic_x86
diff --git a/target/product/aosp_x86_64.mk b/target/product/aosp_x86_64.mk
index 595940d..bd121e3 100644
--- a/target/product/aosp_x86_64.mk
+++ b/target/product/aosp_x86_64.mk
@@ -68,8 +68,12 @@
 MODULE_BUILD_FROM_SOURCE ?= true
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
-endif
 
+PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE := aosp_system_image
+USE_SOONG_DEFINED_SYSTEM_IMAGE := true
+PRODUCT_USE_SOONG_NOTICE_XML := true
+
+endif
 
 PRODUCT_NAME := aosp_x86_64
 PRODUCT_DEVICE := generic_x86_64
diff --git a/target/product/generic/Android.bp b/target/product/generic/Android.bp
index 82b6e76..12abea9 100644
--- a/target/product/generic/Android.bp
+++ b/target/product/generic/Android.bp
@@ -126,6 +126,23 @@
     },
 ]
 
+extra_vendor_symlinks = [
+    // Some vendors still haven't cleaned up all device specific directories under root!
+    // TODO(b/111434759, b/111287060) SoC specific hacks
+    {
+        target: "/vendor/lib/dsp",
+        name: "dsp",
+    },
+    {
+        target: "/mnt/vendor/persist",
+        name: "persist",
+    },
+    {
+        target: "/vendor/firmware_mnt",
+        name: "firmware",
+    },
+]
+
 filegroup {
     name: "generic_system_sign_key",
     srcs: [":avb_testkey_rsa4096"],
@@ -376,8 +393,8 @@
         "charger",
     ] + select(release_flag("RELEASE_APPFUNCTION_SIDECAR"), {
         true: [
-            "com.android.extensions.appfunctions",
-            "appfunctions.extension.xml",
+            "com.google.android.appfunctions.sidecar",
+            "appfunctions.sidecar.xml",
         ],
         default: [],
     }),
@@ -429,13 +446,40 @@
     libs: [":framework-res{.export-package.apk}"],
 }
 
-android_filesystem_defaults {
+soong_config_module_type {
+    name: "system_image_defaults",
+    module_type: "android_filesystem_defaults",
+    config_namespace: "ANDROID",
+    bool_variables: ["TARGET_ADD_ROOT_EXTRA_VENDOR_SYMLINKS"],
+    properties: ["symlinks"],
+}
+
+genrule {
+    name: "plat_and_vendor_file_contexts",
+    device_common_srcs: [
+        ":plat_file_contexts",
+        ":vendor_file_contexts",
+    ],
+    out: ["file_contexts"],
+    cmd: "cat $(in) > $(out)",
+}
+
+system_image_defaults {
     name: "system_image_defaults",
     partition_name: "system",
     base_dir: "system",
+    stem: "system.img",
+    no_full_install: true,
     dirs: generic_rootdirs,
-    symlinks: generic_symlinks,
-    file_contexts: ":plat_file_contexts",
+    soong_config_variables: {
+        TARGET_ADD_ROOT_EXTRA_VENDOR_SYMLINKS: {
+            symlinks: generic_symlinks + extra_vendor_symlinks,
+            conditions_default: {
+                symlinks: generic_symlinks,
+            },
+        },
+    },
+    file_contexts: ":plat_and_vendor_file_contexts",
     linker_config: {
         gen_linker_config: true,
         linker_config_srcs: [":system_linker_config_json_file"],
@@ -467,6 +511,7 @@
     avb_private_key: ":generic_system_sign_key",
     avb_algorithm: "SHA256_RSA4096",
     avb_hash_algorithm: "sha256",
+    rollback_index_location: 1,
 
     deps: [
         "abx",
@@ -707,6 +752,11 @@
             "update_engine_client",
         ],
         default: [],
+    }) + select(release_flag("RELEASE_UPROBESTATS_MODULE"), {
+        true: [],
+        default: [
+            "uprobestats", // base_system internal
+        ],
     }),
     multilib: {
         common: {
@@ -854,12 +904,7 @@
                 "android.system.virtualizationservice-ndk",
                 "libgsi",
                 "servicemanager",
-            ] + select(release_flag("RELEASE_UPROBESTATS_MODULE"), {
-                true: [],
-                default: [
-                    "uprobestats", // base_system internal
-                ],
-            }),
+            ],
         },
         both: {
             deps: [
diff --git a/target/product/gsi/Android.bp b/target/product/gsi/Android.bp
index 97b3895..dafbe46 100644
--- a/target/product/gsi/Android.bp
+++ b/target/product/gsi/Android.bp
@@ -81,8 +81,8 @@
     },
 ]
 
-android_system_image {
-    name: "android_gsi",
+android_filesystem_defaults {
+    name: "android_gsi_defaults",
     defaults: [
         "system_image_defaults",
         "system_ext_image_defaults",
@@ -105,11 +105,6 @@
         // telephony packages
         "CarrierConfig",
 
-        // Install a copy of the debug policy to the system_ext partition, and allow
-        // init-second-stage to load debug policy from system_ext.
-        // This option is only meant to be set by compliance GSI targets.
-        "system_ext_userdebug_plat_sepolicy.cil",
-
         ///////////////////////////////////////////
         // gsi_release
         ///////////////////////////////////////////
@@ -154,9 +149,64 @@
             deps: ["android.hidl.memory@1.0-impl"],
         },
     },
+    type: "ext4",
+}
+
+// system.img for gsi_{arch} targets
+android_system_image {
+    name: "android_gsi",
+    defaults: ["android_gsi_defaults"],
     enabled: select(soong_config_variable("ANDROID", "PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT"), {
         "true": true,
         default: false,
     }),
-    type: "ext4",
+    deps: [
+        // Install a copy of the debug policy to the system_ext partition, and allow
+        // init-second-stage to load debug policy from system_ext.
+        // This option is only meant to be set by compliance GSI targets.
+        "system_ext_userdebug_plat_sepolicy.cil",
+    ],
+}
+
+// system.img for aosp_{arch} targets
+android_system_image {
+    name: "aosp_system_image",
+    defaults: ["android_gsi_defaults"],
+    deps: [
+        // handheld_system_ext
+        "AccessibilityMenu",
+        "WallpaperCropper",
+
+        // telephony_system_ext
+        "EmergencyInfo",
+
+        // handheld_product
+        "Calendar",
+        "Contacts",
+        "DeskClock",
+        "Gallery2",
+        "Music",
+        "preinstalled-packages-platform-handheld-product.xml",
+        "QuickSearchBox",
+        "SettingsIntelligence",
+        "frameworks-base-overlays",
+
+        // telephony_product
+        "ImsServiceEntitlement",
+        "preinstalled-packages-platform-telephony-product.xml",
+
+        // more AOSP packages
+        "initial-package-stopped-states-aosp.xml",
+        "messaging",
+        "PhotoTable",
+        "preinstalled-packages-platform-aosp-product.xml",
+        "ThemePicker",
+    ] + select(product_variable("debuggable"), {
+        true: ["frameworks-base-overlays-debug"],
+        default: [],
+    }),
+    enabled: select(soong_config_variable("gsi", "building_gsi"), {
+        true: true,
+        default: false,
+    }),
 }
diff --git a/teams/OWNERS b/teams/OWNERS
index 85e69f3..02846eb 100644
--- a/teams/OWNERS
+++ b/teams/OWNERS
@@ -1,3 +1,2 @@
 dariofreni@google.com
 ronish@google.com
-caditya@google.com
diff --git a/tools/aconfig/aconfig/src/codegen/cpp.rs b/tools/aconfig/aconfig/src/codegen/cpp.rs
index 30e1a89..b855d78 100644
--- a/tools/aconfig/aconfig/src/codegen/cpp.rs
+++ b/tools/aconfig/aconfig/src/codegen/cpp.rs
@@ -234,11 +234,11 @@
     return provider_->disabled_rw_in_other_namespace();
 }
 
-inline bool enabled_fixed_ro() {
+constexpr inline bool enabled_fixed_ro() {
     return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
 }
 
-inline bool enabled_fixed_ro_exported() {
+constexpr inline bool enabled_fixed_ro_exported() {
     return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED;
 }
 
@@ -496,7 +496,7 @@
     return false;
 }
 
-inline bool enabled_fixed_ro() {
+constexpr inline bool enabled_fixed_ro() {
     return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
 }
 
@@ -1189,7 +1189,7 @@
 
 extern std::unique_ptr<flag_provider_interface> provider_;
 
-inline bool disabled_fixed_ro() {
+constexpr inline bool disabled_fixed_ro() {
     return COM_ANDROID_ACONFIG_TEST_DISABLED_FIXED_RO;
 }
 
@@ -1197,7 +1197,7 @@
     return false;
 }
 
-inline bool enabled_fixed_ro() {
+constexpr inline bool enabled_fixed_ro() {
     return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
 }
 
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index d6988c4..6bd9416 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -33,6 +33,7 @@
     pub allow_instrumentation: bool,
     pub package_fingerprint: u64,
     pub new_exported: bool,
+    pub single_exported_file: bool,
     pub check_api_level: bool,
 }
 
@@ -71,8 +72,15 @@
         is_platform_container,
         package_fingerprint: format!("0x{:X}L", config.package_fingerprint),
         new_exported: config.new_exported,
+        single_exported_file: config.single_exported_file,
     };
     let mut template = TinyTemplate::new();
+    if library_exported && config.single_exported_file {
+        template.add_template(
+            "ExportedFlags.java",
+            include_str!("../../templates/ExportedFlags.java.template"),
+        )?;
+    }
     template.add_template("Flags.java", include_str!("../../templates/Flags.java.template"))?;
     add_feature_flags_impl_template(&context, &mut template)?;
     template.add_template(
@@ -89,18 +97,25 @@
     )?;
 
     let path: PathBuf = package.split('.').collect();
-    [
+    let mut files = vec![
         "Flags.java",
         "FeatureFlags.java",
         "FeatureFlagsImpl.java",
         "CustomFeatureFlags.java",
         "FakeFeatureFlagsImpl.java",
-    ]
-    .iter()
-    .map(|file| {
-        Ok(OutputFile { contents: template.render(file, &context)?.into(), path: path.join(file) })
-    })
-    .collect::<Result<Vec<OutputFile>>>()
+    ];
+    if library_exported && config.single_exported_file {
+        files.push("ExportedFlags.java");
+    }
+    files
+        .iter()
+        .map(|file| {
+            Ok(OutputFile {
+                contents: template.render(file, &context)?.into(),
+                path: path.join(file),
+            })
+        })
+        .collect::<Result<Vec<OutputFile>>>()
 }
 
 fn gen_flags_by_namespace(flags: &[FlagElement]) -> Vec<NamespaceFlags> {
@@ -138,6 +153,7 @@
     pub is_platform_container: bool,
     pub package_fingerprint: String,
     pub new_exported: bool,
+    pub single_exported_file: bool,
 }
 
 #[derive(Serialize, Debug)]
@@ -243,13 +259,9 @@
         return Ok(());
     }
 
-    println!("lib exported: {}", context.library_exported);
-    println!("new_exp: {}", context.new_exported);
-    println!("allow in: {}", context.allow_instrumentation);
     match (context.library_exported, context.new_exported, context.allow_instrumentation) {
         // Exported library with new_exported enabled, use new storage exported template.
         (true, true, _) => {
-            println!("new exported template");
             template.add_template(
                 "FeatureFlagsImpl.java",
                 include_str!("../../templates/FeatureFlagsImpl.exported.java.template"),
@@ -261,10 +273,9 @@
         // device config for exported libs if new_exported isn't enabled.
         // Remove once new_exported is fully rolled out.
         (true, false, _) => {
-            println!("old exported, old template");
             template.add_template(
                 "FeatureFlagsImpl.java",
-                include_str!("../../templates/FeatureFlagsImpl.java.template"),
+                include_str!("../../templates/FeatureFlagsImpl.deviceConfig.java.template"),
             )?;
         }
 
@@ -280,7 +291,7 @@
         (false, _, false) => {
             template.add_template(
                 "FeatureFlagsImpl.java",
-                include_str!("../../templates/FeatureFlagsImpl.java.template"),
+                include_str!("../../templates/FeatureFlagsImpl.deviceConfig.java.template"),
             )?;
         }
     };
@@ -597,6 +608,7 @@
             allow_instrumentation: true,
             package_fingerprint: 5801144784618221668,
             new_exported: false,
+            single_exported_file: false,
             check_api_level: false,
         };
         let generated_files = generate_java_code(
@@ -757,6 +769,7 @@
             allow_instrumentation: true,
             package_fingerprint: 5801144784618221668,
             new_exported: false,
+            single_exported_file: false,
             check_api_level: false,
         };
         let generated_files = generate_java_code(
@@ -961,6 +974,7 @@
             allow_instrumentation: true,
             package_fingerprint: 5801144784618221668,
             new_exported: true,
+            single_exported_file: false,
             check_api_level: false,
         };
         let generated_files = generate_java_code(
@@ -1027,7 +1041,7 @@
                 } catch (LinkageError e) {
                     // for mainline module running on older devices.
                     // This should be replaces to version check, after the version bump.
-                    Log.e(TAG, e.toString());
+                    Log.w(TAG, e.toString());
                 }
                 isCached = true;
             }
@@ -1155,6 +1169,7 @@
             allow_instrumentation: true,
             package_fingerprint: 5801144784618221668,
             new_exported: false,
+            single_exported_file: false,
             check_api_level: false,
         };
         let generated_files = generate_java_code(
@@ -1282,6 +1297,7 @@
             allow_instrumentation: true,
             package_fingerprint: 5801144784618221668,
             new_exported: false,
+            single_exported_file: false,
             check_api_level: false,
         };
         let generated_files = generate_java_code(
diff --git a/tools/aconfig/aconfig/src/commands.rs b/tools/aconfig/aconfig/src/commands.rs
index ab726aa..ea63c7a 100644
--- a/tools/aconfig/aconfig/src/commands.rs
+++ b/tools/aconfig/aconfig/src/commands.rs
@@ -219,6 +219,7 @@
     codegen_mode: CodegenMode,
     allow_instrumentation: bool,
     new_exported: bool,
+    single_exported_file: bool,
     check_api_level: bool,
 ) -> Result<Vec<OutputFile>> {
     let parsed_flags = input.try_parse_flags()?;
@@ -237,6 +238,7 @@
         allow_instrumentation,
         package_fingerprint,
         new_exported,
+        single_exported_file,
         check_api_level,
     };
     generate_java_code(&package, modified_parsed_flags.into_iter(), config)
diff --git a/tools/aconfig/aconfig/src/main.rs b/tools/aconfig/aconfig/src/main.rs
index ef3b7ab..16b8272 100644
--- a/tools/aconfig/aconfig/src/main.rs
+++ b/tools/aconfig/aconfig/src/main.rs
@@ -158,11 +158,19 @@
                         .default_value("production"),
                 )
                 .arg(
+                    Arg::new("single-exported-file")
+                        .long("single-exported-file")
+                        .value_parser(clap::value_parser!(bool))
+                        .default_value("false"),
+                )
+                // TODO: b/395899938 - clean up flags for switching to new storage
+                .arg(
                     Arg::new("allow-instrumentation")
                         .long("allow-instrumentation")
                         .value_parser(clap::value_parser!(bool))
                         .default_value("false"),
                 )
+                // TODO: b/395899938 - clean up flags for switching to new storage
                 .arg(
                     Arg::new("new-exported")
                         .long("new-exported")
@@ -373,12 +381,15 @@
             let allow_instrumentation =
                 get_required_arg::<bool>(sub_matches, "allow-instrumentation")?;
             let new_exported = get_required_arg::<bool>(sub_matches, "new-exported")?;
+            let single_exported_file =
+                get_required_arg::<bool>(sub_matches, "single-exported-file")?;
             let check_api_level = get_required_arg::<bool>(sub_matches, "check-api-level")?;
             let generated_files = commands::create_java_lib(
                 cache,
                 *mode,
                 *allow_instrumentation,
                 *new_exported,
+                *single_exported_file,
                 *check_api_level,
             )
             .context("failed to create java lib")?;
diff --git a/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template b/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
index b82b9cb..ef18367 100644
--- a/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
+++ b/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
@@ -11,7 +11,13 @@
 import java.util.function.BiPredicate;
 import java.util.function.Predicate;
 
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
 /** @hide */
+{{ -endif }}
 public class CustomFeatureFlags implements FeatureFlags \{
 
     private BiPredicate<String, Predicate<FeatureFlags>> mGetValueImpl;
diff --git a/tools/aconfig/aconfig/templates/ExportedFlags.java.template b/tools/aconfig/aconfig/templates/ExportedFlags.java.template
new file mode 100644
index 0000000..4e36942
--- /dev/null
+++ b/tools/aconfig/aconfig/templates/ExportedFlags.java.template
@@ -0,0 +1,49 @@
+package {package_name}; {#- CODEGEN FOR EXPORTED MODE FOR NEW STORAGE SINGLE EXPORTED FILE#}
+
+import android.os.Build;
+import android.os.flagging.AconfigPackage;
+import android.util.Log;
+public final class ExportedFlags \{
+{{ -for item in flag_elements}}
+    public static final String FLAG_{item.flag_name_constant_suffix} = "{item.device_config_flag}";
+{{- endfor }}
+    private static final String TAG = "ExportedFlags";
+    private static volatile boolean isCached = false;
+{{ for flag in flag_elements }}
+    private static boolean {flag.method_name} = false;
+{{ -endfor }} {#- end flag_elements #}
+    private ExportedFlags() \{}
+
+    private void init() \{
+        try \{
+            AconfigPackage reader = AconfigPackage.load("{package_name}");
+            {{ -for namespace_with_flags in namespace_flags }}
+            {{ -for flag in namespace_with_flags.flags }}
+            {{ -if flag.finalized_sdk_present }}
+            {flag.method_name} = Build.VERSION.SDK_INT >= {flag.finalized_sdk_value} ? true : reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
+            {{ - else }} {#- else finalized_sdk_present #}
+            {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
+            {{ -endif}}  {#- end finalized_sdk_present#}
+            {{ -endfor }} {#- end namespace_with_flags.flags #}
+            {{ -endfor }} {#- end namespace_flags #}
+        } catch (Exception e) \{
+            // pass
+            Log.e(TAG, e.toString());
+        } catch (LinkageError e) \{
+            // for mainline module running on older devices.
+            // This should be replaces to version check, after the version bump.
+            Log.w(TAG, e.toString());
+        }
+        isCached = true;
+    }
+
+{{ -for flag in flag_elements }}
+    public static boolean {flag.method_name}() \{
+        if (!featureFlags.isCached) \{
+            featureFlags.init();
+        }
+        return featureFlags.{flag.method_name};
+    }
+{{ -endfor }}
+    private static ExportedFlags featureFlags = new ExportedFlags();
+}
diff --git a/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template
index 290d2c4..ed277ae 100644
--- a/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template
@@ -4,7 +4,13 @@
 import java.util.Map;
 import java.util.function.Predicate;
 
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
 /** @hide */
+{{ -endif }}
 public class FakeFeatureFlagsImpl extends CustomFeatureFlags \{
     private final Map<String, Boolean> mFlagMap = new HashMap<>();
     private final FeatureFlags mDefaults;
diff --git a/tools/aconfig/aconfig/templates/FeatureFlags.java.template b/tools/aconfig/aconfig/templates/FeatureFlags.java.template
index d2799b2..c8b9b7f 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlags.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlags.java.template
@@ -3,7 +3,16 @@
 // TODO(b/303773055): Remove the annotation after access issue is resolved.
 import android.compat.annotation.UnsupportedAppUsage;
 {{ -endif }}
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+/**
+ * @deprecated Use \{@link ExportedFlags} instead.
+ */
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
 /** @hide */
+{{ -endif }}
 public interface FeatureFlags \{
 {{ for item in flag_elements }}
 {{ -if not item.is_read_write }}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.deviceConfig.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.deviceConfig.java.template
new file mode 100644
index 0000000..44d5cc0
--- /dev/null
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.deviceConfig.java.template
@@ -0,0 +1,68 @@
+package {package_name};
+{{ if not library_exported- }}
+// TODO(b/303773055): Remove the annotation after access issue is resolved.
+import android.compat.annotation.UnsupportedAppUsage;
+{{ -endif }} {#- end of not library_exported#}
+{{ -if runtime_lookup_required }}
+import android.os.Binder;
+import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
+{{ -endif }}  {#- end of runtime_lookup_required#}
+/** @hide */
+public final class FeatureFlagsImpl implements FeatureFlags \{
+{{ -if runtime_lookup_required }}
+{{ -for namespace_with_flags in namespace_flags }}
+    private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
+{{ -endfor- }}
+{{ for flag in flag_elements }}
+{{- if flag.is_read_write }}
+    private static boolean {flag.method_name} = {flag.default_value};
+{{ -endif }} {#- end of is_read_write#}
+{{ -endfor }}
+{{ for namespace_with_flags in namespace_flags }}
+    private void load_overrides_{namespace_with_flags.namespace}() \{
+        final long ident = Binder.clearCallingIdentity();
+        try \{
+            Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
+{{ -for flag in namespace_with_flags.flags }}
+{{ -if flag.is_read_write }}
+            {flag.method_name} =
+                properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
+{{ -endif }} {#- end of is_read_write#}
+{{ -endfor }}
+        } catch (NullPointerException e) \{
+            throw new RuntimeException(
+                "Cannot read value from namespace {namespace_with_flags.namespace} "
+                + "from DeviceConfig. It could be that the code using flag "
+                + "executed before SettingsProvider initialization. Please use "
+                + "fixed read-only flag by adding is_fixed_read_only: true in "
+                + "flag declaration.",
+                e
+            );
+        } catch (SecurityException e) \{
+            // for isolated process case, skip loading flag value from the storage, use the default
+        } finally \{
+            Binder.restoreCallingIdentity(ident);
+        }
+        {namespace_with_flags.namespace}_is_cached = true;
+}
+{{ endfor- }}
+{{ -endif }}{#- end of runtime_lookup_required #}
+{{ -for flag in flag_elements }}
+    @Override
+{{ -if not library_exported }}
+    @com.android.aconfig.annotations.AconfigFlagAccessor
+    @UnsupportedAppUsage
+{{ -endif }}{#- end of not library_exported #}
+    public boolean {flag.method_name}() \{
+{{ -if flag.is_read_write }}
+        if (!{flag.device_config_namespace}_is_cached) \{
+            load_overrides_{flag.device_config_namespace}();
+        }
+        return {flag.method_name};
+{{ -else }} {#- else is_read_write #}
+        return {flag.default_value};
+{{ -endif }}{#- end of is_read_write #}
+    }
+{{ endfor }}
+}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
index 8b60824..b843ec2 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
@@ -3,7 +3,16 @@
 import android.os.Build;
 import android.os.flagging.AconfigPackage;
 import android.util.Log;
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+/**
+ * @deprecated Use \{@link ExportedFlags} instead.
+ */
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
 /** @hide */
+{{ -endif }}
 public final class FeatureFlagsImpl implements FeatureFlags \{
     private static final String TAG = "FeatureFlagsImplExport";
     private static volatile boolean isCached = false;
@@ -28,7 +37,7 @@
         } catch (LinkageError e) \{
             // for mainline module running on older devices.
             // This should be replaces to version check, after the version bump.
-            Log.e(TAG, e.toString());
+            Log.w(TAG, e.toString());
         }
         isCached = true;
     }
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
deleted file mode 100644
index ea2a2ee..0000000
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ /dev/null
@@ -1,248 +0,0 @@
-package {package_name};
-{{ -if not is_test_mode }}
-{{ -if allow_instrumentation }}
-{{ if not library_exported- }}{#- only new storage for prod mode #}
-// TODO(b/303773055): Remove the annotation after access issue is resolved.
-import android.compat.annotation.UnsupportedAppUsage;
-{{ -if runtime_lookup_required }}
-import android.os.Build;
-{{ if is_platform_container }}
-import android.os.flagging.PlatformAconfigPackageInternal;
-{{ -else }} {#- else is_platform_container #}
-import android.os.flagging.AconfigPackageInternal;
-{{ -endif }} {#- end of is_platform_container#}
-import android.util.Log;
-{{ -endif }} {#- end of runtime_lookup_required#}
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ -if runtime_lookup_required }}
-    private static final String TAG = "FeatureFlagsImpl";
-    private static volatile boolean isCached = false;
-{{ for flag in flag_elements }}
-{{ -if flag.is_read_write }}
-    private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
-
-    private void init() \{
-        try \{
-{{ if is_platform_container }}
-            PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("{package_name}", {package_fingerprint});
-{{ -else }} {#- else is_platform_container #}
-            AconfigPackageInternal reader = AconfigPackageInternal.load("{package_name}", {package_fingerprint});
-{{ -endif }} {#- end of is_platform_container#}
-        {{ -for namespace_with_flags in namespace_flags }}
-        {{ -for flag in namespace_with_flags.flags }}
-        {{ -if flag.is_read_write }}
-            {flag.method_name} = reader.getBooleanFlagValue({flag.flag_offset});
-        {{ -endif }} {#- is_read_write#}
-        {{ -endfor }}
-        {{ -endfor }}
-        } catch (Exception e) \{
-            Log.e(TAG, e.toString());
-        } catch (LinkageError e) \{
-            // for mainline module running on older devices.
-            // This should be replaces to version check, after the version bump.
-            Log.e(TAG, e.toString());
-        }
-        isCached = true;
-    }
-{{ -endif }}{#- end of runtime_lookup_required #}
-{{ -for flag in flag_elements }}
-    @Override
-    @com.android.aconfig.annotations.AconfigFlagAccessor
-    @UnsupportedAppUsage
-    public boolean {flag.method_name}() \{
-{{ -if flag.is_read_write }}
-        if (!isCached) \{
-            init();
-        }
-        return {flag.method_name};
-{{ -else }}{#- else is_read_write #}
-        return {flag.default_value};
-{{ -endif }}  {#- end of is_read_write#}
-    }
-{{ endfor }}
-}
-{{ -else- }}{#- device config for exproted mode #}
-{{ -if new_exported }}
-import android.os.Build;
-import android.os.flagging.AconfigPackage;
-import android.util.Log;
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-    private static final String TAG = "FeatureFlagsImplExport";
-    private static volatile boolean isCached = false;
-{{ for flag in flag_elements }}
-    private static boolean {flag.method_name} = false;
-{{ -endfor }}
-    private void init() \{
-        try \{
-            AconfigPackage reader = AconfigPackage.load("{package_name}");
-            {{ -for namespace_with_flags in namespace_flags }}
-            {{ -for flag in namespace_with_flags.flags }}
-            {{ -if flag.finalized_sdk_present }}
-            {flag.method_name} = Build.VERSION.SDK_INT >= {flag.finalized_sdk_value} ? true : reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
-            {{ - else }} {#- else finalized_sdk_present #}
-            {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
-            {{ -endif}}  {#- end of finalized_sdk_present#}
-            {{ -endfor }}
-            {{ -endfor }}
-        } catch (Exception e) \{
-            // pass
-            Log.e(TAG, e.toString());
-        } catch (LinkageError e) \{
-            // for mainline module running on older devices.
-            // This should be replaces to version check, after the version bump.
-            Log.e(TAG, e.toString());
-        }
-        isCached = true;
-    }
-{{ -for flag in flag_elements }}
-    @Override
-    public boolean {flag.method_name}() \{
-        if (!isCached) \{
-            init();
-        }
-        return {flag.method_name};
-    }
-{{ endfor }}
-}
-{{ else }}
-import android.os.Binder;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ -for namespace_with_flags in namespace_flags }}
-    private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
-{{ -endfor- }}
-{{ for flag in flag_elements }}
-{{ -if flag.is_read_write }}
-    private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }}  {#- end of is_read_write#}
-{{ -endfor }}
-{{ for namespace_with_flags in namespace_flags }}
-    private void load_overrides_{namespace_with_flags.namespace}() \{
-        final long ident = Binder.clearCallingIdentity();
-        try \{
-            Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
-{{ -for flag in namespace_with_flags.flags }}
-{{ -if flag.is_read_write }}
-            {flag.method_name} =
-                properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
-{{ -endif }}  {#- end of is_read_write#}
-{{ -endfor }}
-        } catch (NullPointerException e) \{
-            throw new RuntimeException(
-                "Cannot read value from namespace {namespace_with_flags.namespace} "
-                + "from DeviceConfig. It could be that the code using flag "
-                + "executed before SettingsProvider initialization. Please use "
-                + "fixed read-only flag by adding is_fixed_read_only: true in "
-                + "flag declaration.",
-                e
-            );
-        } catch (SecurityException e) \{
-            // for isolated process case, skip loading flag value from the storage, use the default
-        } finally \{
-            Binder.restoreCallingIdentity(ident);
-        }
-        {namespace_with_flags.namespace}_is_cached = true;
-    }
-{{ endfor- }}
-{{ -for flag in flag_elements }}
-    @Override
-    public boolean {flag.method_name}() \{
-        if (!{flag.device_config_namespace}_is_cached) \{
-            load_overrides_{flag.device_config_namespace}();
-        }
-        return {flag.method_name};
-    }
-{{ endfor }}
-}
-{{ -endif- }} {#- end new_exported mode #}
-{{ -endif- }} {#- end exported mode #}
-{{ else }} {#- else for allow_instrumentation is not enabled #}
-{{ if not library_exported- }}
-// TODO(b/303773055): Remove the annotation after access issue is resolved.
-import android.compat.annotation.UnsupportedAppUsage;
-{{ -endif }} {#- end of not library_exported#}
-
-{{ -if runtime_lookup_required }}
-import android.os.Binder;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
-{{ -endif }}  {#- end of runtime_lookup_required#}
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ -if runtime_lookup_required }}
-{{ -for namespace_with_flags in namespace_flags }}
-    private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
-{{ -endfor- }}
-
-{{ for flag in flag_elements }}
-{{- if flag.is_read_write }}
-    private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
-{{ for namespace_with_flags in namespace_flags }}
-    private void load_overrides_{namespace_with_flags.namespace}() \{
-        final long ident = Binder.clearCallingIdentity();
-        try \{
-            Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
-{{ -for flag in namespace_with_flags.flags }}
-{{ -if flag.is_read_write }}
-            {flag.method_name} =
-                properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
-        } catch (NullPointerException e) \{
-            throw new RuntimeException(
-                "Cannot read value from namespace {namespace_with_flags.namespace} "
-                + "from DeviceConfig. It could be that the code using flag "
-                + "executed before SettingsProvider initialization. Please use "
-                + "fixed read-only flag by adding is_fixed_read_only: true in "
-                + "flag declaration.",
-                e
-            );
-        } finally \{
-            Binder.restoreCallingIdentity(ident);
-        }
-        {namespace_with_flags.namespace}_is_cached = true;
-}
-{{ endfor- }}
-{{ -endif }}{#- end of runtime_lookup_required #}
-{{ -for flag in flag_elements }}
-    @Override
-{{ -if not library_exported }}
-    @com.android.aconfig.annotations.AconfigFlagAccessor
-    @UnsupportedAppUsage
-{{ -endif }}{#- end of not library_exported #}
-    public boolean {flag.method_name}() \{
-{{ -if flag.is_read_write }}
-        if (!{flag.device_config_namespace}_is_cached) \{
-            load_overrides_{flag.device_config_namespace}();
-        }
-        return {flag.method_name};
-{{ -else }} {#- else is_read_write #}
-        return {flag.default_value};
-{{ -endif }}{#- end of is_read_write #}
-    }
-{{ endfor }}
-}
-{{ endif}} {#- endif for allow_instrumentation #}
-{{ else }} {#- Generate only stub if in test mode #}
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ for flag in flag_elements }}
-    @Override
-{{ -if not library_exported }}
-    @com.android.aconfig.annotations.AconfigFlagAccessor
-{{ -endif }}
-    public boolean {flag.method_name}() \{
-        throw new UnsupportedOperationException(
-            "Method is not implemented.");
-    }
-{{ endfor- }}
-}
-{{ endif }}
diff --git a/tools/aconfig/aconfig/templates/Flags.java.template b/tools/aconfig/aconfig/templates/Flags.java.template
index e2f70b9..8a92d33 100644
--- a/tools/aconfig/aconfig/templates/Flags.java.template
+++ b/tools/aconfig/aconfig/templates/Flags.java.template
@@ -3,7 +3,16 @@
 // TODO(b/303773055): Remove the annotation after access issue is resolved.
 import android.compat.annotation.UnsupportedAppUsage;
 {{ -endif }}
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+/**
+ * @deprecated Use \{@link ExportedFlags} instead.
+ */
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
 /** @hide */
+{{ -endif }}
 public final class Flags \{
 {{ -for item in flag_elements}}
     /** @hide */
diff --git a/tools/aconfig/aconfig/templates/cpp_exported_header.template b/tools/aconfig/aconfig/templates/cpp_exported_header.template
index 4643c97..f6f576a 100644
--- a/tools/aconfig/aconfig/templates/cpp_exported_header.template
+++ b/tools/aconfig/aconfig/templates/cpp_exported_header.template
@@ -41,6 +41,7 @@
 extern std::unique_ptr<flag_provider_interface> provider_;
 
 {{ for item in class_elements}}
+{{ if not is_test_mode }}{{ if item.is_fixed_read_only }}constexpr {{ endif }}{{ endif -}}
 inline bool {item.flag_name}() \{
     {{ -if is_test_mode }}
     return provider_->{item.flag_name}();
diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
index e07ac1d..5acb54a 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
@@ -34,7 +34,7 @@
           ctor @FlaggedApi("android.flag.foo") public Clazz();
           field @FlaggedApi("android.flag.foo") public static final int FOO = 1; // 0x1
           method @FlaggedApi("android.flag.foo") public int getErrorCode();
-          method @FlaggedApi("android.flag.foo") public boolean setData(int, int[][], @NonNull android.util.Utility<T, U>);
+          method @FlaggedApi("android.flag.foo") public <T,U> boolean setData(int, int[][], @NonNull android.util.Utility<T, U>);
           method @FlaggedApi("android.flag.foo") public boolean setVariableData(int, android.util.Atom...);
           method @FlaggedApi("android.flag.foo") public boolean innerClassArg(android.Clazz.Builder);
         }
diff --git a/tools/edit_monitor/daemon_manager_test.py b/tools/edit_monitor/daemon_manager_test.py
index be28965..a7c175d 100644
--- a/tools/edit_monitor/daemon_manager_test.py
+++ b/tools/edit_monitor/daemon_manager_test.py
@@ -494,8 +494,8 @@
 
   def _assert_error_event_logged(self, fake_cclient, error_type):
     error_events = fake_cclient.get_sent_events()
-    self.assertEquals(len(error_events), 1)
-    self.assertEquals(
+    self.assertEqual(len(error_events), 1)
+    self.assertEqual(
         edit_event_pb2.EditEvent.FromString(
             error_events[0].source_extension
         ).edit_monitor_error_event.error_type,
diff --git a/tools/edit_monitor/edit_monitor_test.py b/tools/edit_monitor/edit_monitor_test.py
index 64a3871..deb73e7 100644
--- a/tools/edit_monitor/edit_monitor_test.py
+++ b/tools/edit_monitor/edit_monitor_test.py
@@ -260,7 +260,7 @@
 
     # Wait until observer started.
     received_data = receiver.recv()
-    self.assertEquals(received_data, 'Observer started.')
+    self.assertEqual(received_data, 'Observer started.')
 
     receiver.close()
     return p
diff --git a/tools/releasetools/fsverity_metadata_generator.py b/tools/releasetools/fsverity_metadata_generator.py
index fa7cd39..50e23e7 100644
--- a/tools/releasetools/fsverity_metadata_generator.py
+++ b/tools/releasetools/fsverity_metadata_generator.py
@@ -104,16 +104,13 @@
     out = subprocess.check_output(cmd, universal_newlines=True).strip()
     return bytes(bytearray.fromhex(out))
 
-  def generate(self, input_file, output_file=None):
+  def generate(self, input_file, output_file):
     if self._signature != 'none':
       if not self._key:
         raise RuntimeError("key must be specified.")
       if not self._cert:
         raise RuntimeError("cert must be specified.")
 
-    if not output_file:
-      output_file = input_file + '.fsv_meta'
-
     with TempDirectory() as temp_dir:
       self._do_generate(input_file, output_file, temp_dir)
 
@@ -229,6 +226,27 @@
       required=True)
   args = p.parse_args(sys.argv[1:])
 
+  output_file = args.output
+  if not output_file:
+    output_file = input_file + '.fsv_meta'
+
+  if output_file != args.input + '.fsv_meta':
+    sys.exit('When generating .fsv_meta files for symlinks, we assume that all fsv_meta files '
+      'are named the same as the file they protect, just with the .fsv_meta suffix appended. '
+      'We require that all .fsv_meta files follow this convention regardless of if it\'s a link or '
+      'not. However {args.input} had a different output file: {args.output}')
+
+  # remove the output file first, as switching between a file and a symlink can be complicated
+  try:
+    os.remove(output_file)
+  except FileNotFoundError:
+    pass
+
+  if os.path.islink(args.input):
+    target = os.readlink(args.input) + '.fsv_meta'
+    os.symlink(target, output_file)
+    sys.exit(0)
+
   generator = FSVerityMetadataGenerator(args.fsverity_path)
   generator.set_signature(args.signature)
   if args.signature == 'none':
@@ -241,4 +259,4 @@
     generator.set_cert(args.cert)
   generator.set_key_format(args.key_format)
   generator.set_hash_alg(args.hash_alg)
-  generator.generate(args.input, args.output)
+  generator.generate(args.input, output_file)
diff --git a/tools/tool_event_logger/OWNERS b/tools/tool_event_logger/OWNERS
index b692c9e..e93d20f 100644
--- a/tools/tool_event_logger/OWNERS
+++ b/tools/tool_event_logger/OWNERS
@@ -1,4 +1,3 @@
 include platform/tools/asuite:/OWNERS
 
 zhuoyao@google.com
-hzalek@google.com
\ No newline at end of file