Merge "Add metadata to module info about whether the module came from soong or make" into main
diff --git a/ci/build_test_suites.py b/ci/build_test_suites.py
index addad15..cdcba5a 100644
--- a/ci/build_test_suites.py
+++ b/ci/build_test_suites.py
@@ -84,46 +84,16 @@
     packaging_commands_getters = []
     # In order to roll optimizations out differently between test suites and
     # device builds, we have separate flags.
-    if (
-        'test_suites_zip_test_discovery'
+    enable_discovery = ('test_suites_zip_test_discovery'
         in self.build_context.enabled_build_features
         and not self.args.device_build
     ) or (
         'device_zip_test_discovery'
         in self.build_context.enabled_build_features
         and self.args.device_build
-    ):
-      preliminary_build_targets = self._collect_preliminary_build_targets()
-    else:
-      preliminary_build_targets = self._legacy_collect_preliminary_build_targets()
-
-      # Keep reporting metrics when test discovery is disabled.
-      # To be removed once test discovery is fully rolled out.
-      optimization_rationale = ''
-      test_discovery_zip_regexes = set()
-      try:
-        test_discovery_zip_regexes = self._get_test_discovery_zip_regexes()
-        logging.info(f'Discovered test discovery regexes: {test_discovery_zip_regexes}')
-      except test_discovery_agent.TestDiscoveryError as e:
-        optimization_rationale = e.message
-        logging.warning(f'Unable to perform test discovery: {optimization_rationale}')
-
-      for target in self.args.extra_targets:
-        if optimization_rationale:
-          get_metrics_agent().report_unoptimized_target(target, optimization_rationale)
-          continue
-        if target in REQUIRED_BUILD_TARGETS:
-          get_metrics_agent().report_unoptimized_target(target, 'Required build target.')
-          continue
-        try:
-          regex = r'\b(%s.*)\b' % re.escape(target)
-          if any(re.search(regex, opt) for opt in test_discovery_zip_regexes):
-            get_metrics_agent().report_unoptimized_target(target, 'Test artifact used.')
-            continue
-          get_metrics_agent().report_optimized_target(target)
-        except Exception as e:
-          logging.error(f'unable to parse test discovery output: {repr(e)}')
-          get_metrics_agent().report_unoptimized_target(target, f'Error in parsing test discovery output for {target}: {repr(e)}')
+    )
+    logging.info(f'Discovery mode is enabled= {enable_discovery}')
+    preliminary_build_targets = self._collect_preliminary_build_targets(enable_discovery)
 
     for target in preliminary_build_targets:
       target_optimizer_getter = self.target_optimizations.get(target, None)
@@ -141,7 +111,7 @@
 
     return BuildPlan(build_targets, packaging_commands_getters)
 
-  def _collect_preliminary_build_targets(self):
+  def _collect_preliminary_build_targets(self, enable_discovery: bool):
     build_targets = set()
     try:
       test_discovery_zip_regexes = self._get_test_discovery_zip_regexes()
@@ -159,6 +129,10 @@
         build_targets.add(target)
         get_metrics_agent().report_unoptimized_target(target, 'Required build target.')
         continue
+      # If nothing is discovered without error, that means nothing is needed.
+      if not test_discovery_zip_regexes:
+        get_metrics_agent().report_optimized_target(target)
+        continue
 
       regex = r'\b(%s.*)\b' % re.escape(target)
       for opt in test_discovery_zip_regexes:
@@ -166,13 +140,18 @@
           if re.search(regex, opt):
             get_metrics_agent().report_unoptimized_target(target, 'Test artifact used.')
             build_targets.add(target)
-            continue
+            # proceed to next target evaluation
+            break
           get_metrics_agent().report_optimized_target(target)
         except Exception as e:
           # In case of exception report as unoptimized
           build_targets.add(target)
           get_metrics_agent().report_unoptimized_target(target, f'Error in parsing test discovery output for {target}: {repr(e)}')
           logging.error(f'unable to parse test discovery output: {repr(e)}')
+          break
+    # If discovery is not enabled, return the original list
+    if not enable_discovery:
+      return self._legacy_collect_preliminary_build_targets()
 
     return build_targets
 
diff --git a/core/Makefile b/core/Makefile
index 3ba931c..5a7ddd2 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -169,7 +169,7 @@
             $(eval $(call copy-xml-file-checked,$(_src),$(_fulldest))),\
             $(if $(and $(filter %.jar,$(_dest)),$(filter $(basename $(notdir $(_dest))),$(PRODUCT_LOADED_BY_PRIVILEGED_MODULES))),\
                 $(eval $(call copy-and-uncompress-dexs,$(_src),$(_fulldest))), \
-                $(if $(filter init%rc,$(notdir $(_dest)))$(filter %/etc/init,$(dir $(_dest))),\
+                $(if $(filter init%rc,$(notdir $(_dest)))$(filter %/etc/init/,$(dir $(_dest))),\
                     $(eval $(call copy-init-script-file-checked,$(_src),$(_fulldest))),\
                     $(if $(and $(filter true,$(check_elf_prebuilt_product_copy_files)), \
                                $(filter bin lib lib64,$(subst /,$(space),$(_dest)))), \
@@ -885,11 +885,6 @@
 $(call declare-1p-target,$(SOONG_TO_CONVERT),build)
 $(call dist-for-goals,droidcore-unbundled,$(SOONG_TO_CONVERT))
 
-$(PRODUCT_OUT)/product_packages.txt:
-	@rm -f $@
-	echo "" > $@
-	$(foreach x,$(PRODUCT_PACKAGES),echo $(x) >> $@$(newline))
-
 MK2BP_CATALOG_SCRIPT := build/make/tools/mk2bp_catalog.py
 PRODUCT_PACKAGES_TXT := $(PRODUCT_OUT)/product_packages.txt
 MK2BP_REMAINING_HTML := $(PRODUCT_OUT)/mk2bp_remaining.html
@@ -2403,7 +2398,7 @@
 $(hide) echo "root_dir=$(TARGET_ROOT_OUT)" >> $(1)
 $(if $(filter true,$(PRODUCT_USE_DYNAMIC_PARTITION_SIZE)),\
     $(hide) echo "use_dynamic_partition_size=true" >> $(1))
-$(if $(COPY_IMAGES_FOR_TARGET_FILES_ZIP),\
+$(if $(USE_FIXED_TIMESTAMP_IMG_FILES)$(COPY_IMAGES_FOR_TARGET_FILES_ZIP),\
     $(hide) echo "use_fixed_timestamp=true" >> $(1))
 $(if $(3),$(hide) $(foreach kv,$(3),echo "$(kv)" >> $(1);))
 $(hide) sort -o $(1) $(1)
@@ -3558,7 +3553,7 @@
   PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(systemimage_intermediates)/file_list.txt) \
-          $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) $(TARGET_OUT) --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) $(TARGET_OUT) \
           || ( mkdir -p $${DIST_DIR}; \
                cp $(INSTALLED_FILES_FILE) $${DIST_DIR}/installed-files-rescued.txt; \
                exit 1 )
@@ -3709,7 +3704,7 @@
   PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(userdataimage_intermediates)/file_list.txt) \
-          $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt \
           $(INSTALLED_USERDATAIMAGE_TARGET) $(TARGET_OUT)
   $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE))
 endef
@@ -3771,7 +3766,7 @@
   PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(cacheimage_intermediates)/file_list.txt) \
-          $(TARGET_OUT_CACHE) $(cacheimage_intermediates)/cache_image_info.txt --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(TARGET_OUT_CACHE) $(cacheimage_intermediates)/cache_image_info.txt \
           $(INSTALLED_CACHEIMAGE_TARGET) $(TARGET_OUT)
   $(call assert-max-image-size,$(INSTALLED_CACHEIMAGE_TARGET),$(BOARD_CACHEIMAGE_PARTITION_SIZE))
 endef
@@ -3858,7 +3853,7 @@
   PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(systemotherimage_intermediates)/file_list.txt) \
-          $(TARGET_OUT_SYSTEM_OTHER) $(systemotherimage_intermediates)/system_other_image_info.txt --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(TARGET_OUT_SYSTEM_OTHER) $(systemotherimage_intermediates)/system_other_image_info.txt \
           $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) $(TARGET_OUT)
   $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
 endef
@@ -3964,7 +3959,7 @@
   PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(vendorimage_intermediates)/file_list.txt) \
-          $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt \
           $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT)
   $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET) $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_VENDORIMAGE_PARTITION_SIZE))
 endef
@@ -4052,7 +4047,7 @@
   PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(productimage_intermediates)/file_list.txt) \
-          $(TARGET_OUT_PRODUCT) $(productimage_intermediates)/product_image_info.txt --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(TARGET_OUT_PRODUCT) $(productimage_intermediates)/product_image_info.txt \
           $(INSTALLED_PRODUCTIMAGE_TARGET) $(TARGET_OUT)
   $(call assert-max-image-size,$(INSTALLED_PRODUCTIMAGE_TARGET),$(BOARD_PRODUCTIMAGE_PARTITION_SIZE))
 endef
@@ -4121,7 +4116,7 @@
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(system_extimage_intermediates)/file_list.txt) \
           $(TARGET_OUT_SYSTEM_EXT) \
-          $(system_extimage_intermediates)/system_ext_image_info.txt --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(system_extimage_intermediates)/system_ext_image_info.txt \
           $(INSTALLED_SYSTEM_EXTIMAGE_TARGET) \
           $(TARGET_OUT)
   $(call assert-max-image-size,$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET),$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE))
@@ -4211,7 +4206,7 @@
   PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(odmimage_intermediates)/file_list.txt) \
-          $(TARGET_OUT_ODM) $(odmimage_intermediates)/odm_image_info.txt --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(TARGET_OUT_ODM) $(odmimage_intermediates)/odm_image_info.txt \
           $(INSTALLED_ODMIMAGE_TARGET) $(TARGET_OUT)
   $(call assert-max-image-size,$(INSTALLED_ODMIMAGE_TARGET),$(BOARD_ODMIMAGE_PARTITION_SIZE))
 endef
@@ -4280,7 +4275,7 @@
   PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(vendor_dlkmimage_intermediates)/file_list.txt) \
-          $(TARGET_OUT_VENDOR_DLKM) $(vendor_dlkmimage_intermediates)/vendor_dlkm_image_info.txt --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(TARGET_OUT_VENDOR_DLKM) $(vendor_dlkmimage_intermediates)/vendor_dlkm_image_info.txt \
           $(INSTALLED_VENDOR_DLKMIMAGE_TARGET) $(TARGET_OUT)
   $(call assert-max-image-size,$(INSTALLED_VENDOR_DLKMIMAGE_TARGET),$(BOARD_VENDOR_DLKMIMAGE_PARTITION_SIZE))
 endef
@@ -4349,7 +4344,7 @@
   PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(odm_dlkmimage_intermediates)/file_list.txt) \
-          $(TARGET_OUT_ODM_DLKM) $(odm_dlkmimage_intermediates)/odm_dlkm_image_info.txt --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(TARGET_OUT_ODM_DLKM) $(odm_dlkmimage_intermediates)/odm_dlkm_image_info.txt \
           $(INSTALLED_ODM_DLKMIMAGE_TARGET) $(TARGET_OUT)
   $(call assert-max-image-size,$(INSTALLED_ODM_DLKMIMAGE_TARGET),$(BOARD_ODM_DLKMIMAGE_PARTITION_SIZE))
 endef
@@ -4420,7 +4415,7 @@
   PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
       $(BUILD_IMAGE) \
           $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(system_dlkmimage_intermediates)/file_list.txt) \
-          $(TARGET_OUT_SYSTEM_DLKM) $(system_dlkmimage_intermediates)/system_dlkm_image_info.txt --build_datetime_file $(BUILD_DATETIME_FILE) \
+          $(TARGET_OUT_SYSTEM_DLKM) $(system_dlkmimage_intermediates)/system_dlkm_image_info.txt \
           $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET) $(TARGET_OUT)
   $(call assert-max-image-size,$(INSTALLED_SYSTEM_DLKMIMAGE_TARGET),$(BOARD_SYSTEM_DLKMIMAGE_PARTITION_SIZE))
 endef
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index f17d8c6..862fcb2 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -82,6 +82,7 @@
 $(call soong_config_set_bool,chre,chre_dedicated_transport_channel_enabled,$(if $(filter true,$(CHRE_DEDICATED_TRANSPORT_CHANNEL_ENABLED)),true,false))
 $(call soong_config_set_bool,chre,chre_log_atom_extension_enabled,$(if $(filter true,$(CHRE_LOG_ATOM_EXTENSION_ENABLED)),true,false))
 $(call soong_config_set_bool,chre,building_vendor_image,$(if $(filter true,$(BUILDING_VENDOR_IMAGE)),true,false))
+$(call soong_config_set_bool,chre,chre_usf_daemon_enabled,$(if $(filter true,$(CHRE_USF_DAEMON_ENABLED)),true,false))
 
 ifdef TARGET_BOARD_AUTO
   $(call add_soong_config_var_value, ANDROID, target_board_auto, $(TARGET_BOARD_AUTO))
@@ -127,6 +128,8 @@
 
 ifdef PRODUCT_CGROUP_V2_SYS_APP_ISOLATION_ENABLED
 $(call add_soong_config_var_value,ANDROID,cgroup_v2_sys_app_isolation,$(PRODUCT_CGROUP_V2_SYS_APP_ISOLATION_ENABLED))
+else
+$(call add_soong_config_var_value,ANDROID,cgroup_v2_sys_app_isolation,true)
 endif
 
 $(call add_soong_config_var_value,ANDROID,release_avf_allow_preinstalled_apps,$(RELEASE_AVF_ALLOW_PREINSTALLED_APPS))
diff --git a/core/config.mk b/core/config.mk
index 20ebeeb..454c0e5 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -1333,3 +1333,58 @@
 $(error SYSTEM_OPTIMIZE_JAVA must be enabled when FULL_SYSTEM_OPTIMIZE_JAVA is enabled)
 endif
 endif
+
+# -----------------------------------------------------------------
+# Define fingerprint, thumbprint, and version tags for the current build
+#
+# BUILD_VERSION_TAGS is a comma-separated list of tags chosen by the device
+# implementer that further distinguishes the build. It's basically defined
+# by the device implementer. Here, we are adding a mandatory tag that
+# identifies the signing config of the build.
+BUILD_VERSION_TAGS := $(BUILD_VERSION_TAGS)
+ifeq ($(TARGET_BUILD_TYPE),debug)
+  BUILD_VERSION_TAGS += debug
+endif
+# The "test-keys" tag marks builds signed with the old test keys,
+# which are available in the SDK.  "dev-keys" marks builds signed with
+# non-default dev keys (usually private keys from a vendor directory).
+# Both of these tags will be removed and replaced with "release-keys"
+# when the target-files is signed in a post-build step.
+ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/make/target/product/security/testkey)
+BUILD_KEYS := test-keys
+else
+BUILD_KEYS := dev-keys
+endif
+BUILD_VERSION_TAGS += $(BUILD_KEYS)
+BUILD_VERSION_TAGS := $(subst $(space),$(comma),$(sort $(BUILD_VERSION_TAGS)))
+
+# BUILD_FINGERPRINT is used used to uniquely identify the combined build and
+# product; used by the OTA server.
+ifeq (,$(strip $(BUILD_FINGERPRINT)))
+  BUILD_FINGERPRINT := $(PRODUCT_BRAND)/$(TARGET_PRODUCT)/$(TARGET_DEVICE):$(PLATFORM_VERSION)/$(BUILD_ID)/$(BUILD_NUMBER_FROM_FILE):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)
+endif
+
+BUILD_FINGERPRINT_FILE := $(PRODUCT_OUT)/build_fingerprint.txt
+ifneq (,$(shell mkdir -p $(PRODUCT_OUT) && echo $(BUILD_FINGERPRINT) >$(BUILD_FINGERPRINT_FILE).tmp && (if ! cmp -s $(BUILD_FINGERPRINT_FILE).tmp $(BUILD_FINGERPRINT_FILE); then mv $(BUILD_FINGERPRINT_FILE).tmp $(BUILD_FINGERPRINT_FILE); else rm $(BUILD_FINGERPRINT_FILE).tmp; fi) && grep " " $(BUILD_FINGERPRINT_FILE)))
+  $(error BUILD_FINGERPRINT cannot contain spaces: "$(file <$(BUILD_FINGERPRINT_FILE))")
+endif
+BUILD_FINGERPRINT_FROM_FILE := $$(cat $(BUILD_FINGERPRINT_FILE))
+# unset it for safety.
+BUILD_FINGERPRINT :=
+
+# BUILD_THUMBPRINT is used to uniquely identify the system build; used by the
+# OTA server. This purposefully excludes any product-specific variables.
+ifeq (,$(strip $(BUILD_THUMBPRINT)))
+  BUILD_THUMBPRINT := $(PLATFORM_VERSION)/$(BUILD_ID)/$(BUILD_NUMBER_FROM_FILE):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)
+endif
+
+BUILD_THUMBPRINT_FILE := $(PRODUCT_OUT)/build_thumbprint.txt
+ifeq ($(strip $(HAS_BUILD_NUMBER)),true)
+$(BUILD_THUMBPRINT_FILE): $(BUILD_NUMBER_FILE)
+endif
+ifneq (,$(shell mkdir -p $(PRODUCT_OUT) && echo $(BUILD_THUMBPRINT) >$(BUILD_THUMBPRINT_FILE) && grep " " $(BUILD_THUMBPRINT_FILE)))
+  $(error BUILD_THUMBPRINT cannot contain spaces: "$(file <$(BUILD_THUMBPRINT_FILE))")
+endif
+# unset it for safety.
+BUILD_THUMBPRINT_FILE :=
+BUILD_THUMBPRINT :=
diff --git a/core/main.mk b/core/main.mk
index 624df49..25580e2 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1759,10 +1759,6 @@
 	@echo $(sort $(patsubst $(PRODUCT_OUT)/%,%,$(filter $(PRODUCT_OUT)/%,$(modules_to_install)))) | tr -s ' ' '\n'
 	@echo Successfully dumped product target file list.
 
-.PHONY: nothing
-nothing:
-	@echo Successfully read the makefiles.
-
 .PHONY: tidy_only
 tidy_only:
 	@echo Successfully make tidy_only.
diff --git a/core/misc_prebuilt_internal.mk b/core/misc_prebuilt_internal.mk
index a562207..b14b9ce 100644
--- a/core/misc_prebuilt_internal.mk
+++ b/core/misc_prebuilt_internal.mk
@@ -25,7 +25,7 @@
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
-ifneq ($(filter init%rc,$(notdir $(LOCAL_INSTALLED_MODULE)))$(filter %/etc/init,$(dir $(LOCAL_INSTALLED_MODULE))),)
+ifneq ($(filter init%rc,$(notdir $(LOCAL_INSTALLED_MODULE)))$(filter %/etc/init/,$(dir $(LOCAL_INSTALLED_MODULE))),)
   $(eval $(call copy-init-script-file-checked,$(my_prebuilt_src_file),$(LOCAL_BUILT_MODULE)))
 else
 $(LOCAL_BUILT_MODULE) : $(my_prebuilt_src_file)
diff --git a/core/packaging/flags.mk b/core/packaging/flags.mk
index fd9dc9b..a371a00 100644
--- a/core/packaging/flags.mk
+++ b/core/packaging/flags.mk
@@ -109,10 +109,17 @@
 define generate-partition-aconfig-storage-file
 $(eval $(strip $(1)): PRIVATE_OUT := $(strip $(1)))
 $(eval $(strip $(1)): PRIVATE_IN := $(strip $(9)))
+
+ifneq (,$(RELEASE_FINGERPRINT_ACONFIG_PACKAGES))
+STORAGE_FILE_VERSION := 2
+else
+STORAGE_FILE_VERSION := 1
+endif
+
 $(strip $(1)): $(ACONFIG) $(strip $(9))
 	mkdir -p $$(dir $$(PRIVATE_OUT))
 	$$(if $$(PRIVATE_IN), \
-		$$(ACONFIG) create-storage --container $(10) --file package_map --out $$(PRIVATE_OUT) \
+		$$(ACONFIG) create-storage --container $(10) --file package_map --out $$(PRIVATE_OUT) --version $$(STORAGE_FILE_VERSION) \
 			$$(addprefix --cache ,$$(PRIVATE_IN)), \
 	)
 	touch $$(PRIVATE_OUT)
@@ -121,7 +128,7 @@
 $(strip $(2)): $(ACONFIG) $(strip $(9))
 	mkdir -p $$(dir $$(PRIVATE_OUT))
 	$$(if $$(PRIVATE_IN), \
-		$$(ACONFIG) create-storage --container $(10) --file flag_map --out $$(PRIVATE_OUT) \
+		$$(ACONFIG) create-storage --container $(10) --file flag_map --out $$(PRIVATE_OUT) --version $$(STORAGE_FILE_VERSION) \
 			$$(addprefix --cache ,$$(PRIVATE_IN)), \
 	)
 	touch $$(PRIVATE_OUT)
@@ -130,7 +137,7 @@
 $(strip $(3)): $(ACONFIG) $(strip $(9))
 	mkdir -p $$(dir $$(PRIVATE_OUT))
 	$$(if $$(PRIVATE_IN), \
-		$$(ACONFIG) create-storage --container $(10) --file flag_val --out $$(PRIVATE_OUT) \
+		$$(ACONFIG) create-storage --container $(10) --file flag_val --out $$(PRIVATE_OUT) --version $$(STORAGE_FILE_VERSION) \
 		$$(addprefix --cache ,$$(PRIVATE_IN)), \
 	)
 	touch $$(PRIVATE_OUT)
@@ -139,7 +146,7 @@
 $(strip $(4)): $(ACONFIG) $(strip $(9))
 	mkdir -p $$(dir $$(PRIVATE_OUT))
 	$$(if $$(PRIVATE_IN), \
-		$$(ACONFIG) create-storage --container $(10) --file flag_info --out $$(PRIVATE_OUT) \
+		$$(ACONFIG) create-storage --container $(10) --file flag_info --out $$(PRIVATE_OUT) --version $$(STORAGE_FILE_VERSION) \
 		$$(addprefix --cache ,$$(PRIVATE_IN)), \
 	)
 	touch $$(PRIVATE_OUT)
diff --git a/core/soong_config.mk b/core/soong_config.mk
index ace025e..ba59f5e 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -370,6 +370,7 @@
   $(firstword $(OVERRIDE_ENABLE_UFFD_GC) $(PRODUCT_ENABLE_UFFD_GC) default)
 $(call add_json_str, EnableUffdGc, $(_config_enable_uffd_gc))
 _config_enable_uffd_gc :=
+$(call add_json_str, BoardKernelVersion, $(BOARD_KERNEL_VERSION))
 
 $(call add_json_list, DeviceFrameworkCompatibilityMatrixFile, $(DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE))
 $(call add_json_list, DeviceProductCompatibilityMatrixFile, $(DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE))
@@ -440,6 +441,7 @@
   $(call add_json_str, BoardPrebuiltBootimage, $(BOARD_PREBUILT_BOOT_IMAGE))
   $(call add_json_str, BoardPrebuiltInitBootimage, $(BOARD_PREBUILT_INIT_BOOT_IMAGE))
   $(call add_json_str, BoardBootimagePartitionSize, $(BOARD_BOOTIMAGE_PARTITION_SIZE))
+  $(call add_json_str, BoardVendorBootimagePartitionSize, $(BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE))
   $(call add_json_str, BoardInitBootimagePartitionSize, $(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE))
   $(call add_json_str, BoardBootHeaderVersion, $(BOARD_BOOT_HEADER_VERSION))
   $(call add_json_str, TargetKernelPath, $(TARGET_KERNEL_PATH))
diff --git a/core/sysprop.mk b/core/sysprop.mk
index c532dd1..e4f994f 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -160,61 +160,6 @@
 $(call declare-1p-target,$(2))
 endef
 
-# -----------------------------------------------------------------
-# Define fingerprint, thumbprint, and version tags for the current build
-#
-# BUILD_VERSION_TAGS is a comma-separated list of tags chosen by the device
-# implementer that further distinguishes the build. It's basically defined
-# by the device implementer. Here, we are adding a mandatory tag that
-# identifies the signing config of the build.
-BUILD_VERSION_TAGS := $(BUILD_VERSION_TAGS)
-ifeq ($(TARGET_BUILD_TYPE),debug)
-  BUILD_VERSION_TAGS += debug
-endif
-# The "test-keys" tag marks builds signed with the old test keys,
-# which are available in the SDK.  "dev-keys" marks builds signed with
-# non-default dev keys (usually private keys from a vendor directory).
-# Both of these tags will be removed and replaced with "release-keys"
-# when the target-files is signed in a post-build step.
-ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/make/target/product/security/testkey)
-BUILD_KEYS := test-keys
-else
-BUILD_KEYS := dev-keys
-endif
-BUILD_VERSION_TAGS += $(BUILD_KEYS)
-BUILD_VERSION_TAGS := $(subst $(space),$(comma),$(sort $(BUILD_VERSION_TAGS)))
-
-# BUILD_FINGERPRINT is used used to uniquely identify the combined build and
-# product; used by the OTA server.
-ifeq (,$(strip $(BUILD_FINGERPRINT)))
-  BUILD_FINGERPRINT := $(PRODUCT_BRAND)/$(TARGET_PRODUCT)/$(TARGET_DEVICE):$(PLATFORM_VERSION)/$(BUILD_ID)/$(BUILD_NUMBER_FROM_FILE):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)
-endif
-
-BUILD_FINGERPRINT_FILE := $(PRODUCT_OUT)/build_fingerprint.txt
-ifneq (,$(shell mkdir -p $(PRODUCT_OUT) && echo $(BUILD_FINGERPRINT) >$(BUILD_FINGERPRINT_FILE).tmp && (if ! cmp -s $(BUILD_FINGERPRINT_FILE).tmp $(BUILD_FINGERPRINT_FILE); then mv $(BUILD_FINGERPRINT_FILE).tmp $(BUILD_FINGERPRINT_FILE); else rm $(BUILD_FINGERPRINT_FILE).tmp; fi) && grep " " $(BUILD_FINGERPRINT_FILE)))
-  $(error BUILD_FINGERPRINT cannot contain spaces: "$(file <$(BUILD_FINGERPRINT_FILE))")
-endif
-BUILD_FINGERPRINT_FROM_FILE := $$(cat $(BUILD_FINGERPRINT_FILE))
-# unset it for safety.
-BUILD_FINGERPRINT :=
-
-# BUILD_THUMBPRINT is used to uniquely identify the system build; used by the
-# OTA server. This purposefully excludes any product-specific variables.
-ifeq (,$(strip $(BUILD_THUMBPRINT)))
-  BUILD_THUMBPRINT := $(PLATFORM_VERSION)/$(BUILD_ID)/$(BUILD_NUMBER_FROM_FILE):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)
-endif
-
-BUILD_THUMBPRINT_FILE := $(PRODUCT_OUT)/build_thumbprint.txt
-ifeq ($(strip $(HAS_BUILD_NUMBER)),true)
-$(BUILD_THUMBPRINT_FILE): $(BUILD_NUMBER_FILE)
-endif
-ifneq (,$(shell mkdir -p $(PRODUCT_OUT) && echo $(BUILD_THUMBPRINT) >$(BUILD_THUMBPRINT_FILE) && grep " " $(BUILD_THUMBPRINT_FILE)))
-  $(error BUILD_THUMBPRINT cannot contain spaces: "$(file <$(BUILD_THUMBPRINT_FILE))")
-endif
-# unset it for safety.
-BUILD_THUMBPRINT_FILE :=
-BUILD_THUMBPRINT :=
-
 KNOWN_OEM_THUMBPRINT_PROPERTIES := \
     ro.product.brand \
     ro.product.name \
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index 294cb57..d9f6150 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -97,12 +97,28 @@
 coverage_out := $(HOST_OUT)/cts-api-coverage
 api_map_out := $(HOST_OUT)/cts-api-map
 
-cts_jar_files := $(api_map_out)/api_map_files.txt
+cts_jar_files := $(api_map_out)/cts_jar_files.txt
+cts_interactive_jar_files := $(api_map_out)/cts_interactive_jar_files.txt
+cts_all_jar_files := $(api_map_out)/cts_all_jar_files.txt
+
 $(cts_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts.API_MAP_FILES))
 $(cts_jar_files):
 	mkdir -p $(dir $@)
 	echo $(PRIVATE_API_MAP_FILES) > $@
 
+$(cts_interactive_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts-interactive.API_MAP_FILES))
+$(cts_interactive_jar_files): $(SOONG_ANDROID_CTS_VERIFIER_APP_LIST)
+	mkdir -p $(dir $@)
+	cp $< $@
+	echo $(PRIVATE_API_MAP_FILES) >> $@
+
+$(cts_all_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts.API_MAP_FILES) \
+                                                      $(COMPATIBILITY.cts-interactive.API_MAP_FILES))
+$(cts_all_jar_files): $(SOONG_ANDROID_CTS_VERIFIER_APP_LIST)
+	mkdir -p $(dir $@)
+	cp $< $@
+	echo $(PRIVATE_API_MAP_FILES) >> $@
+
 api_xml_description := $(TARGET_OUT_COMMON_INTERMEDIATES)/api.xml
 
 napi_text_description := cts/tools/cts-api-coverage/etc/ndk-api.xml
@@ -124,13 +140,14 @@
 cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description) $(napi_xml_description)
 cts_system_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(system_api_xml_description)
 
-cts-api-xml-api-map-report := $(api_map_out)/api-map.xml
-cts-api-html-api-map-report := $(api_map_out)/api-map.html
-cts-system-api-xml-api-map-report := $(api_map_out)/system-api-map.xml
-cts-system-api-html-api-map-report := $(api_map_out)/system-api-map.html
+cts-system-api-map-xml-report := $(api_map_out)/cts-system-api-map.xml
+cts-interactive-system-api-map-xml-report := $(api_map_out)/cts-interactive-system-api-map.xml
+cts-combined-system-api-map-xml-report := $(api_map_out)/cts-combined-system-api-map.xml
+cts-combined-system-api-map-html-report := $(api_map_out)/cts-combined-system-api-map.html
 
 cts_system_api_map_dependencies := $(cts_api_map_exe) $(system_api_xml_description) $(cts_jar_files)
-cts_api_map_dependencies := $(cts_api_map_exe) $(api_xml_description) $(cts_jar_files)
+cts_interactive_system_api_map_dependencies := $(cts_api_map_exe) $(system_api_xml_description) $(cts_interactive_jar_files)
+cts_combined_system_api_map_dependencies := $(cts_api_map_exe) $(system_api_xml_description) $(cts_all_jar_files)
 
 android_cts_zip := $(HOST_OUT)/cts/android-cts.zip
 cts_verifier_apk := $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk
@@ -210,45 +227,42 @@
 .PHONY: cts-coverage-report-all cts-api-coverage
 cts-coverage-report-all: cts-test-coverage cts-verifier-coverage cts-combined-coverage cts-combined-xml-coverage
 
-$(cts-system-api-xml-api-map-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-system-api-xml-api-map-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-system-api-xml-api-map-report): PRIVATE_JAR_FILES := $(cts_jar_files)
-$(cts-system-api-xml-api-map-report) : $(android_cts_zip) $(cts_system_api_map_dependencies) | $(ACP)
+$(cts-system-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-system-api-map-xml-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
+$(cts-system-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_jar_files)
+$(cts-system-api-map-xml-report) : $(android_cts_zip) $(cts_system_api_map_dependencies) | $(ACP)
 	$(call generate-api-map-report-cts,"CTS System API MAP Report - XML",\
 			$(PRIVATE_JAR_FILES),xml)
 
-$(cts-system-api-html-api-map-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-system-api-html-api-map-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-system-api-html-api-map-report): PRIVATE_JAR_FILES := $(cts_jar_files)
-$(cts-system-api-html-api-map-report) : $(android_cts_zip) $(cts_system_api_map_dependencies) | $(ACP)
-	$(call generate-api-map-report-cts,"CTS System API MAP Report - HTML",\
-			$(PRIVATE_JAR_FILES),html)
-
-$(cts-api-xml-api-map-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-api-xml-api-map-report): PRIVATE_API_XML_DESC := $(api_xml_description)
-$(cts-api-xml-api-map-report): PRIVATE_JAR_FILES := $(cts_jar_files)
-$(cts-api-xml-api-map-report) : $(android_cts_zip) $(cts_api_map_dependencies) | $(ACP)
-	$(call generate-api-map-report-cts,"CTS API MAP Report - XML",\
+$(cts-interactive-system-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-interactive-system-api-map-xml-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
+$(cts-interactive-system-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_interactive_jar_files)
+$(cts-interactive-system-api-map-xml-report) : $(verifier_zip) $(cts_interactive_system_api_map_dependencies) | $(ACP)
+	$(call generate-api-map-report-cts,"CTS Interactive System API MAP Report - XML",\
 			$(PRIVATE_JAR_FILES),xml)
 
-$(cts-api-html-api-map-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-api-html-api-map-report): PRIVATE_API_XML_DESC := $(api_xml_description)
-$(cts-api-html-api-map-report): PRIVATE_JAR_FILES := $(cts_jar_files)
-$(cts-api-html-api-map-report) : $(android_cts_zip) $(cts_api_map_dependencies) | $(ACP)
-	$(call generate-api-map-report-cts,"CTS API MAP Report - HTML",\
+$(cts-combined-system-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-combined-system-api-map-xml-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
+$(cts-combined-system-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
+$(cts-combined-system-api-map-xml-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_system_api_map_dependencies) | $(ACP)
+	$(call generate-api-map-report-cts,"CTS Combined System API MAP Report - XML",\
+			$(PRIVATE_JAR_FILES),xml)
+
+$(cts-combined-system-api-map-html-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-combined-system-api-map-html-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
+$(cts-combined-system-api-map-html-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
+$(cts-combined-system-api-map-html-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_system_api_map_dependencies) | $(ACP)
+	$(call generate-api-map-report-cts,"CTS Combined System API MAP Report - HTML",\
 			$(PRIVATE_JAR_FILES),html)
 
-.PHONY: cts-system-api-xml-api-map
-cts-system-api-xml-api-map : $(cts-system-api-xml-api-map-report)
+.PHONY: cts-system-api-map-xml
+cts-system-api-map-xml : $(cts-system-api-map-xml-report)
 
-.PHONY: cts-system-api-html-api-map
-cts-system-api-html-api-map : $(cts-system-api-html-api-map-report)
+.PHONY: cts-interactive-system-api-map-xml
+cts-interactive-system-api-map-xml: $(cts-interactive-system-api-map-xml-report)
 
-.PHONY: cts-api-xml-api-map
-cts-api-xml-api-map : $(cts-api-xml-api-map-report)
-
-.PHONY: cts-api-html-api-map
-cts-api-html-api-map : $(cts-api-html-api-map-report)
+.PHONY: cts-combined-system-api-map-xml
+cts-combined-system-api-map-xml : $(cts-combined-system-api-map-xml-report)
 
 .PHONY: cts-api-map-all
 
@@ -268,15 +282,13 @@
 ALL_TARGETS.$(cts-combined-xml-coverage-report).META_LIC:=$(module_license_metadata)
 
 # Put the test api map report in the dist dir if "cts-api-map-all" is among the build goals.
-$(call dist-for-goals, cts-api-map-all, $(cts-system-api-xml-api-map-report):cts-system-api-xml-api-map-report.xml)
-$(call dist-for-goals, cts-api-map-all, $(cts-system-api-html-api-map-report):cts-system-api-html-api-map-report.html)
-$(call dist-for-goals, cts-api-map-all, $(cts-api-xml-api-map-report):cts-api-xml-api-map-report.xml)
-$(call dist-for-goals, cts-api-map-all, $(cts-api-html-api-map-report):cts-api-html-api-map-report.html)
+$(call dist-for-goals, cts-api-map-all, $(cts-combined-system-api-map-xml-report):cts-api-map-report.xml)
+$(call dist-for-goals, cts-api-map-all, $(cts-combined-system-api-map-html-report):cts-api-map-report.html)
 
-ALL_TARGETS.$(cts-system-api-xml-api-map-report).META_LIC:=$(module_license_metadata)
-ALL_TARGETS.$(cts-system-api-html-api-map-report).META_LIC:=$(module_license_metadata)
-ALL_TARGETS.$(cts-api-xml-api-map-report).META_LIC:=$(module_license_metadata)
-ALL_TARGETS.$(cts-api-html-api-map-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-system-api-map-xml-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-interactive-system-api-map-xml-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-combined-system-api-map-xml-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-combined-system-api-map-html-report).META_LIC:=$(module_license_metadata)
 
 # Arguments;
 #  1 - Name of the report printed out on the screen
@@ -301,18 +313,19 @@
 # Reset temp vars
 cts_api_coverage_dependencies :=
 cts_system_api_coverage_dependencies :=
-cts_api_map_dependencies :=
 cts_system_api_map_dependencies :=
+cts_interactive_system_api_map_dependencies :=
+cts_combined_system_api_map_dependencies :=
 cts-combined-coverage-report :=
 cts-combined-xml-coverage-report :=
 cts-verifier-coverage-report :=
 cts-test-coverage-report :=
 cts-system-api-coverage-report :=
 cts-system-api-xml-coverage-report :=
-cts-api-xml-api-map-report :=
-cts-api-html-api-map-report :=
-cts-system-api-xml-api-map-report :=
-cts-system-api-html-api-map-report :=
+cts-system-api-map-xml-report :=
+cts-interactive-system-api-map-xml-report :=
+cts-combined-system-api-map-xml-report :=
+cts-combined-system-api-map-html-report :=
 api_xml_description :=
 api_text_description :=
 system_api_xml_description :=
diff --git a/core/tasks/general-tests-shared-libs.mk b/core/tasks/general-tests-shared-libs.mk
deleted file mode 100644
index 2405140..0000000
--- a/core/tasks/general-tests-shared-libs.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-# 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.
-
-.PHONY: general-tests-shared-libs
-
-intermediates_dir := $(call intermediates-dir-for,PACKAGING,general-tests-shared-libs)
-
-general_tests_shared_libs_zip := $(PRODUCT_OUT)/general-tests_host-shared-libs.zip
-
-# Filter shared entries between general-tests and device-tests's HOST_SHARED_LIBRARY.FILES,
-# to avoid warning about overriding commands.
-my_host_shared_lib_for_general_tests := \
-  $(foreach m,$(filter $(COMPATIBILITY.device-tests.HOST_SHARED_LIBRARY.FILES),\
-	   $(COMPATIBILITY.general-tests.HOST_SHARED_LIBRARY.FILES)),$(call word-colon,2,$(m)))
-my_general_tests_shared_lib_files := \
-  $(filter-out $(COMPATIBILITY.device-tests.HOST_SHARED_LIBRARY.FILES),\
-	 $(COMPATIBILITY.general-tests.HOST_SHARED_LIBRARY.FILES))
-
-my_host_shared_lib_for_general_tests += $(call copy-many-files,$(my_general_tests_shared_lib_files))
-
-$(general_tests_shared_libs_zip) : PRIVATE_INTERMEDIATES_DIR := $(intermediates_dir)
-$(general_tests_shared_libs_zip) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_general_tests)
-$(general_tests_shared_libs_zip) : PRIVATE_general_host_shared_libs_zip := $(general_tests_shared_libs_zip)
-$(general_tests_shared_libs_zip) : $(my_host_shared_lib_for_general_tests) $(SOONG_ZIP)
-	rm -rf $(PRIVATE_INTERMEDIATES_DIR)
-	mkdir -p $(PRIVATE_INTERMEDIATES_DIR) $(PRIVATE_INTERMEDIATES_DIR)/tools
-	$(hide) for shared_lib in $(PRIVATE_HOST_SHARED_LIBS); do \
-	  echo $$shared_lib >> $(PRIVATE_INTERMEDIATES_DIR)/shared-libs.list; \
-	done
-	grep $(HOST_OUT_TESTCASES) $(PRIVATE_INTERMEDIATES_DIR)/shared-libs.list > $(PRIVATE_INTERMEDIATES_DIR)/host-shared-libs.list || true
-	$(SOONG_ZIP) -d -o $(PRIVATE_general_host_shared_libs_zip) \
-	  -P host -C $(HOST_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/host-shared-libs.list
-
-general-tests-shared-libs: $(general_tests_shared_libs_zip)
-$(call dist-for-goals, general-tests-shared-libs, $(general_tests_shared_libs_zip))
-
-$(call declare-1p-container,$(general_tests_shared_libs_zip),)
-$(call declare-container-license-deps,$(general_tests_shared_libs_zip),$(my_host_shared_lib_for_general_tests),$(PRODUCT_OUT)/:/)
-
-intermediates_dir :=
-general_tests_shared_libs_zip :=
diff --git a/core/tasks/general-tests.mk b/core/tasks/general-tests.mk
index 1901ed5..dcfcfad 100644
--- a/core/tasks/general-tests.mk
+++ b/core/tasks/general-tests.mk
@@ -27,19 +27,61 @@
 # Create an artifact to include all test config files in general-tests.
 general_tests_configs_zip := $(PRODUCT_OUT)/general-tests_configs.zip
 
-general_tests_shared_libs_zip := $(PRODUCT_OUT)/general-tests_host-shared-libs.zip
+# Filter shared entries between general-tests and device-tests's HOST_SHARED_LIBRARY.FILES,
+# to avoid warning about overriding commands.
+my_host_shared_lib_for_general_tests := \
+  $(foreach m,$(filter $(COMPATIBILITY.device-tests.HOST_SHARED_LIBRARY.FILES),\
+	   $(COMPATIBILITY.general-tests.HOST_SHARED_LIBRARY.FILES)),$(call word-colon,2,$(m)))
+my_general_tests_shared_lib_files := \
+  $(filter-out $(COMPATIBILITY.device-tests.HOST_SHARED_LIBRARY.FILES),\
+	 $(COMPATIBILITY.general-tests.HOST_SHARED_LIBRARY.FILES))
 
-$(general_tests_zip) : $(general_tests_shared_libs_zip)
+my_host_shared_lib_for_general_tests += $(call copy-many-files,$(my_general_tests_shared_lib_files))
+
+my_host_shared_lib_symlinks := \
+    $(filter $(COMPATIBILITY.host-unit-tests.SYMLINKS),\
+	$(COMPATIBILITY.general-tests.SYMLINKS))
+
+my_general_tests_symlinks := \
+    $(filter-out $(COMPATIBILITY.camera-hal-tests.SYMLINKS),\
+    $(filter-out $(COMPATIBILITY.host-unit-tests.SYMLINKS),\
+	 $(COMPATIBILITY.general-tests.SYMLINKS)))
+
+my_symlinks_for_general_tests := $(foreach f,$(my_general_tests_symlinks),\
+	$(strip $(eval _cmf_tuple := $(subst :, ,$(f))) \
+	$(eval _cmf_dep := $(word 1,$(_cmf_tuple))) \
+	$(eval _cmf_src := $(word 2,$(_cmf_tuple))) \
+	$(eval _cmf_dest := $(word 3,$(_cmf_tuple))) \
+	$(call symlink-file,$(_cmf_dep),$(_cmf_src),$(_cmf_dest)) \
+	$(_cmf_dest)))
+
+# In this one directly take the overlap into the zip since we can't rewrite rules
+my_symlinks_for_general_tests += $(foreach f,$(my_host_shared_lib_symlinks),\
+        $(strip $(eval _cmf_tuple := $(subst :, ,$(f))) \
+        $(eval _cmf_dep := $(word 1,$(_cmf_tuple))) \
+        $(eval _cmf_src := $(word 2,$(_cmf_tuple))) \
+        $(eval _cmf_dest := $(word 3,$(_cmf_tuple))) \
+        $(_cmf_dest)))
+
 $(general_tests_zip) : PRIVATE_general_tests_list_zip := $(general_tests_list_zip)
 $(general_tests_zip) : .KATI_IMPLICIT_OUTPUTS := $(general_tests_list_zip) $(general_tests_configs_zip)
 $(general_tests_zip) : PRIVATE_TOOLS := $(general_tests_tools)
 $(general_tests_zip) : PRIVATE_INTERMEDIATES_DIR := $(intermediates_dir)
+$(general_tests_zip) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_general_tests)
+$(general_tests_zip) : PRIVATE_SYMLINKS := $(my_symlinks_for_general_tests)
 $(general_tests_zip) : PRIVATE_general_tests_configs_zip := $(general_tests_configs_zip)
-$(general_tests_zip) : $(COMPATIBILITY.general-tests.FILES) $(COMPATIBILITY.general-tests.SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES) $(general_tests_tools) $(SOONG_ZIP)
+$(general_tests_zip) : $(COMPATIBILITY.general-tests.FILES) $(my_host_shared_lib_for_general_tests) $(COMPATIBILITY.general-tests.SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES) $(general_tests_tools) $(my_symlinks_for_general_tests) $(SOONG_ZIP)
 	rm -rf $(PRIVATE_INTERMEDIATES_DIR)
 	rm -f $@ $(PRIVATE_general_tests_list_zip)
 	mkdir -p $(PRIVATE_INTERMEDIATES_DIR) $(PRIVATE_INTERMEDIATES_DIR)/tools
 	echo $(sort $(COMPATIBILITY.general-tests.FILES) $(COMPATIBILITY.general-tests.SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES)) | tr " " "\n" > $(PRIVATE_INTERMEDIATES_DIR)/list
+	for symlink in $(PRIVATE_SYMLINKS); do \
+	  echo $$symlink >> $(PRIVATE_INTERMEDIATES_DIR)/list; \
+	done
+	$(hide) for shared_lib in $(PRIVATE_HOST_SHARED_LIBS); do \
+	  echo $$shared_lib >> $(PRIVATE_INTERMEDIATES_DIR)/shared-libs.list; \
+	done
+	grep $(HOST_OUT_TESTCASES) $(PRIVATE_INTERMEDIATES_DIR)/shared-libs.list > $(PRIVATE_INTERMEDIATES_DIR)/host-shared-libs.list || true
 	grep $(HOST_OUT_TESTCASES) $(PRIVATE_INTERMEDIATES_DIR)/list > $(PRIVATE_INTERMEDIATES_DIR)/host.list || true
 	grep $(TARGET_OUT_TESTCASES) $(PRIVATE_INTERMEDIATES_DIR)/list > $(PRIVATE_INTERMEDIATES_DIR)/target.list || true
 	grep -e .*\\.config$$ $(PRIVATE_INTERMEDIATES_DIR)/host.list > $(PRIVATE_INTERMEDIATES_DIR)/host-test-configs.list || true
@@ -49,6 +91,7 @@
 	  -P host -C $(PRIVATE_INTERMEDIATES_DIR) -D $(PRIVATE_INTERMEDIATES_DIR)/tools \
 	  -P host -C $(HOST_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/host.list \
 	  -P target -C $(PRODUCT_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/target.list \
+	  -P host -C $(HOST_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/host-shared-libs.list \
 	  -sha256
 	$(SOONG_ZIP) -d -o $(PRIVATE_general_tests_configs_zip) \
 	  -P host -C $(HOST_OUT) -l $(PRIVATE_INTERMEDIATES_DIR)/host-test-configs.list \
@@ -69,3 +112,8 @@
 general_tests_list_zip :=
 general_tests_configs_zip :=
 general_tests_shared_libs_zip :=
+my_host_shared_lib_for_general_tests :=
+my_symlinks_for_general_tests :=
+my_general_tests_shared_lib_files :=
+my_general_tests_symlinks :=
+my_host_shared_lib_symlinks :=
diff --git a/target/board/generic_64bitonly_x86_64/device.mk b/target/board/generic_64bitonly_x86_64/device.mk
index bb49057..5edf5e0 100644
--- a/target/board/generic_64bitonly_x86_64/device.mk
+++ b/target/board/generic_64bitonly_x86_64/device.mk
@@ -17,8 +17,3 @@
 ifdef NET_ETH0_STARTONBOOT
   PRODUCT_PROPERTY_OVERRIDES += net.eth0.startonboot=1
 endif
-
-# Ensure we package the BIOS files too.
-PRODUCT_HOST_PACKAGES += \
-    bios.bin \
-    vgabios-cirrus.bin \
diff --git a/target/board/generic_x86/device.mk b/target/board/generic_x86/device.mk
index 60f0cc3..27fb310 100644
--- a/target/board/generic_x86/device.mk
+++ b/target/board/generic_x86/device.mk
@@ -17,8 +17,3 @@
 ifdef NET_ETH0_STARTONBOOT
   PRODUCT_VENDOR_PROPERTIES += net.eth0.startonboot=1
 endif
-
-# Ensure we package the BIOS files too.
-PRODUCT_HOST_PACKAGES += \
-	bios.bin \
-	vgabios-cirrus.bin \
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 52498ee..b3b58d3 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -489,6 +489,7 @@
 
 PRODUCT_SYSTEM_PROPERTIES += debug.atrace.tags.enableflags=0
 PRODUCT_SYSTEM_PROPERTIES += persist.traced.enable=1
+PRODUCT_SYSTEM_PROPERTIES += ro.surface_flinger.game_default_frame_rate_override=60
 
 # Include kernel configs.
 PRODUCT_PACKAGES += \
diff --git a/target/product/full_x86.mk b/target/product/full_x86.mk
index 07f6472..a1b71ca 100644
--- a/target/product/full_x86.mk
+++ b/target/product/full_x86.mk
@@ -32,11 +32,6 @@
   PRODUCT_VENDOR_PROPERTIES += net.eth0.startonboot=1
 endif
 
-# Ensure we package the BIOS files too.
-PRODUCT_HOST_PACKAGES += \
-	bios.bin \
-	vgabios-cirrus.bin \
-
 # Enable dynamic partition size
 PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
 
diff --git a/target/product/fullmte.mk b/target/product/fullmte.mk
index b622496..fed66e7 100644
--- a/target/product/fullmte.mk
+++ b/target/product/fullmte.mk
@@ -20,7 +20,7 @@
 # For more details, see:
 # https://source.android.com/docs/security/test/memory-safety/arm-mte
 ifeq ($(filter memtag_heap,$(SANITIZE_TARGET)),)
-  SANITIZE_TARGET := $(strip $(SANITIZE_TARGET) memtag_heap memtag_stack)
+  SANITIZE_TARGET := $(strip $(SANITIZE_TARGET) memtag_heap memtag_stack memtag_globals)
   SANITIZE_TARGET_DIAG := $(strip $(SANITIZE_TARGET_DIAG) memtag_heap)
 endif
 PRODUCT_PRODUCT_PROPERTIES += persist.arm64.memtag.default=sync
diff --git a/target/product/generic/Android.bp b/target/product/generic/Android.bp
index 1b585d8..314816d 100644
--- a/target/product/generic/Android.bp
+++ b/target/product/generic/Android.bp
@@ -1,5 +1,4 @@
 generic_rootdirs = [
-    "acct",
     "apex",
     "bootstrap-apex",
     "config",
@@ -347,6 +346,77 @@
 }
 
 android_filesystem_defaults {
+    name: "system_ext_image_defaults",
+    deps: [
+        ///////////////////////////////////////////
+        // base_system_ext
+        ///////////////////////////////////////////
+        "build_flag_system_ext",
+        "fs_config_dirs_system_ext",
+        "fs_config_files_system_ext",
+        "group_system_ext",
+        "passwd_system_ext",
+        "SatelliteClient",
+        "selinux_policy_system_ext",
+        "system_ext_manifest.xml",
+        "system_ext-build.prop",
+        // Base modules when shipping api level is less than or equal to 34
+        "hwservicemanager",
+        "android.hidl.allocator@1.0-service",
+
+        ///////////////////////////////////////////
+        // window_extensions_base
+        ///////////////////////////////////////////
+        "androidx.window.extensions",
+        "androidx.window.sidecar",
+
+        ///////////////////////////////////////////
+        // base_system
+        ///////////////////////////////////////////
+        "charger",
+    ] + select(release_flag("RELEASE_APPFUNCTION_SIDECAR"), {
+        true: [
+            "com.android.extensions.appfunctions",
+            "appfunctions.extension.xml",
+        ],
+        default: [],
+    }),
+}
+
+android_filesystem_defaults {
+    name: "product_image_defaults",
+    deps: [
+        ///////////////////////////////////////////
+        // media_product
+        ///////////////////////////////////////////
+        "webview",
+
+        ///////////////////////////////////////////
+        // base_product
+        ///////////////////////////////////////////
+
+        // Base modules and settings for the product partition.
+        "build_flag_product",
+        "fs_config_dirs_product",
+        "fs_config_files_product",
+        "group_product",
+        "ModuleMetadata",
+        "passwd_product",
+        "product_compatibility_matrix.xml",
+        "product_manifest.xml",
+        "selinux_policy_product",
+        "product-build.prop",
+
+        // AUDIO
+        "frameworks_sounds",
+    ] + select(product_variable("debuggable"), {
+        // Packages included only for eng or userdebug builds, previously debug tagged
+        true: ["adb_keys"],
+        default: [],
+    }),
+}
+
+android_filesystem_defaults {
     name: "system_image_defaults",
     partition_name: "system",
     base_dir: "system",
@@ -471,7 +541,6 @@
         "locksettings", // base_system
         "logcat", // base_system
         "logd", // base_system
-        "logpersist.start",
         "lpdump", // base_system
         "lshal", // base_system
         "make_f2fs", // media_system
@@ -528,7 +597,6 @@
         "sfdo", // base_system
         "sgdisk", // base_system
         "sm", // base_system
-        "snapshotctl", // base_system
         "snapuserd", // base_system
         "storaged", // base_system
         "surfaceflinger", // base_system
@@ -574,6 +642,7 @@
         default: [],
     }) + select(product_variable("debuggable"), {
         true: [
+            "alloctop",
             "adevice_fingerprint",
             "arping",
             "avbctl",
@@ -586,6 +655,7 @@
             "iperf3",
             "iw",
             "layertracegenerator",
+            "logpersist.start",
             "logtagd.rc",
             "ot-cli-ftd",
             "ot-ctl",
@@ -596,6 +666,7 @@
             "sanitizer-status",
             "servicedispatcher",
             "showmap",
+            "snapshotctl",
             "sqlite3",
             "ss",
             "start_with_lockagent",
@@ -912,4 +983,9 @@
         compressor: "lz4hc,9",
         compress_hints: "erofs_compress_hints.txt",
     },
+    deps: [
+        // DO NOT update this list. Instead, update the system_image_defaults to
+        // sync with the base_system.mk
+        "logpersist.start", // cf only
+    ],
 }
diff --git a/target/product/gsi/Android.bp b/target/product/gsi/Android.bp
index 9e8946d..c6fc021 100644
--- a/target/product/gsi/Android.bp
+++ b/target/product/gsi/Android.bp
@@ -83,7 +83,11 @@
 
 android_system_image {
     name: "android_gsi",
-    defaults: ["system_image_defaults"],
+    defaults: [
+        "system_image_defaults",
+        "system_ext_image_defaults",
+        "product_image_defaults",
+    ],
     symlinks: gsi_symlinks,
     dirs: ["cache"],
     deps: [
@@ -107,28 +111,6 @@
         "system_ext_userdebug_plat_sepolicy.cil",
 
         ///////////////////////////////////////////
-        // base_system_ext
-        ///////////////////////////////////////////
-        "build_flag_system_ext",
-        "fs_config_dirs_system_ext",
-        "fs_config_files_system_ext",
-        "group_system_ext",
-        "passwd_system_ext",
-        "SatelliteClient",
-        "selinux_policy_system_ext",
-        "system_ext_manifest.xml",
-        "system_ext-build.prop",
-        // Base modules when shipping api level is less than or equal to 34
-        "hwservicemanager",
-        "android.hidl.allocator@1.0-service",
-
-        ///////////////////////////////////////////
-        // window_extensions_base
-        ///////////////////////////////////////////
-        "androidx.window.extensions",
-        "androidx.window.sidecar",
-
-        ///////////////////////////////////////////
         // gsi_release
         ///////////////////////////////////////////
         "gsi_skip_mount.cfg",
@@ -161,40 +143,7 @@
         "Dialer",
         "LatinIME",
         "apns-full-conf.xml",
-
-        ///////////////////////////////////////////
-        // media_product
-        ///////////////////////////////////////////
-        "webview",
-
-        ///////////////////////////////////////////
-        // base_product
-        ///////////////////////////////////////////
-
-        // Base modules and settings for the product partition.
-        "build_flag_product",
-        "fs_config_dirs_product",
-        "fs_config_files_product",
-        "group_product",
-        "ModuleMetadata",
-        "passwd_product",
-        "product_compatibility_matrix.xml",
-        "product_manifest.xml",
-        "selinux_policy_product",
-        "product-build.prop",
-
-        // AUDIO
-        "frameworks_sounds",
-
-        ///////////////////////////////////////////
-        // base_system
-        ///////////////////////////////////////////
-        "charger",
-    ] + select(product_variable("debuggable"), {
-        // Packages included only for eng or userdebug builds, previously debug tagged
-        true: ["adb_keys"],
-        default: [],
-    }),
+    ],
     multilib: {
         both: {
             // PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34
diff --git a/tools/aconfig/aconfig/Android.bp b/tools/aconfig/aconfig/Android.bp
index 5e3eb12..cce0ca9 100644
--- a/tools/aconfig/aconfig/Android.bp
+++ b/tools/aconfig/aconfig/Android.bp
@@ -243,6 +243,11 @@
     crate_name: "aconfig_test_rust_library",
     aconfig_declarations: "aconfig.test.flags",
     host_supported: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.configinfrastructure",
+    ],
+    min_sdk_version: "34",
 }
 
 rust_test {
diff --git a/tools/aconfig/aconfig/src/codegen/cpp.rs b/tools/aconfig/aconfig/src/codegen/cpp.rs
index ae18679..d7d77c5 100644
--- a/tools/aconfig/aconfig/src/codegen/cpp.rs
+++ b/tools/aconfig/aconfig/src/codegen/cpp.rs
@@ -24,7 +24,7 @@
 
 use crate::codegen;
 use crate::codegen::CodegenMode;
-use crate::commands::OutputFile;
+use crate::commands::{should_include_flag, OutputFile};
 
 pub fn generate_cpp_code<I>(
     package: &str,
@@ -127,10 +127,7 @@
     flag_ids: HashMap<String, u16>,
     rw_count: &mut i32,
 ) -> ClassElement {
-    let no_assigned_offset =
-        (pf.container() == "system" || pf.container() == "vendor" || pf.container() == "product")
-            && pf.permission() == ProtoFlagPermission::READ_ONLY
-            && pf.state() == ProtoFlagState::DISABLED;
+    let no_assigned_offset = !should_include_flag(pf);
 
     let flag_offset = match flag_ids.get(pf.name()) {
         Some(offset) => offset,
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index 0d528d2..81340f2 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -22,7 +22,7 @@
 
 use crate::codegen;
 use crate::codegen::CodegenMode;
-use crate::commands::OutputFile;
+use crate::commands::{should_include_flag, OutputFile};
 use aconfig_protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag};
 use std::collections::HashMap;
 
@@ -162,10 +162,7 @@
     let device_config_flag = codegen::create_device_config_ident(package, pf.name())
         .expect("values checked at flag parse time");
 
-    let no_assigned_offset =
-        (pf.container() == "system" || pf.container() == "vendor" || pf.container() == "product")
-            && pf.permission() == ProtoFlagPermission::READ_ONLY
-            && pf.state() == ProtoFlagState::DISABLED;
+    let no_assigned_offset = !should_include_flag(pf);
 
     let flag_offset = match flag_offsets.get(pf.name()) {
         Some(offset) => offset,
diff --git a/tools/aconfig/aconfig/src/codegen/rust.rs b/tools/aconfig/aconfig/src/codegen/rust.rs
index 2bf565a..74da1bc 100644
--- a/tools/aconfig/aconfig/src/codegen/rust.rs
+++ b/tools/aconfig/aconfig/src/codegen/rust.rs
@@ -24,7 +24,7 @@
 
 use crate::codegen;
 use crate::codegen::CodegenMode;
-use crate::commands::OutputFile;
+use crate::commands::{should_include_flag, OutputFile};
 
 pub fn generate_rust_code<I>(
     package: &str,
@@ -88,18 +88,12 @@
 impl TemplateParsedFlag {
     #[allow(clippy::nonminimal_bool)]
     fn new(package: &str, flag_offsets: HashMap<String, u16>, pf: &ProtoParsedFlag) -> Self {
-        let no_assigned_offset = (pf.container() == "system"
-            || pf.container() == "vendor"
-            || pf.container() == "product")
-            && pf.permission() == ProtoFlagPermission::READ_ONLY
-            && pf.state() == ProtoFlagState::DISABLED;
-
         let flag_offset = match flag_offsets.get(pf.name()) {
             Some(offset) => offset,
             None => {
                 // System/vendor/product RO+disabled flags have no offset in storage files.
                 // Assign placeholder value.
-                if no_assigned_offset {
+                if !should_include_flag(pf) {
                     &0
                 }
                 // All other flags _must_ have an offset.
diff --git a/tools/aconfig/aconfig/src/commands.rs b/tools/aconfig/aconfig/src/commands.rs
index 4c06462..2f96015 100644
--- a/tools/aconfig/aconfig/src/commands.rs
+++ b/tools/aconfig/aconfig/src/commands.rs
@@ -221,13 +221,13 @@
     new_exported: bool,
 ) -> Result<Vec<OutputFile>> {
     let parsed_flags = input.try_parse_flags()?;
-    let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, codegen_mode)?;
+    let modified_parsed_flags =
+        modify_parsed_flags_based_on_mode(parsed_flags.clone(), codegen_mode)?;
     let Some(package) = find_unique_package(&modified_parsed_flags) else {
         bail!("no parsed flags, or the parsed flags use different packages");
     };
     let package = package.to_string();
-    let mut flag_names =
-        modified_parsed_flags.iter().map(|pf| pf.name().to_string()).collect::<Vec<_>>();
+    let mut flag_names = extract_flag_names(parsed_flags)?;
     let package_fingerprint = compute_flags_fingerprint(&mut flag_names);
     let flag_ids = assign_flag_ids(&package, modified_parsed_flags.iter())?;
     generate_java_code(
@@ -436,14 +436,7 @@
             return Err(anyhow::anyhow!("the number of flags in a package cannot exceed 65535"));
         }
 
-        // Exclude system/vendor/product flags that are RO+disabled.
-        let should_filter_container = pf.container == Some("vendor".to_string())
-            || pf.container == Some("system".to_string())
-            || pf.container == Some("vendor".to_string());
-        if !(should_filter_container
-            && pf.state == Some(ProtoFlagState::DISABLED.into())
-            && pf.permission == Some(ProtoFlagPermission::READ_ONLY.into()))
-        {
+        if should_include_flag(pf) {
             flag_ids.insert(pf.name().to_string(), flag_idx as u16);
             flag_idx += 1;
         }
@@ -451,10 +444,8 @@
     Ok(flag_ids)
 }
 
-#[allow(dead_code)] // TODO: b/316357686 - Use fingerprint in codegen to
-                    // protect hardcoded offset reads.
-                    // Creates a fingerprint of the flag names (which requires sorting the vector).
-                    // Fingerprint is used by both codegen and storage files.
+// Creates a fingerprint of the flag names (which requires sorting the vector).
+// Fingerprint is used by both codegen and storage files.
 pub fn compute_flags_fingerprint(flag_names: &mut Vec<String>) -> u64 {
     flag_names.sort();
 
@@ -465,11 +456,9 @@
     hasher.finish()
 }
 
-#[allow(dead_code)] // TODO: b/316357686 - Use fingerprint in codegen to
-                    // protect hardcoded offset reads.
-                    // Converts ProtoParsedFlags into a vector of strings containing all of the flag
-                    // names. Helper fn for creating fingerprint for codegen files. Flags must all
-                    // belong to the same package.
+// Converts ProtoParsedFlags into a vector of strings containing all of the flag
+// names. Helper fn for creating fingerprint for codegen files. Flags must all
+// belong to the same package.
 fn extract_flag_names(flags: ProtoParsedFlags) -> Result<Vec<String>> {
     let separated_flags: Vec<ProtoParsedFlag> = flags.parsed_flag.into_iter().collect::<Vec<_>>();
 
@@ -478,7 +467,23 @@
         bail!("No parsed flags, or the parsed flags use different packages.");
     };
 
-    Ok(separated_flags.into_iter().map(|flag| flag.name.unwrap()).collect::<Vec<_>>())
+    Ok(separated_flags
+        .into_iter()
+        .filter(should_include_flag)
+        .map(|flag| flag.name.unwrap())
+        .collect::<Vec<_>>())
+}
+
+// Exclude system/vendor/product flags that are RO+disabled.
+pub fn should_include_flag(pf: &ProtoParsedFlag) -> bool {
+    let should_filter_container = pf.container == Some("vendor".to_string())
+        || pf.container == Some("system".to_string())
+        || pf.container == Some("product".to_string());
+
+    let disabled_ro = pf.state == Some(ProtoFlagState::DISABLED.into())
+        && pf.permission == Some(ProtoFlagPermission::READ_ONLY.into());
+
+    !should_filter_container || !disabled_ro
 }
 
 #[cfg(test)]
@@ -489,7 +494,7 @@
     #[test]
     fn test_offset_fingerprint() {
         let parsed_flags = crate::test::parse_test_flags();
-        let expected_fingerprint: u64 = 5801144784618221668;
+        let expected_fingerprint: u64 = 11551379960324242360;
 
         let mut extracted_flags = extract_flag_names(parsed_flags).unwrap();
         let hash_result = compute_flags_fingerprint(&mut extracted_flags);
@@ -509,6 +514,7 @@
             .parsed_flag
             .clone()
             .into_iter()
+            .filter(should_include_flag)
             .map(|flag| flag.name.unwrap())
             .map(String::from)
             .collect::<Vec<_>>();
diff --git a/tools/aconfig/aconfig/src/storage/flag_table.rs b/tools/aconfig/aconfig/src/storage/flag_table.rs
index 3b245a7..a3b4e8f 100644
--- a/tools/aconfig/aconfig/src/storage/flag_table.rs
+++ b/tools/aconfig/aconfig/src/storage/flag_table.rs
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-use crate::commands::assign_flag_ids;
+use crate::commands::{assign_flag_ids, should_include_flag};
 use crate::storage::FlagPackage;
-use aconfig_protos::{ProtoFlagPermission, ProtoFlagState};
+use aconfig_protos::ProtoFlagPermission;
 use aconfig_storage_file::{
     get_table_size, FlagTable, FlagTableHeader, FlagTableNode, StorageFileType, StoredFlagType,
 };
@@ -64,13 +64,7 @@
     fn create_nodes(package: &FlagPackage, num_buckets: u32) -> Result<Vec<Self>> {
         // Exclude system/vendor/product flags that are RO+disabled.
         let mut filtered_package = package.clone();
-        filtered_package.boolean_flags.retain(|f| {
-            !((f.container == Some("system".to_string())
-                || f.container == Some("vendor".to_string())
-                || f.container == Some("product".to_string()))
-                && f.permission == Some(ProtoFlagPermission::READ_ONLY.into())
-                && f.state == Some(ProtoFlagState::DISABLED.into()))
-        });
+        filtered_package.boolean_flags.retain(|pf| should_include_flag(pf));
 
         let flag_ids =
             assign_flag_ids(package.package_name, filtered_package.boolean_flags.iter().copied())?;
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
index 8b3d3e1..c390574 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
@@ -73,7 +73,7 @@
     private static final String TAG = "{package_name}.FeatureFlagsImpl_exported";
     private static volatile boolean isCached = false;
 {{ for flag in flag_elements }}
-    private static boolean {flag.method_name} = {flag.default_value};
+    private static boolean {flag.method_name} = false;
 {{ -endfor }}
     private void init() \{
         try \{
diff --git a/tools/aconfig/aconfig/templates/cpp_source_file.template b/tools/aconfig/aconfig/templates/cpp_source_file.template
index 9be59e0..325dbdc 100644
--- a/tools/aconfig/aconfig/templates/cpp_source_file.template
+++ b/tools/aconfig/aconfig/templates/cpp_source_file.template
@@ -29,25 +29,103 @@
     private:
         std::unordered_map<std::string, bool> overrides_;
 
+    {{ if allow_instrumentation- }}
+        uint32_t boolean_start_index_;
+
+        std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_;
+
+        bool package_exists_in_storage_;
+    {{ -endif }}
+
     public:
+    {{ if allow_instrumentation- }}
+        flag_provider()
+            : overrides_()
+            , boolean_start_index_()
+            , flag_value_file_(nullptr)
+            , package_exists_in_storage_(true) \{
+
+            auto package_map_file = aconfig_storage::get_mapped_file(
+                 "{container}",
+                 aconfig_storage::StorageFileType::package_map);
+
+            if (!package_map_file.ok()) \{
+                ALOGE("error: failed to get package map file: %s", package_map_file.error().c_str());
+                package_exists_in_storage_ = false;
+                return;
+            }
+
+            auto context = aconfig_storage::get_package_read_context(
+                **package_map_file, "{package}");
+
+            if (!context.ok()) \{
+                ALOGE("error: failed to get package read context: %s", context.error().c_str());
+                package_exists_in_storage_ = false;
+                return;
+            }
+
+            if (!(context->package_exists)) \{
+                package_exists_in_storage_ = false;
+                return;
+            }
+
+            // cache package boolean flag start index
+            boolean_start_index_ = context->boolean_start_index;
+
+            // unmap package map file and free memory
+            delete *package_map_file;
+
+            auto flag_value_file = aconfig_storage::get_mapped_file(
+                "{container}",
+                aconfig_storage::StorageFileType::flag_val);
+            if (!flag_value_file.ok()) \{
+                ALOGE("error: failed to get flag value file: %s", flag_value_file.error().c_str());
+                package_exists_in_storage_ = false;
+                return;
+            }
+
+            // cache flag value file
+            flag_value_file_ = std::unique_ptr<aconfig_storage::MappedStorageFile>(
+                *flag_value_file);
+
+        }
+    {{ -else }}
         flag_provider()
             : overrides_()
         \{}
+    {{ -endif }}
 
 {{ for item in class_elements }}
         virtual bool {item.flag_name}() override \{
             auto it = overrides_.find("{item.flag_name}");
-              if (it != overrides_.end()) \{
-                  return it->second;
+            if (it != overrides_.end()) \{
+                return it->second;
             } else \{
-              {{ if item.readwrite- }}
-              return server_configurable_flags::GetServerConfigurableFlag(
+                {{ if item.readwrite- }}
+                {{ if allow_instrumentation- }}
+                if (!package_exists_in_storage_) \{
+                    return {item.default_value};
+                }
+
+                auto value = aconfig_storage::get_boolean_flag_value(
+                    *flag_value_file_,
+                    boolean_start_index_ + {item.flag_offset});
+
+                if (!value.ok()) \{
+                    ALOGE("error: failed to read flag value: %s", value.error().c_str());
+                    return {item.default_value};
+                } else \{
+                    return *value;
+                }
+                {{ -else }}
+                return server_configurable_flags::GetServerConfigurableFlag(
                   "aconfig_flags.{item.device_config_namespace}",
                   "{item.device_config_flag}",
                   "{item.default_value}") == "true";
-              {{ -else }}
-                  return {item.default_value};
-              {{ -endif }}
+                {{ -endif }}
+                {{ -else }}
+                return {item.default_value};
+                {{ -endif }}
             }
         }
 
@@ -66,15 +144,11 @@
     class flag_provider : public flag_provider_interface \{
     public:
 
-        {{ if allow_instrumentation- }}
         {{ if readwrite- }}
+        {{ if allow_instrumentation- }}
         flag_provider()
-            {{ if readwrite- }}
             : cache_({readwrite_count}, -1)
             , boolean_start_index_()
-            {{ -else- }}
-            : boolean_start_index_()
-            {{ -endif }}
             , flag_value_file_(nullptr)
             , package_exists_in_storage_(true) \{
 
@@ -138,6 +212,7 @@
 
                 if (!value.ok()) \{
                     ALOGE("error: failed to read flag value: %s", value.error().c_str());
+                    return {item.default_value};
                 }
 
                 cache_[{item.readwrite_idx}] = *value;
diff --git a/tools/aconfig/aconfig_device_paths/Android.bp b/tools/aconfig/aconfig_device_paths/Android.bp
index bdf96ed..3531450 100644
--- a/tools/aconfig/aconfig_device_paths/Android.bp
+++ b/tools/aconfig/aconfig_device_paths/Android.bp
@@ -26,7 +26,6 @@
         "libaconfig_protos",
         "libanyhow",
         "libprotobuf",
-        "libregex",
     ],
 }
 
@@ -35,6 +34,11 @@
     crate_name: "aconfig_device_paths",
     host_supported: true,
     defaults: ["libaconfig_device_paths.defaults"],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.configinfrastructure",
+    ],
+    min_sdk_version: "34",
 }
 
 genrule {
@@ -54,7 +58,9 @@
     sdk_version: "core_platform",
     apex_available: [
         "//apex_available:platform",
+        "com.android.configinfrastructure",
     ],
+    min_sdk_version: "34",
 }
 
 genrule {
@@ -73,3 +79,23 @@
     name: "aconfig_host_device_paths_java",
     srcs: [":libaconfig_java_host_device_paths_src"],
 }
+
+genrule {
+    name: "java_device_paths_test_util_src",
+    srcs: ["src/DeviceProtosTestUtilTemplate.java"],
+    out: ["DeviceProtosTestUtil.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_util",
+    srcs: [":java_device_paths_test_util_src"],
+    static_libs: [
+        "libaconfig_java_proto_nano",
+    ],
+    sdk_version: "core_platform",
+    apex_available: [
+        "//apex_available:platform",
+    ],
+}
diff --git a/tools/aconfig/aconfig_device_paths/src/DeviceProtosTestUtilTemplate.java b/tools/aconfig/aconfig_device_paths/src/DeviceProtosTestUtilTemplate.java
new file mode 100644
index 0000000..2b113df
--- /dev/null
+++ b/tools/aconfig/aconfig_device_paths/src/DeviceProtosTestUtilTemplate.java
@@ -0,0 +1,99 @@
+/*
+ * 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 android.aconfig.nano.Aconfig.parsed_flag;
+import android.aconfig.nano.Aconfig.parsed_flags;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/** @hide */
+public class DeviceProtosTestUtil {
+    public static final String[] PATHS = {
+        TEMPLATE
+    };
+
+    private static final String APEX_DIR = "/apex/";
+    private static final String APEX_ACONFIG_PATH_SUFFIX = "/etc/aconfig_flags.pb";
+    private static final String SYSTEM_APEX_DIR = "/system/apex";
+
+    /**
+     * Returns a list of all on-device aconfig protos.
+     *
+     * <p>May throw an exception if the protos can't be read at the call site. For example, some of
+     * the protos are in the apex/ partition, which is mounted somewhat late in the boot process.
+     *
+     * @throws IOException if we can't read one of the protos yet
+     * @return a list of all on-device aconfig protos
+     */
+    public static List<parsed_flag> loadAndParseFlagProtos() throws IOException {
+        ArrayList<parsed_flag> result = new ArrayList();
+
+        for (String path : parsedFlagsProtoPaths()) {
+            try (FileInputStream inputStream = new FileInputStream(path)) {
+                parsed_flags parsedFlags = parsed_flags.parseFrom(inputStream.readAllBytes());
+                for (parsed_flag flag : parsedFlags.parsedFlag) {
+                    result.add(flag);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the list of all on-device aconfig protos paths.
+     *
+     * @hide
+     */
+    public static List<String> parsedFlagsProtoPaths() {
+        ArrayList<String> paths = new ArrayList(Arrays.asList(PATHS));
+
+        File apexDirectory = new File(SYSTEM_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().endsWith(".apex")) {
+                continue;
+            }
+
+            String apexName = prefix.getName().replace("com.google", "com");
+            apexName = apexName.substring(0, apexName.length() - 5);
+
+            File protoPath = new File(APEX_DIR + apexName + APEX_ACONFIG_PATH_SUFFIX);
+            if (!protoPath.exists()) {
+                continue;
+            }
+
+            paths.add(protoPath.getAbsolutePath());
+        }
+        return paths;
+    }
+}
diff --git a/tools/aconfig/aconfig_device_paths/test/Android.bp b/tools/aconfig/aconfig_device_paths/test/Android.bp
new file mode 100644
index 0000000..37f561f
--- /dev/null
+++ b/tools/aconfig/aconfig_device_paths/test/Android.bp
@@ -0,0 +1,35 @@
+// 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 {
+    default_team: "trendy_team_android_core_experiments",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "aconfig_device_paths_java_test",
+    srcs: [
+        "src/**/*.java",
+    ],
+    static_libs: [
+        "androidx.test.runner",
+        "junit",
+        "aconfig_device_paths_java_util",
+    ],
+    test_suites: [
+        "general-tests",
+    ],
+    platform_apis: true,
+    certificate: "platform",
+}
diff --git a/tools/aconfig/aconfig_device_paths/test/AndroidManifest.xml b/tools/aconfig/aconfig_device_paths/test/AndroidManifest.xml
new file mode 100644
index 0000000..5e01879
--- /dev/null
+++ b/tools/aconfig/aconfig_device_paths/test/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.aconfig.storage.test">
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.aconfig.storage.test" />
+
+</manifest>
diff --git a/tools/aconfig/aconfig_device_paths/test/src/DeviceProtosTestUtilTest.java b/tools/aconfig/aconfig_device_paths/test/src/DeviceProtosTestUtilTest.java
new file mode 100644
index 0000000..8dd0fd0
--- /dev/null
+++ b/tools/aconfig/aconfig_device_paths/test/src/DeviceProtosTestUtilTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.test;
+
+import static org.junit.Assert.assertTrue;
+
+import android.aconfig.DeviceProtosTestUtil;
+import android.aconfig.nano.Aconfig.parsed_flag;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.List;
+import java.util.Set;
+
+@RunWith(JUnit4.class)
+public class DeviceProtosTestUtilTest {
+
+    private static final Set<String> PLATFORM_CONTAINERS = Set.of("system", "vendor", "product");
+
+    @Test
+    public void testDeviceProtos_loadAndParseFlagProtos() throws Exception {
+        List<parsed_flag> flags = DeviceProtosTestUtil.loadAndParseFlagProtos();
+        int platformFlags = 0;
+        int mainlineFlags = 0;
+        for (parsed_flag pf : flags) {
+            if (PLATFORM_CONTAINERS.contains(pf.container)) {
+                platformFlags++;
+            } else {
+                mainlineFlags++;
+            }
+        }
+
+        assertTrue(platformFlags > 3);
+        assertTrue(mainlineFlags > 3);
+    }
+}
diff --git a/tools/aconfig/aconfig_flags/Android.bp b/tools/aconfig/aconfig_flags/Android.bp
index 4c1fd4e..1b4e148 100644
--- a/tools/aconfig/aconfig_flags/Android.bp
+++ b/tools/aconfig/aconfig_flags/Android.bp
@@ -24,6 +24,11 @@
         "libaconfig_flags_rust",
     ],
     host_supported: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.configinfrastructure",
+    ],
+    min_sdk_version: "34",
 }
 
 aconfig_declarations {
@@ -38,6 +43,11 @@
     crate_name: "aconfig_flags_rust",
     aconfig_declarations: "aconfig_flags",
     host_supported: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.configinfrastructure",
+    ],
+    min_sdk_version: "34",
 }
 
 cc_aconfig_library {
diff --git a/tools/aconfig/aconfig_flags/flags.aconfig b/tools/aconfig/aconfig_flags/flags.aconfig
index 367a2d0..96bb81a 100644
--- a/tools/aconfig/aconfig_flags/flags.aconfig
+++ b/tools/aconfig/aconfig_flags/flags.aconfig
@@ -20,4 +20,14 @@
   namespace: "core_experiments_team_internal"
   bug: "370499640"
   description: "When enabled, tools read directly from the new aconfig storage."
+}
+
+flag {
+  name: "tools_read_from_new_storage_bugfix"
+  namespace: "core_experiments_team_internal"
+  bug: "370499640"
+  description: "When enabled, tools read directly from the new aconfig storage."
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
 }
\ No newline at end of file
diff --git a/tools/aconfig/aconfig_protos/Android.bp b/tools/aconfig/aconfig_protos/Android.bp
index d241994..62a2b64 100644
--- a/tools/aconfig/aconfig_protos/Android.bp
+++ b/tools/aconfig/aconfig_protos/Android.bp
@@ -58,6 +58,11 @@
     crate_name: "aconfig_rust_proto",
     source_stem: "aconfig_rust_proto",
     host_supported: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.configinfrastructure",
+    ],
+    min_sdk_version: "34",
 }
 
 rust_defaults {
@@ -81,6 +86,11 @@
     crate_name: "aconfig_protos",
     host_supported: true,
     defaults: ["aconfig_protos.defaults"],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.configinfrastructure",
+    ],
+    min_sdk_version: "34",
 }
 
 rust_test_host {
diff --git a/tools/aconfig/aconfig_storage_read_api/Android.bp b/tools/aconfig/aconfig_storage_read_api/Android.bp
index fa41ff0..16341b9 100644
--- a/tools/aconfig/aconfig_storage_read_api/Android.bp
+++ b/tools/aconfig/aconfig_storage_read_api/Android.bp
@@ -154,18 +154,15 @@
 java_library {
     name: "aconfig_storage_reader_java",
     srcs: [
-        "srcs/android/os/flagging/PlatformAconfigPackageInternal.java",
+        "srcs/android/os/flagging/*.java",
     ],
     libs: [
         "unsupportedappusage",
-        "strict_mode_stub",
-        "aconfig_storage_stub",
     ],
     static_libs: [
         "aconfig_storage_file_java",
     ],
-    sdk_version: "core_current",
-    host_supported: true,
+    sdk_version: "current",
     visibility: [
         "//frameworks/base",
         "//build/make/tools/aconfig/aconfig_storage_read_api/tests",
diff --git a/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java b/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
new file mode 100644
index 0000000..5fbe567
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
@@ -0,0 +1,168 @@
+/*
+ * 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.os.flagging;
+
+import android.aconfig.storage.AconfigStorageException;
+import android.aconfig.storage.FlagTable;
+import android.aconfig.storage.FlagValueList;
+import android.aconfig.storage.PackageTable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.util.Log;
+
+import java.io.Closeable;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * An {@code aconfig} package containing the enabled state of its flags.
+ *
+ * <p><strong>Note: this is intended only to be used by generated code. To determine if a given flag
+ * is enabled in app code, the generated android flags should be used.</strong>
+ *
+ * <p>This class is used to read the flag from platform Aconfig Package.Each instance of this class
+ * will cache information related to one package. To read flags from a different package, a new
+ * instance of this class should be {@link #load loaded}.
+ *
+ * @hide
+ */
+public class PlatformAconfigPackage {
+    private static final String TAG = "PlatformAconfigPackage";
+    private static final String MAP_PATH = "/metadata/aconfig/maps/";
+    private static final String BOOT_PATH = "/metadata/aconfig/boot/";
+
+    private static final Map<String, PackageTable> sPackageTableCache = new HashMap<>();
+
+    private FlagTable mFlagTable;
+    private FlagValueList mFlagValueList;
+
+    private int mPackageBooleanStartOffset = -1;
+    private int mPackageId = -1;
+
+    private PlatformAconfigPackage() {}
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final Set<String> PLATFORM_PACKAGE_MAP_FILES =
+            Set.of("system.package.map", "vendor.package.map", "product.package.map");
+
+    static {
+        for (String pf : PLATFORM_PACKAGE_MAP_FILES) {
+            try {
+                PackageTable pTable = PackageTable.fromBytes(mapStorageFile(MAP_PATH + pf));
+                for (String packageName : pTable.getPackageList()) {
+                    sPackageTableCache.put(packageName, pTable);
+                }
+            } catch (Exception e) {
+                // pass
+                Log.w(TAG, e.toString());
+            }
+        }
+    }
+
+    /**
+     * Loads a platform Aconfig Package from Aconfig Storage.
+     *
+     * <p>This method attempts to load the specified platform Aconfig package.
+     *
+     * @param packageName The name of the Aconfig package to load.
+     * @return An instance of {@link PlatformAconfigPackage}, which may be empty if the package is
+     *     not found in the container. Null if the package is not found in platform partitions.
+     * @throws AconfigStorageReadException if there is an error reading from Aconfig Storage, such
+     *     as if the storage system is not found, or there is an error reading the storage file. The
+     *     specific error code can be got using {@link AconfigStorageReadException#getErrorCode()}.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static PlatformAconfigPackage load(String packageName) {
+        try {
+            PlatformAconfigPackage aconfigPackage = new PlatformAconfigPackage();
+            PackageTable pTable = sPackageTableCache.get(packageName);
+            if (pTable == null) {
+                return null;
+            }
+            PackageTable.Node pNode = pTable.get(packageName);
+            String container = pTable.getHeader().getContainer();
+            aconfigPackage.mFlagTable =
+                    FlagTable.fromBytes(mapStorageFile(MAP_PATH + container + ".flag.map"));
+            aconfigPackage.mFlagValueList =
+                    FlagValueList.fromBytes(mapStorageFile(BOOT_PATH + container + ".val"));
+            aconfigPackage.mPackageBooleanStartOffset = pNode.getBooleanStartIndex();
+            aconfigPackage.mPackageId = pNode.getPackageId();
+            return aconfigPackage;
+        } catch (AconfigStorageException e) {
+            throw new AconfigStorageReadException(
+                    e.getErrorCode(), "Fail to create AconfigPackage", e);
+        } catch (Exception e) {
+            throw new AconfigStorageReadException(
+                    AconfigStorageReadException.ERROR_GENERIC,
+                    "Fail to create PlatformAconfigPackage",
+                    e);
+        }
+    }
+
+    /**
+     * Retrieves the value of a boolean flag.
+     *
+     * <p>This method retrieves the value of the specified flag. If the flag exists within the
+     * loaded Aconfig Package, its value is returned. Otherwise, the provided `defaultValue` is
+     * returned.
+     *
+     * @param flagName The name of the flag (excluding any package name prefix).
+     * @param defaultValue The value to return if the flag is not found.
+     * @return The boolean value of the flag, or `defaultValue` if the flag is not found.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public boolean getBooleanFlagValue(String flagName, boolean defaultValue) {
+        FlagTable.Node fNode = mFlagTable.get(mPackageId, flagName);
+        if (fNode == null) {
+            return defaultValue;
+        }
+        return mFlagValueList.getBoolean(fNode.getFlagIndex() + mPackageBooleanStartOffset);
+    }
+
+    // Map a storage file given file path
+    private static MappedByteBuffer mapStorageFile(String file) {
+        FileChannel channel = null;
+        try {
+            channel = FileChannel.open(Paths.get(file), StandardOpenOption.READ);
+            return channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
+        } catch (Exception e) {
+            throw new AconfigStorageReadException(
+                    AconfigStorageReadException.ERROR_CANNOT_READ_STORAGE_FILE,
+                    "Fail to mmap storage",
+                    e);
+        } finally {
+            quietlyDispose(channel);
+        }
+    }
+
+    private static void quietlyDispose(Closeable closable) {
+        try {
+            if (closable != null) {
+                closable.close();
+            }
+        } catch (Exception e) {
+            // no need to care, at least as of now
+        }
+    }
+}
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/PlatformAconfigPackageInternalTest.java b/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/PlatformAconfigPackageInternalTest.java
index 2b0aeae..e532ff6 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/PlatformAconfigPackageInternalTest.java
+++ b/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/PlatformAconfigPackageInternalTest.java
@@ -45,7 +45,7 @@
     private static final Set<String> PLATFORM_CONTAINERS = Set.of("system", "vendor", "product");
 
     @Test
-    public void testAconfigPackageInternal_load() throws IOException {
+    public void testPlatformAconfigPackageInternal_load() throws IOException {
         List<parsed_flag> flags = DeviceProtos.loadAndParseFlagProtos();
         Map<String, PlatformAconfigPackageInternal> readerMap = new HashMap<>();
         StorageFileProvider fp = StorageFileProvider.getDefaultProvider();
@@ -82,7 +82,7 @@
     }
 
     @Test
-    public void testAconfigPackage_load_withError() throws IOException {
+    public void testPlatformAconfigPackage_load_withError() throws IOException {
         // container not found fake_container
         AconfigStorageException e =
                 assertThrows(
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/PlatformAconfigPackageTest.java b/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/PlatformAconfigPackageTest.java
new file mode 100644
index 0000000..fabc2c9
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/PlatformAconfigPackageTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.storage.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.aconfig.DeviceProtos;
+import android.aconfig.nano.Aconfig;
+import android.aconfig.nano.Aconfig.parsed_flag;
+import android.aconfig.storage.FlagTable;
+import android.aconfig.storage.FlagValueList;
+import android.aconfig.storage.PackageTable;
+import android.aconfig.storage.StorageFileProvider;
+import android.os.flagging.PlatformAconfigPackage;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+@RunWith(JUnit4.class)
+public class PlatformAconfigPackageTest {
+
+    private static final Set<String> PLATFORM_CONTAINERS = Set.of("system", "vendor", "product");
+
+    @Test
+    public void testPlatformAconfigPackage_load() throws IOException {
+        List<parsed_flag> flags = DeviceProtos.loadAndParseFlagProtos();
+        Map<String, PlatformAconfigPackage> readerMap = new HashMap<>();
+        StorageFileProvider fp = StorageFileProvider.getDefaultProvider();
+
+        for (parsed_flag flag : flags) {
+            if (flag.permission == Aconfig.READ_ONLY && flag.state == Aconfig.DISABLED) {
+                continue;
+            }
+            String container = flag.container;
+            String packageName = flag.package_;
+            String flagName = flag.name;
+            if (!PLATFORM_CONTAINERS.contains(container)) continue;
+
+            PackageTable pTable = fp.getPackageTable(container);
+            PackageTable.Node pNode = pTable.get(packageName);
+            FlagTable fTable = fp.getFlagTable(container);
+            FlagTable.Node fNode = fTable.get(pNode.getPackageId(), flagName);
+            FlagValueList fList = fp.getFlagValueList(container);
+
+            int index = pNode.getBooleanStartIndex() + fNode.getFlagIndex();
+            boolean rVal = fList.getBoolean(index);
+
+            long fingerprint = pNode.getPackageFingerprint();
+
+            PlatformAconfigPackage reader = readerMap.get(packageName);
+            if (reader == null) {
+                reader = PlatformAconfigPackage.load(packageName);
+                readerMap.put(packageName, reader);
+            }
+            boolean jVal = reader.getBooleanFlagValue(flagName, !rVal);
+
+            assertEquals(rVal, jVal);
+        }
+    }
+
+    @Test
+    public void testPlatformAconfigPackage_load_withError() throws IOException {
+        // package not found
+        assertNull(PlatformAconfigPackage.load("fake_container"));
+    }
+}
diff --git a/tools/aconfig/aflags/Android.bp b/tools/aconfig/aflags/Android.bp
index a7aceee..341975d 100644
--- a/tools/aconfig/aflags/Android.bp
+++ b/tools/aconfig/aflags/Android.bp
@@ -31,6 +31,9 @@
     name: "aflags",
     host_supported: true,
     defaults: ["aflags.defaults"],
+    apex_available: [
+        "//apex_available:platform",
+    ],
 }
 
 rust_test_host {
diff --git a/tools/aconfig/fake_device_config/src/android/os/flagging/AconfigStorageReadException.java b/tools/aconfig/fake_device_config/src/android/os/flagging/AconfigStorageReadException.java
deleted file mode 100644
index bfec98c..0000000
--- a/tools/aconfig/fake_device_config/src/android/os/flagging/AconfigStorageReadException.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.os.flagging;
-
-public class AconfigStorageReadException extends RuntimeException {
-
-    /** Generic error code indicating an unspecified Aconfig Storage error. */
-    public static final int ERROR_GENERIC = 0;
-
-    /** Error code indicating that the Aconfig Storage system is not found on the device. */
-    public static final int ERROR_STORAGE_SYSTEM_NOT_FOUND = 1;
-
-    /** Error code indicating that the requested configuration package is not found. */
-    public static final int ERROR_PACKAGE_NOT_FOUND = 2;
-
-    /** Error code indicating that the specified container is not found. */
-    public static final int ERROR_CONTAINER_NOT_FOUND = 3;
-
-    /** Error code indicating that there was an error reading the Aconfig Storage file. */
-    public static final int ERROR_CANNOT_READ_STORAGE_FILE = 4;
-
-    public static final int ERROR_FILE_FINGERPRINT_MISMATCH = 5;
-
-    public AconfigStorageReadException(int errorCode, String msg) {
-        super(msg);
-        throw new UnsupportedOperationException("Stub!");
-    }
-
-    public AconfigStorageReadException(int errorCode, String msg, Throwable cause) {
-        super(msg, cause);
-        throw new UnsupportedOperationException("Stub!");
-    }
-
-    public AconfigStorageReadException(int errorCode, Throwable cause) {
-        super(cause);
-        throw new UnsupportedOperationException("Stub!");
-    }
-
-    public int getErrorCode() {
-        throw new UnsupportedOperationException("Stub!");
-    }
-
-    @Override
-    public String getMessage() {
-        throw new UnsupportedOperationException("Stub!");
-    }
-}
diff --git a/tools/aconfig/fake_device_config/src/android/os/flagging/PlatformAconfigPackage.java b/tools/aconfig/fake_device_config/src/android/os/flagging/PlatformAconfigPackage.java
new file mode 100644
index 0000000..ec79f7d
--- /dev/null
+++ b/tools/aconfig/fake_device_config/src/android/os/flagging/PlatformAconfigPackage.java
@@ -0,0 +1,36 @@
+/*
+ * 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.os.flagging;
+
+import java.util.Set;
+
+/*
+ * This class allows generated aconfig code to compile independently of the framework.
+ */
+public class PlatformAconfigPackage {
+
+    public static final Set<String> PLATFORM_PACKAGE_MAP_FILES =
+            Set.of("system.package.map", "vendor.package.map", "product.package.map");
+
+    public static PlatformAconfigPackage load(String packageName) {
+        throw new UnsupportedOperationException("Stub!");
+    }
+
+    public boolean getBooleanFlagValue(String flagName, boolean defaultValue) {
+        throw new UnsupportedOperationException("Stub!");
+    }
+}
diff --git a/tools/aconfig/printflags/Android.bp b/tools/aconfig/printflags/Android.bp
index d50a77d..6f7bca3 100644
--- a/tools/aconfig/printflags/Android.bp
+++ b/tools/aconfig/printflags/Android.bp
@@ -19,6 +19,9 @@
 rust_binary {
     name: "printflags",
     defaults: ["printflags.defaults"],
+    apex_available: [
+        "//apex_available:platform",
+    ],
 }
 
 rust_test_host {
diff --git a/tools/check_elf_file.py b/tools/check_elf_file.py
index 1fd7950..0640041 100755
--- a/tools/check_elf_file.py
+++ b/tools/check_elf_file.py
@@ -42,8 +42,9 @@
 _EM_X86_64 = 62
 _EM_AARCH64 = 183
 
-_KNOWN_MACHINES = {_EM_386, _EM_ARM, _EM_X86_64, _EM_AARCH64}
-
+_32_BIT_MACHINES = {_EM_386, _EM_ARM}
+_64_BIT_MACHINES = {_EM_X86_64, _EM_AARCH64}
+_KNOWN_MACHINES = _32_BIT_MACHINES | _64_BIT_MACHINES
 
 # ELF header struct
 _ELF_HEADER_STRUCT = (
@@ -483,6 +484,11 @@
       sys.exit(2)
 
   def check_max_page_size(self, max_page_size):
+    if self._file_under_test.header.e_machine in _32_BIT_MACHINES:
+      # Skip test on 32-bit machines. 16 KB pages is an arm64 feature
+      # and no 32-bit systems in Android use it.
+      return
+
     for alignment in self._file_under_test.alignments:
       if alignment % max_page_size != 0:
         self._error(f'Load segment has alignment {alignment} but '
diff --git a/tools/finalization/command-line-options.sh b/tools/finalization/command-line-options.sh
index d9397c2..3a1e049 100644
--- a/tools/finalization/command-line-options.sh
+++ b/tools/finalization/command-line-options.sh
@@ -3,6 +3,7 @@
 while true; do
     case "$1" in
         --dry-run) repo_upload_dry_run_arg="--dry-run"; repo_branch="finalization-dry-run"; shift ;;
+        --) shift; break;;
         *) break
     esac
 done
diff --git a/tools/finalization/environment.sh b/tools/finalization/environment.sh
index cf3e61b..0d3a9e1 100755
--- a/tools/finalization/environment.sh
+++ b/tools/finalization/environment.sh
@@ -30,7 +30,7 @@
 # TODO(b/323985297): The version must match with that from the release configuration.
 # Instead of hardcoding the version here, read it from a release configuration.
 export FINAL_BOARD_API_LEVEL='202504'
-export FINAL_CORRESPONDING_VERSION_LETTER='W'
+export FINAL_CORRESPONDING_VERSION_LETTER='B'
 export FINAL_CORRESPONDING_PLATFORM_VERSION='16'
 export FINAL_NEXT_BOARD_API_LEVEL='202604'
-export FINAL_NEXT_CORRESPONDING_VERSION_LETTER='X'
+export FINAL_NEXT_CORRESPONDING_VERSION_LETTER='C'
diff --git a/tools/ide_query/prober_scripts/jvm/Android.bp b/tools/ide_query/prober_scripts/jvm/Android.bp
new file mode 100644
index 0000000..84d00b5
--- /dev/null
+++ b/tools/ide_query/prober_scripts/jvm/Android.bp
@@ -0,0 +1,28 @@
+/*
+ * 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+    name: "ide_query_proberscript_jvm",
+    srcs: [
+        "Foo.java",
+        "Bar.java",
+        "other/Other.java",
+    ],
+}
diff --git a/tools/ide_query/prober_scripts/jvm/Bar.java b/tools/ide_query/prober_scripts/jvm/Bar.java
new file mode 100644
index 0000000..8d51576
--- /dev/null
+++ b/tools/ide_query/prober_scripts/jvm/Bar.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014 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 jvm;
+
+/** Bar class. The class for testing code assist within the same build module. */
+class Bar<K extends Number, V extends Number> {
+  Bar() {
+    foo(new Foo());
+  }
+
+  void foo(Foo f) {}
+
+  void foo(Object o) {}
+
+  void bar(Foo f) {}
+
+  void baz(Object o) {}
+}
\ No newline at end of file
diff --git a/tools/ide_query/prober_scripts/jvm/Foo.java b/tools/ide_query/prober_scripts/jvm/Foo.java
index a043f72..9397bc4 100644
--- a/tools/ide_query/prober_scripts/jvm/Foo.java
+++ b/tools/ide_query/prober_scripts/jvm/Foo.java
@@ -16,22 +16,109 @@
 
 package jvm;
 
-import java.util.ArrayList;
-import java.util.HashSet;
+import jvm.other.Other;
 
 /** Foo class. */
 public final class Foo {
+//               |  | foo_def
+
+  void testParameterInfo() {
+    // Test signature help for type parameters.
+
+    Bar<Integer, Double> b = new Bar<>();
+    //                               ^ ctor
+    //     ^ decl_1
+    //              ^ decl_2
+    System.out.println(b);
+
+    // step at ctor
+    // workspace.waitForReady()
+    // paraminfo.trigger()
+    // assert paraminfo.items.filter(
+    //  label="K extends Number, V extends Number",
+    //  selection="K extends Number",
+    // )
+
+    // step at decl_1
+    // workspace.waitForReady()
+    // paraminfo.trigger()
+    // assert paraminfo.items.filter(
+    //  label="K extends Number, V extends Number",
+    //  selection="K extends Number",
+    // )
+
+    // step at decl_2
+    // workspace.waitForReady()
+    // paraminfo.trigger()
+    // assert paraminfo.items.filter(
+    //  label="K extends Number, V extends Number",
+    //  selection="V extends Number",
+    // )
+
+    // Test signature help for constructor parameters.
+
+    Other other = new Other(123, "foo");
+    //                       ^ param_1
+    //                             ^ param_2
+    System.out.println(other);
+
+    // step at param_1
+    // workspace.waitForReady()
+    // paraminfo.trigger()
+    // assert paraminfo.items.filter(
+    //  label="\\(int first, String second\\)",
+    //  selection="int first",
+    // )
+
+    // step at param_2
+    // workspace.waitForReady()
+    // paraminfo.trigger()
+    // assert paraminfo.items.empty()
+  }
 
   void testCompletion() {
-    ArrayList<Integer> list = new ArrayList<>();
-    System.out.println(list);
+    Bar<Integer, Double> b = new Bar<>();
+    System.out.println(b);
 
     // ^
 
     // step
-    // ; Test completion on the standard types.
-    // type("list.")
+    // ; Test completion on types from the same package.
+    // workspace.waitForReady()
+    // type("b.")
     // completion.trigger()
-    // assert completion.items.filter(label="add.*")
+    // assert completion.items.filter(label="foo.*")
+    // delline()
+
+    Other other = new Other(1, "foo");
+    System.out.println(other);
+
+    // ^
+
+    // step
+    // ; Test completion on types from a different package.
+    // workspace.waitForReady()
+    // type("other.")
+    // completion.trigger()
+    // apply(completion.items.filter(label="other.*").first())
+    // type(".")
+    // completion.trigger()
+    // apply(completion.items.filter(label="other.*").first())
+    // delline()
+  }
+
+  void testDiagnostics() {
+
+    // ^
+
+    // step
+    // ; Test diagnostics about wrong type argument bounds.
+    // workspace.waitForReady()
+    // type("Bar<String, Double> b;")
+    // assert diagnostics.items.filter(
+    //  message="type argument .* is not within bounds .*",
+    //  code="compiler.err.not.within.bounds",
+    // )
+    // delline()
   }
 }
diff --git a/tools/ide_query/prober_scripts/jvm/ide_query.out b/tools/ide_query/prober_scripts/jvm/ide_query.out
new file mode 100644
index 0000000..af9fb86
--- /dev/null
+++ b/tools/ide_query/prober_scripts/jvm/ide_query.out
@@ -0,0 +1,4 @@
+
+out2X
+6build/make/tools/ide_query/prober_scripts/jvm/Foo.javaide_query_proberscript_jvm:Î
+ide_query_proberscript_jvm6build/make/tools/ide_query/prober_scripts/jvm/Foo.java6build/make/tools/ide_query/prober_scripts/jvm/Bar.java>build/make/tools/ide_query/prober_scripts/jvm/other/Other.java
\ No newline at end of file
diff --git a/tools/ide_query/prober_scripts/jvm/other/Other.java b/tools/ide_query/prober_scripts/jvm/other/Other.java
new file mode 100644
index 0000000..822662a
--- /dev/null
+++ b/tools/ide_query/prober_scripts/jvm/other/Other.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2014 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 jvm.other;
+
+/** Other class */
+public class Other {
+  public Other(int first, String second) {}
+
+  public Other other() {
+    return new Other(0, "");
+  }
+}
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 25bcb52..b6c96c4 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -977,8 +977,6 @@
     "will install in by default, so there could be files in the input_directory that are not "
     "actually supposed to be part of the partition. The paths in this file must be relative to "
     "input_directory.")
-  parser.add_argument("--build_datetime_file",
-                      help="a file containing the build id timestamp")
   parser.add_argument("input_directory",
     help="the staging directory to be converted to an image file")
   parser.add_argument("properties_file",
@@ -998,11 +996,6 @@
   common.InitLogging()
 
   glob_dict = LoadGlobalDict(args.properties_file)
-  if args.build_datetime_file:
-    # Parse the timestamp from build_datetime_file.
-    with open(args.build_datetime_file, "r") as f:
-      glob_dict["timestamp"] = int(f.read())
-
   if "mount_point" in glob_dict:
     # The caller knows the mount point and provides a dictionary needed by
     # BuildImage().
diff --git a/tools/releasetools/merge_ota.py b/tools/releasetools/merge_ota.py
index fb5957a..e8732a2 100644
--- a/tools/releasetools/merge_ota.py
+++ b/tools/releasetools/merge_ota.py
@@ -226,9 +226,21 @@
     logger.setLevel(logging.INFO)
 
   logger.info(args)
+  if args.java_path:
+    common.OPTIONS.java_path = args.java_path
+
   if args.search_path:
     common.OPTIONS.search_path = args.search_path
 
+  if args.signapk_path:
+    common.OPTIONS.signapk_path = args.signapk_path
+
+  if args.extra_signapk_args:
+    common.OPTIONS.extra_signapk_args = args.extra_signapk_args
+
+  if args.signapk_shared_library_path:
+    common.OPTIONS.signapk_shared_library_path = args.signapk_shared_library_path
+
   metadata_ota = args.packages[-1]
   if args.metadata_ota is not None:
     metadata_ota = args.metadata_ota
diff --git a/tools/releasetools/ota_signing_utils.py b/tools/releasetools/ota_signing_utils.py
index 60c8c94..9d04c3b 100644
--- a/tools/releasetools/ota_signing_utils.py
+++ b/tools/releasetools/ota_signing_utils.py
@@ -23,10 +23,18 @@
 
 
 def AddSigningArgumentParse(parser: argparse.ArgumentParser):
+  parser.add_argument('--java_path', type=str,
+                      help='Path to JVM if other than default')
   parser.add_argument('--package_key', type=str,
                       help='Paths to private key for signing payload')
   parser.add_argument('--search_path', '--path', type=str,
                       help='Search path for framework/signapk.jar')
+  parser.add_argument('--signapk_path', type=str,
+                      help='Path to signapk.jar, relative to search_path')
+  parser.add_argument('--extra_signapk_args', type=ParseSignerArgs,
+                      help='Extra arguments for signapk.jar')
+  parser.add_argument('--signapk_shared_library_path', type=str,
+                      help='Path to lib64 libraries used by signapk.jar')
   parser.add_argument('--payload_signer', type=str,
                       help='Path to custom payload signer')
   parser.add_argument('--payload_signer_args', type=ParseSignerArgs,
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 4ad97e0..2378539 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -862,21 +862,32 @@
 
     # Updates pvmfw embedded public key with the virt APEX payload key.
     elif filename == "PREBUILT_IMAGES/pvmfw.img":
-      # Find the name of the virt APEX in the target files.
+      # Find the path of the virt APEX in the target files.
       namelist = input_tf_zip.namelist()
-      apex_gen = (GetApexFilename(f) for f in namelist if IsApexFile(f))
-      virt_apex_re = re.compile("^com\.([^\.]+\.)?android\.virt\.apex$")
-      virt_apex = next((a for a in apex_gen if virt_apex_re.match(a)), None)
-      if not virt_apex:
+      apex_gen = (f for f in namelist if IsApexFile(f))
+      virt_apex_re = re.compile("^.*com\.([^\.]+\.)?android\.virt\.apex$")
+      virt_apex_path = next(
+        (a for a in apex_gen if virt_apex_re.match(a)), None)
+      if not virt_apex_path:
         print("Removing %s from ramdisk: virt APEX not found" % filename)
       else:
-        print("Replacing %s embedded key with %s key" % (filename, virt_apex))
+        print("Replacing %s embedded key with %s key" % (filename,
+                                                         virt_apex_path))
         # Get the current and new embedded keys.
+        virt_apex = GetApexFilename(virt_apex_path)
         payload_key, container_key, sign_tool = apex_keys[virt_apex]
-        new_pubkey_path = common.ExtractAvbPublicKey(
-            misc_info['avb_avbtool'], payload_key)
-        with open(new_pubkey_path, 'rb') as f:
-          new_pubkey = f.read()
+
+        # b/384813199: handles the pre-signed com.android.virt.apex in GSI.
+        if payload_key == 'PRESIGNED':
+          with input_tf_zip.open(virt_apex_path) as apex_fp:
+            with zipfile.ZipFile(apex_fp) as apex_zip:
+              new_pubkey = apex_zip.read('apex_pubkey')
+        else:
+          new_pubkey_path = common.ExtractAvbPublicKey(
+              misc_info['avb_avbtool'], payload_key)
+          with open(new_pubkey_path, 'rb') as f:
+            new_pubkey = f.read()
+
         pubkey_info = copy.copy(
             input_tf_zip.getinfo("PREBUILT_IMAGES/pvmfw_embedded.avbpubkey"))
         old_pubkey = input_tf_zip.read(pubkey_info.filename)