Merge "Revert "Add modprobe (toolbox) to generic ramdisk"" into main
diff --git a/backported_fixes/Android.bp b/backported_fixes/Android.bp
index 243e77e..0caea56 100644
--- a/backported_fixes/Android.bp
+++ b/backported_fixes/Android.bp
@@ -38,6 +38,7 @@
     name: "backported_fixes_proto",
     srcs: ["backported_fixes.proto"],
     host_supported: true,
+    sdk_version: "current",
 }
 
 java_library {
diff --git a/core/Makefile b/core/Makefile
index a951715..80ad33c 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)))), \
@@ -2398,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)
@@ -3553,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 )
@@ -3704,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
@@ -3766,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
@@ -3853,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
@@ -3959,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
@@ -4047,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
@@ -4116,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))
@@ -4206,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
@@ -4275,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
@@ -4344,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
@@ -4415,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
@@ -6181,11 +6181,14 @@
 
 built_ota_tools :=
 
+
 # We can't build static executables when SANITIZE_TARGET=address
 ifeq (,$(filter address, $(SANITIZE_TARGET)))
+ifeq (false,$(AB_OTA_UPDATER))
 built_ota_tools += \
     $(call intermediates-dir-for,EXECUTABLES,updater)/updater
 endif
+endif
 
 $(BUILT_TARGET_FILES_DIR): PRIVATE_OTA_TOOLS := $(built_ota_tools)
 
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index 95c0736..73831dc 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -39,6 +39,8 @@
 $(call add_soong_config_var,ANDROID,TARGET_DYNAMIC_64_32_DRMSERVER)
 $(call add_soong_config_var,ANDROID,TARGET_ENABLE_MEDIADRM_64)
 $(call add_soong_config_var,ANDROID,TARGET_DYNAMIC_64_32_MEDIASERVER)
+$(call soong_config_set_bool,ANDROID,TARGET_SUPPORTS_32_BIT_APPS,$(if $(TARGET_SUPPORTS_32_BIT_APPS),true,false))
+$(call soong_config_set_bool,ANDROID,TARGET_SUPPORTS_64_BIT_APPS,$(if $(TARGET_SUPPORTS_64_BIT_APPS),true,false))
 $(call add_soong_config_var,ANDROID,BOARD_GENFS_LABELS_VERSION)
 
 $(call add_soong_config_var,ANDROID,ADDITIONAL_M4DEFS,$(if $(BOARD_SEPOLICY_M4DEFS),$(addprefix -D,$(BOARD_SEPOLICY_M4DEFS))))
@@ -128,6 +130,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/main.mk b/core/main.mk
index 624df49..da5d49c 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.
@@ -1927,7 +1923,8 @@
 	  $(eval _is_platform_generated := $(_is_build_prop)$(_is_notice_file)$(_is_product_system_other_avbkey)$(_is_event_log_tags_file)$(_is_system_other_odex_marker)$(_is_kernel_modules_blocklist)$(_is_fsverity_build_manifest_apk)$(_is_linker_config)$(_is_partition_compat_symlink)$(_is_flags_file)$(_is_rootdir_symlink)) \
 	  $(eval _static_libs := $(if $(_is_soong_module),,$(ALL_INSTALLED_FILES.$f.STATIC_LIBRARIES))) \
 	  $(eval _whole_static_libs := $(if $(_is_soong_module),,$(ALL_INSTALLED_FILES.$f.WHOLE_STATIC_LIBRARIES))) \
-	  $(eval _license_text := $(if $(filter $(_build_output_path),$(ALL_NON_MODULES)),$(ALL_NON_MODULES.$(_build_output_path).NOTICES))) \
+	  $(eval _license_text := $(if $(filter $(_build_output_path),$(ALL_NON_MODULES)),$(ALL_NON_MODULES.$(_build_output_path).NOTICES),\
+	                          $(if $(_is_partition_compat_symlink),build/soong/licenses/LICENSE))) \
 	  echo '$(_build_output_path),$(_module_path),$(_is_soong_module),$(_is_prebuilt_make_module),$(_product_copy_files),$(_kernel_module_copy_files),$(_is_platform_generated),$(_static_libs),$(_whole_static_libs),$(_license_text)' >> $@; \
 	)
 
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/product_config.mk b/core/product_config.mk
index f93b63c..d18770b 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -485,9 +485,7 @@
 
 # Show a warning wall of text if non-compliance-GSI products set this option.
 ifdef PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT
-  ifeq (,$(filter gsi_arm gsi_arm64 gsi_arm64_soong_system gsi_x86 gsi_x86_64 \
-                  gsi_x86_64_soong_system gsi_car_arm64 gsi_car_x86_64 \
-                  gsi_tv_arm gsi_tv_arm64,$(PRODUCT_NAME)))
+  ifeq (,$(filter gsi_arm gsi_arm64 gsi_x86 gsi_x86_64 gsi_car_arm64 gsi_car_x86_64 gsi_tv_arm gsi_tv_arm64,$(PRODUCT_NAME)))
     $(warning PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT is set but \
       PRODUCT_NAME ($(PRODUCT_NAME)) doesn't look like a GSI for compliance \
       testing. This is a special configuration for compliance GSI, so do make \
diff --git a/core/proguard.flags b/core/proguard.flags
index 5148e56..dc32e15 100644
--- a/core/proguard.flags
+++ b/core/proguard.flags
@@ -1,14 +1,3 @@
-# We have moved -dontobfuscate and -dontoptimize to the makefiles.
-# dex does not like code run through proguard optimize and preverify steps.
-# -dontoptimize
--dontpreverify
-
-# Don't obfuscate. We only need dead code striping.
-# -dontobfuscate
-
-# Add this flag in your package's own configuration if it's needed.
-#-flattenpackagehierarchy
-
 # Keep classes and members with the platform-defined @VisibleForTesting annotation.
 -keep @com.android.internal.annotations.VisibleForTesting class *
 -keepclassmembers class * {
diff --git a/core/proguard_basic_keeps.flags b/core/proguard_basic_keeps.flags
index f6b34b8..a9416d5 100644
--- a/core/proguard_basic_keeps.flags
+++ b/core/proguard_basic_keeps.flags
@@ -1,7 +1,3 @@
-# Some classes in the libraries extend package private classes to chare common functionality
-# that isn't explicitly part of the API
--dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers
-
 # Preserve line number information for debugging stack traces.
 -keepattributes SourceFile,LineNumberTable
 
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 739905d..adfdb9c 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -441,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))
@@ -546,6 +547,8 @@
     $(call add_json_str, brightness_dimmed_percent, $(TARGET_RECOVERY_UI_BRIGHTNESS_DIMMED))
   $(call end_json_map)
 
+  $(call add_json_str, PrebuiltBootloader, $(BOARD_PREBUILT_BOOTLOADER))
+
 $(call end_json_map)
 
 # For converting vintf_data
diff --git a/core/sysprop.mk b/core/sysprop.mk
index e4f994f..9a9f509 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -123,7 +123,7 @@
 	$(hide) $$(call generate-common-build-props,$(call to-lower,$(strip $(1))),$$@)
 endif
         # Make and Soong use different intermediate files to build vendor/build.prop.
-        # Although the sysprop contents are same, the absolute paths of android_info.prop are different.
+        # Although the sysprop contents are same, the absolute paths of android-info.prop are different.
         # Print the filename for the intermediate files (files in OUT_DIR).
         # This helps with validating mk->soong migration of android partitions.
 	$(hide) $(foreach file,$(strip $(3)),\
@@ -183,7 +183,7 @@
     $(TARGET_VENDOR_PROP),\
     $(wildcard $(TARGET_DEVICE_DIR)/vendor.prop))
 
-android_info_prop := $(call intermediates-dir-for,ETC,android_info_prop)/android_info.prop
+android_info_prop := $(call intermediates-dir-for,ETC,android_info_prop)/android-info.prop
 $(android_info_prop): $(INSTALLED_ANDROID_INFO_TXT_TARGET)
 	cat $< | grep 'require version-' | sed -e 's/require version-/ro.build.expect./g' > $@
 
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/core/tasks/module-info.mk b/core/tasks/module-info.mk
index 0ca27d8..dd01f96 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -50,6 +50,8 @@
 			$(call write-optional-json-list, "host_dependencies", $(sort $(ALL_MODULES.$(m).HOST_REQUIRED_FROM_TARGET))) \
 			$(call write-optional-json-list, "target_dependencies", $(sort $(ALL_MODULES.$(m).TARGET_REQUIRED_FROM_HOST))) \
 			$(call write-optional-json-bool, "test_module_config_base", $(ALL_MODULES.$(m).TEST_MODULE_CONFIG_BASE)) \
+			$(call write-optional-json-bool, "make", $(if $(ALL_MODULES.$(m).IS_SOONG_MODULE),,true)) \
+			$(call write-optional-json-bool, "make_generated_module_info", true) \
 		'}')'\n}\n' >> $@.tmp
 	$(PRIVATE_MERGE_JSON_OBJECTS) -o $@ $(PRIVATE_SOONG_MODULE_INFO) $@.tmp
 	rm $@.tmp
diff --git a/packaging/distdir.mk b/packaging/distdir.mk
index 153ecf6..97ed95a 100644
--- a/packaging/distdir.mk
+++ b/packaging/distdir.mk
@@ -45,5 +45,3 @@
 endif
 
 copy-one-dist-file :=
-DIST_GOAL_OUTPUT_PAIRS :=
-DIST_SRC_DST_PAIRS :=
diff --git a/packaging/main_soong_only.mk b/packaging/main_soong_only.mk
new file mode 100644
index 0000000..f29e5f6
--- /dev/null
+++ b/packaging/main_soong_only.mk
@@ -0,0 +1,60 @@
+# Copyright (C) 2025 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+ifndef KATI
+$(error Only Kati is supported.)
+endif
+
+$(info [1/4] initializing packaging system ...)
+
+.KATI_READONLY := KATI_PACKAGE_MK_DIR
+
+include build/make/common/core.mk
+include build/make/common/strings.mk
+
+# Define well-known goals and their dependency graph that they've
+# traditionally had in make builds. Also it's important to define
+# droid first so that it's built by default.
+
+.PHONY: droid
+droid: droid_targets
+
+.PHONY: droid_targets
+droid_targets: droidcore dist_files
+
+.PHONY: dist_files
+dist_files:
+
+.PHONY: droidcore
+droidcore: droidcore-unbundled
+
+.PHONY: droidcore-unbundled
+droidcore-unbundled:
+
+$(info [2/4] including distdir.mk ...)
+
+include build/make/packaging/distdir.mk
+
+$(info [3/4] defining phony modules ...)
+
+include $(OUT_DIR)/soong/soong_phony_targets.mk
+
+goals := $(sort $(foreach pair,$(DIST_GOAL_OUTPUT_PAIRS),$(call word-colon,1,$(pair))))
+$(foreach goal,$(goals), \
+  $(eval .PHONY: $$(goal)) \
+  $(eval $$(goal):) \
+  $(if $(call streq,$(DIST),true),\
+    $(eval $$(goal): _dist_$$(goal))))
+
+$(info [4/4] writing packaging rules ...)
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index b3b58d3..90d45a8 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -52,7 +52,7 @@
     com.android.adbd \
     com.android.adservices \
     com.android.appsearch \
-    com.android.btservices \
+    com.android.bt \
     com.android.configinfrastructure \
     com.android.conscrypt \
     com.android.devicelock \
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index d857e04..e543ccf 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -65,7 +65,7 @@
     com.android.adservices:framework-adservices \
     com.android.adservices:framework-sdksandbox \
     com.android.appsearch:framework-appsearch \
-    com.android.btservices:framework-bluetooth \
+    com.android.bt:framework-bluetooth \
     com.android.configinfrastructure:framework-configinfrastructure \
     com.android.conscrypt:conscrypt \
     com.android.devicelock:framework-devicelock \
@@ -171,7 +171,7 @@
 # Keep the list sorted by module names and then library names.
 # Note: For modules available in Q, DO NOT add new entries here.
 PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS := \
-    com.android.btservices:service-bluetooth \
+    com.android.bt:service-bluetooth \
     com.android.devicelock:service-devicelock \
     com.android.os.statsd:service-statsd \
     com.android.scheduling:service-scheduling \
diff --git a/target/product/generic/Android.bp b/target/product/generic/Android.bp
index 7407d7f..314816d 100644
--- a/target/product/generic/Android.bp
+++ b/target/product/generic/Android.bp
@@ -642,6 +642,7 @@
         default: [],
     }) + select(product_variable("debuggable"), {
         true: [
+            "alloctop",
             "adevice_fingerprint",
             "arping",
             "avbctl",
diff --git a/target/product/gsi_release.mk b/target/product/gsi_release.mk
index 115b355..c288ad0 100644
--- a/target/product/gsi_release.mk
+++ b/target/product/gsi_release.mk
@@ -27,6 +27,7 @@
 #
 
 BUILDING_GSI := true
+$(call soong_config_set_bool,gsi,building_gsi,true)
 
 PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
     system/etc/init/config \
diff --git a/tools/aconfig/TEST_MAPPING b/tools/aconfig/TEST_MAPPING
index a7f0a4f..6e53018 100644
--- a/tools/aconfig/TEST_MAPPING
+++ b/tools/aconfig/TEST_MAPPING
@@ -106,10 +106,6 @@
     {
       // aconfig_storage read functional test
       "name": "aconfig_storage_read_functional"
-    },
-    {
-      // aconfig_storage read unit test
-      "name": "aconfig_storage_read_unit"
     }
   ]
 }
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/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index 81340f2..f41a6ca 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -547,7 +547,7 @@
         import android.util.Log;
         /** @hide */
         public final class FeatureFlagsImpl implements FeatureFlags {
-            private static final String TAG = "com.android.aconfig.test.FeatureFlagsImpl";
+            private static final String TAG = "FeatureFlagsImpl";
             private static volatile boolean isCached = false;
             private static boolean disabledRw = false;
             private static boolean disabledRwExported = false;
@@ -555,14 +555,14 @@
             private static boolean enabledRw = true;
             private void init() {
                 try {
-                    PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("system", "com.android.aconfig.test", 0x5081CE7221C77064L);
+                    PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("com.android.aconfig.test", 0x5081CE7221C77064L);
                     disabledRw = reader.getBooleanFlagValue(0);
                     disabledRwExported = reader.getBooleanFlagValue(1);
                     enabledRw = reader.getBooleanFlagValue(7);
                     disabledRwInOtherNamespace = reader.getBooleanFlagValue(2);
                 } catch (Exception e) {
                     Log.e(TAG, e.toString());
-                } catch (NoClassDefFoundError e) {
+                } catch (LinkageError e) {
                     // for mainline module running on older devices.
                     // This should be replaces to version check, after the version bump.
                     Log.e(TAG, e.toString());
@@ -929,7 +929,7 @@
         import android.util.Log;
         /** @hide */
         public final class FeatureFlagsImpl implements FeatureFlags {
-            private static final String TAG = "com.android.aconfig.test.FeatureFlagsImpl_exported";
+            private static final String TAG = "FeatureFlagsImplExport";
             private static volatile boolean isCached = false;
             private static boolean disabledRwExported = false;
             private static boolean enabledFixedRoExported = false;
@@ -943,7 +943,7 @@
                 } catch (Exception e) {
                     // pass
                     Log.e(TAG, e.toString());
-                } catch (NoClassDefFoundError e) {
+                } catch (LinkageError e) {
                     // for mainline module running on older devices.
                     // This should be replaces to version check, after the version bump.
                     Log.e(TAG, e.toString());
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
index 8b3d3e1..750a6be 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
@@ -16,7 +16,7 @@
 /** @hide */
 public final class FeatureFlagsImpl implements FeatureFlags \{
 {{ -if runtime_lookup_required }}
-    private static final String TAG = "{package_name}.FeatureFlagsImpl";
+    private static final String TAG = "FeatureFlagsImpl";
     private static volatile boolean isCached = false;
 {{ for flag in flag_elements }}
 {{ -if flag.is_read_write }}
@@ -27,9 +27,9 @@
     private void init() \{
         try \{
 {{ if is_platform_container }}
-            PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("{container}", "{package_name}", {package_fingerprint});
+            PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("{package_name}", {package_fingerprint});
 {{ -else }}
-            AconfigPackageInternal reader = AconfigPackageInternal.load("{container}", "{package_name}", {package_fingerprint});
+            AconfigPackageInternal reader = AconfigPackageInternal.load("{package_name}", {package_fingerprint});
 {{ -endif }}
         {{ -for namespace_with_flags in namespace_flags }}
         {{ -for flag in namespace_with_flags.flags }}
@@ -40,7 +40,7 @@
         {{ -endfor }}
         } catch (Exception e) \{
             Log.e(TAG, e.toString());
-        } catch (NoClassDefFoundError e) \{
+        } catch (LinkageError e) \{
             // for mainline module running on older devices.
             // This should be replaces to version check, after the version bump.
             Log.e(TAG, e.toString());
@@ -70,10 +70,10 @@
 import android.util.Log;
 /** @hide */
 public final class FeatureFlagsImpl implements FeatureFlags \{
-    private static final String TAG = "{package_name}.FeatureFlagsImpl_exported";
+    private static final String TAG = "FeatureFlagsImplExport";
     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 \{
@@ -86,7 +86,7 @@
         } catch (Exception e) \{
             // pass
             Log.e(TAG, e.toString());
-        } catch (NoClassDefFoundError e) \{
+        } catch (LinkageError e) \{
             // for mainline module running on older devices.
             // This should be replaces to version check, after the version bump.
             Log.e(TAG, e.toString());
diff --git a/tools/aconfig/aconfig/templates/cpp_source_file.template b/tools/aconfig/aconfig/templates/cpp_source_file.template
index 325dbdc..dc4e435 100644
--- a/tools/aconfig/aconfig/templates/cpp_source_file.template
+++ b/tools/aconfig/aconfig/templates/cpp_source_file.template
@@ -30,15 +30,18 @@
         std::unordered_map<std::string, bool> overrides_;
 
     {{ if allow_instrumentation- }}
+    {{ if readwrite- }}
         uint32_t boolean_start_index_;
 
         std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_;
 
         bool package_exists_in_storage_;
     {{ -endif }}
+    {{ -endif }}
 
     public:
     {{ if allow_instrumentation- }}
+    {{ if readwrite- }}
         flag_provider()
             : overrides_()
             , boolean_start_index_()
@@ -94,8 +97,13 @@
             : overrides_()
         \{}
     {{ -endif }}
+    {{ -else }}
+        flag_provider()
+            : overrides_()
+        \{}
+    {{ -endif }}
 
-{{ for item in class_elements }}
+    {{ for item in class_elements }}
         virtual bool {item.flag_name}() override \{
             auto it = overrides_.find("{item.flag_name}");
             if (it != overrides_.end()) \{
@@ -132,7 +140,7 @@
         virtual void {item.flag_name}(bool val) override \{
             overrides_["{item.flag_name}"] = val;
         }
-{{ endfor }}
+    {{ endfor }}
 
         virtual void reset_flags() override \{
             overrides_.clear();
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/mainline_aconfig_flags_paths.txt b/tools/aconfig/aconfig_device_paths/mainline_aconfig_flags_paths.txt
index af73a84..aad2b23 100644
--- a/tools/aconfig/aconfig_device_paths/mainline_aconfig_flags_paths.txt
+++ b/tools/aconfig/aconfig_device_paths/mainline_aconfig_flags_paths.txt
@@ -1,7 +1,7 @@
 "/apex/com.android.adservices/etc/aconfig_flags.pb",
 "/apex/com.android.appsearch/etc/aconfig_flags.pb",
 "/apex/com.android.art/etc/aconfig_flags.pb",
-"/apex/com.android.btservices/etc/aconfig_flags.pb",
+"/apex/com.android.bt/etc/aconfig_flags.pb",
 "/apex/com.android.cellbroadcast/etc/aconfig_flags.pb",
 "/apex/com.android.configinfrastructure/etc/aconfig_flags.pb",
 "/apex/com.android.conscrypt/etc/aconfig_flags.pb",
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..45d6766
--- /dev/null
+++ b/tools/aconfig/aconfig_device_paths/src/DeviceProtosTestUtilTemplate.java
@@ -0,0 +1,93 @@
+/*
+ * 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) {
+            String apexName = prefix.getName().replace("com.google", "com");
+            apexName = apexName.substring(0, apexName.lastIndexOf('.'));
+
+            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 96bb81a..2488b5c 100644
--- a/tools/aconfig/aconfig_flags/flags.aconfig
+++ b/tools/aconfig/aconfig_flags/flags.aconfig
@@ -30,4 +30,14 @@
   metadata {
     purpose: PURPOSE_BUGFIX
   }
-}
\ No newline at end of file
+}
+
+flag {
+  name: "invoke_updatable_aflags"
+  namespace: "core_experiments_team_internal"
+  bug: "385383899"
+  description: "When enabled, the system aflags binary invokes the updatable aflags."
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
diff --git a/tools/aconfig/aconfig_flags/src/lib.rs b/tools/aconfig/aconfig_flags/src/lib.rs
index 2e89127..dc507ae 100644
--- a/tools/aconfig/aconfig_flags/src/lib.rs
+++ b/tools/aconfig/aconfig_flags/src/lib.rs
@@ -39,6 +39,11 @@
     pub fn enable_aconfigd_from_mainline() -> bool {
         aconfig_flags_rust::enable_only_new_storage()
     }
+
+    /// Returns the value for the invoke_updatable_aflags flag.
+    pub fn invoke_updatable_aflags() -> bool {
+        aconfig_flags_rust::invoke_updatable_aflags()
+    }
 }
 
 /// Module used when building with cargo
@@ -55,4 +60,10 @@
         // Used only to enable typechecking and testing with cargo
         true
     }
+
+    /// Returns the value for the invoke_updatable_aflags flag.
+    pub fn invoke_updatable_aflags() -> bool {
+        // Used only to enable typechecking and testing with cargo
+        true
+    }
 }
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_file/srcs/android/aconfig/storage/TableUtils.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/TableUtils.java
index 81168f5..d4269da 100644
--- a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/TableUtils.java
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/TableUtils.java
@@ -63,4 +63,16 @@
         long hashVal = SipHasher13.hash(val);
         return (int) Long.remainderUnsigned(hashVal, numBuckets);
     }
+
+     public static class StorageFilesBundle {
+        public final PackageTable packageTable;
+        public final FlagTable flagTable;
+        public final FlagValueList flagValueList;
+
+        public StorageFilesBundle (PackageTable pTable, FlagTable fTable, FlagValueList fValueList) {
+            this.packageTable = pTable;
+            this.flagTable = fTable;
+            this.flagValueList = fValueList;
+        }
+     }
 }
diff --git a/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java b/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
index 5fbe567..ddad249 100644
--- a/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
+++ b/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
@@ -16,6 +16,8 @@
 
 package android.os.flagging;
 
+import static android.aconfig.storage.TableUtils.StorageFilesBundle;
+
 import android.aconfig.storage.AconfigStorageException;
 import android.aconfig.storage.FlagTable;
 import android.aconfig.storage.FlagValueList;
@@ -49,8 +51,6 @@
     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;
 
@@ -60,6 +60,9 @@
     private PlatformAconfigPackage() {}
 
     /** @hide */
+    static final Map<String, StorageFilesBundle> sStorageFilesCache = new HashMap<>();
+
+    /** @hide */
     @UnsupportedAppUsage
     public static final Set<String> PLATFORM_PACKAGE_MAP_FILES =
             Set.of("system.package.map", "vendor.package.map", "product.package.map");
@@ -68,8 +71,14 @@
         for (String pf : PLATFORM_PACKAGE_MAP_FILES) {
             try {
                 PackageTable pTable = PackageTable.fromBytes(mapStorageFile(MAP_PATH + pf));
+                String container = pTable.getHeader().getContainer();
+                FlagTable fTable =
+                        FlagTable.fromBytes(mapStorageFile(MAP_PATH + container + ".flag.map"));
+                FlagValueList fValueList =
+                        FlagValueList.fromBytes(mapStorageFile(BOOT_PATH + container + ".val"));
+                StorageFilesBundle files = new StorageFilesBundle(pTable, fTable, fValueList);
                 for (String packageName : pTable.getPackageList()) {
-                    sPackageTableCache.put(packageName, pTable);
+                    sStorageFilesCache.put(packageName, files);
                 }
             } catch (Exception e) {
                 // pass
@@ -95,16 +104,13 @@
     public static PlatformAconfigPackage load(String packageName) {
         try {
             PlatformAconfigPackage aconfigPackage = new PlatformAconfigPackage();
-            PackageTable pTable = sPackageTableCache.get(packageName);
-            if (pTable == null) {
+            StorageFilesBundle files = sStorageFilesCache.get(packageName);
+            if (files == 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"));
+            PackageTable.Node pNode = files.packageTable.get(packageName);
+            aconfigPackage.mFlagTable = files.flagTable;
+            aconfigPackage.mFlagValueList = files.flagValueList;
             aconfigPackage.mPackageBooleanStartOffset = pNode.getBooleanStartIndex();
             aconfigPackage.mPackageId = pNode.getPackageId();
             return aconfigPackage;
diff --git a/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackageInternal.java b/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackageInternal.java
index 854e68b..da18fb9 100644
--- a/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackageInternal.java
+++ b/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackageInternal.java
@@ -16,12 +16,12 @@
 
 package android.os.flagging;
 
+import static android.aconfig.storage.TableUtils.StorageFilesBundle;
+
 import android.aconfig.storage.AconfigStorageException;
 import android.aconfig.storage.FlagValueList;
 import android.aconfig.storage.PackageTable;
-import android.aconfig.storage.StorageFileProvider;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.os.StrictMode;
 
 /**
  * An {@code aconfig} package containing the enabled state of its flags.
@@ -55,7 +55,6 @@
      * <p>This method is intended for internal use only and may be changed or removed without
      * notice.
      *
-     * @param container The name of the container.
      * @param packageName The name of the Aconfig package.
      * @param packageFingerprint The expected fingerprint of the package.
      * @return An instance of {@link PlatformAconfigPackageInternal} representing the loaded
@@ -63,51 +62,20 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public static PlatformAconfigPackageInternal load(
-            String container, String packageName, long packageFingerprint) {
-        return load(
-                container,
-                packageName,
-                packageFingerprint,
-                StorageFileProvider.getDefaultProvider());
-    }
-
-    /** @hide */
-    public static PlatformAconfigPackageInternal load(
-            String container,
-            String packageName,
-            long packageFingerprint,
-            StorageFileProvider fileProvider) {
-        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
-        PackageTable.Node pNode = null;
-        FlagValueList vList = null;
-        try {
-            pNode = fileProvider.getPackageTable(container).get(packageName);
-            vList = fileProvider.getFlagValueList(container);
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-
-        if (pNode == null || vList == null) {
+    public static PlatformAconfigPackageInternal load(String packageName, long packageFingerprint) {
+        StorageFilesBundle files = PlatformAconfigPackage.sStorageFilesCache.get(packageName);
+        if (files == null) {
             throw new AconfigStorageException(
                     AconfigStorageException.ERROR_PACKAGE_NOT_FOUND,
-                    String.format(
-                            "package "
-                                    + packageName
-                                    + " in container "
-                                    + container
-                                    + " cannot be found on the device"));
+                    "package " + packageName + " cannot be found on the device");
         }
+        PackageTable.Node pNode = files.packageTable.get(packageName);
+        FlagValueList vList = files.flagValueList;
 
         if (pNode.hasPackageFingerprint() && packageFingerprint != pNode.getPackageFingerprint()) {
             throw new AconfigStorageException(
                     AconfigStorageException.ERROR_FILE_FINGERPRINT_MISMATCH,
-                    String.format(
-                            "package "
-                                    + packageName
-                                    + " in container "
-                                    + container
-                                    + " cannot be found on the device"));
+                    "package " + packageName + "fingerprint doesn't match the one on device");
         }
 
         return new PlatformAconfigPackageInternal(vList, pNode.getBooleanStartIndex());
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/AconfigStorageReadUnitTest.xml b/tools/aconfig/aconfig_storage_read_api/tests/AconfigStorageReadUnitTest.xml
deleted file mode 100644
index e528dd5..0000000
--- a/tools/aconfig/aconfig_storage_read_api/tests/AconfigStorageReadUnitTest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?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.
-  -->
-<configuration description="Test aconfig storage java tests">
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="aconfig_storage_read_unit.apk" />
-    </target_preparer>
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-        <option name="cleanup" value="true" />
-        <option name="push" value="package_v2.map->/data/local/tmp/aconfig_storage_read_unit/testdata/mockup.package.map" />
-        <option name="push" value="flag_v2.map->/data/local/tmp/aconfig_storage_read_unit/testdata/mockup.flag.map" />
-        <option name="push" value="flag_v2.val->/data/local/tmp/aconfig_storage_read_unit/testdata/mockup.val" />
-        <option name="push" value="flag_v2.info->/data/local/tmp/aconfig_storage_read_unit/testdata/mockup.info" />
-        <option name="post-push" value="chmod +r /data/local/tmp/aconfig_storage_read_unit/testdata/" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.aconfig.storage.test" />
-        <option name="runtime-hint" value="1m" />
-    </test>
-</configuration>
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/Android.bp b/tools/aconfig/aconfig_storage_read_api/tests/Android.bp
index 702325d..c071f7c 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/Android.bp
+++ b/tools/aconfig/aconfig_storage_read_api/tests/Android.bp
@@ -55,7 +55,7 @@
         "functional/srcs/**/*.java",
     ],
     static_libs: [
-        "aconfig_device_paths_java",
+        "aconfig_device_paths_java_util",
         "aconfig_storage_file_java",
         "androidx.test.rules",
         "libaconfig_storage_read_api_java",
@@ -75,25 +75,3 @@
     test_config: "AconfigStorageReadFunctionalTest.xml",
     team: "trendy_team_android_core_experiments",
 }
-
-android_test {
-    name: "aconfig_storage_read_unit",
-    team: "trendy_team_android_core_experiments",
-    srcs: [
-        "unit/srcs/**/*.java",
-    ],
-    static_libs: [
-        "androidx.test.runner",
-        "junit",
-        "aconfig_storage_reader_java",
-    ],
-    sdk_version: "test_current",
-    data: [
-        ":read_api_test_storage_files",
-    ],
-    test_suites: [
-        "general-tests",
-    ],
-    test_config: "AconfigStorageReadUnitTest.xml",
-    jarjar_rules: "jarjar.txt",
-}
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/AconfigStorageReadAPITest.java b/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/AconfigStorageReadAPITest.java
index 2557048..0587e9d 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/AconfigStorageReadAPITest.java
+++ b/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/AconfigStorageReadAPITest.java
@@ -19,7 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import android.aconfig.DeviceProtos;
+import android.aconfig.DeviceProtosTestUtil;
 import android.aconfig.nano.Aconfig.parsed_flag;
 import android.aconfig.storage.AconfigStorageReadAPI;
 import android.aconfig.storage.FlagReadContext;
@@ -210,7 +210,7 @@
 
     @Test
     public void testRustJavaEqualHash() throws IOException {
-        List<parsed_flag> flags = DeviceProtos.loadAndParseFlagProtos();
+        List<parsed_flag> flags = DeviceProtosTestUtil.loadAndParseFlagProtos();
         for (parsed_flag flag : flags) {
             String packageName = flag.package_;
             String flagName = flag.name;
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 e532ff6..9896baf 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
@@ -19,7 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThrows;
 
-import android.aconfig.DeviceProtos;
+import android.aconfig.DeviceProtosTestUtil;
 import android.aconfig.nano.Aconfig;
 import android.aconfig.nano.Aconfig.parsed_flag;
 import android.aconfig.storage.FlagTable;
@@ -46,7 +46,7 @@
 
     @Test
     public void testPlatformAconfigPackageInternal_load() throws IOException {
-        List<parsed_flag> flags = DeviceProtos.loadAndParseFlagProtos();
+        List<parsed_flag> flags = DeviceProtosTestUtil.loadAndParseFlagProtos();
         Map<String, PlatformAconfigPackageInternal> readerMap = new HashMap<>();
         StorageFileProvider fp = StorageFileProvider.getDefaultProvider();
 
@@ -72,7 +72,7 @@
 
             PlatformAconfigPackageInternal reader = readerMap.get(packageName);
             if (reader == null) {
-                reader = PlatformAconfigPackageInternal.load(container, packageName, fingerprint);
+                reader = PlatformAconfigPackageInternal.load(packageName, fingerprint);
                 readerMap.put(packageName, reader);
             }
             boolean jVal = reader.getBooleanFlagValue(fNode.getFlagIndex());
@@ -83,24 +83,15 @@
 
     @Test
     public void testPlatformAconfigPackage_load_withError() throws IOException {
-        // container not found fake_container
+        // package not found
         AconfigStorageException e =
                 assertThrows(
                         AconfigStorageException.class,
-                        () ->
-                                PlatformAconfigPackageInternal.load(
-                                        "fake_container", "fake_package", 0));
-        assertEquals(AconfigStorageException.ERROR_CANNOT_READ_STORAGE_FILE, e.getErrorCode());
-
-        // package not found
-        e =
-                assertThrows(
-                        AconfigStorageException.class,
-                        () -> PlatformAconfigPackageInternal.load("system", "fake_container", 0));
+                        () -> PlatformAconfigPackageInternal.load("fake_package", 0));
         assertEquals(AconfigStorageException.ERROR_PACKAGE_NOT_FOUND, e.getErrorCode());
 
         // fingerprint doesn't match
-        List<parsed_flag> flags = DeviceProtos.loadAndParseFlagProtos();
+        List<parsed_flag> flags = DeviceProtosTestUtil.loadAndParseFlagProtos();
         StorageFileProvider fp = StorageFileProvider.getDefaultProvider();
 
         parsed_flag flag = flags.get(0);
@@ -119,7 +110,7 @@
                             AconfigStorageException.class,
                             () ->
                                     PlatformAconfigPackageInternal.load(
-                                            container, packageName, fingerprint + 1));
+                                            packageName, fingerprint + 1));
             assertEquals(AconfigStorageException.ERROR_FILE_FINGERPRINT_MISMATCH, e.getErrorCode());
         }
     }
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
index fabc2c9..1c6c238 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/PlatformAconfigPackageTest.java
+++ b/tools/aconfig/aconfig_storage_read_api/tests/functional/srcs/PlatformAconfigPackageTest.java
@@ -17,9 +17,10 @@
 package android.aconfig.storage.test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
-import android.aconfig.DeviceProtos;
+import android.aconfig.DeviceProtosTestUtil;
 import android.aconfig.nano.Aconfig;
 import android.aconfig.nano.Aconfig.parsed_flag;
 import android.aconfig.storage.FlagTable;
@@ -44,8 +45,22 @@
     private static final Set<String> PLATFORM_CONTAINERS = Set.of("system", "vendor", "product");
 
     @Test
+    public void testPlatformAconfigPackage_StorageFilesCache() throws IOException {
+        List<parsed_flag> flags = DeviceProtosTestUtil.loadAndParseFlagProtos();
+        for (parsed_flag flag : flags) {
+            if (flag.permission == Aconfig.READ_ONLY && flag.state == Aconfig.DISABLED) {
+                continue;
+            }
+            String container = flag.container;
+            String packageName = flag.package_;
+            if (!PLATFORM_CONTAINERS.contains(container)) continue;
+            assertNotNull(PlatformAconfigPackage.load(packageName));
+        }
+    }
+
+    @Test
     public void testPlatformAconfigPackage_load() throws IOException {
-        List<parsed_flag> flags = DeviceProtos.loadAndParseFlagProtos();
+        List<parsed_flag> flags = DeviceProtosTestUtil.loadAndParseFlagProtos();
         Map<String, PlatformAconfigPackage> readerMap = new HashMap<>();
         StorageFileProvider fp = StorageFileProvider.getDefaultProvider();
 
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/jarjar.txt b/tools/aconfig/aconfig_storage_read_api/tests/jarjar.txt
deleted file mode 100644
index 49250d4..0000000
--- a/tools/aconfig/aconfig_storage_read_api/tests/jarjar.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-rule android.aconfig.storage.AconfigStorageException android.aconfig.storage.test.AconfigStorageException
-rule android.aconfig.storage.FlagTable android.aconfig.storage.test.FlagTable
-rule android.aconfig.storage.PackageTable android.aconfig.storage.test.PackageTable
-rule android.aconfig.storage.ByteBufferReader android.aconfig.storage.test.ByteBufferReader
-rule android.aconfig.storage.FlagType android.aconfig.storage.test.FlagType
-rule android.aconfig.storage.SipHasher13 android.aconfig.storage.test.SipHasher13
-rule android.aconfig.storage.FileType android.aconfig.storage.test.FileType
-rule android.aconfig.storage.FlagValueList android.aconfig.storage.test.FlagValueList
-rule android.aconfig.storage.TableUtils android.aconfig.storage.test.TableUtils
-rule android.aconfig.storage.AconfigPackageImpl android.aconfig.storage.test.AconfigPackageImpl
-rule android.aconfig.storage.StorageFileProvider android.aconfig.storage.test.StorageFileProvider
-
-
-rule android.aconfig.storage.FlagTable$* android.aconfig.storage.test.FlagTable$@1
-rule android.aconfig.storage.PackageTable$* android.aconfig.storage.test.PackageTable$@1
-rule android.aconfig.storage.FlagValueList$* android.aconfig.storage.test.FlagValueList@1
-rule android.aconfig.storage.SipHasher13$* android.aconfig.storage.test.SipHasher13@1
-
-rule android.os.flagging.PlatformAconfigPackageInternal android.aconfig.storage.test.PlatformAconfigPackageInternal
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/unit/srcs/PlatformAconfigPackageInternalTest.java b/tools/aconfig/aconfig_storage_read_api/tests/unit/srcs/PlatformAconfigPackageInternalTest.java
deleted file mode 100644
index cac3de2..0000000
--- a/tools/aconfig/aconfig_storage_read_api/tests/unit/srcs/PlatformAconfigPackageInternalTest.java
+++ /dev/null
@@ -1,152 +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.aconfig.storage.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-
-import android.aconfig.storage.AconfigStorageException;
-import android.aconfig.storage.PackageTable;
-import android.aconfig.storage.StorageFileProvider;
-import android.os.flagging.PlatformAconfigPackageInternal;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class PlatformAconfigPackageInternalTest {
-
-    public static final String TESTDATA_PATH =
-            "/data/local/tmp/aconfig_storage_read_unit/testdata/";
-
-    private StorageFileProvider pr;
-
-    @Before
-    public void setup() {
-        pr = new StorageFileProvider(TESTDATA_PATH, TESTDATA_PATH);
-    }
-
-    @Test
-    public void testLoad_container_package() throws Exception {
-        PackageTable packageTable = pr.getPackageTable("mockup");
-
-        PackageTable.Node node1 = packageTable.get("com.android.aconfig.storage.test_1");
-
-        long fingerprint = node1.getPackageFingerprint();
-        PlatformAconfigPackageInternal p =
-                PlatformAconfigPackageInternal.load(
-                        "mockup", "com.android.aconfig.storage.test_1", fingerprint, pr);
-    }
-
-    @Test
-    public void testLoad_container_package_error() throws Exception {
-        PackageTable packageTable = pr.getPackageTable("mockup");
-        PackageTable.Node node1 = packageTable.get("com.android.aconfig.storage.test_1");
-        long fingerprint = node1.getPackageFingerprint();
-        // cannot find package
-        AconfigStorageException e =
-                assertThrows(
-                        AconfigStorageException.class,
-                        () ->
-                                PlatformAconfigPackageInternal.load(
-                                        "mockup",
-                                        "com.android.aconfig.storage.test_10",
-                                        fingerprint,
-                                        pr));
-        assertEquals(AconfigStorageException.ERROR_PACKAGE_NOT_FOUND, e.getErrorCode());
-
-        // cannot find container
-        e =
-                assertThrows(
-                        AconfigStorageException.class,
-                        () ->
-                                PlatformAconfigPackageInternal.load(
-                                        null,
-                                        "com.android.aconfig.storage.test_1",
-                                        fingerprint,
-                                        pr));
-        assertEquals(AconfigStorageException.ERROR_CANNOT_READ_STORAGE_FILE, e.getErrorCode());
-
-        e =
-                assertThrows(
-                        AconfigStorageException.class,
-                        () ->
-                                PlatformAconfigPackageInternal.load(
-                                        "test",
-                                        "com.android.aconfig.storage.test_1",
-                                        fingerprint,
-                                        pr));
-        assertEquals(AconfigStorageException.ERROR_CANNOT_READ_STORAGE_FILE, e.getErrorCode());
-
-        // fingerprint doesn't match
-        e =
-                assertThrows(
-                        AconfigStorageException.class,
-                        () ->
-                                PlatformAconfigPackageInternal.load(
-                                        "mockup",
-                                        "com.android.aconfig.storage.test_1",
-                                        fingerprint + 1,
-                                        pr));
-        assertEquals(
-                // AconfigStorageException.ERROR_FILE_FINGERPRINT_MISMATCH,
-                5, e.getErrorCode());
-
-        // new storage doesn't exist
-        pr = new StorageFileProvider("fake/path/", "fake/path/");
-        e =
-                assertThrows(
-                        AconfigStorageException.class,
-                        () ->
-                                PlatformAconfigPackageInternal.load(
-                                        "mockup",
-                                        "com.android.aconfig.storage.test_1",
-                                        fingerprint,
-                                        pr));
-        assertEquals(AconfigStorageException.ERROR_CANNOT_READ_STORAGE_FILE, e.getErrorCode());
-
-        // file read issue
-        pr = new StorageFileProvider(TESTDATA_PATH, "fake/path/");
-        e =
-                assertThrows(
-                        AconfigStorageException.class,
-                        () ->
-                                PlatformAconfigPackageInternal.load(
-                                        "mockup",
-                                        "com.android.aconfig.storage.test_1",
-                                        fingerprint,
-                                        pr));
-        assertEquals(AconfigStorageException.ERROR_CANNOT_READ_STORAGE_FILE, e.getErrorCode());
-    }
-
-    @Test
-    public void testGetBooleanFlagValue_index() throws Exception {
-        PackageTable packageTable = pr.getPackageTable("mockup");
-        PackageTable.Node node1 = packageTable.get("com.android.aconfig.storage.test_1");
-        long fingerprint = node1.getPackageFingerprint();
-        PlatformAconfigPackageInternal p =
-                PlatformAconfigPackageInternal.load(
-                        "mockup", "com.android.aconfig.storage.test_1", fingerprint, pr);
-        assertFalse(p.getBooleanFlagValue(0));
-        assertTrue(p.getBooleanFlagValue(1));
-        assertTrue(p.getBooleanFlagValue(2));
-    }
-}
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/aflags/src/main.rs b/tools/aconfig/aflags/src/main.rs
index 8173bc2..e4af2a7 100644
--- a/tools/aconfig/aflags/src/main.rs
+++ b/tools/aconfig/aflags/src/main.rs
@@ -16,6 +16,9 @@
 
 //! `aflags` is a device binary to read and write aconfig flags.
 
+use std::env;
+use std::process::{Command as OsCommand, Stdio};
+
 use anyhow::{anyhow, ensure, Result};
 use clap::Parser;
 
@@ -298,7 +301,34 @@
     }
 }
 
+fn invoke_updatable_aflags() {
+    let updatable_command = "/apex/com.android.configinfrastructure/bin/aflags_updatable";
+
+    let args: Vec<String> = env::args().collect();
+    let command_args = if args.len() >= 2 { &args[1..] } else { &["--help".to_string()] };
+
+    let mut child = OsCommand::new(updatable_command);
+    for arg in command_args {
+        child.arg(arg);
+    }
+
+    let output = child
+        .stdin(Stdio::piped())
+        .stdout(Stdio::piped())
+        .spawn()
+        .expect("failed to execute child")
+        .wait_with_output()
+        .expect("failed to execute command");
+
+    println!("{}", String::from_utf8_lossy(&output.stdout).trim());
+}
+
 fn main() -> Result<()> {
+    if aconfig_flags::auto_generated::invoke_updatable_aflags() {
+        invoke_updatable_aflags();
+        return Ok(());
+    }
+
     ensure!(nix::unistd::Uid::current().is_root(), "must be root");
 
     let cli = Cli::parse();
diff --git a/tools/aconfig/fake_device_config/src/android/os/flagging/AconfigPackageInternal.java b/tools/aconfig/fake_device_config/src/android/os/flagging/AconfigPackageInternal.java
index d084048..46058b6 100644
--- a/tools/aconfig/fake_device_config/src/android/os/flagging/AconfigPackageInternal.java
+++ b/tools/aconfig/fake_device_config/src/android/os/flagging/AconfigPackageInternal.java
@@ -21,8 +21,7 @@
  */
 public class AconfigPackageInternal {
 
-    public static AconfigPackageInternal load(
-            String container, String packageName, long packageFingerprint) {
+    public static AconfigPackageInternal load(String packageName, long packageFingerprint) {
         throw new UnsupportedOperationException("Stub!");
     }
 
diff --git a/tools/aconfig/fake_device_config/src/android/os/flagging/PlatformAconfigPackageInternal.java b/tools/aconfig/fake_device_config/src/android/os/flagging/PlatformAconfigPackageInternal.java
index 283b251..378c963 100644
--- a/tools/aconfig/fake_device_config/src/android/os/flagging/PlatformAconfigPackageInternal.java
+++ b/tools/aconfig/fake_device_config/src/android/os/flagging/PlatformAconfigPackageInternal.java
@@ -21,8 +21,7 @@
  */
 public class PlatformAconfigPackageInternal {
 
-    public static PlatformAconfigPackageInternal load(
-            String container, String packageName, long packageFingerprint) {
+    public static PlatformAconfigPackageInternal load(String packageName, long packageFingerprint) {
         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/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/missing_soong_module_info.py b/tools/missing_soong_module_info.py
new file mode 100755
index 0000000..6fa7f2b
--- /dev/null
+++ b/tools/missing_soong_module_info.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2016 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.
+
+import json
+import os
+import sys
+
+def main():
+    try:
+        product_out = os.environ["ANDROID_PRODUCT_OUT"]
+    except KeyError:
+        sys.stderr.write("Can't get ANDROID_PRODUCT_OUT. Run lunch first.\n")
+        sys.exit(1)
+
+    filename = os.path.join(product_out, "module-info.json")
+    try:
+        with open(filename) as f:
+            modules = json.load(f)
+    except FileNotFoundError:
+        sys.stderr.write(f"File not found: {filename}\n")
+        sys.exit(1)
+    except json.JSONDecodeError:
+        sys.stderr.write(f"Invalid json: {filename}\n")
+        return None
+
+    classes = {}
+
+    for name, info in modules.items():
+        make = info.get("make")
+        make_gen = info.get("make_generated_module_info")
+        if not make and make_gen:
+            classes.setdefault(frozenset(info.get("class")), []).append(name)
+
+    for cl, names in classes.items():
+        print(" ".join(cl))
+        for name in names:
+            print(" ", name)
+
+if __name__ == "__main__":
+    main()
diff --git a/tools/perf/benchmarks b/tools/perf/benchmarks
index 6998ecd..4fdb8c2 100755
--- a/tools/perf/benchmarks
+++ b/tools/perf/benchmarks
@@ -786,6 +786,14 @@
                       preroll=1,
                       postroll=2,
                       ),
+            Benchmark(id="add_systemui_field_with_tests",
+                      title="Add SystemUI field with tests",
+                      change=AddJavaField("frameworks/base/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java",
+                                    "public"),
+                      modules=["SystemUiRavenTests"],
+                      preroll=1,
+                      postroll=2,
+                      ),
         ]
 
     def _error(self, message):
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/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)