Merge "Replace impl ToString with impl Display" into main
diff --git a/CleanSpec.mk b/CleanSpec.mk
index dfc0cd0..f8c96ff 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -779,6 +779,14 @@
 # Clear out rustc compiler intermediates after reverting rust compiler/linker split.
 $(call add-clean-step, find $(OUT_DIR) -name "*.rsp.whole.a" -print0 | xargs -0 /bin/bash -c 'rm -f $$$${@}; rm -f $$$${@/.rsp.whole.a/.rsp.a}; rm -f $$$${@/.rsp.whole.a/.rsp}')
 
+# Remove obsolete java compilation artifacts
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/)
+$(call add-clean-step, find $(OUT_DIR) -type f -name "*.jar" -print0 | xargs -0 rm -f)
+
+# Remove obsolete java compilation artifacts
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/)
+$(call add-clean-step, find $(OUT_DIR) -type f -name "*.jar" -print0 | xargs -0 rm -f)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index 00577ed..712719a 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -3406,12 +3406,29 @@
 
 FULL_SYSTEMIMAGE_DEPS += $(INTERNAL_ROOT_FILES) $(INSTALLED_FILES_FILE_ROOT)
 
-define write-file-lines
-$(1):
+# Returns a list of all the zip files from EXTRA_INSTALL_ZIPS whose install destination is
+# under $(1)
+define relevant-extra-install-zips
+$(strip $(foreach p,$(EXTRA_INSTALL_ZIPS), \
+  $(if $(filter $(1)/%,$(call word-colon,1,$(p))/), \
+    $(call word-colon,2,$(p)))))
+endef
+
+# Writes a text file that contains all of the files that will be inside a partition.
+# All the file paths will be relative to the partition's staging directory.
+# It will also take into account files inside zips listed in EXTRA_INSTALL_ZIPS.
+#
+# Arguments:
+#   $(1): Output file
+#   $(2): The partition's staging directory
+#   $(3): Files to include in the partition
+define write-partition-file-list
+$(1): $$(HOST_OUT_EXECUTABLES)/extra_install_zips_file_list $(call relevant-extra-install-zips,$(2))
 	@echo Writing $$@
 	rm -f $$@
 	echo -n > $$@
-	$$(foreach f,$(2),echo "$$(f)" >> $$@$$(newline))
+	$$(foreach f,$(subst $(2)/,,$(filter $(2)/%,$(3))),echo "$$(f)" >> $$@$$(newline))
+	$$(HOST_OUT_EXECUTABLES)/extra_install_zips_file_list $(2) $$(EXTRA_INSTALL_ZIPS) >> $$@
 endef
 
 # -----------------------------------------------------------------
@@ -3477,7 +3494,7 @@
                exit 1 )
 endef
 
-$(eval $(call write-file-lines,$(systemimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT)/,,$(filter $(TARGET_OUT)/%,$(FULL_SYSTEMIMAGE_DEPS)))))
+$(eval $(call write-partition-file-list,$(systemimage_intermediates)/file_list.txt,$(TARGET_OUT),$(FULL_SYSTEMIMAGE_DEPS)))
 # Used by soong sandwich to request the staging dir be built
 $(systemimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT)/%,$(FULL_SYSTEMIMAGE_DEPS))
 	touch $@
@@ -3594,7 +3611,7 @@
     $(INTERNAL_USERIMAGES_DEPS) \
     $(INTERNAL_USERDATAIMAGE_FILES)
 
-$(eval $(call write-file-lines,$(userdataimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_DATA)/,,$(filter $(TARGET_OUT_DATA)/%,$(INSTALLED_USERDATAIMAGE_TARGET_DEPS)))))
+$(eval $(call write-partition-file-list,$(userdataimage_intermediates)/file_list.txt,$(TARGET_OUT_DATA),$(INSTALLED_USERDATAIMAGE_TARGET_DEPS)))
 # Used by soong sandwich to request the staging dir be built
 $(userdataimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_DATA)/%,$(INSTALLED_USERDATAIMAGE_TARGET_DEPS))
 	touch $@
@@ -3650,7 +3667,7 @@
   $(call assert-max-image-size,$(INSTALLED_CACHEIMAGE_TARGET),$(BOARD_CACHEIMAGE_PARTITION_SIZE))
 endef
 
-$(eval $(call write-file-lines,$(cacheimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_CACHE)/,,$(filter $(TARGET_OUT_CACHE)/%,$(INTERNAL_CACHEIMAGE_FILES)))))
+$(eval $(call write-partition-file-list,$(cacheimage_intermediates)/file_list.txt,$(TARGET_OUT_CACHE),$(INTERNAL_CACHEIMAGE_FILES)))
 # Used by soong sandwich to request the staging dir be built
 $(cacheimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_CACHE)/%,$(INTERNAL_CACHEIMAGE_FILES))
 	touch $@
@@ -3737,7 +3754,7 @@
   $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
 endef
 
-$(eval $(call write-file-lines,$(systemotherimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_SYSTEM_OTHER)/,,$(filter $(TARGET_OUT_SYSTEM_OTHER)/%,$(INTERNAL_SYSTEMOTHERIMAGE_FILES)))))
+$(eval $(call write-partition-file-list,$(systemotherimage_intermediates)/file_list.txt,$(TARGET_OUT_SYSTEM_OTHER),$(INTERNAL_SYSTEMOTHERIMAGE_FILES)))
 # Used by soong sandwich to request the staging dir be built
 $(systemotherimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_SYSTEM_OTHER)/%,$(INTERNAL_SYSTEMOTHERIMAGE_FILES))
 	touch $@
@@ -3843,7 +3860,7 @@
   $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET) $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_VENDORIMAGE_PARTITION_SIZE))
 endef
 
-$(eval $(call write-file-lines,$(vendorimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_VENDOR)/,,$(filter $(TARGET_OUT_VENDOR)/%,$(INTERNAL_VENDORIMAGE_FILES)))))
+$(eval $(call write-partition-file-list,$(vendorimage_intermediates)/file_list.txt,$(TARGET_OUT_VENDOR),$(INTERNAL_VENDORIMAGE_FILES)))
 # Used by soong sandwich to request the staging dir be built
 $(vendorimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_VENDOR)/%,$(INTERNAL_VENDORIMAGE_FILES))
 	touch $@
@@ -3916,7 +3933,7 @@
   $(call assert-max-image-size,$(INSTALLED_PRODUCTIMAGE_TARGET),$(BOARD_PRODUCTIMAGE_PARTITION_SIZE))
 endef
 
-$(eval $(call write-file-lines,$(productimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_PRODUCT)/,,$(filter $(TARGET_OUT_PRODUCT)/%,$(INTERNAL_PRODUCTIMAGE_FILES)))))
+$(eval $(call write-partition-file-list,$(productimage_intermediates)/file_list.txt,$(TARGET_OUT_PRODUCT),$(INTERNAL_PRODUCTIMAGE_FILES)))
 # Used by soong sandwich to request the staging dir be built
 $(productimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_PRODUCT)/%,$(INTERNAL_PRODUCTIMAGE_FILES))
 	touch $@
@@ -3986,7 +4003,7 @@
   $(call assert-max-image-size,$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET),$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE))
 endef
 
-$(eval $(call write-file-lines,$(system_extimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_SYSTEM_EXT)/,,$(filter $(TARGET_OUT_SYSTEM_EXT)/%,$(INTERNAL_SYSTEM_EXTIMAGE_FILES)))))
+$(eval $(call write-partition-file-list,$(system_extimage_intermediates)/file_list.txt,$(TARGET_OUT_SYSTEM_EXT),$(INTERNAL_SYSTEM_EXTIMAGE_FILES)))
 # Used by soong sandwich to request the staging dir be built
 $(system_extimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_SYSTEM_EXT)/%,$(INTERNAL_SYSTEM_EXTIMAGE_FILES))
 	touch $@
@@ -4075,7 +4092,7 @@
   $(call assert-max-image-size,$(INSTALLED_ODMIMAGE_TARGET),$(BOARD_ODMIMAGE_PARTITION_SIZE))
 endef
 
-$(eval $(call write-file-lines,$(odmimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_ODM)/,,$(filter $(TARGET_OUT_ODM)/%,$(INTERNAL_ODMIMAGE_FILES)))))
+$(eval $(call write-partition-file-list,$(odmimage_intermediates)/file_list.txt,$(TARGET_OUT_ODM),$(INTERNAL_ODMIMAGE_FILES)))
 # Used by soong sandwich to request the staging dir be built
 $(odmimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_ODM)/%,$(INTERNAL_ODMIMAGE_FILES))
 	touch $@
@@ -4144,7 +4161,7 @@
   $(call assert-max-image-size,$(INSTALLED_VENDOR_DLKMIMAGE_TARGET),$(BOARD_VENDOR_DLKMIMAGE_PARTITION_SIZE))
 endef
 
-$(eval $(call write-file-lines,$(vendor_dlkmimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_VENDOR_DLKM)/,,$(filter $(TARGET_OUT_VENDOR_DLKM)/%,$(INTERNAL_VENDOR_DLKMIMAGE_FILES)))))
+$(eval $(call write-partition-file-list,$(vendor_dlkmimage_intermediates)/file_list.txt,$(TARGET_OUT_VENDOR_DLKM),$(INTERNAL_VENDOR_DLKMIMAGE_FILES)))
 # Used by soong sandwich to request the staging dir be built
 $(vendor_dlkmimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_VENDOR_DLKM)/%,$(INTERNAL_VENDOR_DLKMIMAGE_FILES))
 	touch $@
@@ -4213,7 +4230,7 @@
   $(call assert-max-image-size,$(INSTALLED_ODM_DLKMIMAGE_TARGET),$(BOARD_ODM_DLKMIMAGE_PARTITION_SIZE))
 endef
 
-$(eval $(call write-file-lines,$(odm_dlkmimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_ODM_DLKM)/,,$(filter $(TARGET_OUT_ODM_DLKM)/%,$(INTERNAL_ODM_DLKMIMAGE_FILES)))))
+$(eval $(call write-partition-file-list,$(odm_dlkmimage_intermediates)/file_list.txt,$(TARGET_OUT_ODM_DLKM),$(INTERNAL_ODM_DLKMIMAGE_FILES)))
 # Used by soong sandwich to request the staging dir be built
 $(odm_dlkmimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_ODM_DLKM)/%,$(INTERNAL_ODM_DLKMIMAGE_FILES))
 	touch $@
@@ -4284,7 +4301,7 @@
   $(call assert-max-image-size,$(INSTALLED_SYSTEM_DLKMIMAGE_TARGET),$(BOARD_SYSTEM_DLKMIMAGE_PARTITION_SIZE))
 endef
 
-$(eval $(call write-file-lines,$(system_dlkmimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_SYSTEM_DLKM)/,,$(filter $(TARGET_OUT_SYSTEM_DLKM)/%,$(INTERNAL_SYSTEM_DLKMIMAGE_FILES)))))
+$(eval $(call write-partition-file-list,$(system_dlkmimage_intermediates)/file_list.txt,$(TARGET_OUT_SYSTEM_DLKM),$(INTERNAL_SYSTEM_DLKMIMAGE_FILES)))
 # Used by soong sandwich to request the staging dir be built
 $(system_dlkmimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_SYSTEM_DLKM)/%,$(INTERNAL_SYSTEM_DLKMIMAGE_FILES))
 	touch $@
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index 56da574..ed72fc3 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -38,38 +38,6 @@
 # PRODUCT_PRECOMPILED_SEPOLICY defaults to true. Explicitly check if it's "false" or not.
 $(call add_soong_config_var_value,ANDROID,PRODUCT_PRECOMPILED_SEPOLICY,$(if $(filter false,$(PRODUCT_PRECOMPILED_SEPOLICY)),false,true))
 
-# Default behavior for the tree wrt building modules or using prebuilts. This
-# can always be overridden by setting the environment variable
-# MODULE_BUILD_FROM_SOURCE.
-BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := $(RELEASE_DEFAULT_MODULE_BUILD_FROM_SOURCE)
-# TODO(b/301454934): The value from build flag is set to empty when use `False`
-# The condition below can be removed after the issue get sorted.
-ifeq (,$(BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE))
-  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := false
-endif
-
-ifneq (,$(MODULE_BUILD_FROM_SOURCE))
-  # Keep an explicit setting.
-else ifeq (,$(filter docs sdk win_sdk sdk_addon,$(MAKECMDGOALS)))
-  MODULE_BUILD_FROM_SOURCE := true
-else ifneq (,$(PRODUCT_MODULE_BUILD_FROM_SOURCE))
-  # Let products override the branch default.
-  MODULE_BUILD_FROM_SOURCE := $(PRODUCT_MODULE_BUILD_FROM_SOURCE)
-else
-  MODULE_BUILD_FROM_SOURCE := $(BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE)
-endif
-
-ifneq (,$(ART_MODULE_BUILD_FROM_SOURCE))
-  # Keep an explicit setting.
-else ifneq (,$(findstring .android.art,$(TARGET_BUILD_APPS)))
-  # Build ART modules from source if they are listed in TARGET_BUILD_APPS.
-  ART_MODULE_BUILD_FROM_SOURCE := true
-else
-  # Do the same as other modules by default.
-  ART_MODULE_BUILD_FROM_SOURCE := $(MODULE_BUILD_FROM_SOURCE)
-endif
-
-$(call soong_config_set,art_module,source_build,$(ART_MODULE_BUILD_FROM_SOURCE))
 ifdef ART_DEBUG_OPT_FLAG
 $(call soong_config_set,art_module,art_debug_opt_flag,$(ART_DEBUG_OPT_FLAG))
 endif
@@ -87,9 +55,10 @@
 endif
 endif
 
-ifeq (true,$(MODULE_BUILD_FROM_SOURCE))
+# TODO(b/308187800): some internal modules set `prefer` to true on the prebuilt apex module,
+# and set that to false when `ANDROID.module_build_from_source` is true.
+# Set this soong config variable to true for now, and cleanup `prefer` as part of b/308187800
 $(call add_soong_config_var_value,ANDROID,module_build_from_source,true)
-endif
 
 # Messaging app vars
 ifeq (eng,$(TARGET_BUILD_VARIANT))
diff --git a/core/art_config.mk b/core/art_config.mk
index 47b4bcf..196db4f 100644
--- a/core/art_config.mk
+++ b/core/art_config.mk
@@ -19,8 +19,6 @@
 endif
 
 ENABLE_UFFD_GC := $(config_enable_uffd_gc)
-# If the value is "default", it will be mangled by post_process_props.py.
-ADDITIONAL_PRODUCT_PROPERTIES += ro.dalvik.vm.enable_uffd_gc=$(config_enable_uffd_gc)
 
 # Create APEX_BOOT_JARS_EXCLUDED which is a list of jars to be removed from
 # ApexBoorJars when built from mainline prebuilts.
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 4c92814..9c7e906 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -393,8 +393,8 @@
 
 logtags_sources := $(filter %.logtags,$(LOCAL_SRC_FILES)) $(LOCAL_LOGTAGS_FILES)
 
-ifneq ($(strip $(logtags_sources)),)
-event_log_tags := $(foreach f,$(addprefix $(LOCAL_PATH)/,$(logtags_sources)),$(call clean-path,$(f)))
+ifneq ($(strip $(logtags_sources) $(LOCAL_SOONG_LOGTAGS_FILES)),)
+event_log_tags := $(foreach f,$(LOCAL_SOONG_LOGTAGS_FILES) $(addprefix $(LOCAL_PATH)/,$(logtags_sources)),$(call clean-path,$(f)))
 else
 event_log_tags :=
 endif
@@ -716,6 +716,14 @@
   test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
 endif
 
+ifeq ($(EXCLUDE_MCTS),true)
+  ifneq (,$(test_config))
+    ifneq (,$(filter mcts-%,$(LOCAL_COMPATIBILITY_SUITE)))
+      LOCAL_COMPATIBILITY_SUITE := $(filter-out cts,$(LOCAL_COMPATIBILITY_SUITE))
+    endif
+  endif
+endif
+
 ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
 
 # If we are building a native test or benchmark and its stem variants are not defined,
diff --git a/core/binary.mk b/core/binary.mk
index b17ab00..f86b5a4 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1196,6 +1196,17 @@
 endif
 
 ###################################################################
+## When compiling a memtag_stack enabled target, use the .memtag_stack variant
+## of any static dependencies (where they exist).
+##################################################################
+ifneq ($(filter memtag_stack,$(my_sanitize)),)
+  my_whole_static_libraries := $(call use_soong_sanitized_static_libraries,\
+    $(my_whole_static_libraries),memtag_stack)
+  my_static_libraries := $(call use_soong_sanitized_static_libraries,\
+    $(my_static_libraries),memtag_stack)
+endif
+
+###################################################################
 ## When compiling against API imported module, use API import stub
 ## libraries.
 ##################################################################
diff --git a/core/board_config.mk b/core/board_config.mk
index 633303f..e184601 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -274,7 +274,7 @@
 
 ifneq ($(MALLOC_IMPL),)
   $(warning *** Unsupported option MALLOC_IMPL defined by board config: $(board_config_mk).)
-  $(error Use `MALLOC_SVELTE := true` to configure jemalloc for low-memory)
+  $(error Use `MALLOC_LOW_MEMORY := true` to use low-memory allocator config)
 endif
 board_config_mk :=
 
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 5481d50..fb42878 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -264,6 +264,7 @@
 LOCAL_SOONG_LICENSE_METADATA :=
 LOCAL_SOONG_LINK_TYPE :=
 LOCAL_SOONG_LINT_REPORTS :=
+LOCAL_SOONG_LOGTAGS_FILES :=
 LOCAL_SOONG_MODULE_INFO_JSON :=
 LOCAL_SOONG_MODULE_TYPE :=
 LOCAL_SOONG_PROGUARD_DICT :=
diff --git a/core/config.mk b/core/config.mk
index aaf8117..ce11b1d 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -1231,6 +1231,8 @@
 # in the source tree.
 dont_bother_goals := out product-graph
 
+include $(BUILD_SYSTEM)/sysprop_config.mk
+
 # Make ANDROID Soong config variables visible to Android.mk files, for
 # consistency with those defined in BoardConfig.mk files.
 include $(BUILD_SYSTEM)/android_soong_config_vars.mk
diff --git a/core/main.mk b/core/main.mk
index 8182740..d700fcb 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -113,37 +113,8 @@
   # $(error TARGET_ARCH_SUITE is not supported in kati/make builds)
 endif
 
-# ADDITIONAL_<partition>_PROPERTIES are properties that are determined by the
-# build system itself. Don't let it be defined from outside of the core build
-# system like Android.mk or <product>.mk files.
-_additional_prop_var_names := \
-    ADDITIONAL_SYSTEM_PROPERTIES \
-    ADDITIONAL_VENDOR_PROPERTIES \
-    ADDITIONAL_ODM_PROPERTIES \
-    ADDITIONAL_PRODUCT_PROPERTIES
-
-$(foreach name, $(_additional_prop_var_names),\
-  $(if $($(name)),\
-    $(error $(name) must not set before here. $($(name)))\
-  ,)\
-  $(eval $(name) :=)\
-)
-_additional_prop_var_names :=
-
 $(KATI_obsolete_var ADDITIONAL_BUILD_PROPERTIES, Please use ADDITIONAL_SYSTEM_PROPERTIES)
 
-#
-# -----------------------------------------------------------------
-# Add the product-defined properties to the build properties.
-ifneq ($(BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED), true)
-  ADDITIONAL_SYSTEM_PROPERTIES += $(PRODUCT_PROPERTY_OVERRIDES)
-else
-  ifndef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
-    ADDITIONAL_SYSTEM_PROPERTIES += $(PRODUCT_PROPERTY_OVERRIDES)
-  endif
-endif
-
-
 # Bring in standard build system definitions.
 include $(BUILD_SYSTEM)/definitions.mk
 
@@ -175,178 +146,8 @@
 # PDK builds are no longer supported, this is always platform
 TARGET_BUILD_JAVA_SUPPORT_LEVEL :=$= platform
 
-# -----------------------------------------------------------------
-
-ADDITIONAL_SYSTEM_PROPERTIES += ro.treble.enabled=${PRODUCT_FULL_TREBLE}
-
 $(KATI_obsolete_var PRODUCT_FULL_TREBLE,\
 	Code should be written to work regardless of a device being Treble)
-
-# Set ro.llndk.api_level to show the maximum vendor API level that the LLNDK in
-# the system partition supports.
-ifdef RELEASE_BOARD_API_LEVEL
-ADDITIONAL_SYSTEM_PROPERTIES += ro.llndk.api_level=$(RELEASE_BOARD_API_LEVEL)
-endif
-
-# Sets ro.actionable_compatible_property.enabled to know on runtime whether the
-# allowed list of actionable compatible properties is enabled or not.
-ADDITIONAL_SYSTEM_PROPERTIES += ro.actionable_compatible_property.enabled=true
-
-# Add the system server compiler filter if they are specified for the product.
-ifneq (,$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER))
-ADDITIONAL_PRODUCT_PROPERTIES += dalvik.vm.systemservercompilerfilter=$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER)
-endif
-
-# Add the 16K developer option if it is defined for the product.
-ifeq ($(PRODUCT_16K_DEVELOPER_OPTION),true)
-ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.16k_page.enabled=true
-else
-ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.16k_page.enabled=false
-endif
-
-# Enable core platform API violation warnings on userdebug and eng builds.
-ifneq ($(TARGET_BUILD_VARIANT),user)
-ADDITIONAL_SYSTEM_PROPERTIES += persist.debug.dalvik.vm.core_platform_api_policy=just-warn
-endif
-
-# Define ro.sanitize.<name> properties for all global sanitizers.
-ADDITIONAL_SYSTEM_PROPERTIES += $(foreach s,$(SANITIZE_TARGET),ro.sanitize.$(s)=true)
-
-# Sets the default value of ro.postinstall.fstab.prefix to /system.
-# Device board config should override the value to /product when needed by:
-#
-#     PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product
-#
-# It then uses ${ro.postinstall.fstab.prefix}/etc/fstab.postinstall to
-# mount system_other partition.
-ADDITIONAL_SYSTEM_PROPERTIES += ro.postinstall.fstab.prefix=/system
-
-# Add cpu properties for bionic and ART.
-ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.arch=$(TARGET_ARCH)
-ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.cpu_variant=$(TARGET_CPU_VARIANT_RUNTIME)
-ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.2nd_arch=$(TARGET_2ND_ARCH)
-ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.2nd_cpu_variant=$(TARGET_2ND_CPU_VARIANT_RUNTIME)
-
-ADDITIONAL_VENDOR_PROPERTIES += persist.sys.dalvik.vm.lib.2=libart.so
-ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_ARCH).variant=$(DEX2OAT_TARGET_CPU_VARIANT_RUNTIME)
-ifneq ($(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),)
-  ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_ARCH).features=$(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
-endif
-
-ifdef TARGET_2ND_ARCH
-  ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_2ND_ARCH).variant=$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT_RUNTIME)
-  ifneq ($($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),)
-    ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_2ND_ARCH).features=$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
-  endif
-endif
-
-# Although these variables are prefixed with TARGET_RECOVERY_, they are also needed under charger
-# mode (via libminui).
-ifdef TARGET_RECOVERY_DEFAULT_ROTATION
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.minui.default_rotation=$(TARGET_RECOVERY_DEFAULT_ROTATION)
-endif
-ifdef TARGET_RECOVERY_OVERSCAN_PERCENT
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.minui.overscan_percent=$(TARGET_RECOVERY_OVERSCAN_PERCENT)
-endif
-ifdef TARGET_RECOVERY_PIXEL_FORMAT
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.minui.pixel_format=$(TARGET_RECOVERY_PIXEL_FORMAT)
-endif
-
-ifdef PRODUCT_USE_DYNAMIC_PARTITIONS
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.boot.dynamic_partitions=$(PRODUCT_USE_DYNAMIC_PARTITIONS)
-endif
-
-ifdef PRODUCT_RETROFIT_DYNAMIC_PARTITIONS
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.boot.dynamic_partitions_retrofit=$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS)
-endif
-
-ifdef PRODUCT_SHIPPING_API_LEVEL
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.product.first_api_level=$(PRODUCT_SHIPPING_API_LEVEL)
-endif
-
-ifdef PRODUCT_SHIPPING_VENDOR_API_LEVEL
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.vendor.api_level=$(PRODUCT_SHIPPING_VENDOR_API_LEVEL)
-endif
-
-ifneq ($(TARGET_BUILD_VARIANT),user)
-  ifdef PRODUCT_SET_DEBUGFS_RESTRICTIONS
-    ADDITIONAL_VENDOR_PROPERTIES += \
-      ro.product.debugfs_restrictions.enabled=$(PRODUCT_SET_DEBUGFS_RESTRICTIONS)
-  endif
-endif
-
-# Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level.
-# This must not be defined for the non-GRF devices.
-# The values of the GRF properties will be verified by post_process_props.py
-ifdef BOARD_SHIPPING_API_LEVEL
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.board.first_api_level=$(BOARD_SHIPPING_API_LEVEL)
-endif
-
-# Build system set BOARD_API_LEVEL to show the api level of the vendor API surface.
-# This must not be altered outside of build system.
-ifdef BOARD_API_LEVEL
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.board.api_level=$(BOARD_API_LEVEL)
-endif
-# RELEASE_BOARD_API_LEVEL_FROZEN is true when the vendor API surface is frozen.
-ifdef RELEASE_BOARD_API_LEVEL_FROZEN
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.board.api_frozen=$(RELEASE_BOARD_API_LEVEL_FROZEN)
-endif
-
-# Set build prop. This prop is read by ota_from_target_files when generating OTA,
-# to decide if VABC should be disabled.
-ifeq ($(BOARD_DONT_USE_VABC_OTA),true)
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.vendor.build.dont_use_vabc=true
-endif
-
-# Set the flag in vendor. So VTS would know if the new fingerprint format is in use when
-# the system images are replaced by GSI.
-ifeq ($(BOARD_USE_VBMETA_DIGTEST_IN_FINGERPRINT),true)
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.vendor.build.fingerprint_has_digest=1
-endif
-
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.vendor.build.security_patch=$(VENDOR_SECURITY_PATCH) \
-    ro.product.board=$(TARGET_BOOTLOADER_BOARD_NAME) \
-    ro.board.platform=$(TARGET_BOARD_PLATFORM) \
-    ro.hwui.use_vulkan=$(TARGET_USES_VULKAN)
-
-ifdef TARGET_SCREEN_DENSITY
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.sf.lcd_density=$(TARGET_SCREEN_DENSITY)
-endif
-
-ifdef AB_OTA_UPDATER
-ADDITIONAL_VENDOR_PROPERTIES += \
-    ro.build.ab_update=$(AB_OTA_UPDATER)
-endif
-
-ADDITIONAL_PRODUCT_PROPERTIES += ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS)
-
-ifeq ($(AB_OTA_UPDATER),true)
-ADDITIONAL_PRODUCT_PROPERTIES += ro.product.ab_ota_partitions=$(subst $(space),$(comma),$(sort $(AB_OTA_PARTITIONS)))
-ADDITIONAL_VENDOR_PROPERTIES += ro.vendor.build.ab_ota_partitions=$(subst $(space),$(comma),$(sort $(AB_OTA_PARTITIONS)))
-endif
-
-# Set this property for VTS to skip large page size tests on unsupported devices.
-ADDITIONAL_PRODUCT_PROPERTIES += \
-    ro.product.cpu.pagesize.max=$(TARGET_MAX_PAGE_SIZE_SUPPORTED)
-
-ifeq ($(PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO),true)
-ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.no_bionic_page_size_macro=true
-endif
-
 # -----------------------------------------------------------------
 ###
 ### In this section we set up the things that are different
@@ -359,66 +160,15 @@
 is_sdk_build := true
 endif
 
-## user/userdebug ##
-
-user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT))
-enable_target_debugging := true
 tags_to_install :=
-ifneq (,$(user_variant))
-  # Target is secure in user builds.
-  ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=1
-  ADDITIONAL_SYSTEM_PROPERTIES += security.perf_harden=1
 
-  ifeq ($(user_variant),user)
-    ADDITIONAL_SYSTEM_PROPERTIES += ro.adb.secure=1
-  endif
-
-  ifeq ($(user_variant),userdebug)
-    # Pick up some extra useful tools
-    tags_to_install += debug
-  else
-    # Disable debugging in plain user builds.
-    enable_target_debugging :=
-  endif
-
-  # Disallow mock locations by default for user builds
-  ADDITIONAL_SYSTEM_PROPERTIES += ro.allow.mock.location=0
-
-else # !user_variant
-  # Turn on checkjni for non-user builds.
-  ADDITIONAL_SYSTEM_PROPERTIES += ro.kernel.android.checkjni=1
-  # Set device insecure for non-user builds.
-  ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=0
-  # Allow mock locations by default for non user builds
-  ADDITIONAL_SYSTEM_PROPERTIES += ro.allow.mock.location=1
-endif # !user_variant
-
-ifeq (true,$(strip $(enable_target_debugging)))
-  # Target is more debuggable and adbd is on by default
-  ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=1
-  # Enable Dalvik lock contention logging.
-  ADDITIONAL_SYSTEM_PROPERTIES += dalvik.vm.lockprof.threshold=500
-else # !enable_target_debugging
-  # Target is less debuggable and adbd is off by default
-  ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=0
-endif # !enable_target_debugging
-
-## eng ##
+ifeq ($(TARGET_BUILD_VARIANT),userdebug)
+# Pick up some extra useful tools
+tags_to_install := debug
+endif
 
 ifeq ($(TARGET_BUILD_VARIANT),eng)
 tags_to_install := debug eng
-ifneq ($(filter ro.setupwizard.mode=ENABLED, $(call collapse-pairs, $(ADDITIONAL_SYSTEM_PROPERTIES))),)
-  # Don't require the setup wizard on eng builds
-  ADDITIONAL_SYSTEM_PROPERTIES := $(filter-out ro.setupwizard.mode=%,\
-          $(call collapse-pairs, $(ADDITIONAL_SYSTEM_PROPERTIES))) \
-          ro.setupwizard.mode=OPTIONAL
-endif
-ifndef is_sdk_build
-  # To speedup startup of non-preopted builds, don't verify or compile the boot image.
-  ADDITIONAL_SYSTEM_PROPERTIES += dalvik.vm.image-dex2oat-filter=extract
-endif
-# b/323566535
-ADDITIONAL_SYSTEM_PROPERTIES += init.svc_debug.no_fatal.zygote=true
 endif
 
 ## asan ##
@@ -454,18 +204,11 @@
 # TODO: this should be eng I think.  Since the sdk is built from the eng
 # variant.
 tags_to_install := debug eng
-ADDITIONAL_SYSTEM_PROPERTIES += xmpp.auto-presence=true
-ADDITIONAL_SYSTEM_PROPERTIES += ro.config.nocheckin=yes
 else # !sdk
 endif
 
 BUILD_WITHOUT_PV := true
 
-ADDITIONAL_SYSTEM_PROPERTIES += net.bt.name=Android
-
-# This property is set by flashing debug boot image, so default to false.
-ADDITIONAL_SYSTEM_PROPERTIES += ro.force.debuggable=0
-
 # ------------------------------------------------------------
 # Define a function that, given a list of module tags, returns
 # non-empty if that module should be installed in /system.
@@ -506,10 +249,6 @@
 
 # Strip and readonly a few more variables so they won't be modified.
 $(readonly-final-product-vars)
-ADDITIONAL_SYSTEM_PROPERTIES := $(strip $(ADDITIONAL_SYSTEM_PROPERTIES))
-.KATI_READONLY := ADDITIONAL_SYSTEM_PROPERTIES
-ADDITIONAL_PRODUCT_PROPERTIES := $(strip $(ADDITIONAL_PRODUCT_PROPERTIES))
-.KATI_READONLY := ADDITIONAL_PRODUCT_PROPERTIES
 
 ifneq ($(PRODUCT_ENFORCE_RRO_TARGETS),)
 ENFORCE_RRO_SOURCES :=
@@ -537,7 +276,7 @@
 # Include all of the makefiles in the system
 #
 
-subdir_makefiles := $(SOONG_OUT_DIR)/installs-$(TARGET_PRODUCT).mk $(SOONG_ANDROID_MK)
+subdir_makefiles := $(SOONG_ANDROID_MK)
 # Android.mk files are only used on Linux builds, Mac only supports Android.bp
 ifeq ($(HOST_OS),linux)
   subdir_makefiles += $(file <$(OUT_DIR)/.module_paths/Android.mk.list)
@@ -548,6 +287,8 @@
 
 $(foreach mk,$(subdir_makefiles),$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] including $(mk) ...)$(eval include $(mk)))
 
+include $(SOONG_OUT_DIR)/installs-$(TARGET_PRODUCT).mk
+
 # For an unbundled image, we can skip blueprint_tools because unbundled image
 # aims to remove a large number framework projects from the manifest, the
 # sources or dependencies for these tools may be missing from the tree.
diff --git a/core/product.mk b/core/product.mk
index f8634ef..0a761fb 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -418,8 +418,9 @@
 # /system/etc/security/fsverity/BuildManifest.apk
 _product_single_value_vars += PRODUCT_FSVERITY_GENERATE_METADATA
 
-# If true, sets the default for MODULE_BUILD_FROM_SOURCE. This overrides
-# BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE but not an explicitly set value.
+# If true, this builds the mainline modules from source. This overrides any
+# prebuilts selected via RELEASE_APEX_CONTRIBUTIONS_* build flags for the
+# current release config.
 _product_single_value_vars += PRODUCT_MODULE_BUILD_FROM_SOURCE
 
 # If true, installs a full version of com.android.virt APEX.
diff --git a/core/release_config.mk b/core/release_config.mk
index 3e51af5..97c8dd3 100644
--- a/core/release_config.mk
+++ b/core/release_config.mk
@@ -41,6 +41,7 @@
 # which has OWNERS control.  If it isn't let others define their own.
 # TODO: Remove wildcard for build/release one when all branch manifests
 # have updated.
+_must_protobuf :=
 config_map_files := $(wildcard build/release/release_config_map.mk) \
     $(wildcard vendor/google_shared/build/release/release_config_map.mk) \
     $(if $(wildcard vendor/google/release/release_config_map.mk), \
@@ -53,13 +54,86 @@
         ) \
     )
 
+protobuf_map_files := $(wildcard build/release/release_config_map.textproto) \
+    $(wildcard vendor/google_shared/build/release/release_config_map.textproto) \
+    $(if $(wildcard vendor/google/release/release_config_map.textproto), \
+        vendor/google/release/release_config_map.textproto, \
+        $(sort \
+            $(wildcard device/*/release/release_config_map.textproto) \
+            $(wildcard device/*/*/release/release_config_map.textproto) \
+            $(wildcard vendor/*/release/release_config_map.textproto) \
+            $(wildcard vendor/*/*/release/release_config_map.textproto) \
+        ) \
+    )
+
 # PRODUCT_RELEASE_CONFIG_MAPS is set by Soong using an initial run of product
 # config to capture only the list of config maps needed by the build.
 # Keep them in the order provided, but remove duplicates.
+# Treat .mk and .textproto as equal for duplicate elimination, but force
+# protobuf if any PRODUCT_RELEASE_CONFIG_MAPS specify .textproto.
 $(foreach map,$(PRODUCT_RELEASE_CONFIG_MAPS), \
-    $(if $(filter $(map),$(config_map_files)),,$(eval config_map_files += $(map))) \
+    $(if $(filter $(basename $(map)),$(basename $(config_map_files))),, \
+        $(eval config_map_files += $(map))) \
+    $(if $(filter $(basename $(map)).textproto,$(map)),$(eval _must_protobuf := true)) \
 )
 
+
+# If we are missing the textproto version of any of $(config_map_files), we cannot use protobuf.
+_can_protobuf := true
+$(foreach map,$(config_map_files), \
+    $(if $(wildcard $(basename $(map)).textproto),,$(eval _can_protobuf :=)) \
+)
+# If we are missing the mk version of any of $(protobuf_map_files), we must use protobuf.
+$(foreach map,$(protobuf_map_files), \
+    $(if $(wildcard $(basename $(map)).mk),,$(eval _must_protobuf := true)) \
+)
+
+ifneq (,$(_must_protobuf))
+    ifeq (,$(_can_protobuf))
+	# We must use protobuf, but we cannot use protobuf.
+        $(error release config is a mixture of .scl and .textproto)
+    endif
+endif
+
+_use_protobuf :=
+ifneq (,$(_must_protobuf))
+    _use_protobuf := true
+else
+    ifneq ($(_can_protobuf),)
+        # Determine the default
+        $(foreach map,$(config_map_files), \
+            $(if $(wildcard $(dir $(map))/build_config/DEFAULT=proto),$(eval _use_protobuf := true)) \
+            $(if $(wildcard $(dir $(map))/build_config/DEFAULT=make),$(eval _use_protobuf := )) \
+        )
+        # Update for this specific release config only (no inheritance).
+        $(foreach map,$(config_map_files), \
+            $(if $(wildcard $(dir $(map))/build_config/$(TARGET_RELEASE)=proto),$(eval _use_protobuf := true)) \
+            $(if $(wildcard $(dir $(map))/build_config/$(TARGET_RELEASE)=make),$(eval _use_protobuf := )) \
+        )
+    endif
+endif
+
+ifneq (,$(_use_protobuf))
+    # The .textproto files are the canonical source of truth.
+    _args := $(foreach map,$(config_map_files), --map $(map) )
+    ifneq (,$(_must_protobuf))
+        # Disable the build flag in release-config.
+        _args += --guard=false
+    endif
+    _flags_file:=$(OUT_DIR)/soong/release-config/release_config-$(TARGET_PRODUCT)-$(TARGET_RELEASE).mk
+    $(KATI_shell_no_rerun $(OUT_DIR)/release-config $(_args) >$(OUT_DIR)/release-config.out 2>&1 && touch -t 200001010000 $(OUT_DIR)/release-config.out $(_flags_file))
+    $(if $(filter-out 0,$(.SHELLSTATUS)),$(error release-config failed to run))
+    # This will also set _all_release_configs for us.
+    $(eval include $(OUT_DIR)/soong/release-config/release_config-$(TARGET_PRODUCT)-$(TARGET_RELEASE).mk)
+    $(KATI_extra_file_deps $(OUT_DIR)/release-config $(config_map_files))
+    ifeq (,$(_must_protobuf)$(RELEASE_BUILD_FLAGS_IN_PROTOBUF))
+        _use_protobuf :=
+    endif
+endif
+ifeq (,$(_use_protobuf))
+    # The .mk files are the canonical source of truth.
+
+
 # Declare an alias release-config
 #
 # This should be used to declare a release as an alias of another, meaning no
@@ -144,6 +218,9 @@
     $(error Alias release config "$(r)" may not specify release config files $(_all_release_configs.$(r).FILES))\
 )))
 
+# Use makefiles
+endif
+
 ifeq ($(TARGET_RELEASE),)
     # We allow some internal paths to explicitly set TARGET_RELEASE to the
     # empty string.  For the most part, 'make' treats unset and empty string as
@@ -167,6 +244,7 @@
     endif
 endif
 
+ifeq (,$(_use_protobuf))
 # Choose flag files
 # Don't sort this, use it in the order they gave us.
 # Do allow duplicate entries, retaining only the first usage.
@@ -196,6 +274,9 @@
 $(error invalid use of apply-release-config-overrides)
 endef
 
+# use makefiles
+endif
+
 # TODO: Remove this check after enough people have sourced lunch that we don't
 # need to worry about it trying to do get_build_vars TARGET_RELEASE. Maybe after ~9/2023
 ifneq ($(CALLED_FROM_SETUP),true)
@@ -207,15 +288,20 @@
 endif
 .KATI_READONLY := TARGET_RELEASE
 
+ifeq (,$(_use_protobuf))
 $(foreach config, $(_all_release_configs), \
     $(eval _all_release_configs.$(config).DECLARED_IN:= ) \
     $(eval _all_release_configs.$(config).FILES:= ) \
 )
+applied_releases:=
+# use makefiles
+endif
 _all_release_configs:=
 config_map_files:=
-applied_releases:=
+protobuf_map_files:=
 
 
+ifeq (,$(_use_protobuf))
 # -----------------------------------------------------------------
 # Flag declarations and values
 # -----------------------------------------------------------------
@@ -252,3 +338,8 @@
 # outside of the source tree.
 $(call run-starlark,$(OUT_DIR)/release_config_entrypoint.scl,$(OUT_DIR)/release_config_entrypoint.scl,--allow_external_entrypoint)
 
+# use makefiles
+endif
+_can_protobuf :=
+_must_protobuf :=
+_use_protobuf :=
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 534270e..acd213c 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -154,7 +154,7 @@
 $(call add_json_list, DeviceSystemSdkVersions,           $(BOARD_SYSTEMSDK_VERSIONS))
 $(call add_json_str,  RecoverySnapshotVersion,           $(RECOVERY_SNAPSHOT_VERSION))
 $(call add_json_list, Platform_systemsdk_versions,       $(PLATFORM_SYSTEMSDK_VERSIONS))
-$(call add_json_bool, Malloc_not_svelte,                 $(call invert_bool,$(filter true,$(MALLOC_SVELTE))))
+$(call add_json_bool, Malloc_low_memory,                 $(findstring true,$(MALLOC_SVELTE) $(MALLOC_LOW_MEMORY)))
 $(call add_json_bool, Malloc_zero_contents,              $(call invert_bool,$(filter false,$(MALLOC_ZERO_CONTENTS))))
 $(call add_json_bool, Malloc_pattern_fill_contents,      $(MALLOC_PATTERN_FILL_CONTENTS))
 $(call add_json_str,  Override_rs_driver,                $(OVERRIDE_RS_DRIVER))
diff --git a/core/sysprop_config.mk b/core/sysprop_config.mk
new file mode 100644
index 0000000..a019a7d
--- /dev/null
+++ b/core/sysprop_config.mk
@@ -0,0 +1,278 @@
+# ADDITIONAL_<partition>_PROPERTIES are properties that are determined by the
+# build system itself. Don't let it be defined from outside of the core build
+# system like Android.mk or <product>.mk files.
+_additional_prop_var_names := \
+    ADDITIONAL_SYSTEM_PROPERTIES \
+    ADDITIONAL_VENDOR_PROPERTIES \
+    ADDITIONAL_ODM_PROPERTIES \
+    ADDITIONAL_PRODUCT_PROPERTIES
+
+$(foreach name, $(_additional_prop_var_names),\
+  $(if $($(name)),\
+    $(error $(name) must not set before here. $($(name)))\
+  ,)\
+  $(eval $(name) :=)\
+)
+_additional_prop_var_names :=
+
+#
+# -----------------------------------------------------------------
+# Add the product-defined properties to the build properties.
+ifneq ($(BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED), true)
+  ADDITIONAL_SYSTEM_PROPERTIES += $(PRODUCT_PROPERTY_OVERRIDES)
+else
+  ifndef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
+    ADDITIONAL_SYSTEM_PROPERTIES += $(PRODUCT_PROPERTY_OVERRIDES)
+  endif
+endif
+
+ADDITIONAL_SYSTEM_PROPERTIES += ro.treble.enabled=${PRODUCT_FULL_TREBLE}
+
+# Set ro.llndk.api_level to show the maximum vendor API level that the LLNDK in
+# the system partition supports.
+ifdef RELEASE_BOARD_API_LEVEL
+ADDITIONAL_SYSTEM_PROPERTIES += ro.llndk.api_level=$(RELEASE_BOARD_API_LEVEL)
+endif
+
+# Sets ro.actionable_compatible_property.enabled to know on runtime whether the
+# allowed list of actionable compatible properties is enabled or not.
+ADDITIONAL_SYSTEM_PROPERTIES += ro.actionable_compatible_property.enabled=true
+
+# Add the system server compiler filter if they are specified for the product.
+ifneq (,$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER))
+ADDITIONAL_PRODUCT_PROPERTIES += dalvik.vm.systemservercompilerfilter=$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER)
+endif
+
+# Add the 16K developer option if it is defined for the product.
+ifeq ($(PRODUCT_16K_DEVELOPER_OPTION),true)
+ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.16k_page.enabled=true
+else
+ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.16k_page.enabled=false
+endif
+
+# Enable core platform API violation warnings on userdebug and eng builds.
+ifneq ($(TARGET_BUILD_VARIANT),user)
+ADDITIONAL_SYSTEM_PROPERTIES += persist.debug.dalvik.vm.core_platform_api_policy=just-warn
+endif
+
+# Define ro.sanitize.<name> properties for all global sanitizers.
+ADDITIONAL_SYSTEM_PROPERTIES += $(foreach s,$(SANITIZE_TARGET),ro.sanitize.$(s)=true)
+
+# Sets the default value of ro.postinstall.fstab.prefix to /system.
+# Device board config should override the value to /product when needed by:
+#
+#     PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product
+#
+# It then uses ${ro.postinstall.fstab.prefix}/etc/fstab.postinstall to
+# mount system_other partition.
+ADDITIONAL_SYSTEM_PROPERTIES += ro.postinstall.fstab.prefix=/system
+
+# Add cpu properties for bionic and ART.
+ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.arch=$(TARGET_ARCH)
+ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.cpu_variant=$(TARGET_CPU_VARIANT_RUNTIME)
+ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.2nd_arch=$(TARGET_2ND_ARCH)
+ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.2nd_cpu_variant=$(TARGET_2ND_CPU_VARIANT_RUNTIME)
+
+ADDITIONAL_VENDOR_PROPERTIES += persist.sys.dalvik.vm.lib.2=libart.so
+ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_ARCH).variant=$(DEX2OAT_TARGET_CPU_VARIANT_RUNTIME)
+ifneq ($(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),)
+  ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_ARCH).features=$(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
+endif
+
+ifdef TARGET_2ND_ARCH
+  ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_2ND_ARCH).variant=$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT_RUNTIME)
+  ifneq ($($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),)
+    ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_2ND_ARCH).features=$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
+  endif
+endif
+
+# Although these variables are prefixed with TARGET_RECOVERY_, they are also needed under charger
+# mode (via libminui).
+ifdef TARGET_RECOVERY_DEFAULT_ROTATION
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.minui.default_rotation=$(TARGET_RECOVERY_DEFAULT_ROTATION)
+endif
+ifdef TARGET_RECOVERY_OVERSCAN_PERCENT
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.minui.overscan_percent=$(TARGET_RECOVERY_OVERSCAN_PERCENT)
+endif
+ifdef TARGET_RECOVERY_PIXEL_FORMAT
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.minui.pixel_format=$(TARGET_RECOVERY_PIXEL_FORMAT)
+endif
+
+ifdef PRODUCT_USE_DYNAMIC_PARTITIONS
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.boot.dynamic_partitions=$(PRODUCT_USE_DYNAMIC_PARTITIONS)
+endif
+
+ifdef PRODUCT_RETROFIT_DYNAMIC_PARTITIONS
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.boot.dynamic_partitions_retrofit=$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS)
+endif
+
+ifdef PRODUCT_SHIPPING_API_LEVEL
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.product.first_api_level=$(PRODUCT_SHIPPING_API_LEVEL)
+endif
+
+ifdef PRODUCT_SHIPPING_VENDOR_API_LEVEL
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.vendor.api_level=$(PRODUCT_SHIPPING_VENDOR_API_LEVEL)
+endif
+
+ifneq ($(TARGET_BUILD_VARIANT),user)
+  ifdef PRODUCT_SET_DEBUGFS_RESTRICTIONS
+    ADDITIONAL_VENDOR_PROPERTIES += \
+      ro.product.debugfs_restrictions.enabled=$(PRODUCT_SET_DEBUGFS_RESTRICTIONS)
+  endif
+endif
+
+# Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level.
+# This must not be defined for the non-GRF devices.
+# The values of the GRF properties will be verified by post_process_props.py
+ifdef BOARD_SHIPPING_API_LEVEL
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.board.first_api_level=$(BOARD_SHIPPING_API_LEVEL)
+endif
+
+# Build system set BOARD_API_LEVEL to show the api level of the vendor API surface.
+# This must not be altered outside of build system.
+ifdef BOARD_API_LEVEL
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.board.api_level=$(BOARD_API_LEVEL)
+endif
+# RELEASE_BOARD_API_LEVEL_FROZEN is true when the vendor API surface is frozen.
+ifdef RELEASE_BOARD_API_LEVEL_FROZEN
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.board.api_frozen=$(RELEASE_BOARD_API_LEVEL_FROZEN)
+endif
+
+# Set build prop. This prop is read by ota_from_target_files when generating OTA,
+# to decide if VABC should be disabled.
+ifeq ($(BOARD_DONT_USE_VABC_OTA),true)
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.vendor.build.dont_use_vabc=true
+endif
+
+# Set the flag in vendor. So VTS would know if the new fingerprint format is in use when
+# the system images are replaced by GSI.
+ifeq ($(BOARD_USE_VBMETA_DIGTEST_IN_FINGERPRINT),true)
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.vendor.build.fingerprint_has_digest=1
+endif
+
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.vendor.build.security_patch=$(VENDOR_SECURITY_PATCH) \
+    ro.product.board=$(TARGET_BOOTLOADER_BOARD_NAME) \
+    ro.board.platform=$(TARGET_BOARD_PLATFORM) \
+    ro.hwui.use_vulkan=$(TARGET_USES_VULKAN)
+
+ifdef TARGET_SCREEN_DENSITY
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.sf.lcd_density=$(TARGET_SCREEN_DENSITY)
+endif
+
+ifdef AB_OTA_UPDATER
+ADDITIONAL_VENDOR_PROPERTIES += \
+    ro.build.ab_update=$(AB_OTA_UPDATER)
+endif
+
+ADDITIONAL_PRODUCT_PROPERTIES += ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS)
+
+ifeq ($(AB_OTA_UPDATER),true)
+ADDITIONAL_PRODUCT_PROPERTIES += ro.product.ab_ota_partitions=$(subst $(space),$(comma),$(sort $(AB_OTA_PARTITIONS)))
+ADDITIONAL_VENDOR_PROPERTIES += ro.vendor.build.ab_ota_partitions=$(subst $(space),$(comma),$(sort $(AB_OTA_PARTITIONS)))
+endif
+
+# Set this property for VTS to skip large page size tests on unsupported devices.
+ADDITIONAL_PRODUCT_PROPERTIES += \
+    ro.product.cpu.pagesize.max=$(TARGET_MAX_PAGE_SIZE_SUPPORTED)
+
+ifeq ($(PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO),true)
+ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.no_bionic_page_size_macro=true
+endif
+
+user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT))
+enable_target_debugging := true
+ifneq (,$(user_variant))
+  # Target is secure in user builds.
+  ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=1
+  ADDITIONAL_SYSTEM_PROPERTIES += security.perf_harden=1
+
+  ifeq ($(user_variant),user)
+    ADDITIONAL_SYSTEM_PROPERTIES += ro.adb.secure=1
+  endif
+
+  ifneq ($(user_variant),userdebug)
+    # Disable debugging in plain user builds.
+    enable_target_debugging :=
+  endif
+
+  # Disallow mock locations by default for user builds
+  ADDITIONAL_SYSTEM_PROPERTIES += ro.allow.mock.location=0
+
+else # !user_variant
+  # Turn on checkjni for non-user builds.
+  ADDITIONAL_SYSTEM_PROPERTIES += ro.kernel.android.checkjni=1
+  # Set device insecure for non-user builds.
+  ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=0
+  # Allow mock locations by default for non user builds
+  ADDITIONAL_SYSTEM_PROPERTIES += ro.allow.mock.location=1
+endif # !user_variant
+
+ifeq (true,$(strip $(enable_target_debugging)))
+  # Target is more debuggable and adbd is on by default
+  ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=1
+  # Enable Dalvik lock contention logging.
+  ADDITIONAL_SYSTEM_PROPERTIES += dalvik.vm.lockprof.threshold=500
+else # !enable_target_debugging
+  # Target is less debuggable and adbd is off by default
+  ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=0
+endif # !enable_target_debugging
+
+ifneq ($(filter sdk sdk_addon,$(MAKECMDGOALS)),)
+_is_sdk_build := true
+endif
+
+ifeq ($(TARGET_BUILD_VARIANT),eng)
+ifneq ($(filter ro.setupwizard.mode=ENABLED, $(call collapse-pairs, $(ADDITIONAL_SYSTEM_PROPERTIES))),)
+  # Don't require the setup wizard on eng builds
+  ADDITIONAL_SYSTEM_PROPERTIES := $(filter-out ro.setupwizard.mode=%,\
+          $(call collapse-pairs, $(ADDITIONAL_SYSTEM_PROPERTIES))) \
+          ro.setupwizard.mode=OPTIONAL
+endif
+ifndef _is_sdk_build
+  # To speedup startup of non-preopted builds, don't verify or compile the boot image.
+  ADDITIONAL_SYSTEM_PROPERTIES += dalvik.vm.image-dex2oat-filter=extract
+endif
+# b/323566535
+ADDITIONAL_SYSTEM_PROPERTIES += init.svc_debug.no_fatal.zygote=true
+endif
+
+ifdef _is_sdk_build
+ADDITIONAL_SYSTEM_PROPERTIES += xmpp.auto-presence=true
+ADDITIONAL_SYSTEM_PROPERTIES += ro.config.nocheckin=yes
+endif
+
+_is_sdk_build :=
+
+ADDITIONAL_SYSTEM_PROPERTIES += net.bt.name=Android
+
+# This property is set by flashing debug boot image, so default to false.
+ADDITIONAL_SYSTEM_PROPERTIES += ro.force.debuggable=0
+
+config_enable_uffd_gc := \
+  $(firstword $(OVERRIDE_ENABLE_UFFD_GC) $(PRODUCT_ENABLE_UFFD_GC) default)
+
+# If the value is "default", it will be mangled by post_process_props.py.
+ADDITIONAL_PRODUCT_PROPERTIES += ro.dalvik.vm.enable_uffd_gc=$(config_enable_uffd_gc)
+
+ADDITIONAL_SYSTEM_PROPERTIES := $(strip $(ADDITIONAL_SYSTEM_PROPERTIES))
+ADDITIONAL_PRODUCT_PROPERTIES := $(strip $(ADDITIONAL_PRODUCT_PROPERTIES))
+ADDITIONAL_VENDOR_PROPERTIES := $(strip $(ADDITIONAL_VENDOR_PROPERTIES))
+
+.KATI_READONLY += \
+    ADDITIONAL_SYSTEM_PROPERTIES \
+    ADDITIONAL_PRODUCT_PROPERTIES \
+    ADDITIONAL_VENDOR_PROPERTIES
diff --git a/core/tasks/meta-lic.mk b/core/tasks/meta-lic.mk
index c630bcc..2126bd0 100644
--- a/core/tasks/meta-lic.mk
+++ b/core/tasks/meta-lic.mk
@@ -30,6 +30,23 @@
 $(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/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,))
@@ -84,9 +101,29 @@
 
 $(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,))
 
+# Moved here from device/google/trout/Android.mk
+$(eval $(call declare-1p-copy-files,device/google/trout,))
+
 # Moved here from frameworks/av/media/Android.mk
 $(eval $(call declare-1p-copy-files,frameworks/av/media/libeffects,audio_effects.conf))
 $(eval $(call declare-1p-copy-files,frameworks/av/media/libeffects,audio_effects.xml))
diff --git a/envsetup.sh b/envsetup.sh
index ab43ada..50fec51 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1112,8 +1112,8 @@
   local tool_binary="$1"
   shift
 
-  # If logging is not enabled or the logger is not configured, run the original command and return.
-  if [[ "${ANDROID_ENABLE_TOOL_LOGGING}" != "true" ]] || [[ -z "${ANDROID_TOOL_LOGGER}" ]]; then
+  # If the logger is not configured, run the original command and return.
+  if [[ -z "${ANDROID_TOOL_LOGGER}" ]]; then
      "${tool_binary}" "${@}"
      return $?
   fi
@@ -1134,8 +1134,9 @@
     --tool_tag "${tool_tag}" \
     --start_timestamp "${start_time}" \
     --end_timestamp "$(date +%s.%N)" \
-    --tool_args \""${@}"\" \
+    --tool_args "$*" \
     --exit_code "${exit_code}" \
+    ${ANDROID_TOOL_LOGGER_EXTRA_ARGS} \
     > /dev/null 2>&1 &
   exit ${exit_code}
   ' SIGINT SIGTERM SIGQUIT EXIT
diff --git a/target/board/ndk/BoardConfig.mk b/target/board/ndk/BoardConfig.mk
index b485f8b..d5399b2 100644
--- a/target/board/ndk/BoardConfig.mk
+++ b/target/board/ndk/BoardConfig.mk
@@ -15,6 +15,6 @@
 
 TARGET_ARCH_SUITE := ndk
 
-MALLOC_SVELTE := true
+MALLOC_LOW_MEMORY := true
 
 USE_SAFESTACK := false
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 57e8275..22284b1 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -486,6 +486,11 @@
 # Enable dirty image object binning to reduce dirty pages in the image.
 PRODUCT_PACKAGES += dirty-image-objects
 
+# Enable go/perfetto-persistent-tracing for eng builds
+ifneq (,$(filter eng, $(TARGET_BUILD_VARIANT)))
+    PRODUCT_PRODUCT_PROPERTIES += persist.debug.perfetto.persistent_sysui_tracing_for_bugreport=1
+endif
+
 $(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
 
 # Ensure all trunk-stable flags are available.
diff --git a/target/product/module_arm64.mk b/target/product/module_arm64.mk
index 634a03d..d6487ca 100644
--- a/target/product/module_arm64.mk
+++ b/target/product/module_arm64.mk
@@ -21,3 +21,4 @@
 PRODUCT_DEVICE := module_arm64
 
 PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
+PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
diff --git a/target/product/module_arm64only.mk b/target/product/module_arm64only.mk
index 822ac24..137701a 100644
--- a/target/product/module_arm64only.mk
+++ b/target/product/module_arm64only.mk
@@ -21,3 +21,4 @@
 PRODUCT_DEVICE := module_arm64only
 
 PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
+PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
diff --git a/target/product/module_common.mk b/target/product/module_common.mk
index bf146a0..da4ea23 100644
--- a/target/product/module_common.mk
+++ b/target/product/module_common.mk
@@ -24,8 +24,9 @@
 # uses -DENFORCE_VINTF_MANIFEST. See b/185759877
 PRODUCT_SHIPPING_API_LEVEL := 29
 
-# Builds using a module product should build modules from source, even if
-# BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE says otherwise.
+# If true, this builds the mainline modules from source. This overrides any
+# prebuilts selected via RELEASE_APEX_CONTRIBUTIONS_* build flags for the
+# current release config.
 PRODUCT_MODULE_BUILD_FROM_SOURCE := true
 
 # Build sdk from source if the branch is not using slim manifests.
diff --git a/target/product/module_x86_64.mk b/target/product/module_x86_64.mk
index 9bd0264..e182bf6 100644
--- a/target/product/module_x86_64.mk
+++ b/target/product/module_x86_64.mk
@@ -21,3 +21,4 @@
 PRODUCT_DEVICE := module_x86_64
 
 PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
+PRODUCT_MAX_PAGE_SIZE_SUPPORTED :=  16384
diff --git a/target/product/module_x86_64only.mk b/target/product/module_x86_64only.mk
index 056fb90..fa4a04d 100644
--- a/target/product/module_x86_64only.mk
+++ b/target/product/module_x86_64only.mk
@@ -21,3 +21,4 @@
 PRODUCT_DEVICE := module_x86_64only
 
 PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
+PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
diff --git a/teams/Android.bp b/teams/Android.bp
index 78efa61..b3a5752 100644
--- a/teams/Android.bp
+++ b/teams/Android.bp
@@ -4337,39 +4337,45 @@
 }
 
 team {
-  name: "trendy_team_media_framework_drm",
+    name: "trendy_team_media_framework_drm",
 
-  // go/trendy/manage/engineers/5311752690335744
-  trendy_team_id: "5311752690335744",
+    // go/trendy/manage/engineers/5311752690335744
+    trendy_team_id: "5311752690335744",
 }
 
 team {
-  name: "trendy_team_media_framework_audio",
+    name: "trendy_team_media_framework_audio",
 
-  // go/trendy/manage/engineers/5823575353065472
-  trendy_team_id: "5823575353065472",
+    // go/trendy/manage/engineers/5823575353065472
+    trendy_team_id: "5823575353065472",
 }
 
 team {
-  name: "trendy_team_ar_sensors_context_hub",
+    name: "trendy_team_pixel_pearl",
 
-  // go/trendy/manage/engineers/4776371090259968
-  trendy_team_id: "4776371090259968",
-}
-
-
-team {
-  name: "trendy_team_media_codec_framework",
-
-  // go/trendy/manage/engineers/4943966050844672
-  trendy_team_id: "4943966050844672",
+    // go/trendy/manage/engineers/6326219602231296
+    trendy_team_id: "6326219602231296",
 }
 
 team {
-  name: "trendy_team_android_platform_performance_testing",
+    name: "trendy_team_ar_sensors_context_hub",
 
-  // go/trendy/manage/engineers/5810097836621824
-  trendy_team_id: "5810097836621824",
+    // go/trendy/manage/engineers/4776371090259968
+    trendy_team_id: "4776371090259968",
+}
+
+team {
+    name: "trendy_team_media_codec_framework",
+
+    // go/trendy/manage/engineers/4943966050844672
+    trendy_team_id: "4943966050844672",
+}
+
+team {
+    name: "trendy_team_android_platform_performance_testing",
+
+    // go/trendy/manage/engineers/5810097836621824
+    trendy_team_id: "5810097836621824",
 }
 
 team {
@@ -4378,3 +4384,10 @@
     // go/trendy/manage/engineers/5551098528825344
     trendy_team_id: "5551098528825344",
 }
+
+team {
+    name: "trendy_team_incremental",
+
+    // go/trendy/manage/engineers/5955405559201792
+    trendy_team_id: "5955405559201792",
+}
diff --git a/tests/Android.bp b/tests/Android.bp
index d3964e5..39debf5 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -29,6 +29,7 @@
     },
     data: [
         ":envsetup_minimum.zip",
+        ":tool_event_logger",
     ],
     test_suites: [
         "general-tests",
diff --git a/tests/run_tool_with_logging_test.py b/tests/run_tool_with_logging_test.py
index 1eb78f1..18abd8e 100644
--- a/tests/run_tool_with_logging_test.py
+++ b/tests/run_tool_with_logging_test.py
@@ -13,20 +13,22 @@
 # limitations under the License.
 
 import dataclasses
+import glob
 from importlib import resources
 import logging
 import os
 from pathlib import Path
 import re
+import shutil
 import signal
 import stat
 import subprocess
+import sys
 import tempfile
 import textwrap
 import time
 import unittest
 import zipfile
-import sys
 
 EXII_RETURN_CODE = 0
 INTERRUPTED_RETURN_CODE = 130
@@ -40,7 +42,7 @@
     # Configure to print logging to stdout.
     logging.basicConfig(filename=None, level=logging.DEBUG)
     console = logging.StreamHandler(sys.stdout)
-    logging.getLogger('').addHandler(console)
+    logging.getLogger("").addHandler(console)
 
   def setUp(self):
     super().setUp()
@@ -49,7 +51,7 @@
     os.chdir(self.working_dir.name)
     # Extract envsetup.zip which contains the envsetup.sh and other dependent
     # scripts required to set up the build environments.
-    with resources.files("testdata").joinpath("envsetup.zip").open('rb') as p:
+    with resources.files("testdata").joinpath("envsetup.zip").open("rb") as p:
       with zipfile.ZipFile(p, "r") as zip_f:
         zip_f.extractall()
 
@@ -57,37 +59,10 @@
     self.working_dir.cleanup()
     super().tearDown()
 
-  def test_does_not_log_when_logging_disabled(self):
-    test_tool = TestScript.create(self.working_dir)
-    test_logger = TestScript.create(self.working_dir)
-
-    self._run_script_and_wait(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=false
-      ANDROID_TOOL_LOGGER="{test_logger.executable}"
-      run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
-    """)
-
-    test_tool.assert_called_once_with_args("arg1 arg2")
-    test_logger.assert_not_called()
-
-  def test_does_not_log_when_logger_var_unset(self):
-    test_tool = TestScript.create(self.working_dir)
-    test_logger = TestScript.create(self.working_dir)
-
-    self._run_script_and_wait(f"""
-      unset ANDROID_ENABLE_TOOL_LOGGING
-      ANDROID_TOOL_LOGGER="{test_logger.executable}"
-      run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
-    """)
-
-    test_tool.assert_called_once_with_args("arg1 arg2")
-    test_logger.assert_not_called()
-
   def test_does_not_log_when_logger_var_empty(self):
     test_tool = TestScript.create(self.working_dir)
 
     self._run_script_and_wait(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=true
       ANDROID_TOOL_LOGGER=""
       run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
     """)
@@ -98,7 +73,6 @@
     test_tool = TestScript.create(self.working_dir)
 
     self._run_script_and_wait(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=true
       unset ANDROID_TOOL_LOGGER
       run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
     """)
@@ -110,7 +84,6 @@
     test_logger = TestScript.create(self.working_dir)
 
     self._run_script_and_wait(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=true
       ANDROID_TOOL_LOGGER="{test_logger.executable}"
       run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
     """)
@@ -118,7 +91,7 @@
     test_tool.assert_called_once_with_args("arg1 arg2")
     expected_logger_args = (
         "--tool_tag FAKE_TOOL --start_timestamp \d+\.\d+ --end_timestamp"
-        ' \d+\.\d+ --tool_args "arg1 arg2" --exit_code 0'
+        " \d+\.\d+ --tool_args arg1 arg2 --exit_code 0"
     )
     test_logger.assert_called_once_with_args(expected_logger_args)
 
@@ -128,7 +101,6 @@
 
     run_tool_with_logging_stdout, run_tool_with_logging_stderr = (
         self._run_script_and_wait(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=true
       ANDROID_TOOL_LOGGER="{test_logger.executable}"
       run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
     """)
@@ -136,7 +108,6 @@
 
     run_tool_without_logging_stdout, run_tool_without_logging_stderr = (
         self._run_script_and_wait(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=true
       ANDROID_TOOL_LOGGER="{test_logger.executable}"
       {test_tool.executable} arg1 arg2
     """)
@@ -154,7 +125,6 @@
     test_logger = TestScript.create(self.working_dir, "echo 'logger called'")
 
     run_tool_with_logging_output, _ = self._run_script_and_wait(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=true
       ANDROID_TOOL_LOGGER="{test_logger.executable}"
       run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
     """)
@@ -168,7 +138,6 @@
     )
 
     _, err = self._run_script_and_wait(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=true
       ANDROID_TOOL_LOGGER="{test_logger.executable}"
       run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
     """)
@@ -180,7 +149,6 @@
     test_logger = TestScript.create(self.working_dir)
 
     process = self._run_script_in_build_env(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=true
       ANDROID_TOOL_LOGGER="{test_logger.executable}"
       run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
     """)
@@ -196,7 +164,7 @@
 
     expected_logger_args = (
         "--tool_tag FAKE_TOOL --start_timestamp \d+\.\d+ --end_timestamp"
-        ' \d+\.\d+ --tool_args "arg1 arg2" --exit_code 130'
+        " \d+\.\d+ --tool_args arg1 arg2 --exit_code 130"
     )
     test_logger.assert_called_once_with_args(expected_logger_args)
 
@@ -205,9 +173,8 @@
     test_logger = TestScript.create(self.working_dir)
 
     self._run_script_and_wait(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=false
+      ANDROID_TOOL_LOGGER=""
       ANDROID_TOOL_LOGGER="{test_logger.executable}"
-      ANDROID_ENABLE_TOOL_LOGGING=true
       run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
     """)
 
@@ -218,14 +185,43 @@
     test_logger = TestScript.create(self.working_dir)
 
     self._run_script_and_wait(f"""
-      ANDROID_ENABLE_TOOL_LOGGING=true
       ANDROID_TOOL_LOGGER="{test_logger.executable}"
-      ANDROID_ENABLE_TOOL_LOGGING=false
+      ANDROID_TOOL_LOGGER=""
       run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
     """)
 
     test_logger.assert_not_called()
 
+  def test_integration_tool_event_logger_dry_run(self):
+    test_tool = TestScript.create(self.working_dir)
+    logger_path = self._import_logger()
+
+    self._run_script_and_wait(f"""
+      TMPDIR="{self.working_dir.name}"
+      ANDROID_TOOL_LOGGER="{logger_path}"
+      ANDROID_TOOL_LOGGER_EXTRA_ARGS="--dry_run"
+      run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2
+    """)
+
+    self._assert_logger_dry_run()
+
+  def _import_logger(self) -> Path:
+    logger = "tool_event_logger"
+    logger_path = Path(self.working_dir.name).joinpath(logger)
+    with resources.as_file(resources.files("testdata").joinpath(logger)) as p:
+      shutil.copy(p, logger_path)
+    Path.chmod(logger_path, 0o755)
+    return logger_path
+
+  def _assert_logger_dry_run(self):
+    log_files = glob.glob(self.working_dir.name + "/tool_event_logger_*/*.log")
+    self.assertEqual(len(log_files), 1)
+
+    with open(log_files[0], "r") as f:
+      lines = f.readlines()
+      self.assertEqual(len(lines), 1)
+      self.assertIn("dry run", lines[0])
+
   def _create_build_env_script(self) -> str:
     return f"""
       source {Path(self.working_dir.name).joinpath("build/make/envsetup.sh")}
@@ -248,7 +244,7 @@
         stderr=subprocess.PIPE,
         text=True,
         start_new_session=True,
-        executable='/bin/bash'
+        executable="/bin/bash",
         )
 
   def _wait_for_process(
@@ -301,7 +297,7 @@
       """)
       f.write(executable_contents.encode("utf-8"))
 
-    os.chmod(f.name, os.stat(f.name).st_mode | stat.S_IEXEC)
+    Path.chmod(f.name, os.stat(f.name).st_mode | stat.S_IEXEC)
 
     return TestScript(executable, output_file)
 
diff --git a/tools/Android.bp b/tools/Android.bp
index 0a55ed4..59831a6 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -115,3 +115,11 @@
         },
     },
 }
+
+python_binary_host {
+    name: "merge-event-log-tags",
+    srcs: [
+        "event_log_tags.py",
+        "merge-event-log-tags.py",
+    ],
+}
diff --git a/tools/aconfig/aconfig/templates/cpp_source_file.template b/tools/aconfig/aconfig/templates/cpp_source_file.template
index 62664bc..4c098c5 100644
--- a/tools/aconfig/aconfig/templates/cpp_source_file.template
+++ b/tools/aconfig/aconfig/templates/cpp_source_file.template
@@ -129,12 +129,14 @@
     }
 
     auto package_read_context = aconfig_storage::get_package_read_context(
-        *package_map_file, "{package}");
+        **package_map_file, "{package}");
     if (!package_read_context.ok()) \{
         ALOGI("error: failed to get package read context: %s", package_map_file.error().message().c_str());
         return result;
     }
 
+    delete *package_map_file;
+
     auto flag_val_map = aconfig_storage::get_mapped_file(
         "{item.container}",
         aconfig_storage::StorageFileType::flag_val);
@@ -144,13 +146,15 @@
     }
 
     auto value = aconfig_storage::get_boolean_flag_value(
-        *flag_val_map,
-        package_read_context->package_id + {item.flag_offset});
+        **flag_val_map,
+        package_read_context->boolean_start_index + {item.flag_offset});
     if (!value.ok()) \{
         ALOGI("error: failed to get flag val: %s", package_map_file.error().message().c_str());
         return result;
     }
 
+    delete *flag_val_map;
+
     if (*value != result) \{
         ALOGI("error: new storage value '%d' does not match current value '%d'", *value, result);
     } else \{
diff --git a/tools/aconfig/aconfig_device_paths/Android.bp b/tools/aconfig/aconfig_device_paths/Android.bp
index 21aa9a9..2c771e0 100644
--- a/tools/aconfig/aconfig_device_paths/Android.bp
+++ b/tools/aconfig/aconfig_device_paths/Android.bp
@@ -36,3 +36,16 @@
     host_supported: true,
     defaults: ["libaconfig_device_paths.defaults"],
 }
+
+genrule {
+    name: "libaconfig_java_device_paths_src",
+    srcs: ["src/DevicePathsTemplate.java"],
+    out: ["DevicePaths.java"],
+    tool_files: ["partition_aconfig_flags_paths.txt"],
+    cmd: "sed -e '/TEMPLATE/{r$(location partition_aconfig_flags_paths.txt)' -e 'd}' $(in) > $(out)"
+}
+
+java_library {
+    name: "aconfig_device_paths_java",
+    srcs: [":libaconfig_java_device_paths_src"],
+}
diff --git a/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt b/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt
index 3d2deb2..140cd21 100644
--- a/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt
+++ b/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt
@@ -1,6 +1,4 @@
-[
-    "/system/etc/aconfig_flags.pb",
-    "/system_ext/etc/aconfig_flags.pb",
-    "/product/etc/aconfig_flags.pb",
-    "/vendor/etc/aconfig_flags.pb",
-]
+"/system/etc/aconfig_flags.pb",
+"/system_ext/etc/aconfig_flags.pb",
+"/product/etc/aconfig_flags.pb",
+"/vendor/etc/aconfig_flags.pb",
diff --git a/tools/aconfig/aconfig_device_paths/src/DevicePathsTemplate.java b/tools/aconfig/aconfig_device_paths/src/DevicePathsTemplate.java
new file mode 100644
index 0000000..f27b9bd
--- /dev/null
+++ b/tools/aconfig/aconfig_device_paths/src/DevicePathsTemplate.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.aconfig;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @hide
+ */
+public class DevicePaths {
+    static final String[] PATHS = {
+        TEMPLATE
+    };
+
+    private static final String APEX_DIR = "/apex";
+    private static final String APEX_ACONFIG_PATH_SUFFIX = "/etc/aconfig_flags.pb";
+
+
+    /**
+     * Returns the list of all on-device aconfig protos paths.
+     * @hide
+     */
+    public List<String> parsedFlagsProtoPaths() {
+        ArrayList<String> paths = new ArrayList(Arrays.asList(PATHS));
+
+        File apexDirectory = new File(APEX_DIR);
+        if (!apexDirectory.isDirectory()) {
+            return paths;
+        }
+
+        File[] subdirs = apexDirectory.listFiles();
+        if (subdirs == null) {
+            return paths;
+        }
+
+        for (File prefix : subdirs) {
+            // For each mainline modules, there are two directories, one <modulepackage>/,
+            // and one <modulepackage>@<versioncode>/. Just read the former.
+            if (prefix.getAbsolutePath().contains("@")) {
+                continue;
+            }
+
+            File protoPath = new File(prefix + APEX_ACONFIG_PATH_SUFFIX);
+            if (!protoPath.exists()) {
+                continue;
+            }
+
+            paths.add(protoPath.getAbsolutePath());
+        }
+        return paths;
+    }
+}
diff --git a/tools/aconfig/aconfig_device_paths/src/lib.rs b/tools/aconfig/aconfig_device_paths/src/lib.rs
index 7bb62f4..c5a6bff 100644
--- a/tools/aconfig/aconfig_device_paths/src/lib.rs
+++ b/tools/aconfig/aconfig_device_paths/src/lib.rs
@@ -23,7 +23,7 @@
 
 /// Determine all paths that contain an aconfig protobuf file.
 pub fn parsed_flags_proto_paths() -> Result<Vec<PathBuf>> {
-    let mut result: Vec<PathBuf> = include!("../partition_aconfig_flags_paths.txt")
+    let mut result: Vec<PathBuf> = [include_str!("../partition_aconfig_flags_paths.txt")]
         .map(|s| PathBuf::from(s.to_string()))
         .to_vec();
     for dir in fs::read_dir("/apex")? {
diff --git a/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp b/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp
index 548078f..7af024b 100644
--- a/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp
+++ b/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp
@@ -7,6 +7,29 @@
 
 namespace aconfig_storage {
 
+Result<std::vector<FlagValueSummary>> list_flags(
+    const std::string& package_map,
+    const std::string& flag_map,
+    const std::string& flag_val) {
+  auto flag_list_cxx = list_flags_cxx(rust::Str(package_map.c_str()),
+                                      rust::Str(flag_map.c_str()),
+                                      rust::Str(flag_val.c_str()));
+  if (flag_list_cxx.query_success) {
+    auto flag_list = std::vector<FlagValueSummary>();
+    for (const auto& flag_cxx : flag_list_cxx.flags) {
+      auto flag = FlagValueSummary();
+      flag.package_name = std::string(flag_cxx.package_name);
+      flag.flag_name = std::string(flag_cxx.flag_name);
+      flag.flag_value = std::string(flag_cxx.flag_value);
+      flag.value_type = std::string(flag_cxx.value_type);
+      flag_list.push_back(flag);
+    }
+    return flag_list;
+  } else {
+    return Error() << flag_list_cxx.error_message;
+  }
+}
+
 Result<std::vector<FlagValueAndInfoSummary>> list_flags_with_info(
     const std::string& package_map,
     const std::string& flag_map,
diff --git a/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp b/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp
index 5044a4d..9f3cdb0 100644
--- a/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp
+++ b/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp
@@ -6,6 +6,23 @@
 
 namespace aconfig_storage {
 
+/// Flag value summary for a flag
+struct FlagValueSummary {
+  std::string package_name;
+  std::string flag_name;
+  std::string flag_value;
+  std::string value_type;
+};
+
+/// List all flag values
+/// \input package_map: package map file
+/// \input flag_map: flag map file
+/// \input flag_val: flag value file
+android::base::Result<std::vector<FlagValueSummary>> list_flags(
+    const std::string& package_map,
+    const std::string& flag_map,
+    const std::string& flag_val);
+
 /// Flag value and info summary for a flag
 struct FlagValueAndInfoSummary {
   std::string package_name;
diff --git a/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto b/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto
index 7de43ca..f6bf1a4 100644
--- a/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto
+++ b/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto
@@ -28,7 +28,8 @@
   optional string flag_val = 5;
   optional string flag_info = 6;
   optional string local_overrides = 7;
-  optional int64 timestamp = 8;
+  optional string default_flag_val = 8;
+  optional int64 timestamp = 9;
 }
 
 message storage_files {
diff --git a/tools/aconfig/aconfig_storage_file/src/lib.rs b/tools/aconfig/aconfig_storage_file/src/lib.rs
index 80602bb..26e9c1a 100644
--- a/tools/aconfig/aconfig_storage_file/src/lib.rs
+++ b/tools/aconfig/aconfig_storage_file/src/lib.rs
@@ -382,6 +382,14 @@
 // Exported rust data structure and methods, c++ code will be generated
 #[cxx::bridge]
 mod ffi {
+    /// flag value summary cxx return
+    pub struct FlagValueSummaryCXX {
+        pub package_name: String,
+        pub flag_name: String,
+        pub flag_value: String,
+        pub value_type: String,
+    }
+
     /// flag value and info summary cxx return
     pub struct FlagValueAndInfoSummaryCXX {
         pub package_name: String,
@@ -394,6 +402,13 @@
     }
 
     /// list flag result cxx return
+    pub struct ListFlagValueResultCXX {
+        pub query_success: bool,
+        pub error_message: String,
+        pub flags: Vec<FlagValueSummaryCXX>,
+    }
+
+    /// list flag with info result cxx return
     pub struct ListFlagValueAndInfoResultCXX {
         pub query_success: bool,
         pub error_message: String,
@@ -402,6 +417,12 @@
 
     // Rust export to c++
     extern "Rust" {
+        pub fn list_flags_cxx(
+            package_map: &str,
+            flag_map: &str,
+            flag_val: &str,
+        ) -> ListFlagValueResultCXX;
+
         pub fn list_flags_with_info_cxx(
             package_map: &str,
             flag_map: &str,
@@ -411,6 +432,18 @@
     }
 }
 
+/// implement flag value summary cxx return type
+impl ffi::FlagValueSummaryCXX {
+    pub(crate) fn new(summary: FlagValueSummary) -> Self {
+        Self {
+            package_name: summary.package_name,
+            flag_name: summary.flag_name,
+            flag_value: summary.flag_value,
+            value_type: format!("{:?}", summary.value_type),
+        }
+    }
+}
+
 /// implement flag value and info summary cxx return type
 impl ffi::FlagValueAndInfoSummaryCXX {
     pub(crate) fn new(summary: FlagValueAndInfoSummary) -> Self {
@@ -426,6 +459,26 @@
     }
 }
 
+/// implement list flag cxx interlop
+pub fn list_flags_cxx(
+    package_map: &str,
+    flag_map: &str,
+    flag_val: &str,
+) -> ffi::ListFlagValueResultCXX {
+    match list_flags(package_map, flag_map, flag_val) {
+        Ok(summary) => ffi::ListFlagValueResultCXX {
+            query_success: true,
+            error_message: String::new(),
+            flags: summary.into_iter().map(ffi::FlagValueSummaryCXX::new).collect(),
+        },
+        Err(errmsg) => ffi::ListFlagValueResultCXX {
+            query_success: false,
+            error_message: format!("{:?}", errmsg),
+            flags: Vec::new(),
+        },
+    }
+}
+
 /// implement list flag with info cxx interlop
 pub fn list_flags_with_info_cxx(
     package_map: &str,
diff --git a/tools/aconfig/aconfig_storage_file/tests/storage_file_test.cpp b/tools/aconfig/aconfig_storage_file/tests/storage_file_test.cpp
index eccbca5..ebd1dd8 100644
--- a/tools/aconfig/aconfig_storage_file/tests/storage_file_test.cpp
+++ b/tools/aconfig/aconfig_storage_file/tests/storage_file_test.cpp
@@ -24,15 +24,25 @@
 using namespace android::base;
 using namespace aconfig_storage;
 
+void verify_value(const FlagValueSummary& flag,
+                  const std::string& package_name,
+                  const std::string& flag_name,
+                  const std::string& flag_val,
+                  const std::string& value_type) {
+  ASSERT_EQ(flag.package_name, package_name);
+  ASSERT_EQ(flag.flag_name, flag_name);
+  ASSERT_EQ(flag.flag_value, flag_val);
+  ASSERT_EQ(flag.value_type, value_type);
+}
 
-void verify_flag(const FlagValueAndInfoSummary& flag,
-                 const std::string& package_name,
-                 const std::string& flag_name,
-                 const std::string& flag_val,
-                 const std::string& value_type,
-                 bool is_readwrite,
-                 bool has_server_override,
-                 bool has_local_override) {
+void verify_value_info(const FlagValueAndInfoSummary& flag,
+                       const std::string& package_name,
+                       const std::string& flag_name,
+                       const std::string& flag_val,
+                       const std::string& value_type,
+                       bool is_readwrite,
+                       bool has_server_override,
+                       bool has_local_override) {
   ASSERT_EQ(flag.package_name, package_name);
   ASSERT_EQ(flag.flag_name, flag_name);
   ASSERT_EQ(flag.flag_value, flag_val);
@@ -42,6 +52,35 @@
   ASSERT_EQ(flag.has_local_override, has_local_override);
 }
 
+TEST(AconfigStorageFileTest, test_list_flag) {
+  auto const test_dir = GetExecutableDirectory();
+  auto const package_map = test_dir + "/package.map";
+  auto const flag_map = test_dir + "/flag.map";
+  auto const flag_val = test_dir + "/flag.val";
+  auto flag_list_result = aconfig_storage::list_flags(
+      package_map, flag_map, flag_val);
+  ASSERT_TRUE(flag_list_result.ok());
+
+  auto const& flag_list = *flag_list_result;
+  ASSERT_EQ(flag_list.size(), 8);
+  verify_value(flag_list[0], "com.android.aconfig.storage.test_1", "disabled_rw",
+               "false", "ReadWriteBoolean");
+  verify_value(flag_list[1], "com.android.aconfig.storage.test_1", "enabled_ro",
+               "true", "ReadOnlyBoolean");
+  verify_value(flag_list[2], "com.android.aconfig.storage.test_1", "enabled_rw",
+               "true", "ReadWriteBoolean");
+  verify_value(flag_list[3], "com.android.aconfig.storage.test_2", "disabled_rw",
+               "false", "ReadWriteBoolean");
+  verify_value(flag_list[4], "com.android.aconfig.storage.test_2", "enabled_fixed_ro",
+               "true", "FixedReadOnlyBoolean");
+  verify_value(flag_list[5], "com.android.aconfig.storage.test_2", "enabled_ro",
+               "true", "ReadOnlyBoolean");
+  verify_value(flag_list[6], "com.android.aconfig.storage.test_4", "enabled_fixed_ro",
+               "true", "FixedReadOnlyBoolean");
+  verify_value(flag_list[7], "com.android.aconfig.storage.test_4", "enabled_rw",
+               "true", "ReadWriteBoolean");
+}
+
 TEST(AconfigStorageFileTest, test_list_flag_with_info) {
   auto const test_dir = GetExecutableDirectory();
   auto const package_map = test_dir + "/package.map";
@@ -54,20 +93,20 @@
 
   auto const& flag_list = *flag_list_result;
   ASSERT_EQ(flag_list.size(), 8);
-  verify_flag(flag_list[0], "com.android.aconfig.storage.test_1", "disabled_rw",
-              "false", "ReadWriteBoolean", true, false, false);
-  verify_flag(flag_list[1], "com.android.aconfig.storage.test_1", "enabled_ro",
-              "true", "ReadOnlyBoolean", false, false, false);
-  verify_flag(flag_list[2], "com.android.aconfig.storage.test_1", "enabled_rw",
-              "true", "ReadWriteBoolean", true, false, false);
-  verify_flag(flag_list[3], "com.android.aconfig.storage.test_2", "disabled_rw",
-              "false", "ReadWriteBoolean", true, false, false);
-  verify_flag(flag_list[4], "com.android.aconfig.storage.test_2", "enabled_fixed_ro",
-              "true", "FixedReadOnlyBoolean", false, false, false);
-  verify_flag(flag_list[5], "com.android.aconfig.storage.test_2", "enabled_ro",
-              "true", "ReadOnlyBoolean", false, false, false);
-  verify_flag(flag_list[6], "com.android.aconfig.storage.test_4", "enabled_fixed_ro",
-              "true", "FixedReadOnlyBoolean", false, false, false);
-  verify_flag(flag_list[7], "com.android.aconfig.storage.test_4", "enabled_rw",
-              "true", "ReadWriteBoolean", true, false, false);
+  verify_value_info(flag_list[0], "com.android.aconfig.storage.test_1", "disabled_rw",
+                    "false", "ReadWriteBoolean", true, false, false);
+  verify_value_info(flag_list[1], "com.android.aconfig.storage.test_1", "enabled_ro",
+                    "true", "ReadOnlyBoolean", false, false, false);
+  verify_value_info(flag_list[2], "com.android.aconfig.storage.test_1", "enabled_rw",
+                    "true", "ReadWriteBoolean", true, false, false);
+  verify_value_info(flag_list[3], "com.android.aconfig.storage.test_2", "disabled_rw",
+                    "false", "ReadWriteBoolean", true, false, false);
+  verify_value_info(flag_list[4], "com.android.aconfig.storage.test_2", "enabled_fixed_ro",
+                    "true", "FixedReadOnlyBoolean", false, false, false);
+  verify_value_info(flag_list[5], "com.android.aconfig.storage.test_2", "enabled_ro",
+                    "true", "ReadOnlyBoolean", false, false, false);
+  verify_value_info(flag_list[6], "com.android.aconfig.storage.test_4", "enabled_fixed_ro",
+                    "true", "FixedReadOnlyBoolean", false, false, false);
+  verify_value_info(flag_list[7], "com.android.aconfig.storage.test_4", "enabled_rw",
+                    "true", "ReadWriteBoolean", true, false, false);
 }
diff --git a/tools/aconfig/aconfig_storage_read_api/Android.bp b/tools/aconfig/aconfig_storage_read_api/Android.bp
index 217104b..db36294 100644
--- a/tools/aconfig/aconfig_storage_read_api/Android.bp
+++ b/tools/aconfig/aconfig_storage_read_api/Android.bp
@@ -92,10 +92,10 @@
     static_libs: [
         "libaconfig_storage_protos_cc",
         "libprotobuf-cpp-lite",
-        "libbase",
     ],
     shared_libs: [
         "liblog",
+        "libbase",
     ],
     apex_available: [
         "//apex_available:platform",
diff --git a/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp b/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
index 8fe42ce..0aa936a 100644
--- a/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
+++ b/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
@@ -20,6 +20,11 @@
 static constexpr char kAvailableStorageRecordsPb[] =
     "/metadata/aconfig/boot/available_storage_file_records.pb";
 
+/// destructor
+MappedStorageFile::~MappedStorageFile() {
+  munmap(file_ptr, file_size);
+}
+
 /// Read aconfig storage records pb file
 static Result<storage_records_pb> read_storage_records_pb(std::string const& pb_file) {
   auto records = storage_records_pb();
@@ -68,7 +73,7 @@
 namespace private_internal_api {
 
 /// Get mapped file implementation.
-Result<MappedStorageFile> get_mapped_file_impl(
+Result<MappedStorageFile*> get_mapped_file_impl(
     std::string const& pb_file,
     std::string const& container,
     StorageFileType file_type) {
@@ -82,7 +87,7 @@
 } // namespace private internal api
 
 /// Map a storage file
-Result<MappedStorageFile> map_storage_file(std::string const& file) {
+Result<MappedStorageFile*> map_storage_file(std::string const& file) {
   int fd = open(file.c_str(), O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
   if (fd == -1) {
     return ErrnoError() << "failed to open " << file;
@@ -99,9 +104,9 @@
     return ErrnoError() << "mmap failed";
   }
 
-  auto mapped_file = MappedStorageFile();
-  mapped_file.file_ptr = map_result;
-  mapped_file.file_size = file_size;
+  auto mapped_file = new MappedStorageFile();
+  mapped_file->file_ptr = map_result;
+  mapped_file->file_size = file_size;
 
   return mapped_file;
 }
@@ -120,7 +125,7 @@
 }
 
 /// Get mapped storage file
-Result<MappedStorageFile> get_mapped_file(
+Result<MappedStorageFile*> get_mapped_file(
     std::string const& container,
     StorageFileType file_type) {
   return private_internal_api::get_mapped_file_impl(
diff --git a/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp b/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp
index 2bd84fc..e6d7537 100644
--- a/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp
+++ b/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp
@@ -41,6 +41,7 @@
 struct MappedStorageFile {
   void* file_ptr;
   size_t file_size;
+  virtual ~MappedStorageFile();
 };
 
 /// Package read context query result
@@ -60,7 +61,7 @@
 /// DO NOT USE APIS IN THE FOLLOWING NAMESPACE DIRECTLY
 namespace private_internal_api {
 
-android::base::Result<MappedStorageFile> get_mapped_file_impl(
+android::base::Result<MappedStorageFile*> get_mapped_file_impl(
     std::string const& pb_file,
     std::string const& container,
     StorageFileType file_type);
@@ -68,7 +69,7 @@
 } // namespace private_internal_api
 
 /// Map a storage file
-android::base::Result<MappedStorageFile> map_storage_file(
+android::base::Result<MappedStorageFile*> map_storage_file(
     std::string const& file);
 
 
@@ -82,7 +83,7 @@
 /// \input container: stoarge container name
 /// \input file_type: storage file type enum
 /// \returns a MappedStorageFileQuery
-android::base::Result<MappedStorageFile> get_mapped_file(
+android::base::Result<MappedStorageFile*> get_mapped_file(
     std::string const& container,
     StorageFileType file_type);
 
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp
index cfd128d..5393c49 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp
+++ b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp
@@ -16,6 +16,7 @@
 
 #include <string>
 #include <vector>
+#include <memory>
 #include <cstdio>
 
 #include <sys/stat.h>
@@ -111,18 +112,19 @@
 
 /// Negative test to lock down the error when mapping none exist storage files
 TEST_F(AconfigStorageTest, test_none_exist_storage_file_mapping) {
-  auto mapped_file = private_api::get_mapped_file_impl(
+  auto mapped_file_result = private_api::get_mapped_file_impl(
       storage_record_pb, "vendor", api::StorageFileType::package_map);
-  ASSERT_FALSE(mapped_file.ok());
-  ASSERT_EQ(mapped_file.error().message(),
+  ASSERT_FALSE(mapped_file_result.ok());
+  ASSERT_EQ(mapped_file_result.error().message(),
             "Unable to find storage files for container vendor");
 }
 
 /// Test to lock down storage package context query api
 TEST_F(AconfigStorageTest, test_package_context_query) {
-  auto mapped_file = private_api::get_mapped_file_impl(
+  auto mapped_file_result = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::package_map);
-  ASSERT_TRUE(mapped_file.ok());
+  ASSERT_TRUE(mapped_file_result.ok());
+  auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result);
 
   auto context = api::get_package_read_context(
       *mapped_file, "com.android.aconfig.storage.test_1");
@@ -148,9 +150,10 @@
 
 /// Test to lock down when querying none exist package
 TEST_F(AconfigStorageTest, test_none_existent_package_context_query) {
-  auto mapped_file = private_api::get_mapped_file_impl(
+  auto mapped_file_result = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::package_map);
-  ASSERT_TRUE(mapped_file.ok());
+  ASSERT_TRUE(mapped_file_result.ok());
+  auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result);
 
   auto context = api::get_package_read_context(
       *mapped_file, "com.android.aconfig.storage.test_3");
@@ -160,9 +163,10 @@
 
 /// Test to lock down storage flag context query api
 TEST_F(AconfigStorageTest, test_flag_context_query) {
-  auto mapped_file = private_api::get_mapped_file_impl(
+  auto mapped_file_result = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::flag_map);
-  ASSERT_TRUE(mapped_file.ok());
+  ASSERT_TRUE(mapped_file_result.ok());
+  auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result);
 
   auto baseline = std::vector<std::tuple<int, std::string, api::StoredFlagType, int>>{
     {0, "enabled_ro", api::StoredFlagType::ReadOnlyBoolean, 1},
@@ -185,9 +189,10 @@
 
 /// Test to lock down when querying none exist flag
 TEST_F(AconfigStorageTest, test_none_existent_flag_context_query) {
-  auto mapped_file = private_api::get_mapped_file_impl(
+  auto mapped_file_result = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::flag_map);
-  ASSERT_TRUE(mapped_file.ok());
+  ASSERT_TRUE(mapped_file_result.ok());
+  auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result);
 
   auto context = api::get_flag_read_context(*mapped_file, 0, "none_exist");
   ASSERT_TRUE(context.ok());
@@ -200,9 +205,10 @@
 
 /// Test to lock down storage flag value query api
 TEST_F(AconfigStorageTest, test_boolean_flag_value_query) {
-  auto mapped_file = private_api::get_mapped_file_impl(
+  auto mapped_file_result = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::flag_val);
-  ASSERT_TRUE(mapped_file.ok());
+  ASSERT_TRUE(mapped_file_result.ok());
+  auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result);
 
   auto expected_value = std::vector<bool>{
     false, true, true, false, true, true, true, true};
@@ -215,9 +221,10 @@
 
 /// Negative test to lock down the error when querying flag value out of range
 TEST_F(AconfigStorageTest, test_invalid_boolean_flag_value_query) {
-  auto mapped_file = private_api::get_mapped_file_impl(
+  auto mapped_file_result = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::flag_val);
-  ASSERT_TRUE(mapped_file.ok());
+  ASSERT_TRUE(mapped_file_result.ok());
+  auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result);
 
   auto value = api::get_boolean_flag_value(*mapped_file, 8);
   ASSERT_FALSE(value.ok());
@@ -227,9 +234,10 @@
 
 /// Test to lock down storage flag info query api
 TEST_F(AconfigStorageTest, test_boolean_flag_info_query) {
-  auto mapped_file = private_api::get_mapped_file_impl(
+  auto mapped_file_result = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::flag_info);
-  ASSERT_TRUE(mapped_file.ok());
+  ASSERT_TRUE(mapped_file_result.ok());
+  auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result);
 
   auto expected_value = std::vector<bool>{
     true, false, true, true, false, false, false, true};
@@ -245,9 +253,10 @@
 
 /// Negative test to lock down the error when querying flag info out of range
 TEST_F(AconfigStorageTest, test_invalid_boolean_flag_info_query) {
-  auto mapped_file = private_api::get_mapped_file_impl(
+  auto mapped_file_result = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::flag_info);
-  ASSERT_TRUE(mapped_file.ok());
+  ASSERT_TRUE(mapped_file_result.ok());
+  auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result);
 
   auto attribute = api::get_flag_attribute(*mapped_file, api::FlagValueType::Boolean, 8);
   ASSERT_FALSE(attribute.ok());
diff --git a/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp b/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp
index cd57f4f..f529f79 100644
--- a/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp
+++ b/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp
@@ -18,7 +18,7 @@
 namespace aconfig_storage {
 
 /// Map a storage file
-Result<MutableMappedStorageFile> map_mutable_storage_file(std::string const& file) {
+Result<MutableMappedStorageFile*> map_mutable_storage_file(std::string const& file) {
   struct stat file_stat;
   if (stat(file.c_str(), &file_stat) < 0) {
     return ErrnoError() << "stat failed";
@@ -41,9 +41,9 @@
     return ErrnoError() << "mmap failed";
   }
 
-  auto mapped_file = MutableMappedStorageFile();
-  mapped_file.file_ptr = map_result;
-  mapped_file.file_size = file_size;
+  auto mapped_file = new MutableMappedStorageFile();
+  mapped_file->file_ptr = map_result;
+  mapped_file->file_size = file_size;
 
   return mapped_file;
 }
diff --git a/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp b/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp
index 7148396..ff06cbc 100644
--- a/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp
+++ b/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp
@@ -11,13 +11,10 @@
 namespace aconfig_storage {
 
 /// Mapped flag value file
-struct MutableMappedStorageFile{
-  void* file_ptr;
-  size_t file_size;
-};
+struct MutableMappedStorageFile : MappedStorageFile {};
 
 /// Map a storage file
-Result<MutableMappedStorageFile> map_mutable_storage_file(
+Result<MutableMappedStorageFile*> map_mutable_storage_file(
     std::string const& file);
 
 /// Set boolean flag value
diff --git a/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp b/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp
index bd39e9e..5437379 100644
--- a/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp
+++ b/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp
@@ -78,15 +78,12 @@
 TEST_F(AconfigStorageTest, test_boolean_flag_value_update) {
   auto mapped_file_result = api::map_mutable_storage_file(flag_val);
   ASSERT_TRUE(mapped_file_result.ok());
+  auto mapped_file = std::unique_ptr<api::MutableMappedStorageFile>(*mapped_file_result);
 
-  auto mapped_file = *mapped_file_result;
   for (int offset = 0; offset < 8; ++offset) {
-    auto update_result = api::set_boolean_flag_value(mapped_file, offset, true);
+    auto update_result = api::set_boolean_flag_value(*mapped_file, offset, true);
     ASSERT_TRUE(update_result.ok());
-    auto ro_mapped_file = api::MappedStorageFile();
-    ro_mapped_file.file_ptr = mapped_file.file_ptr;
-    ro_mapped_file.file_size = mapped_file.file_size;
-    auto value = api::get_boolean_flag_value(ro_mapped_file, offset);
+    auto value = api::get_boolean_flag_value(*mapped_file, offset);
     ASSERT_TRUE(value.ok());
     ASSERT_TRUE(*value);
   }
@@ -96,9 +93,8 @@
 TEST_F(AconfigStorageTest, test_invalid_boolean_flag_value_update) {
   auto mapped_file_result = api::map_mutable_storage_file(flag_val);
   ASSERT_TRUE(mapped_file_result.ok());
-  auto mapped_file = *mapped_file_result;
-
-  auto update_result = api::set_boolean_flag_value(mapped_file, 8, true);
+  auto mapped_file = std::unique_ptr<api::MutableMappedStorageFile>(*mapped_file_result);
+  auto update_result = api::set_boolean_flag_value(*mapped_file, 8, true);
   ASSERT_FALSE(update_result.ok());
   ASSERT_EQ(update_result.error().message(),
             std::string("InvalidStorageFileOffset(Flag value offset goes beyond the end of the file.)"));
@@ -108,27 +104,22 @@
 TEST_F(AconfigStorageTest, test_flag_has_server_override_update) {
   auto mapped_file_result = api::map_mutable_storage_file(flag_info);
   ASSERT_TRUE(mapped_file_result.ok());
-  auto mapped_file = *mapped_file_result;
+  auto mapped_file = std::unique_ptr<api::MutableMappedStorageFile>(*mapped_file_result);
 
   for (int offset = 0; offset < 8; ++offset) {
     auto update_result = api::set_flag_has_server_override(
-        mapped_file, api::FlagValueType::Boolean, offset, true);
+        *mapped_file, api::FlagValueType::Boolean, offset, true);
     ASSERT_TRUE(update_result.ok()) << update_result.error();
-    auto ro_mapped_file = api::MappedStorageFile();
-    ro_mapped_file.file_ptr = mapped_file.file_ptr;
-    ro_mapped_file.file_size = mapped_file.file_size;
     auto attribute = api::get_flag_attribute(
-        ro_mapped_file, api::FlagValueType::Boolean, offset);
+        *mapped_file, api::FlagValueType::Boolean, offset);
     ASSERT_TRUE(attribute.ok());
     ASSERT_TRUE(*attribute & api::FlagInfoBit::HasServerOverride);
 
     update_result = api::set_flag_has_server_override(
-        mapped_file, api::FlagValueType::Boolean, offset, false);
+        *mapped_file, api::FlagValueType::Boolean, offset, false);
     ASSERT_TRUE(update_result.ok());
-    ro_mapped_file.file_ptr = mapped_file.file_ptr;
-    ro_mapped_file.file_size = mapped_file.file_size;
     attribute = api::get_flag_attribute(
-        ro_mapped_file, api::FlagValueType::Boolean, offset);
+        *mapped_file, api::FlagValueType::Boolean, offset);
     ASSERT_TRUE(attribute.ok());
     ASSERT_FALSE(*attribute & api::FlagInfoBit::HasServerOverride);
   }
@@ -138,27 +129,22 @@
 TEST_F(AconfigStorageTest, test_flag_has_local_override_update) {
   auto mapped_file_result = api::map_mutable_storage_file(flag_info);
   ASSERT_TRUE(mapped_file_result.ok());
-  auto mapped_file = *mapped_file_result;
+  auto mapped_file = std::unique_ptr<api::MutableMappedStorageFile>(*mapped_file_result);
 
   for (int offset = 0; offset < 8; ++offset) {
     auto update_result = api::set_flag_has_local_override(
-        mapped_file, api::FlagValueType::Boolean, offset, true);
+        *mapped_file, api::FlagValueType::Boolean, offset, true);
     ASSERT_TRUE(update_result.ok());
-    auto ro_mapped_file = api::MappedStorageFile();
-    ro_mapped_file.file_ptr = mapped_file.file_ptr;
-    ro_mapped_file.file_size = mapped_file.file_size;
     auto attribute = api::get_flag_attribute(
-        ro_mapped_file, api::FlagValueType::Boolean, offset);
+        *mapped_file, api::FlagValueType::Boolean, offset);
     ASSERT_TRUE(attribute.ok());
     ASSERT_TRUE(*attribute & api::FlagInfoBit::HasLocalOverride);
 
     update_result = api::set_flag_has_local_override(
-        mapped_file, api::FlagValueType::Boolean, offset, false);
+        *mapped_file, api::FlagValueType::Boolean, offset, false);
     ASSERT_TRUE(update_result.ok());
-    ro_mapped_file.file_ptr = mapped_file.file_ptr;
-    ro_mapped_file.file_size = mapped_file.file_size;
     attribute = api::get_flag_attribute(
-        ro_mapped_file, api::FlagValueType::Boolean, offset);
+        *mapped_file, api::FlagValueType::Boolean, offset);
     ASSERT_TRUE(attribute.ok());
     ASSERT_FALSE(*attribute & api::FlagInfoBit::HasLocalOverride);
   }
diff --git a/tools/check-flagged-apis/check-flagged-apis.sh b/tools/check-flagged-apis/check-flagged-apis.sh
index cd37a2d..d9934a1 100755
--- a/tools/check-flagged-apis/check-flagged-apis.sh
+++ b/tools/check-flagged-apis/check-flagged-apis.sh
@@ -20,18 +20,36 @@
 source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../shell_utils.sh
 require_top
 
+PUBLIC_XML_VERSIONS=out/target/common/obj/PACKAGING/api_versions_public_generated-api-versions.xml
+SYSTEM_XML_VERSIONS=out/target/common/obj/PACKAGING/api_versions_system_generated-api-versions.xml
+SYSTEM_SERVER_XML_VERSONS=out/target/common/obj/PACKAGING/api_versions_system_server_complete_generated-api-versions.xml
+MODULE_LIB_XML_VERSIONS=out/target/common/obj/PACKAGING/api_versions_module_lib_complete_generated-api-versions.xml
+
 function m() {
     $(gettop)/build/soong/soong_ui.bash --build-mode --all-modules --dir="$(pwd)" "$@"
 }
 
 function build() {
-    m sdk dist && m \
+    m \
         check-flagged-apis \
         all_aconfig_declarations \
         frameworks-base-api-current.txt \
         frameworks-base-api-system-current.txt \
         frameworks-base-api-system-server-current.txt \
-        frameworks-base-api-module-lib-current.txt
+        frameworks-base-api-module-lib-current.txt \
+        $PUBLIC_XML_VERSIONS \
+        $SYSTEM_XML_VERSIONS \
+        $SYSTEM_SERVER_XML_VERSONS \
+        $MODULE_LIB_XML_VERSIONS
+}
+
+function aninja() {
+    local T="$(gettop)"
+    (\cd "${T}" && prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-${TARGET_PRODUCT}.ninja "$@")
+}
+
+function path_to_api_signature_file {
+    aninja -t query device_"$1"_all_targets | grep -A1 -e input: | tail -n1
 }
 
 function run() {
@@ -39,33 +57,33 @@
 
     echo "# current"
     check-flagged-apis \
-        --api-signature $(gettop)/out/target/product/mainline_x86/obj/ETC/frameworks-base-api-current.txt_intermediates/frameworks-base-api-current.txt \
+        --api-signature $(path_to_api_signature_file "frameworks-base-api-current.txt") \
         --flag-values $(gettop)/out/soong/.intermediates/all_aconfig_declarations.pb \
-        --api-versions $(gettop)/out/dist/data/api-versions.xml
+        --api-versions $PUBLIC_XML_VERSIONS
     (( errors += $? ))
 
     echo
     echo "# system-current"
     check-flagged-apis \
-        --api-signature $(gettop)/out/target/product/mainline_x86/obj/ETC/frameworks-base-api-system-current.txt_intermediates/frameworks-base-api-system-current.txt \
+        --api-signature $(path_to_api_signature_file "frameworks-base-api-system-current.txt") \
         --flag-values $(gettop)/out/soong/.intermediates/all_aconfig_declarations.pb \
-        --api-versions $(gettop)/out/dist/system-data/api-versions.xml
+        --api-versions $SYSTEM_XML_VERSIONS
     (( errors += $? ))
 
     echo
     echo "# system-server-current"
     check-flagged-apis \
-        --api-signature $(gettop)/out/target/product/mainline_x86/obj/ETC/frameworks-base-api-system-server-current.txt_intermediates/frameworks-base-api-system-server-current.txt \
+        --api-signature $(path_to_api_signature_file "frameworks-base-api-system-server-current.txt") \
         --flag-values $(gettop)/out/soong/.intermediates/all_aconfig_declarations.pb \
-        --api-versions $(gettop)/out/dist/system-server-data/api-versions.xml
+        --api-versions $SYSTEM_SERVER_XML_VERSONS
     (( errors += $? ))
 
     echo
     echo "# module-lib"
     check-flagged-apis \
-        --api-signature $(gettop)/out/target/product/mainline_x86/obj/ETC/frameworks-base-api-module-lib-current.txt_intermediates/frameworks-base-api-module-lib-current.txt \
+        --api-signature $(path_to_api_signature_file "frameworks-base-api-module-lib-current.txt") \
         --flag-values $(gettop)/out/soong/.intermediates/all_aconfig_declarations.pb \
-        --api-versions $(gettop)/out/dist/module-lib-data/api-versions.xml
+        --api-versions $MODULE_LIB_XML_VERSIONS
     (( errors += $? ))
 
     return $errors
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 04c2f80..cd85944 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
@@ -34,6 +34,9 @@
           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 boolean setVariableData(int, android.util.Atom...);
+          method @FlaggedApi("android.flag.foo") public boolean innerClassArg(android.Clazz.Builder);
         }
         @FlaggedApi("android.flag.bar") public static class Clazz.Builder {
         }
@@ -46,11 +49,16 @@
       <?xml version="1.0" encoding="utf-8"?>
       <api version="3">
         <class name="android/Clazz" since="1">
+          <extends name="java/lang/Object"/>
           <method name="&lt;init>()V"/>
           <field name="FOO"/>
           <method name="getErrorCode()I"/>
+          <method name="setData(I[[ILandroid/util/Utility;)Z"/>
+          <method name="setVariableData(I[Landroid/util/Atom;)Z"/>
+          <method name="innerClassArg(Landroid/Clazz${"$"}Builder;)"/>
         </class>
         <class name="android/Clazz${"$"}Builder" since="2">
+          <extends name="java/lang/Object"/>
         </class>
       </api>
 """
@@ -89,11 +97,24 @@
   fun testParseApiSignature() {
     val expected =
         setOf(
-            Pair(Symbol("android/Clazz"), Flag("android.flag.foo")),
-            Pair(Symbol("android/Clazz/Clazz()"), Flag("android.flag.foo")),
-            Pair(Symbol("android/Clazz/FOO"), Flag("android.flag.foo")),
-            Pair(Symbol("android/Clazz/getErrorCode()"), Flag("android.flag.foo")),
-            Pair(Symbol("android/Clazz/Builder"), Flag("android.flag.bar")),
+            Pair(
+                Symbol.createClass("android/Clazz", "java/lang/Object", setOf()),
+                Flag("android.flag.foo")),
+            Pair(Symbol.createMethod("android/Clazz", "Clazz()"), Flag("android.flag.foo")),
+            Pair(Symbol.createField("android/Clazz", "FOO"), Flag("android.flag.foo")),
+            Pair(Symbol.createMethod("android/Clazz", "getErrorCode()"), Flag("android.flag.foo")),
+            Pair(
+                Symbol.createMethod("android/Clazz", "setData(I[[ILandroid/util/Utility;)"),
+                Flag("android.flag.foo")),
+            Pair(
+                Symbol.createMethod("android/Clazz", "setVariableData(I[Landroid/util/Atom;)"),
+                Flag("android.flag.foo")),
+            Pair(
+                Symbol.createMethod("android/Clazz", "innerClassArg(Landroid/Clazz/Builder;)"),
+                Flag("android.flag.foo")),
+            Pair(
+                Symbol.createClass("android/Clazz/Builder", "java/lang/Object", setOf()),
+                Flag("android.flag.bar")),
         )
     val actual = parseApiSignature("in-memory", API_SIGNATURE.byteInputStream())
     assertEquals(expected, actual)
@@ -111,17 +132,42 @@
   fun testParseApiVersions() {
     val expected: Set<Symbol> =
         setOf(
-            Symbol("android/Clazz"),
-            Symbol("android/Clazz/Clazz()"),
-            Symbol("android/Clazz/FOO"),
-            Symbol("android/Clazz/getErrorCode()"),
-            Symbol("android/Clazz/Builder"),
+            Symbol.createClass("android/Clazz", "java/lang/Object", setOf()),
+            Symbol.createMethod("android/Clazz", "Clazz()"),
+            Symbol.createField("android/Clazz", "FOO"),
+            Symbol.createMethod("android/Clazz", "getErrorCode()"),
+            Symbol.createMethod("android/Clazz", "setData(I[[ILandroid/util/Utility;)"),
+            Symbol.createMethod("android/Clazz", "setVariableData(I[Landroid/util/Atom;)"),
+            Symbol.createMethod("android/Clazz", "innerClassArg(Landroid/Clazz/Builder;)"),
+            Symbol.createClass("android/Clazz/Builder", "java/lang/Object", setOf()),
         )
     val actual = parseApiVersions(API_VERSIONS.byteInputStream())
     assertEquals(expected, actual)
   }
 
   @Test
+  fun testParseApiVersionsNestedClasses() {
+    val apiVersions =
+        """
+          <?xml version="1.0" encoding="utf-8"?>
+          <api version="3">
+            <class name="android/Clazz${'$'}Foo${'$'}Bar" since="1">
+              <extends name="java/lang/Object"/>
+              <method name="&lt;init>()V"/>
+            </class>
+          </api>
+        """
+            .trim()
+    val expected: Set<Symbol> =
+        setOf(
+            Symbol.createClass("android/Clazz/Foo/Bar", "java/lang/Object", setOf()),
+            Symbol.createMethod("android/Clazz/Foo/Bar", "Bar()"),
+        )
+    val actual = parseApiVersions(apiVersions.byteInputStream())
+    assertEquals(expected, actual)
+  }
+
+  @Test
   fun testFindErrorsNoErrors() {
     val expected = setOf<ApiError>()
     val actual =
@@ -133,17 +179,121 @@
   }
 
   @Test
+  fun testFindErrorsVerifyImplements() {
+    val apiSignature =
+        """
+          // Signature format: 2.0
+          package android {
+            @FlaggedApi("android.flag.foo") public final class Clazz implements android.Interface {
+              method @FlaggedApi("android.flag.foo") public boolean foo();
+              method @FlaggedApi("android.flag.foo") public boolean bar();
+            }
+            public interface Interface {
+              method public boolean bar();
+            }
+          }
+        """
+            .trim()
+
+    val apiVersions =
+        """
+          <?xml version="1.0" encoding="utf-8"?>
+          <api version="3">
+            <class name="android/Clazz" since="1">
+              <extends name="java/lang/Object"/>
+              <implements name="android/Interface"/>
+              <method name="foo()Z"/>
+            </class>
+            <class name="android/Interface" since="1">
+              <method name="bar()Z"/>
+            </class>
+          </api>
+        """
+            .trim()
+
+    val expected = setOf<ApiError>()
+    val actual =
+        findErrors(
+            parseApiSignature("in-memory", apiSignature.byteInputStream()),
+            parseFlagValues(generateFlagsProto(ENABLED, ENABLED)),
+            parseApiVersions(apiVersions.byteInputStream()))
+    assertEquals(expected, actual)
+  }
+
+  @Test
+  fun testFindErrorsVerifySuperclass() {
+    val apiSignature =
+        """
+          // Signature format: 2.0
+          package android {
+            @FlaggedApi("android.flag.foo") public final class C extends android.B {
+              method @FlaggedApi("android.flag.foo") public boolean c();
+              method @FlaggedApi("android.flag.foo") public boolean b();
+              method @FlaggedApi("android.flag.foo") public boolean a();
+            }
+            public final class B extends android.A {
+              method public boolean b();
+            }
+            public final class A {
+              method public boolean a();
+            }
+          }
+        """
+            .trim()
+
+    val apiVersions =
+        """
+          <?xml version="1.0" encoding="utf-8"?>
+          <api version="3">
+            <class name="android/C" since="1">
+              <extends name="android/B"/>
+              <method name="c()Z"/>
+            </class>
+            <class name="android/B" since="1">
+              <extends name="android/A"/>
+              <method name="b()Z"/>
+            </class>
+            <class name="android/A" since="1">
+              <method name="a()Z"/>
+            </class>
+          </api>
+        """
+            .trim()
+
+    val expected = setOf<ApiError>()
+    val actual =
+        findErrors(
+            parseApiSignature("in-memory", apiSignature.byteInputStream()),
+            parseFlagValues(generateFlagsProto(ENABLED, ENABLED)),
+            parseApiVersions(apiVersions.byteInputStream()))
+    assertEquals(expected, actual)
+  }
+
+  @Test
   fun testFindErrorsDisabledFlaggedApiIsPresent() {
     val expected =
         setOf<ApiError>(
-            DisabledFlaggedApiIsPresentError(Symbol("android/Clazz"), Flag("android.flag.foo")),
             DisabledFlaggedApiIsPresentError(
-                Symbol("android/Clazz/Clazz()"), Flag("android.flag.foo")),
-            DisabledFlaggedApiIsPresentError(Symbol("android/Clazz/FOO"), Flag("android.flag.foo")),
+                Symbol.createClass("android/Clazz", "java/lang/Object", setOf()),
+                Flag("android.flag.foo")),
             DisabledFlaggedApiIsPresentError(
-                Symbol("android/Clazz/getErrorCode()"), Flag("android.flag.foo")),
+                Symbol.createMethod("android/Clazz", "Clazz()"), Flag("android.flag.foo")),
             DisabledFlaggedApiIsPresentError(
-                Symbol("android/Clazz/Builder"), Flag("android.flag.bar")),
+                Symbol.createField("android/Clazz", "FOO"), Flag("android.flag.foo")),
+            DisabledFlaggedApiIsPresentError(
+                Symbol.createMethod("android/Clazz", "getErrorCode()"), Flag("android.flag.foo")),
+            DisabledFlaggedApiIsPresentError(
+                Symbol.createMethod("android/Clazz", "setData(I[[ILandroid/util/Utility;)"),
+                Flag("android.flag.foo")),
+            DisabledFlaggedApiIsPresentError(
+                Symbol.createMethod("android/Clazz", "setVariableData(I[Landroid/util/Atom;)"),
+                Flag("android.flag.foo")),
+            DisabledFlaggedApiIsPresentError(
+                Symbol.createMethod("android/Clazz", "innerClassArg(Landroid/Clazz/Builder;)"),
+                Flag("android.flag.foo")),
+            DisabledFlaggedApiIsPresentError(
+                Symbol.createClass("android/Clazz/Builder", "java/lang/Object", setOf()),
+                Flag("android.flag.bar")),
         )
     val actual =
         findErrors(
diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
index 0f2fbef..b514048 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
@@ -54,29 +54,48 @@
  *
  * 1. https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.2
  */
-@JvmInline
-internal value class Symbol(val name: String) {
+internal sealed class Symbol {
   companion object {
     private val FORBIDDEN_CHARS = listOf('#', '$', '.')
 
-    /** Create a new Symbol from a String that may include delimiters other than dot. */
-    fun create(name: String): Symbol {
-      var sanitizedName = name
+    fun createClass(clazz: String, superclass: String?, interfaces: Set<String>): Symbol {
+      return ClassSymbol(
+          toInternalFormat(clazz),
+          superclass?.let { toInternalFormat(it) },
+          interfaces.map { toInternalFormat(it) }.toSet())
+    }
+
+    fun createField(clazz: String, field: String): Symbol {
+      require(!field.contains("(") && !field.contains(")"))
+      return MemberSymbol(toInternalFormat(clazz), toInternalFormat(field))
+    }
+
+    fun createMethod(clazz: String, method: String): Symbol {
+      return MemberSymbol(toInternalFormat(clazz), toInternalFormat(method))
+    }
+
+    protected fun toInternalFormat(name: String): String {
+      var internalName = name
       for (ch in FORBIDDEN_CHARS) {
-        sanitizedName = sanitizedName.replace(ch, '/')
+        internalName = internalName.replace(ch, '/')
       }
-      return Symbol(sanitizedName)
+      return internalName
     }
   }
 
-  init {
-    require(!name.isEmpty()) { "empty string" }
-    for (ch in FORBIDDEN_CHARS) {
-      require(!name.contains(ch)) { "$name: contains $ch" }
-    }
-  }
+  abstract fun toPrettyString(): String
+}
 
-  override fun toString(): String = name.toString()
+internal data class ClassSymbol(
+    val clazz: String,
+    val superclass: String?,
+    val interfaces: Set<String>
+) : Symbol() {
+  override fun toPrettyString(): String = "$clazz"
+}
+
+internal data class MemberSymbol(val clazz: String, val member: String) : Symbol() {
+  override fun toPrettyString(): String = "$clazz/$member"
 }
 
 /**
@@ -102,7 +121,7 @@
     override val flag: Flag
 ) : ApiError() {
   override fun toString(): String {
-    return "error: enabled @FlaggedApi not present in built artifact: symbol=$symbol flag=$flag"
+    return "error: enabled @FlaggedApi not present in built artifact: symbol=${symbol.toPrettyString()} flag=$flag"
   }
 }
 
@@ -111,14 +130,14 @@
     override val flag: Flag
 ) : ApiError() {
   override fun toString(): String {
-    return "error: disabled @FlaggedApi is present in built artifact: symbol=$symbol flag=$flag"
+    return "error: disabled @FlaggedApi is present in built artifact: symbol=${symbol.toPrettyString()} flag=$flag"
   }
 }
 
 internal data class UnknownFlagError(override val symbol: Symbol, override val flag: Flag) :
     ApiError() {
   override fun toString(): String {
-    return "error: unknown flag: symbol=$symbol flag=$flag"
+    return "error: unknown flag: symbol=${symbol.toPrettyString()} flag=$flag"
   }
 }
 
@@ -178,39 +197,40 @@
 }
 
 internal fun parseApiSignature(path: String, input: InputStream): Set<Pair<Symbol, Flag>> {
-  // TODO(334870672): add support for metods
   val output = mutableSetOf<Pair<Symbol, Flag>>()
   val visitor =
       object : BaseItemVisitor() {
         override fun visitClass(cls: ClassItem) {
           getFlagOrNull(cls)?.let { flag ->
-            val symbol = Symbol.create(cls.baselineElementId())
+            val symbol =
+                Symbol.createClass(
+                    cls.baselineElementId(),
+                    cls.superClass()?.baselineElementId(),
+                    cls.allInterfaces()
+                        .map { it.baselineElementId() }
+                        .filter { it != cls.baselineElementId() }
+                        .toSet())
             output.add(Pair(symbol, flag))
           }
         }
 
         override fun visitField(field: FieldItem) {
           getFlagOrNull(field)?.let { flag ->
-            val symbol = Symbol.create(field.baselineElementId())
+            val symbol =
+                Symbol.createField(field.containingClass().baselineElementId(), field.name())
             output.add(Pair(symbol, flag))
           }
         }
 
         override fun visitMethod(method: MethodItem) {
           getFlagOrNull(method)?.let { flag ->
-            val name = buildString {
-              append(method.containingClass().qualifiedName())
-              append(".")
+            val methodName = buildString {
               append(method.name())
               append("(")
-              // TODO(334870672): replace this early return with proper parsing of the command line
-              // arguments, followed by translation to Lname/of/class; + III format
-              if (!method.parameters().isEmpty()) {
-                return
-              }
+              method.parameters().joinTo(this, separator = "") { it.type().internalName() }
               append(")")
             }
-            val symbol = Symbol.create(name)
+            val symbol = Symbol.createMethod(method.containingClass().qualifiedName(), methodName)
             output.add(Pair(symbol, flag))
           }
         }
@@ -251,7 +271,28 @@
         requireNotNull(cls.getAttribute("name")) {
           "Bad XML: <class> element without name attribute"
         }
-    output.add(Symbol.create(className.replace("/", ".")))
+    var superclass: String? = null
+    val interfaces = mutableSetOf<String>()
+    val children = cls.getChildNodes()
+    for (j in 0.rangeUntil(children.getLength())) {
+      val child = children.item(j)
+      when (child.getNodeName()) {
+        "extends" -> {
+          superclass =
+              requireNotNull(child.getAttribute("name")) {
+                "Bad XML: <extends> element without name attribute"
+              }
+        }
+        "implements" -> {
+          val interfaceName =
+              requireNotNull(child.getAttribute("name")) {
+                "Bad XML: <implements> element without name attribute"
+              }
+          interfaces.add(interfaceName)
+        }
+      }
+    }
+    output.add(Symbol.createClass(className, superclass, interfaces))
   }
 
   val fields = document.getElementsByTagName("field")
@@ -266,7 +307,7 @@
         requireNotNull(field.getParentNode()?.getAttribute("name")) {
           "Bad XML: top level <field> element"
         }
-    output.add(Symbol.create("${className.replace("/", ".")}.$fieldName"))
+    output.add(Symbol.createField(className, fieldName))
   }
 
   val methods = document.getElementsByTagName("method")
@@ -281,15 +322,16 @@
     if (methodSignatureParts.size != 3) {
       throw Exception("Bad XML: method signature '$methodSignature'")
     }
-    var (methodName, methodArgs, methodReturnValue) = methodSignatureParts
+    var (methodName, methodArgs, _) = methodSignatureParts
     val packageAndClassName =
         requireNotNull(method.getParentNode()?.getAttribute("name")) {
-          "Bad XML: top level <method> element, or <class> element missing name attribute"
-        }
+              "Bad XML: top level <method> element, or <class> element missing name attribute"
+            }
+            .replace("$", "/")
     if (methodName == "<init>") {
       methodName = packageAndClassName.split("/").last()
     }
-    output.add(Symbol.create("${packageAndClassName.replace("/", ".")}.$methodName($methodArgs)"))
+    output.add(Symbol.createMethod(packageAndClassName, "$methodName($methodArgs)"))
   }
 
   return output
@@ -308,15 +350,50 @@
     flags: Map<Flag, Boolean>,
     symbolsInOutput: Set<Symbol>
 ): Set<ApiError> {
+  fun Set<Symbol>.containsSymbol(symbol: Symbol): Boolean {
+    // trivial case: the symbol is explicitly listed in api-versions.xml
+    if (contains(symbol)) {
+      return true
+    }
+
+    // non-trivial case: the symbol could be part of the surrounding class'
+    // super class or interfaces
+    val (className, memberName) =
+        when (symbol) {
+          is ClassSymbol -> return false
+          is MemberSymbol -> {
+            Pair(symbol.clazz, symbol.member)
+          }
+        }
+    val clazz = find { it is ClassSymbol && it.clazz == className } as? ClassSymbol?
+    if (clazz == null) {
+      return false
+    }
+
+    for (interfaceName in clazz.interfaces) {
+      // createMethod is the same as createField, except it allows parenthesis
+      val interfaceSymbol = Symbol.createMethod(interfaceName, memberName)
+      if (contains(interfaceSymbol)) {
+        return true
+      }
+    }
+
+    if (clazz.superclass != null) {
+      val superclassSymbol = Symbol.createMethod(clazz.superclass, memberName)
+      return containsSymbol(superclassSymbol)
+    }
+
+    return false
+  }
   val errors = mutableSetOf<ApiError>()
   for ((symbol, flag) in flaggedSymbolsInSource) {
     try {
       if (flags.getValue(flag)) {
-        if (!symbolsInOutput.contains(symbol)) {
+        if (!symbolsInOutput.containsSymbol(symbol)) {
           errors.add(EnabledFlaggedApiNotPresentError(symbol, flag))
         }
       } else {
-        if (symbolsInOutput.contains(symbol)) {
+        if (symbolsInOutput.containsSymbol(symbol)) {
           errors.add(DisabledFlaggedApiIsPresentError(symbol, flag))
         }
       }
diff --git a/tools/fs_config/Android.bp b/tools/fs_config/Android.bp
index bd9543a..6aa5289 100644
--- a/tools/fs_config/Android.bp
+++ b/tools/fs_config/Android.bp
@@ -258,3 +258,173 @@
     system_ext_specific: true,
     src: ":group_gen_system_ext",
 }
+
+fs_config_cmd = "$(location fs_config_generator) fsconfig " +
+    "--aid-header $(location :android_filesystem_config_header) " +
+    "--capability-header $(location :linux_capability_header) " +
+    "--out_file $(out) "
+fs_config_cmd_dirs = fs_config_cmd + "--dirs "
+fs_config_cmd_files = fs_config_cmd + "--files "
+
+genrule_defaults {
+    name: "fs_config_defaults",
+    tools: ["fs_config_generator"],
+    srcs: [
+        ":android_filesystem_config_header",
+        ":linux_capability_header",
+        ":target_fs_config_gen",
+    ],
+    out: ["out"],
+}
+
+genrule {
+    name: "fs_config_dirs_system_gen",
+    defaults: ["fs_config_defaults"],
+    cmd: fs_config_cmd_dirs +
+        "--partition system " +
+        "--all-partitions vendor,oem,odm,vendor_dlkm,odm_dlkm,system_dlkm " +
+        "$(locations :target_fs_config_gen)",
+}
+
+prebuilt_etc {
+    name: "fs_config_dirs_system",
+    filename: "fs_config_dirs",
+    src: ":fs_config_dirs_system_gen",
+}
+
+genrule {
+    name: "fs_config_files_system_gen",
+    defaults: ["fs_config_defaults"],
+    cmd: fs_config_cmd_files +
+        "--partition system " +
+        "--all-partitions vendor,oem,odm,vendor_dlkm,odm_dlkm,system_dlkm " +
+        "$(locations :target_fs_config_gen)",
+}
+
+prebuilt_etc {
+    name: "fs_config_files_system",
+    filename: "fs_config_files",
+    src: ":fs_config_files_system_gen",
+}
+
+genrule {
+    name: "fs_config_dirs_system_ext_gen",
+    defaults: ["fs_config_defaults"],
+    cmd: fs_config_cmd_dirs +
+        "--partition system_ext " +
+        "$(locations :target_fs_config_gen)",
+}
+
+prebuilt_etc {
+    name: "fs_config_dirs_system_ext",
+    filename: "fs_config_dirs",
+    src: ":fs_config_dirs_system_ext_gen",
+    system_ext_specific: true,
+}
+
+genrule {
+    name: "fs_config_files_system_ext_gen",
+    defaults: ["fs_config_defaults"],
+    cmd: fs_config_cmd_files +
+        "--partition system_ext " +
+        "$(locations :target_fs_config_gen)",
+}
+
+prebuilt_etc {
+    name: "fs_config_files_system_ext",
+    filename: "fs_config_files",
+    src: ":fs_config_files_system_ext_gen",
+    system_ext_specific: true,
+}
+
+genrule {
+    name: "fs_config_dirs_product_gen",
+    defaults: ["fs_config_defaults"],
+    cmd: fs_config_cmd_dirs +
+        "--partition product " +
+        "$(locations :target_fs_config_gen)",
+}
+
+prebuilt_etc {
+    name: "fs_config_dirs_product",
+    filename: "fs_config_dirs",
+    src: ":fs_config_dirs_product_gen",
+    product_specific: true,
+}
+
+genrule {
+    name: "fs_config_files_product_gen",
+    defaults: ["fs_config_defaults"],
+    cmd: fs_config_cmd_files +
+        "--partition product " +
+        "$(locations :target_fs_config_gen)",
+}
+
+prebuilt_etc {
+    name: "fs_config_files_product",
+    filename: "fs_config_files",
+    src: ":fs_config_files_product_gen",
+    product_specific: true,
+}
+
+genrule {
+    name: "fs_config_dirs_vendor_gen",
+    defaults: ["fs_config_defaults"],
+    cmd: fs_config_cmd_dirs +
+        "--partition vendor " +
+        "$(locations :target_fs_config_gen)",
+}
+
+prebuilt_etc {
+    name: "fs_config_dirs_vendor",
+    filename: "fs_config_dirs",
+    src: ":fs_config_dirs_vendor_gen",
+    vendor: true,
+}
+
+genrule {
+    name: "fs_config_files_vendor_gen",
+    defaults: ["fs_config_defaults"],
+    cmd: fs_config_cmd_files +
+        "--partition vendor " +
+        "$(locations :target_fs_config_gen)",
+}
+
+prebuilt_etc {
+    name: "fs_config_files_vendor",
+    filename: "fs_config_files",
+    src: ":fs_config_files_vendor_gen",
+    vendor: true,
+}
+
+genrule {
+    name: "fs_config_dirs_odm_gen",
+    defaults: ["fs_config_defaults"],
+    cmd: fs_config_cmd_dirs +
+        "--partition odm " +
+        "$(locations :target_fs_config_gen)",
+}
+
+prebuilt_etc {
+    name: "fs_config_dirs_odm",
+    filename: "fs_config_dirs",
+    src: ":fs_config_dirs_odm_gen",
+    device_specific: true,
+}
+
+genrule {
+    name: "fs_config_files_odm_gen",
+    defaults: ["fs_config_defaults"],
+    cmd: fs_config_cmd_files +
+        "--partition odm " +
+        "$(locations :target_fs_config_gen)",
+}
+
+prebuilt_etc {
+    name: "fs_config_files_odm",
+    filename: "fs_config_files",
+    src: ":fs_config_files_odm_gen",
+    device_specific: true,
+}
+
+// TODO(jiyong): add fs_config for oem, system_dlkm, vendor_dlkm, odm_dlkm partitions
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index c36c3aa..e4c3626 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -24,23 +24,8 @@
 $(error Using $(TARGET_DEVICE_DIR)/android_filesystem_config.h is deprecated, please use TARGET_FS_CONFIG_GEN instead)
 endif
 
-system_android_filesystem_config := system/core/libcutils/include/private/android_filesystem_config.h
-system_capability_header := bionic/libc/kernel/uapi/linux/capability.h
-
-# Use snapshots if exist
-vendor_android_filesystem_config := $(strip \
-  $(if $(filter-out current,$(BOARD_VNDK_VERSION)), \
-    $(SOONG_VENDOR_$(BOARD_VNDK_VERSION)_SNAPSHOT_DIR)/include/$(system_android_filesystem_config)))
-ifeq (,$(wildcard $(vendor_android_filesystem_config)))
-vendor_android_filesystem_config := $(system_android_filesystem_config)
-endif
-
-vendor_capability_header := $(strip \
-  $(if $(filter-out current,$(BOARD_VNDK_VERSION)), \
-    $(SOONG_VENDOR_$(BOARD_VNDK_VERSION)_SNAPSHOT_DIR)/include/$(system_capability_header)))
-ifeq (,$(wildcard $(vendor_capability_header)))
-vendor_capability_header := $(system_capability_header)
-endif
+android_filesystem_config := system/core/libcutils/include/private/android_filesystem_config.h
+capability_header := bionic/libc/kernel/uapi/linux/capability.h
 
 # List of supported vendor, oem, odm, vendor_dlkm, odm_dlkm, and system_dlkm Partitions
 fs_config_generate_extra_partition_list := $(strip \
@@ -85,58 +70,6 @@
 include $(BUILD_PHONY_PACKAGE)
 
 ##################################
-# Generate the system_ext/etc/fs_config_dirs binary file for the target if the
-# system_ext partition is generated. Add fs_config_dirs or fs_config_dirs_system_ext
-# to PRODUCT_PACKAGES in the device make file to enable.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := fs_config_dirs_system_ext
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_SYSTEM_EXTIMAGE)$(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),_fs_config_dirs_system_ext)
-include $(BUILD_PHONY_PACKAGE)
-
-##################################
-# Generate the system_ext/etc/fs_config_files binary file for the target if the
-# system_ext partition is generated. Add fs_config_files or fs_config_files_system_ext
-# to PRODUCT_PACKAGES in the device make file to enable.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := fs_config_files_system_ext
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_SYSTEM_EXTIMAGE)$(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),_fs_config_files_system_ext)
-include $(BUILD_PHONY_PACKAGE)
-
-##################################
-# Generate the product/etc/fs_config_dirs binary file for the target if the
-# product partition is generated. Add fs_config_dirs or fs_config_dirs_product
-# to PRODUCT_PACKAGES in the device make file to enable.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := fs_config_dirs_product
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_PRODUCTIMAGE)$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),_fs_config_dirs_product)
-include $(BUILD_PHONY_PACKAGE)
-
-##################################
-# Generate the product/etc/fs_config_files binary file for the target if the
-# product partition is generated. Add fs_config_files or fs_config_files_product
-# to PRODUCT_PACKAGES in the device make file to enable.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := fs_config_files_product
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_PRODUCTIMAGE)$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),_fs_config_files_product)
-include $(BUILD_PHONY_PACKAGE)
-
-##################################
 # Generate the <p>/etc/fs_config_dirs binary files for all enabled partitions
 # excluding /system, /system_ext and /product. Add fs_config_dirs_nonsystem to
 # PRODUCT_PACKAGES in the device make file to enable.
@@ -146,7 +79,7 @@
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),_fs_config_dirs_$(t))
+LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),fs_config_dirs_$(t))
 include $(BUILD_PHONY_PACKAGE)
 
 ##################################
@@ -159,122 +92,9 @@
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),_fs_config_files_$(t))
+LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),fs_config_files_$(t))
 include $(BUILD_PHONY_PACKAGE)
 
-##################################
-# Generate the system/etc/fs_config_dirs binary file for the target
-# Add fs_config_dirs or fs_config_dirs_system to PRODUCT_PACKAGES in
-# the device make file to enable
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := fs_config_dirs_system
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := ETC
-LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header)
-$(LOCAL_BUILT_MODULE): PRIVATE_PARTITION_LIST := $(fs_config_generate_extra_partition_list)
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header)
-	@mkdir -p $(dir $@)
-	$< fsconfig \
-	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
-	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
-	   --partition system \
-	   --all-partitions "$(subst $(space),$(comma),$(PRIVATE_PARTITION_LIST))" \
-	   --dirs \
-	   --out_file $@ \
-	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
-
-##################################
-# Generate the system/etc/fs_config_files binary file for the target
-# Add fs_config_files or fs_config_files_system to PRODUCT_PACKAGES in
-# the device make file to enable
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := fs_config_files_system
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := ETC
-LOCAL_INSTALLED_MODULE_STEM := fs_config_files
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header)
-$(LOCAL_BUILT_MODULE): PRIVATE_PARTITION_LIST := $(fs_config_generate_extra_partition_list)
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header)
-	@mkdir -p $(dir $@)
-	$< fsconfig \
-	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
-	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
-	   --partition system \
-	   --all-partitions "$(subst $(space),$(comma),$(PRIVATE_PARTITION_LIST))" \
-	   --files \
-	   --out_file $@ \
-	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
-
-ifneq ($(filter vendor,$(fs_config_generate_extra_partition_list)),)
-##################################
-# Generate the vendor/etc/fs_config_dirs binary file for the target
-# Add fs_config_dirs or fs_config_dirs_nonsystem to PRODUCT_PACKAGES
-# in the device make file to enable
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := _fs_config_dirs_vendor
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := ETC
-LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header)
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header)
-	@mkdir -p $(dir $@)
-	$< fsconfig \
-	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
-	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
-	   --partition vendor \
-	   --dirs \
-	   --out_file $@ \
-	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
-
-##################################
-# Generate the vendor/etc/fs_config_files binary file for the target
-# Add fs_config_files or fs_config_files_nonsystem to PRODUCT_PACKAGES
-# in the device make file to enable
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := _fs_config_files_vendor
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := ETC
-LOCAL_INSTALLED_MODULE_STEM := fs_config_files
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header)
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header)
-	@mkdir -p $(dir $@)
-	$< fsconfig \
-	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
-	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
-	   --partition vendor \
-	   --files \
-	   --out_file $@ \
-	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
-
-endif
-
 ifneq ($(filter oem,$(fs_config_generate_extra_partition_list)),)
 ##################################
 # Generate the oem/etc/fs_config_dirs binary file for the target
@@ -282,7 +102,7 @@
 # in the device make file to enable
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := _fs_config_dirs_oem
+LOCAL_MODULE := fs_config_dirs_oem
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
@@ -290,10 +110,10 @@
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/etc
 include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header)
 $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header)
 	@mkdir -p $(dir $@)
 	$< fsconfig \
 	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
@@ -309,7 +129,7 @@
 # in the device make file to enable
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := _fs_config_files_oem
+LOCAL_MODULE := fs_config_files_oem
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
@@ -317,10 +137,10 @@
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/etc
 include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header)
 $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header)
 	@mkdir -p $(dir $@)
 	$< fsconfig \
 	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
@@ -332,63 +152,6 @@
 
 endif
 
-ifneq ($(filter odm,$(fs_config_generate_extra_partition_list)),)
-##################################
-# Generate the odm/etc/fs_config_dirs binary file for the target
-# Add fs_config_dirs or fs_config_dirs_nonsystem to PRODUCT_PACKAGES
-# in the device make file to enable
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := _fs_config_dirs_odm
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := ETC
-LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
-LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header)
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header)
-	@mkdir -p $(dir $@)
-	$< fsconfig \
-	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
-	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
-	   --partition odm \
-	   --dirs \
-	   --out_file $@ \
-	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
-
-##################################
-# Generate the odm/etc/fs_config_files binary file for the target
-# Add fs_config_files or fs_config_files_nonsystem to PRODUCT_PACKAGES
-# in the device make file to enable
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := _fs_config_files_odm
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := ETC
-LOCAL_INSTALLED_MODULE_STEM := fs_config_files
-LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header)
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header)
-	@mkdir -p $(dir $@)
-	$< fsconfig \
-	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
-	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
-	   --partition odm \
-	   --files \
-	   --out_file $@ \
-	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
-
-endif
-
 ifneq ($(filter vendor_dlkm,$(fs_config_generate_extra_partition_list)),)
 ##################################
 # Generate the vendor_dlkm/etc/fs_config_dirs binary file for the target
@@ -396,7 +159,7 @@
 # the device make file to enable
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := _fs_config_dirs_vendor_dlkm
+LOCAL_MODULE := fs_config_dirs_vendor_dlkm
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
@@ -404,10 +167,10 @@
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_DLKM)/etc
 include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header)
 $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header)
 	@mkdir -p $(dir $@)
 	$< fsconfig \
 	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
@@ -423,7 +186,7 @@
 # the device make file to enable
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := _fs_config_files_vendor_dlkm
+LOCAL_MODULE := fs_config_files_vendor_dlkm
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
@@ -431,10 +194,10 @@
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_DLKM)/etc
 include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header)
 $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header)
 	@mkdir -p $(dir $@)
 	$< fsconfig \
 	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
@@ -453,7 +216,7 @@
 # in the device make file to enable
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := _fs_config_dirs_odm_dlkm
+LOCAL_MODULE := fs_config_dirs_odm_dlkm
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
@@ -461,10 +224,10 @@
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_ODM_DLKM)/etc
 include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header)
 $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header)
 	@mkdir -p $(dir $@)
 	$< fsconfig \
 	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
@@ -480,7 +243,7 @@
 # in the device make file to enable
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := _fs_config_files_odm_dlkm
+LOCAL_MODULE := fs_config_files_odm_dlkm
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
@@ -488,10 +251,10 @@
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_ODM_DLKM)/etc
 include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header)
 $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header)
 	@mkdir -p $(dir $@)
 	$< fsconfig \
 	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
@@ -510,7 +273,7 @@
 # in the device make file to enable
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := _fs_config_dirs_system_dlkm
+LOCAL_MODULE := fs_config_dirs_system_dlkm
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
@@ -518,10 +281,10 @@
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_DLKM)/etc
 include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header)
 $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header)
 	@mkdir -p $(dir $@)
 	$< fsconfig \
 	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
@@ -537,7 +300,7 @@
 # in the device make file to enable
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := _fs_config_files_system_dlkm
+LOCAL_MODULE := fs_config_files_system_dlkm
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
@@ -545,10 +308,10 @@
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_DLKM)/etc
 include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header)
 $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header)
 	@mkdir -p $(dir $@)
 	$< fsconfig \
 	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
@@ -560,118 +323,6 @@
 
 endif
 
-ifneq ($(BOARD_USES_PRODUCTIMAGE)$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),)
-##################################
-# Generate the product/etc/fs_config_dirs binary file for the target
-# Add fs_config_dirs or fs_config_dirs_product to PRODUCT_PACKAGES in
-# the device make file to enable
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := _fs_config_dirs_product
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := ETC
-LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
-LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header)
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header)
-	@mkdir -p $(dir $@)
-	$< fsconfig \
-	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
-	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
-	   --partition product \
-	   --dirs \
-	   --out_file $@ \
-	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
-
-##################################
-# Generate the product/etc/fs_config_files binary file for the target
-# Add fs_config_files or fs_config_files_product to PRODUCT_PACKAGES in
-# the device make file to enable
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := _fs_config_files_product
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := ETC
-LOCAL_INSTALLED_MODULE_STEM := fs_config_files
-LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header)
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header)
-	@mkdir -p $(dir $@)
-	$< fsconfig \
-	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
-	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
-	   --partition product \
-	   --files \
-	   --out_file $@ \
-	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
-endif
-
-ifneq ($(BOARD_USES_SYSTEM_EXTIMAGE)$(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),)
-##################################
-# Generate the system_ext/etc/fs_config_dirs binary file for the target
-# Add fs_config_dirs or fs_config_dirs_system_ext to PRODUCT_PACKAGES in
-# the device make file to enable
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := _fs_config_dirs_system_ext
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := ETC
-LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
-LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_EXT)/etc
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header)
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header)
-	@mkdir -p $(dir $@)
-	$< fsconfig \
-	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
-	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
-	   --partition system_ext \
-	   --dirs \
-	   --out_file $@ \
-	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
-
-##################################
-# Generate the system_ext/etc/fs_config_files binary file for the target
-# Add fs_config_files or fs_config_files_system_ext to PRODUCT_PACKAGES in
-# the device make file to enable
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := _fs_config_files_system_ext
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := ETC
-LOCAL_INSTALLED_MODULE_STEM := fs_config_files
-LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_EXT)/etc
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header)
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header)
-	@mkdir -p $(dir $@)
-	$< fsconfig \
-	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
-	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
-	   --partition system_ext \
-	   --files \
-	   --out_file $@ \
-	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
-endif
-
-system_android_filesystem_config :=
-system_capability_header :=
+android_filesystem_config :=
+capability_header :=
 fs_config_generate_extra_partition_list :=
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 9385f0c..9b134f2 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -632,7 +632,6 @@
     data: [
         "testdata/**/*",
         ":com.android.apex.compressed.v1",
-        ":com.android.apex.compressed.v1_original",
         ":com.android.apex.vendor.foo.with_vintf"
     ],
     target: {
diff --git a/tools/releasetools/create_brick_ota.py b/tools/releasetools/create_brick_ota.py
index 9e040a5..bf50f71 100644
--- a/tools/releasetools/create_brick_ota.py
+++ b/tools/releasetools/create_brick_ota.py
@@ -45,10 +45,10 @@
   partitions_to_wipe = PARTITIONS_TO_WIPE
   if extra_wipe_partitions is not None:
     partitions_to_wipe = PARTITIONS_TO_WIPE + extra_wipe_partitions.split(",")
-    ota_metadata = ["ota-type=BRICK", "post-timestamp=9999999999",
-                    "pre-device=" + product_name]
-    if serialno is not None:
-        ota_metadata.append("serialno=" + serialno)
+  ota_metadata = ["ota-type=BRICK", "post-timestamp=9999999999",
+                  "pre-device=" + product_name]
+  if serialno is not None:
+      ota_metadata.append("serialno=" + serialno)
   # recovery requiers product name to be a | separated list
   product_name = product_name.replace(",", "|")
   with zipfile.ZipFile(output_path, "w") as zfp:
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index 048a497..81b53dc 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -1111,9 +1111,10 @@
       relative_path = path.removeprefix(input_dir).removeprefix("/")
       if not Fnmatch(relative_path, UNZIP_PATTERN):
         continue
-      if filename.endswith(".prop") or filename == "prop.default" or "/etc/vintf/" in relative_path:
-        target_path = os.path.join(
-            output_dir, relative_path)
-        os.makedirs(os.path.dirname(target_path), exist_ok=True)
-        shutil.copy(path, target_path)
+      target_path = os.path.join(
+          output_dir, relative_path)
+      if os.path.exists(target_path):
+        continue
+      os.makedirs(os.path.dirname(target_path), exist_ok=True)
+      shutil.copy(path, target_path)
   return output_dir
diff --git a/tools/whichgit b/tools/whichgit
index 8cf84f5..55c8c6f 100755
--- a/tools/whichgit
+++ b/tools/whichgit
@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 
 import argparse
+import itertools
 import os
 import subprocess
 import sys
@@ -10,15 +11,34 @@
                         check=True, capture_output=True, text=True).stdout.strip()
 
 
+def get_all_modules():
+  product_out = subprocess.run(["build/soong/soong_ui.bash", "--dumpvar-mode", "--abs", "PRODUCT_OUT"],
+                                check=True, capture_output=True, text=True).stdout.strip()
+  result = subprocess.run(["cat", product_out + "/all_modules.txt"], check=True, capture_output=True, text=True)
+  return result.stdout.strip().split("\n")
+
+
+def batched(iterable, n):
+  # introduced in itertools 3.12, could delete once that's universally available
+  if n < 1:
+    raise ValueError('n must be at least one')
+  it = iter(iterable)
+  while batch := tuple(itertools.islice(it, n)):
+    yield batch
+
+
 def get_sources(modules):
-  result = subprocess.run(["./prebuilts/build-tools/linux-x86/bin/ninja", "-f",
-                           "out/combined-" + os.environ["TARGET_PRODUCT"] + ".ninja",
-                           "-t", "inputs", "-d", ] + modules,
-                          stderr=subprocess.STDOUT, stdout=subprocess.PIPE, check=False, text=True)
-  if result.returncode != 0:
-    sys.stderr.write(result.stdout)
-    sys.exit(1)
-  return set([f for f in result.stdout.split("\n") if not f.startswith("out/")])
+  sources = set()
+  for module_group in batched(modules, 40_000):
+    result = subprocess.run(["./prebuilts/build-tools/linux-x86/bin/ninja", "-f",
+                            "out/combined-" + os.environ["TARGET_PRODUCT"] + ".ninja",
+                            "-t", "inputs", "-d", ] + list(module_group),
+                            stderr=subprocess.STDOUT, stdout=subprocess.PIPE, check=False, text=True)
+    if result.returncode != 0:
+      sys.stderr.write(result.stdout)
+      sys.exit(1)
+    sources.update(set([f for f in result.stdout.split("\n") if not f.startswith("out/")]))
+  return sources
 
 
 def m_nothing():
@@ -57,13 +77,13 @@
   # Argument parsing
   ap = argparse.ArgumentParser(description="List the required git projects for the given modules")
   ap.add_argument("--products", nargs="*",
-                  help="The TARGET_PRODUCT to check. If not provided just uses whatever has"
-                        + " already been built")
+                  help="One or more TARGET_PRODUCT to check, or \"*\" for all. If not provided"
+                        + "just uses whatever has already been built")
   ap.add_argument("--variants", nargs="*",
                   help="The TARGET_BUILD_VARIANTS to check. If not provided just uses whatever has"
                         + " already been built, or eng if --products is supplied")
   ap.add_argument("--modules", nargs="*",
-                  help="The build modules to check, or droid if not supplied")
+                  help="The build modules to check, or \"*\" for all, or droid if not supplied")
   ap.add_argument("--why", nargs="*",
                   help="Also print the input files used in these projects, or \"*\" for all")
   ap.add_argument("--unused", help="List the unused git projects for the given modules rather than"
@@ -72,22 +92,33 @@
 
   modules = args.modules if args.modules else ["droid"]
 
+  match args.products:
+    case ["*"]:
+      products = get_build_var("all_named_products").split(" ")
+    case _:
+      products = args.products
+
   # Get the list of sources for all of the requested build combos
-  if not args.products and not args.variants:
+  if not products and not args.variants:
+    m_nothing()
+    if args.modules == ["*"]:
+      modules = get_all_modules()
     sources = get_sources(modules)
   else:
-    if not args.products:
+    if not products:
       sys.stderr.write("Error: --products must be supplied if --variants is supplied")
       sys.exit(1)
     sources = set()
     build_num = 1
-    for product in args.products:
+    for product in products:
       os.environ["TARGET_PRODUCT"] = product
       variants = args.variants if args.variants else ["user", "userdebug", "eng"]
       for variant in variants:
-        sys.stderr.write(f"Analyzing build {build_num} of {len(args.products)*len(variants)}\r")
+        sys.stderr.write(f"Analyzing build {build_num} of {len(products)*len(variants)}\r")
         os.environ["TARGET_BUILD_VARIANT"] = variant
         m_nothing()
+        if args.modules == ["*"]:
+          modules = get_all_modules()
         sources.update(get_sources(modules))
         build_num += 1
     sys.stderr.write("\n\n")